Esempio n. 1
0
    def handle_request(
        self,
        method: bytes,
        url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes],
        headers: typing.List[typing.Tuple[bytes, bytes]],
        stream: typing.Iterable[bytes],
        extensions: dict,
    ) -> typing.Tuple[int, typing.List[typing.Tuple[bytes, bytes]],
                      typing.Iterable[bytes], dict]:
        with map_httpcore_exceptions():
            status_code, headers, byte_stream, extensions = self._pool.request(
                method=method,
                url=url,
                headers=headers,
                stream=httpcore.IteratorByteStream(iter(stream)),
                ext=extensions,
            )

        def response_stream() -> typing.Iterator[bytes]:
            with map_httpcore_exceptions():
                for part in byte_stream:
                    yield part

        def close() -> None:
            with map_httpcore_exceptions():
                byte_stream.close()

        ensure_http_version_reason_phrase_as_bytes(extensions)
        extensions["close"] = close

        return status_code, headers, response_stream(), extensions
Esempio n. 2
0
 def request(
     self,
     method: bytes,
     url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes],
     headers: typing.List[typing.Tuple[bytes, bytes]] = None,
     stream: httpcore.SyncByteStream = None,
     timeout: typing.Mapping[str, typing.Optional[float]] = None,
 ) -> typing.Tuple[bytes, int, bytes, typing.List[typing.Tuple[
         bytes, bytes]], httpcore.SyncByteStream, ]:
     assert stream is not None
     content = httpcore.IteratorByteStream(iterator=(part
                                                     for part in stream))
     return b"HTTP/1.1", 200, b"OK", [], content
Esempio n. 3
0
    def handle_request(
        self,
        method: bytes,
        url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes],
        headers: typing.List[typing.Tuple[bytes, bytes]],
        stream: SyncByteStream,
        extensions: dict,
    ) -> typing.Tuple[int, typing.List[typing.Tuple[bytes, bytes]],
                      SyncByteStream, dict]:
        with map_httpcore_exceptions():
            status_code, headers, byte_stream, extensions = self._pool.handle_request(
                method=method,
                url=url,
                headers=headers,
                stream=httpcore.IteratorByteStream(iter(stream)),
                extensions=extensions,
            )

        stream = ResponseStream(byte_stream)

        return status_code, headers, stream, extensions
Esempio n. 4
0
    def request(
        self,
        method: bytes,
        url: URL,
        headers: Headers = None,
        stream: httpcore.SyncByteStream = None,
        ext: dict = None,
    ) -> Tuple[int, Headers, httpcore.SyncByteStream, dict]:
        self.state = ConnectionState.ACTIVE
        self.stream_count += 1

        def on_close():
            self.stream_count -= 1
            if self.stream_count == 0:
                self.state = ConnectionState.IDLE

        def iterator() -> Iterator[bytes]:
            yield b""

        stream = httpcore.IteratorByteStream(iterator=iterator(),
                                             close_func=on_close)

        return 200, [], stream, {}
Esempio n. 5
0
    def request(
        self,
        method: bytes,
        url: typing.Tuple[bytes, bytes, typing.Optional[int], bytes],
        headers: typing.List[typing.Tuple[bytes, bytes]] = None,
        stream: httpcore.SyncByteStream = None,
        ext: dict = None,
    ) -> typing.Tuple[
        int, typing.List[typing.Tuple[bytes, bytes]], httpcore.SyncByteStream, dict
    ]:
        headers = [] if headers is None else headers
        stream = httpcore.PlainByteStream(content=b"") if stream is None else stream

        scheme, host, port, full_path = url
        path, _, query = full_path.partition(b"?")
        environ = {
            "wsgi.version": (1, 0),
            "wsgi.url_scheme": scheme.decode("ascii"),
            "wsgi.input": io.BytesIO(b"".join(stream)),
            "wsgi.errors": io.BytesIO(),
            "wsgi.multithread": True,
            "wsgi.multiprocess": False,
            "wsgi.run_once": False,
            "REQUEST_METHOD": method.decode(),
            "SCRIPT_NAME": self.script_name,
            "PATH_INFO": unquote(path.decode("ascii")),
            "QUERY_STRING": query.decode("ascii"),
            "SERVER_NAME": host.decode("ascii"),
            "SERVER_PORT": str(port),
            "REMOTE_ADDR": self.remote_addr,
        }
        for header_key, header_value in headers:
            key = header_key.decode("ascii").upper().replace("-", "_")
            if key not in ("CONTENT_TYPE", "CONTENT_LENGTH"):
                key = "HTTP_" + key
            environ[key] = header_value.decode("ascii")

        seen_status = None
        seen_response_headers = None
        seen_exc_info = None

        def start_response(
            status: str, response_headers: list, exc_info: typing.Any = None
        ) -> None:
            nonlocal seen_status, seen_response_headers, seen_exc_info
            seen_status = status
            seen_response_headers = response_headers
            seen_exc_info = exc_info

        result = self.app(environ, start_response)
        # This is needed because the status returned by start_response
        # shouldn't be used until the first non-empty chunk has been served.
        result = _skip_leading_empty_chunks(result)

        assert seen_status is not None
        assert seen_response_headers is not None
        if seen_exc_info and self.raise_app_exceptions:
            raise seen_exc_info[1]

        status_code = int(seen_status.split()[0])
        headers = [
            (key.encode("ascii"), value.encode("ascii"))
            for key, value in seen_response_headers
        ]
        stream = httpcore.IteratorByteStream(iterator=result)
        ext = {}

        return (status_code, headers, stream, ext)