diff --git a/src/client.c b/src/client.c index cf62b20..ea542cc 100644 --- a/src/client.c +++ b/src/client.c @@ -102,15 +102,15 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int if (ret < 0) { goto abort; } else if (ret == 1) { - sprintf(err_msg, "Unable to parse header: Invalid header format."); + sprintf(err_msg, "Unable to parse http header: Invalid header format."); } else if (ret == 2) { - sprintf(err_msg, "Unable to parse header: Invalid method."); + sprintf(err_msg, "Unable to parse http header: Invalid method."); } else if (ret == 3) { - sprintf(err_msg, "Unable to parse header: Invalid version."); + sprintf(err_msg, "Unable to parse http header: Invalid version."); } else if (ret == 4) { - sprintf(err_msg, "Unable to parse header: Header contains illegal characters."); + sprintf(err_msg, "Unable to parse http header: Header contains illegal characters."); } else if (ret == 5) { - sprintf(err_msg, "Unable to parse header: End of header not found."); + sprintf(err_msg, "Unable to parse http header: End of header not found."); } res.status = http_get_status(400); goto respond; @@ -138,7 +138,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int strcpy(host, host_ptr); } - sprintf(log_req_prefix, "[%s%24s%s]%s ", BLD_STR, host, CLR_STR, log_client_prefix); + sprintf(log_req_prefix, "[%6i][%s%24s%s]%s ", getpid(), BLD_STR, host, CLR_STR, log_client_prefix); log_prefix = log_req_prefix; print(BLD_STR "%s %s" CLR_STR, req.method, req.uri); @@ -448,6 +448,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int ret = rev_proxy_init(&req, &res, conf, client, &custom_status, err_msg); use_rev_proxy = (ret == 0); + /* char *content_encoding = http_get_header_field(&res.hdr, "Content-Encoding"); if (use_rev_proxy && content_encoding == NULL) { int http_comp = http_get_compression(&req, &res); @@ -456,7 +457,6 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int } else if (http_comp & COMPRESS_GZ) { use_rev_proxy |= REV_PROXY_COMPRESS_GZ; } - use_rev_proxy &= ~REV_PROXY_COMPRESS; } char *transfer_encoding = http_get_header_field(&res.hdr, "Transfer-Encoding"); @@ -470,6 +470,7 @@ int client_request_handler(sock *client, unsigned long client_num, unsigned int if (ret > 0) { http_add_header_field(&res.hdr, "Transfer-Encoding", buf0); } + */ } else { print(ERR_STR "Unknown host type: %i" CLR_STR, conf->type); res.status = http_get_status(501); @@ -706,6 +707,7 @@ int client_connection_handler(sock *client, unsigned long client_num) { client->_ssl_error = ERR_get_error(); if (ret <= 0) { print(ERR_STR "Unable to perform handshake: %s" CLR_STR, sock_strerror(client)); + ret = -1; goto close; } } @@ -768,12 +770,13 @@ int client_handler(sock *client, unsigned long client_num, struct sockaddr_in6 * ntohs(client_addr->sin6_port), CLR_STR); log_conn_prefix = malloc(256); - sprintf(log_conn_prefix, "[%24s]%s ", server_addr_str, log_client_prefix); + sprintf(log_conn_prefix, "[%6i][%24s]%s ", getpid(), server_addr_str, log_client_prefix); log_prefix = log_conn_prefix; print("Started child process with PID %i", getpid()); ret = client_connection_handler(client, client_num); + free(client_addr_str_ptr); client_addr_str_ptr = NULL; free(server_addr_str_ptr); @@ -788,5 +791,6 @@ int client_handler(sock *client, unsigned long client_num, struct sockaddr_in6 * log_req_prefix = NULL; free(log_client_prefix); log_client_prefix = NULL; + return ret; } diff --git a/src/lib/fastcgi.c b/src/lib/fastcgi.c index cfd50ff..86cc8ee 100644 --- a/src/lib/fastcgi.c +++ b/src/lib/fastcgi.c @@ -423,6 +423,7 @@ int fastcgi_send(fastcgi_conn *conn, sock *client, int flags) { print(ERR_STR "Unable to receive from PHP-FPM" CLR_STR); return -1; } + req_id = (header.requestIdB1 << 8) | header.requestIdB0; content_len = (header.contentLengthB1 << 8) | header.contentLengthB0; content = malloc(content_len + header.paddingLength); diff --git a/src/lib/http.c b/src/lib/http.c index b63d8eb..b723b63 100644 --- a/src/lib/http.c +++ b/src/lib/http.c @@ -33,7 +33,7 @@ void http_free_hdr(http_hdr *hdr) { } void http_free_req(http_req *req) { - if (req->uri == NULL) free(req->uri); + if (req->uri != NULL) free(req->uri); req->uri = NULL; http_free_hdr(&req->hdr); } @@ -85,19 +85,19 @@ int http_receive_request(sock *client, http_req *req) { while (1) { rcv_len = sock_recv(client, buf, CLIENT_MAX_HEADER_SIZE, 0); if (rcv_len <= 0) { - print("Unable to receive: %s", sock_strerror(client)); + print("Unable to receive http header: %s", sock_strerror(client)); return -1; } unsigned long header_len = strstr(buf, "\r\n\r\n") - buf + 4; if (header_len <= 0) { - print(ERR_STR "Unable to parse header: End of header not found" CLR_STR); + print(ERR_STR "Unable to parse http header: End of header not found" CLR_STR); return 5; } for (int i = 0; i < header_len; i++) { if ((buf[i] >= 0x00 && buf[i] <= 0x1F && buf[i] != '\r' && buf[i] != '\n') || buf[i] == 0x7F) { - print(ERR_STR "Unable to parse header: Header contains illegal characters" CLR_STR); + print(ERR_STR "Unable to parse http header: Header contains illegal characters" CLR_STR); return 4; } } @@ -106,7 +106,7 @@ int http_receive_request(sock *client, http_req *req) { 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); + print(ERR_STR "Unable to parse http header: Invalid header format" CLR_STR); return 1; } @@ -115,13 +115,13 @@ int http_receive_request(sock *client, http_req *req) { if (pos1 == NULL) goto err_hdr_fmt; if (pos1 - ptr - 1 >= sizeof(req->method)) { - print(ERR_STR "Unable to parse header: Method name too long" CLR_STR); + print(ERR_STR "Unable to parse http header: Method name too long" CLR_STR); return 2; } for (int i = 0; i < (pos1 - ptr - 1); i++) { if (ptr[i] < 'A' || ptr[i] > 'Z') { - print(ERR_STR "Unable to parse header: Invalid method" CLR_STR); + print(ERR_STR "Unable to parse http header: Invalid method" CLR_STR); return 2; } } @@ -130,12 +130,12 @@ int http_receive_request(sock *client, http_req *req) { pos2 = memchr(pos1, ' ', rcv_len - (pos1 - buf)) + 1; if (pos2 == NULL) { err_hdr_fmt: - print(ERR_STR "Unable to parse header: Invalid header format" CLR_STR); + print(ERR_STR "Unable to parse http header: Invalid header format" CLR_STR); return 1; } if (memcmp(pos2, "HTTP/", 5) != 0 || memcmp(pos2 + 8, "\r\n", 2) != 0) { - print(ERR_STR "Unable to parse header: Invalid version" CLR_STR); + print(ERR_STR "Unable to parse http header: Invalid version" CLR_STR); return 3; } diff --git a/src/lib/rev_proxy.c b/src/lib/rev_proxy.c index 3f1c637..e950867 100644 --- a/src/lib/rev_proxy.c +++ b/src/lib/rev_proxy.c @@ -404,18 +404,21 @@ int rev_proxy_send(sock *client, unsigned long len_to_send, int flags) { } do { + snd_len = 0; if (flags & REV_PROXY_CHUNKED) { + char *pos; ret = sock_recv(&rev_proxy, buffer, 16, MSG_PEEK); - if (ret <= 0) { - print("Unable to receive: %s", sock_strerror(&rev_proxy)); - break; - } + if (ret <= 0) goto err0; len_to_send = strtol(buffer, NULL, 16); - char *pos = strstr(buffer, "\r\n"); + pos = strstr(buffer, "\r\n"); len = pos - buffer + 2; sock_recv(&rev_proxy, buffer, len, 0); - if (ret <= 0) break; + if (ret <= 0) { + err0: + print("Unable to receive from server: %s", sock_strerror(&rev_proxy)); + break; + } if (len_to_send == 0 && (flags & REV_PROXY_COMPRESS)) { finish_comp = 1; @@ -425,10 +428,14 @@ int rev_proxy_send(sock *client, unsigned long len_to_send, int flags) { compress_free(&comp_ctx); } } - snd_len = 0; while (snd_len < len_to_send) { unsigned long avail_in, avail_out; - len = sock_recv(&rev_proxy, buffer, CHUNK_SIZE < (len_to_send - snd_len) ? CHUNK_SIZE : len_to_send - snd_len, 0); + ret = sock_recv(&rev_proxy, buffer, CHUNK_SIZE < (len_to_send - snd_len) ? CHUNK_SIZE : len_to_send - snd_len, 0); + if (ret <= 0) { + print("Unable to receive from server: %s", sock_strerror(&rev_proxy)); + break; + } + len = ret; ptr = buffer; out: avail_in = len; @@ -466,8 +473,14 @@ int rev_proxy_send(sock *client, unsigned long len_to_send, int flags) { if (flags & REV_PROXY_CHUNKED) sock_recv(&rev_proxy, buffer, 2, 0); } while ((flags & REV_PROXY_CHUNKED) && len_to_send > 0); + if (ret <= 0) return (int) -1; + if (flags & REV_PROXY_CHUNKED) { - sock_send(client, "0\r\n\r\n", 5, 0); + ret = sock_send(client, "0\r\n\r\n", 5, 0); + if (ret <= 0) { + print(ERR_STR "Unable to send: %s" CLR_STR, sock_strerror(client)); + return -1; + } } return 0; diff --git a/src/lib/sock.c b/src/lib/sock.c index 37d9bf6..9ed83ec 100644 --- a/src/lib/sock.c +++ b/src/lib/sock.c @@ -52,12 +52,12 @@ long sock_send(sock *s, void *buf, unsigned long len, int flags) { long ret; if (s->enc) { ret = SSL_write(s->ssl, buf, (int) len); + s->_ssl_error = ERR_get_error(); } else { ret = send(s->socket, buf, len, flags); } s->_last_ret = ret; s->_errno = errno; - s->_ssl_error = ERR_get_error(); return ret >= 0 ? ret : -1; } @@ -69,12 +69,12 @@ long sock_recv(sock *s, void *buf, unsigned long len, int flags) { } else { ret = SSL_read(s->ssl, buf, (int) len); } + s->_ssl_error = ERR_get_error(); } else { ret = recv(s->socket, buf, len, flags); } s->_last_ret = ret; s->_errno = errno; - s->_ssl_error = ERR_get_error(); return ret >= 0 ? ret : -1; } @@ -97,14 +97,14 @@ long sock_splice(sock *dst, sock *src, void *buf, unsigned long buf_len, unsigne int sock_close(sock *s) { if ((int) s->enc && s->ssl != NULL) { - SSL_shutdown(s->ssl); + if (s->_last_ret >= 0) SSL_shutdown(s->ssl); SSL_free(s->ssl); + s->ssl = NULL; } shutdown(s->socket, SHUT_RDWR); close(s->socket); s->socket = 0; s->enc = 0; - s->ssl = NULL; return 0; } diff --git a/src/necronda-server.h b/src/necronda-server.h index 46a083a..6c9bd9c 100644 --- a/src/necronda-server.h +++ b/src/necronda-server.h @@ -15,7 +15,7 @@ #define MAX_CHILDREN 1024 #define MAX_MMDB 3 #define LISTEN_BACKLOG 16 -#define REQ_PER_CONNECTION 100 +#define REQ_PER_CONNECTION 200 #define CLIENT_TIMEOUT 3600 #define SERVER_TIMEOUT 4