Skip to content

Commit

Permalink
http: add primitive way of handling body
Browse files Browse the repository at this point in the history
  • Loading branch information
michaldziuba03 committed Jul 25, 2024
1 parent 31c34ea commit 26ee1f3
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 4 deletions.
70 changes: 68 additions & 2 deletions src/http/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ void print_raw_headers(http_request_t *req) {
void lx_http_on_request(http_request_t *req) {
log_info("%s %s", http_map_method(req->method), req->path);
print_raw_headers(req);

if (req->body) {
log_info("Request with body (%ld):", req->received);
//fwrite(req->body, 1, req->received + 1, stdout);
for (size_t i = 0; i < req->received; ++i) {
printf("%c", req->body[i]);
}
printf("\n");
}

const char *response = "HTTP/1.1 200 OK\r\nContent-Length: 22\r\nContent-Type: text/html\r\n\r\n<h1>Hello world!</h1>\n";
send(req->connection->fd, response, strlen(response), 0);
}
Expand All @@ -32,6 +42,38 @@ void lx_http_on_request(http_request_t *req) {

#define MAX_BODY_BUFFER 16000

void lx_http_read_body(lx_connection_t *conn) {
lx_http_t *http_ctx = lx_http_ctx(conn);
http_request_t *req = conn->data;

size_t to_read = req->content_length - req->received;

if (to_read <= 0) {
lx_http_on_request(req);
lx_close(conn);
return;
}

size_t chunk_size = recv(conn->fd, req->body + req->received, to_read, 0);
if (chunk_size < 0) {
perror("body:recv");
lx_close(conn);
return;
}

if (chunk_size == 0) {
lx_close(conn);
return;
}

req->received += chunk_size;

if (req->content_length <= req->received) {
lx_http_on_request(req);
lx_close(conn);
}
}

void lx_http_read_headers(lx_connection_t *conn) {
lx_http_t *http_ctx = lx_http_ctx(conn);
http_request_t *req = conn->data;
Expand Down Expand Up @@ -64,8 +106,32 @@ void lx_http_read_headers(lx_connection_t *conn) {

switch (parser_code) {
case LX_COMPLETE:
lx_http_on_request(req);
lx_close(conn);
size_t nread = req->parser.nread;
if (req->content_length == 0) {
lx_http_on_request(req);
lx_close(conn);
return;
}

if (req->content_length > MAX_BODY_BUFFER) {
log_err("Too big body");
lx_close(conn);
return;
}

req->body = malloc(req->content_length * sizeof(char));
if (conn->size > nread) {
memcpy(req->body, conn->buf + nread, conn->size - nread);
req->received += conn->size - nread;
}

if (req->received == req->content_length) {
lx_http_on_request(req);
lx_close(conn);
return;
}

conn->ondata = lx_http_read_body;
return;
case LX_PARTIAL:
log_info("Received partial data");
Expand Down
3 changes: 2 additions & 1 deletion src/http/http_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ void lx_http_parser_init(lx_http_parser_t *parser) {
}

#define CONTENT_LENGTH "content-length"

#define CONNECTION "connection"
#define CLOSE "close"
#define UPGRADE "upgrade"
Expand Down Expand Up @@ -418,13 +417,15 @@ int lx_http_parser_exec(lx_http_parser_t *parser, lx_buf_t *data) {
}
break;
case h_end:
parser->nread = buf - data->buf;
return LX_COMPLETE;
default:
return LX_UNEXPECTED_ERROR;
}
}

if (parser->state == h_end) {
parser->nread = buf - data->buf;
return LX_COMPLETE;
}

Expand Down
2 changes: 1 addition & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#define DEFAULT_PORT 8000
#define DEFAULT_WORKERS 4

void handle_onrequest() {}
void handle_onrequest(http_request_t *req) {}

void worker(int id, int port) {
lx_io_t ctx = lx_init();
Expand Down

0 comments on commit 26ee1f3

Please sign in to comment.