116 if ( isset($working_transport[$transport]) ) |
116 if ( isset($working_transport[$transport]) ) |
117 $nonblocking_transport[] = &$working_transport[$transport]; |
117 $nonblocking_transport[] = &$working_transport[$transport]; |
118 } |
118 } |
119 } |
119 } |
120 |
120 |
121 if ( has_filter('http_transport_get_debug') ) |
121 do_action( 'http_transport_get_debug', $working_transport, $blocking_transport, $nonblocking_transport ); |
122 do_action('http_transport_get_debug', $working_transport, $blocking_transport, $nonblocking_transport); |
|
123 |
122 |
124 if ( isset($args['blocking']) && !$args['blocking'] ) |
123 if ( isset($args['blocking']) && !$args['blocking'] ) |
125 return $nonblocking_transport; |
124 return $nonblocking_transport; |
126 else |
125 else |
127 return $blocking_transport; |
126 return $blocking_transport; |
164 if ( isset($working_transport[$transport]) ) |
163 if ( isset($working_transport[$transport]) ) |
165 $nonblocking_transport[] = &$working_transport[$transport]; |
164 $nonblocking_transport[] = &$working_transport[$transport]; |
166 } |
165 } |
167 } |
166 } |
168 |
167 |
169 if ( has_filter('http_transport_post_debug') ) |
168 do_action( 'http_transport_post_debug', $working_transport, $blocking_transport, $nonblocking_transport ); |
170 do_action('http_transport_post_debug', $working_transport, $blocking_transport, $nonblocking_transport); |
|
171 |
169 |
172 if ( isset($args['blocking']) && !$args['blocking'] ) |
170 if ( isset($args['blocking']) && !$args['blocking'] ) |
173 return $nonblocking_transport; |
171 return $nonblocking_transport; |
174 else |
172 else |
175 return $blocking_transport; |
173 return $blocking_transport; |
208 * the entire content. It doesn't actually always mean that PHP will continue going after making |
206 * the entire content. It doesn't actually always mean that PHP will continue going after making |
209 * the request. |
207 * the request. |
210 * |
208 * |
211 * @access public |
209 * @access public |
212 * @since 2.7.0 |
210 * @since 2.7.0 |
|
211 * @todo Refactor this code. The code in this method extends the scope of its original purpose |
|
212 * and should be refactored to allow for cleaner abstraction and reduce duplication of the |
|
213 * code. One suggestion is to create a class specifically for the arguments, however |
|
214 * preliminary refactoring to this affect has affect more than just the scope of the |
|
215 * arguments. Something to ponder at least. |
213 * |
216 * |
214 * @param string $url URI resource. |
217 * @param string $url URI resource. |
215 * @param str|array $args Optional. Override the defaults. |
218 * @param str|array $args Optional. Override the defaults. |
216 * @return array containing 'headers', 'body', 'response', 'cookies' |
219 * @return array containing 'headers', 'body', 'response', 'cookies' |
217 */ |
220 */ |
234 ); |
237 ); |
235 |
238 |
236 $r = wp_parse_args( $args, $defaults ); |
239 $r = wp_parse_args( $args, $defaults ); |
237 $r = apply_filters( 'http_request_args', $r, $url ); |
240 $r = apply_filters( 'http_request_args', $r, $url ); |
238 |
241 |
|
242 // Allow plugins to short-circuit the request |
|
243 $pre = apply_filters( 'pre_http_request', false, $r, $url ); |
|
244 if ( false !== $pre ) |
|
245 return $pre; |
|
246 |
239 $arrURL = parse_url($url); |
247 $arrURL = parse_url($url); |
240 |
248 |
241 if ( $this->block_request( $url ) ) |
249 if ( $this->block_request( $url ) ) |
242 return new WP_Error('http_request_failed', __('User has blocked requests through HTTP.')); |
250 return new WP_Error('http_request_failed', __('User has blocked requests through HTTP.')); |
243 |
251 |
272 WP_Http::buildCookieHeader( $r ); |
280 WP_Http::buildCookieHeader( $r ); |
273 |
281 |
274 if ( WP_Http_Encoding::is_available() ) |
282 if ( WP_Http_Encoding::is_available() ) |
275 $r['headers']['Accept-Encoding'] = WP_Http_Encoding::accept_encoding(); |
283 $r['headers']['Accept-Encoding'] = WP_Http_Encoding::accept_encoding(); |
276 |
284 |
277 if ( is_null($r['body']) ) { |
285 if ( empty($r['body']) ) { |
278 // Some servers fail when sending content without the content-length |
286 // Some servers fail when sending content without the content-length header being set. |
279 // header being set. |
287 // Also, to fix another bug, we only send when doing POST and PUT and the content-length |
280 $r['headers']['Content-Length'] = 0; |
288 // header isn't already set. |
|
289 if( ($r['method'] == 'POST' || $r['method'] == 'PUT') && ! isset($r['headers']['Content-Length']) ) |
|
290 $r['headers']['Content-Length'] = 0; |
|
291 |
|
292 // The method is ambiguous, because we aren't talking about HTTP methods, the "get" in |
|
293 // this case is simply that we aren't sending any bodies and to get the transports that |
|
294 // don't support sending bodies along with those which do. |
281 $transports = WP_Http::_getTransport($r); |
295 $transports = WP_Http::_getTransport($r); |
282 } else { |
296 } else { |
283 if ( is_array( $r['body'] ) || is_object( $r['body'] ) ) { |
297 if ( is_array( $r['body'] ) || is_object( $r['body'] ) ) { |
284 if ( ! version_compare(phpversion(), '5.1.2', '>=') ) |
298 if ( ! version_compare(phpversion(), '5.1.2', '>=') ) |
285 $r['body'] = _http_build_query($r['body'], null, '&'); |
299 $r['body'] = _http_build_query($r['body'], null, '&'); |
290 } |
304 } |
291 |
305 |
292 if ( ! isset( $r['headers']['Content-Length'] ) && ! isset( $r['headers']['content-length'] ) ) |
306 if ( ! isset( $r['headers']['Content-Length'] ) && ! isset( $r['headers']['content-length'] ) ) |
293 $r['headers']['Content-Length'] = strlen($r['body']); |
307 $r['headers']['Content-Length'] = strlen($r['body']); |
294 |
308 |
|
309 // The method is ambiguous, because we aren't talking about HTTP methods, the "post" in |
|
310 // this case is simply that we are sending HTTP body and to get the transports that do |
|
311 // support sending the body. Not all do, depending on the limitations of the PHP core |
|
312 // limitations. |
295 $transports = WP_Http::_postTransport($r); |
313 $transports = WP_Http::_postTransport($r); |
296 } |
314 } |
297 |
315 |
298 if ( has_action('http_api_debug') ) |
316 do_action( 'http_api_debug', $transports, 'transports_list' ); |
299 do_action('http_api_debug', $transports, 'transports_list'); |
|
300 |
317 |
301 $response = array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); |
318 $response = array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); |
302 foreach ( (array) $transports as $transport ) { |
319 foreach ( (array) $transports as $transport ) { |
303 $response = $transport->request($url, $r); |
320 $response = $transport->request($url, $r); |
304 |
321 |
305 if ( has_action('http_api_debug') ) |
322 do_action( 'http_api_debug', $response, 'response', get_class($transport) ); |
306 do_action( 'http_api_debug', $response, 'response', get_class($transport) ); |
|
307 |
323 |
308 if ( ! is_wp_error($response) ) |
324 if ( ! is_wp_error($response) ) |
309 return $response; |
325 return apply_filters( 'http_response', $response, $r, $url ); |
310 } |
326 } |
311 |
327 |
312 return $response; |
328 return $response; |
313 } |
329 } |
314 |
330 |
623 } else { |
639 } else { |
624 $arrURL['port'] = 80; |
640 $arrURL['port'] = 80; |
625 } |
641 } |
626 } |
642 } |
627 |
643 |
|
644 //fsockopen has issues with 'localhost' with IPv6 with certain versions of PHP, It attempts to connect to ::1, |
|
645 // which fails when the server is not setup for it. For compatibility, always connect to the IPv4 address. |
|
646 if ( 'localhost' == strtolower($fsockopen_host) ) |
|
647 $fsockopen_host = '127.0.0.1'; |
|
648 |
628 // There are issues with the HTTPS and SSL protocols that cause errors that can be safely |
649 // There are issues with the HTTPS and SSL protocols that cause errors that can be safely |
629 // ignored and should be ignored. |
650 // ignored and should be ignored. |
630 if ( true === $secure_transport ) |
651 if ( true === $secure_transport ) |
631 $error_reporting = error_reporting(0); |
652 $error_reporting = error_reporting(0); |
632 |
653 |
633 $startDelay = time(); |
654 $startDelay = time(); |
634 |
655 |
635 $proxy = new WP_HTTP_Proxy(); |
656 $proxy = new WP_HTTP_Proxy(); |
636 |
657 |
637 if ( !defined('WP_DEBUG') || ( defined('WP_DEBUG') && false === WP_DEBUG ) ) { |
658 if ( !WP_DEBUG ) { |
638 if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) |
659 if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) |
639 $handle = @fsockopen( $proxy->host(), $proxy->port(), $iError, $strError, $r['timeout'] ); |
660 $handle = @fsockopen( $proxy->host(), $proxy->port(), $iError, $strError, $r['timeout'] ); |
640 else |
661 else |
641 $handle = @fsockopen( $fsockopen_host, $arrURL['port'], $iError, $strError, $r['timeout'] ); |
662 $handle = @fsockopen( $fsockopen_host, $arrURL['port'], $iError, $strError, $r['timeout'] ); |
642 } else { |
663 } else { |
655 add_option( 'disable_fsockopen', $endDelay, null, true ); |
676 add_option( 'disable_fsockopen', $endDelay, null, true ); |
656 |
677 |
657 if ( false === $handle ) |
678 if ( false === $handle ) |
658 return new WP_Error('http_request_failed', $iError . ': ' . $strError); |
679 return new WP_Error('http_request_failed', $iError . ': ' . $strError); |
659 |
680 |
660 stream_set_timeout($handle, $r['timeout'] ); |
681 $timeout = (int) floor( $r['timeout'] ); |
|
682 $utimeout = $timeout == $r['timeout'] ? 0 : 1000000 * $r['timeout'] % 1000000; |
|
683 stream_set_timeout( $handle, $timeout, $utimeout ); |
661 |
684 |
662 if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) //Some proxies require full URL in this field. |
685 if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) //Some proxies require full URL in this field. |
663 $requestPath = $url; |
686 $requestPath = $url; |
664 else |
687 else |
665 $requestPath = $arrURL['path'] . ( isset($arrURL['query']) ? '?' . $arrURL['query'] : '' ); |
688 $requestPath = $arrURL['path'] . ( isset($arrURL['query']) ? '?' . $arrURL['query'] : '' ); |
803 return new WP_Error('http_request_failed', sprintf(__('Malformed URL: %s'), $url)); |
826 return new WP_Error('http_request_failed', sprintf(__('Malformed URL: %s'), $url)); |
804 |
827 |
805 if ( 'http' != $arrURL['scheme'] && 'https' != $arrURL['scheme'] ) |
828 if ( 'http' != $arrURL['scheme'] && 'https' != $arrURL['scheme'] ) |
806 $url = str_replace($arrURL['scheme'], 'http', $url); |
829 $url = str_replace($arrURL['scheme'], 'http', $url); |
807 |
830 |
808 if ( !defined('WP_DEBUG') || ( defined('WP_DEBUG') && false === WP_DEBUG ) ) |
831 if ( !WP_DEBUG ) |
809 $handle = @fopen($url, 'r'); |
832 $handle = @fopen($url, 'r'); |
810 else |
833 else |
811 $handle = fopen($url, 'r'); |
834 $handle = fopen($url, 'r'); |
812 |
835 |
813 if (! $handle) |
836 if (! $handle) |
814 return new WP_Error('http_request_failed', sprintf(__('Could not open handle for fopen() to %s'), $url)); |
837 return new WP_Error('http_request_failed', sprintf(__('Could not open handle for fopen() to %s'), $url)); |
815 |
838 |
816 stream_set_timeout($handle, $r['timeout'] ); |
839 $timeout = (int) floor( $r['timeout'] ); |
|
840 $utimeout = $timeout == $r['timeout'] ? 0 : 1000000 * $r['timeout'] % 1000000; |
|
841 stream_set_timeout( $handle, $timeout, $utimeout ); |
817 |
842 |
818 if ( ! $r['blocking'] ) { |
843 if ( ! $r['blocking'] ) { |
819 fclose($handle); |
844 fclose($handle); |
820 return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); |
845 return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); |
821 } |
846 } |
976 if ( ! is_null($r['body']) && ! empty($r['body'] ) ) |
1001 if ( ! is_null($r['body']) && ! empty($r['body'] ) ) |
977 $arrContext['http']['content'] = $r['body']; |
1002 $arrContext['http']['content'] = $r['body']; |
978 |
1003 |
979 $context = stream_context_create($arrContext); |
1004 $context = stream_context_create($arrContext); |
980 |
1005 |
981 if ( ! defined('WP_DEBUG') || ( defined('WP_DEBUG') && false === WP_DEBUG ) ) |
1006 if ( !WP_DEBUG ) |
982 $handle = @fopen($url, 'r', false, $context); |
1007 $handle = @fopen($url, 'r', false, $context); |
983 else |
1008 else |
984 $handle = fopen($url, 'r', false, $context); |
1009 $handle = fopen($url, 'r', false, $context); |
985 |
1010 |
986 if ( ! $handle) |
1011 if ( ! $handle) |
987 return new WP_Error('http_request_failed', sprintf(__('Could not open handle for fopen() to %s'), $url)); |
1012 return new WP_Error('http_request_failed', sprintf(__('Could not open handle for fopen() to %s'), $url)); |
988 |
1013 |
989 // WordPress supports PHP 4.3, which has this function. Removed sanity checking for |
1014 $timeout = (int) floor( $r['timeout'] ); |
990 // performance reasons. |
1015 $utimeout = $timeout == $r['timeout'] ? 0 : 1000000 * $r['timeout'] % 1000000; |
991 stream_set_timeout($handle, $r['timeout'] ); |
1016 stream_set_timeout( $handle, $timeout, $utimeout ); |
992 |
1017 |
993 if ( ! $r['blocking'] ) { |
1018 if ( ! $r['blocking'] ) { |
994 stream_set_blocking($handle, 0); |
1019 stream_set_blocking($handle, 0); |
995 fclose($handle); |
1020 fclose($handle); |
996 return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); |
1021 return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); |
1114 $ssl_verify = isset($args['sslverify']) && $args['sslverify']; |
1142 $ssl_verify = isset($args['sslverify']) && $args['sslverify']; |
1115 if ( $is_local ) |
1143 if ( $is_local ) |
1116 $ssl_verify = apply_filters('https_local_ssl_verify', $ssl_verify); |
1144 $ssl_verify = apply_filters('https_local_ssl_verify', $ssl_verify); |
1117 elseif ( ! $is_local ) |
1145 elseif ( ! $is_local ) |
1118 $ssl_verify = apply_filters('https_ssl_verify', $ssl_verify); |
1146 $ssl_verify = apply_filters('https_ssl_verify', $ssl_verify); |
|
1147 |
|
1148 $r['timeout'] = (int) ceil( $r['timeout'] ); |
1119 |
1149 |
1120 $options = array( |
1150 $options = array( |
1121 'timeout' => $r['timeout'], |
1151 'timeout' => $r['timeout'], |
1122 'connecttimeout' => $r['timeout'], |
1152 'connecttimeout' => $r['timeout'], |
1123 'redirect' => $r['redirection'], |
1153 'redirect' => $r['redirection'], |
1141 $options['proxyauth'] = $proxy->authentication(); |
1171 $options['proxyauth'] = $proxy->authentication(); |
1142 $options['proxyauthtype'] = HTTP_AUTH_BASIC; |
1172 $options['proxyauthtype'] = HTTP_AUTH_BASIC; |
1143 } |
1173 } |
1144 } |
1174 } |
1145 |
1175 |
1146 if ( !defined('WP_DEBUG') || ( defined('WP_DEBUG') && false === WP_DEBUG ) ) //Emits warning level notices for max redirects and timeouts |
1176 if ( !WP_DEBUG ) //Emits warning level notices for max redirects and timeouts |
1147 $strResponse = @http_request($r['method'], $url, $r['body'], $options, $info); |
1177 $strResponse = @http_request($r['method'], $url, $r['body'], $options, $info); |
1148 else |
1178 else |
1149 $strResponse = http_request($r['method'], $url, $r['body'], $options, $info); //Emits warning level notices for max redirects and timeouts |
1179 $strResponse = http_request($r['method'], $url, $r['body'], $options, $info); //Emits warning level notices for max redirects and timeouts |
1150 |
1180 |
1151 // Error may still be set, Response may return headers or partial document, and error |
1181 // Error may still be set, Response may return headers or partial document, and error |
1158 |
1188 |
1159 list($theHeaders, $theBody) = explode("\r\n\r\n", $strResponse, 2); |
1189 list($theHeaders, $theBody) = explode("\r\n\r\n", $strResponse, 2); |
1160 $theHeaders = WP_Http::processHeaders($theHeaders); |
1190 $theHeaders = WP_Http::processHeaders($theHeaders); |
1161 |
1191 |
1162 if ( ! empty( $theBody ) && isset( $theHeaders['headers']['transfer-encoding'] ) && 'chunked' == $theHeaders['headers']['transfer-encoding'] ) { |
1192 if ( ! empty( $theBody ) && isset( $theHeaders['headers']['transfer-encoding'] ) && 'chunked' == $theHeaders['headers']['transfer-encoding'] ) { |
1163 if ( !defined('WP_DEBUG') || ( defined('WP_DEBUG') && false === WP_DEBUG ) ) |
1193 if ( !WP_DEBUG ) |
1164 $theBody = @http_chunked_decode($theBody); |
1194 $theBody = @http_chunked_decode($theBody); |
1165 else |
1195 else |
1166 $theBody = http_chunked_decode($theBody); |
1196 $theBody = http_chunked_decode($theBody); |
1167 } |
1197 } |
1168 |
1198 |
1229 } |
1259 } |
1230 |
1260 |
1231 // Construct Cookie: header if any cookies are set. |
1261 // Construct Cookie: header if any cookies are set. |
1232 WP_Http::buildCookieHeader( $r ); |
1262 WP_Http::buildCookieHeader( $r ); |
1233 |
1263 |
1234 // cURL extension will sometimes fail when the timeout is less than 1 as it may round down |
|
1235 // to 0, which gives it unlimited timeout. |
|
1236 if ( $r['timeout'] > 0 && $r['timeout'] < 1 ) |
|
1237 $r['timeout'] = 1; |
|
1238 |
|
1239 $handle = curl_init(); |
1264 $handle = curl_init(); |
1240 |
1265 |
1241 // cURL offers really easy proxy support. |
1266 // cURL offers really easy proxy support. |
1242 $proxy = new WP_HTTP_Proxy(); |
1267 $proxy = new WP_HTTP_Proxy(); |
1243 |
1268 |
1266 if ( $is_local ) |
1291 if ( $is_local ) |
1267 $ssl_verify = apply_filters('https_local_ssl_verify', $ssl_verify); |
1292 $ssl_verify = apply_filters('https_local_ssl_verify', $ssl_verify); |
1268 elseif ( ! $is_local ) |
1293 elseif ( ! $is_local ) |
1269 $ssl_verify = apply_filters('https_ssl_verify', $ssl_verify); |
1294 $ssl_verify = apply_filters('https_ssl_verify', $ssl_verify); |
1270 |
1295 |
|
1296 |
|
1297 // CURLOPT_TIMEOUT and CURLOPT_CONNECTTIMEOUT expect integers. Have to use ceil since |
|
1298 // a value of 0 will allow an ulimited timeout. |
|
1299 $timeout = (int) ceil( $r['timeout'] ); |
|
1300 curl_setopt( $handle, CURLOPT_CONNECTTIMEOUT, $timeout ); |
|
1301 curl_setopt( $handle, CURLOPT_TIMEOUT, $timeout ); |
|
1302 |
1271 curl_setopt( $handle, CURLOPT_URL, $url); |
1303 curl_setopt( $handle, CURLOPT_URL, $url); |
1272 curl_setopt( $handle, CURLOPT_RETURNTRANSFER, true ); |
1304 curl_setopt( $handle, CURLOPT_RETURNTRANSFER, true ); |
1273 curl_setopt( $handle, CURLOPT_SSL_VERIFYHOST, $ssl_verify ); |
1305 curl_setopt( $handle, CURLOPT_SSL_VERIFYHOST, $ssl_verify ); |
1274 curl_setopt( $handle, CURLOPT_SSL_VERIFYPEER, $ssl_verify ); |
1306 curl_setopt( $handle, CURLOPT_SSL_VERIFYPEER, $ssl_verify ); |
1275 curl_setopt( $handle, CURLOPT_USERAGENT, $r['user-agent'] ); |
1307 curl_setopt( $handle, CURLOPT_USERAGENT, $r['user-agent'] ); |
1276 curl_setopt( $handle, CURLOPT_CONNECTTIMEOUT, $r['timeout'] ); |
|
1277 curl_setopt( $handle, CURLOPT_TIMEOUT, $r['timeout'] ); |
|
1278 curl_setopt( $handle, CURLOPT_MAXREDIRS, $r['redirection'] ); |
1308 curl_setopt( $handle, CURLOPT_MAXREDIRS, $r['redirection'] ); |
1279 |
1309 |
1280 switch ( $r['method'] ) { |
1310 switch ( $r['method'] ) { |
1281 case 'HEAD': |
1311 case 'HEAD': |
1282 curl_setopt( $handle, CURLOPT_NOBODY, true ); |
1312 curl_setopt( $handle, CURLOPT_NOBODY, true ); |
1283 break; |
1313 break; |
1284 case 'POST': |
1314 case 'POST': |
1285 curl_setopt( $handle, CURLOPT_POST, true ); |
1315 curl_setopt( $handle, CURLOPT_POST, true ); |
1286 curl_setopt( $handle, CURLOPT_POSTFIELDS, $r['body'] ); |
1316 curl_setopt( $handle, CURLOPT_POSTFIELDS, $r['body'] ); |
1287 break; |
1317 break; |
|
1318 case 'PUT': |
|
1319 curl_setopt( $handle, CURLOPT_CUSTOMREQUEST, 'PUT' ); |
|
1320 curl_setopt( $handle, CURLOPT_POSTFIELDS, $r['body'] ); |
|
1321 break; |
1288 } |
1322 } |
1289 |
1323 |
1290 if ( true === $r['blocking'] ) |
1324 if ( true === $r['blocking'] ) |
1291 curl_setopt( $handle, CURLOPT_HEADER, true ); |
1325 curl_setopt( $handle, CURLOPT_HEADER, true ); |
1292 else |
1326 else |
1322 } |
1356 } |
1323 |
1357 |
1324 $theResponse = curl_exec( $handle ); |
1358 $theResponse = curl_exec( $handle ); |
1325 |
1359 |
1326 if ( !empty($theResponse) ) { |
1360 if ( !empty($theResponse) ) { |
1327 $parts = explode("\r\n\r\n", $theResponse); |
|
1328 |
|
1329 $headerLength = curl_getinfo($handle, CURLINFO_HEADER_SIZE); |
1361 $headerLength = curl_getinfo($handle, CURLINFO_HEADER_SIZE); |
1330 $theHeaders = trim( substr($theResponse, 0, $headerLength) ); |
1362 $theHeaders = trim( substr($theResponse, 0, $headerLength) ); |
1331 $theBody = substr( $theResponse, $headerLength ); |
1363 $theBody = substr( $theResponse, $headerLength ); |
1332 if ( false !== strrpos($theHeaders, "\r\n\r\n") ) { |
1364 if ( false !== strrpos($theHeaders, "\r\n\r\n") ) { |
1333 $headerParts = explode("\r\n\r\n", $theHeaders); |
1365 $headerParts = explode("\r\n\r\n", $theHeaders); |
1782 * @param string $compressed String to decompress. |
1814 * @param string $compressed String to decompress. |
1783 * @param int $length The optional length of the compressed data. |
1815 * @param int $length The optional length of the compressed data. |
1784 * @return string|bool False on failure. |
1816 * @return string|bool False on failure. |
1785 */ |
1817 */ |
1786 function decompress( $compressed, $length = null ) { |
1818 function decompress( $compressed, $length = null ) { |
1787 $decompressed = gzinflate( $compressed ); |
1819 $decompressed = WP_Http_Encoding::compatible_gzinflate( $compressed ); |
1788 |
1820 |
1789 if ( false !== $decompressed ) |
1821 if ( false !== $decompressed ) |
1790 return $decompressed; |
1822 return $decompressed; |
1791 |
1823 |
1792 $decompressed = gzuncompress( $compressed ); |
1824 $decompressed = gzuncompress( $compressed ); |
1800 if ( false !== $decompressed ) |
1832 if ( false !== $decompressed ) |
1801 return $decompressed; |
1833 return $decompressed; |
1802 } |
1834 } |
1803 |
1835 |
1804 return $compressed; |
1836 return $compressed; |
|
1837 } |
|
1838 |
|
1839 /** |
|
1840 * Decompression of deflated string while staying compatible with the majority of servers. |
|
1841 * |
|
1842 * Certain Servers will return deflated data with headers which PHP's gziniflate() |
|
1843 * function cannot handle out of the box. The following function lifted from |
|
1844 * http://au2.php.net/manual/en/function.gzinflate.php#77336 will attempt to deflate |
|
1845 * the various return forms used. |
|
1846 * |
|
1847 * @since 2.8.1 |
|
1848 * @link http://au2.php.net/manual/en/function.gzinflate.php#77336 |
|
1849 * |
|
1850 * @param string $gzData String to decompress. |
|
1851 * @return string|bool False on failure. |
|
1852 */ |
|
1853 function compatible_gzinflate($gzData) { |
|
1854 if ( substr($gzData, 0, 3) == "\x1f\x8b\x08" ) { |
|
1855 $i = 10; |
|
1856 $flg = ord( substr($gzData, 3, 1) ); |
|
1857 if ( $flg > 0 ) { |
|
1858 if ( $flg & 4 ) { |
|
1859 list($xlen) = unpack('v', substr($gzData, $i, 2) ); |
|
1860 $i = $i + 2 + $xlen; |
|
1861 } |
|
1862 if ( $flg & 8 ) |
|
1863 $i = strpos($gzData, "\0", $i) + 1; |
|
1864 if ( $flg & 16 ) |
|
1865 $i = strpos($gzData, "\0", $i) + 1; |
|
1866 if ( $flg & 2 ) |
|
1867 $i = $i + 2; |
|
1868 } |
|
1869 return gzinflate( substr($gzData, $i, -8) ); |
|
1870 } else { |
|
1871 return false; |
|
1872 } |
1805 } |
1873 } |
1806 |
1874 |
1807 /** |
1875 /** |
1808 * What encoding types to accept and their priority values. |
1876 * What encoding types to accept and their priority values. |
1809 * |
1877 * |