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