diff --git a/src/http/http.c b/src/http/http.c
index fa0ce07..d23986a 100644
--- a/src/http/http.c
+++ b/src/http/http.c
@@ -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
Hello world!
\n";
send(req->connection->fd, response, strlen(response), 0);
}
@@ -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;
@@ -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");
diff --git a/src/http/http_parser.c b/src/http/http_parser.c
index d32ec4b..7c27423 100644
--- a/src/http/http_parser.c
+++ b/src/http/http_parser.c
@@ -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"
@@ -418,6 +417,7 @@ 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;
@@ -425,6 +425,7 @@ int lx_http_parser_exec(lx_http_parser_t *parser, lx_buf_t *data) {
}
if (parser->state == h_end) {
+ parser->nread = buf - data->buf;
return LX_COMPLETE;
}
diff --git a/src/main.c b/src/main.c
index 60f8b6b..da4deca 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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();