diff options
Diffstat (limited to 'src/reqs.c')
-rw-r--r-- | src/reqs.c | 401 |
1 files changed, 184 insertions, 217 deletions
@@ -32,7 +32,8 @@ #include "buffer.h" #include "conns.h" #include "filter.h" -#include "hashmap.h" +#include "hsearch.h" +#include "orderedmap.h" #include "heap.h" #include "html-error.h" #include "log.h" @@ -42,7 +43,7 @@ #include "stats.h" #include "text.h" #include "utils.h" -#include "vector.h" +#include "sblist.h" #include "reverse-proxy.h" #include "transparent-proxy.h" #include "upstream.h" @@ -50,6 +51,7 @@ #include "conf.h" #include "basicauth.h" #include "loop.h" +#include "mypoll.h" /* * Maximum length of a HTTP line @@ -321,7 +323,7 @@ static int send_ssl_response (struct conn_s *connptr) * build a new request line. Finally connect to the remote server. */ static struct request_s *process_request (struct conn_s *connptr, - hashmap_t hashofheaders) + orderedmap hashofheaders) { char *url; struct request_s *request; @@ -602,7 +604,7 @@ static int add_xtinyproxy_header (struct conn_s *connptr) * can be retrieved and manipulated later. */ static int -add_header_to_connection (hashmap_t hashofheaders, char *header, size_t len) +add_header_to_connection (orderedmap hashofheaders, char *header, size_t len) { char *sep; @@ -620,7 +622,7 @@ add_header_to_connection (hashmap_t hashofheaders, char *header, size_t len) /* Calculate the new length of just the data */ len -= sep - header - 1; - return hashmap_insert (hashofheaders, header, sep, len); + return orderedmap_append (hashofheaders, header, sep); } /* @@ -633,7 +635,7 @@ add_header_to_connection (hashmap_t hashofheaders, char *header, size_t len) /* * Read all the headers from the stream */ -static int get_all_headers (int fd, hashmap_t hashofheaders) +static int get_all_headers (int fd, orderedmap hashofheaders) { char *line = NULL; char *header = NULL; @@ -726,7 +728,7 @@ static int get_all_headers (int fd, hashmap_t hashofheaders) * Extract the headers to remove. These headers were listed in the Connection * and Proxy-Connection headers. */ -static int remove_connection_headers (hashmap_t hashofheaders) +static int remove_connection_headers (orderedmap hashofheaders) { static const char *headers[] = { "connection", @@ -740,12 +742,13 @@ static int remove_connection_headers (hashmap_t hashofheaders) for (i = 0; i != (sizeof (headers) / sizeof (char *)); ++i) { /* Look for the connection header. If it's not found, return. */ - len = - hashmap_entry_by_key (hashofheaders, headers[i], - (void **) &data); - if (len <= 0) + data = orderedmap_find(hashofheaders, headers[i]); + + if (!data) return 0; + len = strlen(data); + /* * Go through the data line and replace any special characters * with a NULL. @@ -760,7 +763,7 @@ static int remove_connection_headers (hashmap_t hashofheaders) */ ptr = data; while (ptr < data + len) { - hashmap_remove (hashofheaders, ptr); + orderedmap_remove (hashofheaders, ptr); /* Advance ptr to the next token */ ptr += strlen (ptr) + 1; @@ -769,7 +772,7 @@ static int remove_connection_headers (hashmap_t hashofheaders) } /* Now remove the connection header it self. */ - hashmap_remove (hashofheaders, headers[i]); + orderedmap_remove (hashofheaders, headers[i]); } return 0; @@ -779,16 +782,14 @@ static int remove_connection_headers (hashmap_t hashofheaders) * If there is a Content-Length header, then return the value; otherwise, return * a negative number. */ -static long get_content_length (hashmap_t hashofheaders) +static long get_content_length (orderedmap hashofheaders) { - ssize_t len; char *data; long content_length = -1; - len = - hashmap_entry_by_key (hashofheaders, "content-length", - (void **) &data); - if (len > 0) + data = orderedmap_find (hashofheaders, "content-length"); + + if (data) content_length = atol (data); return content_length; @@ -802,10 +803,9 @@ static long get_content_length (hashmap_t hashofheaders) * purposes. */ static int -write_via_header (int fd, hashmap_t hashofheaders, +write_via_header (int fd, orderedmap hashofheaders, unsigned int major, unsigned int minor) { - ssize_t len; char hostname[512]; char *data; int ret; @@ -825,14 +825,14 @@ write_via_header (int fd, hashmap_t hashofheaders, * See if there is a "Via" header. If so, again we need to do a bit * of processing. */ - len = hashmap_entry_by_key (hashofheaders, "via", (void **) &data); - if (len > 0) { + data = orderedmap_find (hashofheaders, "via"); + if (data) { ret = write_message (fd, "Via: %s, %hu.%hu %s (%s/%s)\r\n", data, major, minor, hostname, PACKAGE, VERSION); - hashmap_remove (hashofheaders, "via"); + orderedmap_remove (hashofheaders, "via"); } else { ret = write_message (fd, "Via: %hu.%hu %s (%s/%s)\r\n", @@ -846,7 +846,7 @@ done: /* * Number of buckets to use internally in the hashmap. */ -#define HEADER_BUCKETS 256 +#define HEADER_BUCKETS 32 /* * Here we loop through all the headers the client is sending. If we @@ -855,7 +855,7 @@ done: * - rjkaes */ static int -process_client_headers (struct conn_s *connptr, hashmap_t hashofheaders) +process_client_headers (struct conn_s *connptr, orderedmap hashofheaders) { static const char *skipheaders[] = { "host", @@ -866,7 +866,7 @@ process_client_headers (struct conn_s *connptr, hashmap_t hashofheaders) "upgrade" }; int i; - hashmap_iter iter; + size_t iter; int ret = 0; char *data, *header; @@ -899,7 +899,7 @@ process_client_headers (struct conn_s *connptr, hashmap_t hashofheaders) * Delete the headers listed in the skipheaders list */ for (i = 0; i != (sizeof (skipheaders) / sizeof (char *)); i++) { - hashmap_remove (hashofheaders, skipheaders[i]); + orderedmap_remove (hashofheaders, skipheaders[i]); } /* Send, or add the Via header */ @@ -919,27 +919,22 @@ process_client_headers (struct conn_s *connptr, hashmap_t hashofheaders) /* * Output all the remaining headers to the remote machine. */ - iter = hashmap_first (hashofheaders); - if (iter >= 0) { - for (; !hashmap_is_end (hashofheaders, iter); ++iter) { - hashmap_return_entry (hashofheaders, - iter, &data, (void **) &header); - - if (!is_anonymous_enabled (config) - || anonymous_search (config, data) > 0) { - ret = - write_message (connptr->server_fd, - "%s: %s\r\n", data, header); - if (ret < 0) { - indicate_http_error (connptr, 503, - "Could not send data to remote server", - "detail", - "A network error occurred while " - "trying to write data to the " - "remote web server.", - NULL); - goto PULL_CLIENT_DATA; - } + iter = 0; + while((iter = orderedmap_next(hashofheaders, iter, &data, &header))) { + if (!is_anonymous_enabled (config) + || anonymous_search (config, data) > 0) { + ret = + write_message (connptr->server_fd, + "%s: %s\r\n", data, header); + if (ret < 0) { + indicate_http_error (connptr, 503, + "Could not send data to remote server", + "detail", + "A network error occurred while " + "trying to write data to the " + "remote web server.", + NULL); + goto PULL_CLIENT_DATA; } } } @@ -979,8 +974,8 @@ static int process_server_headers (struct conn_s *connptr) char *response_line; - hashmap_t hashofheaders; - hashmap_iter iter; + orderedmap hashofheaders; + size_t iter; char *data, *header; ssize_t len; int i; @@ -1009,7 +1004,7 @@ retry: goto retry; } - hashofheaders = hashmap_create (HEADER_BUCKETS); + hashofheaders = orderedmap_create (HEADER_BUCKETS); if (!hashofheaders) { safefree (response_line); return -1; @@ -1021,7 +1016,7 @@ retry: if (get_all_headers (connptr->server_fd, hashofheaders) < 0) { log_message (LOG_WARNING, "Could not retrieve all the headers from the remote server."); - hashmap_delete (hashofheaders); + orderedmap_destroy (hashofheaders); safefree (response_line); indicate_http_error (connptr, 503, @@ -1040,7 +1035,7 @@ retry: * Instead we'll free all the memory and return. */ if (connptr->protocol.major < 1) { - hashmap_delete (hashofheaders); + orderedmap_destroy (hashofheaders); safefree (response_line); return 0; } @@ -1067,7 +1062,7 @@ retry: * Delete the headers listed in the skipheaders list */ for (i = 0; i != (sizeof (skipheaders) / sizeof (char *)); i++) { - hashmap_remove (hashofheaders, skipheaders[i]); + orderedmap_remove (hashofheaders, skipheaders[i]); } /* Send, or add the Via header */ @@ -1089,8 +1084,7 @@ retry: /* Rewrite the HTTP redirect if needed */ if (config->reversebaseurl && - hashmap_entry_by_key (hashofheaders, "location", - (void **) &header) > 0) { + (header = orderedmap_find (hashofheaders, "location"))) { /* Look for a matching entry in the reversepath list */ while (reverse) { @@ -1115,7 +1109,7 @@ retry: "Rewriting HTTP redirect: %s -> %s%s%s", header, config->reversebaseurl, (reverse->path + 1), (header + len)); - hashmap_remove (hashofheaders, "location"); + orderedmap_remove (hashofheaders, "location"); } } #endif @@ -1123,19 +1117,15 @@ retry: /* * All right, output all the remaining headers to the client. */ - iter = hashmap_first (hashofheaders); - if (iter >= 0) { - for (; !hashmap_is_end (hashofheaders, iter); ++iter) { - hashmap_return_entry (hashofheaders, - iter, &data, (void **) &header); - - ret = write_message (connptr->client_fd, - "%s: %s\r\n", data, header); - if (ret < 0) - goto ERROR_EXIT; - } + iter = 0; + while ((iter = orderedmap_next(hashofheaders, iter, &data, &header))) { + + ret = write_message (connptr->client_fd, + "%s: %s\r\n", data, header); + if (ret < 0) + goto ERROR_EXIT; } - hashmap_delete (hashofheaders); + orderedmap_destroy (hashofheaders); /* Write the final blank line to signify the end of the headers */ if (safe_write (connptr->client_fd, "\r\n", 2) < 0) @@ -1144,7 +1134,7 @@ retry: return 0; ERROR_EXIT: - hashmap_delete (hashofheaders); + orderedmap_destroy (hashofheaders); return -1; } @@ -1158,74 +1148,39 @@ ERROR_EXIT: */ static void relay_connection (struct conn_s *connptr) { - fd_set rset, wset; - struct timeval tv; - time_t last_access; int ret; - double tdiff; - int maxfd = max (connptr->client_fd, connptr->server_fd) + 1; ssize_t bytes_received; - ret = socket_nonblocking (connptr->client_fd); - if (ret != 0) { - log_message(LOG_ERR, "Failed to set the client socket " - "to non-blocking: %s", strerror(errno)); - return; - } - - ret = socket_nonblocking (connptr->server_fd); - if (ret != 0) { - log_message(LOG_ERR, "Failed to set the server socket " - "to non-blocking: %s", strerror(errno)); - return; - } - - last_access = time (NULL); - for (;;) { - FD_ZERO (&rset); - FD_ZERO (&wset); - - tv.tv_sec = - config->idletimeout - difftime (time (NULL), last_access); - tv.tv_usec = 0; + pollfd_struct fds[2] = {0}; + fds[0].fd = connptr->client_fd; + fds[1].fd = connptr->server_fd; if (buffer_size (connptr->sbuffer) > 0) - FD_SET (connptr->client_fd, &wset); + fds[0].events |= MYPOLL_WRITE; if (buffer_size (connptr->cbuffer) > 0) - FD_SET (connptr->server_fd, &wset); + fds[1].events |= MYPOLL_WRITE; if (buffer_size (connptr->sbuffer) < MAXBUFFSIZE) - FD_SET (connptr->server_fd, &rset); + fds[1].events |= MYPOLL_READ; if (buffer_size (connptr->cbuffer) < MAXBUFFSIZE) - FD_SET (connptr->client_fd, &rset); + fds[0].events |= MYPOLL_READ; - ret = select (maxfd, &rset, &wset, NULL, &tv); + ret = mypoll(fds, 2, config->idletimeout); if (ret == 0) { - tdiff = difftime (time (NULL), last_access); - if (tdiff > config->idletimeout) { - log_message (LOG_INFO, - "Idle Timeout (after select) as %g > %u.", - tdiff, config->idletimeout); + log_message (LOG_INFO, + "Idle Timeout (after " SELECT_OR_POLL ")"); return; - } else { - continue; - } } else if (ret < 0) { log_message (LOG_ERR, - "relay_connection: select() error \"%s\". " + "relay_connection: " SELECT_OR_POLL "() error \"%s\". " "Closing connection (client_fd:%d, server_fd:%d)", strerror (errno), connptr->client_fd, connptr->server_fd); return; - } else { - /* - * All right, something was actually selected so mark it. - */ - last_access = time (NULL); } - if (FD_ISSET (connptr->server_fd, &rset)) { + if (fds[1].revents & MYPOLL_READ) { bytes_received = read_buffer (connptr->server_fd, connptr->sbuffer); if (bytes_received < 0) @@ -1235,32 +1190,20 @@ static void relay_connection (struct conn_s *connptr) if (connptr->content_length.server == 0) break; } - if (FD_ISSET (connptr->client_fd, &rset) + if ((fds[0].revents & MYPOLL_READ) && read_buffer (connptr->client_fd, connptr->cbuffer) < 0) { break; } - if (FD_ISSET (connptr->server_fd, &wset) + if ((fds[1].revents & MYPOLL_WRITE) && write_buffer (connptr->server_fd, connptr->cbuffer) < 0) { break; } - if (FD_ISSET (connptr->client_fd, &wset) + if ((fds[0].revents & MYPOLL_WRITE) && write_buffer (connptr->client_fd, connptr->sbuffer) < 0) { break; } } - /* - * Here the server has closed the connection... write the - * remainder to the client and then exit. - */ - ret = socket_blocking (connptr->client_fd); - if (ret != 0) { - log_message(LOG_ERR, - "Failed to set client socket to blocking: %s", - strerror(errno)); - return; - } - while (buffer_size (connptr->sbuffer) > 0) { if (write_buffer (connptr->client_fd, connptr->sbuffer) < 0) break; @@ -1431,7 +1374,7 @@ connect_to_upstream (struct conn_s *connptr, struct request_s *request) connptr->server_fd = opensock (cur_upstream->host, cur_upstream->port, - connptr->server_ip_addr); + connptr->server_ip_addr, NULL); if (connptr->server_fd < 0) { log_message (LOG_WARNING, @@ -1487,27 +1430,27 @@ connect_to_upstream (struct conn_s *connptr, struct request_s *request) #endif } +/* this function "drains" remaining bytes in the read pipe from + the client. it's usually only called on error before displaying + an error code/page. */ static int get_request_entity(struct conn_s *connptr) { int ret; - fd_set rset, wset; - struct timeval tv; + pollfd_struct fds[1] = {0}; - FD_ZERO (&rset); - FD_SET (connptr->client_fd, &rset); - memcpy(&wset, &rset, sizeof wset); - tv.tv_sec = config->idletimeout; - tv.tv_usec = 0; - ret = select (connptr->client_fd + 1, &rset, &wset, NULL, &tv); + fds[0].fd = connptr->client_fd; + fds[0].events |= MYPOLL_READ; + + ret = mypoll(fds, 1, config->idletimeout); if (ret == -1) { log_message (LOG_ERR, - "Error calling select on client fd %d: %s", + "Error calling " SELECT_OR_POLL " on client fd %d: %s", connptr->client_fd, strerror(errno)); } else if (ret == 0) { log_message (LOG_INFO, "no entity"); - } else if (ret == 1 && FD_ISSET (connptr->client_fd, &rset)) { + } else if (ret == 1 && (fds[0].revents & MYPOLL_READ)) { ssize_t nread; nread = read_buffer (connptr->client_fd, connptr->cbuffer); if (nread < 0) { @@ -1517,14 +1460,12 @@ get_request_entity(struct conn_s *connptr) ret = -1; } else { log_message (LOG_INFO, - "Read request entity of %d bytes", - nread); + "Read request entity of %ld bytes", + (long) nread); ret = 0; } - } else if (ret == 1 && FD_ISSET (connptr->client_fd, &wset) && connptr->connect_method) { - ret = 0; } else { - log_message (LOG_ERR, "strange situation after select: " + log_message (LOG_ERR, "strange situation after " SELECT_OR_POLL ": " "ret = %d, but client_fd (%d) is not readable...", ret, connptr->client_fd); ret = -1; @@ -1533,6 +1474,31 @@ get_request_entity(struct conn_s *connptr) return ret; } +static void handle_connection_failure(struct conn_s *connptr, int got_headers) +{ + /* + * First, get the body if there is one. + * If we don't read all there is from the socket first, + * it is still marked for reading and we won't be able + * to send our data properly. + */ + if (!got_headers && get_request_entity (connptr) < 0) { + log_message (LOG_WARNING, + "Could not retrieve request entity"); + indicate_http_error (connptr, 400, "Bad Request", + "detail", + "Could not retrieve the request entity " + "the client.", NULL); + update_stats (STAT_BADCONN); + } + + if (connptr->error_variables) { + send_http_error_message (connptr); + } else if (connptr->show_stats) { + showstats (connptr); + } +} + /* * This is the main drive for each connection. As you can tell, for the @@ -1543,15 +1509,21 @@ get_request_entity(struct conn_s *connptr) * tinyproxy code, which was confusing, redundant. Hail progress. * - rjkaes */ -void handle_connection (int fd, union sockaddr_union* addr) +void handle_connection (struct conn_s *connptr, union sockaddr_union* addr) { - ssize_t i; - struct conn_s *connptr; + +#define HC_FAIL() \ + do {handle_connection_failure(connptr, got_headers); goto done;} \ + while(0) + + int got_headers = 0, fd = connptr->client_fd; + size_t i; struct request_s *request = NULL; struct timeval tv; - hashmap_t hashofheaders = NULL; + orderedmap hashofheaders = NULL; char sock_ipaddr[IP_LENGTH]; + char sock_ipaddr_alt[IP_LENGTH]=""; char peer_ipaddr[IP_LENGTH]; getpeer_information (addr, peer_ipaddr, sizeof(peer_ipaddr)); @@ -1559,14 +1531,25 @@ void handle_connection (int fd, union sockaddr_union* addr) if (config->bindsame) getsock_ip (fd, sock_ipaddr); + switch (SOCKADDR_UNION_AF(addr)) { + case AF_INET: + if (config->bind_ipv4mapped) + getmapped_ipv6 (config->bind_ipv4mapped, sock_ipaddr, sock_ipaddr_alt); + break; + case AF_INET6: + if (config->bind_ipv6mapped) + getmapped_ipv4 (config->bind_ipv6mapped, sock_ipaddr, sock_ipaddr_alt); + break; + } + log_message (LOG_CONN, config->bindsame ? "Connect (file descriptor %d): %s at [%s]" : "Connect (file descriptor %d): %s", fd, peer_ipaddr, sock_ipaddr); - connptr = initialize_conn (fd, peer_ipaddr, - config->bindsame ? sock_ipaddr : NULL); - if (!connptr) { + if(!conn_init_contents (connptr, peer_ipaddr, + config->bindsame ? sock_ipaddr : NULL, + sock_ipaddr_alt[0] ? sock_ipaddr_alt : NULL)) { close (fd); return; } @@ -1588,7 +1571,7 @@ void handle_connection (int fd, union sockaddr_union* addr) "You tried to connect to the " "machine the proxy is running on", NULL); - goto fail; + HC_FAIL(); } @@ -1599,7 +1582,7 @@ void handle_connection (int fd, union sockaddr_union* addr) "The administrator of this proxy has not configured " "it to service requests from your host.", NULL); - goto fail; + HC_FAIL(); } if (read_request_line (connptr) < 0) { @@ -1608,13 +1591,13 @@ void handle_connection (int fd, union sockaddr_union* addr) "detail", "Server timeout waiting for the HTTP request " "from the client.", NULL); - goto fail; + HC_FAIL(); } /* * The "hashofheaders" store the client's headers. */ - hashofheaders = hashmap_create (HEADER_BUCKETS); + hashofheaders = orderedmap_create (HEADER_BUCKETS); if (hashofheaders == NULL) { update_stats (STAT_BADCONN); indicate_http_error (connptr, 503, "Internal error", @@ -1622,7 +1605,7 @@ void handle_connection (int fd, union sockaddr_union* addr) "An internal server error occurred while processing " "your request. Please contact the administrator.", NULL); - goto fail; + HC_FAIL(); } /* @@ -1636,34 +1619,31 @@ void handle_connection (int fd, union sockaddr_union* addr) "Could not retrieve all the headers from " "the client.", NULL); update_stats (STAT_BADCONN); - goto fail; + HC_FAIL(); } + got_headers = 1; if (config->basicauth_list != NULL) { - ssize_t len; char *authstring; int failure = 1, stathost_connect = 0; - len = hashmap_entry_by_key (hashofheaders, "proxy-authorization", - (void **) &authstring); - - if (len == 0 && config->stathost) { - len = hashmap_entry_by_key (hashofheaders, "host", - (void **) &authstring); - if (len && !strncmp(authstring, config->stathost, strlen(config->stathost))) { - len = hashmap_entry_by_key (hashofheaders, "authorization", - (void **) &authstring); + authstring = orderedmap_find (hashofheaders, "proxy-authorization"); + + if (!authstring && config->stathost) { + authstring = orderedmap_find (hashofheaders, "host"); + if (authstring && !strncmp(authstring, config->stathost, strlen(config->stathost))) { + authstring = orderedmap_find (hashofheaders, "authorization"); stathost_connect = 1; - } else len = 0; + } else authstring = 0; } - if (len == 0) { + if (!authstring) { if (stathost_connect) goto e401; update_stats (STAT_DENIED); indicate_http_error (connptr, 407, "Proxy Authentication Required", "detail", "This proxy requires authentication.", NULL); - goto fail; + HC_FAIL(); } if ( /* currently only "basic" auth supported */ (strncmp(authstring, "Basic ", 6) == 0 || @@ -1678,22 +1658,20 @@ e401: "The administrator of this proxy has not configured " "it to service requests from you.", NULL); - goto fail; + HC_FAIL(); } - hashmap_remove (hashofheaders, "proxy-authorization"); + orderedmap_remove (hashofheaders, "proxy-authorization"); } /* * Add any user-specified headers (AddHeader directive) to the * outgoing HTTP request. */ - for (i = 0; i < vector_length (config->add_headers); i++) { - http_header_t *header = (http_header_t *) - vector_getentry (config->add_headers, i, NULL); + if (config->add_headers) + for (i = 0; i < sblist_getsize (config->add_headers); i++) { + http_header_t *header = sblist_get (config->add_headers, i); - hashmap_insert (hashofheaders, - header->name, - header->value, strlen (header->value) + 1); + orderedmap_append (hashofheaders, header->name, header->value); } request = process_request (connptr, hashofheaders); @@ -1701,24 +1679,25 @@ e401: if (!connptr->show_stats) { update_stats (STAT_BADCONN); } - goto fail; + HC_FAIL(); } connptr->upstream_proxy = UPSTREAM_HOST (request->host); if (connptr->upstream_proxy != NULL) { if (connect_to_upstream (connptr, request) < 0) { - goto fail; + HC_FAIL(); } } else { connptr->server_fd = opensock (request->host, request->port, - connptr->server_ip_addr); + connptr->server_ip_addr, + connptr->server_ip_addr_alt); if (connptr->server_fd < 0) { indicate_http_error (connptr, 500, "Unable to connect", "detail", PACKAGE_NAME " " "was unable to connect to the remote web server.", "error", strerror (errno), NULL); - goto fail; + HC_FAIL(); } log_message (LOG_CONN, @@ -1732,13 +1711,25 @@ e401: if (process_client_headers (connptr, hashofheaders) < 0) { update_stats (STAT_BADCONN); - goto fail; + log_message (LOG_INFO, + "process_client_headers failed: %s. host \"%s\" using " + "file descriptor %d.", strerror(errno), + request->host, + connptr->server_fd); + + HC_FAIL(); } if (!connptr->connect_method || UPSTREAM_IS_HTTP(connptr)) { if (process_server_headers (connptr) < 0) { update_stats (STAT_BADCONN); - goto fail; + log_message (LOG_INFO, + "process_server_headers failed: %s. host \"%s\" using " + "file descriptor %d.", strerror(errno), + request->host, + connptr->server_fd); + + HC_FAIL(); } } else { if (send_ssl_response (connptr) < 0) { @@ -1746,7 +1737,7 @@ e401: "handle_connection: Could not send SSL greeting " "to client."); update_stats (STAT_BADCONN); - goto fail; + HC_FAIL(); } } @@ -1757,34 +1748,10 @@ e401: "and remote client (fd:%d)", connptr->client_fd, connptr->server_fd); - goto done; - -fail: - /* - * First, get the body if there is one. - * If we don't read all there is from the socket first, - * it is still marked for reading and we won't be able - * to send our data properly. - */ - if (get_request_entity (connptr) < 0) { - log_message (LOG_WARNING, - "Could not retrieve request entity"); - indicate_http_error (connptr, 400, "Bad Request", - "detail", - "Could not retrieve the request entity " - "the client.", NULL); - update_stats (STAT_BADCONN); - } - - if (connptr->error_variables) { - send_http_error_message (connptr); - } else if (connptr->show_stats) { - showstats (connptr); - } - done: free_request_struct (request); - hashmap_delete (hashofheaders); - destroy_conn (connptr); + orderedmap_destroy (hashofheaders); + conn_destroy_contents (connptr); return; +#undef HC_FAIL } |