mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-27 01:02:42 +01:00
Allow custom Sites to have custom 404 controllers
Summary: Currently, custom Sites must match `.*` or similar to handle 404's, since the fallback is always generic. This locks them out of the "redirect to canonicalize to `path/` code", so they currently have a choice between a custom 404 page or automatic correction of `/`. Instead, allow the 404 controller to be constructed explicitly. Sites can now customize 404 by implementing this method and not matching everything. (Sites can still match everything with a catchall rule if they don't want this behavior for some reason, so this should be strictly more powerful than the old behavior.) See next diff for CORGI. Test Plan: - Visited real 404 (like "/asdfafewfq"), missing-slash-404 (like "/maniphest") and real page (like "/maniphest/") URIs on blog, main, and CORGI sites. - Got 404 behavior, redirects, and real pages, respectively. Reviewers: chad Reviewed By: chad Differential Revision: https://secure.phabricator.com/D16966
This commit is contained in:
parent
29a3cd5121
commit
9730f5a34f
5 changed files with 25 additions and 5 deletions
|
@ -545,6 +545,13 @@ final class AphrontRequest extends Phobject {
|
||||||
return id(new PhutilURI($path))->setQueryParams($get);
|
return id(new PhutilURI($path))->setQueryParams($get);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getAbsoluteRequestURI() {
|
||||||
|
$uri = $this->getRequestURI();
|
||||||
|
$uri->setDomain($this->getHost());
|
||||||
|
$uri->setProtocol($this->isHTTPS() ? 'https' : 'http');
|
||||||
|
return $uri;
|
||||||
|
}
|
||||||
|
|
||||||
public function isDialogFormPost() {
|
public function isDialogFormPost() {
|
||||||
return $this->isFormPost() && $this->getStr('__dialog__');
|
return $this->isFormPost() && $this->getStr('__dialog__');
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,19 +409,25 @@ abstract class AphrontApplicationConfiguration extends Phobject {
|
||||||
if (!preg_match('@/$@', $path) && $request->isHTTPGet()) {
|
if (!preg_match('@/$@', $path) && $request->isHTTPGet()) {
|
||||||
$result = $this->routePath($maps, $path.'/');
|
$result = $this->routePath($maps, $path.'/');
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$slash_uri = $request->getRequestURI()->setPath($path.'/');
|
$target_uri = $request->getAbsoluteRequestURI();
|
||||||
|
|
||||||
// We need to restore URI encoding because the webserver has
|
// We need to restore URI encoding because the webserver has
|
||||||
// interpreted it. For example, this allows us to redirect a path
|
// interpreted it. For example, this allows us to redirect a path
|
||||||
// like `/tag/aa%20bb` to `/tag/aa%20bb/`, which may eventually be
|
// like `/tag/aa%20bb` to `/tag/aa%20bb/`, which may eventually be
|
||||||
// resolved meaningfully by an application.
|
// resolved meaningfully by an application.
|
||||||
$slash_uri = phutil_escape_uri($slash_uri);
|
$target_path = phutil_escape_uri($path.'/');
|
||||||
|
$target_uri->setPath($target_path);
|
||||||
|
$target_uri = (string)$target_uri;
|
||||||
|
|
||||||
$external = strlen($request->getRequestURI()->getDomain());
|
return $this->buildRedirectController($target_uri, true);
|
||||||
return $this->buildRedirectController($slash_uri, $external);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$result = $site->new404Controller($request);
|
||||||
|
if ($result) {
|
||||||
|
return array($result, array());
|
||||||
|
}
|
||||||
|
|
||||||
return $this->build404Controller();
|
return $this->build404Controller();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,10 @@ abstract class AphrontSite extends Phobject {
|
||||||
abstract public function newSiteForRequest(AphrontRequest $request);
|
abstract public function newSiteForRequest(AphrontRequest $request);
|
||||||
abstract public function getRoutingMaps();
|
abstract public function getRoutingMaps();
|
||||||
|
|
||||||
|
public function new404Controller(AphrontRequest $request) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
protected function isHostMatch($host, array $uris) {
|
protected function isHostMatch($host, array $uris) {
|
||||||
foreach ($uris as $uri) {
|
foreach ($uris as $uri) {
|
||||||
if (!strlen($uri)) {
|
if (!strlen($uri)) {
|
||||||
|
|
|
@ -92,7 +92,6 @@ final class PhabricatorPhameApplication extends PhabricatorApplication {
|
||||||
'/' => array(
|
'/' => array(
|
||||||
'' => 'PhameBlogViewController',
|
'' => 'PhameBlogViewController',
|
||||||
'post/(?P<id>\d+)/(?:(?P<slug>[^/]+)/)?' => 'PhamePostViewController',
|
'post/(?P<id>\d+)/(?:(?P<slug>[^/]+)/)?' => 'PhamePostViewController',
|
||||||
'.*' => 'PhameBlog404Controller',
|
|
||||||
),
|
),
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -60,6 +60,10 @@ final class PhameBlogSite extends PhameSite {
|
||||||
return id(new PhameBlogSite())->setBlog($blog);
|
return id(new PhameBlogSite())->setBlog($blog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function new404Controller(AphrontRequest $request) {
|
||||||
|
return new PhameBlog404Controller();
|
||||||
|
}
|
||||||
|
|
||||||
public function getRoutingMaps() {
|
public function getRoutingMaps() {
|
||||||
$app = PhabricatorApplication::getByClass('PhabricatorPhameApplication');
|
$app = PhabricatorApplication::getByClass('PhabricatorPhameApplication');
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue