feat: split route into route & query
parent
7ece0eb4e5
commit
4d436aa8aa
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 &&
|
||||||
|
|
|
@ -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 <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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue