diff options
author | goodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164> | 2000-09-16 14:22:38 +0000 |
---|---|---|
committer | goodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164> | 2000-09-16 14:22:38 +0000 |
commit | 3ab68329120dcbc0a6ceff2dabdd1c6318ae17ab (patch) | |
tree | 36fee834924e9c3c753db5ff440eb68f36428bd6 | |
parent | 21938abcbb2d93a318511fcbe5d0398a3184a2e2 (diff) |
New function HTTP_ArgumentWalk to allow walking through the argument list.
Tom
git-svn-id: http://svn.cactuscode.org/arrangements/CactusConnect/HTTPD/trunk@25 1faa4e14-9dd3-4be0-9f0e-ffe519881164
-rw-r--r-- | src/http.c | 210 | ||||
-rw-r--r-- | src/http_Request.h | 47 |
2 files changed, 224 insertions, 33 deletions
@@ -42,9 +42,11 @@ static int AddHeader(httpRequest *request, const char *line); static int StripArgs(httpRequest *request, char *request_uri); static void Decode(char *string); +static int InitialiseRequest(httpRequest *request); static int ClearRequest(httpRequest *request); static void DestroyHeader(struct httpHeader *header); +static void DestroyArgument(httpArg *argument); /******************************************************************** ********************* Other Routine Prototypes ********************* @@ -77,6 +79,8 @@ static void DestroyHeader(struct httpHeader *header); @@*/ int HTTP_ReadFromClient(cGH *cctkGH, int filedes) { + int retval; + int keepalive; char buffer[MAXMSG]; int nbytes; @@ -100,10 +104,19 @@ int HTTP_ReadFromClient(cGH *cctkGH, int filedes) if(nbytes > 0) { - DealWithRequest(cctkGH, filedes, buffer, nbytes); + keepalive = DealWithRequest(cctkGH, filedes, buffer, nbytes); } - return -1; + if(keepalive) + { + retval = 0; + } + else + { + retval = -1; + } + + return retval; } /*@@ @@ -137,6 +150,34 @@ const char *HTTP_ArgumentValue(const httpRequest *request, const char *arg) } /*@@ + @routine HTTP_ArgumentWalk + @date Sat Sep 16 14:41:01 2000 + @author Tom Goodale + @desc + Walks the argument list. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +const httpArg *HTTP_ArgumentWalk(httpRequest *request, int first) +{ + if(first || ! (request->currentarg)) + { + request->currentarg = request->firstarg; + } + else + { + request->currentarg = request->currentarg->all_next; + } + + return request->currentarg; +} + + /*@@ @routine HTTP_HeaderValue @date Thu Sep 14 19:55:04 2000 @author Tom Goodale @@ -251,6 +292,8 @@ static int DealWithRequest(cGH *cctkGH, int filedes, char *buffer, int bufsize) char *http_version; httpRequest request; + InitialiseRequest(&request); + request.filedes = filedes; tmp = buffer; @@ -296,12 +339,7 @@ static int DealWithRequest(cGH *cctkGH, int filedes, char *buffer, int bufsize) request.method = method; } - else - { - request.method = NULL; - } - request.n_arguments = 0; if(request_uri) { printf("URI: %s\n", request_uri); @@ -309,11 +347,6 @@ static int DealWithRequest(cGH *cctkGH, int filedes, char *buffer, int bufsize) request.uri = request_uri; StripArgs(&request, request.uri); } - else - { - request.uri = NULL; - request.arguments=NULL; - } if(http_version) { @@ -337,9 +370,6 @@ static int DealWithRequest(cGH *cctkGH, int filedes, char *buffer, int bufsize) printf("Start of request header\n"); #endif - request.body = NULL; - request.headers = NULL; - while(line = NextLine(tmp, &start, bufsize)) { if(! request.body && *line != 0) @@ -502,8 +532,9 @@ static int StripArgs(httpRequest *request, char *request_uri) char *position; char *token; char *value; - char *storable; - + httpArg *argument; + httpArg *stored; + httpArg *last; /* Do we have arguments ? */ if((position = strchr(request_uri, '?'))) { @@ -532,18 +563,49 @@ static int StripArgs(httpRequest *request, char *request_uri) Decode(token); Decode(value); - storable = Util_Strdup(value); + argument = (httpArg *)malloc(sizeof(httpArg)); - if(Util_HashData(request->arguments, strlen(token), token, 0)) + if(argument) { -#ifdef HTTP_DEBUG - fprintf(stderr, "Ignoring duplicate argument '%s'\n", token); -#endif + argument->next = NULL; + argument->all_next = NULL; + argument->arg = Util_Strdup(token); + argument->value = Util_Strdup(value); + + if((stored = (httpArg *)Util_HashData(request->arguments, strlen(token), token, 0))) + { + /* Argument already exists */ + + /* Find the last one on the list */ + for(; stored; stored = stored->next) + { + last = stored; + } + + /* Append to local list */ + last->next = argument; + } + else + { + Util_HashStore(request->arguments, strlen(token), token, 0, (void *)argument); + request->n_arguments++; + } + /* Append to global list. */ + if(request->lastarg) + { + request->lastarg->all_next = argument; + } + request->lastarg = argument; + if(!request->firstarg) + { + request->firstarg = argument; + } } else { - Util_HashStore(request->arguments, strlen(token), token, 0, (void *)storable); - request->n_arguments++; +#ifdef HTTP_DEBUG + fprintf(stderr, "Out of memory\n"); +#endif } } else @@ -564,11 +626,67 @@ static int StripArgs(httpRequest *request, char *request_uri) return 0; } + /*@@ + @routine InitialiseRequest + @date Sat Sep 16 14:29:17 2000 + @author Tom Goodale + @desc + Initialises a request data structure. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +static int InitialiseRequest(httpRequest *request) +{ + + /* Initialise the public data */ + request->body = NULL; + request->body_length = 0; + request->method = NULL; + request->uri = NULL; + request->residual = NULL; + + request->http_major_version = -1; + request->http_minor_version = -1; + + request->n_arguments = 0; + + /* Initialise the private data */ + + request->filedes = -1; + request->headers = NULL; + request->arguments = NULL; + + request->firstarg = NULL; + request->lastarg = NULL; + request->currentarg = NULL; + + return 0; +} + + /*@@ + @routine ClearRequest + @date Wed Sep 13 20:44:31 2000 + @author Tom Goodale + @desc + Frees all memory associated with a request. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ static int ClearRequest(httpRequest *request) { if(request->arguments) { - Util_HashDestroy(request->arguments, (void (*)(void *))free); + Util_HashDestroy(request->arguments, (void (*)(void *))DestroyArgument); } if(request->headers) @@ -620,8 +738,50 @@ static void Decode(char *string) *to = 0; } + /*@@ + @routine DestroyHeader + @date Wed Sep 13 20:44:31 2000 + @author Tom Goodale + @desc + Frees all memory associated with a header structure. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ static void DestroyHeader(struct httpHeader *header) { free(header->line); free(header); } + + /*@@ + @routine DestroyArgument + @date Sat Sep 16 14:10:57 2000 + @author Tom Goodale + @desc + Frees all memory associated with an argument. + @enddesc + @calls + @calledby + @history + + @endhistory + +@@*/ +static void DestroyArgument(httpArg *argument) +{ + httpArg *next; + + for(; argument; argument = next) + { + next = argument->next; + free(argument->arg); + free(argument->value); + free(argument); + } +} + diff --git a/src/http_Request.h b/src/http_Request.h index 89a4930..5f39fe0 100644 --- a/src/http_Request.h +++ b/src/http_Request.h @@ -13,24 +13,53 @@ #ifndef __HTTP_REQUEST_H__ #define __HTTP_REQUEST_H__ 1 +typedef struct HTTPArg +{ + /* Public data */ + char *arg; + char *value; + + /* Private data */ + struct HTTPArg *next; + struct HTTPArg *all_next; +} httpArg; + +/* This is the main structure for storing data about a request. */ typedef struct { - int filedes; - char *body; - int body_length; + /* Public members of the structure. */ + char *body; /* The body of the request */ + int body_length; /* How long the body is */ - char *method; - char *uri; - char *residual; + char *method; /* The HTTP method */ + char *uri; /* The URI */ + char *residual; /* What's left of the URI after subtracting the found page */ - int http_major_version; + /* HTTP version numbers */ + int http_major_version; int http_minor_version; + /* How many arguments there are */ int n_arguments; - uHash *arguments; + /* These are all private members of this structure */ + + /* The file descriptor */ + int filedes; + + /* The request header lines */ uHash *headers; + /* Stuff for arguments */ + + /* First a hash table to look the data up quickly */ + uHash *arguments; + + /* Now a linked list to allow walking. */ + httpArg *firstarg; + httpArg *lastarg; + httpArg *currentarg; + } httpRequest; #ifdef __cplusplus @@ -42,6 +71,8 @@ int HTTP_RegisterPage(const char *path, int (*function)(cGH *, httpRequest *, vo const char *HTTP_ArgumentValue(const httpRequest *request, const char *arg); +const httpArg *HTTP_ArgumentWalk(httpRequest *request, int first); + const char *HTTP_HeaderValue(const httpRequest *request, const char *header); int HTTP_Write(httpRequest *request, const char *buffer, size_t count); |