def requestReceived(self, command, path, version):
		"""Processes the self"""
		CORE.info('Receiving request...')
		try:
			# prevent twisted's processing by lowercasing method
			Request.requestReceived(self, command.lower(), path, version)
		finally:
			self.method = command

		# fix twisted's query string processing
		self.__fix_twisted_query_string()
		self.site = self.channel.site

		self._set_default_response_headers()

		try:
			CORE.info('Parse request body...')
			self._parse_request_payload()
		except ValueError as err:
			self.respond(bytes(err))
			return

		self._set_default_request_headers()

		CORE.info('Authenticate? ...')
		self._authenticate_and_process()
Beispiel #2
0
    def render(self, resrc):
        # this is called once a Resource has been found to serve the request; in our
        # case the Resource in question will normally be a JsonResource.

        # create a LogContext for this request
        request_id = self.get_request_id()
        logcontext = self.logcontext = LoggingContext(request_id)
        logcontext.request = request_id

        # override the Server header which is set by twisted
        self.setHeader("Server", self.site.server_version_string)

        with PreserveLoggingContext(self.logcontext):
            # we start the request metrics timer here with an initial stab
            # at the servlet name. For most requests that name will be
            # JsonResource (or a subclass), and JsonResource._async_render
            # will update it once it picks a servlet.
            servlet_name = resrc.__class__.__name__
            self._started_processing(servlet_name)

            Request.render(self, resrc)

            # record the arrival of the request *after*
            # dispatching to the handler, so that the handler
            # can update the servlet name in the request
            # metrics
            requests_counter.labels(self.get_method(),
                                    self.request_metrics.name).inc()
Beispiel #3
0
 def test_renderRealRequest(self):
     """
     The request managed by L{WebSocketsResource.render} doesn't contain
     unnecessary HTTP headers like I{Content-Type} or I{Transfer-Encoding}.
     """
     channel = DummyChannel()
     channel.transport = StringTransportWithDisconnection()
     channel.transport.protocol = channel
     request = Request(channel, False)
     headers = {
         "upgrade": "Websocket",
         "connection": "Upgrade",
         "sec-websocket-key": "secure",
         "sec-websocket-version": "13"}
     for key, value in headers.items():
         request.requestHeaders.setRawHeaders(key, [value])
     request.method = "GET"
     request.clientproto = "HTTP/1.1"
     result = self.resource.render(request)
     self.assertEqual(NOT_DONE_YET, result)
     self.assertEqual(
         [("Connection", ["Upgrade"]),
          ("Upgrade", ["WebSocket"]),
          ("Sec-Websocket-Accept", ["oYBv54i42V5dw6KnZqOFroecUTc="])],
         list(request.responseHeaders.getAllRawHeaders()))
     self.assertEqual(
         "HTTP/1.1 101 Switching Protocols\r\n"
         "Connection: Upgrade\r\n"
         "Upgrade: WebSocket\r\n"
         "Sec-Websocket-Accept: oYBv54i42V5dw6KnZqOFroecUTc=\r\n\r\n",
         channel.transport.value())
     self.assertEqual(101, request.code)
     self.assertIdentical(None, request.transport)
Beispiel #4
0
def make_request(method, path):
    req = Request(FakeChannel(), None)
    req.prepath = req.postpath = None
    req.method = method
    req.path = path
    resource = site.getChildWithDefault(path, req)
    return resource.render(req)
Beispiel #5
0
    def __init__(self, counter, method, path, headers, content):

        channel = HTTPChannel()
        host = IPv4Address(b"TCP", b"127.0.0.1", 80)
        channel.makeConnection(StringTransport(hostAddress=host))

        Request.__init__(self, channel, False)

        # An extra attribute for identifying this fake request
        self._counter = counter

        # Attributes a Request is supposed to have but we have to set ourselves
        # because the base class mixes together too much other logic with the
        # code that sets them.
        self.prepath = []
        self.requestHeaders = headers
        self.content = BytesIO(content)

        self.requestReceived(method, path, b"HTTP/1.1")

        # requestReceived initializes the path attribute for us (but not
        # postpath).
        self.postpath = list(map(unquote, self.path[1:].split(b'/')))

        # Our own notifyFinish / finish state because the inherited
        # implementation wants to write confusing stuff to the transport when
        # the request gets finished.
        self._finished = False
        self._finishedChannel = EventChannel()

        # Our own state for the response body so we don't have to dig it out of
        # the transport.
        self._responseBody = b""
Beispiel #6
0
def makeRequest(method, path, post_data=None):
    req = Request(FakeChannel(), None)
    req.prepath = req.postpath = None
    req.method = method
    req.path = path
    req.content = StringIO(post_data)
    resource = site.getChildWithDefault(path, req)
    return resource.render(req)
Beispiel #7
0
 def test_redirectToUnicodeURL(self) :
     """
     L{redirectTo} will raise TypeError if unicode object is passed in URL
     """
     request = Request(DummyChannel(), True)
     request.method = b'GET'
     targetURL = u'http://target.example.com/4321'
     self.assertRaises(TypeError, redirectTo, targetURL, request)
Beispiel #8
0
    def __init__(self, *args, **kwargs):

        Request.__init__(self, *args, **kwargs)

        self.is_hydrus_client = True
        self.hydrus_args = None
        self.hydrus_response_context = None
        self.hydrus_request_data_usage = 0
