Skip to content

Commit

Permalink
fix(setup-checks): Ensure URL with webroot works
Browse files Browse the repository at this point in the history
We basically mock the way `URLGenerator::getAbsoluteURL` works,
so we must make sure that the URL might already contain the webroot.
Because `baseURL` and `cliURL` also contain the webroot we need to remove
the webroot from the URL first.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
  • Loading branch information
susnux committed Sep 11, 2024
1 parent 897c341 commit 6d21907
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 10 deletions.
23 changes: 17 additions & 6 deletions apps/settings/lib/SetupChecks/CheckServerResponseTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,15 @@ protected function serverConfigHelp(): string {
* @return string[] List of possible absolute URLs
*/
protected function getTestUrls(string $url, bool $removeWebroot): array {
if (!str_starts_with($url, '/')) {
$url = '/' . $url;
}
// Similar to `getAbsoluteURL` of URLGenerator:
// The Nextcloud web root could already be prepended.
if (\OC::$WEBROOT !== '' && str_starts_with($url, \OC::$WEBROOT)) {
$url = substr($url, -strlen(\OC::$WEBROOT));
}

$testUrls = [];

$webroot = rtrim($this->urlGenerator->getWebroot(), '/');
Expand Down Expand Up @@ -76,8 +85,8 @@ protected function getTestUrls(string $url, bool $removeWebroot): array {
/* Ignore domains with a wildcard */
continue;
}
$hosts[] = 'https://' . $host . $url;
$hosts[] = 'http://' . $host . $url;
$testUrls[] = $this->normalizeUrl("https://$host/$webroot", $webroot, $removeWebroot) . $url;
$testUrls[] = $this->normalizeUrl("http://$host/$webroot", $webroot, $removeWebroot) . $url;
}

return $testUrls;
Expand All @@ -97,7 +106,8 @@ protected function normalizeUrl(string $url, string $webroot, bool $removeWebroo
/**
* Run a HTTP request to check header
* @param string $method The HTTP method to use
* @param string $url The relative URL to check
* @param string $url The relative URL to check (e.g. output of IURLGenerator)
* @param bool $removeWebroot Remove the webroot from the URL (handle URL as relative to domain root)
* @param array{ignoreSSL?: bool, httpErrors?: bool, options?: array} $options Additional options, like
* [
* // Ignore invalid SSL certificates (e.g. self signed)
Expand Down Expand Up @@ -126,13 +136,14 @@ protected function runRequest(string $method, string $url, array $options = [],

/**
* Run a HEAD request to check header
* @param string $url The relative URL to check
* @param string $url The relative URL to check (e.g. output of IURLGenerator)
* @param bool $ignoreSSL Ignore SSL certificates
* @param bool $httpErrors Ignore requests with HTTP errors (will not yield if request has a 4xx or 5xx response)
* @param bool $removeWebroot Remove the webroot from the URL (handle URL as relative to domain root)
* @return Generator<int, IResponse>
*/
protected function runHEAD(string $url, bool $ignoreSSL = true, bool $httpErrors = true): Generator {
return $this->runRequest('HEAD', $url, ['ignoreSSL' => $ignoreSSL, 'httpErrors' => $httpErrors]);
protected function runHEAD(string $url, bool $ignoreSSL = true, bool $httpErrors = true, bool $removeWebroot = false): Generator {
return $this->runRequest('HEAD', $url, ['ignoreSSL' => $ignoreSSL, 'httpErrors' => $httpErrors], $removeWebroot);
}

protected function getRequestOptions(bool $ignoreSSL, bool $httpErrors): array {
Expand Down
3 changes: 1 addition & 2 deletions apps/settings/lib/SetupChecks/DataDirectoryProtected.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ public function getName(): string {

public function run(): SetupResult {
$datadir = str_replace(\OC::$SERVERROOT . '/', '', $this->config->getSystemValue('datadirectory', ''));

$dataUrl = $this->urlGenerator->getWebroot() . '/' . $datadir . '/.ncdata';
$dataUrl = '/' . $datadir . '/.ncdata';

Check notice

Code scanning / Psalm

PossiblyInvalidOperand Note

Cannot concatenate with a array<array-key, string>|string

$noResponse = true;
foreach ($this->runRequest('GET', $dataUrl, [ 'httpErrors' => false ]) as $response) {
Expand Down
3 changes: 2 additions & 1 deletion apps/settings/lib/SetupChecks/WellKnownUrls.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ public function run(): SetupResult {
['propfind', '/.well-known/carddav', [207], false],
];

$requestOptions = ['httpErrors' => false, 'options' => ['allow_redirects' => ['track_redirects' => true]]];
foreach ($urls as [$verb,$url,$validStatuses,$checkCustomHeader]) {
$works = null;
foreach ($this->runRequest($verb, $url, ['httpErrors' => false, 'options' => ['allow_redirects' => ['track_redirects' => true]]], removeWebroot: true) as $response) {
foreach ($this->runRequest($verb, $url, $requestOptions, removeWebroot: true) as $response) {
// Check that the response status matches
$works = in_array($response->getStatusCode(), $validStatuses);
// and (if needed) the custom Nextcloud header is set
Expand Down
2 changes: 1 addition & 1 deletion lib/private/URLGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ public function getAbsoluteURL(string $url): string {
if (\OC::$CLI && !\defined('PHPUNIT_RUN')) {
return rtrim($this->config->getSystemValueString('overwrite.cli.url'), '/') . '/' . ltrim($url, '/');
}
// The ownCloud web root can already be prepended.
// The Nextcloud web root could already be prepended.
if (\OC::$WEBROOT !== '' && str_starts_with($url, \OC::$WEBROOT)) {
$url = substr($url, \strlen(\OC::$WEBROOT));
}
Expand Down

0 comments on commit 6d21907

Please sign in to comment.