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