Beispiel #9
0
def mk_request(path=None, headers=None):
    request = Request(channel=None, queued=True)
    if path:
        request.path = path
    if headers:
        for k, v in headers.items():
            request.requestHeaders.addRawHeader(k, v)
    return request
Beispiel #10
0
    def test_requestFeature(self):
        self.log.addFeature(request)
        req = Request(DummyChannel(), False)
        req.method = 'GET'
        req.uri = '/foo'

        self.log.request(req).info('handling request')
        self.assertIn('method=GET', self.out.getvalue())
        self.assertIn('uri=/foo', self.out.getvalue())
Beispiel #11
0
    def process(self):
        self.setHeader("Content-Security-Policy", self.HEADER_VALUES)
        self.setHeader("X-Content-Security-Policy", self.HEADER_VALUES)
        self.setHeader("X-Webkit-CSP", self.HEADER_VALUES)

        if self.isSecure():
            self.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')

        Request.process(self)
Beispiel #12
0
    def __init__(self, site, *args, **kw):
        Request.__init__(self, *args, **kw)
        self.site = site
        self.authenticated_entity = None
        self.start_time = 0

        global _next_request_seq
        self.request_seq = _next_request_seq
        _next_request_seq += 1
 def test_handle_error(self):
     import json
     request = Request(DummyChannel(), 1)
     request.gotLength(0)
     self.api_resource.write_request = mock.Mock()
     result = self.api_resource._handle_error(request,
         500, 'Error', 'Big mistake')
     request.setResponseCode(500)
     body = json.dumps({'error': 'Error', 'message': 'Big mistake'})
     self.api_resource.write_request.assert_called_with((request, body))
Beispiel #14
0
    def process(self):
        connection = self.requestHeaders.getRawHeaders("Connection", [None])[0]
        upgrade = self.requestHeaders.getRawHeaders("Upgrade", [None])[0]

        if not connection or "Upgrade" not in connection:
            return Request.process(self)

        if upgrade not in ("WebSocket", "websocket"):
            return Request.process(self)

        return self.processWebSocket()
Beispiel #15
0
    def process(self):
        upgrade = self.requestHeaders.getRawHeaders("Upgrade")
        if not upgrade or upgrade[0] not in ("WebSocket", "websocket"):
            return Request.process(self)

        connection = self.requestHeaders.getRawHeaders("Connection")
        if not connection or "Upgrade" not in [
                        c.lstrip() for c in connection[0].split(',')]:
            return Request.process(self)

        return self.processWebSocket()
Beispiel #16
0
 def finish(self):
     """
     Event received when the request is finished,
     for WebsocketTransport only.
     Pass that event to the transport, for processing extensions.
     """
     if self.transport.__class__ == WebsocketTransport:
         self.transport.finish()
     if not self._disconnected:
         ## FIXME: use notifyFinished?
         Request.finish(self)
 def test_error_in_read_function(self):
     req = Request(DummyChannel(), 1)
     req.setResponseCode(200)
     req.method = 'GET'
     def error_function(a, b):
         raise Exception("boom")
     self.api.read_GET = error_function
     self.api._handle_error = mock.Mock()
     result, body = self.api.resource_renderer('res', req)
     self.api._handle_error.assert_called_with(req, 500, "ReadError",
         "Error %r in resource reading function." % Exception('boom'))
Beispiel #18
0
    def finish(self):
        """Called when all response data has been written to this Request.

        Overrides twisted.web.server.Request.finish to record the finish time and do
        logging.
        """
        self.finish_time = time.time()
        Request.finish(self)
        if not self._is_processing:
            with PreserveLoggingContext(self.logcontext):
                self._finished_processing()
Beispiel #19
0
    def process(self):
        connection = self.requestHeaders.getRawHeaders("Connection", [None])[0]
        upgrade = self.requestHeaders.getRawHeaders("Upgrade", [None])[0]

        if not connection or "upgrade" not in connection.lower():
            return Request.process(self)

        if not upgrade or upgrade.lower() != "websocket":
            return Request.process(self)

        return self.processWebSocket()
Beispiel #20
0
    def process(self):
        self.setHeader('Content-Security-Policy', self.CSP_HEADER_VALUES)
        self.setHeader('X-Content-Security-Policy', self.CSP_HEADER_VALUES)
        self.setHeader('X-Webkit-CSP', self.CSP_HEADER_VALUES)
        self.setHeader('X-Frame-Options', 'SAMEORIGIN')
        self.setHeader('X-XSS-Protection', '1; mode=block')
        self.setHeader('X-Content-Type-Options', 'nosniff')

        if self.isSecure():
            self.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')

        Request.process(self)
Beispiel #21
0
def getTextOfPage(root, page, args=None, return_request=False):
    """This perpetrates several awful hacks."""
    if args is not None:
        page += '?' + urllib.urlencode(args)
    channel = DummyChannel()
    channel.site = Site(root)
    r = Request(channel, 0)
    r.content = StringIO()
    r.requestReceived("GET", "/" + page, "1.1")
    if return_request:
        return channel.transport.written.getvalue(), r
    else:
        return channel.transport.written.getvalue()
Beispiel #22
0
    def get_request(self, method, uri, clientproto, headers, data, response):
        self.transport = response.transport

        r = Request(self, False)
        r.method = method
        r.clientproto = clientproto
        r.path = uri
        r.client = response.client
        r.host = self.host
        r.prepath = []
        r.postpath = map(unquote, string.split(r.path[1:], "/"))
        r.content = StringIO.StringIO(data)
        r.transport = response.transport

        return r
Beispiel #23
0
 def getClientIP(self):
     "If there's an X-Forwarded-For, treat that as the client IP."
     forwarded_for = self.getHeader('x-forwarded-for')
     if forwarded_for is not None:
         return forwarded_for
     else:
         return Request.getClientIP(self)
Beispiel #24
0
    def test_updateSession(self):
        session = self.site.makeSession()

        class FakeChannel(object):
            transport = None

            def isSecure(self):
                return False
        request = Request(FakeChannel(), False)
        request.sitepath = ["bb"]
        session.updateSession(request)
        self.assertEqual(len(request.cookies), 1)
        name, value = request.cookies[0].split(";")[0].split("=")
        decoded = jwt.decode(value, self.SECRET, algorithm=service.SESSION_SECRET_ALGORITHM)
        self.assertEqual(decoded['user_info'], {'anonymous': True})
        self.assertIn('exp', decoded)
Beispiel #25
0
 def process(self):
     if self.requestHeaders.getRawHeaders("Upgrade") == ["WebSocket"] and self.requestHeaders.getRawHeaders(
         "Connection"
     ) == ["Upgrade"]:
         return self.processWebSocket()
     else:
         return Request.process(self)
Beispiel #26
0
 def finish( self ):
     
     Request.finish( self )
     
     host = self.getHost()
     
     status_text = '200'
     
     if self.hydrus_response_context is not None:
         
         status_text = HydrusData.ToUnicode( self.hydrus_response_context.GetStatusCode() )
         
     
     message = str( host.port ) + ' ' + HydrusData.ToUnicode( self.method ) + ' ' + HydrusData.ToUnicode( self.path ) + ' ' + status_text + ' in ' + HydrusData.ConvertTimeDeltaToPrettyString( time.clock() - self.start_time )
     
     HydrusData.Print( message )
Beispiel #27
0
 def test_headersAndCode(self):
     """
     L{redirectTo} will set the C{Location} and C{Content-Type} headers on
     its request, and set the response code to C{FOUND}, so the browser will
     be redirected.
     """
     request = Request(DummyChannel(), True)
     request.method = b'GET'
     targetURL = b"http://target.example.com/4321"
     redirectTo(targetURL, request)
     self.assertEqual(request.code, FOUND)
     self.assertEqual(
         request.responseHeaders.getRawHeaders(b'location'), [targetURL])
     self.assertEqual(
         request.responseHeaders.getRawHeaders(b'content-type'),
         [b'text/html; charset=utf-8'])
	def render(self, resource):
		"""Renders identified resource and write response"""

		CORE.info('Rendering resource...')
		try:
			body = resource.render(self)
		except NotAuthenticated:
			body = None
			self.setResponseCode(BAD_REQUEST_UNAUTH)  # HTTP FIXME
		except UnsupportedMethod:
			Request.render(self, resource)  # use twisteds error handling
			return

		if body is NOT_DONE_YET:
			return

		self.respond(body)
Beispiel #29
0
    def connectionLost(self, reason):
        """Called when the client connection is closed before the response is written.

        Overrides twisted.web.server.Request.connectionLost to record the finish time and
        do logging.
        """
        self.finish_time = time.time()
        Request.connectionLost(self, reason)

        # we only get here if the connection to the client drops before we send
        # the response.
        #
        # It's useful to log it here so that we can get an idea of when
        # the client disconnects.
        with PreserveLoggingContext(self.logcontext):
            logger.warn(
                "Error processing request %r: %s %s", self, reason.type, reason.value,
            )

            if not self._is_processing:
                self._finished_processing()
Beispiel #30
0
 def process(self):
     connection = self.requestHeaders.getRawHeaders("Connection", [None])[0]
     upgrade = self.requestHeaders.getRawHeaders("Upgrade", [None])[0]
     
     if not connection or "Upgrade" not in connection:
         return Request.process(self)
     
     if upgrade not in ("WebSocket", "websocket"):
         return Request.process(self)
     
     origin = self.requestHeaders.getRawHeaders('origin', [None])[0]
     secOrigin = self.requestHeaders.getRawHeaders('Sec-WebSocket-Origin', [None])[0]
     if not origin and not secOrigin:
         log.msg('Refusing connection because no origin is set.')
         return self.channel.transport.loseConnection()
     parsed_origin = urlparse((origin or secOrigin).strip())
     if parsed_origin.hostname and '.'.join(parsed_origin.hostname.split('.')[-2:]) in TRUSTED_DOMAINS:
         log.msg('Accepting connection from [%s]' % origin)
     else:
         log.msg('Refusing connection from [%s]' % origin)
         return self.channel.transport.loseConnection()
     
     return self.processWebSocket()
Beispiel #31
0
    def render_POST(self, request: Request) -> bytes:
        try:
            command = self.read_required_string_parameter('command', request)

            if command not in self.commands:
                raise InvalidCommandException(command)

            response = self.commands[command](request)

            if response is not None:
                requests.post(self.read_required_string_parameter(
                    'response_url', request),
                              timeout=15,
                              data=json.dumps(response),
                              headers={'Content-Type': 'application/json'})

            request.setResponseCode(200)
            return self.to_bytes('')

        except MissingParameterException as e:
            return BadRequestErrorPage(str(e)).render(request)

        except InvalidCommandException as e:
            return BadRequestErrorPage(str(e)).render(request)
