request.php
来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 1,192 行 · 第 1/3 页
PHP
1,192 行
*/
function setHttpVer($http)
{
$this->_http = $http;
}
/**
* Adds a request header
*
* @param string Header name
* @param string Header value
* @access public
*/
function addHeader($name, $value)
{
$this->_requestHeaders[strtolower($name)] = $value;
}
/**
* Removes a request header
*
* @param string Header name to remove
* @access public
*/
function removeHeader($name)
{
if (isset($this->_requestHeaders[strtolower($name)])) {
unset($this->_requestHeaders[strtolower($name)]);
}
}
/**
* Adds a querystring parameter
*
* @param string Querystring parameter name
* @param string Querystring parameter value
* @param bool Whether the value is already urlencoded or not, default = not
* @access public
*/
function addQueryString($name, $value, $preencoded = false)
{
$this->_url->addQueryString($name, $value, $preencoded);
}
/**
* Sets the querystring to literally what you supply
*
* @param string The querystring data. Should be of the format foo=bar&x=y etc
* @param bool Whether data is already urlencoded or not, default = already encoded
* @access public
*/
function addRawQueryString($querystring, $preencoded = true)
{
$this->_url->addRawQueryString($querystring, $preencoded);
}
/**
* Adds postdata items
*
* @param string Post data name
* @param string Post data value
* @param bool Whether data is already urlencoded or not, default = not
* @access public
*/
function addPostData($name, $value, $preencoded = false)
{
if ($preencoded) {
$this->_postData[$name] = $value;
} else {
$this->_postData[$name] = $this->_arrayMapRecursive('urlencode', $value);
}
}
/**
* Recursively applies the callback function to the value
*
* @param mixed Callback function
* @param mixed Value to process
* @access private
* @return mixed Processed value
*/
function _arrayMapRecursive($callback, $value)
{
if (!is_array($value)) {
return call_user_func($callback, $value);
} else {
$map = array();
foreach ($value as $k => $v) {
$map[$k] = $this->_arrayMapRecursive($callback, $v);
}
return $map;
}
}
/**
* Adds a file to upload
*
* This also changes content-type to 'multipart/form-data' for proper upload
*
* @access public
* @param string name of file-upload field
* @param mixed file name(s)
* @param mixed content-type(s) of file(s) being uploaded
* @return bool true on success
* @throws PEAR_Error
*/
function addFile($inputName, $fileName, $contentType = 'application/octet-stream')
{
if (!is_array($fileName) && !is_readable($fileName)) {
return PEAR::raiseError("File '{$fileName}' is not readable");
} elseif (is_array($fileName)) {
foreach ($fileName as $name) {
if (!is_readable($name)) {
return PEAR::raiseError("File '{$name}' is not readable");
}
}
}
$this->addHeader('Content-Type', 'multipart/form-data');
$this->_postFiles[$inputName] = array(
'name' => $fileName,
'type' => $contentType
);
return true;
}
/**
* Adds raw postdata (DEPRECATED)
*
* @param string The data
* @param bool Whether data is preencoded or not, default = already encoded
* @access public
* @deprecated deprecated since 1.3.0, method addBody() should be used instead
*/
function addRawPostData($postdata, $preencoded = true)
{
$this->_body = $preencoded ? $postdata : urlencode($postdata);
}
/**
* Sets the request body (for POST, PUT and similar requests)
*
* @param string Request body
* @access public
*/
function setBody($body)
{
$this->_body = $body;
}
/**
* Clears any postdata that has been added (DEPRECATED).
*
* Useful for multiple request scenarios.
*
* @access public
* @deprecated deprecated since 1.2
*/
function clearPostData()
{
$this->_postData = null;
}
/**
* Appends a cookie to "Cookie:" header
*
* @param string $name cookie name
* @param string $value cookie value
* @access public
*/
function addCookie($name, $value)
{
$cookies = isset($this->_requestHeaders['cookie']) ? $this->_requestHeaders['cookie']. '; ' : '';
$this->addHeader('Cookie', $cookies . $name . '=' . $value);
}
/**
* Clears any cookies that have been added (DEPRECATED).
*
* Useful for multiple request scenarios
*
* @access public
* @deprecated deprecated since 1.2
*/
function clearCookies()
{
$this->removeHeader('Cookie');
}
/**
* Sends the request
*
* @access public
* @param bool Whether to store response body in Response object property,
* set this to false if downloading a LARGE file and using a Listener
* @return mixed PEAR error on error, true otherwise
*/
function sendRequest($saveBody = true)
{
if (!is_a($this->_url, 'Net_URL')) {
return PEAR::raiseError('No URL given.');
}
$host = isset($this->_proxy_host) ? $this->_proxy_host : $this->_url->host;
$port = isset($this->_proxy_port) ? $this->_proxy_port : $this->_url->port;
// 4.3.0 supports SSL connections using OpenSSL. The function test determines
// we running on at least 4.3.0
if (strcasecmp($this->_url->protocol, 'https') == 0 AND function_exists('file_get_contents') AND extension_loaded('openssl')) {
if (isset($this->_proxy_host)) {
return PEAR::raiseError('HTTPS proxies are not supported.');
}
$host = 'ssl://' . $host;
}
// magic quotes may fuck up file uploads and chunked response processing
$magicQuotes = ini_get('magic_quotes_runtime');
ini_set('magic_quotes_runtime', false);
// If this is a second request, we may get away without
// re-connecting if they're on the same server
$err = $this->_sock->connect($host, $port, null, $this->_timeout, $this->_socketOptions);
PEAR::isError($err) or $err = $this->_sock->write($this->_buildRequest());
if (!PEAR::isError($err)) {
if (!empty($this->_readTimeout)) {
$this->_sock->setTimeout($this->_readTimeout[0], $this->_readTimeout[1]);
}
$this->_notify('sentRequest');
// Read the response
$this->_response = &new HTTP_Response($this->_sock, $this->_listeners);
$err = $this->_response->process($this->_saveBody && $saveBody);
}
ini_set('magic_quotes_runtime', $magicQuotes);
if (PEAR::isError($err)) {
return $err;
}
// Check for redirection
if ( $this->_allowRedirects
AND $this->_redirects <= $this->_maxRedirects
AND $this->getResponseCode() > 300
AND $this->getResponseCode() < 399
AND !empty($this->_response->_headers['location'])) {
$redirect = $this->_response->_headers['location'];
// Absolute URL
if (preg_match('/^https?:\/\//i', $redirect)) {
$this->_url = &new Net_URL($redirect);
$this->addHeader('Host', $this->_generateHostHeader());
// Absolute path
} elseif ($redirect{0} == '/') {
$this->_url->path = $redirect;
// Relative path
} elseif (substr($redirect, 0, 3) == '../' OR substr($redirect, 0, 2) == './') {
if (substr($this->_url->path, -1) == '/') {
$redirect = $this->_url->path . $redirect;
} else {
$redirect = dirname($this->_url->path) . '/' . $redirect;
}
$redirect = Net_URL::resolvePath($redirect);
$this->_url->path = $redirect;
// Filename, no path
} else {
if (substr($this->_url->path, -1) == '/') {
$redirect = $this->_url->path . $redirect;
} else {
$redirect = dirname($this->_url->path) . '/' . $redirect;
}
$this->_url->path = $redirect;
}
$this->_redirects++;
return $this->sendRequest($saveBody);
// Too many redirects
} elseif ($this->_allowRedirects AND $this->_redirects > $this->_maxRedirects) {
return PEAR::raiseError('Too many redirects');
}
$this->_sock->disconnect();
return true;
}
/**
* Returns the response code
*
* @access public
* @return mixed Response code, false if not set
*/
function getResponseCode()
{
return isset($this->_response->_code) ? $this->_response->_code : false;
}
/**
* Returns either the named header or all if no name given
*
* @access public
* @param string The header name to return, do not set to get all headers
* @return mixed either the value of $headername (false if header is not present)
* or an array of all headers
*/
function getResponseHeader($headername = null)
{
if (!isset($headername)) {
return isset($this->_response->_headers)? $this->_response->_headers: array();
} else {
$headername = strtolower($headername);
return isset($this->_response->_headers[$headername]) ? $this->_response->_headers[$headername] : false;
}
}
/**
* Returns the body of the response
*
* @access public
* @return mixed response body, false if not set
*/
function getResponseBody()
{
return isset($this->_response->_body) ? $this->_response->_body : false;
}
/**
* Returns cookies set in response
*
* @access public
* @return mixed array of response cookies, false if none are present
*/
function getResponseCookies()
{
return isset($this->_response->_cookies) ? $this->_response->_cookies : false;
}
/**
* Builds the request string
*
* @access private
* @return string The request string
*/
function _buildRequest()
{
$separator = ini_get('arg_separator.output');
ini_set('arg_separator.output', '&');
$querystring = ($querystring = $this->_url->getQueryString()) ? '?' . $querystring : '';
ini_set('arg_separator.output', $separator);
$host = isset($this->_proxy_host) ? $this->_url->protocol . '://' . $this->_url->host : '';
$port = (isset($this->_proxy_host) AND $this->_url->port != 80) ? ':' . $this->_url->port : '';
$path = (empty($this->_url->path)? '/': $this->_url->path) . $querystring;
$url = $host . $port . $path;
$request = $this->_method . ' ' . $url . ' HTTP/' . $this->_http . "\r\n";
if (in_array($this->_method, $this->_bodyDisallowed) ||
(HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_body)) ||
(HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_postData) && empty($this->_postFiles))) {
$this->removeHeader('Content-Type');
} else {
if (empty($this->_requestHeaders['content-type'])) {
// Add default content-type
$this->addHeader('Content-Type', 'application/x-www-form-urlencoded');
} elseif ('multipart/form-data' == $this->_requestHeaders['content-type']) {
$boundary = 'HTTP_Request_' . md5(uniqid('request') . microtime());
$this->addHeader('Content-Type', 'multipart/form-data; boundary=' . $boundary);
}
}
// Request Headers
if (!empty($this->_requestHeaders)) {
foreach ($this->_requestHeaders as $name => $value) {
$canonicalName = implode('-', array_map('ucfirst', explode('-', $name)));
$request .= $canonicalName . ': ' . $value . "\r\n";
}
}
// No post data or wrong method, so simply add a final CRLF
if (in_array($this->_method, $this->_bodyDisallowed) ||
(HTTP_REQUEST_METHOD_POST != $this->_method && empty($this->_body))) {
$request .= "\r\n";
// Post data if it's an array
} elseif (HTTP_REQUEST_METHOD_POST == $this->_method &&
(!empty($this->_postData) || !empty($this->_postFiles))) {
// "normal" POST request
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?