From 8a51dd0db9176a56c482ca5cecb5051d2b6848ba Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Tue, 27 Feb 2007 06:41:03 +0000 Subject: This may require slightly more testing, but basically I made ConnectionManager more general, you can now listen to all local addresses (the old way), or individual addressses. --- src/connectionmanager.cpp | 37 ++++++++--- src/connectionmanager.h | 29 ++++++++- src/tests/httpsrv/httpconnectionmonitor.cpp | 98 ++++++++++++++++------------- 3 files changed, 108 insertions(+), 56 deletions(-) diff --git a/src/connectionmanager.cpp b/src/connectionmanager.cpp index ea794a8..ea60b2b 100644 --- a/src/connectionmanager.cpp +++ b/src/connectionmanager.cpp @@ -46,14 +46,6 @@ bool ConnectionManager::startServer( int nPort ) /* Create the socket and set it up to accept connections. */ struct sockaddr_in name; - /* Create the socket. */ - int nMasterSocket = socket (PF_INET, SOCK_STREAM, 0); - if (nMasterSocket < 0) - { - xLog.LineLog( MultiLog::LError, "Couldn't create a listen socket."); - return false; - } - /* Give the socket a name. */ name.sin_family = AF_INET; name.sin_port = htons( nPort ); @@ -62,6 +54,33 @@ bool ConnectionManager::startServer( int nPort ) // a good thing to make configurable later on name.sin_addr.s_addr = htonl( INADDR_ANY ); + return startServer( name ); +} + +bool ConnectionManager::startServer( const char *sAddr, int nPort ) +{ + /* Create the socket and set it up to accept connections. */ + struct sockaddr_in name; + + /* Give the socket a name. */ + name.sin_family = AF_INET; + name.sin_port = htons( nPort ); + + inet_aton( sAddr, &name.sin_addr ); + + return startServer( name ); +} + +bool ConnectionManager::startServer( struct sockaddr_in &name ) +{ + /* Create the socket. */ + int nMasterSocket = socket (PF_INET, SOCK_STREAM, 0); + if (nMasterSocket < 0) + { + xLog.LineLog( MultiLog::LError, "Couldn't create a listen socket."); + return false; + } + int opt = 1; setsockopt( nMasterSocket, @@ -86,7 +105,7 @@ bool ConnectionManager::startServer( int nPort ) /* Initialize the set of active sockets. */ FD_SET (nMasterSocket, &fdActive); - sMasterSocket[nMasterSocket] = nPort; + sMasterSocket[nMasterSocket] = name.sin_port; return true; } diff --git a/src/connectionmanager.h b/src/connectionmanager.h index e80119b..cff036b 100644 --- a/src/connectionmanager.h +++ b/src/connectionmanager.h @@ -37,14 +37,39 @@ public: /** * Starts a server socket and binds to it, listening for new connections. + * Unlike the version of this that takes two parameters, this listens on + * all local addresses, or the virtual 0.0.0.0 address if available, which + * is mapped to all active local addresses. *@param nPort The port to listen on. - *@param nInitPool The size of the initial connection pool. This will - * grow automatically if necesarry. *@returns True if the socket was bound to the port and serving was * started. False if there was a problem connecting to the port. */ bool startServer( int nPort ); + /** + * Starts a server socket and binds to it, listening only on the address + * specified. If you want to listen to all local addresses you can enter + * "0.0.0.0" for the address, but the version of this with one parameter + * is more universal. + *@param sAddr The local ip address to bind to + *@param nPort The port to listen on. + *@returns True if the socket was bound to the port and serving was + * started. False if there was a problem connecting to the port. + */ + bool startServer( const char *sAddr, int nPort ); + + /** + * I recomend probably not using this function on your own too much, it + * does the real work of setting up a socket, but requires a properly + * prepared sackaddr_in structure. This isn't too hard, but it's easier + * to use the other startServer functions. They call this function after + * some prepwork. + *@param name A properly formed sockaddr_in structure that will not be + * modified, but describes how to listen and to what to listen. + *@returns True on success. + */ + bool startServer( struct sockaddr_in &name ); + /** * This is identicle to the simpler startServer function except that it * will automatically try to connect multiple times in case the first diff --git a/src/tests/httpsrv/httpconnectionmonitor.cpp b/src/tests/httpsrv/httpconnectionmonitor.cpp index 451478e..51d82f3 100644 --- a/src/tests/httpsrv/httpconnectionmonitor.cpp +++ b/src/tests/httpsrv/httpconnectionmonitor.cpp @@ -1,5 +1,6 @@ #include "httpconnectionmonitor.h" #include "http.h" +#include "exceptions.h" #include HttpConnectionMonitor::HttpConnectionMonitor() @@ -14,62 +15,69 @@ bool HttpConnectionMonitor::onNewConnection( Connection *pCon, int nPort ) { printf("Got connection on port %d\n", nPort ); - pCon->readInput( 60, 0 ); - printf("#######################\n%s\n#######################\n", pCon->getInput() ); + try + { + pCon->readInput( 60, 0 ); + printf("#######################\n%s\n#######################\n", pCon->getInput() ); - Http hp( pCon ); - while( hp.parseRequest() == false ); - printf("Done parsing.\n\n"); + Http hp( pCon ); + while( hp.parseRequest() == false ); + printf("Done parsing.\n\n"); - if( hp.getRequestType() == Http::reqGet ) - { - printf("\"\"\"%s\"\"\"\n", hp.getRequestURI() ); - if( !strcmp( hp.getRequestURI(), "/" ) ) + if( hp.getRequestType() == Http::reqGet ) { - std::string content("Server Test</test></head><body>This is a test of a new system where all the pages will be more or less dynamic...<br>If you want to try to login, you can do that here:<br><form method=\"post\" action=\"showvars\" enctype=\"multipart/form-data\">Name: <input type=\"text\" name=\"name\"><br>Password: <input type=\"password\" name=\"pass\"><br><input type=\"submit\" name=\"action\" value=\"login\"></form></body></html>"); - hp.buildResponse(); - hp.setResponseContent( - "text/html", - content.c_str(), - content.size() - ); - hp.sendResponse(); + printf("\"\"\"%s\"\"\"\n", hp.getRequestURI() ); + if( !strcmp( hp.getRequestURI(), "/" ) ) + { + std::string content("<html><head><title>Server Test</test></head><body>This is a test of a new system where all the pages will be more or less dynamic...<br>If you want to try to login, you can do that here:<br><form method=\"post\" action=\"showvars\" enctype=\"multipart/form-data\">Name: <input type=\"text\" name=\"name\"><br>Password: <input type=\"password\" name=\"pass\"><br><input type=\"submit\" name=\"action\" value=\"login\"></form></body></html>"); + hp.buildResponse(); + hp.setResponseContent( + "text/html", + content.c_str(), + content.size() + ); + hp.sendResponse(); + } + else + { + std::string content("<html><head><title>URL Not Found</test></head><body>There is no content mapped to the URL you requested. Please try another one.</body></html>"); + hp.buildResponse( 404, "File not found."); + hp.setResponseContent( + "text/html", + content.c_str(), + content.size() + ); + hp.sendResponse(); + } } else { - std::string content("<html><head><title>URL Not Found</test></head><body>There is no content mapped to the URL you requested. Please try another one.</body></html>"); - hp.buildResponse( 404, "File not found."); - hp.setResponseContent( - "text/html", - content.c_str(), - content.size() - ); - hp.sendResponse(); + printf("Non get: %s\n", hp.getRequestTypeStr() ); + pCon->appendOutput("HTTP/1.1 100 Continue\r\n\r\n"); } + pCon->writeOutput(); + //for( int j = 0; j < 50; j++ ) + { + pCon->readInput( 1, 0 ); + //printf("Size so far: %d\n", pCon->getInputAmnt() ); + } + + if( pCon->hasInput() ) + { + std::string s( pCon->getInput(), pCon->getInputAmnt() ); + + pCon->printInputDebug(); + //printf("Reamining data\n==============\n%s\n==============\n", + // s.c_str() ); + } + + pCon->disconnect(); } - else - { - printf("Non get: %s\n", hp.getRequestTypeStr() ); - pCon->appendOutput("HTTP/1.1 100 Continue\r\n\r\n"); - } - pCon->writeOutput(); - //for( int j = 0; j < 50; j++ ) - { - pCon->readInput( 1, 0 ); - //printf("Size so far: %d\n", pCon->getInputAmnt() ); - } - - if( pCon->hasInput() ) + catch( ConnectionException &e ) { - std::string s( pCon->getInput(), pCon->getInputAmnt() ); - - pCon->printInputDebug(); - //printf("Reamining data\n==============\n%s\n==============\n", - // s.c_str() ); + printf("Connection: %s\n", e.what() ); } - pCon->disconnect(); - return true; } -- cgit v1.2.3