Changeset View
Changeset View
Standalone View
Standalone View
src/aphront/configuration/AphrontApplicationConfiguration.php
Show First 20 Lines • Show All 344 Lines • ▼ Show 20 Lines | if ($cluster_addresses) { | ||||
'Phabricator is configured in cluster mode and the address '. | 'Phabricator is configured in cluster mode and the address '. | ||||
'this request was received on ("%s") is not whitelisted as '. | 'this request was received on ("%s") is not whitelisted as '. | ||||
'a cluster address.', | 'a cluster address.', | ||||
$server_addr)); | $server_addr)); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (PhabricatorEnv::getEnvConfig('security.require-https')) { | $site = $this->buildSiteForRequest($request); | ||||
if ($site->shouldRequireHTTPS()) { | |||||
if (!$request->isHTTPS()) { | if (!$request->isHTTPS()) { | ||||
$https_uri = $request->getRequestURI(); | $https_uri = $request->getRequestURI(); | ||||
$https_uri->setDomain($request->getHost()); | $https_uri->setDomain($request->getHost()); | ||||
$https_uri->setProtocol('https'); | $https_uri->setProtocol('https'); | ||||
// In this scenario, we'll be redirecting to HTTPS using an absolute | // In this scenario, we'll be redirecting to HTTPS using an absolute | ||||
// URI, so we need to permit an external redirect. | // URI, so we need to permit an external redirect. | ||||
return $this->buildRedirectController($https_uri, true); | return $this->buildRedirectController($https_uri, true); | ||||
} | } | ||||
} | } | ||||
$path = $request->getPath(); | // TODO: Really, the Site should get more control here and be able to | ||||
$host = $request->getHost(); | // do its own routing logic if it wants, but we don't need that for now. | ||||
$base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri'); | $path = $site->getPathForRouting($request); | ||||
$prod_uri = PhabricatorEnv::getEnvConfig('phabricator.production-uri'); | |||||
$file_uri = PhabricatorEnv::getEnvConfig( | |||||
'security.alternate-file-domain'); | |||||
$allowed_uris = PhabricatorEnv::getEnvConfig('phabricator.allowed-uris'); | |||||
$uris = array_merge( | |||||
array( | |||||
$base_uri, | |||||
$prod_uri, | |||||
), | |||||
$allowed_uris); | |||||
$cdn_routes = array( | |||||
'/res/', | |||||
'/file/data/', | |||||
'/file/xform/', | |||||
'/phame/r/', | |||||
); | |||||
$host_match = false; | |||||
foreach ($uris as $uri) { | |||||
if ($host === id(new PhutilURI($uri))->getDomain()) { | |||||
$host_match = true; | |||||
break; | |||||
} | |||||
} | |||||
if (!$host_match) { | |||||
if ($host === id(new PhutilURI($file_uri))->getDomain()) { | |||||
foreach ($cdn_routes as $route) { | |||||
if (strncmp($path, $route, strlen($route)) == 0) { | |||||
$host_match = true; | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
// NOTE: If the base URI isn't defined yet, don't activate alternate | |||||
// domains. | |||||
if ($base_uri && !$host_match) { | |||||
try { | |||||
$blog = id(new PhameBlogQuery()) | |||||
->setViewer(new PhabricatorUser()) | |||||
->withDomain($host) | |||||
->executeOne(); | |||||
} catch (PhabricatorPolicyException $ex) { | |||||
throw new Exception( | |||||
pht( | |||||
'This blog is not visible to logged out users, so it can not be '. | |||||
'visited from a custom domain.')); | |||||
} | |||||
if (!$blog) { | |||||
if ($prod_uri && $prod_uri != $base_uri) { | |||||
$prod_str = pht('%s or %s', $base_uri, $prod_uri); | |||||
} else { | |||||
$prod_str = $base_uri; | |||||
} | |||||
throw new Exception( | |||||
pht( | |||||
'Specified domain %s is not configured for Phabricator '. | |||||
'requests. Please use %s to visit this instance.', | |||||
$host, | |||||
$prod_str)); | |||||
} | |||||
// TODO: Make this more flexible and modular so any application can | |||||
// do crazy stuff here if it wants. | |||||
$path = '/phame/live/'.$blog->getID().'/'.$path; | |||||
} | |||||
list($controller, $uri_data) = $this->buildControllerForPath($path); | list($controller, $uri_data) = $this->buildControllerForPath($path); | ||||
if (!$controller) { | if (!$controller) { | ||||
if (!preg_match('@/$@', $path)) { | if (!preg_match('@/$@', $path)) { | ||||
// If we failed to match anything but don't have a trailing slash, try | // If we failed to match anything but don't have a trailing slash, try | ||||
// to add a trailing slash and issue a redirect if that resolves. | // to add a trailing slash and issue a redirect if that resolves. | ||||
list($controller, $uri_data) = $this->buildControllerForPath($path.'/'); | list($controller, $uri_data) = $this->buildControllerForPath($path.'/'); | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | final public function buildControllerForPath($path) { | ||||
$controller = newv($controller_class, array()); | $controller = newv($controller_class, array()); | ||||
if ($current_application) { | if ($current_application) { | ||||
$controller->setCurrentApplication($current_application); | $controller->setCurrentApplication($current_application); | ||||
} | } | ||||
return array($controller, $uri_data); | return array($controller, $uri_data); | ||||
} | } | ||||
private function buildSiteForRequest(AphrontRequest $request) { | |||||
$sites = PhabricatorSite::getAllSites(); | |||||
$site = null; | |||||
foreach ($sites as $candidate) { | |||||
$site = $candidate->newSiteForRequest($request); | |||||
if ($site) { | |||||
break; | |||||
} | |||||
} | |||||
if (!$site) { | |||||
$path = $request->getPath(); | |||||
$host = $request->getHost(); | |||||
throw new Exception( | |||||
pht( | |||||
'This request asked for "%s" on host "%s", but no site is '. | |||||
'configured which can serve this request.', | |||||
$path, | |||||
$host)); | |||||
} | |||||
return $site; | |||||
} | |||||
} | } |