XmlRpc::XmlRpcServerConnection Class Reference

A class to handle XML RPC requests from a particular client. More...

#include <XmlRpcServerConnection.h>

Inheritance diagram for XmlRpc::XmlRpcServerConnection:
XmlRpc::XmlRpcSource

List of all members.

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.

Detailed Description

A class to handle XML RPC requests from a particular client.

Definition at line 31 of file XmlRpcServerConnection.h.


Member Enumeration Documentation

Possible IO states for the connection.

Enumerator:
READ_HEADER 
READ_REQUEST 
WRITE_RESPONSE 

Definition at line 64 of file XmlRpcServerConnection.h.


Constructor & Destructor Documentation

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 }


Member Function Documentation

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.

Parameters:
eventType Type of IO event that occurred.
See also:
XmlRpcDispatch::EventType.

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 }


Member Data Documentation

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().

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().

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().

Request body.

Definition at line 75 of file XmlRpcServerConnection.h.

Referenced by executeRequest(), readHeader(), readRequest(), and writeResponse().

Response.

Definition at line 78 of file XmlRpcServerConnection.h.

Referenced by executeRequest(), and writeResponse().

The XmlRpc server that accepted this connection.

Definition at line 61 of file XmlRpcServerConnection.h.

Referenced by executeRequest(), XmlRpcServerConnection(), and ~XmlRpcServerConnection().


The documentation for this class was generated from the following files:
Generated on Wed May 26 16:21:20 2010 for OverSim by  doxygen 1.6.3