/** * @param string $type NORMAL, BROKEN, TIMEOUT */ public function finish($type = 'NORMAL') { $this->finished = true; if ($type === 'BROKEN') { $this->res->error = HttpConn::getLastError(); } else { if ($type !== 'NORMAL') { $this->res->error = ucfirst(strtolower($type)); } } // gzip decode $encoding = $this->res->getHeader('content-encoding'); if ($encoding !== null && strstr($encoding, 'gzip')) { $this->res->body = HttpClient::gzdecode($this->res->body); } // parser $this->res->timeCost = microtime(true) - $this->timeBegin; $this->cli->runParser($this->res, $this->req, $this->key); // conn if ($this->conn) { // close conn $close = $this->res->getHeader('connection'); $this->conn->close($type !== 'NORMAL' || !strcasecmp($close, 'close')); $this->conn = null; // redirect if (($this->res->status === 301 || $this->res->status === 302) && $this->res->numRedirected < $this->req->getMaxRedirect() && ($location = $this->res->getHeader('location')) !== null) { HttpClient::debug('redirect to \'', $location, '\''); $req = $this->req; if (!preg_match('/^https?:\\/\\//i', $location)) { $pa = $req->getUrlParams(); $url = $pa['scheme'] . '://' . $pa['host']; if (isset($pa['port'])) { $url .= ':' . $pa['port']; } if (substr($location, 0, 1) == '/') { $url .= $location; } else { $url .= substr($pa['path'], 0, strrpos($pa['path'], '/') + 1) . $location; } $location = $url; /// FIXME: strip relative '../../' } // change new url $prevUrl = $req->getUrl(); $req->setUrl($location); if (!$req->getHeader('referer')) { $req->setHeader('referer', $prevUrl); } if ($req->getMethod() !== 'HEAD') { $req->setMethod('GET'); } $req->clearCookie(); $req->setHeader('host', null); $req->setHeader('x-server-ip', null); // reset response $this->res->numRedirected++; $this->finished = $this->headerOK = false; return $this->res->reset(); } } HttpClient::debug('finished', $this->res->hasError() ? ' (' . $this->res->error . ')' : ''); $this->req = $this->cli = null; }