Ejemplo n.º 1
0
    def _request(
        self,
        method: bytes,
        url: typing.Tuple[bytes, bytes, int, bytes],
        headers: typing.List[typing.Tuple[bytes, bytes]],
        stream: ContentStream,
        timeout: typing.Mapping[str, typing.Optional[float]] = None,
    ) -> typing.Tuple[bytes, int, bytes, typing.List[typing.Tuple[
            bytes, bytes]], ContentStream]:
        scheme, host, port, path = url
        if scheme not in (b"http", b"https"):
            raise httpcore.UnsupportedProtocol(
                f"Scheme {scheme!r} not supported.")

        path, _, query = path.partition(b"?")
        if path == b"/no_redirect":
            return b"HTTP/1.1", codes.OK, b"OK", [], ByteStream(b"")

        elif path == b"/redirect_301":

            async def body():
                yield b"<a href='https://example.org/'>here</a>"

            status_code = codes.MOVED_PERMANENTLY
            headers = [(b"location", b"https://example.org/")]
            stream = AsyncIteratorStream(aiterator=body())
            return b"HTTP/1.1", status_code, b"Moved Permanently", headers, stream

        elif path == b"/redirect_302":
            status_code = codes.FOUND
            headers = [(b"location", b"https://example.org/")]
            return b"HTTP/1.1", status_code, b"Found", headers, ByteStream(b"")

        elif path == b"/redirect_303":
            status_code = codes.SEE_OTHER
            headers = [(b"location", b"https://example.org/")]
            return b"HTTP/1.1", status_code, b"See Other", headers, ByteStream(
                b"")

        elif path == b"/relative_redirect":
            status_code = codes.SEE_OTHER
            headers = [(b"location", b"/")]
            return b"HTTP/1.1", status_code, b"See Other", headers, ByteStream(
                b"")

        elif path == b"/malformed_redirect":
            status_code = codes.SEE_OTHER
            headers = [(b"location", b"https://:443/")]
            return b"HTTP/1.1", status_code, b"See Other", headers, ByteStream(
                b"")

        elif path == b"/invalid_redirect":
            status_code = codes.SEE_OTHER
            headers = [(b"location", "https://😇/".encode("utf-8"))]
            return b"HTTP/1.1", status_code, b"See Other", headers, ByteStream(
                b"")

        elif path == b"/no_scheme_redirect":
            status_code = codes.SEE_OTHER
            headers = [(b"location", b"//example.org/")]
            return b"HTTP/1.1", status_code, b"See Other", headers, ByteStream(
                b"")

        elif path == b"/multiple_redirects":
            params = parse_qs(query.decode("ascii"))
            count = int(params.get("count", "0")[0])
            redirect_count = count - 1
            code = codes.SEE_OTHER if count else codes.OK
            phrase = b"See Other" if count else b"OK"
            location = b"/multiple_redirects"
            if redirect_count:
                location += b"?count=" + str(redirect_count).encode("ascii")
            headers = [(b"location", location)] if count else []
            return b"HTTP/1.1", code, phrase, headers, ByteStream(b"")

        if path == b"/redirect_loop":
            code = codes.SEE_OTHER
            headers = [(b"location", b"/redirect_loop")]
            return b"HTTP/1.1", code, b"See Other", headers, ByteStream(b"")

        elif path == b"/cross_domain":
            code = codes.SEE_OTHER
            headers = [(b"location",
                        b"https://example.org/cross_domain_target")]
            return b"HTTP/1.1", code, b"See Other", headers, ByteStream(b"")

        elif path == b"/cross_domain_target":
            headers_dict = {
                key.decode("ascii"): value.decode("ascii")
                for key, value in headers
            }
            stream = ByteStream(json.dumps({"headers": headers_dict}).encode())
            return b"HTTP/1.1", 200, b"OK", [], stream

        elif path == b"/redirect_body":
            code = codes.PERMANENT_REDIRECT
            headers = [(b"location", b"/redirect_body_target")]
            return b"HTTP/1.1", code, b"Permanent Redirect", headers, ByteStream(
                b"")

        elif path == b"/redirect_no_body":
            code = codes.SEE_OTHER
            headers = [(b"location", b"/redirect_body_target")]
            return b"HTTP/1.1", code, b"See Other", headers, ByteStream(b"")

        elif path == b"/redirect_body_target":
            content = b"".join(stream)
            headers_dict = {
                key.decode("ascii"): value.decode("ascii")
                for key, value in headers
            }
            stream = ByteStream(
                json.dumps({
                    "body": content.decode(),
                    "headers": headers_dict
                }).encode())
            return b"HTTP/1.1", 200, b"OK", [], stream

        elif path == b"/cross_subdomain":
            host = get_header_value(headers, "host")
            if host != "www.example.org":
                headers = [(b"location",
                            b"https://www.example.org/cross_subdomain")]
                return (
                    b"HTTP/1.1",
                    codes.PERMANENT_REDIRECT,
                    b"Permanent Redirect",
                    headers,
                    ByteStream(b""),
                )
            else:
                return b"HTTP/1.1", 200, b"OK", [], ByteStream(
                    b"Hello, world!")

        elif path == b"/redirect_custom_scheme":
            status_code = codes.MOVED_PERMANENTLY
            headers = [(b"location", b"market://details?id=42")]
            return (
                b"HTTP/1.1",
                status_code,
                b"Moved Permanently",
                headers,
                ByteStream(b""),
            )

        return b"HTTP/1.1", 200, b"OK", [], ByteStream(b"Hello, world!")
