feat: abstract http body
							parent
							
								
									a6257a923d
								
							
						
					
					
						commit
						bbfea5876e
					
				| 
						 | 
					@ -23,14 +23,7 @@ typedef struct http_request {
 | 
				
			||||||
  size_t path_len;
 | 
					  size_t path_len;
 | 
				
			||||||
  const char *query;
 | 
					  const char *query;
 | 
				
			||||||
  size_t query_len;
 | 
					  size_t query_len;
 | 
				
			||||||
  http_body_type body_type;
 | 
					  http_body body;
 | 
				
			||||||
  union {
 | 
					 | 
				
			||||||
    char *buf;
 | 
					 | 
				
			||||||
    FILE *file;
 | 
					 | 
				
			||||||
  } body;
 | 
					 | 
				
			||||||
  size_t body_len;
 | 
					 | 
				
			||||||
  size_t body_received;
 | 
					 | 
				
			||||||
  char *body_file_name;
 | 
					 | 
				
			||||||
  regmatch_t regex_groups[HTTP_MAX_REGEX_GROUPS];
 | 
					  regmatch_t regex_groups[HTTP_MAX_REGEX_GROUPS];
 | 
				
			||||||
  struct phr_header headers[HTTP_MAX_ALLOWED_HEADERS];
 | 
					  struct phr_header headers[HTTP_MAX_ALLOWED_HEADERS];
 | 
				
			||||||
  size_t num_headers;
 | 
					  size_t num_headers;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,15 +17,7 @@ typedef struct http_response {
 | 
				
			||||||
  const char *head;
 | 
					  const char *head;
 | 
				
			||||||
  size_t head_len;
 | 
					  size_t head_len;
 | 
				
			||||||
  size_t head_written;
 | 
					  size_t head_written;
 | 
				
			||||||
  http_body_type body_type;
 | 
					  http_body body;
 | 
				
			||||||
  union {
 | 
					 | 
				
			||||||
    char *buf;
 | 
					 | 
				
			||||||
    FILE *file;
 | 
					 | 
				
			||||||
  } body;
 | 
					 | 
				
			||||||
  size_t body_len;
 | 
					 | 
				
			||||||
  size_t body_written;
 | 
					 | 
				
			||||||
  // If false, the body won't be freed
 | 
					 | 
				
			||||||
  bool owns_body;
 | 
					 | 
				
			||||||
  http_response_header headers[4];
 | 
					  http_response_header headers[4];
 | 
				
			||||||
  size_t header_count;
 | 
					  size_t header_count;
 | 
				
			||||||
} http_response;
 | 
					} http_response;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,8 @@
 | 
				
			||||||
#define LANDER_HTTP_TYPES
 | 
					#define LANDER_HTTP_TYPES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <sys/types.h>
 | 
					#include <sys/types.h>
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Array mapping the http_request_method enum to strings
 | 
					// Array mapping the http_request_method enum to strings
 | 
				
			||||||
extern const char *http_method_names[];
 | 
					extern const char *http_method_names[];
 | 
				
			||||||
