feat: started designing http framework
parent
90d83bc5d4
commit
8250a5b8b0
|
@ -9,7 +9,7 @@
|
|||
#define EVENT_LOOP_BUFFER_SIZE 1024
|
||||
|
||||
/**
|
||||
* Represents an active connection managed by the event loop
|
||||
* State of a connection
|
||||
*/
|
||||
typedef enum {
|
||||
event_loop_conn_state_req = 0,
|
||||
|
@ -17,14 +17,17 @@ typedef enum {
|
|||
event_loop_conn_state_end = 2,
|
||||
} event_loop_conn_state;
|
||||
|
||||
/**
|
||||
* Represents an active connection managed by the event loop
|
||||
*/
|
||||
typedef struct event_loop_conn {
|
||||
int fd;
|
||||
event_loop_conn_state state;
|
||||
// buffer for reading
|
||||
// Read buffer
|
||||
size_t rbuf_size;
|
||||
size_t rbuf_read;
|
||||
uint8_t rbuf[EVENT_LOOP_BUFFER_SIZE];
|
||||
// buffer for writing
|
||||
// Write buffer
|
||||
size_t wbuf_size;
|
||||
size_t wbuf_sent;
|
||||
uint8_t wbuf[EVENT_LOOP_BUFFER_SIZE];
|
||||
|
@ -32,6 +35,7 @@ typedef struct event_loop_conn {
|
|||
// If true, the server will close the connection after the final write buffer
|
||||
// has been written
|
||||
bool close_after_write;
|
||||
// Context for a request
|
||||
void *ctx;
|
||||
} event_loop_conn;
|
||||
|
||||
|
@ -47,23 +51,27 @@ typedef struct event_loop {
|
|||
void *(*ctx_init)(void *gctx);
|
||||
// Function to free a context for a connection
|
||||
void (*ctx_free)(void *ctx);
|
||||
// Function that processes incoming data
|
||||
bool (*handle_data)(event_loop_conn *conn);
|
||||
} event_loop;
|
||||
|
||||
/*
|
||||
* Initialize a new event_loop_conn struct
|
||||
* Initialize a new connection struct
|
||||
*/
|
||||
event_loop_conn *event_loop_conn_init(event_loop *el);
|
||||
|
||||
/*
|
||||
* Free a connection struct
|
||||
*/
|
||||
void event_loop_conn_free(event_loop *el, event_loop_conn *conn);
|
||||
|
||||
/*
|
||||
* Process data on a connection
|
||||
* Handle I/O for a connection, be it reading input or writing output.
|
||||
*/
|
||||
void event_loop_conn_io(event_loop *el, event_loop_conn *conn);
|
||||
|
||||
/*
|
||||
* Initialize a new event_loop struct
|
||||
* Initialize a new event loop struct
|
||||
*/
|
||||
event_loop *event_loop_init();
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
#include "picohttpparser.h"
|
||||
|
||||
#include "event_loop.h"
|
||||
#include "http_req.h"
|
||||
|
||||
#define HTTP_MAX_ALLOWED_HEADERS 8
|
||||
|
||||
extern const char http_404[];
|
||||
extern const size_t http_404_len;
|
||||
|
@ -15,6 +16,27 @@ extern const size_t http_405_len;
|
|||
extern const char http_500[];
|
||||
extern const size_t http_500_len;
|
||||
|
||||
typedef enum http_request_method {
|
||||
http_request_method_get = 0,
|
||||
http_request_method_post = 1,
|
||||
http_request_method_put = 2,
|
||||
http_request_method_patch = 3,
|
||||
http_request_method_delete = 4
|
||||
} http_request_method;
|
||||
|
||||
/*
|
||||
* Struct representing the specific type of request
|
||||
*/
|
||||
typedef struct http_request {
|
||||
size_t len;
|
||||
int minor_version;
|
||||
const char *method;
|
||||
size_t method_len;
|
||||
const char *path;
|
||||
size_t path_len;
|
||||
struct phr_header headers[HTTP_MAX_ALLOWED_HEADERS];
|
||||
} http_request;
|
||||
|
||||
typedef enum http_parse_error {
|
||||
http_parse_error_ok = 0,
|
||||
http_parse_error_incomplete = 1,
|
||||
|
@ -24,7 +46,7 @@ typedef enum http_parse_error {
|
|||
http_parse_error http_parse_request(http_request *req, const char *path,
|
||||
size_t path_len);
|
||||
|
||||
void http_route(event_loop_conn *conn);
|
||||
/* void http_route(event_loop_conn *conn); */
|
||||
|
||||
typedef enum http_response_type {
|
||||
http_not_found = 404,
|
||||
|
|
|
@ -1,17 +1,36 @@
|
|||
#ifndef LANDER_HTTP_LOOP
|
||||
#define LANDER_HTTP_LOOP
|
||||
|
||||
#include <regex.h>
|
||||
|
||||
#include "event_loop.h"
|
||||
#include "http_req.h"
|
||||
#include "http.h"
|
||||
#include "trie.h"
|
||||
|
||||
typedef enum http_route_type {
|
||||
http_route_literal = 0,
|
||||
http_route_regex = 1,
|
||||
} http_route_type;
|
||||
|
||||
typedef struct http_route {
|
||||
http_route_type type;
|
||||
char *path;
|
||||
regex_t *regex;
|
||||
size_t step_count;
|
||||
void (**steps)(event_loop_conn *);
|
||||
} http_route;
|
||||
|
||||
/*
|
||||
* Global context passed to every connection using the same pointer
|
||||
*/
|
||||
typedef struct http_loop_gctx {
|
||||
http_route **routes;
|
||||
Trie *trie;
|
||||
} http_loop_gctx;
|
||||
|
||||
/*
|
||||
* Initialize a new global context
|
||||
*/
|
||||
http_loop_gctx *http_loop_gctx_init();
|
||||
|
||||
/*
|
||||
|
@ -19,15 +38,31 @@ http_loop_gctx *http_loop_gctx_init();
|
|||
*/
|
||||
typedef struct http_loop_ctx {
|
||||
http_request req;
|
||||
http_route *route;
|
||||
size_t current_step;
|
||||
http_loop_gctx *g;
|
||||
} http_loop_ctx;
|
||||
|
||||
/*
|
||||
* Initialize a context struct
|
||||
*/
|
||||
http_loop_ctx *http_loop_ctx_init(http_loop_gctx *g);
|
||||
|
||||
/*
|
||||
* Free a context struct
|
||||
*/
|
||||
void http_loop_ctx_free(http_loop_ctx *ctx);
|
||||
|
||||
/**
|
||||
* Process incoming data as an HTTP request
|
||||
*/
|
||||
bool http_loop_handle_request(event_loop_conn *conn);
|
||||
|
||||
void http_loop_process_request(event_loop_conn *conn);
|
||||
|
||||
/**
|
||||
* Initialize a new http loop
|
||||
*/
|
||||
event_loop *http_loop_init(http_loop_gctx *gctx);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
#ifndef HTTP_REQ
|
||||
#define HTTP_REQ
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "picohttpparser.h"
|
||||
|
||||
#define HTTP_MAX_ALLOWED_HEADERS 16
|
||||
|
||||
typedef enum http_request_method {
|
||||
http_request_method_get = 0,
|
||||
http_request_method_post = 1,
|
||||
http_request_method_put = 2,
|
||||
http_request_method_patch = 3,
|
||||
http_request_method_delete = 4
|
||||
} http_request_method;
|
||||
|
||||
/*
|
||||
* Struct representing the specific type of request
|
||||
*/
|
||||
typedef struct http_request {
|
||||
size_t len;
|
||||
int minor_version;
|
||||
const char *method;
|
||||
size_t method_len;
|
||||
const char *path;
|
||||
size_t path_len;
|
||||
struct phr_header headers[HTTP_MAX_ALLOWED_HEADERS];
|
||||
} http_request;
|
||||
|
||||
#endif
|
|
@ -172,7 +172,7 @@ void event_loop_run(event_loop *el, int port) {
|
|||
|
||||
// poll for active fds
|
||||
// the timeout argument doesn't matter here
|
||||
int rv = poll(poll_args, (nfds_t)poll_args_count, 0);
|
||||
int rv = poll(poll_args, (nfds_t)poll_args_count, -1);
|
||||
|
||||
if (rv < 0) {
|
||||
critical(1, "Poll failed, errno: %i", errno);
|
||||
|
|
|
@ -109,7 +109,6 @@ void event_loop_conn_io(event_loop *el, event_loop_conn *conn) {
|
|||
case event_loop_conn_state_res:
|
||||
event_loop_conn_io_res(conn);
|
||||
break;
|
||||
case event_loop_conn_state_end:
|
||||
break;
|
||||
case event_loop_conn_state_end:;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ bool http_loop_handle_request(event_loop_conn *conn) {
|
|||
|
||||
if (res == http_parse_error_ok) {
|
||||
// Perform the request
|
||||
http_route(conn);
|
||||
/* http_route(conn); */
|
||||
}
|
||||
// Both in the case of an invalid HTTP request or one that's larger than the
|
||||
// read buffer, we cannot determine when the next, possibly valid, HTTP
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
#include "event_loop.h"
|
||||
#include "http.h"
|
||||
|
||||
typedef void (*routing_func)(event_loop_conn *);
|
||||
void http_loop_process_request(event_loop_conn *conn) {}
|
||||
|
||||
void http_route(event_loop_conn *conn) {
|
||||
// TODO routing
|
||||
/* void http_route(event_loop_conn *conn) { */
|
||||
/* // TODO routing */
|
||||
|
||||
// Fallthrough is to return a 404
|
||||
http_write_standard_response(conn, http_not_found);
|
||||
}
|
||||
/* // Fallthrough is to return a 404 */
|
||||
/* http_write_standard_response(conn, http_not_found); */
|
||||
/* } */
|
||||
|
|
13
src/main.c
13
src/main.c
|
@ -1,8 +1,21 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "http.h"
|
||||
#include "http_loop.h"
|
||||
#include "log.h"
|
||||
|
||||
void http_write_404(event_loop_conn *conn) {
|
||||
memcpy(conn->wbuf, http_404, http_404_len);
|
||||
|
||||
conn->state = event_loop_conn_state_res;
|
||||
conn->wbuf_size = http_404_len;
|
||||
conn->wbuf_sent = 0;
|
||||
}
|
||||
|
||||
void (*steps[])(event_loop_conn *) = {http_write_404, NULL};
|
||||
http_route routes[] = {
|
||||
{.type = http_route_literal, .path = "/", .step_count = 1, .steps = steps}};
|
||||
|
||||
int main() {
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
|
|
Loading…
Reference in New Issue