/** * Send a HTTP request to a URI using streams with fopen(). * * @access public * @since 2.7.0 * * @param string $url * @param str|array $args Optional. Override the defaults. * @return array 'headers', 'body', 'cookies' and 'response' keys. */ function request($url, $args = array()) { $defaults = array('method' => 'GET', 'timeout' => 5, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => array(), 'body' => null, 'cookies' => array()); $r = nxt_parse_args($args, $defaults); if (isset($r['headers']['User-Agent'])) { $r['user-agent'] = $r['headers']['User-Agent']; unset($r['headers']['User-Agent']); } else { if (isset($r['headers']['user-agent'])) { $r['user-agent'] = $r['headers']['user-agent']; unset($r['headers']['user-agent']); } } // Construct Cookie: header if any cookies are set nxt_Http::buildCookieHeader($r); $arrURL = parse_url($url); if (false === $arrURL) { return new nxt_Error('http_request_failed', sprintf(__('Malformed URL: %s'), $url)); } if ('http' != $arrURL['scheme'] && 'https' != $arrURL['scheme']) { $url = preg_replace('|^' . preg_quote($arrURL['scheme'], '|') . '|', 'http', $url); } // Convert Header array to string. $strHeaders = ''; if (is_array($r['headers'])) { foreach ($r['headers'] as $name => $value) { $strHeaders .= "{$name}: {$value}\r\n"; } } else { if (is_string($r['headers'])) { $strHeaders = $r['headers']; } } $is_local = isset($args['local']) && $args['local']; $ssl_verify = isset($args['sslverify']) && $args['sslverify']; if ($is_local) { $ssl_verify = apply_filters('https_local_ssl_verify', $ssl_verify); } elseif (!$is_local) { $ssl_verify = apply_filters('https_ssl_verify', $ssl_verify); } $arrContext = array('http' => array('method' => strtoupper($r['method']), 'user_agent' => $r['user-agent'], 'max_redirects' => $r['redirection'], 'protocol_version' => (double) $r['httpversion'], 'header' => $strHeaders, 'timeout' => $r['timeout'], 'ssl' => array('verify_peer' => $ssl_verify, 'verify_host' => $ssl_verify))); $proxy = new nxt_HTTP_Proxy(); if ($proxy->is_enabled() && $proxy->send_through_proxy($url)) { $arrContext['http']['proxy'] = 'tcp://' . $proxy->host() . ':' . $proxy->port(); $arrContext['http']['request_fulluri'] = true; // We only support Basic authentication so this will only work if that is what your proxy supports. if ($proxy->use_authentication()) { $arrContext['http']['header'] .= $proxy->authentication_header() . "\r\n"; } } if (!is_null($r['body']) && !empty($r['body'])) { $arrContext['http']['content'] = $r['body']; } $context = stream_context_create($arrContext); if (!defined('nxt_DEBUG') || defined('nxt_DEBUG') && false === nxt_DEBUG) { $handle = @fopen($url, 'r', false, $context); } else { $handle = fopen($url, 'r', false, $context); } if (!$handle) { return new nxt_Error('http_request_failed', sprintf(__('Could not open handle for fopen() to %s'), $url)); } // NXTClass supports PHP 4.3, which has this function. Removed sanity checking for // performance reasons. stream_set_timeout($handle, $r['timeout']); if (!$r['blocking']) { stream_set_blocking($handle, 0); fclose($handle); return array('headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array()); } $strResponse = stream_get_contents($handle); $meta = stream_get_meta_data($handle); fclose($handle); $processedHeaders = array(); if (isset($meta['wrapper_data']['headers'])) { $processedHeaders = nxt_Http::processHeaders($meta['wrapper_data']['headers']); } else { $processedHeaders = nxt_Http::processHeaders($meta['wrapper_data']); } if (!empty($strResponse) && isset($processedHeaders['headers']['transfer-encoding']) && 'chunked' == $processedHeaders['headers']['transfer-encoding']) { $strResponse = nxt_Http::chunkTransferDecode($strResponse); } if (true === $r['decompress'] && true === nxt_Http_Encoding::should_decode($processedHeaders['headers'])) { $strResponse = nxt_Http_Encoding::decompress($strResponse); } return array('headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response'], 'cookies' => $processedHeaders['cookies']); }
/** * Send a HTTP request to a URI using streams with fopen(). * * @access public * @since 2.7.0 * * @param string $url * @param str|array $args Optional. Override the defaults. * @return array 'headers', 'body', 'response', 'cookies' and 'filename' keys. */ function request($url, $args = array()) { $defaults = array('method' => 'GET', 'timeout' => 5, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => array(), 'body' => null, 'cookies' => array()); $r = nxt_parse_args($args, $defaults); if (isset($r['headers']['User-Agent'])) { $r['user-agent'] = $r['headers']['User-Agent']; unset($r['headers']['User-Agent']); } else { if (isset($r['headers']['user-agent'])) { $r['user-agent'] = $r['headers']['user-agent']; unset($r['headers']['user-agent']); } } // Construct Cookie: header if any cookies are set nxt_Http::buildCookieHeader($r); $arrURL = parse_url($url); if (false === $arrURL) { return new nxt_Error('http_request_failed', sprintf(__('Malformed URL: %s'), $url)); } if ('http' != $arrURL['scheme'] && 'https' != $arrURL['scheme']) { $url = preg_replace('|^' . preg_quote($arrURL['scheme'], '|') . '|', 'http', $url); } // Convert Header array to string. $strHeaders = ''; if (is_array($r['headers'])) { foreach ($r['headers'] as $name => $value) { $strHeaders .= "{$name}: {$value}\r\n"; } } else { if (is_string($r['headers'])) { $strHeaders = $r['headers']; } } $is_local = isset($args['local']) && $args['local']; $ssl_verify = isset($args['sslverify']) && $args['sslverify']; if ($is_local) { $ssl_verify = apply_filters('https_local_ssl_verify', $ssl_verify); } elseif (!$is_local) { $ssl_verify = apply_filters('https_ssl_verify', $ssl_verify); } $arrContext = array('http' => array('method' => strtoupper($r['method']), 'user_agent' => $r['user-agent'], 'max_redirects' => $r['redirection'] + 1, 'protocol_version' => (double) $r['httpversion'], 'header' => $strHeaders, 'ignore_errors' => true, 'timeout' => $r['timeout'], 'ssl' => array('verify_peer' => $ssl_verify, 'verify_host' => $ssl_verify))); $proxy = new nxt_HTTP_Proxy(); if ($proxy->is_enabled() && $proxy->send_through_proxy($url)) { $arrContext['http']['proxy'] = 'tcp://' . $proxy->host() . ':' . $proxy->port(); $arrContext['http']['request_fulluri'] = true; // We only support Basic authentication so this will only work if that is what your proxy supports. if ($proxy->use_authentication()) { $arrContext['http']['header'] .= $proxy->authentication_header() . "\r\n"; } } if (!empty($r['body'])) { $arrContext['http']['content'] = $r['body']; } $context = stream_context_create($arrContext); if (!nxt_DEBUG) { $handle = @fopen($url, 'r', false, $context); } else { $handle = fopen($url, 'r', false, $context); } if (!$handle) { return new nxt_Error('http_request_failed', sprintf(__('Could not open handle for fopen() to %s'), $url)); } $timeout = (int) floor($r['timeout']); $utimeout = $timeout == $r['timeout'] ? 0 : 1000000 * $r['timeout'] % 1000000; stream_set_timeout($handle, $timeout, $utimeout); if (!$r['blocking']) { stream_set_blocking($handle, 0); fclose($handle); return array('headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array()); } if ($r['stream']) { if (!nxt_DEBUG) { $stream_handle = @fopen($r['filename'], 'w+'); } else { $stream_handle = fopen($r['filename'], 'w+'); } if (!$stream_handle) { return new nxt_Error('http_request_failed', sprintf(__('Could not open handle for fopen() to %s'), $r['filename'])); } stream_copy_to_stream($handle, $stream_handle); fclose($stream_handle); $strResponse = ''; } else { $strResponse = stream_get_contents($handle); } $meta = stream_get_meta_data($handle); fclose($handle); $processedHeaders = array(); if (isset($meta['wrapper_data']['headers'])) { $processedHeaders = nxt_Http::processHeaders($meta['wrapper_data']['headers']); } else { $processedHeaders = nxt_Http::processHeaders($meta['wrapper_data']); } // Streams does not provide an error code which we can use to see why the request stream stopped. // We can however test to see if a location header is present and return based on that. if (isset($processedHeaders['headers']['location']) && 0 !== $args['_redirection']) { return new nxt_Error('http_request_failed', __('Too many redirects.')); } if (!empty($strResponse) && isset($processedHeaders['headers']['transfer-encoding']) && 'chunked' == $processedHeaders['headers']['transfer-encoding']) { $strResponse = nxt_Http::chunkTransferDecode($strResponse); } if (true === $r['decompress'] && true === nxt_Http_Encoding::should_decode($processedHeaders['headers'])) { $strResponse = nxt_Http_Encoding::decompress($strResponse); } return array('headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response'], 'cookies' => $processedHeaders['cookies'], 'filename' => $r['filename']); }