| 
						 | 
					@ -129,4 +131,26 @@ typedef enum http_body_type {
 | 
				
			||||||
  http_body_file = 1
 | 
					  http_body_file = 1
 | 
				
			||||||
} http_body_type;
 | 
					} http_body_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct http_body {
 | 
				
			||||||
 | 
					  http_body_type type;
 | 
				
			||||||
 | 
					  char *buf;
 | 
				
			||||||
 | 
					  bool buf_owned;
 | 
				
			||||||
 | 
					  FILE *file;
 | 
				
			||||||
 | 
					  char *fname;
 | 
				
			||||||
 | 
					  bool fname_owned;
 | 
				
			||||||
 | 
					  // In the context of a request, expected_len is the content of the request's
 | 
				
			||||||
 | 
					  // Content-Length header, and len is how many bytes have already been
 | 
				
			||||||
 | 
					  // received.
 | 
				
			||||||
 | 
					  // In the context of a response, expected_len is the actual length of the
 | 
				
			||||||
 | 
					  // body, and len is how many have been written.
 | 
				
			||||||
 | 
					  size_t expected_len;
 | 
				
			||||||
 | 
					  size_t len;
 | 
				
			||||||
 | 
					} http_body;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					http_body *http_body_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void http_body_reset(http_body *body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void http_body_free(http_body *body);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,10 +4,10 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void http_res_set_body_buf(http_response *res, const char *body,
 | 
					void http_res_set_body_buf(http_response *res, const char *body,
 | 
				
			||||||
                           size_t body_len, bool owned) {
 | 
					                           size_t body_len, bool owned) {
 | 
				
			||||||
  res->body_type = http_body_buf;
 | 
					  res->body.type = http_body_buf;
 | 
				
			||||||
  res->body.buf = (char *)body;
 | 
					  res->body.buf = (char *)body;
 | 
				
			||||||
  res->body_len = body_len;
 | 
					  res->body.expected_len = body_len;
 | 
				
			||||||
  res->owns_body = owned;
 | 
					  res->body.buf_owned = owned;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void http_res_set_body_file(http_response *res, const char *filename) {
 | 
					void http_res_set_body_file(http_response *res, const char *filename) {
 | 
				
			||||||
| 
						 | 
					@ -17,9 +17,9 @@ void http_res_set_body_file(http_response *res, const char *filename) {
 | 
				
			||||||
  // TODO error handling
 | 
					  // TODO error handling
 | 
				
			||||||
  FILE *f = fopen(filename, "r");
 | 
					  FILE *f = fopen(filename, "r");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  res->body_type = http_body_file;
 | 
					  res->body.type = http_body_file;
 | 
				
			||||||
  res->body.file = f;
 | 
					  res->body.file = f;
 | 
				
			||||||
  res->body_len = st.st_size;
 | 
					  res->body.expected_len = st.st_size;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void http_res_add_header(http_response *res, http_header type,
 | 
					void http_res_add_header(http_response *res, http_header type,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "http/types.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					http_body *http_body_init() {
 | 
				
			||||||
 | 
					  return calloc(sizeof(http_body), 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void http_body_reset(http_body *body) {
 | 
				
			||||||
 | 
					  if (body->type == http_body_file) {
 | 
				
			||||||
 | 
					    fclose(body->file);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (body->buf_owned) {
 | 
				
			||||||
 | 
					    free(body->buf);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (body->fname_owned) {
 | 
				
			||||||
 | 
					    free(body->fname);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  body->type = 0;
 | 
				
			||||||
 | 
					  body->buf = NULL;
 | 
				
			||||||
 | 
					  body->buf_owned = false;
 | 
				
			||||||
 | 
					  body->file = NULL;
 | 
				
			||||||
 | 
					  body->fname = NULL;
 | 
				
			||||||
 | 
					  body->fname_owned = false;
 | 
				
			||||||
 | 
					  body->expected_len = 0;
 | 
				
			||||||
 | 
					  body->len = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void http_body_free(http_body *body) {
 | 
				
			||||||
 | 
					  http_body_reset(body);
 | 
				
			||||||
 | 
					  free(body);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -26,29 +26,13 @@ void http_loop_ctx_reset(http_loop_ctx *ctx) {
 | 
				
			||||||
  ctx->route = NULL;
 | 
					  ctx->route = NULL;
 | 
				
			||||||
  ctx->current_step = 0;
 | 
					  ctx->current_step = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (ctx->req.body_type == http_body_buf && ctx->req.body.buf != NULL) {
 | 
					 | 
				
			||||||
    free(ctx->req.body.buf);
 | 
					 | 
				
			||||||
    ctx->req.body.buf = NULL;
 | 
					 | 
				
			||||||
  } else if (ctx->req.body_type == http_body_file &&
 | 
					 | 
				
			||||||
             ctx->req.body.file != NULL) {
 | 
					 | 
				
			||||||
    fclose(ctx->req.body.file);
 | 
					 | 
				
			||||||
    ctx->req.body.file = NULL;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (ctx->res.head != NULL) {
 | 
					  if (ctx->res.head != NULL) {
 | 
				
			||||||
    free((void *)ctx->res.head);
 | 
					    free((void *)ctx->res.head);
 | 
				
			||||||
    ctx->res.head = NULL;
 | 
					    ctx->res.head = NULL;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (ctx->res.body_type == http_body_buf && ctx->res.body.buf != NULL &&
 | 
					  http_body_reset(&ctx->req.body);
 | 
				
			||||||
      ctx->res.owns_body) {
 | 
					  http_body_reset(&ctx->res.body);
 | 
				
			||||||
    free(ctx->res.body.buf);
 | 
					 | 
				
			||||||
    ctx->res.body.buf = NULL;
 | 
					 | 
				
			||||||
  } else if (ctx->res.body_type == http_body_file &&
 | 
					 | 
				
			||||||
             ctx->res.body.file != NULL) {
 | 
					 | 
				
			||||||
    fclose(ctx->res.body.file);
 | 
					 | 
				
			||||||
    ctx->res.body.file = NULL;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (size_t i = 0; i < ctx->res.header_count; i++) {
 | 
					  for (size_t i = 0; i < ctx->res.header_count; i++) {
 | 
				
			||||||
    if (ctx->res.headers[i].owned) {
 | 
					    if (ctx->res.headers[i].owned) {
 | 
				
			||||||
| 
						 | 
					@ -61,7 +45,4 @@ void http_loop_ctx_reset(http_loop_ctx *ctx) {
 | 
				
			||||||
  ctx->res.status = 0;
 | 
					  ctx->res.status = 0;
 | 
				
			||||||
  ctx->res.head_len = 0;
 | 
					  ctx->res.head_len = 0;
 | 
				
			||||||
  ctx->res.head_written = 0;
 | 
					  ctx->res.head_written = 0;
 | 
				
			||||||
  ctx->res.body_len = 0;
 | 
					 | 
				
			||||||
  ctx->res.body_written = 0;
 | 
					 | 
				
			||||||
  ctx->res.owns_body = false;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ void http_loop_init_header(http_response *res) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // First we calculate the size of the start of the header
 | 
					  // First we calculate the size of the start of the header
 | 
				
			||||||
  int buf_size = snprintf(NULL, 0, http_response_format, res->status,
 | 
					  int buf_size = snprintf(NULL, 0, http_response_format, res->status,
 | 
				
			||||||
                          response_type_name, res->body_len);
 | 
					                          response_type_name, res->body.expected_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // We add each header's required size
 | 
					  // We add each header's required size
 | 
				
			||||||
  for (size_t i = 0; i < res->header_count; i++) {
 | 
					  for (size_t i = 0; i < res->header_count; i++) {
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,7 @@ void http_loop_init_header(http_response *res) {
 | 
				
			||||||
  // with the required final newline
 | 
					  // with the required final newline
 | 
				
			||||||
  char *buf = malloc(buf_size + 1);
 | 
					  char *buf = malloc(buf_size + 1);
 | 
				
			||||||
  buf_size = sprintf(buf, http_response_format, res->status, response_type_name,
 | 
					  buf_size = sprintf(buf, http_response_format, res->status, response_type_name,
 | 
				
			||||||
                     res->body_len);
 | 
					                     res->body.expected_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  for (size_t i = 0; i < res->header_count; i++) {
 | 
					  for (size_t i = 0; i < res->header_count; i++) {
 | 
				
			||||||
    buf_size +=
 | 
					    buf_size +=
 | 
				
			||||||
| 
						 | 
					@ -59,7 +59,7 @@ void http_loop_write_response(event_loop_conn *conn) {
 | 
				
			||||||
  // The final iteration marks the end of the response, after which we reset the
 | 
					  // The final iteration marks the end of the response, after which we reset the
 | 
				
			||||||
  // context so a next request can be processed
 | 
					  // context so a next request can be processed
 | 
				
			||||||
  if (res->head_written == res->head_len &&
 | 
					  if (res->head_written == res->head_len &&
 | 
				
			||||||
      res->body_written == res->body_len) {
 | 
					      res->body.expected_len == res->body.len) {
 | 
				
			||||||
    http_loop_ctx_reset(conn->ctx);
 | 
					    http_loop_ctx_reset(conn->ctx);
 | 
				
			||||||
    conn->state = event_loop_conn_state_req;
 | 
					    conn->state = event_loop_conn_state_req;
 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
| 
						 | 
					@ -75,23 +75,23 @@ void http_loop_write_response(event_loop_conn *conn) {
 | 
				
			||||||
    res->head_written += bytes_to_write;
 | 
					    res->head_written += bytes_to_write;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (res->body_written < res->body_len) {
 | 
					  if (res->body.len < res->body.expected_len) {
 | 
				
			||||||
    size_t bytes_to_write = MIN(res->body_len - res->body_written,
 | 
					    size_t bytes_to_write = MIN(res->body.expected_len - res->body.len,
 | 
				
			||||||
                                EVENT_LOOP_BUFFER_SIZE - conn->wbuf_size);
 | 
					                                EVENT_LOOP_BUFFER_SIZE - conn->wbuf_size);
 | 
				
			||||||
    size_t bytes_written;
 | 
					    size_t bytes_written;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    switch (res->body_type) {
 | 
					    switch (res->body.type) {
 | 
				
			||||||
    case http_body_buf:
 | 
					    case http_body_buf:
 | 
				
			||||||
      memcpy(&conn->wbuf[conn->wbuf_size], &(res->body.buf)[res->body_written],
 | 
					      memcpy(&conn->wbuf[conn->wbuf_size], &(res->body.buf)[res->body.len],
 | 
				
			||||||
             bytes_to_write);
 | 
					             bytes_to_write);
 | 
				
			||||||
      conn->wbuf_size += bytes_to_write;
 | 
					      conn->wbuf_size += bytes_to_write;
 | 
				
			||||||
      res->body_written += bytes_to_write;
 | 
					      res->body.len += bytes_to_write;
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    case http_body_file:
 | 
					    case http_body_file:
 | 
				
			||||||
      bytes_written = fread(&conn->wbuf[conn->wbuf_size], sizeof(uint8_t),
 | 
					      bytes_written = fread(&conn->wbuf[conn->wbuf_size], sizeof(uint8_t),
 | 
				
			||||||
                            bytes_to_write, res->body.file);
 | 
					                            bytes_to_write, res->body.file);
 | 
				
			||||||
      conn->wbuf_size += bytes_written;
 | 
					      conn->wbuf_size += bytes_written;
 | 
				
			||||||
      res->body_written += bytes_written;
 | 
					      res->body.len += bytes_written;
 | 
				
			||||||
      break;
 | 
					      break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,7 +36,7 @@ static bool try_parse_content_length(event_loop_conn *conn) {
 | 
				
			||||||
    if (strncmp(header->name, "Content-Length", header->name_len) == 0) {
 | 
					    if (strncmp(header->name, "Content-Length", header->name_len) == 0) {
 | 
				
			||||||
      // If the content length header is present but contains an invalid
 | 
					      // If the content length header is present but contains an invalid
 | 
				
			||||||
      // number, we return a bad request error
 | 
					      // number, we return a bad request error
 | 
				
			||||||
      if (!string_to_num(&ctx->req.body_len, header->value,
 | 
					      if (!string_to_num(&ctx->req.body.expected_len, header->value,
 | 
				
			||||||
                         header->value_len)) {
 | 
					                         header->value_len)) {
 | 
				
			||||||
        ctx->res.status = http_bad_request;
 | 
					        ctx->res.status = http_bad_request;
 | 
				
			||||||
        conn->state = event_loop_conn_state_res;
 | 
					        conn->state = event_loop_conn_state_res;
 | 
				
			||||||
| 
						 | 
					@ -44,14 +44,14 @@ static bool try_parse_content_length(event_loop_conn *conn) {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      // The content length was actually 0, so we can instantly return here
 | 
					      // The content length was actually 0, so we can instantly return here
 | 
				
			||||||
      else if (ctx->req.body_len == 0) {
 | 
					      else if (ctx->req.body.expected_len == 0) {
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // A zero here means there's no content length header
 | 
					  // A zero here means there's no content length header
 | 
				
			||||||
  if (ctx->req.body_len == 0) {
 | 
					  if (ctx->req.body.expected_len == 0) {
 | 
				
			||||||
    ctx->res.status = http_length_required;
 | 
					    ctx->res.status = http_length_required;
 | 
				
			||||||
    conn->state = event_loop_conn_state_res;
 | 
					    conn->state = event_loop_conn_state_res;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,47 +64,47 @@ static bool try_parse_content_length(event_loop_conn *conn) {
 | 
				
			||||||
bool http_loop_step_body_to_buf(event_loop_conn *conn) {
 | 
					bool http_loop_step_body_to_buf(event_loop_conn *conn) {
 | 
				
			||||||
  http_loop_ctx *ctx = conn->ctx;
 | 
					  http_loop_ctx *ctx = conn->ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (ctx->req.body_len == 0) {
 | 
					  if (ctx->req.body.expected_len == 0) {
 | 
				
			||||||
    if (!try_parse_content_length(conn)) {
 | 
					    if (!try_parse_content_length(conn)) {
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ctx->req.body_type = http_body_buf;
 | 
					    ctx->req.body.type = http_body_buf;
 | 
				
			||||||
    ctx->req.body.buf = malloc(ctx->req.body_len * sizeof(uint8_t));
 | 
					    ctx->req.body.buf = malloc(ctx->req.body.expected_len * sizeof(uint8_t));
 | 
				
			||||||
    ctx->req.body_received = 0;
 | 
					    ctx->req.body.len = 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  size_t bytes_to_copy = MIN(conn->rbuf_size - conn->rbuf_read,
 | 
					  size_t bytes_to_copy = MIN(conn->rbuf_size - conn->rbuf_read,
 | 
				
			||||||
                             ctx->req.body_len - ctx->req.body_received);
 | 
					                             ctx->req.body.expected_len - ctx->req.body.len);
 | 
				
			||||||
  memcpy(&ctx->req.body.buf[ctx->req.body_received],
 | 
					  memcpy(&ctx->req.body.buf[ctx->req.body.len],
 | 
				
			||||||
         &conn->rbuf[conn->rbuf_read], bytes_to_copy);
 | 
					         &conn->rbuf[conn->rbuf_read], bytes_to_copy);
 | 
				
			||||||
  ctx->req.body_received += bytes_to_copy;
 | 
					  ctx->req.body.len += bytes_to_copy;
 | 
				
			||||||
  conn->rbuf_read += bytes_to_copy;
 | 
					  conn->rbuf_read += bytes_to_copy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return ctx->req.body_received == ctx->req.body_len;
 | 
					  return ctx->req.body.len == ctx->req.body.expected_len;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool http_loop_step_body_to_file(event_loop_conn *conn) {
 | 
					bool http_loop_step_body_to_file(event_loop_conn *conn) {
 | 
				
			||||||
  http_loop_ctx *ctx = conn->ctx;
 | 
					  http_loop_ctx *ctx = conn->ctx;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (ctx->req.body_len == 0) {
 | 
					  if (ctx->req.body.expected_len == 0) {
 | 
				
			||||||
    if (!try_parse_content_length(conn)) {
 | 
					    if (!try_parse_content_length(conn)) {
 | 
				
			||||||
      return true;
 | 
					      return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ctx->req.body_type = http_body_file;
 | 
					    ctx->req.body.type = http_body_file;
 | 
				
			||||||
    ctx->req.body.file = fopen(ctx->req.body_file_name, "wb");
 | 
					    ctx->req.body.file = fopen(ctx->req.body.fname, "wb");
 | 
				
			||||||
    ctx->req.body_received = 0;
 | 
					    ctx->req.body.len = 0;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  size_t bytes_to_write = MIN(conn->rbuf_size - conn->rbuf_read,
 | 
					  size_t bytes_to_write = MIN(conn->rbuf_size - conn->rbuf_read,
 | 
				
			||||||
                              ctx->req.body_len - ctx->req.body_received);
 | 
					                              ctx->req.body.expected_len - ctx->req.body.len);
 | 
				
			||||||
  size_t bytes_written = fwrite(&conn->rbuf[conn->rbuf_read], sizeof(uint8_t),
 | 
					  size_t bytes_written = fwrite(&conn->rbuf[conn->rbuf_read], sizeof(uint8_t),
 | 
				
			||||||
                                bytes_to_write, ctx->req.body.file);
 | 
					                                bytes_to_write, ctx->req.body.file);
 | 
				
			||||||
  ctx->req.body_received += bytes_written;
 | 
					  ctx->req.body.len += bytes_written;
 | 
				
			||||||
  conn->rbuf_read += bytes_written;
 | 
					  conn->rbuf_read += bytes_written;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return ctx->req.body_received == ctx->req.body_len;
 | 
					  return ctx->req.body.len == ctx->req.body.expected_len;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool http_loop_step_auth(event_loop_conn *conn) {
 | 
					bool http_loop_step_auth(event_loop_conn *conn) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,9 +63,9 @@ bool lander_post_redirect(event_loop_conn *conn) {
 | 
				
			||||||
      ctx->req.regex_groups[2].rm_eo == ctx->req.regex_groups[2].rm_so;
 | 
					      ctx->req.regex_groups[2].rm_eo == ctx->req.regex_groups[2].rm_so;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Allocate a new buffer to pass to the trie
 | 
					  // Allocate a new buffer to pass to the trie
 | 
				
			||||||
  char *url = malloc(ctx->req.body_len + 1);
 | 
					  char *url = malloc(ctx->req.body.len + 1);
 | 
				
			||||||
  memcpy(url, ctx->req.body.buf, ctx->req.body_len);
 | 
					  memcpy(url, ctx->req.body.buf, ctx->req.body.len);
 | 
				
			||||||
  url[ctx->req.body_len] = '\0';
 | 
					  url[ctx->req.body.len] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  Entry *new_entry = entry_new(Redirect, url);
 | 
					  Entry *new_entry = entry_new(Redirect, url);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,11 +101,11 @@ bool lander_post_paste(event_loop_conn *conn) {
 | 
				
			||||||
    return true;
 | 
					    return true;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // TODO free this
 | 
					 | 
				
			||||||
  char *fname = malloc(8 + key_len);
 | 
					  char *fname = malloc(8 + key_len);
 | 
				
			||||||
  sprintf(fname, "pastes/%.*s", key_len, key);
 | 
					  sprintf(fname, "pastes/%.*s", key_len, key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ctx->req.body_file_name = fname;
 | 
					  ctx->req.body.fname = fname;
 | 
				
			||||||
 | 
					  ctx->req.body.fname_owned = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (random) {
 | 
					  if (random) {
 | 
				
			||||||
    free(key);
 | 
					    free(key);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue