diff options
Diffstat (limited to 'src/reqs.c')
-rw-r--r-- | src/reqs.c | 37 |
1 files changed, 31 insertions, 6 deletions
@@ -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 @@ retry: 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. */ @@ -441,7 +447,7 @@ BAD_REQUEST_ERROR: goto fail; } - connptr->connect_method = TRUE; + connptr->connect_method = CM_TRUE; } else { #ifdef TRANSPARENT_PROXY if (!do_transparent_proxy @@ -635,7 +641,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, hashmap_t hashofheaders, char** lines, size_t* lines_len) { char *line = NULL; char *header = NULL; @@ -655,6 +661,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 @@ -1013,7 +1027,7 @@ retry: /* * 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); @@ -1525,6 +1539,9 @@ void handle_connection (struct conn_s *connptr, union sockaddr_union* addr) char sock_ipaddr[IP_LENGTH]; char sock_ipaddr_alt[IP_LENGTH]=""; char peer_ipaddr[IP_LENGTH]; + char peer_string[HOSTNAME_LENGTH]; + char *lines = NULL; + size_t lines_len = 0; getpeer_information (addr, peer_ipaddr, sizeof(peer_ipaddr)); @@ -1585,7 +1602,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", @@ -1611,7 +1628,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", @@ -1705,6 +1722,11 @@ e401: "file descriptor %d.", request->host, connptr->server_fd); + if(hashmap_search(hashofheaders, "upgrade") > 0) { + connptr->connect_method = CM_UPGRADE; + safe_write (connptr->server_fd, lines, lines_len); + } + if (!connptr->connect_method) establish_http_connection (connptr, request); } @@ -1731,6 +1753,8 @@ e401: HC_FAIL(); } + } else if (connptr->connect_method == CM_UPGRADE) { + /* NOP */ ; } else { if (send_ssl_response (connptr) < 0) { log_message (LOG_ERR, @@ -1749,6 +1773,7 @@ e401: connptr->client_fd, connptr->server_fd); done: + safefree(lines); free_request_struct (request); orderedmap_destroy (hashofheaders); conn_destroy_contents (connptr); |