feat: parse method into enum value
							parent
							
								
									90ff55d977
								
							
						
					
					
						commit
						a90330dd6e
					
				|  | @ -15,6 +15,8 @@ extern const char http_405[]; | |||
| extern const size_t http_405_len; | ||||
| extern const char http_500[]; | ||||
| extern const size_t http_500_len; | ||||
| extern const char http_501[]; | ||||
| extern const size_t http_501_len; | ||||
| 
 | ||||
| typedef enum http_request_method { | ||||
|   http_request_method_get = 0, | ||||
|  | @ -24,14 +26,16 @@ typedef enum http_request_method { | |||
|   http_request_method_delete = 4 | ||||
| } http_request_method; | ||||
| 
 | ||||
| extern const char *request_method_names[]; | ||||
| extern const size_t request_method_names_len; | ||||
| 
 | ||||
| /*
 | ||||
|  * Struct representing the specific type of request | ||||
|  */ | ||||
| typedef struct http_request { | ||||
|   size_t len; | ||||
|   int minor_version; | ||||
|   const char *method; | ||||
|   size_t method_len; | ||||
|   http_request_method method; | ||||
|   const char *path; | ||||
|   size_t path_len; | ||||
|   const char *query; | ||||
|  | @ -43,13 +47,15 @@ typedef enum http_parse_error { | |||
|   http_parse_error_ok = 0, | ||||
|   http_parse_error_incomplete = 1, | ||||
|   http_parse_error_invalid = 2, | ||||
|   http_parse_error_unknown_method = 3 | ||||
| } http_parse_error; | ||||
| 
 | ||||
| /* void http_route(event_loop_conn *conn); */ | ||||
| 
 | ||||
| typedef enum http_response_type { | ||||
|   http_not_found = 404, | ||||
|   http_method_not_allowed = 405 | ||||
|   http_method_not_allowed = 405, | ||||
|   http_method_not_implemented = 501 | ||||
| } http_response_type; | ||||
| 
 | ||||
| void http_write_standard_response(event_loop_conn *conn, | ||||
|  |  | |||
|  | @ -36,6 +36,12 @@ bool http_loop_handle_request(event_loop_conn *conn) { | |||
| 
 | ||||
|       return false; | ||||
|     } | ||||
|     // It's fun to respond with extremely specific error messages
 | ||||
|     // https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/501
 | ||||
|     else if (res == http_parse_error_unknown_method) { | ||||
|       http_write_standard_response(conn, 501); | ||||
|       return false; | ||||
|     } | ||||
| 
 | ||||
|     conn->rbuf_read += res; | ||||
| 
 | ||||
|  |  | |||
|  | @ -11,3 +11,11 @@ const size_t http_405_len = sizeof(http_405) - 1; | |||
| const char http_500[] = "HTTP/1.1 500 Internal Server Error\n" | ||||
|                         "Content-Length: 0\n\n"; | ||||
| const size_t http_500_len = sizeof(http_500) - 1; | ||||
| const char http_501[] = "HTTP/1.1 501 Not Implemented\n" | ||||
|                         "Content-Length: 0\n\n"; | ||||
| const size_t http_501_len = sizeof(http_501) - 1; | ||||
| 
 | ||||
| // Very important that this is in the same order as http_request_method
 | ||||
| const char *request_method_names[] = {"GET", "POST", "PUT", "PATCH", "DELETE"}; | ||||
| const size_t request_method_names_len = | ||||
|     sizeof(request_method_names) / sizeof(request_method_names[0]); | ||||
|  |  | |||
|  | @ -10,11 +10,13 @@ http_parse_error http_loop_parse_request(event_loop_conn *conn) { | |||
|   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); | ||||
|   const char *method; | ||||
|   size_t method_len; | ||||
| 
 | ||||
|   int res = phr_parse_request( | ||||
|       (const char *)&conn->rbuf[conn->rbuf_read], | ||||
|       conn->rbuf_size - conn->rbuf_read, &method, &method_len, &req->path, | ||||
|       &req->path_len, &req->minor_version, req->headers, &num_headers, 0); | ||||
| 
 | ||||
|   if (res == -1) { | ||||
|     return http_parse_error_invalid; | ||||
|  | @ -24,8 +26,23 @@ http_parse_error http_loop_parse_request(event_loop_conn *conn) { | |||
| 
 | ||||
|   req->len = res; | ||||
| 
 | ||||
|   // Split path into path & query
 | ||||
|   // Try to parse the method type
 | ||||
|   bool match = false; | ||||
|   size_t i = 0; | ||||
| 
 | ||||
|   for (i = 0; i < request_method_names_len; i++) { | ||||
|     if (strncmp(method, request_method_names[i], method_len) == 0) { | ||||
|       req->method = i; | ||||
|       match = true; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   if (!match) { | ||||
|     return http_parse_error_unknown_method; | ||||
|   } | ||||
| 
 | ||||
|   // Split path into path & query
 | ||||
|   i = 0; | ||||
|   bool no_query = true; | ||||
| 
 | ||||
|   while (no_query && i < req->path_len) { | ||||
|  | @ -77,7 +94,7 @@ 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, | ||||
|   info("%s %.*s", request_method_names[ctx->req.method], ctx->req.path_len, | ||||
|        ctx->req.path); | ||||
| 
 | ||||
|   http_route *route; | ||||
|  |  | |||
|  | @ -14,6 +14,9 @@ void http_write_standard_response(event_loop_conn *conn, | |||
|   case 405: | ||||
|     s = http_405; | ||||
|     len = http_405_len; | ||||
|   case 501: | ||||
|     s = http_501; | ||||
|     len = http_501_len; | ||||
|   } | ||||
| 
 | ||||
|   memcpy(conn->wbuf, s, len); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue