aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgoodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164>2001-11-21 14:42:31 +0000
committergoodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164>2001-11-21 14:42:31 +0000
commitcc7c56cde014daa6e0d745cec28fc6d2e6a40179 (patch)
tree7ecdaa120001633183a9bfb80e6af97f47e24e4b
parent75b21bc034b2b5e657c13d1537f1478ec7a9ba11 (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.c103
1 files changed, 86 insertions, 17 deletions
diff --git a/src/http.c b/src/http.c
index 7daa41a..fa5fa05 100644
--- a/src/http.c
+++ b/src/http.c
@@ -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;
}