Ejemplo n.º 2
0
def redirects(request: httpx.Request) -> httpx.Response:
    if request.url.scheme not in ("http", "https"):
        raise httpcore.UnsupportedProtocol(
            f"Scheme {request.url.scheme!r} not supported.")

    if request.url.path == "/no_redirect":
        return httpx.Response(200)

    elif request.url.path == "/redirect_301":
        status_code = httpx.codes.MOVED_PERMANENTLY
        content = b"<a href='https://example.org/'>here</a>"
        headers = {"location": "https://example.org/"}
        return httpx.Response(status_code, headers=headers, content=content)

    elif request.url.path == "/redirect_302":
        status_code = httpx.codes.FOUND
        headers = {"location": "https://example.org/"}
        return httpx.Response(status_code, headers=headers)

    elif request.url.path == "/redirect_303":
        status_code = httpx.codes.SEE_OTHER
        headers = {"location": "https://example.org/"}
        return httpx.Response(status_code, headers=headers)

    elif request.url.path == "/relative_redirect":
        status_code = httpx.codes.SEE_OTHER
        headers = {"location": "/"}
        return httpx.Response(status_code, headers=headers)

    elif request.url.path == "/malformed_redirect":
        status_code = httpx.codes.SEE_OTHER
        headers = {"location": "https://:443/"}
        return httpx.Response(status_code, headers=headers)

    elif request.url.path == "/invalid_redirect":
        status_code = httpx.codes.SEE_OTHER
        raw_headers = [(b"location", "https://😇/".encode("utf-8"))]
        return httpx.Response(status_code, headers=raw_headers)

    elif request.url.path == "/no_scheme_redirect":
        status_code = httpx.codes.SEE_OTHER
        headers = {"location": "//example.org/"}
        return httpx.Response(status_code, headers=headers)

    elif request.url.path == "/multiple_redirects":
        params = httpx.QueryParams(request.url.query)
        count = int(params.get("count", "0"))
        redirect_count = count - 1
        status_code = httpx.codes.SEE_OTHER if count else httpx.codes.OK
        if count:
            location = "/multiple_redirects"
            if redirect_count:
                location += f"?count={redirect_count}"
            headers = {"location": location}
        else:
            headers = {}
        return httpx.Response(status_code, headers=headers)

    if request.url.path == "/redirect_loop":
        status_code = httpx.codes.SEE_OTHER
        headers = {"location": "/redirect_loop"}
        return httpx.Response(status_code, headers=headers)

    elif request.url.path == "/cross_domain":
        status_code = httpx.codes.SEE_OTHER
        headers = {"location": "https://example.org/cross_domain_target"}
        return httpx.Response(status_code, headers=headers)

    elif request.url.path == "/cross_domain_target":
        status_code = httpx.codes.OK
        data = {
            "body": request.content.decode("ascii"),
            "headers": dict(request.headers),
        }
        return httpx.Response(status_code, json=data)

    elif request.url.path == "/redirect_body":
        status_code = httpx.codes.PERMANENT_REDIRECT
        headers = {"location": "/redirect_body_target"}
        return httpx.Response(status_code, headers=headers)

    elif request.url.path == "/redirect_no_body":
        status_code = httpx.codes.SEE_OTHER
        headers = {"location": "/redirect_body_target"}
        return httpx.Response(status_code, headers=headers)

    elif request.url.path == "/redirect_body_target":
        data = {
            "body": request.content.decode("ascii"),
            "headers": dict(request.headers),
        }
        return httpx.Response(200, json=data)

    elif request.url.path == "/cross_subdomain":
        if request.headers["Host"] != "www.example.org":
            status_code = httpx.codes.PERMANENT_REDIRECT
            headers = {"location": "https://www.example.org/cross_subdomain"}
            return httpx.Response(status_code, headers=headers)
        else:
            return httpx.Response(200, text="Hello, world!")

    elif request.url.path == "/redirect_custom_scheme":
        status_code = httpx.codes.MOVED_PERMANENTLY
        headers = {"location": "market://details?id=42"}
        return httpx.Response(status_code, headers=headers)

    if request.method == "HEAD":
        return httpx.Response(200)

    return httpx.Response(200, html="<html><body>Hello, world!</body></html>")
Ejemplo n.º 3
0
 async def arequest(self, method, url, headers=None, stream=None, ext=None):
     raise httpcore.UnsupportedProtocol("HTTP protocol is disabled")