summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAki <please@ignore.pl>2020-05-30 15:28:40 +0200
committerAki <please@ignore.pl>2020-05-30 15:28:40 +0200
commitebf5def64dbb2474e9105a4fbdd9b875c023d3e5 (patch)
tree36e5bf33c9be5fa7f883145a72ba686d396af277
parentb95df8445bec1e88ec686cd2c03cc48c6bae3c70 (diff)
downloadplop-ebf5def64dbb2474e9105a4fbdd9b875c023d3e5.zip
plop-ebf5def64dbb2474e9105a4fbdd9b875c023d3e5.tar.gz
plop-ebf5def64dbb2474e9105a4fbdd9b875c023d3e5.tar.bz2
Added headers parsing
-rw-r--r--http.c103
-rw-r--r--http.h5
-rw-r--r--plop.c10
3 files changed, 113 insertions, 5 deletions
diff --git a/http.c b/http.c
index 5e1472c..89716cd 100644
--- a/http.c
+++ b/http.c
@@ -8,6 +8,7 @@
#include <unistd.h>
static const int REQUEST_DATA_SIZE = 4096;
+static const int MAX_HEADERS = 30;
const char * status_str[] = {
[STATUS_OK] = "200 OK",
@@ -55,9 +56,9 @@ void free_request(struct request * request)
free(request->data);
}
- if (NULL != request->headers)
+ if (NULL != request->headerv)
{
- free(request->headers);
+ free(request->headerv);
}
free(request);
@@ -261,7 +262,101 @@ int parse_step_version(struct request * request)
}
request->version.length = request->position - request->version.start;
- request->step = NULL; // TODO: Parse headers
+ request->step = parse_step_header_name;
- return request->position;
+ return parse_step_header_name(request);
+}
+
+/// Parses and verifies name of a single header from the request.
+/// \param request Request to process
+/// \return -1 if an error has occured, 0 if too little data available or total number of bytes processed
+int parse_step_header_name(struct request * request)
+{
+ if (NULL == request->headerv)
+ {
+ request->headerv = malloc(sizeof(struct header) * MAX_HEADERS);
+ request->headerc = 0;
+ memset(request->headerv, 0, sizeof(struct header) * MAX_HEADERS);
+
+ if (NULL == request->headerv)
+ {
+ return -1;
+ }
+ }
+
+ // TODO: Check for the header section end without backtracking.
+ const int position = request->position;
+ int result = read_rest_of_line(request);
+
+ if (0 == result)
+ {
+ return 0;
+ }
+
+ if (2 == result - position)
+ {
+ // Header section ended, nothing left to parse.
+ return request->position + 2;
+ }
+
+ request->position = position;
+
+ if (0 >= request->headerv[request->headerc].name.start)
+ {
+ request->headerv[request->headerc].name.start = read_until_word(request);
+
+ if (0 == request->headerv[request->headerc].name.start)
+ {
+ return 0;
+ }
+ }
+
+ result = read_until_char(request, ':');
+
+ if (0 == result)
+ {
+ return 0;
+ }
+
+ request->headerv[request->headerc].name.length = request->position - request->headerv[request->headerc].name.start;
+ request->step = parse_step_header_value;
+
+ // Skip ':'
+ request->position++;
+
+ return parse_step_header_value(request);
+}
+
+/// Parses and verifies value of a single header from the request.
+/// \param request Request to process
+/// \return -1 if an error has occured, 0 if too little data available or total number of bytes processed
+int parse_step_header_value(struct request * request)
+{
+ if (0 >= request->headerv[request->headerc].value.start)
+ {
+ request->headerv[request->headerc].value.start = read_until_word(request);
+
+ if (0 == request->headerv[request->headerc].value.start)
+ {
+ return 0;
+ }
+ }
+
+ const int result = read_rest_of_line(request);
+
+ if (0 == result)
+ {
+ return 0;
+ }
+
+ request->headerv[request->headerc].value.length = request->position - request->headerv[request->headerc].value.start;
+ request->step = parse_step_header_name;
+ request->headerc++;
+
+ if (MAX_HEADERS == request->headerc)
+ {
+ return -1;
+ }
+
+ return parse_step_header_name(request);
}
diff --git a/http.h b/http.h
index 90f4bbf..d24d996 100644
--- a/http.h
+++ b/http.h
@@ -22,7 +22,8 @@ struct request
struct span method;
struct span path;
struct span version;
- struct header * headers;
+ struct header * headerv;
+ int headerc;
struct span body;
};
@@ -50,5 +51,7 @@ int parse_request(int, struct request **);
int parse_step_method(struct request *);
int parse_step_path(struct request *);
int parse_step_version(struct request *);
+int parse_step_header_name(struct request *);
+int parse_step_header_value(struct request *);
#endif // HTTP_H
diff --git a/plop.c b/plop.c
index 2a52b22..7e53457 100644
--- a/plop.c
+++ b/plop.c
@@ -112,6 +112,16 @@ int handle_client(lua_State * L, struct pollfd * pfd, struct request ** request,
(*request)->method.length, (*request)->data + (*request)->method.start,
(*request)->path.length, (*request)->data + (*request)->path.start);
+ for (int h = 0; h < (*request)->headerc; ++h)
+ {
+ printf(
+ "\t'%.*s' = '%.*s'\n",
+ (*request)->headerv[h].name.length,
+ (*request)->data + (*request)->headerv[h].name.start,
+ (*request)->headerv[h].value.length,
+ (*request)->data + (*request)->headerv[h].value.start);
+ }
+
// TODO: Use results from parsing instead of raw data
lua_getglobal(L, "Handler");
lua_pushlstring(L, (*request)->data, (*request)->length);