diff options
author | goodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164> | 2001-11-21 14:42:31 +0000 |
---|---|---|
committer | goodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164> | 2001-11-21 14:42:31 +0000 |
commit | cc7c56cde014daa6e0d745cec28fc6d2e6a40179 (patch) | |
tree | 7ecdaa120001633183a9bfb80e6af97f47e24e4b | |
parent | 75b21bc034b2b5e657c13d1537f1478ec7a9ba11 (diff) |
Made the HTTP server more compliant with the standard - it now
waits for the \r\n\r\n indicating the end of the HTTP header fields
before beginning to process the request. It currently also does the
same if it gets a \n\n as this is useful for debugging with telnet and
I suspect other servers allow this too.
Tom
git-svn-id: http://svn.cactuscode.org/arrangements/CactusConnect/HTTPD/trunk@142 1faa4e14-9dd3-4be0-9f0e-ffe519881164
-rw-r--r-- | src/http.c | 103 |
1 files changed, 86 insertions, 17 deletions
@@ -7,13 +7,18 @@ @enddesc @version $Header$ @@*/ + +#include "cctk.h" + #include <stdio.h> #include <stdio.h> #include <stdlib.h> -#include <string.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif -#include "cctk.h" +#include <string.h> #include "util_String.h" @@ -57,7 +62,7 @@ static void DestroyArgument(httpArg *argument); ********************************************************************/ #define INITIAL_SIZE 16 -#define MAXMSG 80480 +#define MAXMSG 2048 /******************************************************************** ********************* External Routines ********************** @@ -81,36 +86,95 @@ int HTTP_ReadFromClient(cGH *cctkGH, void *connection) { int retval; int keepalive; - char buffer[MAXMSG]; + char inbuffer[MAXMSG]; int nbytes; httpRequest request; + int request_buffer_length; + char *request_buffer; + char *tmp; + + int found_eoh; + int failure_count; InitialiseRequest(&request); request.connection = connection; - nbytes = HTTP_Read(&request, buffer, MAXMSG); + found_eoh = 0; + failure_count = 0; + request_buffer_length = 0; + request_buffer = NULL; + - if (nbytes < 0) + while(! found_eoh) { - /* Read error. */ - perror ("HTTP_Read"); - CCTK_Abort(cctkGH, EXIT_FAILURE); + nbytes = HTTP_Read(&request, inbuffer, MAXMSG); + + if (nbytes < 0) + { + /* Read error. */ + perror ("HTTP_Read"); + CCTK_WARN(1, "Error reading from socket"); + } + else if (nbytes == 0) + { + CCTK_WARN(1, "Got 0 bytes when waiting for end of HTTP request header"); + if(failure_count < 3) + { + failure_count++; + sleep(1); + } + else + { + /* Give up waiting for this socket */ + CCTK_WARN(1, "Too many failures reading from socket. Giving up."); + request_buffer_length = 0; + break; + } + } + else + { + /* Reallocate space for buffer. + * Add space for one extra char so can null-terminate to allow string search. + */ + tmp = (char *)realloc(request_buffer, (request_buffer_length+nbytes+1)*sizeof(char)); + if(tmp) + { + request_buffer = tmp; + } + else + { + CCTK_WARN(0, "Memory allocation failure."); + } + + /* Copy the new data into the buffer */ + memcpy(request_buffer+request_buffer_length, inbuffer, nbytes); + request_buffer_length += nbytes; + /* Add a null byte in the extra allocated space to allow strstr */ + request_buffer[request_buffer_length] = 0; + + /* Look for end of HTTP header. + * Comment out the check for \n\n for strict compliance, but this is + * useful for debugging with telnet. + */ + if(strstr(request_buffer, "\r\n\r\n") || strstr(request_buffer, "\n\n")) + { + found_eoh = 1; +#ifdef HTTP_DEBUG + fprintf (stderr, "Found end of HTTP header.\n"); +#endif + } + } } - else if (nbytes == 0) - /* End-of-file. */ - return -1; - else + + if(request_buffer_length > 0) { /* Data read. */ #ifdef HTTP_DEBUG fprintf (stderr, "Server: got message: `%s'\n", buffer); #endif - } - if(nbytes > 0) - { - keepalive = DealWithRequest(cctkGH, &request, buffer, nbytes); + keepalive = DealWithRequest(cctkGH, &request, request_buffer, request_buffer_length); } else { @@ -126,6 +190,11 @@ int HTTP_ReadFromClient(cGH *cctkGH, void *connection) retval = -1; } + if(request_buffer) + { + free(request_buffer); + } + return retval; } |