diff --git a/src/wp-includes/class-http.php b/src/wp-includes/class-http.php index 8917b90c1d..2a458eb705 100644 --- a/src/wp-includes/class-http.php +++ b/src/wp-includes/class-http.php @@ -449,7 +449,7 @@ class WP_Http { foreach ( $cookies as $name => $value ) { if ( $value instanceof WP_Http_Cookie ) { - $cookie_jar[ $value->name ] = new Requests_Cookie( $value->name, $value->value, $value->get_attributes() ); + $cookie_jar[ $value->name ] = new Requests_Cookie( $value->name, $value->value, $value->get_attributes(), array( 'host-only' => $value->host_only ) ); } elseif ( is_scalar( $value ) ) { $cookie_jar[ $name ] = new Requests_Cookie( $name, $value ); } diff --git a/src/wp-includes/class-wp-http-cookie.php b/src/wp-includes/class-wp-http-cookie.php index 568fe4848a..c265540323 100644 --- a/src/wp-includes/class-wp-http-cookie.php +++ b/src/wp-includes/class-wp-http-cookie.php @@ -60,6 +60,14 @@ class WP_Http_Cookie { */ public $domain; + /** + * host-only flag. + * + * @since 5.2.0 + * @var bool + */ + public $host_only; + /** * Sets up this cookie object. * @@ -67,16 +75,18 @@ class WP_Http_Cookie { * or a header string detailing it. * * @since 2.8.0 + * @since 5.2.0 Added `host_only` to the `$data` parameter. * * @param string|array $data { * Raw cookie data as header string or data array. * - * @type string $name Cookie name. - * @type mixed $value Value. Should NOT already be urlencoded. - * @type string|int $expires Optional. Unix timestamp or formatted date. Default null. - * @type string $path Optional. Path. Default '/'. - * @type string $domain Optional. Domain. Default host of parsed $requested_url. - * @type int $port Optional. Port. Default null. + * @type string $name Cookie name. + * @type mixed $value Value. Should NOT already be urlencoded. + * @type string|int $expires Optional. Unix timestamp or formatted date. Default null. + * @type string $path Optional. Path. Default '/'. + * @type string $domain Optional. Domain. Default host of parsed $requested_url. + * @type int $port Optional. Port. Default null. + * @type bool $host_only Optional. host-only storage flag. Default true. * } * @param string $requested_url The URL which the cookie was set on, used for default $domain * and $port values. @@ -128,7 +138,7 @@ class WP_Http_Cookie { } // Set properties based directly on parameters. - foreach ( array( 'name', 'value', 'path', 'domain', 'port' ) as $field ) { + foreach ( array( 'name', 'value', 'path', 'domain', 'port', 'host_only' ) as $field ) { if ( isset( $data[ $field ] ) ) { $this->$field = $data[ $field ]; } diff --git a/src/wp-includes/class-wp-http-requests-response.php b/src/wp-includes/class-wp-http-requests-response.php index df0957f6ff..b6c5f24a96 100644 --- a/src/wp-includes/class-wp-http-requests-response.php +++ b/src/wp-includes/class-wp-http-requests-response.php @@ -164,11 +164,12 @@ class WP_HTTP_Requests_Response extends WP_HTTP_Response { foreach ( $this->response->cookies as $cookie ) { $cookies[] = new WP_Http_Cookie( array( - 'name' => $cookie->name, - 'value' => urldecode( $cookie->value ), - 'expires' => isset( $cookie->attributes['expires'] ) ? $cookie->attributes['expires'] : null, - 'path' => isset( $cookie->attributes['path'] ) ? $cookie->attributes['path'] : null, - 'domain' => isset( $cookie->attributes['domain'] ) ? $cookie->attributes['domain'] : null, + 'name' => $cookie->name, + 'value' => urldecode( $cookie->value ), + 'expires' => isset( $cookie->attributes['expires'] ) ? $cookie->attributes['expires'] : null, + 'path' => isset( $cookie->attributes['path'] ) ? $cookie->attributes['path'] : null, + 'domain' => isset( $cookie->attributes['domain'] ) ? $cookie->attributes['domain'] : null, + 'host_only' => isset( $cookie->flags['host-only'] ) ? $cookie->flags['host-only'] : null, ) ); } diff --git a/tests/phpunit/tests/http/functions.php b/tests/phpunit/tests/http/functions.php index bfa4cd3e2a..3b15c6856e 100644 --- a/tests/phpunit/tests/http/functions.php +++ b/tests/phpunit/tests/http/functions.php @@ -199,4 +199,29 @@ class Tests_HTTP_Functions extends WP_UnitTestCase { $this->assertSame( 'test', $cookie->name ); $this->assertSame( 'foo', $cookie->value ); } + + /** + * @ticket 43231 + */ + function test_get_cookie_host_only() { + // emulate WP_Http::request() internals + $requests_response = new Requests_Response(); + + $requests_response->cookies['test'] = Requests_Cookie::parse( 'test=foo; domain=.wordpress.org' ); + + $requests_response->cookies['test']->flags['host-only'] = false; // https://github.com/rmccue/Requests/issues/306 + + $http_response = new WP_HTTP_Requests_Response( $requests_response ); + + $response = $http_response->to_array(); + + // check the host_only flag in the resulting WP_Http_Cookie + $cookie = wp_remote_retrieve_cookie( $response, 'test' ); + $this->assertEquals( $cookie->domain, 'wordpress.org' ); + $this->assertFalse( $cookie->host_only, 'host-only flag not set' ); + + // regurgitate (Requests_Cookie -> WP_Http_Cookie -> Requests_Cookie) + $cookies = WP_Http::normalize_cookies( wp_remote_retrieve_cookies( $response ) ); + $this->assertFalse( $cookies['test']->flags['host-only'], 'host-only flag data lost' ); + } }