87
87
* connections. The request line is allocated from the heap, but it must
88
88
* be freed in another function.
89
89
*/
90
- static int read_request_line (struct conn_s * connptr )
90
+ static int read_request_line (struct conn_s * connptr , char * * lines , size_t * lines_len )
91
91
{
92
92
ssize_t len ;
93
93
@@ -101,6 +101,12 @@ static int read_request_line (struct conn_s *connptr)
101
101
return -1 ;
102
102
}
103
103
104
+ * lines = saferealloc (* lines , * lines_len + len + 1 );
105
+ if (* lines ) {
106
+ strcpy (* lines + * lines_len , connptr -> request_line );
107
+ * lines_len += len ;
108
+ }
109
+
104
110
/*
105
111
* Strip the new line and carriage return from the string.
106
112
*/
@@ -626,7 +632,7 @@ add_header_to_connection (hashmap_t hashofheaders, char *header, size_t len)
626
632
/*
627
633
* Read all the headers from the stream
628
634
*/
629
- static int get_all_headers (int fd , hashmap_t hashofheaders )
635
+ static int get_all_headers (int fd , hashmap_t hashofheaders , char * * lines , size_t * lines_len )
630
636
{
631
637
char * line = NULL ;
632
638
char * header = NULL ;
@@ -646,6 +652,14 @@ static int get_all_headers (int fd, hashmap_t hashofheaders)
646
652
return -1 ;
647
653
}
648
654
655
+ if (lines ) {
656
+ * lines = saferealloc (* lines , * lines_len + linelen + 1 );
657
+ if (* lines ) {
658
+ strcpy (* lines + * lines_len , line );
659
+ * lines_len += linelen ;
660
+ }
661
+ }
662
+
649
663
/*
650
664
* If we received a CR LF or a non-continuation line, then add
651
665
* the accumulated header field, if any, to the hashmap, and
@@ -1011,7 +1025,7 @@ static int process_server_headers (struct conn_s *connptr)
1011
1025
/*
1012
1026
* Get all the headers from the remote server in a big hash
1013
1027
*/
1014
- if (get_all_headers (connptr -> server_fd , hashofheaders ) < 0 ) {
1028
+ if (get_all_headers (connptr -> server_fd , hashofheaders , NULL , NULL ) < 0 ) {
1015
1029
log_message (LOG_WARNING ,
1016
1030
"Could not retrieve all the headers from the remote server." );
1017
1031
hashmap_delete (hashofheaders );
@@ -1543,6 +1557,8 @@ void handle_connection (int fd)
1543
1557
char sock_ipaddr [IP_LENGTH ];
1544
1558
char peer_ipaddr [IP_LENGTH ];
1545
1559
char peer_string [HOSTNAME_LENGTH ];
1560
+ char * lines = NULL ;
1561
+ size_t lines_len = 0 ;
1546
1562
1547
1563
getpeer_information (fd , peer_ipaddr , peer_string );
1548
1564
@@ -1571,7 +1587,7 @@ void handle_connection (int fd)
1571
1587
goto fail ;
1572
1588
}
1573
1589
1574
- if (read_request_line (connptr ) < 0 ) {
1590
+ if (read_request_line (connptr , & lines , & lines_len ) < 0 ) {
1575
1591
update_stats (STAT_BADCONN );
1576
1592
indicate_http_error (connptr , 408 , "Timeout" ,
1577
1593
"detail" ,
@@ -1597,7 +1613,7 @@ void handle_connection (int fd)
1597
1613
/*
1598
1614
* Get all the headers from the client in a big hash.
1599
1615
*/
1600
- if (get_all_headers (connptr -> client_fd , hashofheaders ) < 0 ) {
1616
+ if (get_all_headers (connptr -> client_fd , hashofheaders , & lines , & lines_len ) < 0 ) {
1601
1617
log_message (LOG_WARNING ,
1602
1618
"Could not retrieve all the headers from the client" );
1603
1619
indicate_http_error (connptr , 400 , "Bad Request" ,
@@ -1683,6 +1699,11 @@ void handle_connection (int fd)
1683
1699
"file descriptor %d." , request -> host ,
1684
1700
connptr -> server_fd );
1685
1701
1702
+ if (hashmap_search (hashofheaders , "upgrade" ) > 0 ) {
1703
+ connptr -> connect_method = TRUE;
1704
+ safe_write (connptr -> server_fd , lines , lines_len );
1705
+ }
1706
+
1686
1707
if (!connptr -> connect_method )
1687
1708
establish_http_connection (connptr , request );
1688
1709
}
@@ -1740,6 +1761,7 @@ void handle_connection (int fd)
1740
1761
}
1741
1762
1742
1763
done :
1764
+ safefree (lines );
1743
1765
free_request_struct (request );
1744
1766
hashmap_delete (hashofheaders );
1745
1767
destroy_conn (connptr );
0 commit comments