[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * TODO: Should be final but isn't because of AphrontReloadResponse. 5 */ 6 class AphrontRedirectResponse extends AphrontResponse { 7 8 private $uri; 9 private $stackWhenCreated; 10 private $isExternal; 11 12 public function setIsExternal($external) { 13 $this->isExternal = $external; 14 return $this; 15 } 16 17 public function __construct() { 18 if ($this->shouldStopForDebugging()) { 19 // If we're going to stop, capture the stack so we can print it out. 20 $this->stackWhenCreated = id(new Exception())->getTrace(); 21 } 22 } 23 24 public function setURI($uri) { 25 $this->uri = $uri; 26 return $this; 27 } 28 29 public function getURI() { 30 // NOTE: When we convert a RedirectResponse into an AjaxResponse, we pull 31 // the URI through this method. Make sure it passes checks before we 32 // hand it over to callers. 33 return self::getURIForRedirect($this->uri, $this->isExternal); 34 } 35 36 public function shouldStopForDebugging() { 37 return PhabricatorEnv::getEnvConfig('debug.stop-on-redirect'); 38 } 39 40 public function getHeaders() { 41 $headers = array(); 42 if (!$this->shouldStopForDebugging()) { 43 $uri = self::getURIForRedirect($this->uri, $this->isExternal); 44 $headers[] = array('Location', $uri); 45 } 46 $headers = array_merge(parent::getHeaders(), $headers); 47 return $headers; 48 } 49 50 public function buildResponseString() { 51 if ($this->shouldStopForDebugging()) { 52 $request = $this->getRequest(); 53 $viewer = $request->getUser(); 54 55 $view = new PhabricatorStandardPageView(); 56 $view->setRequest($this->getRequest()); 57 $view->setApplicationName(pht('Debug')); 58 $view->setTitle(pht('Stopped on Redirect')); 59 60 $dialog = new AphrontDialogView(); 61 $dialog->setUser($viewer); 62 $dialog->setTitle(pht('Stopped on Redirect')); 63 64 $dialog->appendParagraph( 65 pht( 66 'You were stopped here because %s is set in your configuration.', 67 phutil_tag('tt', array(), 'debug.stop-on-redirect'))); 68 69 $dialog->appendParagraph( 70 pht( 71 'You are being redirected to: %s', 72 phutil_tag('tt', array(), $this->getURI()))); 73 74 $dialog->addCancelButton($this->getURI(), pht('Continue')); 75 76 $dialog->appendChild(phutil_tag('br')); 77 78 $dialog->appendChild( 79 id(new AphrontStackTraceView()) 80 ->setUser($viewer) 81 ->setTrace($this->stackWhenCreated)); 82 83 $dialog->setIsStandalone(true); 84 $dialog->setWidth(AphrontDialogView::WIDTH_FULL); 85 86 $box = id(new PHUIBoxView()) 87 ->addMargin(PHUI::MARGIN_LARGE) 88 ->appendChild($dialog); 89 90 $view->appendChild($box); 91 92 return $view->render(); 93 } 94 95 return ''; 96 } 97 98 99 /** 100 * Format a URI for use in a "Location:" header. 101 * 102 * Verifies that a URI redirects to the expected type of resource (local or 103 * remote) and formats it for use in a "Location:" header. 104 * 105 * The HTTP spec says "Location:" headers must use absolute URIs. Although 106 * browsers work with relative URIs, we return absolute URIs to avoid 107 * ambiguity. For example, Chrome interprets "Location: /\evil.com" to mean 108 * "perform a protocol-relative redirect to evil.com". 109 * 110 * @param string URI to redirect to. 111 * @param bool True if this URI identifies a remote resource. 112 * @return string URI for use in a "Location:" header. 113 */ 114 public static function getURIForRedirect($uri, $is_external) { 115 $uri_object = new PhutilURI($uri); 116 if ($is_external) { 117 // If this is a remote resource it must have a domain set. This 118 // would also be caught below, but testing for it explicitly first allows 119 // us to raise a better error message. 120 if (!strlen($uri_object->getDomain())) { 121 throw new Exception( 122 pht( 123 'Refusing to redirect to external URI "%s". This URI '. 124 'is not fully qualified, and is missing a domain name. To '. 125 'redirect to a local resource, remove the external flag.', 126 (string)$uri)); 127 } 128 129 // Check that it's a valid remote resource. 130 if (!PhabricatorEnv::isValidRemoteWebResource($uri)) { 131 throw new Exception( 132 pht( 133 'Refusing to redirect to external URI "%s". This URI '. 134 'is not a valid remote web resource.', 135 (string)$uri)); 136 } 137 } else { 138 // If this is a local resource, it must not have a domain set. This allows 139 // us to raise a better error message than the check below can. 140 if (strlen($uri_object->getDomain())) { 141 throw new Exception( 142 pht( 143 'Refusing to redirect to local resource "%s". The URI has a '. 144 'domain, but the redirect is not marked external. Mark '. 145 'redirects as external to allow redirection off the local '. 146 'domain.', 147 (string)$uri)); 148 } 149 150 // If this is a local resource, it must be a valid local resource. 151 if (!PhabricatorEnv::isValidLocalWebResource($uri)) { 152 throw new Exception( 153 pht( 154 'Refusing to redirect to local resource "%s". This URI is not '. 155 'formatted in a recognizable way.', 156 (string)$uri)); 157 } 158 159 // Fully qualify the result URI. 160 $uri = PhabricatorEnv::getURI((string)$uri); 161 } 162 163 return (string)$uri; 164 } 165 166 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |