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.
{ READ_HEADER, READ_REQUEST, WRITE_RESPONSE };
XmlRpcServerConnection::XmlRpcServerConnection | ( | int | fd, | |
XmlRpcServer * | server, | |||
bool | deleteOnClose = false | |||
) |
Constructor.
Definition at line 26 of file XmlRpcServerConnection.cc.
: XmlRpcSource(fd, deleteOnClose) { XmlRpcUtil::log(2,"XmlRpcServerConnection: new socket %d.", fd); _server = server; _connectionState = READ_HEADER; _keepAlive = true; }
XmlRpcServerConnection::~XmlRpcServerConnection | ( | ) | [virtual] |
Destructor.
Definition at line 38 of file XmlRpcServerConnection.cc.
{ XmlRpcUtil::log(4,"XmlRpcServerConnection dtor."); _server->removeConnection(this); }
void XmlRpcServerConnection::executeRequest | ( | ) | [protected, virtual] |
Helper method to execute the client request.
Definition at line 208 of file XmlRpcServerConnection.cc.
Referenced by writeResponse().
{ _response = _server->executeRequest(_request); }
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.
{ if (_connectionState == READ_HEADER) if ( ! readHeader()) return 0; if (_connectionState == READ_REQUEST) if ( ! readRequest()) return 0; if (_connectionState == WRITE_RESPONSE) if ( ! writeResponse()) return 0; return (_connectionState == WRITE_RESPONSE) ? XmlRpcDispatch::WritableEvent : XmlRpcDispatch::ReadableEvent; }
bool XmlRpcServerConnection::readHeader | ( | ) | [protected] |
Reads the http header.
Definition at line 66 of file XmlRpcServerConnection.cc.
Referenced by handleEvent().
{ // Read available data bool eof; if ( ! XmlRpcSocket::nbRead(this->getfd(), _header, &eof, _ssl_ssl)) { // Its only an error if we already have read some data if (_header.length() > 0) XmlRpcUtil::error("XmlRpcServerConnection::readHeader: error while reading header (%s).",XmlRpcSocket::getErrorMsg().c_str()); return false; } XmlRpcUtil::log(4, "XmlRpcServerConnection::readHeader: read %d bytes.", _header.length()); char *hp = (char*)_header.c_str(); // Start of header char *ep = hp + _header.length(); // End of string char *bp = 0; // Start of body char *lp = 0; // Start of content-length value char *kp = 0; // Start of connection value for (char *cp = hp; (bp == 0) && (cp < ep); ++cp) { if ((ep - cp > 16) && (strncasecmp(cp, "Content-length: ", 16) == 0)) lp = cp + 16; else if ((ep - cp > 12) && (strncasecmp(cp, "Connection: ", 12) == 0)) kp = cp + 12; else if ((ep - cp > 4) && (strncmp(cp, "\r\n\r\n", 4) == 0)) bp = cp + 4; else if ((ep - cp > 2) && (strncmp(cp, "\n\n", 2) == 0)) bp = cp + 2; } // If we haven't gotten the entire header yet, return (keep reading) if (bp == 0) { // EOF in the middle of a request is an error, otherwise its ok if (eof) { XmlRpcUtil::log(4, "XmlRpcServerConnection::readHeader: EOF"); if (_header.length() > 0) XmlRpcUtil::error("XmlRpcServerConnection::readHeader: EOF while reading header"); return false; // Either way we close the connection } return true; // Keep reading } // Decode content length if (lp == 0) { XmlRpcUtil::error("XmlRpcServerConnection::readHeader: No Content-length specified"); return false; // We could try to figure it out by parsing as we read, but for now... } _contentLength = atoi(lp); if (_contentLength <= 0) { XmlRpcUtil::error("XmlRpcServerConnection::readHeader: Invalid Content-length specified (%d).", _contentLength); return false; } XmlRpcUtil::log(3, "XmlRpcServerConnection::readHeader: specified content length is %d.", _contentLength); // Otherwise copy non-header data to request buffer and set state to read request. _request = bp; // Parse out any interesting bits from the header (HTTP version, connection) _keepAlive = true; if (_header.find("HTTP/1.0") != std::string::npos) { if (kp == 0 || strncasecmp(kp, "keep-alive", 10) != 0) _keepAlive = false; // Default for HTTP 1.0 is to close the connection } else { if (kp != 0 && strncasecmp(kp, "close", 5) == 0) _keepAlive = false; } XmlRpcUtil::log(3, "KeepAlive: %d", _keepAlive); _header = ""; _connectionState = READ_REQUEST; return true; // Continue monitoring this source }
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().
{ // If we dont have the entire request yet, read available data if (int(_request.length()) < _contentLength) { bool eof; if ( ! XmlRpcSocket::nbRead(this->getfd(), _request, &eof, _ssl_ssl)) { XmlRpcUtil::error("XmlRpcServerConnection::readRequest: read error (%s).",XmlRpcSocket::getErrorMsg().c_str()); return false; } // If we haven't gotten the entire request yet, return (keep reading) if (int(_request.length()) < _contentLength) { if (eof) { XmlRpcUtil::error("XmlRpcServerConnection::readRequest: EOF while reading request"); return false; // Either way we close the connection } return true; } } // Otherwise, parse and dispatch the request XmlRpcUtil::log(3, "XmlRpcServerConnection::readRequest read %d bytes.", _request.length()); //XmlRpcUtil::log(5, "XmlRpcServerConnection::readRequest:\n%s\n", _request.c_str()); _connectionState = WRITE_RESPONSE; return true; // Continue monitoring this source }
bool XmlRpcServerConnection::writeResponse | ( | ) | [protected] |
Executes the request and writes the resulting response.
Definition at line 177 of file XmlRpcServerConnection.cc.
Referenced by handleEvent().
{ if (_response.length() == 0) { executeRequest(); _bytesWritten = 0; if (_response.length() == 0) { XmlRpcUtil::error("XmlRpcServerConnection::writeResponse: empty response."); return false; } } // Try to write the response if ( ! XmlRpcSocket::nbWrite(this->getfd(), _response, &_bytesWritten, _ssl_ssl)) { XmlRpcUtil::error("XmlRpcServerConnection::writeResponse: write error (%s).",XmlRpcSocket::getErrorMsg().c_str()); return false; } XmlRpcUtil::log(3, "XmlRpcServerConnection::writeResponse: wrote %d of %d bytes.", _bytesWritten, _response.length()); // Prepare to read the next request if (_bytesWritten == int(_response.length())) { _header = ""; _request = ""; _response = ""; _connectionState = READ_HEADER; } return _keepAlive; // Continue monitoring this source if true }
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().