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