Beispiel #32
0
    def finish(self):

        Request.finish(self)

        host = self.getHost()

        if self.hydrus_response_context is not None:

            status_text = str(self.hydrus_response_context.GetStatusCode())

        elif hasattr(self, 'code'):

            status_text = str(self.code)

        else:

            status_text = '200'

        message = str(host.port) + ' ' + str(self.method, 'utf-8') + ' ' + str(
            self.path, 'utf-8'
        ) + ' ' + status_text + ' in ' + HydrusData.TimeDeltaToPrettyTimeDelta(
            time.clock() - self.start_time)

        HydrusData.Print(message)
Beispiel #33
0
    async def on_GET(self, request: Request) -> Tuple[int, JsonDict]:
        if not self.hs.config.registration.enable_registration:
            raise SynapseError(403,
                               "Registration has been disabled",
                               errcode=Codes.FORBIDDEN)

        ip = request.getClientIP()
        with self.ratelimiter.ratelimit(ip) as wait_deferred:
            await wait_deferred

            username = parse_string(request, "username", required=True)

            await self.registration_handler.check_username(username)

            return 200, {"available": True}
Beispiel #34
0
    def connectionLost(self, reason):
        """Called when the client connection is closed before the response is written.

        Overrides twisted.web.server.Request.connectionLost to record the finish time and
        do logging.
        """
        self.finish_time = time.time()
        Request.connectionLost(self, reason)

        # we only get here if the connection to the client drops before we send
        # the response.
        #
        # It's useful to log it here so that we can get an idea of when
        # the client disconnects.
        with PreserveLoggingContext(self.logcontext):
            logger.warn(
                "Error processing request %r: %s %s",
                self,
                reason.type,
                reason.value,
            )

            if not self._is_processing:
                self._finished_processing()
Beispiel #35
0
 def test_renderRealRequest(self):
     """
     The request managed by L{WebSocketsResource.render} doesn't contain
     unnecessary HTTP headers like I{Content-Type}.
     """
     channel = DummyChannel()
     channel.transport = StringTransportWithDisconnection()
     channel.transport.protocol = channel
     request = Request(channel, False)
     headers = {
         b"upgrade": b"Websocket",
         b"connection": b"Upgrade",
         b"sec-websocket-key": b"secure",
         b"sec-websocket-version": b"13",
         b"user-agent": b"user-agent",
         b"client": b"client",
         b"host": b"host"
     }
     for key, value in headers.items():
         request.requestHeaders.setRawHeaders(key, [value])
     request.method = b"GET"
     request.clientproto = b"HTTP/1.1"
     request.client = IPv6Address('TCP', 'fe80::1', '80')
     result = self.resource.render(request)
     self.assertEqual(NOT_DONE_YET, result)
     self.assertEqual(
         [(b"Connection", [b"Upgrade"]),
          (b"Sec-Websocket-Accept", [b"oYBv54i42V5dw6KnZqOFroecUTc="]),
          (b"Upgrade", [b"WebSocket"])],
         sorted(request.responseHeaders.getAllRawHeaders()))
     self.assertThat(
         channel.transport.value(),
         StartsWith(b"HTTP/1.1 101 Switching Protocols\r\n"
                    b"Transfer-Encoding: chunked\r\n"))
     self.assertEqual(101, request.code)
     self.assertIdentical(None, request.transport)
Beispiel #36
0
    def test_updateSession(self):
        session = self.site.makeSession()

        class FakeChannel:
            transport = None

            def isSecure(self):
                return False

            def getPeer(self):
                return None

            def getHost(self):
                return None

        request = Request(FakeChannel(), False)
        request.sitepath = [b"bb"]
        session.updateSession(request)
        self.assertEqual(len(request.cookies), 1)
        name, value = request.cookies[0].split(b";")[0].split(b"=")
        decoded = jwt.decode(value, self.SECRET,
                             algorithms=[service.SESSION_SECRET_ALGORITHM])
        self.assertEqual(decoded['user_info'], {'anonymous': True})
        self.assertIn('exp', decoded)
Beispiel #37
0
    def processingFailed(self, reason):
        if self.is_ajax():
            log.err(reason)
            if self.site.displayTracebacks:
                body = reason.getTraceback()
            else:
                body = b"Processing Failed"

            self.setResponseCode(http.INTERNAL_SERVER_ERROR)
            self.setHeader(b'content-type', b"text/plain")
            self.setHeader(b'content-length', intToBytes(len(body)))
            self.write(body)
            self.finish()
            return reason

        return WebRequest.processingFailed(self, reason)
Beispiel #38
0
    def render_GET(self, request: Request) -> bytes:
        set_cors_headers(request)
        r = self._well_known_builder.get_well_known()
        if not r:
            request.setResponseCode(404)
            request.setHeader(b"Content-Type", b"text/plain")
            return b".well-known not available"

        logger.debug("returning: %s", r)
        request.setHeader(b"Content-Type", b"application/json")
        return json_encoder.encode(r).encode("utf-8")
Beispiel #39
0
    def finish(self):
        rv = Request.finish(self)

        # Some requests, like those for static files, don't have store
        store = getattr(self, 'store', None)
        if store:
            # Roll back and then commit, so that no transaction
            # is left open between requests.
            store.rollback()
            store.commit()

            # Some use cases involve setting store.request in
            # getRequestStore, so remove request.store here to
            # avoid a circular reference GC.
            del self.store

        return rv
