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 }
// 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); }
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())); }
//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(); }
// 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); }
// 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); }
// 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; }
// 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); }
// 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); }
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); }
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; } }
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); }
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); }
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 }
// 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); }
// 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); }
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); }