BrowserErrorPagePlugin.php 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\DAV\Files;
  8. use OC\AppFramework\Http\Request;
  9. use OC_Template;
  10. use OCP\AppFramework\Http\ContentSecurityPolicy;
  11. use OCP\IRequest;
  12. use Sabre\DAV\Exception;
  13. use Sabre\DAV\Server;
  14. use Sabre\DAV\ServerPlugin;
  15. class BrowserErrorPagePlugin extends ServerPlugin {
  16. /** @var Server */
  17. private $server;
  18. /**
  19. * This initializes the plugin.
  20. *
  21. * This function is called by Sabre\DAV\Server, after
  22. * addPlugin is called.
  23. *
  24. * This method should set up the required event subscriptions.
  25. *
  26. * @param Server $server
  27. * @return void
  28. */
  29. public function initialize(Server $server) {
  30. $this->server = $server;
  31. $server->on('exception', [$this, 'logException'], 1000);
  32. }
  33. /**
  34. * @param IRequest $request
  35. * @return bool
  36. */
  37. public static function isBrowserRequest(IRequest $request) {
  38. if ($request->getMethod() !== 'GET') {
  39. return false;
  40. }
  41. return $request->isUserAgent([
  42. Request::USER_AGENT_IE,
  43. Request::USER_AGENT_MS_EDGE,
  44. Request::USER_AGENT_CHROME,
  45. Request::USER_AGENT_FIREFOX,
  46. Request::USER_AGENT_SAFARI,
  47. ]);
  48. }
  49. /**
  50. * @param \Throwable $ex
  51. */
  52. public function logException(\Throwable $ex): void {
  53. if ($ex instanceof Exception) {
  54. $httpCode = $ex->getHTTPCode();
  55. $headers = $ex->getHTTPHeaders($this->server);
  56. } else {
  57. $httpCode = 500;
  58. $headers = [];
  59. }
  60. $this->server->httpResponse->addHeaders($headers);
  61. $this->server->httpResponse->setStatus($httpCode);
  62. $body = $this->generateBody($httpCode);
  63. $this->server->httpResponse->setBody($body);
  64. $csp = new ContentSecurityPolicy();
  65. $this->server->httpResponse->addHeader('Content-Security-Policy', $csp->buildPolicy());
  66. $this->sendResponse();
  67. }
  68. /**
  69. * @codeCoverageIgnore
  70. * @return bool|string
  71. */
  72. public function generateBody(int $httpCode) {
  73. $request = \OC::$server->getRequest();
  74. $templateName = 'exception';
  75. if ($httpCode === 403 || $httpCode === 404) {
  76. $templateName = (string)$httpCode;
  77. }
  78. $content = new OC_Template('core', $templateName, 'guest');
  79. $content->assign('title', $this->server->httpResponse->getStatusText());
  80. $content->assign('remoteAddr', $request->getRemoteAddress());
  81. $content->assign('requestID', $request->getId());
  82. return $content->fetchPage();
  83. }
  84. /**
  85. * @codeCoverageIgnore
  86. */
  87. public function sendResponse() {
  88. $this->server->sapi->sendResponse($this->server->httpResponse);
  89. exit();
  90. }
  91. }