/** * Parse a raw HTTP response into a <status, body, headers> tuple. * * @param string Raw HTTP response. * @return tuple Valid resolution tuple. * @task internal */ protected function parseRawHTTPResponse($raw_response) { $rex_base = "@^(?P<head>.*?)\r?\n\r?\n(?P<body>.*)\$@s"; $rex_head = "@^HTTP/\\S+ (?P<code>\\d+) (?P<status>.*?)" . "(?:\r?\n(?P<headers>.*))?\$@s"; // We need to parse one or more header blocks in case we got any // "HTTP/1.X 100 Continue" nonsense back as part of the response. This // happens with HTTPS requests, at the least. $response = $raw_response; while (true) { $matches = null; if (!preg_match($rex_base, $response, $matches)) { return $this->buildMalformedResult($raw_response); } $head = $matches['head']; $body = $matches['body']; if (!preg_match($rex_head, $head, $matches)) { return $this->buildMalformedResult($raw_response); } $response_code = (int) $matches['code']; $response_status = strtolower($matches['status']); if ($response_code == 100) { // This is HTTP/1.X 100 Continue, so this whole chunk is moot. $response = $body; } else { if ($response_code == 200 && $response_status == 'connection established') { // When tunneling through an HTTPS proxy, we get an initial header // block like "HTTP/1.X 200 Connection established", then newlines, // then the normal response. Drop this chunk. $response = $body; } else { $headers = $this->parseHeaders(Utils::idx($matches, 'headers')); break; } } } $status = new Status_HTTPFutureResponseStatusHTTP($response_code, $body, $headers); return array($status, $body, $headers); }
protected function getErrorCodeDescription($code) { $map = array(self::ERROR_TIMEOUT => 'The request took too long to complete.', self::ERROR_CONNECTION_ABORTED => 'The remote host closed the connection before the request completed.', self::ERROR_CONNECTION_REFUSED => 'The remote host refused the connection. This usually means the ' . 'host is not running an HTTP server, or the network is blocking ' . 'connections from this machine. Verify you can connect to the ' . 'remote host from this host.', self::ERROR_CONNECTION_FAILED => 'Connection could not be initiated. This usually indicates a DNS ' . 'problem: verify the domain name is correct, that you can ' . 'perform a DNS lookup for it from this machine. (Did you add the ' . 'domain to `/etc/hosts` on some other machine, but not this one?) ' . 'This might also indicate that you specified the wrong port.'); return Utils::idx($map, $code); }
/** * Close and free resources if necessary. * * @return void * @task internal */ private function closeProcess() { foreach ($this->pipes as $pipe) { if (isset($pipe)) { @fclose($pipe); } } $this->pipes = array(null, null, null); if ($this->proc) { @proc_close($this->proc); $this->proc = null; } $this->stdin = null; if ($this->profilerCallID !== null) { $profiler = ServiceProfiler\PhutilServiceProfiler::getInstance(); $profiler->endServiceCall($this->profilerCallID, array('err' => $this->result ? Utils\Utils::idx($this->result, 0) : null)); $this->profilerCallID = null; } }
protected function getErrorCodeDescription($code) { static $map = array(404 => 'Not Found', 500 => 'Internal Server Error'); return \Hazbo\Component\Utils\Utils::idx($map, $code) . "\n" . $this->excerpt . "\n"; }