feat(http): add step for parsing content-length header
							parent
							
								
									7a21bed2b2
								
							
						
					
					
						commit
						fbf6557c05
					
				|  | @ -166,6 +166,13 @@ bool http_loop_step_body_to_buf(event_loop_conn *conn); | |||
|  */ | ||||
| bool http_loop_step_body_to_file(event_loop_conn *conn); | ||||
| 
 | ||||
| /**
 | ||||
|  * Try to parse the Content-Length header. | ||||
|  * | ||||
|  * @param conn connection to process | ||||
|  */ | ||||
| bool http_loop_step_parse_content_length(event_loop_conn *conn); | ||||
| 
 | ||||
| /**
 | ||||
|  * Authenticate the request using the X-Api-Key header. | ||||
|  * | ||||
|  | @ -201,7 +208,7 @@ bool http_loop_step_write_body(event_loop_conn *conn); | |||
|  * Initialize a new http loop. | ||||
|  * | ||||
|  * @param routes array of routes that should be served | ||||
|  * @parma route_count how many elements are in `routes` | ||||
|  * @param route_count how many elements are in `routes` | ||||
|  * @param custom_gctx the application's custom global context; can be NULL | ||||
|  * @param custom_ctx_init function to initialize a new custom context | ||||
|  * @param custom_ctx_reset function to reset a custom context | ||||
|  |  | |||
|  | @ -144,5 +144,6 @@ void http_loop_process_request(event_loop_conn *conn) { | |||
|   if ((conn->state != event_loop_conn_state_req) || | ||||
|       (ctx->route->steps[ctx->current_step] == NULL)) { | ||||
|     ctx->current_step = 0; | ||||
|     conn->state = event_loop_conn_state_res; | ||||
|   } | ||||
| } | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| #include <math.h> | ||||
| 
 | ||||
| #include "http_loop.h" | ||||
| #include "lander.h" | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -22,12 +23,44 @@ static bool string_to_num(size_t *res, const char *s, size_t len) { | |||
|   return true; | ||||
| } | ||||
| 
 | ||||
| bool http_loop_step_parse_content_length(event_loop_conn *conn) { | ||||
|   http_loop_ctx *ctx = conn->ctx; | ||||
| 
 | ||||
|   for (size_t i = 0; i < ctx->req.num_headers; i++) { | ||||
|     struct phr_header *header = &ctx->req.headers[i]; | ||||
| 
 | ||||
|     if (strncmp(header->name, "Content-Length", header->name_len) == 0) { | ||||
|       // If the content length header is present but contains an invalid
 | ||||
|       // number, we return a bad request error
 | ||||
|       if (!string_to_num(&ctx->req.body.expected_len, header->value, | ||||
|                          header->value_len)) { | ||||
|         ctx->res.status = http_bad_request; | ||||
|         conn->state = event_loop_conn_state_res; | ||||
| 
 | ||||
|         return true; | ||||
|       } | ||||
|       // The content length was actually 0, so we can instantly return here
 | ||||
|       else if (ctx->req.body.expected_len == 0) { | ||||
|         return true; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   // A zero here means there's no content length header
 | ||||
|   if (ctx->req.body.expected_len == 0) { | ||||
|     ctx->res.status = http_length_required; | ||||
|     conn->state = event_loop_conn_state_res; | ||||
|   } | ||||
| 
 | ||||
|   return true; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Try to find and parse the Content-Length header. This function returns true | ||||
|  * if it was successful. If false is returned, the underlying step should | ||||
|  * immediately exit. | ||||
|  */ | ||||
| static bool try_parse_content_length(event_loop_conn *conn) { | ||||
| bool try_parse_content_length(event_loop_conn *conn) { | ||||
|   http_loop_ctx *ctx = conn->ctx; | ||||
| 
 | ||||
|   for (size_t i = 0; i < ctx->req.num_headers; i++) { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue