forked from MirrorHub/synapse
Move SynapseSite to its own file
This commit is contained in:
parent
2022ae0fb9
commit
e856036f4c
2 changed files with 149 additions and 130 deletions
|
@ -16,12 +16,9 @@
|
||||||
|
|
||||||
import synapse
|
import synapse
|
||||||
|
|
||||||
import contextlib
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
|
||||||
import sys
|
import sys
|
||||||
import time
|
|
||||||
from synapse.config._base import ConfigError
|
from synapse.config._base import ConfigError
|
||||||
|
|
||||||
from synapse.python_dependencies import (
|
from synapse.python_dependencies import (
|
||||||
|
@ -46,7 +43,7 @@ from twisted.internet import reactor, task, defer
|
||||||
from twisted.application import service
|
from twisted.application import service
|
||||||
from twisted.web.resource import Resource, EncodingResourceWrapper
|
from twisted.web.resource import Resource, EncodingResourceWrapper
|
||||||
from twisted.web.static import File
|
from twisted.web.static import File
|
||||||
from twisted.web.server import Site, GzipEncoderFactory, Request
|
from twisted.web.server import GzipEncoderFactory
|
||||||
from synapse.http.server import RootRedirect
|
from synapse.http.server import RootRedirect
|
||||||
from synapse.rest.media.v0.content_repository import ContentRepoResource
|
from synapse.rest.media.v0.content_repository import ContentRepoResource
|
||||||
from synapse.rest.media.v1.media_repository import MediaRepositoryResource
|
from synapse.rest.media.v1.media_repository import MediaRepositoryResource
|
||||||
|
@ -67,6 +64,8 @@ from synapse.federation.transport.server import TransportLayerServer
|
||||||
from synapse.util.rlimit import change_resource_limit
|
from synapse.util.rlimit import change_resource_limit
|
||||||
from synapse.util.versionstring import get_version_string
|
from synapse.util.versionstring import get_version_string
|
||||||
|
|
||||||
|
from synapse.http.site import SynapseSite
|
||||||
|
|
||||||
from synapse import events
|
from synapse import events
|
||||||
|
|
||||||
from daemonize import Daemonize
|
from daemonize import Daemonize
|
||||||
|
@ -74,9 +73,6 @@ from daemonize import Daemonize
|
||||||
logger = logging.getLogger("synapse.app.homeserver")
|
logger = logging.getLogger("synapse.app.homeserver")
|
||||||
|
|
||||||
|
|
||||||
ACCESS_TOKEN_RE = re.compile(r'(\?.*access(_|%5[Ff])token=)[^&]*(.*)$')
|
|
||||||
|
|
||||||
|
|
||||||
def gz_wrap(r):
|
def gz_wrap(r):
|
||||||
return EncodingResourceWrapper(r, [GzipEncoderFactory()])
|
return EncodingResourceWrapper(r, [GzipEncoderFactory()])
|
||||||
|
|
||||||
|
@ -371,129 +367,6 @@ class SynapseService(service.Service):
|
||||||
return self._port.stopListening()
|
return self._port.stopListening()
|
||||||
|
|
||||||
|
|
||||||
class SynapseRequest(Request):
|
|
||||||
def __init__(self, site, *args, **kw):
|
|
||||||
Request.__init__(self, *args, **kw)
|
|
||||||
self.site = site
|
|
||||||
self.authenticated_entity = None
|
|
||||||
self.start_time = 0
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
# We overwrite this so that we don't log ``access_token``
|
|
||||||
return '<%s at 0x%x method=%s uri=%s clientproto=%s site=%s>' % (
|
|
||||||
self.__class__.__name__,
|
|
||||||
id(self),
|
|
||||||
self.method,
|
|
||||||
self.get_redacted_uri(),
|
|
||||||
self.clientproto,
|
|
||||||
self.site.site_tag,
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_redacted_uri(self):
|
|
||||||
return ACCESS_TOKEN_RE.sub(
|
|
||||||
r'\1<redacted>\3',
|
|
||||||
self.uri
|
|
||||||
)
|
|
||||||
|
|
||||||
def get_user_agent(self):
|
|
||||||
return self.requestHeaders.getRawHeaders("User-Agent", [None])[-1]
|
|
||||||
|
|
||||||
def started_processing(self):
|
|
||||||
self.site.access_logger.info(
|
|
||||||
"%s - %s - Received request: %s %s",
|
|
||||||
self.getClientIP(),
|
|
||||||
self.site.site_tag,
|
|
||||||
self.method,
|
|
||||||
self.get_redacted_uri()
|
|
||||||
)
|
|
||||||
self.start_time = int(time.time() * 1000)
|
|
||||||
|
|
||||||
def finished_processing(self):
|
|
||||||
|
|
||||||
try:
|
|
||||||
context = LoggingContext.current_context()
|
|
||||||
ru_utime, ru_stime = context.get_resource_usage()
|
|
||||||
db_txn_count = context.db_txn_count
|
|
||||||
db_txn_duration = context.db_txn_duration
|
|
||||||
except:
|
|
||||||
ru_utime, ru_stime = (0, 0)
|
|
||||||
db_txn_count, db_txn_duration = (0, 0)
|
|
||||||
|
|
||||||
self.site.access_logger.info(
|
|
||||||
"%s - %s - {%s}"
|
|
||||||
" Processed request: %dms (%dms, %dms) (%dms/%d)"
|
|
||||||
" %sB %s \"%s %s %s\" \"%s\"",
|
|
||||||
self.getClientIP(),
|
|
||||||
self.site.site_tag,
|
|
||||||
self.authenticated_entity,
|
|
||||||
int(time.time() * 1000) - self.start_time,
|
|
||||||
int(ru_utime * 1000),
|
|
||||||
int(ru_stime * 1000),
|
|
||||||
int(db_txn_duration * 1000),
|
|
||||||
int(db_txn_count),
|
|
||||||
self.sentLength,
|
|
||||||
self.code,
|
|
||||||
self.method,
|
|
||||||
self.get_redacted_uri(),
|
|
||||||
self.clientproto,
|
|
||||||
self.get_user_agent(),
|
|
||||||
)
|
|
||||||
|
|
||||||
@contextlib.contextmanager
|
|
||||||
def processing(self):
|
|
||||||
self.started_processing()
|
|
||||||
yield
|
|
||||||
self.finished_processing()
|
|
||||||
|
|
||||||
|
|
||||||
class XForwardedForRequest(SynapseRequest):
|
|
||||||
def __init__(self, *args, **kw):
|
|
||||||
SynapseRequest.__init__(self, *args, **kw)
|
|
||||||
|
|
||||||
"""
|
|
||||||
Add a layer on top of another request that only uses the value of an
|
|
||||||
X-Forwarded-For header as the result of C{getClientIP}.
|
|
||||||
"""
|
|
||||||
def getClientIP(self):
|
|
||||||
"""
|
|
||||||
@return: The client address (the first address) in the value of the
|
|
||||||
I{X-Forwarded-For header}. If the header is not present, return
|
|
||||||
C{b"-"}.
|
|
||||||
"""
|
|
||||||
return self.requestHeaders.getRawHeaders(
|
|
||||||
b"x-forwarded-for", [b"-"])[0].split(b",")[0].strip()
|
|
||||||
|
|
||||||
|
|
||||||
class SynapseRequestFactory(object):
|
|
||||||
def __init__(self, site, x_forwarded_for):
|
|
||||||
self.site = site
|
|
||||||
self.x_forwarded_for = x_forwarded_for
|
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
|
||||||
if self.x_forwarded_for:
|
|
||||||
return XForwardedForRequest(self.site, *args, **kwargs)
|
|
||||||
else:
|
|
||||||
return SynapseRequest(self.site, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
class SynapseSite(Site):
|
|
||||||
"""
|
|
||||||
Subclass of a twisted http Site that does access logging with python's
|
|
||||||
standard logging
|
|
||||||
"""
|
|
||||||
def __init__(self, logger_name, site_tag, config, resource, *args, **kwargs):
|
|
||||||
Site.__init__(self, resource, *args, **kwargs)
|
|
||||||
|
|
||||||
self.site_tag = site_tag
|
|
||||||
|
|
||||||
proxied = config.get("x_forwarded", False)
|
|
||||||
self.requestFactory = SynapseRequestFactory(self, proxied)
|
|
||||||
self.access_logger = logging.getLogger(logger_name)
|
|
||||||
|
|
||||||
def log(self, request):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def create_resource_tree(desired_tree, redirect_root_to_web_client=True):
|
def create_resource_tree(desired_tree, redirect_root_to_web_client=True):
|
||||||
"""Create the resource tree for this Home Server.
|
"""Create the resource tree for this Home Server.
|
||||||
|
|
||||||
|
|
146
synapse/http/site.py
Normal file
146
synapse/http/site.py
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
# Copyright 2016 OpenMarket Ltd
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
from synapse.util.logcontext import LoggingContext
|
||||||
|
from twisted.web.server import Site, Request
|
||||||
|
|
||||||
|
import contextlib
|
||||||
|
import logging
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
|
||||||
|
ACCESS_TOKEN_RE = re.compile(r'(\?.*access(_|%5[Ff])token=)[^&]*(.*)$')
|
||||||
|
|
||||||
|
|
||||||
|
class SynapseRequest(Request):
|
||||||
|
def __init__(self, site, *args, **kw):
|
||||||
|
Request.__init__(self, *args, **kw)
|
||||||
|
self.site = site
|
||||||
|
self.authenticated_entity = None
|
||||||
|
self.start_time = 0
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
# We overwrite this so that we don't log ``access_token``
|
||||||
|
return '<%s at 0x%x method=%s uri=%s clientproto=%s site=%s>' % (
|
||||||
|
self.__class__.__name__,
|
||||||
|
id(self),
|
||||||
|
self.method,
|
||||||
|
self.get_redacted_uri(),
|
||||||
|
self.clientproto,
|
||||||
|
self.site.site_tag,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_redacted_uri(self):
|
||||||
|
return ACCESS_TOKEN_RE.sub(
|
||||||
|
r'\1<redacted>\3',
|
||||||
|
self.uri
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_user_agent(self):
|
||||||
|
return self.requestHeaders.getRawHeaders("User-Agent", [None])[-1]
|
||||||
|
|
||||||
|
def started_processing(self):
|
||||||
|
self.site.access_logger.info(
|
||||||
|
"%s - %s - Received request: %s %s",
|
||||||
|
self.getClientIP(),
|
||||||
|
self.site.site_tag,
|
||||||
|
self.method,
|
||||||
|
self.get_redacted_uri()
|
||||||
|
)
|
||||||
|
self.start_time = int(time.time() * 1000)
|
||||||
|
|
||||||
|
def finished_processing(self):
|
||||||
|
|
||||||
|
try:
|
||||||
|
context = LoggingContext.current_context()
|
||||||
|
ru_utime, ru_stime = context.get_resource_usage()
|
||||||
|
db_txn_count = context.db_txn_count
|
||||||
|
db_txn_duration = context.db_txn_duration
|
||||||
|
except:
|
||||||
|
ru_utime, ru_stime = (0, 0)
|
||||||
|
db_txn_count, db_txn_duration = (0, 0)
|
||||||
|
|
||||||
|
self.site.access_logger.info(
|
||||||
|
"%s - %s - {%s}"
|
||||||
|
" Processed request: %dms (%dms, %dms) (%dms/%d)"
|
||||||
|
" %sB %s \"%s %s %s\" \"%s\"",
|
||||||
|
self.getClientIP(),
|
||||||
|
self.site.site_tag,
|
||||||
|
self.authenticated_entity,
|
||||||
|
int(time.time() * 1000) - self.start_time,
|
||||||
|
int(ru_utime * 1000),
|
||||||
|
int(ru_stime * 1000),
|
||||||
|
int(db_txn_duration * 1000),
|
||||||
|
int(db_txn_count),
|
||||||
|
self.sentLength,
|
||||||
|
self.code,
|
||||||
|
self.method,
|
||||||
|
self.get_redacted_uri(),
|
||||||
|
self.clientproto,
|
||||||
|
self.get_user_agent(),
|
||||||
|
)
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def processing(self):
|
||||||
|
self.started_processing()
|
||||||
|
yield
|
||||||
|
self.finished_processing()
|
||||||
|
|
||||||
|
|
||||||
|
class XForwardedForRequest(SynapseRequest):
|
||||||
|
def __init__(self, *args, **kw):
|
||||||
|
SynapseRequest.__init__(self, *args, **kw)
|
||||||
|
|
||||||
|
"""
|
||||||
|
Add a layer on top of another request that only uses the value of an
|
||||||
|
X-Forwarded-For header as the result of C{getClientIP}.
|
||||||
|
"""
|
||||||
|
def getClientIP(self):
|
||||||
|
"""
|
||||||
|
@return: The client address (the first address) in the value of the
|
||||||
|
I{X-Forwarded-For header}. If the header is not present, return
|
||||||
|
C{b"-"}.
|
||||||
|
"""
|
||||||
|
return self.requestHeaders.getRawHeaders(
|
||||||
|
b"x-forwarded-for", [b"-"])[0].split(b",")[0].strip()
|
||||||
|
|
||||||
|
|
||||||
|
class SynapseRequestFactory(object):
|
||||||
|
def __init__(self, site, x_forwarded_for):
|
||||||
|
self.site = site
|
||||||
|
self.x_forwarded_for = x_forwarded_for
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
if self.x_forwarded_for:
|
||||||
|
return XForwardedForRequest(self.site, *args, **kwargs)
|
||||||
|
else:
|
||||||
|
return SynapseRequest(self.site, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
class SynapseSite(Site):
|
||||||
|
"""
|
||||||
|
Subclass of a twisted http Site that does access logging with python's
|
||||||
|
standard logging
|
||||||
|
"""
|
||||||
|
def __init__(self, logger_name, site_tag, config, resource, *args, **kwargs):
|
||||||
|
Site.__init__(self, resource, *args, **kwargs)
|
||||||
|
|
||||||
|
self.site_tag = site_tag
|
||||||
|
|
||||||
|
proxied = config.get("x_forwarded", False)
|
||||||
|
self.requestFactory = SynapseRequestFactory(self, proxied)
|
||||||
|
self.access_logger = logging.getLogger(logger_name)
|
||||||
|
|
||||||
|
def log(self, request):
|
||||||
|
pass
|
Loading…
Reference in a new issue