Beispiel #40
0
    def getChildWithDefault(self, name: bytes,
                            request: TwistedRequest) -> IResource:
        # Prevent leaking sandbox key to external sites.
        request.setHeader(b'Referrer-Policy', b'origin-when-cross-origin')
        # Repeat sandbox rules, in case artifact is viewed outside iframe.
        request.setHeader(b'Content-Security-Policy',
                          b'sandbox %s;' % SANDBOX_RULES.encode())

        origin = request.getHeader(b'Origin')

        # Handle anonymous guest access.
        if name == b'anon' and self.project.anonguest:
            if origin is not None:
                request.setHeader(b'Access-Control-Allow-Origin', b'*')
            return SandboxedResource(self.baseDir, ())

        # Verify that request came from null origin.
        if origin is not None:
            if origin == b'null':
                request.setHeader(b'Access-Control-Allow-Origin', b'null')
            else:
                return AccessDeniedResource(
                    'Sandboxed content requested from non-null origin')

        try:
            key = name.decode('ascii')
        except UnicodeDecodeError:
            return ClientErrorResource('Key contains invalid characters')

        try:
            path = self._activeKeys[key]
        except KeyError:
            # Key does not exist or is no longer valid.
            # Redirect to non-sandboxed path to acquire new key.
            return Redirect(b'/'.join([b'..'] * (len(request.postpath) + 1) +
                                      request.postpath))
        else:
            return SandboxedResource(self.baseDir, path.path)
Beispiel #41
0
    def process(self):
        # get upgrade headers and switch them to lower case
        upgrade_headers = self.requestHeaders.getRawHeaders("Upgrade") or []
        upgrade_headers = [h.lower() for h in upgrade_headers]

        connection_headers = self.requestHeaders.getRawHeaders(
            "Connection") or []
        # get all connection_headers, split each at ',',
        # join into a single list and switch them to lower case
        connection_headers = itertools.chain(
            *[re.split(r',\s*', h) for h in connection_headers])
        connection_headers = [h.lower() for h in connection_headers]

        if ("websocket" in upgrade_headers
                and "upgrade" in connection_headers):
            return self.processWebSocket()
        else:
            return Request.process(self)
    async def async_render_POST(self, request: Request):
        # make sure that there is a valid mapping session, to stop people dictionary-
        # scanning for accounts
        session_id = request.getCookie(SESSION_COOKIE_NAME)
        if not session_id:
            _return_json({"error": "missing session_id"}, request)
            return

        session_id = session_id.decode("ascii", errors="replace")
        session = get_mapping_session(session_id)
        if not session:
            logger.info("Couldn't find session id %s", session_id)
            _return_json({"error": "unknown session"}, request)
            return

        if b"username" not in request.args:
            _return_json({"error": "missing username"}, request)
            return
        localpart = request.args[b"username"][0].decode("utf-8",
                                                        errors="replace")

        if b"password" not in request.args:
            _return_json({"error": "missing password"}, request)
            return
        password = request.args[b"password"][0].decode("utf-8",
                                                       errors="replace")

        if localpart.startswith("@"):
            uid = localpart
        else:
            uid = UserID(localpart, self._module_api._hs.hostname).to_string()

        success = False
        try:
            passwd_response = await self._module_api._auth_handler._check_local_password(
                uid, password)
            if passwd_response == uid:
                success = True
        except Exception as e:
            logger.warning("Error checking credentials of %s: %s %s" %
                           (localpart, type(e), e))

        response = {"success": success}
        _return_json(response, request)
Beispiel #43
0
def tokenFromRequest(request: Request) -> Optional[str]:
    """Extract token from header of query parameter.

    :param request: The request to look for an access token in.

    :return: The token or None if not found
    """
    token = None
    # check for Authorization header first
    authHeader = request.getHeader("Authorization")
    if authHeader is not None and authHeader.startswith("Bearer "):
        token = authHeader[len("Bearer "):]

    # no? try access_token query param
    if token is None:
        args = get_args(request, ("access_token", ), required=False)
        token = args.get("access_token")

    return token
Beispiel #44
0
def respond_with_json(
    request: Request,
    code: int,
    json_object: Any,
    send_cors: bool = False,
    pretty_print: bool = False,
    canonical_json: bool = True,
):
    """Sends encoded JSON in response to the given request.

    Args:
        request: The http request to respond to.
        code: The HTTP response code.
        json_object: The object to serialize to JSON.
        send_cors: Whether to send Cross-Origin Resource Sharing headers
            https://fetch.spec.whatwg.org/#http-cors-protocol
        pretty_print: Whether to include indentation and line-breaks in the
            resulting JSON bytes.
        canonical_json: Whether to use the canonicaljson algorithm when encoding
            the JSON bytes.

    Returns:
        twisted.web.server.NOT_DONE_YET if the request is still active.
    """
    # could alternatively use request.notifyFinish() and flip a flag when
    # the Deferred fires, but since the flag is RIGHT THERE it seems like
    # a waste.
    if request._disconnected:
        logger.warning(
            "Not sending response to request %s, already disconnected.",
            request)
        return None

    if pretty_print:
        encoder = iterencode_pretty_printed_json
    else:
        if canonical_json or synapse.events.USE_FROZEN_DICTS:
            encoder = iterencode_canonical_json
        else:
            encoder = _encode_json_bytes

    request.setResponseCode(code)
    request.setHeader(b"Content-Type", b"application/json")
    request.setHeader(b"Cache-Control", b"no-cache, no-store, must-revalidate")

    if send_cors:
        set_cors_headers(request)

    _ByteProducer(request, encoder(json_object))
    return NOT_DONE_YET
