diff options
| -rw-r--r-- | src/connectionmanager.cpp | 37 | ||||
| -rw-r--r-- | src/connectionmanager.h | 29 | ||||
| -rw-r--r-- | 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 ) | |||
| 46 | /* Create the socket and set it up to accept connections. */ | 46 | /* Create the socket and set it up to accept connections. */ |
| 47 | struct sockaddr_in name; | 47 | struct sockaddr_in name; |
| 48 | 48 | ||
| 49 | /* Create the socket. */ | ||
| 50 | int nMasterSocket = socket (PF_INET, SOCK_STREAM, 0); | ||
| 51 | if (nMasterSocket < 0) | ||
| 52 | { | ||
| 53 | xLog.LineLog( MultiLog::LError, "Couldn't create a listen socket."); | ||
| 54 | return false; | ||
| 55 | } | ||
| 56 | |||
| 57 | /* Give the socket a name. */ | 49 | /* Give the socket a name. */ |
| 58 | name.sin_family = AF_INET; | 50 | name.sin_family = AF_INET; |
| 59 | name.sin_port = htons( nPort ); | 51 | name.sin_port = htons( nPort ); |
| @@ -62,6 +54,33 @@ bool ConnectionManager::startServer( int nPort ) | |||
| 62 | // a good thing to make configurable later on | 54 | // a good thing to make configurable later on |
| 63 | name.sin_addr.s_addr = htonl( INADDR_ANY ); | 55 | name.sin_addr.s_addr = htonl( INADDR_ANY ); |
| 64 | 56 | ||
| 57 | return startServer( name ); | ||
| 58 | } | ||
| 59 | |||
| 60 | bool ConnectionManager::startServer( const char *sAddr, int nPort ) | ||
| 61 | { | ||
| 62 | /* Create the socket and set it up to accept connections. */ | ||
| 63 | struct sockaddr_in name; | ||
| 64 | |||
| 65 | /* Give the socket a name. */ | ||
| 66 | name.sin_family = AF_INET; | ||
| 67 | name.sin_port = htons( nPort ); | ||
| 68 | |||
| 69 | inet_aton( sAddr, &name.sin_addr ); | ||
| 70 | |||
| 71 | return startServer( name ); | ||
| 72 | } | ||
| 73 | |||
| 74 | bool ConnectionManager::startServer( struct sockaddr_in &name ) | ||
| 75 | { | ||
| 76 | /* Create the socket. */ | ||
| 77 | int nMasterSocket = socket (PF_INET, SOCK_STREAM, 0); | ||
| 78 | if (nMasterSocket < 0) | ||
| 79 | { | ||
| 80 | xLog.LineLog( MultiLog::LError, "Couldn't create a listen socket."); | ||
| 81 | return false; | ||
| 82 | } | ||
| 83 | |||
| 65 | int opt = 1; | 84 | int opt = 1; |
| 66 | setsockopt( | 85 | setsockopt( |
| 67 | nMasterSocket, | 86 | nMasterSocket, |
| @@ -86,7 +105,7 @@ bool ConnectionManager::startServer( int nPort ) | |||
| 86 | /* Initialize the set of active sockets. */ | 105 | /* Initialize the set of active sockets. */ |
| 87 | FD_SET (nMasterSocket, &fdActive); | 106 | FD_SET (nMasterSocket, &fdActive); |
| 88 | 107 | ||
| 89 | sMasterSocket[nMasterSocket] = nPort; | 108 | sMasterSocket[nMasterSocket] = name.sin_port; |
| 90 | 109 | ||
| 91 | return true; | 110 | return true; |
| 92 | } | 111 | } |
diff --git a/src/connectionmanager.h b/src/connectionmanager.h index e80119b..cff036b 100644 --- a/src/connectionmanager.h +++ b/src/connectionmanager.h | |||
| @@ -37,15 +37,40 @@ public: | |||
| 37 | 37 | ||
| 38 | /** | 38 | /** |
| 39 | * Starts a server socket and binds to it, listening for new connections. | 39 | * Starts a server socket and binds to it, listening for new connections. |
| 40 | * Unlike the version of this that takes two parameters, this listens on | ||
| 41 | * all local addresses, or the virtual 0.0.0.0 address if available, which | ||
| 42 | * is mapped to all active local addresses. | ||
| 40 | *@param nPort The port to listen on. | 43 | *@param nPort The port to listen on. |
| 41 | *@param nInitPool The size of the initial connection pool. This will | ||
| 42 | * grow automatically if necesarry. | ||
| 43 | *@returns True if the socket was bound to the port and serving was | 44 | *@returns True if the socket was bound to the port and serving was |
| 44 | * started. False if there was a problem connecting to the port. | 45 | * started. False if there was a problem connecting to the port. |
| 45 | */ | 46 | */ |
| 46 | bool startServer( int nPort ); | 47 | bool startServer( int nPort ); |
| 47 | 48 | ||
| 48 | /** | 49 | /** |
| 50 | * Starts a server socket and binds to it, listening only on the address | ||
| 51 | * specified. If you want to listen to all local addresses you can enter | ||
| 52 | * "0.0.0.0" for the address, but the version of this with one parameter | ||
| 53 | * is more universal. | ||
| 54 | *@param sAddr The local ip address to bind to | ||
| 55 | *@param nPort The port to listen on. | ||
| 56 | *@returns True if the socket was bound to the port and serving was | ||
| 57 | * started. False if there was a problem connecting to the port. | ||
| 58 | */ | ||
| 59 | bool startServer( const char *sAddr, int nPort ); | ||
| 60 | |||
| 61 | /** | ||
| 62 | * I recomend probably not using this function on your own too much, it | ||
| 63 | * does the real work of setting up a socket, but requires a properly | ||
| 64 | * prepared sackaddr_in structure. This isn't too hard, but it's easier | ||
| 65 | * to use the other startServer functions. They call this function after | ||
| 66 | * some prepwork. | ||
| 67 | *@param name A properly formed sockaddr_in structure that will not be | ||
| 68 | * modified, but describes how to listen and to what to listen. | ||
| 69 | *@returns True on success. | ||
| 70 | */ | ||
| 71 | bool startServer( struct sockaddr_in &name ); | ||
| 72 | |||
| 73 | /** | ||
| 49 | * This is identicle to the simpler startServer function except that it | 74 | * This is identicle to the simpler startServer function except that it |
| 50 | * will automatically try to connect multiple times in case the first | 75 | * will automatically try to connect multiple times in case the first |
| 51 | * attempt or two doesn't work for some reason. Initially this was | 76 | * attempt or two doesn't work for some reason. Initially this was |
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 @@ | |||
| 1 | #include "httpconnectionmonitor.h" | 1 | #include "httpconnectionmonitor.h" |
| 2 | #include "http.h" | 2 | #include "http.h" |
| 3 | #include "exceptions.h" | ||
| 3 | #include <sys/stat.h> | 4 | #include <sys/stat.h> |
| 4 | 5 | ||
| 5 | HttpConnectionMonitor::HttpConnectionMonitor() | 6 | HttpConnectionMonitor::HttpConnectionMonitor() |
| @@ -14,62 +15,69 @@ bool HttpConnectionMonitor::onNewConnection( Connection *pCon, int nPort ) | |||
| 14 | { | 15 | { |
| 15 | printf("Got connection on port %d\n", nPort ); | 16 | printf("Got connection on port %d\n", nPort ); |
| 16 | 17 | ||
| 17 | pCon->readInput( 60, 0 ); | 18 | try |
| 18 | printf("#######################\n%s\n#######################\n", pCon->getInput() ); | 19 | { |
| 20 | pCon->readInput( 60, 0 ); | ||
| 21 | printf("#######################\n%s\n#######################\n", pCon->getInput() ); | ||
| 19 | 22 | ||
| 20 | Http hp( pCon ); | 23 | Http hp( pCon ); |
| 21 | while( hp.parseRequest() == false ); | 24 | while( hp.parseRequest() == false ); |
| 22 | printf("Done parsing.\n\n"); | 25 | printf("Done parsing.\n\n"); |
| 23 | 26 | ||
| 24 | if( hp.getRequestType() == Http::reqGet ) | 27 | if( hp.getRequestType() == Http::reqGet ) |
| 25 | { | ||
| 26 | printf("\"\"\"%s\"\"\"\n", hp.getRequestURI() ); | ||
| 27 | if( !strcmp( hp.getRequestURI(), "/" ) ) | ||
| 28 | { | 28 | { |
| 29 | 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>"); | 29 | printf("\"\"\"%s\"\"\"\n", hp.getRequestURI() ); |
| 30 | hp.buildResponse(); | 30 | if( !strcmp( hp.getRequestURI(), "/" ) ) |
| 31 | hp.setResponseContent( | 31 | { |
| 32 | "text/html", | 32 | 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>"); |
| 33 | content.c_str(), | 33 | hp.buildResponse(); |
| 34 | content.size() | 34 | hp.setResponseContent( |
| 35 | ); | 35 | "text/html", |
| 36 | hp.sendResponse(); | 36 | content.c_str(), |
| 37 | content.size() | ||
| 38 | ); | ||
| 39 | hp.sendResponse(); | ||
| 40 | } | ||
| 41 | else | ||
| 42 | { | ||
| 43 | 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>"); | ||
| 44 | hp.buildResponse( 404, "File not found."); | ||
| 45 | hp.setResponseContent( | ||
| 46 | "text/html", | ||
| 47 | content.c_str(), | ||
| 48 | content.size() | ||
| 49 | ); | ||
| 50 | hp.sendResponse(); | ||
| 51 | } | ||
| 37 | } | 52 | } |
| 38 | else | 53 | else |
| 39 | { | 54 | { |
| 40 | 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>"); | 55 | printf("Non get: %s\n", hp.getRequestTypeStr() ); |
| 41 | hp.buildResponse( 404, "File not found."); | 56 | pCon->appendOutput("HTTP/1.1 100 Continue\r\n\r\n"); |
| 42 | hp.setResponseContent( | ||
| 43 | "text/html", | ||
| 44 | content.c_str(), | ||
| 45 | content.size() | ||
| 46 | ); | ||
| 47 | hp.sendResponse(); | ||
| 48 | } | 57 | } |
| 58 | pCon->writeOutput(); | ||
| 59 | //for( int j = 0; j < 50; j++ ) | ||
| 60 | { | ||
| 61 | pCon->readInput( 1, 0 ); | ||
| 62 | //printf("Size so far: %d\n", pCon->getInputAmnt() ); | ||
| 63 | } | ||
| 64 | |||
| 65 | if( pCon->hasInput() ) | ||
| 66 | { | ||
| 67 | std::string s( pCon->getInput(), pCon->getInputAmnt() ); | ||
| 68 | |||
| 69 | pCon->printInputDebug(); | ||
| 70 | //printf("Reamining data\n==============\n%s\n==============\n", | ||
| 71 | // s.c_str() ); | ||
| 72 | } | ||
| 73 | |||
| 74 | pCon->disconnect(); | ||
| 49 | } | 75 | } |
| 50 | else | 76 | catch( ConnectionException &e ) |
| 51 | { | ||
| 52 | printf("Non get: %s\n", hp.getRequestTypeStr() ); | ||
| 53 | pCon->appendOutput("HTTP/1.1 100 Continue\r\n\r\n"); | ||
| 54 | } | ||
| 55 | pCon->writeOutput(); | ||
| 56 | //for( int j = 0; j < 50; j++ ) | ||
| 57 | { | ||
| 58 | pCon->readInput( 1, 0 ); | ||
| 59 | //printf("Size so far: %d\n", pCon->getInputAmnt() ); | ||
| 60 | } | ||
| 61 | |||
| 62 | if( pCon->hasInput() ) | ||
| 63 | { | 77 | { |
| 64 | std::string s( pCon->getInput(), pCon->getInputAmnt() ); | 78 | printf("Connection: %s\n", e.what() ); |
| 65 | |||
| 66 | pCon->printInputDebug(); | ||
| 67 | //printf("Reamining data\n==============\n%s\n==============\n", | ||
| 68 | // s.c_str() ); | ||
| 69 | } | 79 | } |
| 70 | 80 | ||
| 71 | pCon->disconnect(); | ||
| 72 | |||
| 73 | return true; | 81 | return true; |
| 74 | } | 82 | } |
| 75 | 83 | ||
