feat: split route into route & query
parent
7ece0eb4e5
commit
4d436aa8aa
|
@ -34,6 +34,8 @@ typedef struct http_request {
|
|||
size_t method_len;
|
||||
const char *path;
|
||||
size_t path_len;
|
||||
const char *query;
|
||||
size_t query_len;
|
||||
struct phr_header headers[HTTP_MAX_ALLOWED_HEADERS];
|
||||
} http_request;
|
||||
|
||||
|
@ -43,9 +45,6 @@ typedef enum http_parse_error {
|
|||
http_parse_error_invalid = 2,
|
||||
} 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); */
|
||||
|
||||
typedef enum http_response_type {
|
||||
|
|
|
@ -58,6 +58,8 @@ void http_loop_ctx_free(http_loop_ctx *ctx);
|
|||
*/
|
||||
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);
|
||||
|
||||
void http_loop_process_request(event_loop_conn *conn);
|
||||
|
|
|
@ -27,9 +27,7 @@ bool http_loop_handle_request(event_loop_conn *conn) {
|
|||
|
||||
// If route is defined, we're currently processing a request
|
||||
if (ctx->route == NULL) {
|
||||
http_parse_error res = http_parse_request(
|
||||
&ctx->req, (const char *)&conn->rbuf[conn->rbuf_read],
|
||||
conn->rbuf_size - conn->rbuf_read);
|
||||
http_parse_error res = http_loop_parse_request(conn);
|
||||
|
||||
if (res == http_parse_error_invalid ||
|
||||
(res == http_parse_error_incomplete &&
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -1,6 +1,58 @@
|
|||
#include <string.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) {
|
||||
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_gctx *gctx = ctx->g;
|
||||
|
||||
info("%.*s %.*s", ctx->req.method_len, ctx->req.method, ctx->req.path_len,
|
||||
ctx->req.path);
|
||||
|
||||
http_route *route;
|
||||
|
||||
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) {
|
||||
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;
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue