/** * Return array contains the response of the given URL. * array[code] => HTTP status code * array[headers] => HTTP headers * array[headers] => Entity body * Throw exception if error. * * @param string $url * @param array $headers * @param array $post * @return array */ private function getHttpResponse($url, $headers = array(), $post = array()) { $url = str_replace('&', '&', trim($url)); $req = new HTTP_Request($url, array('allowRedirects' => true, 'maxRedirects' => 5)); /* * @see HTTP_Request_Listener_Extended */ $listener = new HTTP_Request_Listener_Extended(); $req->attach($listener); if (!isset($headers['user-agent'])) { $headers['user-agent'] = $this->httpUserAgent; } foreach ($headers as $key => $value) { if (!empty($value)) { $req->addHeader($key, $value); } } if (!empty($post)) { $req->setMethod('POST'); foreach ($post as $key => $value) { $req->addPostData($key, $value); } } $result = $req->sendRequest(); $is_error = false; if (PEAR::isError($result)) { $is_error = true; $error_message = $result->getMessage(); /* * $error_message could be empty if the error was raised * when fsockopen() returns false in Net_Socket::connect() */ if (empty($error_message)) { $error_message = "Failed connecting to the server."; /* * HTTP_Request raises 'Malformed response' error * if request path is empty (e.g. http://www.example.com). * This bug still exists in its automatic redirection mechanism * in CVS rev. 1.55 (latest as of May 18, 2007). */ } elseif ($error_message == 'Malformed response.') { $url = $req->getURL(null); if (false !== ($urls = @parse_url($url)) and !isset($urls['path'])) { $req->setURL($url); $result = $req->sendRequest(); if (PEAR::isError($result)) { $error_message = $result->getMessage(); if (empty($error_message)) { $error_message = "Failed connecting to the server."; } } else { $is_error = false; } } } } if ($is_error) { throw new Exception($error_message); } return array('url' => $req->getUrl(null), 'code' => $req->getResponseCode(), 'headers' => $req->getResponseHeader(), 'body' => $req->getResponseBody()); }