Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/conns.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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;

/*
Expand Down
36 changes: 30 additions & 6 deletions src/reqs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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.
*/
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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));

Expand Down Expand Up @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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);
}
Expand All @@ -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,
Expand All @@ -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);
Expand Down