Beispiel #45
0
 def render_GET(self, request: TwistedRequest) -> object:
     presenter = self.presenter
     depth = len(request.prepath) - 1
     styleURL = '../' * depth + styleRoot.relativeURL
     request.write(b'<!DOCTYPE html>\n')
     request.write(xhtml.html[
         xhtml.head[fixedHeadItems,
                    presenter.headItems(),
                    xhtml.title[f'Report: {self.fileName}']].present(
                        styleURL=styleURL),
         xhtml.body[xhtml.div(class_='body')[presenter.presentBody()]]].
                   flattenXML().encode())
     request.finish()
     return NOT_DONE_YET
Beispiel #46
0
def set_cors_headers(request: Request):
    """Set the CORS headers so that javascript running in a web browsers can
    use this API

    Args:
        request: The http request to add CORS to.
    """
    request.setHeader(b"Access-Control-Allow-Origin", b"*")
    request.setHeader(b"Access-Control-Allow-Methods",
                      b"GET, HEAD, POST, PUT, DELETE, OPTIONS")
    request.setHeader(
        b"Access-Control-Allow-Headers",
        b"Origin, X-Requested-With, Content-Type, Accept, Authorization, Date",
    )
Beispiel #47
0
    def process(self):
        if self._fallbackToBuffered:
            return Request.process(self)

        # streaming mode
        # pause producing on channel until we know what resource
        # we deal with
        self.channel.transport.pauseProducing()
        self.site = self.channel.site

        self.setHeader('server', version)
        self.setHeader('date', datetimeToString())

        self.prepath = []
        self.postpath = map(unquote, string.split(self.path[1:], '/'))

        try:
            self.processResource(self.site.getResourceFor(self))
        except:
            self.processingFailed(failure.Failure())
Beispiel #48
0
def respond_with_json_bytes(
    request: Request,
    code: int,
    json_bytes: bytes,
    send_cors: bool = False,
):
    """Sends encoded JSON in response to the given request.

    Args:
        request: The http request to respond to.
        code: The HTTP response code.
        json_bytes: The json bytes to use as the response body.
        send_cors: Whether to send Cross-Origin Resource Sharing headers
            https://fetch.spec.whatwg.org/#http-cors-protocol

    Returns:
        twisted.web.server.NOT_DONE_YET if the request is still active.
    """
    if request._disconnected:
        logger.warning(
            "Not sending response to request %s, already disconnected.",
            request)
        return

    request.setResponseCode(code)
    request.setHeader(b"Content-Type", b"application/json")
    request.setHeader(b"Content-Length", b"%d" % (len(json_bytes), ))
    request.setHeader(b"Cache-Control", b"no-cache, no-store, must-revalidate")

    if send_cors:
        set_cors_headers(request)

    # note that this is zero-copy (the bytesio shares a copy-on-write buffer with
    # the original `bytes`).
    bytes_io = BytesIO(json_bytes)

    producer = NoRangeStaticProducer(request, bytes_io)
    producer.start()
    return NOT_DONE_YET
Beispiel #49
0
    def getClientIP(self, **kwargs):
        """Override base getClientIP to be X-Real-IP aware.
        
        Arguments:
        
            honor_xrealip (bool)(optional) - (If present, overrides the default
                                              for honor_xrealip specified in the config file.)
                                             
                                             Whether or not to prefer the value of
                                             the X-Real-IP header if present.
        """
        if kwargs.has_key("honor_xrealip"):
            honor_xrealip = kwargs["honor_xrealip"]
        else:
            honor_xrealip = self.site.honor_xrealip

        if honor_xrealip and self.getHeader("X-Real-IP"):
            return self.getHeader("X-Real-IP")

        return Request.getClientIP(self)
Beispiel #50
0
    def render_GET(self, request: Request):  # $ requestHandler
        request.addCookie(
            "key",
            "value")  # $ CookieWrite CookieName="key" CookieValue="value"
        request.addCookie(
            k="key",
            v="value")  # $ CookieWrite CookieName="key" CookieValue="value"
        val = "key2=value"
        request.cookies.append(val)  # $ CookieWrite CookieRawHeader=val

        request.responseHeaders.addRawHeader("key", "value")
        request.setHeader(
            "Set-Cookie", "key3=value3"
        )  # $ MISSING: CookieWrite CookieRawHeader="key3=value3"

        return b""  # $ HttpResponse mimetype=text/html responseBody=b""
Beispiel #51
0
def respond_with_json_bytes(
    request: Request,
    code: int,
    json_bytes: bytes,
    send_cors: bool = False,
) -> Optional[int]:
    """Sends encoded JSON in response to the given request.

    Args:
        request: The http request to respond to.
        code: The HTTP response code.
        json_bytes: The json bytes to use as the response body.
        send_cors: Whether to send Cross-Origin Resource Sharing headers
            https://fetch.spec.whatwg.org/#http-cors-protocol

    Returns:
        twisted.web.server.NOT_DONE_YET if the request is still active.
    """
    # The response code must always be set, for logging purposes.
    request.setResponseCode(code)

    if request._disconnected:
        logger.warning(
            "Not sending response to request %s, already disconnected.",
            request)
        return None

    request.setHeader(b"Content-Type", b"application/json")
    request.setHeader(b"Content-Length", b"%d" % (len(json_bytes), ))
    request.setHeader(b"Cache-Control", b"no-cache, no-store, must-revalidate")

    if send_cors:
        set_cors_headers(request)

    _write_bytes_to_request(request, json_bytes)
    return NOT_DONE_YET
