summaryrefslogtreecommitdiff
path: root/src/bitz/worker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bitz/worker.cpp')
-rw-r--r--src/bitz/worker.cpp139
1 files changed, 98 insertions, 41 deletions
diff --git a/src/bitz/worker.cpp b/src/bitz/worker.cpp
index efbeef3..42fb3d0 100644
--- a/src/bitz/worker.cpp
+++ b/src/bitz/worker.cpp
@@ -51,65 +51,51 @@ namespace bitz {
}
- void Worker::run( socketlibrary::TCPServerSocket * server_sock, unsigned int max_requests ) throw() {
+ void Worker::run( psocksxx::tcpnsockstream * server_sock, unsigned int max_requests,
+ unsigned int comm_timeout ) throw() {
+ // logger
Logger &logger = Logger::instance();
- socketlibrary::TCPSocket * client_sock;
- icap::RequestHeader * req_header;
- icap::Response * response;
- RequestHandler * req_handler;
-
+ // client socket stream
+ psocksxx::nsockstream * client_sock;
- try {
+ while ( max_requests > 0 ) {
- while ( max_requests > 0 ) {
+ logger.debug( std::string( "[worker] waiting for a connection" ) );
- logger.debug( std::string( "[worker] waiting for a connection" ) );
+ try {
+ // accept a client connection
client_sock = server_sock->accept();
- logger.debug( std::string( "[worker] new connection accepted on " ).append( client_sock->getForeignAddress() )
- .append( ":" ).append( util::itoa( client_sock->getForeignPort() ) ) );
-
- // request header
- req_header = icap::util::read_req_header( client_sock );
- logger.debug( std::string( "[worker] request header:\r\n" ).append( req_header->raw_data() ) );
-
- // try to find a handler for the request
- req_handler = util::find_req_handler( _req_handlers, req_header->method() );
-
- if ( req_handler != NULL ) {
- logger.debug( std::string( "[worker] handling request: " ).append( req_header->method() ) );
-
- // process the request and grab the response
- response = req_handler->process( req_header, client_sock );
-
- } else {
-
- // unsupported request
- logger.info( std::string( "[worker] unsupported request: " ).append( req_header->method() ) );
- response = new icap::Response( new icap::ResponseHeader( icap::ResponseHeader::NOT_ALLOWED ) );
+ // FIXME: log accepted client details (e.g. address, port etc.)
+ logger.debug( std::string( "[worker] new connection accepted on [...]" ) );
+ // set timeout value
+ if ( comm_timeout > 0 ) {
+ client_sock->timeout( comm_timeout, 0 );
+ // TODO: add debug logging
}
- // send the response back to the client
- icap::util::send_response( response, client_sock );
+ } catch ( psocksxx::sockexception &e ) {
- // cleanup
- delete response;
- delete req_header;
-
- // destroy / close connection
- delete client_sock;
+ // failed to accept client connection
+ logger.error( std::string( "[worker] failed to accept connection: " ).append( e.what() ) );
+ // update request count
max_requests--;
+ continue;
}
- } catch( socketlibrary::SocketException &sex ) {
- logger.error( std::string( "[worker] ERROR: " ).append( sex.what() ) );
- }
+ // handle client request(s)
+ max_requests = serve_client( client_sock, max_requests );
+
+ // destroy / close connection
+ delete client_sock;
+
+ };
}
@@ -134,5 +120,76 @@ namespace bitz {
}
+
+ unsigned int Worker::serve_client( psocksxx::nsockstream * client_sock, unsigned int max_requests ) throw() {
+
+ // logger
+ Logger &logger = Logger::instance();
+
+ icap::RequestHeader * req_header = NULL;
+ icap::Response * response;
+ RequestHandler * req_handler;
+
+
+ do {
+
+ // cleanup request header
+ if ( req_header != NULL ) {
+ delete req_header;
+ }
+
+ // request header
+ req_header = icap::util::read_req_header( client_sock );
+ logger.debug( std::string( "[worker] request header:\r\n" ).append( req_header->raw_data() ) );
+
+ // check timeout
+ if ( client_sock->timedout() ) {
+ logger.warn( "[worker] communication timed out..." );
+ return --max_requests;
+ }
+
+ // try to find a handler for the request
+ req_handler = util::find_req_handler( _req_handlers, req_header->method() );
+
+ // sanity check
+ if ( req_handler != NULL ) {
+
+ logger.debug( std::string( "[worker] handling request: " ).append( req_header->method() ) );
+
+ // process the request and grab the response
+ response = req_handler->process( req_header, client_sock );
+
+ } else {
+
+ // unsupported request
+ logger.info( std::string( "[worker] unsupported request: " ).append( req_header->method() ) );
+ response = new icap::Response( new icap::ResponseHeader( icap::ResponseHeader::NOT_ALLOWED ) );
+
+ }
+
+ // FIXME: this should be configurable and should default to close
+ // connection if the client doesn't send a connection header
+ if ( req_header->value( "Connection" ) == "keep-alive" ) {
+ response->header()->attach( "Connection" , "keep-alive" );
+ }
+
+ // send the response back to the client
+ icap::util::send_response( response, client_sock );
+
+ // cleanup
+ delete response;
+
+ } while ( ( --max_requests > 0 ) && ( req_header->value( "Connection" ) == "keep-alive" ) );
+
+
+ // cleanup request header
+ if ( req_header != NULL ) {
+ delete req_header;
+ }
+
+ return max_requests;
+
+ }
+
} /* end of namespace bitz */