@@ -172,6 +172,9 @@ typedef struct php_cli_server_client {
172
172
char * current_header_name ;
173
173
size_t current_header_name_len ;
174
174
unsigned int current_header_name_allocated :1 ;
175
+ char * current_header_value ;
176
+ size_t current_header_value_len ;
177
+ enum { HEADER_NONE = 0 , HEADER_FIELD , HEADER_VALUE } last_header_element ;
175
178
size_t post_read_offset ;
176
179
php_cli_server_request request ;
177
180
unsigned int content_sender_initialized :1 ;
@@ -1567,50 +1570,100 @@ static int php_cli_server_client_read_request_on_fragment(php_http_parser *parse
1567
1570
return 0 ;
1568
1571
}
1569
1572
1570
- static int php_cli_server_client_read_request_on_header_field ( php_http_parser * parser , const char * at , size_t length )
1573
+ static void php_cli_server_client_save_header ( php_cli_server_client * client )
1571
1574
{
1572
- php_cli_server_client * client = parser -> data ;
1575
+ /* strip off the colon */
1576
+ zend_string * orig_header_name = zend_string_init (client -> current_header_name , client -> current_header_name_len , 1 );
1577
+ char * lc_header_name = zend_str_tolower_dup (client -> current_header_name , client -> current_header_name_len );
1578
+ zend_hash_str_add_ptr (& client -> request .headers , lc_header_name , client -> current_header_name_len , client -> current_header_value );
1579
+ zend_hash_add_ptr (& client -> request .headers_original_case , orig_header_name , client -> current_header_value );
1580
+ efree (lc_header_name );
1581
+ zend_string_release (orig_header_name );
1582
+
1573
1583
if (client -> current_header_name_allocated ) {
1574
1584
pefree (client -> current_header_name , 1 );
1575
1585
client -> current_header_name_allocated = 0 ;
1576
1586
}
1577
- client -> current_header_name = (char * )at ;
1578
- client -> current_header_name_len = length ;
1579
- return 0 ;
1587
+ client -> current_header_name = NULL ;
1588
+ client -> current_header_name_len = 0 ;
1589
+ client -> current_header_value = NULL ;
1590
+ client -> current_header_value_len = 0 ;
1580
1591
}
1581
1592
1582
- static int php_cli_server_client_read_request_on_header_value (php_http_parser * parser , const char * at , size_t length )
1593
+ static int php_cli_server_client_read_request_on_header_field (php_http_parser * parser , const char * at , size_t length )
1583
1594
{
1584
1595
php_cli_server_client * client = parser -> data ;
1585
- char * value = pestrndup (at , length , 1 );
1586
- if (!value ) {
1587
- return 1 ;
1588
- }
1589
- {
1590
- /* strip off the colon */
1591
- zend_string * orig_header_name = zend_string_init (client -> current_header_name , client -> current_header_name_len , 1 );
1592
- char * lc_header_name = zend_str_tolower_dup (client -> current_header_name , client -> current_header_name_len );
1593
- zend_hash_str_add_ptr (& client -> request .headers , lc_header_name , client -> current_header_name_len , value );
1594
- zend_hash_add_ptr (& client -> request .headers_original_case , orig_header_name , value );
1595
- efree (lc_header_name );
1596
- zend_string_release (orig_header_name );
1596
+ switch (client -> last_header_element ) {
1597
+ case HEADER_VALUE :
1598
+ php_cli_server_client_save_header (client );
1599
+ /* break missing intentionally */
1600
+ case HEADER_NONE :
1601
+ client -> current_header_name = (char * )at ;
1602
+ client -> current_header_name_len = length ;
1603
+ break ;
1604
+ case HEADER_FIELD :
1605
+ if (client -> current_header_name_allocated ) {
1606
+ size_t new_length = client -> current_header_name_len + length ;
1607
+ client -> current_header_name = perealloc (client -> current_header_name , new_length + 1 , 1 );
1608
+ memcpy (client -> current_header_name + client -> current_header_name_len , at , length );
1609
+ client -> current_header_name_len = new_length ;
1610
+ } else {
1611
+ size_t new_length = client -> current_header_name_len + length ;
1612
+ char * field = pemalloc (new_length + 1 , 1 );
1613
+ memcpy (field , client -> current_header_name , client -> current_header_name_len );
1614
+ memcpy (field + client -> current_header_name_len , at , length );
1615
+ client -> current_header_name = field ;
1616
+ client -> current_header_name_len = new_length ;
1617
+ client -> current_header_name_allocated = 1 ;
1618
+ }
1619
+ break ;
1597
1620
}
1598
1621
1599
- if (client -> current_header_name_allocated ) {
1600
- pefree (client -> current_header_name , 1 );
1601
- client -> current_header_name_allocated = 0 ;
1622
+ client -> last_header_element = HEADER_FIELD ;
1623
+ return 0 ;
1624
+ }
1625
+
1626
+ static int php_cli_server_client_read_request_on_header_value (php_http_parser * parser , const char * at , size_t length )
1627
+ {
1628
+ php_cli_server_client * client = parser -> data ;
1629
+ switch (client -> last_header_element ) {
1630
+ case HEADER_FIELD :
1631
+ client -> current_header_value = pestrndup (at , length , 1 );
1632
+ client -> current_header_value_len = length ;
1633
+ break ;
1634
+ case HEADER_VALUE :
1635
+ {
1636
+ size_t new_length = client -> current_header_value_len + length ;
1637
+ client -> current_header_value = perealloc (client -> current_header_value , new_length + 1 , 1 );
1638
+ memcpy (client -> current_header_value + client -> current_header_value_len , at , length );
1639
+ client -> current_header_value_len = new_length ;
1640
+ }
1641
+ break ;
1642
+ case HEADER_NONE :
1643
+ // can't happen
1644
+ assert (0 );
1645
+ break ;
1602
1646
}
1647
+ client -> last_header_element = HEADER_VALUE ;
1603
1648
return 0 ;
1604
1649
}
1605
1650
1606
1651
static int php_cli_server_client_read_request_on_headers_complete (php_http_parser * parser )
1607
1652
{
1608
1653
php_cli_server_client * client = parser -> data ;
1609
- if (client -> current_header_name_allocated ) {
1610
- pefree (client -> current_header_name , 1 );
1611
- client -> current_header_name_allocated = 0 ;
1654
+ switch (client -> last_header_element ) {
1655
+ case HEADER_NONE :
1656
+ break ;
1657
+ case HEADER_FIELD :
1658
+ client -> current_header_value = pemalloc (1 , 1 );
1659
+ * client -> current_header_value = '\0' ;
1660
+ client -> current_header_value_len = 0 ;
1661
+ /* break missing intentionally */
1662
+ case HEADER_VALUE :
1663
+ php_cli_server_client_save_header (client );
1664
+ break ;
1612
1665
}
1613
- client -> current_header_name = NULL ;
1666
+ client -> last_header_element = HEADER_NONE ;
1614
1667
return 0 ;
1615
1668
}
1616
1669
@@ -1780,9 +1833,14 @@ static int php_cli_server_client_ctor(php_cli_server_client *client, php_cli_ser
1780
1833
}
1781
1834
php_http_parser_init (& client -> parser , PHP_HTTP_REQUEST );
1782
1835
client -> request_read = 0 ;
1836
+
1837
+ client -> last_header_element = HEADER_NONE ;
1783
1838
client -> current_header_name = NULL ;
1784
1839
client -> current_header_name_len = 0 ;
1785
1840
client -> current_header_name_allocated = 0 ;
1841
+ client -> current_header_value = NULL ;
1842
+ client -> current_header_value_len = 0 ;
1843
+
1786
1844
client -> post_read_offset = 0 ;
1787
1845
if (FAILURE == php_cli_server_request_ctor (& client -> request )) {
1788
1846
return FAILURE ;
0 commit comments