@@ -1680,14 +1680,33 @@ static void php_cli_server_client_save_header(php_cli_server_client *client)
1680
1680
{
1681
1681
/* Wrap header value in a zval to add is to the HashTable which acts as an array */
1682
1682
zval tmp ;
1683
- ZVAL_STR (& tmp , client -> current_header_value );
1684
1683
/* strip off the colon */
1685
1684
zend_string * lc_header_name = zend_string_tolower_ex (client -> current_header_name , /* persistent */ true);
1686
1685
GC_MAKE_PERSISTENT_LOCAL (lc_header_name );
1687
1686
1688
- /* Add the wrapped zend_string to the HashTable */
1689
- zend_hash_add (& client -> request .headers , lc_header_name , & tmp );
1690
- zend_hash_add (& client -> request .headers_original_case , client -> current_header_name , & tmp );
1687
+ zval * entry = zend_hash_find (& client -> request .headers , lc_header_name );
1688
+ bool with_comma = !zend_string_equals_literal (lc_header_name , "set-cookie" );
1689
+
1690
+ /**
1691
+ * `Set-Cookie` HTTP header being the exception, they can have 1 or more values separated
1692
+ * by a comma while still possibly be set separately by the client.
1693
+ **/
1694
+ if (!with_comma || entry == NULL ) {
1695
+ ZVAL_STR (& tmp , client -> current_header_value );
1696
+ } else {
1697
+ zend_string * curval = Z_STR_P (entry );
1698
+ zend_string * newval = zend_string_safe_alloc (1 , ZSTR_LEN (curval ), ZSTR_LEN (client -> current_header_value ) + 2 , /* persistent */ true);
1699
+
1700
+ memcpy (ZSTR_VAL (newval ), ZSTR_VAL (curval ), ZSTR_LEN (curval ));
1701
+ memcpy (ZSTR_VAL (newval ) + ZSTR_LEN (curval ), ", " , 2 );
1702
+ memcpy (ZSTR_VAL (newval ) + ZSTR_LEN (curval ) + 2 , ZSTR_VAL (client -> current_header_value ), ZSTR_LEN (client -> current_header_value ) + 1 );
1703
+
1704
+ ZVAL_STR (& tmp , newval );
1705
+ }
1706
+
1707
+ /* Add/Update the wrapped zend_string to the HashTable */
1708
+ zend_hash_update (& client -> request .headers , lc_header_name , & tmp );
1709
+ zend_hash_update (& client -> request .headers_original_case , client -> current_header_name , & tmp );
1691
1710
1692
1711
zend_string_release_ex (lc_header_name , /* persistent */ true);
1693
1712
zend_string_release_ex (client -> current_header_name , /* persistent */ true);
0 commit comments