Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/wp-includes/class-wp-http-streams.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class WP_Http_Streams {
/**
* Send a HTTP request to a URI using PHP Streams.
*
* @see WP_Http::request() For default options descriptions.
* @see WP_Http::format_request() For default options descriptions.
*
* @since 2.7.0
* @since 3.7.0 Combined with the fsockopen transport and switched to stream_socket_client().
Expand Down
205 changes: 181 additions & 24 deletions src/wp-includes/class-wp-http.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class WP_Http {
*
* @since 2.7.0
*
* @param string $url The request URL.
* @param string|array $url The request URL or an array of requests.
* @param string|array $args {
* Optional. Array or string of HTTP request arguments.
*
Expand Down Expand Up @@ -167,6 +167,105 @@ class WP_Http {
* }
*/
public function request( $url, $args = array() ) {
if ( is_array( $url ) ) {
$pending_requests = array();
$responses = array();

foreach ( $url as $index => $request ) {
// Support an array of string URLs.
if ( ! is_array( $request ) ) {
$request = array( $request, array() );
}

$request = $this->format_request( $request[0], isset( $request[1] ) ? $request[1] : array() );

// Handle an error in the pre-request step. Also allow the request to be
// circumvented if the response was short-circuited.
if ( is_wp_error( $request ) ) {
$responses[ $index ] = $request;
continue;
} elseif ( isset( $request['response'] ) ) {
$responses[ $index ] = $request['response'];
continue;
}

$pending_requests[ $index ] = $request;
}

if ( ! empty( $pending_requests ) ) {
// Avoid issues where mbstring.func_overload is enabled.
mbstring_binary_safe_encoding();

try {
$raw_responses = WpOrg\Requests\Requests::request_multiple( $pending_requests );
} catch ( WpOrg\Requests\Exception $e ) {
$raw_responses = new WP_Error( 'http_request_failed', $e->getMessage() );
}

reset_mbstring_encoding();

if ( is_wp_error( $raw_responses ) ) {
return $raw_responses;
}

foreach ( $pending_requests as $index => $request ) {
$responses[ $index ] = $this->format_response(
$raw_responses[ $index ],
$request['args'],
$request['url']
);
}
}

return $responses;
}

$formatted = $this->format_request( $url, $args );

// Handle an error in the pre-request step. Also allow the request to be
// circumvented if the response was short-circuited.
if ( is_wp_error( $formatted ) ) {
return $formatted;
} elseif ( isset( $formatted['response'] ) ) {
return $formatted['response'];
}

// Avoid issues where mbstring.func_overload is enabled.
mbstring_binary_safe_encoding();

try {
$response = WpOrg\Requests\Requests::request(
$formatted['url'],
$formatted['headers'],
$formatted['data'],
$formatted['type'],
$formatted['options']
);
} catch ( WpOrg\Requests\Exception $e ) {
$response = new WP_Error( 'http_request_failed', $e->getMessage() );
}

reset_mbstring_encoding();

return $this->format_response( $response, $formatted['args'], $formatted['url'] );
}

/**
* Format a request to be passed to Requests.
*
* @param string $url URL to request.
* @param array $args Arguments to send to request.
* @return array {
* Array of formatted arguments for the request.
*
* @type string $url URL to request.
* @type array $headers Array of headers for the request.
* @type string $data Data to send with the request.
* @type string $type The type of request to make.
* @type array $options Array of options for the request.
* }
*/
protected function format_request( $url, $args ) {
$defaults = array(
'method' => 'GET',
/**
Expand Down Expand Up @@ -241,6 +340,7 @@ public function request( $url, $args = array() ) {
}

$parsed_args = wp_parse_args( $args, $defaults );

/**
* Filters the arguments used in an HTTP request.
*
Expand Down Expand Up @@ -277,7 +377,9 @@ public function request( $url, $args = array() ) {
$pre = apply_filters( 'pre_http_request', false, $parsed_args, $url );

if ( false !== $pre ) {
return $pre;
return array(
'response' => $pre,
);
}

if ( function_exists( 'wp_kses_bad_protocol' ) ) {
Expand Down Expand Up @@ -408,24 +510,38 @@ public function request( $url, $args = array() ) {
}
}

// Avoid issues where mbstring.func_overload is enabled.
mbstring_binary_safe_encoding();
return array(
'args' => $parsed_args,
'data' => $data,
'headers' => $headers,
'options' => $options,
'type' => $type,
'url' => $url,
);
}

try {
$requests_response = WpOrg\Requests\Requests::request( $url, $headers, $data, $type, $options );
/**
* Format a response into the expected shape.
*
* @param \WpOrg\Requests\Response|\WpOrg\Requests\Exception|WP_Error $response Response to format.
* @param array $args Request arguments.
* @param string $url Request URL.
* @return array|WP_Error
*/
protected function format_response( $response, $args, $url ) {
if ( $response instanceof \WpOrg\Requests\Exception ) {
$response = new \WP_Error( 'http_request_failed', $response->getMessage() );
}

// Convert the response into an array.
$http_response = new WP_HTTP_Requests_Response( $requests_response, $parsed_args['filename'] );
// Convert the response into an array.
if ( ! is_wp_error( $response ) ) {
$http_response = new WP_HTTP_Requests_Response( $response, $args['filename'] );
$response = $http_response->to_array();

// Add the original object to the array.
$response['http_response'] = $http_response;
} catch ( WpOrg\Requests\Exception $e ) {
$response = new WP_Error( 'http_request_failed', $e->getMessage() );
}

reset_mbstring_encoding();

/**
* Fires after an HTTP API response is received and before the response is returned.
*
Expand All @@ -434,15 +550,16 @@ public function request( $url, $args = array() ) {
* @param array|WP_Error $response HTTP response or WP_Error object.
* @param string $context Context under which the hook is fired.
* @param string $class HTTP transport used.
* @param array $parsed_args HTTP request arguments.
* @param array $args HTTP request arguments.
* @param string $url The request URL.
*/
do_action( 'http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url );
do_action( 'http_api_debug', $response, 'response', \WpOrg\Requests\Requests::class, $args, $url );

if ( is_wp_error( $response ) ) {
return $response;
}

if ( ! $parsed_args['blocking'] ) {
if ( ! $args['blocking'] ) {
return array(
'headers' => array(),
'body' => '',
Expand All @@ -464,7 +581,7 @@ public function request( $url, $args = array() ) {
* @param array $parsed_args HTTP request arguments.
* @param string $url The request URL.
*/
return apply_filters( 'http_response', $response, $parsed_args, $url );
return apply_filters( 'http_response', $response, $args, $url );
}

/**
Expand Down Expand Up @@ -633,9 +750,7 @@ private function _dispatch_request( $url, $args ) {
* A WP_Error instance upon error. See WP_Http::response() for details.
*/
public function post( $url, $args = array() ) {
$defaults = array( 'method' => 'POST' );
$parsed_args = wp_parse_args( $args, $defaults );
return $this->request( $url, $parsed_args );
return $this->normalize_request_args( $url, $args, 'POST' );
}

/**
Expand All @@ -645,15 +760,13 @@ public function post( $url, $args = array() ) {
*
* @since 2.7.0
*
* @param string $url The request URL.
* @param string|array $url The request URL or array of remote requests that will be run in parallel.
* @param string|array $args Optional. Override the defaults.
* @return array|WP_Error Array containing 'headers', 'body', 'response', 'cookies', 'filename'.
* A WP_Error instance upon error. See WP_Http::response() for details.
*/
public function get( $url, $args = array() ) {
$defaults = array( 'method' => 'GET' );
$parsed_args = wp_parse_args( $args, $defaults );
return $this->request( $url, $parsed_args );
return $this->normalize_request_args( $url, $args, 'GET' );
}

/**
Expand All @@ -669,8 +782,52 @@ public function get( $url, $args = array() ) {
* A WP_Error instance upon error. See WP_Http::response() for details.
*/
public function head( $url, $args = array() ) {
$defaults = array( 'method' => 'HEAD' );
return $this->normalize_request_args( $url, $args, 'HEAD' );
}

/**
* Normalize the request arguments for a GET, HEAD, or POST request.
*
* @param string|array $url The request URL or array of remote requests that will be run in parallel.
* @param string|array $args Request arguments, optional. Override the defaults.
* @param string $method Request method to make.
* @return array Array containing 'headers', 'body', 'response', 'cookies', 'filename'.
* A WP_Error instance upon error.
*/
protected function normalize_request_args( $url, $args, $method ) {
$defaults = array( 'method' => $method );

// Support an array of parallel requests.
if ( is_array( $url ) ) {
$parsed_requests = array();

if ( ! empty( $args ) ) {
_doing_it_wrong(
__FUNCTION__,
__( 'Arguments passed to the second $args parameter are ignored when $url is an array of parallel requests.' ),
'6.0.0'
);
}

foreach ( $url as $i => $request ) {
// Support an array of string URLs.
if ( ! is_array( $request ) ) {
$request = array( $request, array() );
}

list( $request_url, $request_args ) = $request;

$parsed_requests[ $i ] = array(
$request_url,
wp_parse_args( $request_args, $defaults ),
);
}

return $this->request( $parsed_requests );
}

$parsed_args = wp_parse_args( $args, $defaults );

return $this->request( $url, $parsed_args );
}

Expand Down
30 changes: 15 additions & 15 deletions src/wp-includes/http.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,11 @@ function wp_safe_remote_head( $url, $args = array() ) {
*
* @since 2.7.0
*
* @see WP_Http::request() For information on default arguments.
* @see WP_Http::format_request() For information on default arguments.
*
* @param string $url URL to retrieve.
* @param array $args Optional. Request arguments. Default empty array.
* See WP_Http::request() for information on accepted arguments.
* @param string|array $url URL to retrieve or array of remote requests that will be run in parallel.
* @param array $args Optional. Request arguments. Default empty array.
* See WP_Http::request() for information on accepted arguments.
* @return array|WP_Error The response array or a WP_Error on failure.
* See WP_Http::request() for information on return value.
*/
Expand All @@ -178,9 +178,9 @@ function wp_remote_request( $url, $args = array() ) {
* @see wp_remote_request() For more information on the response array format.
* @see WP_Http::request() For default arguments information.
*
* @param string $url URL to retrieve.
* @param array $args Optional. Request arguments. Default empty array.
* See WP_Http::request() for information on accepted arguments.
* @param string|array $url URL to retrieve or array of remote requests that will be run in parallel.
* @param array $args Optional. Request arguments. Default empty array.
* See WP_Http::request() for information on accepted arguments.
* @return array|WP_Error The response or WP_Error on failure.
* See WP_Http::request() for information on return value.
*/
Expand All @@ -197,11 +197,11 @@ function wp_remote_get( $url, $args = array() ) {
* @since 2.7.0
*
* @see wp_remote_request() For more information on the response array format.
* @see WP_Http::request() For default arguments information.
* @see WP_Http::format_request() For default arguments information.
*
* @param string $url URL to retrieve.
* @param array $args Optional. Request arguments. Default empty array.
* See WP_Http::request() for information on accepted arguments.
* @param string|array $url URL to retrieve or array of remote requests that will be run in parallel.
* @param array $args Optional. Request arguments. Default empty array.
* See WP_Http::request() for information on accepted arguments.
* @return array|WP_Error The response or WP_Error on failure.
* See WP_Http::request() for information on return value.
*/
Expand All @@ -218,11 +218,11 @@ function wp_remote_post( $url, $args = array() ) {
* @since 2.7.0
*
* @see wp_remote_request() For more information on the response array format.
* @see WP_Http::request() For default arguments information.
* @see WP_Http::format_request() For default arguments information.
*
* @param string $url URL to retrieve.
* @param array $args Optional. Request arguments. Default empty array.
* See WP_Http::request() for information on accepted arguments.
* @param string|array $url URL to retrieve or array of remote requests that will be run in parallel.
* @param array $args Optional. Request arguments. Default empty array.
* See WP_Http::request() for information on accepted arguments.
* @return array|WP_Error The response or WP_Error on failure.
* See WP_Http::request() for information on return value.
*/
Expand Down
Loading
Loading