You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
3.0 KiB

  1. <?php
  2. declare(strict_types=1);
  3. use OC\ServiceUnavailableException;
  4. /**
  5. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  6. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  7. * SPDX-License-Identifier: AGPL-3.0-only
  8. */
  9. require_once __DIR__ . '/lib/versioncheck.php';
  10. use OCP\App\IAppManager;
  11. use OCP\IConfig;
  12. use OCP\IRequest;
  13. use OCP\Server;
  14. use OCP\Template\ITemplateManager;
  15. use OCP\Util;
  16. use Psr\Log\LoggerInterface;
  17. function resolveService(string $service): string {
  18. $services = [
  19. 'webdav' => 'dav/appinfo/v1/publicwebdav.php',
  20. 'dav' => 'dav/appinfo/v2/publicremote.php',
  21. ];
  22. if (isset($services[$service])) {
  23. return $services[$service];
  24. }
  25. return Server::get(IConfig::class)->getAppValue('core', 'remote_' . $service);
  26. }
  27. try {
  28. require_once __DIR__ . '/lib/base.php';
  29. // All resources served via the DAV endpoint should have the strictest possible
  30. // policy. Exempted from this is the SabreDAV browser plugin which overwrites
  31. // this policy with a softer one if debug mode is enabled.
  32. header("Content-Security-Policy: default-src 'none';");
  33. // Check if Nextcloud is in maintenance mode
  34. if (Util::needUpgrade()) {
  35. // since the behavior of apps or remotes are unpredictable during
  36. // an upgrade, return a 503 directly
  37. throw new \Exception('Service unavailable', 503);
  38. }
  39. $request = Server::get(IRequest::class);
  40. $pathInfo = $request->getPathInfo();
  41. if ($pathInfo === false || $pathInfo === '') {
  42. throw new \Exception('Path not found', 404);
  43. }
  44. // Extract the service from the path
  45. if (!$pos = strpos($pathInfo, '/', 1)) {
  46. $pos = strlen($pathInfo);
  47. }
  48. $service = substr($pathInfo, 1, $pos - 1);
  49. // Resolve the service to a file
  50. $file = resolveService($service);
  51. if (!$file) {
  52. throw new \Exception('Path not found', 404);
  53. }
  54. // Extract the app from the service file
  55. $file = ltrim($file, '/');
  56. $parts = explode('/', $file, 2);
  57. $app = $parts[0];
  58. // Load all required applications
  59. $appManager = Server::get(IAppManager::class);
  60. \OC::$REQUESTEDAPP = $app;
  61. $appManager->loadApps(['authentication']);
  62. $appManager->loadApps(['extended_authentication']);
  63. $appManager->loadApps(['filesystem', 'logging']);
  64. // Check if the app is enabled
  65. if (!$appManager->isEnabledForUser($app)) {
  66. throw new \Exception('App not installed: ' . $app);
  67. }
  68. // Load the app
  69. $appManager->loadApp($app);
  70. OC_User::setIncognitoMode(true);
  71. $baseuri = OC::$WEBROOT . '/public.php/' . $service . '/';
  72. require_once $file;
  73. } catch (Exception $ex) {
  74. $status = 500;
  75. if ($ex instanceof ServiceUnavailableException) {
  76. $status = 503;
  77. }
  78. //show the user a detailed error page
  79. Server::get(LoggerInterface::class)->error($ex->getMessage(), ['app' => 'public', 'exception' => $ex]);
  80. Server::get(ITemplateManager::class)->printExceptionErrorPage($ex, $status);
  81. } catch (Error $ex) {
  82. //show the user a detailed error page
  83. Server::get(LoggerInterface::class)->error($ex->getMessage(), ['app' => 'public', 'exception' => $ex]);
  84. Server::get(ITemplateManager::class)->printExceptionErrorPage($ex, 500);
  85. }