From 8912994e1df3a12c145660e89987a9cb9eaac9f6 Mon Sep 17 00:00:00 2001 From: Jonathan Hodgson Date: Mon, 17 Jan 2022 14:03:34 +0000 Subject: [PATCH] Work on requests --- src/request.c | 50 +++++++++++++++++++++++++++++++++++++++----- src/request.h | 8 +++++++ tests/request.test.c | 40 +++++++++++++++++++++++++++++++++++ 3 files changed, 93 insertions(+), 5 deletions(-) diff --git a/src/request.c b/src/request.c index 991c247..5d11bd4 100644 --- a/src/request.c +++ b/src/request.c @@ -4,6 +4,7 @@ Request* newRequest(){ Request *request = malloc(sizeof(Request)); memset(request, 0, sizeof(Request)); + request->headers = NULL; return request; } @@ -19,7 +20,7 @@ void requestFirstLine( Request *req, char line[] ){ char path[2000] = {'\0'}; sscanf( line, "%20s %2048s HTTP/%f", method, url, &version ); - req->method = method; + req->method = strdup(method); req->version = version; //We've pulled out the easy bits. Now to go through the url and pull out what we need @@ -67,9 +68,48 @@ Request* newRequestFromSocket(int socket){ //a length of 2 will indicate an empty line which will split the headers //from the body (if there is a body) - //while ( valread > 2 ){ - // printf("%s",line ); - // //valread = fdReadLine( socket , line, 1024); - //} + valread = fdReadLine( socket, line, 1024); + while ( valread > 2 ){ + printf("%s",line ); + requestAddHeader( req, line ); + + //I believe at this point all the headers are done. + valread = fdReadLine( socket , line, 1024); + } return req; } + +char* requestToString( Request *req, bool proxy){ + unsigned int fullLength = strlen(req->method) + 1 + sizeof( req->path ) + + sizeof( req->queryString ) + 11 + headerListCharLength( req->headers ); + if ( proxy ) + fullLength += sizeof(req->method) + 3 + sizeof(req->host); + + + char retString[fullLength]; + + if (proxy) + sprintf(retString, "%s %s://%s%s%s HTTP/%.1f\r\n%s", req->method, + req->method, req->host, req->path, req->queryString, req->version, + headersToString(req->headers)); + else + sprintf(retString, "%s %s%s HTTP/%.1f\r\n%s", req->method, + req->path, req->queryString, req->version, + headersToString(req->headers)); + // rsp->statusMessage,headersToString(rsp->headers),rsp->body); + return strdup(retString); + //return strdup(retString); +} + +void requestAddHeader( Request *req, char header[] ){ + if ( req->headers == NULL ){ + req->headers = malloc(sizeof( HeaderList )); + req->headers->header = newHeader( header ); + req->headers->next = NULL; + } else + addHeader( req->headers, header ); +} + + + + diff --git a/src/request.h b/src/request.h index 2987718..7adbff8 100644 --- a/src/request.h +++ b/src/request.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include "readline.h" @@ -28,6 +29,13 @@ typedef struct { Request* newRequest(); void requestFirstLine( Request *req, char line[] ); Request* newRequestFromSocket(int socket); +/* +* requestToString +* @prarm req the request to convert +* @param proxy whether we want a proxy request (adds the host to the first line) +*/ +char* requestToString( Request *req, bool proxy ); +void requestAddHeader( Request *req, char header[] ); //void* requestAddHeader(Request *req, char line[]); diff --git a/tests/request.test.c b/tests/request.test.c index 80790b0..a77451c 100644 --- a/tests/request.test.c +++ b/tests/request.test.c @@ -4,6 +4,10 @@ #include "munit/munit.h" #include "../src/readline.c" #include "../src/request.c" +#ifndef REQUESTRESPONSE_C +#define REQUESTRESPONSE_C +#include "../src/requestresponse.c" +#endif /* ifndef REQUESTRESPONSE_C */ typedef struct { char *fullLine; @@ -99,6 +103,28 @@ MunitResult testFirstLineQueryString(const MunitParameter params[], return MUNIT_OK; } +MunitResult testRequestAddHeader(const MunitParameter params[], + void* user_data_or_fixture){ + Request *req = newRequest(); + munit_assert_null(req->headers); + requestAddHeader(req, "Content-Length: 0"); + munit_assert_int( 1, ==, countHeaders(req->headers) ); + requestAddHeader(req, "Test-header: 5"); + munit_assert_int( 2, ==, countHeaders(req->headers) ); + return MUNIT_OK; +} + +MunitResult testRequestToString(const MunitParameter params[], + void* user_data_or_fixture){ + Request *req = newRequest(); + requestFirstLine( req, "GET /search?q=test HTTP/1.1" ); + munit_assert_string_equal( requestToString( req, 0 ), "GET /search?q=test HTTP/1.1\r\n" ); + requestAddHeader( req, "Host: example.com" ); + munit_assert_string_equal( requestToString( req, 0 ), "GET /search?q=test HTTP/1.1\r\nHost: example.com\r\n" ); + + return MUNIT_OK; +} + static MunitTest request_tests[] = { { "/line1/versions", /* name */ @@ -142,6 +168,20 @@ static MunitTest request_tests[] = { NULL, /* tear_down */ MUNIT_TEST_OPTION_NONE, /* options */ NULL /* parameters */ + },{ + "/headers/add", /* name */ + testRequestAddHeader, /* test */ + NULL, /* setup */ + NULL, /* tear_down */ + MUNIT_TEST_OPTION_NONE, /* options */ + NULL /* parameters */ + },{ + "/tostring", /* name */ + testRequestToString, /* test */ + NULL, /* setup */ + NULL, /* tear_down */ + MUNIT_TEST_OPTION_NONE, /* options */ + NULL /* parameters */ }, /* Mark the end of the array with an entry where the test * function is NULL */