Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Commit

Permalink
Return 200 for OPTIONS requests everywhere.
Browse files Browse the repository at this point in the history
  • Loading branch information
clokep committed May 20, 2020
1 parent f5aaf42 commit b390d12
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 44 deletions.
15 changes: 2 additions & 13 deletions synapse/app/generic_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
from typing_extensions import ContextManager

from twisted.internet import defer, reactor
from twisted.web.resource import NoResource

import synapse
import synapse.events
Expand All @@ -41,7 +40,7 @@
from synapse.federation import send_queue
from synapse.federation.transport.server import TransportLayerServer
from synapse.handlers.presence import BasePresenceHandler, get_interested_parties
from synapse.http.server import JsonResource, OptionsOnlyResource
from synapse.http.server import JsonResource, OptionsResource
from synapse.http.servlet import RestServlet, parse_json_object_from_request
from synapse.http.site import SynapseSite
from synapse.logging.context import LoggingContext
Expand Down Expand Up @@ -574,17 +573,7 @@ def _listen_http(self, listener_config):
if name == "replication":
resources[REPLICATION_PREFIX] = ReplicationRestResource(self)

# Avoid 404s for requests to the media repo on workers which do not
# have the media listener enabled.
if "media" not in res["names"]:
resources.update(
{
MEDIA_PREFIX: OptionsOnlyResource(),
LEGACY_MEDIA_PREFIX: OptionsOnlyResource(),
}
)

root_resource = create_resource_tree(resources, NoResource())
root_resource = create_resource_tree(resources, OptionsResource())

_base.listen_tcp(
bind_addresses,
Expand Down
14 changes: 9 additions & 5 deletions synapse/app/homeserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from twisted.application import service
from twisted.internet import defer, reactor
from twisted.python.failure import Failure
from twisted.web.resource import EncodingResourceWrapper, IResource, NoResource
from twisted.web.resource import EncodingResourceWrapper, IResource
from twisted.web.server import GzipEncoderFactory
from twisted.web.static import File

Expand All @@ -52,7 +52,11 @@
from synapse.config.homeserver import HomeServerConfig
from synapse.federation.transport.server import TransportLayerServer
from synapse.http.additional_resource import AdditionalResource
from synapse.http.server import RootRedirect
from synapse.http.server import (
OptionsResource,
RootOptionsRedirectResource,
RootRedirect,
)
from synapse.http.site import SynapseSite
from synapse.logging.context import LoggingContext
from synapse.metrics import METRICS_PREFIX, MetricsResource, RegistryProxy
Expand Down Expand Up @@ -121,11 +125,11 @@ def _listener_http(self, config, listener_config):

# try to find something useful to redirect '/' to
if WEB_CLIENT_PREFIX in resources:
root_resource = RootRedirect(WEB_CLIENT_PREFIX)
root_resource = RootOptionsRedirectResource(WEB_CLIENT_PREFIX)
elif STATIC_PREFIX in resources:
root_resource = RootRedirect(STATIC_PREFIX)
root_resource = RootOptionsRedirectResource(STATIC_PREFIX)
else:
root_resource = NoResource()
root_resource = OptionsResource()

root_resource = create_resource_tree(resources, root_resource)

Expand Down
46 changes: 20 additions & 26 deletions synapse/http/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,9 +350,6 @@ def _get_handler_for_request(self, request):
register_paths, so will return (possibly via Deferred) either
None, or a tuple of (http code, response body).
"""
if request.method == b"OPTIONS":
return _options_handler, "options_request_handler", {}

request_path = request.path.decode("ascii")

# Loop through all the registered callbacks to check if the method
Expand Down Expand Up @@ -404,29 +401,6 @@ def render(self, request):
return NOT_DONE_YET


class OptionsOnlyResource(resource.Resource):
"""
A resource which responds only to OPTION requests for itself and all children.
All other requests return a 404.
"""

def render(self, request):
if request.method == b"OPTIONS":
code, response_json_object = _options_handler(request)

else:
# Otherwise, 404.
code, response_json_object = 404, {}

return respond_with_json(
request, code, response_json_object, send_cors=False, canonical_json=False,
)

def getChild(self, name, request):
return self # select ourselves as the child to render


def _options_handler(request):
"""Request handler for OPTIONS requests
Expand Down Expand Up @@ -471,6 +445,26 @@ def getChild(self, name, request):
return resource.Resource.getChild(self, name, request)


class OptionsResource(resource.Resource):
"""Responds to OPTION requests for itself and all children."""

def render_OPTIONS(self, request):
code, response_json_object = _options_handler(request)

return respond_with_json(
request, code, response_json_object, send_cors=False, canonical_json=False,
)

def getChildWithDefault(self, path, request):
if request.method == b"OPTIONS":
return self # select ourselves as the child to render
return resource.Resource.getChildWithDefault(self, path, request)


class RootOptionsRedirectResource(OptionsResource, RootRedirect):
pass


def respond_with_json(
request,
code,
Expand Down

0 comments on commit b390d12

Please sign in to comment.