diff --git a/src/App/Router.php b/src/App/Router.php index bbc3dd348e..c2887b1059 100644 --- a/src/App/Router.php +++ b/src/App/Router.php @@ -37,9 +37,9 @@ use Friendica\Core\Lock\Capability\ICanLock; use Friendica\LegacyModule; use Friendica\Module\HTTPException\MethodNotAllowed; use Friendica\Module\HTTPException\PageNotFound; +use Friendica\Module\Special\Options; use Friendica\Network\HTTPException; use Friendica\Network\HTTPException\MethodNotAllowedException; -use Friendica\Network\HTTPException\NoContentException; use Friendica\Network\HTTPException\NotFoundException; use Psr\Log\LoggerInterface; @@ -141,13 +141,6 @@ class Router $httpMethod = $this->server['REQUEST_METHOD'] ?? self::GET; - // @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS - // @todo Check allowed methods per requested path - if ($httpMethod === static::OPTIONS) { - header('Allow: ' . implode(',', Router::ALLOWED_METHODS)); - throw new NoContentException(); - } - $this->httpMethod = in_array($httpMethod, self::ALLOWED_METHODS) ? $httpMethod : self::GET; $this->routeCollector = isset($routeCollector) ? @@ -284,6 +277,9 @@ class Router $this->parameters = $routeInfo[2]; } elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) { throw new HTTPException\MethodNotAllowedException($this->l10n->t('Method not allowed for this module. Allowed method(s): %s', implode(', ', $routeInfo[1]))); + } elseif ($this->httpMethod === static::OPTIONS) { + // Default response for HTTP OPTIONS requests in case there is no special treatment + $moduleClass = Options::class; } else { throw new HTTPException\NotFoundException($this->l10n->t('Page not found.')); } diff --git a/src/BaseModule.php b/src/BaseModule.php index 08efff3d78..4fbf39cf71 100644 --- a/src/BaseModule.php +++ b/src/BaseModule.php @@ -173,6 +173,18 @@ abstract class BaseModule implements ICanHandleRequests { } + /** + * Module OPTIONS method to process submitted data + * + * Extend this method if the module is supposed to process OPTIONS requests. + * Doesn't display any content + * + * @param string[] $request The $_REQUEST content + */ + protected function options(array $request = []) + { + } + /** * {@inheritDoc} */ @@ -225,6 +237,9 @@ abstract class BaseModule implements ICanHandleRequests case Router::PUT: $this->put($request); break; + case Router::OPTIONS: + $this->options($request); + break; } $timestamp = microtime(true); diff --git a/src/Module/Special/Options.php b/src/Module/Special/Options.php new file mode 100644 index 0000000000..36bbe4fb13 --- /dev/null +++ b/src/Module/Special/Options.php @@ -0,0 +1,16 @@ +response->setHeader('Allow', implode(',', Router::ALLOWED_METHODS)); + $this->response->setHeader(($this->server['SERVER_PROTOCOL'] ?? 'HTTP/1.1') . ' 204 No Content'); + } +}