From 798c41f1c888b94e712e960941923f94dad65d00 Mon Sep 17 00:00:00 2001 From: Lorenz Stechauner Date: Tue, 29 Dec 2020 11:48:56 +0100 Subject: [PATCH] Bugfix for POST and PUT method --- src/client.c | 5 +++++ src/fastcgi.c | 8 ++++++++ src/http.c | 17 +++++++++++++---- src/necronda-server.c | 3 +++ src/necronda-server.h | 3 +++ 5 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/client.c b/src/client.c index 9c90b7b..d554cf8 100644 --- a/src/client.c +++ b/src/client.c @@ -419,6 +419,11 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int if (php_fpm.socket != 0) close(php_fpm.socket); http_free_req(&req); http_free_res(&res); + if (client->buf != NULL) { + free(client->buf); + client->buf_off = 0; + client->buf_len = 0; + } return !client_keep_alive; } diff --git a/src/fastcgi.c b/src/fastcgi.c index b0790bf..61ac8e1 100644 --- a/src/fastcgi.c +++ b/src/fastcgi.c @@ -510,6 +510,13 @@ int fastcgi_receive(fastcgi_conn *conn, sock *client, unsigned long len) { .paddingLength = 0, .reserved = 0 }; + + if (client->buf != NULL && client->buf_len - client->buf_off > 0) { + ret = (int) (client->buf_len - client->buf_off); + memcpy(buf, client->buf + client->buf_off, ret); + goto send; + } + while (rcv_len < len) { if (client->enc) { ret = SSL_read(client->ssl, buf, sizeof(buf)); @@ -524,6 +531,7 @@ int fastcgi_receive(fastcgi_conn *conn, sock *client, unsigned long len) { return -1; } } + send: rcv_len += ret; header.contentLengthB1 = (ret >> 8) & 0xFF; header.contentLengthB0 = ret & 0xFF; diff --git a/src/http.c b/src/http.c index 1e874b6..8bf64c7 100644 --- a/src/http.c +++ b/src/http.c @@ -115,7 +115,7 @@ int http_receive_request(sock *client, http_req *req) { } ptr = buf; - while (header_len != (ptr - buf)) { + while (header_len > (ptr - buf + 2)) { pos0 = strstr(ptr, "\r\n"); if (pos0 == NULL) { print(ERR_STR "Unable to parse header: Invalid header format" CLR_STR); @@ -159,12 +159,21 @@ int http_receive_request(sock *client, http_req *req) { int ret = http_parse_header_field(&req->hdr, ptr, pos0); if (ret != 0) return ret; } - if (pos0[2] == '\r' && pos0[3] == '\n') { - return 0; - } ptr = pos0 + 2; } + if (pos0[2] == '\r' && pos0[3] == '\n') { + break; + } } + + client->buf_len = rcv_len - (pos0 - buf + 4); + if (client->buf_len > 0) { + client->buf = malloc(client->buf_len); + client->buf_off = 0; + memcpy(client->buf, pos0 + 4, client->buf_len); + } + + return 0; } char *http_get_header_field(const http_hdr *hdr, const char *field_name) { diff --git a/src/necronda-server.c b/src/necronda-server.c index 4634ba9..7157df3 100644 --- a/src/necronda-server.c +++ b/src/necronda-server.c @@ -285,6 +285,9 @@ int main(int argc, const char *argv[]) { openssl_init(); + client.buf = NULL; + client.buf_len = 0; + client.buf_off = 0; client.ctx = SSL_CTX_new(TLS_server_method()); SSL_CTX_set_options(client.ctx, SSL_OP_SINGLE_DH_USE); SSL_CTX_set_verify(client.ctx, SSL_VERIFY_NONE, NULL); diff --git a/src/necronda-server.h b/src/necronda-server.h index a13b214..26eeeca 100644 --- a/src/necronda-server.h +++ b/src/necronda-server.h @@ -75,6 +75,9 @@ typedef struct { int socket; SSL_CTX *ctx; SSL *ssl; + char *buf; + unsigned long buf_len; + unsigned long buf_off; } sock; char *ssl_get_error(SSL *ssl, int ret);