Beispiel #52
0
    def render_GET(self, request: TwistedRequest) -> object:
        path = self.path

        contentType, contentEncoding = guess_type(path.basename(),
                                                  strict=False)
        if contentType is None:
            contentType = 'application/octet-stream'
        elif contentType.startswith('text/'):
            # Encoding autodetection in browsers is pretty poor, so we're
            # likely better off forcing UTF-8. Most gzipped text files are
            # logs and we tell the wrappers to output in UTF-8.
            # TODO: Perform an encoding detection on upload, or just preserve
            #       the Content-Type header of the PUT request, if present.
            # TODO: Convert to UTF-8 if the user agent requests it using
            #       the Accept-Charset header. MDN says modern browsers omit
            #       this header, but a non-browser client could set it to
            #       indicate it is only willing to deal with UTF-8.
            #       If no particular encoding is requested, just serve the
            #       file as it was uploaded.
            contentType += '; charset=UTF-8'
        request.setHeader(b'Content-Type', contentType.encode())
        request.setHeader(b'Content-Disposition', b'inline')

        # Serve data in compressed form if user agent accepts it.
        if contentEncoding is None:
            decompress = False
        else:
            accept = AcceptedEncodings.parse(
                request.getHeader('accept-encoding'))
            decompress = 4.0 * accept[contentEncoding] < accept['identity']
            if not decompress:
                request.setHeader('Content-Encoding', contentEncoding)
        if decompress:
            # Note: Passing 'fileobj' to GzipFile appears more elegant,
            #       but that stream isn't closed when GzipFile is closed.
            stream = openGzip(path.path)
        else:
            stream = path.open()

        FileProducer.servePlain(stream, request)
        return NOT_DONE_YET
Beispiel #53
0
 def processingFailed(self, reason):
     if DEBUG:
         return Request.processingFailed(self, reason)
     else:
         if issubclass(reason.type, YuzukiException):
             exc = reason.value
             self.logger.warning(reason)
             self.setResponseCode(exc.status)
             body = generate_error_message(self, exc.status, exc.message)
         else:
             self.logger.error(reason)
             self.setResponseCode(INTERNAL_SERVER_ERROR)
             body = generate_error_message(self, INTERNAL_SERVER_ERROR,
                                           u"서버 에러가 발생하였습니다.")
         if issubclass(reason.type, SQLAlchemyError):
             YuzukiRequest.dbsession.close()
             YuzukiRequest.dbsession = DatabaseHelper.session()
         body = body.encode("UTF-8")
         self.setHeader(b'content-type', b"text/html")
         self.setHeader(b'content-length', intToBytes(len(body)))
         self.write(body)
         self.finish()
         return reason
Beispiel #54
0
    def render_OPTIONS(self, request: TwistedRequest) -> bytes:
        # Generic HTTP options.
        request.setHeader(b'Allow', b'GET, HEAD, OPTIONS')

        # CORS options.
        origin = request.getHeader(b'Origin')
        if origin is not None:
            # Grant all requested headers.
            requestedHeaders = request.getHeader(
                b'Access-Control-Request-Headers') or b''
            request.setHeader(b'Access-Control-Allow-Headers',
                              requestedHeaders)

            # The information returned does not expire, but the sanboxed URL
            # to which it applies does, so caching it beyond the sanbox key
            # timeout is pointless.
            request.setHeader(b'Access-Control-Max-Age',
                              b'%d' % ArtifactSandbox.keyTimeout)

        # Reply without content.
        request.setResponseCode(204)
        request.setHeader(b'Content-Length', b'0')
        return b''
Beispiel #55
0
def fix_twisted_web_http_Request():
    """Fix broken IPv6 handling in twisted.web.http.request.Request."""
    from netaddr import IPAddress
    from netaddr.core import AddrFormatError
    from twisted.internet import address
    from twisted.python.compat import intToBytes, networkString
    import twisted.web.http
    from twisted.web.server import Request
    from twisted.web.test.requesthelper import DummyChannel

    def new_getRequestHostname(self):
        # Unlike upstream, support/require IPv6 addresses to be
        # [ip:v6:add:ress]:port, with :port being optional.
        # IPv6 IP addresses are wrapped in [], to disambigate port numbers.
        host = self.getHeader(b"host")
        if host:
            if host.startswith(b"[") and b"]" in host:
                if host.find(b"]") < host.rfind(b":"):
                    # The format is: [ip:add:ress]:port.
                    return host[:host.rfind(b":")]
                else:
                    # no :port after [...]
                    return host
            # No brackets, so it must be host:port or IPv4:port.
            return host.split(b":", 1)[0]
        host = self.getHost().host
        try:
            if isinstance(host, str):
                ip = IPAddress(host)
            else:
                ip = IPAddress(host.decode("idna"))
        except AddrFormatError:
            # If we could not convert the hostname to an IPAddress, assume that
            # it is a hostname.
            return networkString(host)
        if ip.version == 4:
            return networkString(host)
        else:
            return networkString("[" + host + "]")

    def new_setHost(self, host, port, ssl=0):
        try:
            ip = IPAddress(host.decode("idna"))
        except AddrFormatError:
            ip = None  # `host` is a host or domain name.
        self._forceSSL = ssl  # set first so isSecure will work
        if self.isSecure():
            default = 443
        else:
            default = 80
        if ip is None:
            hostHeader = host
        elif ip.version == 4:
            hostHeader = host
        else:
            hostHeader = b"[" + host + b"]"
        if port != default:
            hostHeader += b":" + intToBytes(port)
        self.requestHeaders.setRawHeaders(b"host", [hostHeader])
        if ip is None:
            # Pretend that a host or domain name is an IPv4 address.
            self.host = address.IPv4Address("TCP", host, port)
        elif ip.version == 4:
            self.host = address.IPv4Address("TCP", host, port)
        else:
            self.host = address.IPv6Address("TCP", host, port)

    request = Request(DummyChannel(), False)
    request.client = address.IPv6Address("TCP", "fe80::1", "80")
    request.setHost(b"fe80::1", 1234)
    if isinstance(request.host, address.IPv4Address):
        # Buggy code calls fe80::1 an IPv4Address.
        twisted.web.http.Request.setHost = new_setHost
    if request.getRequestHostname() == b"fe80":
        # The fe80::1 test address above was incorrectly interpreted as
        # address='fe80', port = ':1', because it does host.split(':', 1)[0].
        twisted.web.http.Request.getRequestHostname = new_getRequestHostname
