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