summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--connection.c2
-rw-r--r--request.c364
-rw-r--r--request.h33
3 files changed, 0 insertions, 399 deletions
diff --git a/connection.c b/connection.c
index 055b498..8fad3c5 100644
--- a/connection.c
+++ b/connection.c
@@ -7,8 +7,6 @@
#include <lauxlib.h>
#include <lua.h>
-#include "request.h"
-
/// Creates new connection.
/// \param L Server's Lua state
/// \param client File descriptor of client's socket
diff --git a/request.c b/request.c
deleted file mode 100644
index ae5f74d..0000000
--- a/request.c
+++ /dev/null
@@ -1,364 +0,0 @@
-#include "request.h"
-
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <unistd.h>
-
-#include <lua.h>
-
-#include "connection.h"
-
-static const int REQUEST_DATA_SIZE = 4096;
-
-/// Allocates and initializes request structure.
-/// \param connection Origin connection of the request
-/// \return Pointer to initialized request or NULL in case of an error
-/// \see /free_request
-struct request * new_request(void)
-{
- struct request * request = malloc(sizeof(struct request));
-
- if (NULL == request)
- {
- return NULL;
- }
-
- memset(request, 0, sizeof(struct request));
- request->step = parse_step_method;
-
- request->data = malloc(REQUEST_DATA_SIZE);
-
- if (NULL == request->data)
- {
- free(request);
- return NULL;
- }
-
- return request;
-}
-
-/// Releases memory used by the request and the request itself.
-/// \param request Request to free
-/// \see /new_request
-void free_request(struct request * request)
-{
- if (NULL != request->data)
- {
- free(request->data);
- }
-
- free(request);
-}
-
-/// Collects request between calls to `poll`.
-/// \param connection Origin connection of the request
-/// \return Number of bytes parsed, -1 if an error occured or 0 if expects more data
-int parse_request(struct connection * connection)
-{
- if (NULL == connection->request)
- {
- connection->request = new_request();
- if (NULL == connection->request)
- {
- return -1;
- }
- }
-
- // TODO: Expand buffer until EAGAIN or arbitrary limit
- int length = read(connection->fd, connection->request->data, REQUEST_DATA_SIZE - 1);
-
- if (0 == length || (-1 == length && EWOULDBLOCK != errno && EAGAIN != errno))
- {
- return -1; // TODO: Handle errors properly
- }
-
- connection->request->data[length] = 0;
- connection->request->length = length;
-
- return connection->request->step(connection->L, connection->request);
-}
-
-
-/// Progresses the readout of the request until delimiter is found.
-/// \param request Request to process
-/// \param delimiter Character that marks the end of the readout
-/// \return Position of the delimiter or 0 if the deliminter could not be found
-static int read_until_char(struct request * request, const char delimiter)
-{
- char character;
- while (request->position < request->length)
- {
- character = request->data[request->position];
- if (delimiter == character)
- {
- return request->position;
- }
- request->position++;
- }
- return 0;
-}
-
-/// Progresses the readout of the request until non-whitespace character is found.
-/// \param request Request to process
-/// \return Position of the first non-whitespace character or 0 if it could not be found
-/// \see isalpha(3)
-static int read_until_word(struct request * request)
-{
- char character;
- while (request->position < request->length)
- {
- character = request->data[request->position];
- if (!isspace(character))
- {
- return request->position;
- }
- request->position++;
- }
- return 0;
-}
-
-/// Progresses the readout of the request until line separator is found.
-/// \param request Request to process
-/// \return Position of the first byte of the separator or 0 if line separator could not be found
-static int read_rest_of_line(struct request * request)
-{
- while (request->position < request->length - 1)
- {
- if ('\r' == request->data[request->position] && '\n' == request->data[request->position + 1])
- {
- return request->position;
- }
- else if ('\r' == request->data[request->position + 1])
- {
- request->position += 1;
- }
- else
- {
- request->position += 2;
- }
- }
- return 0;
-}
-
-#define PROCEED_TO(_x) \
- request->temp.start = 0; \
- request->temp.length = 0; \
- request->step = _x; \
- return _x(L, request)
-
-/// Parses method field of the request.
-/// \param L Connection's Lua state
-/// \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_method(lua_State * L, struct request * request)
-{
- // TODO: Consider reworking read_* functions to be more aware of word boundaries.
- request->temp.length = read_until_char(request, ' ');
-
- if (0 == request->temp.length)
- {
- return 0;
- }
-
- lua_pushlstring(L, request->data + request->temp.start, request->temp.length);
-
- PROCEED_TO(parse_step_path);
-}
-
-/// Parses path field of the request.
-/// \param L Connection's Lua state
-/// \param request Request to process
-/// \return -1 if an error has occured, 0 if too little data available or total number of bytes processed
-// TODO: Consider spliting path into an actual path and arguments in this stage
-int parse_step_path(lua_State * L, struct request * request)
-{
- // TODO: Rethink interface of parse_step_* and read_* functions. After a break it looks like mess; it's a bad sign.
- if (0 >= request->temp.start)
- {
- request->temp.start = read_until_word(request);
-
- if (0 == request->temp.start)
- {
- return 0;
- }
- }
-
- const int result = read_until_char(request, ' ');
-
- if (0 == result)
- {
- return 0;
- }
-
- request->temp.length = request->position - request->temp.start;
-
- // TODO: Use macro for pushing temporary span. Also clear the span in that macro instead of PROCEED_TO.
- lua_pushlstring(L, request->data + request->temp.start, request->temp.length);
-
- PROCEED_TO(parse_step_version);
-}
-
-/// Parses and verifies http version field of the request.
-/// \param L Connection's Lua state
-/// \param request Request to process
-/// \return -1 if an error has occured, 0 if too little data available or total number of bytes processed
-// TODO: Return -1 if version is unsupported, meaning other than HTTP/1.1
-int parse_step_version(lua_State * L, struct request * request)
-{
- if (0 >= request->temp.start)
- {
- request->temp.start = read_until_word(request);
-
- if (0 == request->temp.start)
- {
- return 0;
- }
- }
-
- const int result = read_rest_of_line(request);
-
- if (0 == result)
- {
- return 0;
- }
-
- request->temp.length = request->position - request->temp.start;
-
- lua_pushlstring(L, request->data + request->temp.start, request->temp.length);
-
- PROCEED_TO(parse_step_header_name);
-}
-
-/// Parses and verifies name of a single header from the request.
-/// \param L Connection's Lua state
-/// \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(lua_State * L, struct request * request)
-{
- if (0 == lua_istable(L, -1))
- {
- lua_newtable(L);
- }
-
- if (request->length - request->position < 4)
- {
- return 0;
- }
-
- if (
- request->data[request->position] == '\r' &&
- request->data[request->position + 1] == '\n' &&
- request->data[request->position + 2] == '\r' &&
- request->data[request->position + 3] == '\n')
- {
- // Skip "\r\n\r\n", end of headers.
- request->position += 4;
-
- // Early return hidden in a macro!
- PROCEED_TO(parse_step_data);
- }
-
- if (0 >= request->temp.start)
- {
- request->temp.start = read_until_word(request);
-
- if (0 == request->temp.start)
- {
- return 0;
- }
- }
-
- int result = read_until_char(request, ':');
-
- if (0 == result)
- {
- printf("parse_step_header_name:no ':'\n");
- return 0;
- }
-
- request->temp.length = request->position - request->temp.start;
-
- if (0 == strncasecmp("content-length", request->data + request->temp.start, request->temp.length))
- {
- // TODO: While it shouldn't happen, use a flag instead of a magic value.
- request->expected_data_length = -1;
- }
-
- lua_pushlstring(L, request->data + request->temp.start, request->temp.length);
-
- // Skip ':'
- request->position++;
- PROCEED_TO(parse_step_header_value);
-}
-
-/// Parses and verifies value of a single header from the request.
-/// \param L Connection's Lua state
-/// \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(lua_State * L, struct request * request)
-{
- if (0 >= request->temp.start)
- {
- request->temp.start = read_until_word(request);
-
- if (0 == request->temp.start)
- {
- return 0;
- }
- }
-
- const int result = read_rest_of_line(request);
-
- if (0 == result)
- {
- return 0;
- }
-
- request->temp.length = request->position - request->temp.start;
-
- if (-1 == request->expected_data_length)
- {
- *(request->data + request->temp.start + request->temp.length) = 0;
- request->expected_data_length = atoi(request->data + request->temp.start);
- *(request->data + request->temp.start + request->temp.length) = '\r';
- }
-
- lua_pushlstring(L, request->data + request->temp.start, request->temp.length);
- lua_rawset(L, -3);
-
- PROCEED_TO(parse_step_header_name);
-}
-
-/// Makes sure that the expected data is in payload and pushes it forward to Lua.
-/// \param L Connection's Lua state
-/// \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_data(lua_State * L, struct request * request)
-{
- const int bytes_left = request->length - request->position;
-
- if (bytes_left > request->expected_data_length)
- {
- return -1;
- }
- else if (bytes_left < request->expected_data_length)
- {
- return 0;
- }
-
- lua_pushlstring(L, request->data + request->position, request->expected_data_length);
-
- if (NULL != request->data)
- {
- free(request->data);
- request->data = NULL;
- }
-
- return request->position;
-}
-
-// TODO: Make a table from the request.
diff --git a/request.h b/request.h
deleted file mode 100644
index 690df88..0000000
--- a/request.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#pragma once
-
-#include <lua.h>
-
-struct connection;
-
-struct span
-{
- int start;
- int length;
-};
-
-struct request
-{
- int (* step)(lua_State *, struct request *);
- char * data;
- int length;
- int position;
- struct span temp;
- int expected_data_length;
-};
-
-struct request * new_request(void);
-void free_request(struct request *);
-
-int parse_request(struct connection *);
-
-int parse_step_method(lua_State *, struct request *);
-int parse_step_path(lua_State *, struct request *);
-int parse_step_version(lua_State *, struct request *);
-int parse_step_header_name(lua_State *, struct request *);
-int parse_step_header_value(lua_State *, struct request *);
-int parse_step_data(lua_State *, struct request *);