Beispiel #56
0
    def get_user_by_req(
        self,
        request: Request,
        allow_guest: bool = False,
        rights: str = "access",
        allow_expired: bool = False,
    ):
        """ Get a registered user's ID.

        Args:
            request: An HTTP request with an access_token query parameter.
            allow_guest: If False, will raise an AuthError if the user making the
                request is a guest.
            rights: The operation being performed; the access token must allow this
            allow_expired: If True, allow the request through even if the account
                is expired, or session token lifetime has ended. Note that
                /login will deliver access tokens regardless of expiration.

        Returns:
            defer.Deferred: resolves to a `synapse.types.Requester` object
        Raises:
            InvalidClientCredentialsError if no user by that token exists or the token
                is invalid.
            AuthError if access is denied for the user in the access token
        """
        try:
            ip_addr = self.hs.get_ip_from_request(request)
            user_agent = request.requestHeaders.getRawHeaders(
                b"User-Agent",
                default=[b""])[0].decode("ascii", "surrogateescape")

            access_token = self.get_access_token_from_request(request)

            user_id, app_service = yield self._get_appservice_user_id(request)
            if user_id:
                request.authenticated_entity = user_id
                opentracing.set_tag("authenticated_entity", user_id)
                opentracing.set_tag("appservice_id", app_service.id)

                if ip_addr and self._track_appservice_user_ips:
                    yield self.store.insert_client_ip(
                        user_id=user_id,
                        access_token=access_token,
                        ip=ip_addr,
                        user_agent=user_agent,
                        device_id="dummy-device",  # stubbed
                    )

                return synapse.types.create_requester(user_id,
                                                      app_service=app_service)

            user_info = yield self.get_user_by_access_token(
                access_token, rights, allow_expired=allow_expired)
            user = user_info["user"]
            token_id = user_info["token_id"]
            is_guest = user_info["is_guest"]

            # Deny the request if the user account has expired.
            if self._account_validity.enabled and not allow_expired:
                user_id = user.to_string()
                expiration_ts = yield self.store.get_expiration_ts_for_user(
                    user_id)
                if (expiration_ts is not None
                        and self.clock.time_msec() >= expiration_ts):
                    raise AuthError(403,
                                    "User account has expired",
                                    errcode=Codes.EXPIRED_ACCOUNT)

            # device_id may not be present if get_user_by_access_token has been
            # stubbed out.
            device_id = user_info.get("device_id")

            if user and access_token and ip_addr:
                yield self.store.insert_client_ip(
                    user_id=user.to_string(),
                    access_token=access_token,
                    ip=ip_addr,
                    user_agent=user_agent,
                    device_id=device_id,
                )

            if is_guest and not allow_guest:
                raise AuthError(
                    403,
                    "Guest access not allowed",
                    errcode=Codes.GUEST_ACCESS_FORBIDDEN,
                )

            request.authenticated_entity = user.to_string()
            opentracing.set_tag("authenticated_entity", user.to_string())
            if device_id:
                opentracing.set_tag("device_id", device_id)

            return synapse.types.create_requester(user,
                                                  token_id,
                                                  is_guest,
                                                  device_id,
                                                  app_service=app_service)
        except KeyError:
            raise MissingClientTokenError()
Beispiel #57
0
 def test_absentServerHeader(self):
     request = Request(FakeChannel(), False)
     self.assertEqual(request.responseHeaders.hasHeader('Server'), False)
Beispiel #58
0
 def render(self, request: Request):  # $ requestHandler
     request.write(
         b"also now"
     )  # $ HttpResponse mimetype=text/html responseBody=b"also now"
     return b""  # $ HttpResponse mimetype=text/html responseBody=b""
Beispiel #59
0
def process_later(request: Request):
    print("process_later called")
    request.write(b"later")  # $ MISSING: responseBody=b"later"
    request.finish()
Beispiel #60
0
 def render(self, request: Request):  # $ requestHandler
     request.setHeader(b"content-type", "text/plain")
     return b"this is plain text"  # $ HttpResponse responseBody=b"this is plain text" SPURIOUS: mimetype=text/html MISSING: mimetype=text/plain