Пример #1
0
    def test__get_response_restores_files_across_requests(self):
        handler = views.WebApplicationHandler(3)
        file_content = sample_binary_data
        file_name = 'content'

        recorder = []

        def get_response_read_content_files(self, request):
            # Simple get_response method which returns the 'file_name' file
            # from the request in the response.
            content = request.FILES[file_name].read()
            # Record calls.
            recorder.append(content)
            response = HttpResponse(content=content,
                                    content_type=b"text/plain; charset=utf-8")
            handler._WebApplicationHandler__retry.add(response)
            return response

        self.patch(WSGIHandler, "get_response",
                   get_response_read_content_files)

        body, headers = encode_multipart_data(
            [], [[file_name, io.BytesIO(file_content)]])
        env = {
            'REQUEST_METHOD': 'POST',
            'wsgi.input': wsgi._InputStream(io.BytesIO(body.encode("utf-8"))),
            'CONTENT_TYPE': headers['Content-Type'],
            'CONTENT_LENGTH': headers['Content-Length'],
            'HTTP_MIME_VERSION': headers['MIME-Version'],
        }
        request = make_request(env)

        response = handler.get_response(request)
        self.assertEqual(file_content, response.content)
        self.assertEqual(recorder, [file_content] * 3)
Пример #2
0
def make_request(env=None, oauth_env=None, missing_oauth_param=None):
    # Return a minimal WSGIRequest.
    if oauth_env is None:
        oauth_env = {}
    base_env = {
        "REQUEST_METHOD":
        "GET",
        "wsgi.input":
        wsgi._InputStream(io.BytesIO()),
        "SERVER_NAME":
        "server",
        "SERVER_PORT":
        80,
        "HTTP_AUTHORIZATION":
        factory.make_oauth_header(missing_param=missing_oauth_param,
                                  **oauth_env),
    }
    if env is not None:
        base_env.update(env)
    request = WSGIRequest(base_env)
    return request
Пример #3
0
    def gotMessage(self, payload, topic):  # noqa
        message = pickle.loads(payload)

        now = time.time()
        deferred_guards = []
        for guard, settings in (message.get("guards") or {}).items():
            if guard in self._guards and now < self._guards[guard]["expires"]:
                if set(settings["tokens"]) & set(
                        self._guards[guard]["tokens"]):
                    continue  # OK and continue to check the next guard
                else:
                    return  # Forbidden (according to cached guard)

            environ = deepcopy(self._environ)
            environ["REQUEST_METHOD"] = "GET"
            environ["PATH_INFO"] = settings["method"]
            environ["wsgi.errors"] = _ErrorStream()
            environ["wsgi.input"] = _InputStream(BytesIO(b""))

            # DeferredLock should is used to limit to only ever use single working
            # thread for guard checks
            call = Deferred()
            WS_GUARD_CALL_MUTEX.acquire(
            ).addCallback(lambda _, d=call: threads.deferToThread(
                self._publish_module,
                environ,
                lambda *args: None,
                _request_factory=WebSocketRequest,
            ).addBoth(lambda _: [WS_GUARD_CALL_MUTEX.release(),
                                 d.callback(_)]))
            deferred_guards.append(call)

        if deferred_guards:
            dl = DeferredList(deferred_guards)
            dl.addCallback(
                lambda result: self.gotMessageFinished(message, result))
        else:
            super(PubSubServerProtocol, self).sendMessage(message["payload"],
                                                          isBinary=False)
Пример #4
0
def make_environ(request):
    if request.prepath:
        script_name = b"/" + b"/".join(request.prepath)
    else:
        script_name = b""

    if request.postpath:
        path_info = b"/" + b"/".join(request.postpath)
    else:
        path_info = b""

    parts = request.uri.split(b"?", 1)
    if len(parts) == 1:
        query_string = b""
    else:
        query_string = parts[1]

    # All keys and values need to be native strings, i.e. of type str in
    # *both* Python 2 and Python 3, so says PEP-3333.
    environ = {
        "REQUEST_METHOD":
        _wsgiString(request.method),
        "REMOTE_ADDR":
        _wsgiString(request.getClientAddress().host),
        "SCRIPT_NAME":
        _wsgiString(script_name),
        "PATH_INFO":
        _wsgiString(path_info),
        "QUERY_STRING":
        _wsgiString(query_string),
        "CONTENT_TYPE":
        _wsgiString(request.getHeader(b"content-type") or ""),
        "CONTENT_LENGTH":
        _wsgiString(request.getHeader(b"content-length") or ""),
        "HTTPS":
        request.isSecure() and '1' or False,
        "SERVER_NAME":
        _wsgiString(request.getRequestHostname()),
        "SERVER_PORT":
        _wsgiString(str(request.getHost().port)),
        "SERVER_PROTOCOL":
        _wsgiString(request.clientproto),
        "SERVER_SOFTWARE":
        "Zope/%s ZServer/%s %s" %
        (ZOPE_VERSION, ZSERVER_VERSION, version.decode("utf-8")),
    }

    # The application object is entirely in control of response headers;
    # disable the default Content-Type value normally provided by
    # twisted.web.server.Request.
    request.defaultContentType = None

    for name, values in request.requestHeaders.getAllRawHeaders():
        name = "HTTP_" + _wsgiString(name).upper().replace("-", "_")
        # It might be preferable for http.HTTPChannel to clear out
        # newlines.
        environ[name] = ",".join(_wsgiString(v)
                                 for v in values).replace("\n", " ")

    environ.update({
        "wsgi.version": (1, 0),
        "wsgi.url_scheme": request.isSecure() and "https" or "http",
        "wsgi.run_once": False,
        "wsgi.multithread": True,
        "wsgi.multiprocess": False,
        "wsgi.errors": _ErrorStream(),
        # Attend: request.content was owned by the I/O thread up until
        # this point.  By wrapping it and putting the result into the
        # environment dictionary, it is effectively being given to
        # another thread.  This means that whatever it is, it has to be
        # safe to access it from two different threads.  The access
        # *should* all be serialized (first the I/O thread writes to
        # it, then the WSGI thread reads from it, then the I/O thread
        # closes it).  However, since the request is made available to
        # arbitrary application code during resource traversal, it's
        # possible that some other code might decide to use it in the
        # I/O thread concurrently with its use in the WSGI thread.
        # More likely than not, this will break.  This seems like an
        # unlikely possibility to me, but if it is to be allowed,
        # something here needs to change. -exarkun
        "wsgi.input": _InputStream(request.content),
    })

    return environ