diff --git a/src/conns.h b/src/conns.h index 9618efbb..2f33b365 100644 --- a/src/conns.h +++ b/src/conns.h @@ -24,6 +24,12 @@ #include "main.h" #include "hsearch.h" +enum connect_method_e { + CM_FALSE = 0, + CM_TRUE = 1, + CM_UPGRADE = 2, +}; + /* * Connection Definition */ @@ -37,8 +43,9 @@ struct conn_s { /* The request line (first line) from the client */ char *request_line; + enum connect_method_e connect_method; + /* Booleans */ - unsigned int connect_method; unsigned int show_stats; /* diff --git a/src/reqs.c b/src/reqs.c index a6289a4d..911fb349 100644 --- a/src/reqs.c +++ b/src/reqs.c @@ -90,7 +90,7 @@ * connections. The request line is allocated from the heap, but it must * be freed in another function. */ -static int read_request_line (struct conn_s *connptr) +static int read_request_line (struct conn_s *connptr, char** lines, size_t* lines_len) { ssize_t len; @@ -104,6 +104,12 @@ static int read_request_line (struct conn_s *connptr) return -1; } + *lines = saferealloc(*lines, *lines_len + len + 1); + if(*lines) { + strcpy(*lines + *lines_len, connptr->request_line); + *lines_len += len; + } + /* * Strip the new line and carriage return from the string. */ @@ -448,7 +454,7 @@ static struct request_s *process_request (struct conn_s *connptr, goto fail; } - connptr->connect_method = TRUE; + connptr->connect_method = CM_TRUE; } else { #ifdef TRANSPARENT_PROXY if (!do_transparent_proxy @@ -672,7 +678,7 @@ add_header_to_connection (orderedmap hashofheaders, char *header, size_t len) /* * Read all the headers from the stream */ -static int get_all_headers (int fd, orderedmap hashofheaders) +static int get_all_headers (int fd, orderedmap hashofheaders, char** lines, size_t* lines_len) { char *line = NULL; char *header = NULL; @@ -692,6 +698,14 @@ static int get_all_headers (int fd, orderedmap hashofheaders) return -1; } + if(lines) { + *lines = saferealloc(*lines, *lines_len + linelen + 1); + if(*lines) { + strcpy(*lines + *lines_len, line); + *lines_len += linelen; + } + } + /* * If we received a CR LF or a non-continuation line, then add * the accumulated header field, if any, to the hashmap, and @@ -1062,7 +1076,7 @@ static int process_server_headers (struct conn_s *connptr) /* * Get all the headers from the remote server in a big hash */ - if (get_all_headers (connptr->server_fd, hashofheaders) < 0) { + if (get_all_headers (connptr->server_fd, hashofheaders, NULL, NULL) < 0) { log_message (LOG_WARNING, "Could not retrieve all the headers from the remote server."); orderedmap_destroy (hashofheaders); @@ -1577,6 +1591,8 @@ void handle_connection (struct conn_s *connptr, union sockaddr_union* addr) char sock_ipaddr[IP_LENGTH]; char peer_ipaddr[IP_LENGTH]; + char *lines = NULL; + size_t lines_len = 0; getpeer_information (addr, peer_ipaddr, sizeof(peer_ipaddr)); @@ -1620,7 +1636,7 @@ void handle_connection (struct conn_s *connptr, union sockaddr_union* addr) HC_FAIL(); } - if (read_request_line (connptr) < 0) { + if (read_request_line (connptr, &lines, &lines_len) < 0) { update_stats (STAT_BADCONN); indicate_http_error (connptr, 408, "Timeout", "detail", @@ -1646,7 +1662,7 @@ void handle_connection (struct conn_s *connptr, union sockaddr_union* addr) /* * Get all the headers from the client in a big hash. */ - if (get_all_headers (connptr->client_fd, hashofheaders) < 0) { + if (get_all_headers (connptr->client_fd, hashofheaders, &lines, &lines_len) < 0) { log_message (LOG_WARNING, "Could not retrieve all the headers from the client"); indicate_http_error (connptr, 400, "Bad Request", @@ -1739,6 +1755,11 @@ void handle_connection (struct conn_s *connptr, union sockaddr_union* addr) "file descriptor %d.", request->host, connptr->server_fd); + if(orderedmap_find (hashofheaders, "upgrade")) { + connptr->connect_method = CM_UPGRADE; + safe_write (connptr->server_fd, lines, lines_len); + } + if (!connptr->connect_method) establish_http_connection (connptr, request); } @@ -1765,6 +1786,8 @@ void handle_connection (struct conn_s *connptr, union sockaddr_union* addr) HC_FAIL(); } + } else if (connptr->connect_method == CM_UPGRADE) { + /* NOP */ ; } else { if (send_ssl_response (connptr) < 0) { log_message (LOG_ERR, @@ -1783,6 +1806,7 @@ void handle_connection (struct conn_s *connptr, union sockaddr_union* addr) connptr->client_fd, connptr->server_fd); done: + safefree(lines); free_request_struct (request); orderedmap_destroy (hashofheaders); conn_destroy_contents (connptr);
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: