📄 client.php
字号:
} if (! $adapter instanceof Zend_Http_Client_Adapter_Interface) { require_once 'Zend/Http/Client/Exception.php'; throw new Zend_Http_Client_Exception('Passed adapter is not a HTTP connection adapter'); } $this->adapter = $adapter; $config = $this->config; unset($config['adapter']); $this->adapter->setConfig($config); } /** * Send the HTTP request and return an HTTP response object * * @param string $method * @return Zend_Http_Response */ public function request($method = null) { if (! $this->uri instanceof Zend_Uri_Http) { require_once 'Zend/Http/Client/Exception.php'; throw new Zend_Http_Client_Exception('No valid URI has been passed to the client'); } if ($method) $this->setMethod($method); $this->redirectCounter = 0; $response = null; // Make sure the adapter is loaded if ($this->adapter == null) $this->setAdapter($this->config['adapter']); // Send the first request. If redirected, continue. do { // Clone the URI and add the additional GET parameters to it $uri = clone $this->uri; if (! empty($this->paramsGet)) { $query = $uri->getQuery(); if (! empty($query)) $query .= '&'; $query .= http_build_query($this->paramsGet, null, '&'); $uri->setQuery($query); } $body = $this->prepare_body(); $headers = $this->prepare_headers(); // Open the connection, send the request and read the response $this->adapter->connect($uri->getHost(), $uri->getPort(), ($uri->getScheme() == 'https' ? true : false)); $this->last_request = $this->adapter->write($this->method, $uri, $this->config['httpversion'], $headers, $body); $response = $this->adapter->read(); if (! $response) { require_once 'Zend/Http/Client/Exception.php'; throw new Zend_Http_Client_Exception('Unable to read response, or response is empty'); } $response = Zend_Http_Response::fromString($response); if ($this->config['storeresponse']) $this->last_response = $response; // Load cookies into cookie jar if (isset($this->cookiejar)) $this->cookiejar->addCookiesFromResponse($response, $uri); // If we got redirected, look for the Location header if ($response->isRedirect() && ($location = $response->getHeader('location'))) { // Check whether we send the exact same request again, or drop the parameters // and send a GET request if ($response->getStatus() == 303 || ((! $this->config['strictredirects']) && ($response->getStatus() == 302 || $response->getStatus() == 301))) { $this->resetParameters(); $this->setMethod(self::GET); } // If we got a well formed absolute URI if (Zend_Uri_Http::check($location)) { $this->setHeaders('host', null); $this->setUri($location); } else { // Split into path and query and set the query if (strpos($location, '?') !== false) { list($location, $query) = explode('?', $location, 2); } else { $query = ''; } $this->uri->setQuery($query); // Else, if we got just an absolute path, set it if(strpos($location, '/') === 0) { $this->uri->setPath($location); // Else, assume we have a relative path } else { // Get the current path directory, removing any trailing slashes $path = $this->uri->getPath(); $path = rtrim(substr($path, 0, strrpos($path, '/')), "/"); $this->uri->setPath($path . '/' . $location); } } ++$this->redirectCounter; } else { // If we didn't get any location, stop redirecting break; } } while ($this->redirectCounter < $this->config['maxredirects']); return $response; } /** * Prepare the request headers * * @return array */ protected function prepare_headers() { $headers = array(); // Set the host header if (! isset($this->headers['host'])) { $host = $this->uri->getHost(); // If the port is not default, add it if (! (($this->uri->getScheme() == 'http' && $this->uri->getPort() == 80) || ($this->uri->getScheme() == 'https' && $this->uri->getPort() == 443))) { $host .= ':' . $this->uri->getPort(); } $headers[] = "Host: {$host}"; } // Set the connection header if (! isset($this->headers['connection'])) { if (! $this->config['keepalive']) $headers[] = "Connection: close"; } // Set the Accept-encoding header if not set - depending on whether // zlib is available or not. if (! isset($this->headers['accept-encoding'])) { if (function_exists('gzinflate')) { $headers[] = 'Accept-encoding: gzip, deflate'; } else { $headers[] = 'Accept-encoding: identity'; } } // Set the content-type header if ($this->method == self::POST && (! isset($this->headers['content-type']) && isset($this->enctype))) { $headers[] = "Content-type: {$this->enctype}"; } // Set the user agent header if (! isset($this->headers['user-agent']) && isset($this->config['useragent'])) { $headers[] = "User-agent: {$this->config['useragent']}"; } // Set HTTP authentication if needed if (is_array($this->auth)) { $auth = self::encodeAuthHeader($this->auth['user'], $this->auth['password'], $this->auth['type']); $headers[] = "Authorization: {$auth}"; } // Load cookies from cookie jar if (isset($this->cookiejar)) { $cookstr = $this->cookiejar->getMatchingCookies($this->uri, true, Zend_Http_CookieJar::COOKIE_STRING_CONCAT); if ($cookstr) $headers[] = "Cookie: {$cookstr}"; } // Add all other user defined headers foreach ($this->headers as $header) { list($name, $value) = $header; if (is_array($value)) $value = implode(', ', $value); $headers[] = "$name: $value"; } return $headers; } /** * Prepare the request body (for POST and PUT requests) * * @return string */ protected function prepare_body() { // According to RFC2616, a TRACE request should not have a body. if ($this->method == self::TRACE) { return ''; } // If we have raw_post_data set, just use it as the body. if (isset($this->raw_post_data)) { $this->setHeaders('Content-length', strlen($this->raw_post_data)); return $this->raw_post_data; } $body = ''; // If we have files to upload, force enctype to multipart/form-data if (count ($this->files) > 0) $this->setEncType(self::ENC_FORMDATA); // If we have POST parameters or files, encode and add them to the body if (count($this->paramsPost) > 0 || count($this->files) > 0) { switch($this->enctype) { case self::ENC_FORMDATA: // Encode body as multipart/form-data $boundary = '---ZENDHTTPCLIENT-' . md5(microtime()); $this->setHeaders('Content-type', self::ENC_FORMDATA . "; boundary={$boundary}"); // Get POST parameters and encode them $params = $this->_getParametersRecursive($this->paramsPost); foreach ($params as $pp) { $body .= self::encodeFormData($boundary, $pp[0], $pp[1]); } // Encode files foreach ($this->files as $name => $file) { $fhead = array('Content-type' => $file[1]); $body .= self::encodeFormData($boundary, $name, $file[2], $file[0], $fhead); } $body .= "--{$boundary}--\r\n"; break; case self::ENC_URLENCODED: // Encode body as application/x-www-form-urlencoded $this->setHeaders('Content-type', self::ENC_URLENCODED); $body = http_build_query($this->paramsPost, '', '&'); break; default: require_once 'Zend/Http/Client/Exception.php'; throw new Zend_Http_Client_Exception("Cannot handle content type '{$this->enctype}' automatically." . " Please use Zend_Http_Client::setRawData to send this kind of content."); break; } } if ($body) $this->setHeaders('Content-length', strlen($body)); return $body; } /** * Helper method that gets a possibly multi-level parameters array (get or * post) and flattens it. * * The method returns an array of (key, value) pairs (because keys are not * necessarily unique. If one of the parameters in as array, it will also * add a [] suffix to the key. * * @param array $parray The parameters array * @param bool $urlencode Whether to urlencode the name and value * @return array */ protected function _getParametersRecursive($parray, $urlencode = false) { if (! is_array($parray)) return $parray; $parameters = array(); foreach ($parray as $name => $value) { if ($urlencode) $name = urlencode($name); // If $value is an array, iterate over it if (is_array($value)) { $name .= ($urlencode ? '%5B%5D' : '[]'); foreach ($value as $subval) { if ($urlencode) $subval = urlencode($subval); $parameters[] = array($name, $subval); } } else { if ($urlencode) $value = urlencode($value); $parameters[] = array($name, $value); } } return $parameters; } /** * Encode data to a multipart/form-data part suitable for a POST request. * * @param string $boundary * @param string $name * @param mixed $value * @param string $filename * @param array $headers Associative array of optional headers @example ("Content-transfer-encoding" => "binary") * @return string */ public static function encodeFormData($boundary, $name, $value, $filename = null, $headers = array()) { $ret = "--{$boundary}\r\n" . 'Content-disposition: form-data; name="' . $name .'"'; if ($filename) $ret .= '; filename="' . $filename . '"'; $ret .= "\r\n"; foreach ($headers as $hname => $hvalue) { $ret .= "{$hname}: {$hvalue}\r\n"; } $ret .= "\r\n"; $ret .= "{$value}\r\n"; return $ret; } /** * Create a HTTP authentication "Authorization:" header according to the * specified user, password and authentication method. * * @see http://www.faqs.org/rfcs/rfc2617.html * @param string $user * @param string $password * @param string $type * @return string */ public static function encodeAuthHeader($user, $password, $type = self::AUTH_BASIC) { $authHeader = null; switch ($type) { case self::AUTH_BASIC: // In basic authentication, the user name cannot contain ":" if (strpos($user, ':') !== false) { require_once 'Zend/Http/Client/Exception.php'; throw new Zend_Http_Client_Exception("The user name cannot contain ':' in 'Basic' HTTP authentication"); } $authHeader = 'Basic ' . base64_encode($user . ':' . $password); break; //case self::AUTH_DIGEST: /** * @todo Implement digest authentication */ // break; default: require_once 'Zend/Http/Client/Exception.php'; throw new Zend_Http_Client_Exception("Not a supported HTTP authentication type: '$type'"); } return $authHeader; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -