public function setURI($uri) { $parts = parse_url($uri); if (!$parts) { throw new Exception("Could not parse URI '{$uri}'."); } if (empty($parts['scheme']) || $parts['scheme'] !== 'http') { throw new Exception("URI '{$uri}' must be fully qualified with 'http://' scheme."); } if (!isset($parts['host'])) { throw new Exception("URI '{$uri}' must be fully qualified and include host name."); } $this->host = $parts['host']; if (!empty($parts['port'])) { $this->port = $parts['port']; } if (isset($parts['user']) || isset($parts['pass'])) { throw new Exception("HTTP Basic Auth is not supported by HTTPFuture."); } if (isset($parts['path'])) { $this->fullRequestPath = $parts['path']; } else { $this->fullRequestPath = '/'; } if (isset($parts['query'])) { $this->fullRequestPath .= '?' . $parts['query']; } return parent::setURI($uri); }
public function __construct($status_code, $body, array $headers, $expect = null) { // NOTE: Avoiding PhutilUTF8StringTruncator here because this isn't lazy // and responses may be large. if (strlen($body) > 512) { $excerpt = substr($body, 0, 512) . '...'; } else { $excerpt = $body; } $content_type = BaseHTTPFuture::getHeader($headers, 'Content-Type'); $match = null; if (preg_match('/;\\s*charset=([^;]+)/', $content_type, $match)) { $encoding = trim($match[1], "\"'"); try { $excerpt = phutil_utf8_convert($excerpt, 'UTF-8', $encoding); } catch (Exception $ex) { } } $this->excerpt = phutil_utf8ize($excerpt); $this->expect = $expect; parent::__construct($status_code); }
protected function logHTTPResponse(HarbormasterBuild $build, HarbormasterBuildTarget $build_target, BaseHTTPFuture $future, $label) { list($status, $body, $headers) = $future->resolve(); $header_lines = array(); // TODO: We don't currently preserve the entire "HTTP" response header, but // should. Once we do, reproduce it here faithfully. $status_code = $status->getStatusCode(); $header_lines[] = "HTTP {$status_code}"; foreach ($headers as $header) { list($head, $tail) = $header; $header_lines[] = "{$head}: {$tail}"; } $header_lines = implode("\n", $header_lines); $build_target->newLog($label, 'http.head')->append($header_lines); $build_target->newLog($label, 'http.body')->append($body); }
private function verifyRemotePermissions($viewer, $revision, $repository) { $github_user = $this->account->getUsername(); $github_repo = $this->findGitHubRepo($repository); $uri = urisprintf('https://api.github.com/repos/%s/collaborators/%s', $github_repo, $github_user); $uri = new PhutilURI($uri); $uri->setQueryParam('access_token', $this->getAccessToken()); list($status, $body, $headers) = id(new HTTPSFuture($uri))->resolve(); // Likely status codes: // 204 No Content: Has permissions. Token might be too weak. // 404 Not Found: Not a collaborator. // 401 Unauthorized: Token is bad/revoked. $no_permission = $status->getStatusCode() == 404; if ($no_permission) { throw new Exception(pht("You don't have permission to push to this repository. " . "Push permissions for this repository are managed on GitHub.")); } $scopes = BaseHTTPFuture::getHeader($headers, 'X-OAuth-Scopes'); if (strpos($scopes, 'public_repo') === false) { $provider_key = $this->provider->getProviderKey(); $refresh_token_uri = new PhutilURI("/auth/refresh/{$provider_key}/"); $refresh_token_uri->setQueryParam('scope', 'public_repo'); return id(new AphrontDialogView())->setUser($viewer)->setTitle(pht('Stronger token needed'))->appendChild(pht('In order to complete this action, you need a ' . 'stronger GitHub token.'))->setSubmitURI($refresh_token_uri)->addCancelButton('/D' . $revision->getId())->setDisableWorkflowOnSubmit(true)->addSubmitButton(pht('Refresh Account Link')); } }