feat: split route into route & query

c-web-server
Jef Roosens 2023-05-27 17:14:49 +02:00
parent 7ece0eb4e5
commit 4d436aa8aa
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
5 changed files with 61 additions and 32 deletions

View File

@ -34,6 +34,8 @@ typedef struct http_request {
size_t method_len; size_t method_len;
const char *path; const char *path;
size_t path_len; size_t path_len;
const char *query;
size_t query_len;
struct phr_header headers[HTTP_MAX_ALLOWED_HEADERS]; struct phr_header headers[HTTP_MAX_ALLOWED_HEADERS];
} http_request; } http_request;
@ -43,9 +45,6 @@ typedef enum http_parse_error {
http_parse_error_invalid = 2, http_parse_error_invalid = 2,
} http_parse_error; } 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 { typedef enum http_response_type {

View File

@ -58,6 +58,8 @@ void http_loop_ctx_free(http_loop_ctx *ctx);
*/ */
bool http_loop_handle_request(event_loop_conn *conn); bool http_loop_handle_request(event_loop_conn *conn);
http_parse_error http_loop_parse_request(event_loop_conn *conn);
bool http_loop_route_request(event_loop_conn *conn); bool http_loop_route_request(event_loop_conn *conn);
void http_loop_process_request(event_loop_conn *conn); void http_loop_process_request(event_loop_conn *conn);

View File

@ -27,9 +27,7 @@ bool http_loop_handle_request(event_loop_conn *conn) {
// If route is defined, we're currently processing a request // If route is defined, we're currently processing a request
if (ctx->route == NULL) { if (ctx->route == NULL) {
http_parse_error res = http_parse_request( http_parse_error res = http_loop_parse_request(conn);
&ctx->req, (const char *)&conn->rbuf[conn->rbuf_read],
conn->rbuf_size - conn->rbuf_read);
if (res == http_parse_error_invalid || if (res == http_parse_error_invalid ||
(res == http_parse_error_incomplete && (res == http_parse_error_incomplete &&

View File

@ -1,25 +0,0 @@
#include "http.h"
#include "picohttpparser.h"
/*
* given the HTTP path, parse the request
*/
http_parse_error http_parse_request(http_request *req, const char *buf,
size_t buf_size) {
// First we try to parse the incoming HTTP request
size_t num_headers = HTTP_MAX_ALLOWED_HEADERS;
int res = phr_parse_request(buf, buf_size, &req->method, &req->method_len,
&req->path, &req->path_len, &req->minor_version,
req->headers, &num_headers, 0);
if (res == -1) {
return http_parse_error_invalid;
} else if (res == -2) {
return http_parse_error_incomplete;
}
req->len = res;
return http_parse_error_ok;
}

View File

@ -1,6 +1,58 @@
#include <string.h> #include <string.h>
#include "http_loop.h" #include "http_loop.h"
#include "log.h"
http_parse_error http_loop_parse_request(event_loop_conn *conn) {
http_loop_ctx *ctx = conn->ctx;
// First we try to parse the incoming HTTP request
size_t num_headers = HTTP_MAX_ALLOWED_HEADERS;
http_request *req = &ctx->req;
int res =
phr_parse_request((const char *)&conn->rbuf[conn->rbuf_read],
conn->rbuf_size - conn->rbuf_read, &req->method,
&req->method_len, &req->path, &req->path_len,
&req->minor_version, req->headers, &num_headers, 0);
if (res == -1) {
return http_parse_error_invalid;
} else if (res == -2) {
return http_parse_error_incomplete;
}
req->len = res;
// Split path into path & query
size_t i = 0;
bool no_query = true;
while (no_query && i < req->path_len) {
if (req->path[i] == '?') {
// Ensure we don't store an invalid pointer if the request simply ends
// with '?'
if (i + 1 < req->path_len) {
req->query = &req->path[i + 1];
req->query_len = req->path_len - (i + 1);
}
req->path_len = i;
no_query = false;
}
i++;
}
// Ensure we clear the old request's query
if (no_query) {
req->query = NULL;
req->query_len = 0;
}
return http_parse_error_ok;
}
void http_loop_process_request(event_loop_conn *conn) { void http_loop_process_request(event_loop_conn *conn) {
http_loop_ctx *ctx = conn->ctx; http_loop_ctx *ctx = conn->ctx;
@ -25,6 +77,9 @@ bool http_loop_route_request(event_loop_conn *conn) {
http_loop_ctx *ctx = conn->ctx; http_loop_ctx *ctx = conn->ctx;
http_loop_gctx *gctx = ctx->g; http_loop_gctx *gctx = ctx->g;
info("%.*s %.*s", ctx->req.method_len, ctx->req.method, ctx->req.path_len,
ctx->req.path);
http_route *route; http_route *route;
for (size_t i = 0; i < gctx->route_count; i++) { for (size_t i = 0; i < gctx->route_count; i++) {
@ -32,7 +87,7 @@ bool http_loop_route_request(event_loop_conn *conn) {
switch (route->type) { switch (route->type) {
case http_route_literal: case http_route_literal:
if (strncmp(route->path, ctx->req.method, ctx->req.method_len)) { if (strncmp(route->path, ctx->req.path, ctx->req.path_len) == 0) {
ctx->route = route; ctx->route = route;
return true; return true;
} }