diff --git a/src/wp-includes/class-http.php b/src/wp-includes/class-http.php index 8360abcb03..173566d464 100644 --- a/src/wp-includes/class-http.php +++ b/src/wp-includes/class-http.php @@ -325,9 +325,9 @@ class WP_Http { $options['max_bytes'] = $r['limit_response_size']; } - // If we've got cookies, use them + // If we've got cookies, use and convert them to Requests_Cookie. if ( ! empty( $r['cookies'] ) ) { - $options['cookies'] = $r['cookies']; + $options['cookies'] = WP_Http::normalize_cookies( $r['cookies'] ); } // SSL certificate handling @@ -413,6 +413,30 @@ class WP_Http { return apply_filters( 'http_response', $response, $r, $url ); } + /** + * Normalizes cookies for using in Requests. + * + * @since 4.6.0 + * @access public + * @static + * + * @param array $cookies List of cookies to send with the request. + * @return Requests_Cookie_Jar Cookie holder object. + */ + public static function normalize_cookies( $cookies ) { + $cookie_jar = new Requests_Cookie_Jar(); + + 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() ); + } elseif ( is_string( $value ) ) { + $cookie_jar[ $name ] = new Requests_Cookie( $name, $value ); + } + } + + return $cookie_jar; + } + /** * Match redirect behaviour to browser handling. * @@ -420,9 +444,13 @@ class WP_Http { * RFC 7231, user agents can deviate from the strict reading of the * specification for compatibility purposes. * - * @param string $location URL to redirect to. - * @param array $headers Headers for the redirect. - * @param array $options Redirect request options. + * @since 4.6.0 + * @access public + * @static + * + * @param string $location URL to redirect to. + * @param array $headers Headers for the redirect. + * @param array $options Redirect request options. * @param Requests_Response $original Response object. */ public static function browser_redirect_compatibility( $location, $headers, $data, &$options, $original ) { diff --git a/src/wp-includes/class-wp-http-cookie.php b/src/wp-includes/class-wp-http-cookie.php index 8ae947be57..d2affc2cc1 100644 --- a/src/wp-includes/class-wp-http-cookie.php +++ b/src/wp-includes/class-wp-http-cookie.php @@ -216,4 +216,26 @@ class WP_Http_Cookie { public function getFullHeader() { return 'Cookie: ' . $this->getHeaderValue(); } + + /** + * Retrieves cookie attributes. + * + * @since 4.6.0 + * @access public + * + * @return array { + * List of attributes. + * + * @type string $expires When the cookie expires. + * @type string $path Cookie URL path. + * @type string $domain Cookie domain. + * } + */ + public function get_attributes() { + return array( + 'expires' => $this->expires, + 'path' => $this->path, + 'domain' => $this->domain, + ); + } } diff --git a/src/wp-includes/class-wp-http-requests-response.php b/src/wp-includes/class-wp-http-requests-response.php index 5ed99b3e77..ab0a5cc056 100644 --- a/src/wp-includes/class-wp-http-requests-response.php +++ b/src/wp-includes/class-wp-http-requests-response.php @@ -176,9 +176,9 @@ class WP_HTTP_Requests_Response extends WP_HTTP_Response { $cookies[] = new WP_Http_Cookie( array( 'name' => $cookie->name, 'value' => urldecode( $cookie->value ), - 'expires' => $cookie->attributes['expires'], - 'path' => $cookie->attributes['path'], - 'domain' => $cookie->attributes['domain'], + '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, )); } diff --git a/tests/phpunit/tests/http/functions.php b/tests/phpunit/tests/http/functions.php index 69bd9ab238..5d58abaa89 100644 --- a/tests/phpunit/tests/http/functions.php +++ b/tests/phpunit/tests/http/functions.php @@ -107,4 +107,45 @@ class Tests_HTTP_Functions extends WP_UnitTestCase { $this->assertSame( '', $no_cookie ); } + /** + * @ticket 37437 + */ + function test_get_response_cookies_with_wp_http_cookie_object() { + $url = 'http://example.org'; + + $response = wp_remote_get( $url, array( + 'cookies' => array( + new WP_Http_Cookie( array( 'name' => 'test', 'value' => 'foo' ) ), + ), + ) ); + $cookies = wp_remote_retrieve_cookies( $response ); + + $this->assertNotEmpty( $cookies ); + + $cookie = wp_remote_retrieve_cookie( $response, 'test' ); + $this->assertInstanceOf( 'WP_Http_Cookie', $cookie ); + $this->assertSame( 'test', $cookie->name ); + $this->assertSame( 'foo', $cookie->value ); + } + + /** + * @ticket 37437 + */ + function test_get_response_cookies_with_name_value_array() { + $url = 'http://example.org'; + + $response = wp_remote_get( $url, array( + 'cookies' => array( + 'test' => 'foo', + ), + ) ); + $cookies = wp_remote_retrieve_cookies( $response ); + + $this->assertNotEmpty( $cookies ); + + $cookie = wp_remote_retrieve_cookie( $response, 'test' ); + $this->assertInstanceOf( 'WP_Http_Cookie', $cookie ); + $this->assertSame( 'test', $cookie->name ); + $this->assertSame( 'foo', $cookie->value ); + } }