@@ -168,8 +168,7 @@ typedef struct php_cli_server_client {
168
168
php_http_parser parser ;
169
169
unsigned int request_read :1 ;
170
170
zend_string * current_header_name ;
171
- char * current_header_value ;
172
- size_t current_header_value_len ;
171
+ zend_string * current_header_value ;
173
172
enum { HEADER_NONE = 0 , HEADER_FIELD , HEADER_VALUE } last_header_element ;
174
173
size_t post_read_offset ;
175
174
php_cli_server_request request ;
@@ -347,19 +346,19 @@ static void append_http_status_line(smart_str *buffer, int protocol_version, int
347
346
348
347
static void append_essential_headers (smart_str * buffer , php_cli_server_client * client , bool persistent ) /* {{{ */
349
348
{
350
- char * val ;
349
+ zend_string * val ;
351
350
struct timeval tv = {0 };
352
351
353
352
if (NULL != (val = zend_hash_str_find_ptr (& client -> request .headers , "host" , sizeof ("host" )- 1 ))) {
354
353
smart_str_appends_ex (buffer , "Host: " , persistent );
355
- smart_str_appends_ex (buffer , val , persistent );
354
+ smart_str_append_ex (buffer , val , persistent );
356
355
smart_str_appends_ex (buffer , "\r\n" , persistent );
357
356
}
358
357
359
358
if (!gettimeofday (& tv , NULL )) {
360
359
zend_string * dt = php_format_date ("D, d M Y H:i:s" , sizeof ("D, d M Y H:i:s" ) - 1 , tv .tv_sec , 0 );
361
360
smart_str_appends_ex (buffer , "Date: " , persistent );
362
- smart_str_appends_ex (buffer , dt -> val , persistent );
361
+ smart_str_append_ex (buffer , dt , persistent );
363
362
smart_str_appends_ex (buffer , " GMT\r\n" , persistent );
364
363
zend_string_release_ex (dt , 0 );
365
364
}
@@ -383,7 +382,7 @@ PHP_FUNCTION(apache_request_headers) /* {{{ */
383
382
php_cli_server_client * client ;
384
383
HashTable * headers ;
385
384
zend_string * key ;
386
- char * value ;
385
+ zend_string * value ;
387
386
zval tmp ;
388
387
389
388
if (zend_parse_parameters_none () == FAILURE ) {
@@ -396,7 +395,8 @@ PHP_FUNCTION(apache_request_headers) /* {{{ */
396
395
array_init_size (return_value , zend_hash_num_elements (headers ));
397
396
398
397
ZEND_HASH_MAP_FOREACH_STR_KEY_PTR (headers , key , value ) {
399
- ZVAL_STRING (& tmp , value );
398
+ // TODO There must be a better way
399
+ ZVAL_STRING (& tmp , ZSTR_VAL (value ));
400
400
zend_symtable_update (Z_ARRVAL_P (return_value ), key , & tmp );
401
401
} ZEND_HASH_FOREACH_END ();
402
402
}
@@ -571,11 +571,11 @@ static int sapi_cli_server_send_headers(sapi_headers_struct *sapi_headers) /* {{
571
571
static char * sapi_cli_server_read_cookies (void ) /* {{{ */
572
572
{
573
573
php_cli_server_client * client = SG (server_context );
574
- char * val ;
574
+ zend_string * val ;
575
575
if (NULL == (val = zend_hash_str_find_ptr (& client -> request .headers , "cookie" , sizeof ("cookie" )- 1 ))) {
576
576
return NULL ;
577
577
}
578
- return val ;
578
+ return ZSTR_VAL ( val ) ;
579
579
} /* }}} */
580
580
581
581
static size_t sapi_cli_server_read_post (char * buf , size_t count_bytes ) /* {{{ */
@@ -605,7 +605,7 @@ static void sapi_cli_server_register_variable(zval *track_vars_array, const char
605
605
}
606
606
} /* }}} */
607
607
608
- static int sapi_cli_server_register_entry_cb (char * * entry , int num_args , va_list args , zend_hash_key * hash_key ) /* {{{ */ {
608
+ static int sapi_cli_server_register_entry_cb (zend_string * * entry , int num_args , va_list args , zend_hash_key * hash_key ) /* {{{ */ {
609
609
zval * track_vars_array = va_arg (args , zval * );
610
610
if (hash_key -> key ) {
611
611
char * real_key , * key ;
@@ -620,9 +620,10 @@ static int sapi_cli_server_register_entry_cb(char **entry, int num_args, va_list
620
620
}
621
621
spprintf (& real_key , 0 , "%s_%s" , "HTTP" , key );
622
622
if (strcmp (key , "CONTENT_TYPE" ) == 0 || strcmp (key , "CONTENT_LENGTH" ) == 0 ) {
623
- sapi_cli_server_register_variable (track_vars_array , key , * entry );
623
+ // TODO make a version specialized for zend_string?
624
+ sapi_cli_server_register_variable (track_vars_array , key , ZSTR_VAL (* entry ));
624
625
}
625
- sapi_cli_server_register_variable (track_vars_array , real_key , * entry );
626
+ sapi_cli_server_register_variable (track_vars_array , real_key , ZSTR_VAL ( * entry ) );
626
627
efree (key );
627
628
efree (real_key );
628
629
}
@@ -1629,20 +1630,22 @@ static void php_cli_server_client_save_header(php_cli_server_client *client)
1629
1630
1630
1631
client -> current_header_name = NULL ;
1631
1632
client -> current_header_value = NULL ;
1632
- client -> current_header_value_len = 0 ;
1633
1633
}
1634
1634
1635
1635
static int php_cli_server_client_read_request_on_header_field (php_http_parser * parser , const char * at , size_t length )
1636
1636
{
1637
1637
php_cli_server_client * client = parser -> data ;
1638
1638
switch (client -> last_header_element ) {
1639
1639
case HEADER_VALUE :
1640
+ /* Save previous header before creating new one */
1640
1641
php_cli_server_client_save_header (client );
1641
1642
ZEND_FALLTHROUGH ;
1642
1643
case HEADER_NONE :
1644
+ /* Create new header field */
1643
1645
client -> current_header_name = zend_string_init (at , length , /* persistent */ false);
1644
1646
break ;
1645
1647
case HEADER_FIELD : {
1648
+ /* Append header field */
1646
1649
zend_string * field = zend_string_concat2 (
1647
1650
ZSTR_VAL (client -> current_header_name ), ZSTR_LEN (client -> current_header_name ), at , length );
1648
1651
// Free previous
@@ -1659,23 +1662,24 @@ static int php_cli_server_client_read_request_on_header_value(php_http_parser *p
1659
1662
{
1660
1663
php_cli_server_client * client = parser -> data ;
1661
1664
switch (client -> last_header_element ) {
1662
- case HEADER_FIELD :
1663
- client -> current_header_value = pestrndup (at , length , 1 );
1664
- client -> current_header_value_len = length ;
1665
- break ;
1666
- case HEADER_VALUE :
1667
- {
1668
- size_t new_length = client -> current_header_value_len + length ;
1669
- client -> current_header_value = perealloc (client -> current_header_value , new_length + 1 , 1 );
1670
- memcpy (client -> current_header_value + client -> current_header_value_len , at , length );
1671
- client -> current_header_value [new_length ] = '\0' ;
1672
- client -> current_header_value_len = new_length ;
1665
+ case HEADER_FIELD :
1666
+ /* Previous element was the header field, create the header value */
1667
+ client -> current_header_value = zend_string_init (at , length , /* persistent */ true);
1668
+ break ;
1669
+ case HEADER_VALUE : {
1670
+ /* Previous element was part of header value, append content to it */
1671
+ size_t old_length = ZSTR_LEN (client -> current_header_value );
1672
+ // TODO Release old value?
1673
+ client -> current_header_value = zend_string_extend (client -> current_header_value , old_length + length , /* persistent */ true);
1674
+ memcpy (ZSTR_VAL (client -> current_header_value ) + old_length , at , length );
1675
+ // Null terminate
1676
+ ZSTR_VAL (client -> current_header_value )[ZSTR_LEN (client -> current_header_value )] = '\0' ;
1677
+ break ;
1673
1678
}
1674
- break ;
1675
- case HEADER_NONE :
1676
- // can't happen
1677
- assert (0 );
1678
- break ;
1679
+ case HEADER_NONE :
1680
+ /* Cannot happen as a header field must have been found before */
1681
+ assert (0 );
1682
+ break ;
1679
1683
}
1680
1684
client -> last_header_element = HEADER_VALUE ;
1681
1685
return 0 ;
@@ -1688,11 +1692,11 @@ static int php_cli_server_client_read_request_on_headers_complete(php_http_parse
1688
1692
case HEADER_NONE :
1689
1693
break ;
1690
1694
case HEADER_FIELD :
1691
- client -> current_header_value = pemalloc (1 , 1 );
1692
- * client -> current_header_value = '\0' ;
1693
- client -> current_header_value_len = 0 ;
1695
+ /* Previous element was the header field, set it's value to an empty string */
1696
+ client -> current_header_value = ZSTR_EMPTY_ALLOC ();
1694
1697
ZEND_FALLTHROUGH ;
1695
1698
case HEADER_VALUE :
1699
+ /* Save last header value */
1696
1700
php_cli_server_client_save_header (client );
1697
1701
break ;
1698
1702
}
@@ -1838,7 +1842,7 @@ static size_t php_cli_server_client_send_through(php_cli_server_client *client,
1838
1842
1839
1843
static void php_cli_server_client_populate_request_info (const php_cli_server_client * client , sapi_request_info * request_info ) /* {{{ */
1840
1844
{
1841
- char * val ;
1845
+ zend_string * val ;
1842
1846
1843
1847
request_info -> request_method = php_http_method_str (client -> request .request_method );
1844
1848
request_info -> proto_num = client -> request .protocol_version ;
@@ -1848,7 +1852,7 @@ static void php_cli_server_client_populate_request_info(const php_cli_server_cli
1848
1852
request_info -> content_length = client -> request .content_len ;
1849
1853
request_info -> auth_user = request_info -> auth_password = request_info -> auth_digest = NULL ;
1850
1854
if (NULL != (val = zend_hash_str_find_ptr (& client -> request .headers , "content-type" , sizeof ("content-type" )- 1 ))) {
1851
- request_info -> content_type = val ;
1855
+ request_info -> content_type = ZSTR_VAL ( val ) ;
1852
1856
}
1853
1857
} /* }}} */
1854
1858
@@ -1876,7 +1880,6 @@ static void php_cli_server_client_ctor(php_cli_server_client *client, php_cli_se
1876
1880
client -> last_header_element = HEADER_NONE ;
1877
1881
client -> current_header_name = NULL ;
1878
1882
client -> current_header_value = NULL ;
1879
- client -> current_header_value_len = 0 ;
1880
1883
1881
1884
client -> post_read_offset = 0 ;
1882
1885
@@ -2095,10 +2098,10 @@ static zend_result php_cli_server_begin_send_static(php_cli_server *server, php_
2095
2098
/* }}} */
2096
2099
2097
2100
static zend_result php_cli_server_request_startup (php_cli_server * server , php_cli_server_client * client ) { /* {{{ */
2098
- char * auth ;
2101
+ zend_string * auth ;
2099
2102
php_cli_server_client_populate_request_info (client , & SG (request_info ));
2100
2103
if (NULL != (auth = zend_hash_str_find_ptr (& client -> request .headers , "authorization" , sizeof ("authorization" )- 1 ))) {
2101
- php_handle_auth_data (auth );
2104
+ php_handle_auth_data (ZSTR_VAL ( auth ) );
2102
2105
}
2103
2106
SG (sapi_headers ).http_response_code = 200 ;
2104
2107
if (FAILURE == php_request_startup ()) {
0 commit comments