aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgoodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164>2000-09-16 14:22:38 +0000
committergoodale <goodale@1faa4e14-9dd3-4be0-9f0e-ffe519881164>2000-09-16 14:22:38 +0000
commit3ab68329120dcbc0a6ceff2dabdd1c6318ae17ab (patch)
tree36fee834924e9c3c753db5ff440eb68f36428bd6
parent21938abcbb2d93a318511fcbe5d0398a3184a2e2 (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.c210
-rw-r--r--src/http_Request.h47
2 files changed, 224 insertions, 33 deletions
diff --git a/src/http.c b/src/http.c
index 5437352..6ef45b7 100644
--- a/src/http.c
+++ b/src/http.c
@@ -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);