A class to handle XML RPC requests from a particular client. More...
#include <XmlRpcServerConnection.h>
Public Member Functions | |
XmlRpcServerConnection (int fd, XmlRpcServer *server, bool deleteOnClose=false) | |
Constructor. | |
virtual | ~XmlRpcServerConnection () |
Destructor. | |
virtual unsigned | handleEvent (unsigned eventType) |
Handle IO on the client connection socket. | |
Protected Types | |
enum | ServerConnectionState { READ_HEADER, READ_REQUEST, WRITE_RESPONSE } |
Possible IO states for the connection. More... | |
Protected Member Functions | |
bool | readHeader () |
Reads the http header. | |
bool | readRequest () |
Reads the request (based on the content-length header value). | |
bool | writeResponse () |
Executes the request and writes the resulting response. | |
virtual void | executeRequest () |
Helper method to execute the client request. | |
Protected Attributes | |
XmlRpcServer * | _server |
The XmlRpc server that accepted this connection. | |
ServerConnectionState | _connectionState |
Current IO state for the connection. | |
std::string | _header |
Request headers. | |
int | _contentLength |
Number of bytes expected in the request body (parsed from header). | |
std::string | _request |
Request body. | |
std::string | _response |
Response. | |
int | _bytesWritten |
Number of bytes of the response written so far. | |
bool | _keepAlive |
Whether to keep the current client connection open for further requests. |
A class to handle XML RPC requests from a particular client.
Definition at line 31 of file XmlRpcServerConnection.h.
enum XmlRpc::XmlRpcServerConnection::ServerConnectionState [protected] |
Possible IO states for the connection.
Definition at line 64 of file XmlRpcServerConnection.h.
00064 { READ_HEADER, READ_REQUEST, WRITE_RESPONSE };
XmlRpcServerConnection::XmlRpcServerConnection | ( | int | fd, | |
XmlRpcServer * | server, | |||
bool | deleteOnClose = false | |||
) |
Constructor.
Definition at line 26 of file XmlRpcServerConnection.cc.
00029 : 00030 XmlRpcSource(fd, deleteOnClose) 00031 { 00032 XmlRpcUtil::log(2,"XmlRpcServerConnection: new socket %d.", fd); 00033 _server = server; 00034 _connectionState = READ_HEADER; 00035 _keepAlive = true; }
XmlRpcServerConnection::~XmlRpcServerConnection | ( | ) | [virtual] |
Destructor.
Definition at line 38 of file XmlRpcServerConnection.cc.
00039 { 00040 XmlRpcUtil::log(4,"XmlRpcServerConnection dtor."); 00041 _server->removeConnection(this); 00042 }
void XmlRpcServerConnection::executeRequest | ( | ) | [protected, virtual] |
Helper method to execute the client request.
Definition at line 208 of file XmlRpcServerConnection.cc.
Referenced by writeResponse().
00209 { 00210 _response = _server->executeRequest(_request); 00211 }
unsigned XmlRpcServerConnection::handleEvent | ( | unsigned | eventType | ) | [virtual] |
Handle IO on the client connection socket.
eventType | Type of IO event that occurred. |
Implements XmlRpc::XmlRpcSource.
Definition at line 49 of file XmlRpcServerConnection.cc.
00050 { 00051 if (_connectionState == READ_HEADER) 00052 if ( ! readHeader()) return 0; 00053 00054 if (_connectionState == READ_REQUEST) 00055 if ( ! readRequest()) return 0; 00056 00057 if (_connectionState == WRITE_RESPONSE) 00058 if ( ! writeResponse()) return 0; 00059 00060 return (_connectionState == WRITE_RESPONSE) 00061 ? XmlRpcDispatch::WritableEvent : XmlRpcDispatch::ReadableEvent; 00062 }
bool XmlRpcServerConnection::readHeader | ( | ) | [protected] |
Reads the http header.
Definition at line 66 of file XmlRpcServerConnection.cc.
Referenced by handleEvent().
00067 { 00068 // Read available data 00069 bool eof; 00070 if ( ! XmlRpcSocket::nbRead(this->getfd(), _header, &eof, _ssl_ssl)) { 00071 // Its only an error if we already have read some data 00072 if (_header.length() > 0) 00073 XmlRpcUtil::error("XmlRpcServerConnection::readHeader: error while reading header (%s).",XmlRpcSocket::getErrorMsg().c_str()); 00074 return false; 00075 } 00076 00077 XmlRpcUtil::log(4, "XmlRpcServerConnection::readHeader: read %d bytes.", _header.length()); 00078 char *hp = (char*)_header.c_str(); // Start of header 00079 char *ep = hp + _header.length(); // End of string 00080 char *bp = 0; // Start of body 00081 char *lp = 0; // Start of content-length value 00082 char *kp = 0; // Start of connection value 00083 00084 for (char *cp = hp; (bp == 0) && (cp < ep); ++cp) { 00085 if ((ep - cp > 16) && (strncasecmp(cp, "Content-length: ", 16) == 0)) 00086 lp = cp + 16; 00087 else if ((ep - cp > 12) && (strncasecmp(cp, "Connection: ", 12) == 0)) 00088 kp = cp + 12; 00089 else if ((ep - cp > 4) && (strncmp(cp, "\r\n\r\n", 4) == 0)) 00090 bp = cp + 4; 00091 else if ((ep - cp > 2) && (strncmp(cp, "\n\n", 2) == 0)) 00092 bp = cp + 2; 00093 } 00094 00095 // If we haven't gotten the entire header yet, return (keep reading) 00096 if (bp == 0) { 00097 // EOF in the middle of a request is an error, otherwise its ok 00098 if (eof) { 00099 XmlRpcUtil::log(4, "XmlRpcServerConnection::readHeader: EOF"); 00100 if (_header.length() > 0) 00101 XmlRpcUtil::error("XmlRpcServerConnection::readHeader: EOF while reading header"); 00102 return false; // Either way we close the connection 00103 } 00104 00105 return true; // Keep reading 00106 } 00107 00108 // Decode content length 00109 if (lp == 0) { 00110 XmlRpcUtil::error("XmlRpcServerConnection::readHeader: No Content-length specified"); 00111 return false; // We could try to figure it out by parsing as we read, but for now... 00112 } 00113 00114 _contentLength = atoi(lp); 00115 if (_contentLength <= 0) { 00116 XmlRpcUtil::error("XmlRpcServerConnection::readHeader: Invalid Content-length specified (%d).", _contentLength); 00117 return false; 00118 } 00119 00120 XmlRpcUtil::log(3, "XmlRpcServerConnection::readHeader: specified content length is %d.", _contentLength); 00121 00122 // Otherwise copy non-header data to request buffer and set state to read request. 00123 _request = bp; 00124 00125 // Parse out any interesting bits from the header (HTTP version, connection) 00126 _keepAlive = true; 00127 if (_header.find("HTTP/1.0") != std::string::npos) { 00128 if (kp == 0 || strncasecmp(kp, "keep-alive", 10) != 0) 00129 _keepAlive = false; // Default for HTTP 1.0 is to close the connection 00130 } else { 00131 if (kp != 0 && strncasecmp(kp, "close", 5) == 0) 00132 _keepAlive = false; 00133 } 00134 XmlRpcUtil::log(3, "KeepAlive: %d", _keepAlive); 00135 00136 00137 _header = ""; 00138 _connectionState = READ_REQUEST; 00139 return true; // Continue monitoring this source 00140 }
bool XmlRpcServerConnection::readRequest | ( | ) | [protected] |
Reads the request (based on the content-length header value).
Definition at line 145 of file XmlRpcServerConnection.cc.
Referenced by handleEvent().
00146 { 00147 // If we dont have the entire request yet, read available data 00148 if (int(_request.length()) < _contentLength) { 00149 bool eof; 00150 if ( ! XmlRpcSocket::nbRead(this->getfd(), _request, &eof, _ssl_ssl)) { 00151 XmlRpcUtil::error("XmlRpcServerConnection::readRequest: read error (%s).",XmlRpcSocket::getErrorMsg().c_str()); 00152 return false; 00153 } 00154 00155 // If we haven't gotten the entire request yet, return (keep reading) 00156 if (int(_request.length()) < _contentLength) { 00157 if (eof) { 00158 XmlRpcUtil::error("XmlRpcServerConnection::readRequest: EOF while reading request"); 00159 return false; // Either way we close the connection 00160 } 00161 return true; 00162 } 00163 } 00164 00165 // Otherwise, parse and dispatch the request 00166 XmlRpcUtil::log(3, "XmlRpcServerConnection::readRequest read %d bytes.", _request.length()); 00167 //XmlRpcUtil::log(5, "XmlRpcServerConnection::readRequest:\n%s\n", _request.c_str()); 00168 00169 _connectionState = WRITE_RESPONSE; 00170 00171 return true; // Continue monitoring this source 00172 }
bool XmlRpcServerConnection::writeResponse | ( | ) | [protected] |
Executes the request and writes the resulting response.
Definition at line 177 of file XmlRpcServerConnection.cc.
Referenced by handleEvent().
00178 { 00179 if (_response.length() == 0) { 00180 executeRequest(); 00181 _bytesWritten = 0; 00182 if (_response.length() == 0) { 00183 XmlRpcUtil::error("XmlRpcServerConnection::writeResponse: empty response."); 00184 return false; 00185 } 00186 } 00187 00188 // Try to write the response 00189 if ( ! XmlRpcSocket::nbWrite(this->getfd(), _response, &_bytesWritten, _ssl_ssl)) { 00190 XmlRpcUtil::error("XmlRpcServerConnection::writeResponse: write error (%s).",XmlRpcSocket::getErrorMsg().c_str()); 00191 return false; 00192 } 00193 XmlRpcUtil::log(3, "XmlRpcServerConnection::writeResponse: wrote %d of %d bytes.", _bytesWritten, _response.length()); 00194 00195 // Prepare to read the next request 00196 if (_bytesWritten == int(_response.length())) { 00197 _header = ""; 00198 _request = ""; 00199 _response = ""; 00200 _connectionState = READ_HEADER; 00201 } 00202 00203 return _keepAlive; // Continue monitoring this source if true 00204 }
int XmlRpc::XmlRpcServerConnection::_bytesWritten [protected] |
Number of bytes of the response written so far.
Definition at line 81 of file XmlRpcServerConnection.h.
Referenced by writeResponse().
Current IO state for the connection.
Definition at line 66 of file XmlRpcServerConnection.h.
Referenced by handleEvent(), readHeader(), readRequest(), writeResponse(), and XmlRpcServerConnection().
int XmlRpc::XmlRpcServerConnection::_contentLength [protected] |
Number of bytes expected in the request body (parsed from header).
Definition at line 72 of file XmlRpcServerConnection.h.
Referenced by readHeader(), and readRequest().
std::string XmlRpc::XmlRpcServerConnection::_header [protected] |
Request headers.
Definition at line 69 of file XmlRpcServerConnection.h.
Referenced by readHeader(), and writeResponse().
bool XmlRpc::XmlRpcServerConnection::_keepAlive [protected] |
Whether to keep the current client connection open for further requests.
Definition at line 84 of file XmlRpcServerConnection.h.
Referenced by readHeader(), writeResponse(), and XmlRpcServerConnection().
std::string XmlRpc::XmlRpcServerConnection::_request [protected] |
Request body.
Definition at line 75 of file XmlRpcServerConnection.h.
Referenced by executeRequest(), readHeader(), readRequest(), and writeResponse().
std::string XmlRpc::XmlRpcServerConnection::_response [protected] |
Response.
Definition at line 78 of file XmlRpcServerConnection.h.
Referenced by executeRequest(), and writeResponse().
XmlRpcServer* XmlRpc::XmlRpcServerConnection::_server [protected] |
The XmlRpc server that accepted this connection.
Definition at line 61 of file XmlRpcServerConnection.h.
Referenced by executeRequest(), XmlRpcServerConnection(), and ~XmlRpcServerConnection().