public T Get <T>() { if (!Valid) { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.WARNING, "Trying to Get() the value of an Invalid XmlRpcValue!"); return((T)(object)null); } Type type = typeof(T); if (type.Equals(typeof(String))) { return((T)(object)asString); } if (type.Equals(typeof(Int32))) { return((T)(object)asInt); } if (type.Equals(typeof(Boolean))) { return((T)(object)asBool); } if (type.Equals(typeof(Double))) { return((T)(object)asDouble); } if (type.Equals(typeof(XmlRpcValue))) { return((T)(object)asArray); } throw new Exception(string.Format("Trying to Get {0} from:\n{1}", type.FullName, ToString())); }
private static void RmRef(ref IntPtr ptr) { lock (reflock) { if (_refs.ContainsKey(ptr)) { if (ptr == IntPtr.Zero) { throw new Exception("OHHH NOOOO!!!"); } #if REFDEBUG Console.WriteLine("Removing a reference to: " + ptr + " (" + _refs[ptr] + "==> " + (_refs[ptr] - 1) + ")"); #endif _refs[ptr]--; if (_refs[ptr] == 0) { #if REFDEBUG Console.WriteLine("KILLING " + ptr + " BECAUSE IT'S DEAD!"); #endif _refs.Remove(ptr); XmlRpcUtil.Free(ptr); } return; } ptr = IntPtr.Zero; throw new Exception("OHHH NOOOO!!!"); } }
//done and works private void Initialize(string host, int port, string uri /*=0*/) { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.DEBUG, "XmlRpcClient new client: host {0}, port {1}.", host, port); _host = host; _port = port; if (uri != null) { _uri = uri; } else { _uri = "/RPC2"; } _connectionState = ConnectionState.CONNECTING; _executing = false; _eof = false; if (doConnect()) { _connectionState = ConnectionState.IDLE; } // Default to keeping the connection open until an explicit close is done setKeepOpen(); }
// Execute the named procedure on the remote server, non-blocking. // Params should be an array of the arguments for the method. // Returns true if the request was sent and a result received (although the result // might be a fault). public bool ExecuteNonBlock(string method, XmlRpcValue parameters) { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.SPEW, "XmlRpcClient::ExecuteNonBlock: method {0} (_connectionState {0}.", method, _connectionState); // This is not a thread-safe operation, if you want to do multithreading, use separate // clients for each thread. If you want to protect yourself from multiple threads // accessing the same client, replace this code with a real mutex. XmlRpcValue result = new XmlRpcValue(); if (_executing) { return(false); } _executing = true; _sendAttempts = 0; _isFault = false; if (!setupConnection()) { _executing = false; return(false); } if (!generateRequest(method, parameters)) { _executing = false; return(false); } _executing = false; return(true); }
// Run the method, generate _response string public string executeRequest(string _request) { string _response = ""; XmlRpcValue parms = new XmlRpcValue(), resultValue = new XmlRpcValue(); string methodName = parseRequest(parms, _request); XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.WARNING, "XmlRpcServerConnection::executeRequest: server calling method '{0}'", methodName); try { if (!executeMethod(methodName, parms, resultValue) && !executeMulticall(methodName, parms, resultValue)) { _response = generateFaultResponse(methodName + ": unknown method name"); } else { _response = generateResponse(resultValue.toXml()); } } catch (XmlRpcException fault) { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.WARNING, "XmlRpcServerConnection::executeRequest: fault {0}.", fault.Message); _response = generateFaultResponse(fault.Message, fault.getCode()); } return(_response); }
private bool readRequest() { int left = header.ContentLength - header.DataString.Length; int dataLen = 0; if (left > 0) { byte[] data = new byte[left]; try { dataLen = stream.Read(data, 0, left); if (dataLen == 0) { XmlRpcUtil.error("XmlRpcServerConnection::readRequest: Stream was closed"); return(false); } } catch (Exception ex) { XmlRpcUtil.error("XmlRpcServerConnection::readRequest: error while reading the rest of data ({0}).", ex.Message); return(false); } header.Append(Encoding.ASCII.GetString(data, 0, dataLen)); } // Otherwise, parse and dispatch the request XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.DEBUG, "XmlRpcServerConnection::readRequest read {0} bytes.", dataLen); if (!header.ContentComplete) { return(false); } _connectionState = ServerConnectionState.WRITE_RESPONSE; return(true); // Continue monitoring this source }
// The xml-encoded request, http header of response, and response xml public override void Close() { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.DEBUG, "XmlRpcClient::Close()"); close(); if (Disposed != null) { Disposed(); } }
public override void Close() { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.INFO, "XmlRpcServerConnection is closing"); if (socket != null) { socket.Close(100); socket = null; } server.removeConnection(this); }
// Encode the request to call the specified method with the specified parameters into xml private bool generateRequest(string methodName, XmlRpcValue parameters) { string body = generateRequestStr(methodName, parameters); string header = generateHeader(body); XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.DEBUG, "XmlRpcClient::generateRequest: header is {0} bytes, content-length is {1}.", header.Length, body.Length); _request = header + body; return(true); }
// The server delegates handling client requests to a serverConnection object. public XmlRpcServerConnection(Socket fd, XmlRpcServer server, bool deleteOnClose /*= false*/) //: base(fd, deleteOnClose) { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.INFO, "XmlRpcServerConnection: new socket {0}.", fd.RemoteEndPoint.ToString()); this.server = server; socket = fd; stream = new NetworkStream(socket, true); _connectionState = ServerConnectionState.READ_HEADER; KeepOpen = true; _keepAlive = true; }
// Create a response from results xml public string generateResponse(string resultXml) { string RESPONSE_1 = "<?xml version=\"1.0\"?>\r\n<methodResponse><params><param>\r\n\t"; string RESPONSE_2 = "\r\n</param></params></methodResponse>\r\n"; string body = RESPONSE_1 + resultXml + RESPONSE_2; string header = generateHeader(body); string result = header + body; XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.SPEW, "XmlRpcServerConnection::generateResponse:\n{0}\n", result); return(result); }
internal virtual bool readHeader(ref HTTPHeader header) { // Read available data int dataLen = 0; var stream = getStream(); if (stream == null) { throw new Exception("Could not access network stream"); } byte[] data = new byte[READ_BUFFER_LENGTH]; try { dataLen = stream.Read(data, 0, READ_BUFFER_LENGTH); if (dataLen == 0) { return(false); // If it is disconnect } if (header == null) { header = new HTTPHeader(Encoding.ASCII.GetString(data, 0, dataLen)); if (header.m_headerStatus == HTTPHeader.STATUS.UNINITIALIZED) { return(false); //should only happen if the constructor's invocation of Append did not happen as desired } } else if (header.Append(Encoding.ASCII.GetString(data, 0, dataLen)) == HTTPHeader.STATUS.PARTIAL_HEADER) { return(true); //if we successfully append a piece of the header, return true, but DO NOT change states } } catch (SocketException ex) { XmlRpcUtil.error("XmlRpcServerConnection::readHeader: error while reading header ({0}).", ex.Message); return(false); } catch (Exception ex) { XmlRpcUtil.error("XmlRpcServerConnection::readHeader: error while reading header ({0}).", ex.Message); return(false); } if (header.m_headerStatus != HTTPHeader.STATUS.COMPLETE_HEADER) { return(false); } return(true); }
private bool writeResponse(string request) { string response = server.executeRequest(request); if (response.Length == 0) { XmlRpcUtil.error("XmlRpcServerConnection::writeResponse: empty response."); return(false); } try { MemoryStream memstream = new MemoryStream(); using (StreamWriter writer = new StreamWriter(memstream)) { writer.Write(response); _bytesWritten = response.Length; } try { var buffer = memstream.GetBuffer(); stream.Write(buffer, 0, buffer.Length); } catch (Exception ex) { XmlRpcUtil.error(string.Format("Exception while writing response: {0}", ex.Message)); } } catch (Exception ex) { XmlRpcUtil.error("XmlRpcServerConnection::writeResponse: write error ({0}).", ex.Message); return(false); } /*catch (Exception ex) * { * XmlRpcUtil.error("XmlRpcServerConnection::writeResponse: write error ({0}).", ex.Message); * return false; * }*/ XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.DEBUG, "XmlRpcServerConnection::writeResponse: wrote {0} of {0} bytes.", _bytesWritten, response.Length); // Prepare to read the next request if (_bytesWritten == response.Length) { response = ""; _connectionState = ServerConnectionState.READ_HEADER; } return(_keepAlive); // Continue monitoring this source if true }
/// <summary> /// Either HTTPRequest contains the header AND some data, or it contains part or all of the header. Accumulate pieces /// of the header in case it spans multiple reads. /// </summary> /// <param name="HTTPRequest"></param> /// <returns></returns> public STATUS Append(string HTTPRequest) { if (m_headerStatus != STATUS.COMPLETE_HEADER) { int betweenHeaderAndData = HTTPRequest.IndexOf("\r\n\r\n", StringComparison.OrdinalIgnoreCase); if (betweenHeaderAndData > 0) { m_headerStatus = STATUS.COMPLETE_HEADER; //found the boundary between header and data m_headerSoFar += HTTPRequest.Substring(0, betweenHeaderAndData); HTTPHeaderParse(m_headerSoFar); //shorten the request so we can fall through HTTPRequest = HTTPRequest.Substring(betweenHeaderAndData + 4); // // FALL THROUGH to header complete case // } else { m_headerSoFar += HTTPRequest; m_headerStatus = STATUS.PARTIAL_HEADER; HTTPHeaderParse(m_headerSoFar); return(m_headerStatus); } } if (m_headerStatus == STATUS.COMPLETE_HEADER) { if (ContentComplete) { //this isn't right... restart with empty header and see if it works m_headerStatus = STATUS.UNINITIALIZED; Data = new byte[0]; DataString = ""; m_headerSoFar = ""; m_StrHTTPField.Clear(); return(Append(HTTPRequest)); } DataString += HTTPRequest; if (ContentComplete) { Data = Encoding.ASCII.GetBytes(DataString); XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.INFO, "DONE READING CONTENT"); } } return(m_headerStatus); }
public bool ExecuteCheckDone(XmlRpcValue result) { //result.clear(); // Are we done yet? if (_connectionState != ConnectionState.IDLE) { return(false); } if (!parseResponse(result, header.DataString)) { // Hopefully the caller can determine that parsing failed. } XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.DEBUG, "XmlRpcClient::execute: method completed."); return(true); }
internal override bool readHeader(ref HTTPHeader header) { if (base.readHeader(ref header)) { if (header.m_headerStatus == HTTPHeader.STATUS.COMPLETE_HEADER) { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.DEBUG, "KeepAlive: {0}", _keepAlive); _connectionState = ServerConnectionState.READ_REQUEST; } return(true); } return(false); }
// Close the owned fd public void close() { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.DEBUG, "XmlRpcClient::close."); _connectionState = ConnectionState.NO_CONNECTION; _disp.RemoveSource(this); _disp.Exit(); //_disp.removeSource(this); //XmlRpcSource::close(); if (socket != null) { socket.Close(); //reader = null; //writer = null; } }
private bool writeRequest() { if (_bytesWritten == 0) { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.SPEW, "XmlRpcClient::writeRequest (attempt {0}):\n{1}\n", _sendAttempts + 1, _request); } // Try to write the request try { if (!socket.Connected) { XmlRpcUtil.error("XmlRpcClient::writeRequest not connected"); } MemoryStream memstream = new MemoryStream(); using (StreamWriter writer = new StreamWriter(memstream)) { writer.Write(_request); writer.Flush(); } var stream = socket.GetStream(); try { var buffer = memstream.GetBuffer(); stream.Write(buffer, 0, buffer.Length); stream.Flush(); } catch (Exception ex) { XmlRpcUtil.error(string.Format("Exception while writing request: {0}", ex.Message)); } _bytesWritten = _request.Length; } catch (IOException ex) { XmlRpcUtil.error("Error in XmlRpcClient::writeRequest: write error ({0}).", ex.Message); return(false); } XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.INFO, "XmlRpcClient::writeRequest: wrote {0} of {1} bytes.", _bytesWritten, _request.Length); // Wait for the result if (_bytesWritten == _request.Length) { _connectionState = ConnectionState.READ_HEADER; header = null; } return(true); }
// Execute the named procedure on the remote server. // Params should be an array of the arguments for the method. // Returns true if the request was sent and a result received (although the result // might be a fault). public bool Execute(string method, XmlRpcValue parameters, XmlRpcValue result) { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.SPEW, "XmlRpcClient::Execute: method {0} (_connectionState {0}).", method, _connectionState); lock (this) { //result = null; // This is not a thread-safe operation, if you want to do multithreading, use separate // clients for each thread. If you want to protect yourself from multiple threads // accessing the same client, replace this code with a real mutex. if (_executing) { return(false); } _executing = true; //ClearFlagOnExit cf(_executing); _sendAttempts = 0; _isFault = false; if (!setupConnection()) { _executing = false; return(false); } if (!generateRequest(method, parameters)) { _executing = false; return(false); } double msTime = -1.0; _disp.Work(msTime); if (_connectionState != ConnectionState.IDLE || !parseResponse(result, header.DataString)) { _executing = false; return(false); } XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.DEBUG, "XmlRpcClient::execute: method {0} completed.", method); _executing = false; } _executing = false; return(true); }
// Parse the method name and the argument values from the request. private string parseRequest(XmlRpcValue parms, string _request) { bool success = true; string methodName = "unknown"; //XmlRpcValue result = null; using (XmlReader reader = XmlReader.Create(new StringReader(_request))) { XmlDocument xmldoc = new XmlDocument(); xmldoc.Load(reader); // Parse response xml into result //int offset = 0; XmlNodeList xmlMethodNameList = xmldoc.GetElementsByTagName("methodName"); if (xmlMethodNameList.Count > 0) { XmlNode xmlMethodName = xmlMethodNameList[0]; methodName = xmlMethodName.InnerText; } XmlNodeList xmlParameters = xmldoc.GetElementsByTagName("param"); XmlNodeList xmlFault = xmldoc.GetElementsByTagName("fault"); if (xmlParameters.Count == 0) { XmlRpcUtil.error("Error in XmlRpcServer::parseRequest: Invalid request - no methodResponse. Request:\n{0}", _request); return(null); } parms.SetArray(xmlParameters.Count); for (int i = 0; i < xmlParameters.Count; i++) { var value = new XmlRpcValue(); value.fromXml(xmlParameters[i]["value"]); parms.asArray[i] = value; } if (xmlFault.Count > 0 && parms.fromXml(xmlFault[0])) { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.WARNING, "Read fault on response for request:\n{0}\nFAULT: {1}", _request, parms.ToString()); } } return(methodName); }
// Possible IO states for the connection // XmlRpcSource interface implementation // Handle server responses. Called by the event dispatcher during execute. public override XmlRpcDispatch.EventType HandleEvent(XmlRpcDispatch.EventType eventType) { if (eventType == XmlRpcDispatch.EventType.Exception) { if (_connectionState == ConnectionState.WRITE_REQUEST && _bytesWritten == 0) { XmlRpcUtil.error("Error in XmlRpcClient::handleEvent: could not connect to server ({0}).", getSocketError()); } else { XmlRpcUtil.error("Error in XmlRpcClient::handleEvent (state {0}): {1}.", _connectionState, getSocketError()); } return(0); } if (_connectionState == ConnectionState.WRITE_REQUEST) { if (!writeRequest()) { return(0); } } if (_connectionState == ConnectionState.READ_HEADER) { if (!readHeader(ref header)) { return(0); } } if (_connectionState == ConnectionState.READ_RESPONSE) { if (!readResponse()) { return(0); } } // This should probably always ask for Exception events too return((_connectionState == ConnectionState.WRITE_REQUEST) ? XmlRpcDispatch.EventType.WritableEvent : XmlRpcDispatch.EventType.ReadableEvent); }
private void HTTPHeaderParse(string Header) { #region HTTP HEADER REQUEST & RESPONSE HTTPHeaderField HHField; string HTTPfield = null; int Index; string buffer; for (int f = (int)HTTPHeaderField.Accept; f < (int)HTTPHeaderField.HEADER_VALUE_MAX_PLUS_ONE; f++) { HHField = (HTTPHeaderField)f; HTTPfield = null; if (!HeaderFieldToStrings.TryGetValue(HHField, out HTTPfield) || HTTPField == null) { HTTPfield = "\n" + HHField.ToString().Replace('_', '-') + ": "; HeaderFieldToStrings.Add(HHField, HTTPfield); } // Si le champ n'est pas pr?sent dans la requ?te, on passe au champ suivant Index = Header.IndexOf(HTTPfield, StringComparison.OrdinalIgnoreCase); if (Index == -1) { continue; } buffer = Header.Substring(Index + HTTPfield.Length); Index = buffer.IndexOf("\r\n", StringComparison.OrdinalIgnoreCase); if (Index == -1) { m_StrHTTPField[HHField] = buffer.Trim(); } else { m_StrHTTPField[HHField] = buffer.Substring(0, Index).Trim(); } if (m_StrHTTPField[HHField].Length == 0) { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.WARNING, "HTTP HEADER: field \"{0}\" has a length of 0", HHField.ToString()); } XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.DEBUG, "HTTP HEADER: Index={0} | champ={1} = {2}", f, HTTPfield.Substring(1), m_StrHTTPField[HHField]); } #endregion }
// Accept a client connection request and create a connection to // handle method calls from the client. private void acceptConnection() { bool p = true; // ReSharper disable once CSharpWarnings::CS0665 while (p = listener.Pending()) { try { _disp.AddSource(createConnection(listener.AcceptSocket()), XmlRpcDispatch.EventType.ReadableEvent); XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.WARNING, "XmlRpcServer::acceptConnection: creating a connection"); } catch (SocketException ex) { XmlRpcUtil.error("XmlRpcServer::acceptConnection: Could not accept connection ({0}).", ex.Message); Thread.Sleep(10); } } }
public bool BindAndListen(int port, int backlog) { IPAddress address = new IPAddress(0); // INADDR_ANY try { _port = port; listener = new TcpListener(address, port); listener.Start(backlog); _port = ((IPEndPoint)listener.Server.LocalEndPoint).Port; _disp.AddSource(this, XmlRpcDispatch.EventType.ReadableEvent); //listener.BeginAcceptTcpClient(new AsyncCallback(acceptClient), listener); XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.WARNING, "XmlRpcServer::bindAndListen: server listening on port {0}", _port); } catch (Exception ex) { throw ex; } return(true); }
// Connect to the xmlrpc server private bool doConnect() { if (socket == null) { try { socket = new TcpClient(_host, _port); } catch (SocketException ex) { return(false); } } if (!socket.Connected) { close(); XmlRpcUtil.error("Error in XmlRpcClient::doConnect: Could not connect to server ({0}).", getSocketError()); return(false); } return(true); }
private static void RmRef(ref IntPtr ptr) { lock (reflock) { if (_refs.ContainsKey(ptr)) { #if REFDEBUGWrapper Console.WriteLine("Removing a reference to: " + ptr + " (" + _refs[ptr] + "==> " + (_refs[ptr] - 1) + ")"); #endif _refs[ptr]--; if (_refs[ptr] <= 0) { #if REFDEBUGWrapper Console.WriteLine("KILLING " + ptr + " BECAUSE IT'S NOT VERY NICE!"); #endif _refs.Remove(ptr); XmlRpcUtil.Free(ptr); ptr = IntPtr.Zero; } } } }
private bool readResponse() { int left = header.ContentLength - header.DataString.Length; int dataLen = 0; if (left > 0) { byte[] data = new byte[left]; try { var stream = socket.GetStream(); dataLen = stream.Read(data, 0, left); if (dataLen == 0) { XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.ERROR, "XmlRpcClient::readResponse: Stream was closed"); return(false); } } catch (Exception ex) { XmlRpcUtil.error("XmlRpcClient::readResponse: error while reading the rest of data ({0}).", ex.Message); return(false); } header.Append(Encoding.ASCII.GetString(data, 0, dataLen)); } if (header.ContentComplete) { // Otherwise, parse and dispatch the request XmlRpcUtil.log(XmlRpcUtil.XMLRPC_LOG_LEVEL.INFO, "XmlRpcClient::readResponse read {0} bytes.", _request.Length); _connectionState = ConnectionState.IDLE; return(false); // no need to continue monitoring because we're done reading the response } // Continue monitoring this source return(true); }
// Convert the response xml into a result value private bool parseResponse(XmlRpcValue result, string _response) { bool success = true; //XmlRpcValue result = null; using (XmlReader reader = XmlReader.Create(new StringReader(_response))) { XmlDocument response = new XmlDocument(); response.Load(reader); // Parse response xml into result //int offset = 0; XmlNodeList resp = response.GetElementsByTagName("methodResponse"); XmlNode responseNode = resp[0]; //if (!XmlRpcUtil.findTag(METHODRESPONSE_TAG, _response, out offset)) if (resp.Count == 0) { XmlRpcUtil.error("Error in XmlRpcClient::parseResponse: Invalid response - no methodResponse. Response:\n{0}", _response); return(false); } XmlElement pars = responseNode["params"]; XmlElement fault = responseNode["fault"]; //result = new XmlRpcValue(); if (pars != null) { bool isArray = false; var selection = pars.SelectNodes("param"); if (selection.Count > 1) { result.SetArray(selection.Count); int i = 0; foreach (XmlNode par in selection) { var value = new XmlRpcValue(); value.fromXml(par["value"]); result[i++] = value; } } else if (selection.Count == 1) { result.fromXml(selection[0]["value"]); } else { success = false; } } else if (fault != null && result.fromXml(fault)) { success = false; } else { XmlRpcUtil.error("Error in XmlRpcClient::parseResponse: Invalid response - no param or fault tag. Response:\n{0}", _response); } _response = ""; } return(success); }