Something went wrong. Try again.
@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
Something went wrong. Try again.
PHP
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178<?php
/** * TODO: Should be final but isn't because of AphrontReloadResponse. */class AphrontRedirectResponse extends AphrontResponse {
private $uri; private $stackWhenCreated; private $isExternal; private $closeDialogBeforeRedirect;
public function setIsExternal($external) { $this->isExternal = $external; return $this; }
public function __construct() { if ($this->shouldStopForDebugging()) { // If we're going to stop, capture the stack so we can print it out. $this->stackWhenCreated = id(new Exception())->getTrace(); } }
public function setURI($uri) { $this->uri = $uri; return $this; }
public function getURI() { // NOTE: When we convert a RedirectResponse into an AjaxResponse, we pull // the URI through this method. Make sure it passes checks before we // hand it over to callers. return self::getURIForRedirect($this->uri, $this->isExternal); }
public function shouldStopForDebugging() { return PhabricatorEnv::getEnvConfig('debug.stop-on-redirect'); }
public function setCloseDialogBeforeRedirect($close) { $this->closeDialogBeforeRedirect = $close; return $this; }
public function getCloseDialogBeforeRedirect() { return $this->closeDialogBeforeRedirect; }
public function getHeaders() { $headers = array(); if (!$this->shouldStopForDebugging()) { $uri = self::getURIForRedirect($this->uri, $this->isExternal); $headers[] = array('Location', $uri); } $headers = array_merge(parent::getHeaders(), $headers); return $headers; }
public function buildResponseString() { if ($this->shouldStopForDebugging()) { $request = $this->getRequest(); $viewer = $request->getUser();
$view = new PhabricatorStandardPageView(); $view->setRequest($this->getRequest()); $view->setApplicationName(pht('Debug')); $view->setTitle(pht('Stopped on Redirect'));
$dialog = new AphrontDialogView(); $dialog->setUser($viewer); $dialog->setTitle(pht('Stopped on Redirect'));
$dialog->appendParagraph( pht( 'You were stopped here because %s is set in your configuration.', phutil_tag('tt', array(), 'debug.stop-on-redirect')));
$dialog->appendParagraph( pht( 'You are being redirected to: %s', phutil_tag('tt', array(), $this->getURI())));
$dialog->addCancelButton($this->getURI(), pht('Continue'));
$dialog->appendChild(phutil_tag('br'));
$dialog->appendChild( id(new AphrontStackTraceView()) ->setUser($viewer) ->setTrace($this->stackWhenCreated));
$dialog->setIsStandalone(true); $dialog->setWidth(AphrontDialogView::WIDTH_FULL);
$box = id(new PHUIBoxView()) ->addMargin(PHUI::MARGIN_LARGE) ->appendChild($dialog);
$view->appendChild($box);
return $view->render(); }
return ''; }
/** * Format a URI for use in a "Location:" header. * * Verifies that a URI redirects to the expected type of resource (local or * remote) and formats it for use in a "Location:" header. * * The HTTP spec says "Location:" headers must use absolute URIs. Although * browsers work with relative URIs, we return absolute URIs to avoid * ambiguity. For example, Chrome interprets "Location: /\evil.com" to mean * "perform a protocol-relative redirect to evil.com". * * @param string $uri URI to redirect to. * @param bool $is_external True if this URI identifies a remote * resource. * @return string URI for use in a "Location:" header. */ public static function getURIForRedirect($uri, $is_external) { $uri_object = new PhutilURI($uri); if ($is_external) { // If this is a remote resource it must have a domain set. This // would also be caught below, but testing for it explicitly first allows // us to raise a better error message. if (!strlen($uri_object->getDomain())) { throw new Exception( pht( 'Refusing to redirect to external URI "%s". This URI '. 'is not fully qualified, and is missing a domain name. To '. 'redirect to a local resource, remove the external flag.', (string)$uri)); }
// Check that it's a valid remote resource. if (!PhabricatorEnv::isValidURIForLink($uri)) { throw new Exception( pht( 'Refusing to redirect to external URI "%s". This URI '. 'is not a valid remote web resource.', (string)$uri)); } } else { // If this is a local resource, it must not have a domain set. This allows // us to raise a better error message than the check below can. if (strlen($uri_object->getDomain())) { throw new Exception( pht( 'Refusing to redirect to local resource "%s". The URI has a '. 'domain, but the redirect is not marked external. Mark '. 'redirects as external to allow redirection off the local '. 'domain.', (string)$uri)); }
// If this is a local resource, it must be a valid local resource. if (!PhabricatorEnv::isValidLocalURIForLink($uri)) { throw new Exception( pht( 'Refusing to redirect to local resource "%s". This URI is not '. 'formatted in a recognizable way.', (string)$uri)); }
// Fully qualify the result URI. $uri = PhabricatorEnv::getURI((string)$uri); }
return (string)$uri; }
}