From a55a225899dbd47dd4238adf3a49f62846cb87f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Frings-F=C3=BCrst?= Date: Mon, 14 Dec 2015 06:48:14 +0100 Subject: Imported Upstream version 1.0.0 --- src/bitz/worker.cpp | 139 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 98 insertions(+), 41 deletions(-) (limited to 'src/bitz/worker.cpp') 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 */ -- cgit v1.2.3