From 77589cc6f7b0b395f29df49c767cda6d144812bc Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 16 Sep 2025 18:59:11 +0100 Subject: [PATCH 1/5] Initial commit --- .github/ISSUE_TEMPLATE/config.yml | 1 + .github/ISSUE_TEMPLATE/read-only-issues.md | 10 + .github/workflows/test-suite.yml | 28 + .gitignore | 8 + README.md | 72 ++ docs/about.md | 19 + docs/clients.md | 311 +++++++++ docs/connections.md | 245 +++++++ docs/content-types.md | 174 +++++ docs/headers.md | 54 ++ docs/img/butterfly.png | Bin 0 -> 683778 bytes docs/index.md | 112 +++ docs/networking.md | 381 +++++++++++ docs/parsers.md | 110 +++ docs/quickstart.md | 484 +++++++++++++ docs/requests.md | 178 +++++ docs/responses.md | 131 ++++ docs/servers.md | 85 +++ docs/streams.md | 88 +++ docs/templates/base.html | 186 +++++ docs/urls.md | 240 +++++++ pyproject.toml | 30 + requirements.txt | 17 + scripts/build | 32 + scripts/docs | 153 +++++ scripts/install | 13 + scripts/publish | 15 + scripts/test | 10 + scripts/unasync | 29 + src/ahttpx/__init__.py | 65 ++ src/ahttpx/__version__.py | 2 + src/ahttpx/_client.py | 156 +++++ src/ahttpx/_content.py | 378 +++++++++++ src/ahttpx/_headers.py | 243 +++++++ src/ahttpx/_network.py | 120 ++++ src/ahttpx/_parsers.py | 515 ++++++++++++++ src/ahttpx/_pool.py | 284 ++++++++ src/ahttpx/_quickstart.py | 49 ++ src/ahttpx/_request.py | 93 +++ src/ahttpx/_response.py | 158 +++++ src/ahttpx/_server.py | 126 ++++ src/ahttpx/_streams.py | 235 +++++++ src/ahttpx/_urlencode.py | 85 +++ src/ahttpx/_urlparse.py | 534 +++++++++++++++ src/ahttpx/_urls.py | 552 +++++++++++++++ src/httpx/__init__.py | 65 ++ src/httpx/__version__.py | 2 + src/httpx/_client.py | 156 +++++ src/httpx/_content.py | 378 +++++++++++ src/httpx/_headers.py | 243 +++++++ src/httpx/_network.py | 243 +++++++ src/httpx/_parsers.py | 515 ++++++++++++++ src/httpx/_pool.py | 284 ++++++++ src/httpx/_quickstart.py | 49 ++ src/httpx/_request.py | 93 +++ src/httpx/_response.py | 158 +++++ src/httpx/_server.py | 126 ++++ src/httpx/_streams.py | 235 +++++++ src/httpx/_urlencode.py | 85 +++ src/httpx/_urlparse.py | 534 +++++++++++++++ src/httpx/_urls.py | 552 +++++++++++++++ tests/__init__.py | 0 tests/test_client.py | 112 +++ tests/test_content.py | 285 ++++++++ tests/test_headers.py | 109 +++ tests/test_network.py | 101 +++ tests/test_parsers.py | 748 +++++++++++++++++++++ tests/test_pool.py | 126 ++++ tests/test_quickstart.py | 78 +++ tests/test_request.py | 79 +++ tests/test_response.py | 64 ++ tests/test_streams.py | 82 +++ tests/test_urlencode.py | 33 + tests/test_urls.py | 164 +++++ 74 files changed, 12510 insertions(+) create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/read-only-issues.md create mode 100644 .github/workflows/test-suite.yml create mode 100644 .gitignore create mode 100644 README.md create mode 100644 docs/about.md create mode 100644 docs/clients.md create mode 100644 docs/connections.md create mode 100644 docs/content-types.md create mode 100644 docs/headers.md create mode 100644 docs/img/butterfly.png create mode 100644 docs/index.md create mode 100644 docs/networking.md create mode 100644 docs/parsers.md create mode 100644 docs/quickstart.md create mode 100644 docs/requests.md create mode 100644 docs/responses.md create mode 100644 docs/servers.md create mode 100644 docs/streams.md create mode 100644 docs/templates/base.html create mode 100644 docs/urls.md create mode 100644 pyproject.toml create mode 100644 requirements.txt create mode 100755 scripts/build create mode 100755 scripts/docs create mode 100755 scripts/install create mode 100755 scripts/publish create mode 100755 scripts/test create mode 100755 scripts/unasync create mode 100644 src/ahttpx/__init__.py create mode 100644 src/ahttpx/__version__.py create mode 100644 src/ahttpx/_client.py create mode 100644 src/ahttpx/_content.py create mode 100644 src/ahttpx/_headers.py create mode 100644 src/ahttpx/_network.py create mode 100644 src/ahttpx/_parsers.py create mode 100644 src/ahttpx/_pool.py create mode 100644 src/ahttpx/_quickstart.py create mode 100644 src/ahttpx/_request.py create mode 100644 src/ahttpx/_response.py create mode 100644 src/ahttpx/_server.py create mode 100644 src/ahttpx/_streams.py create mode 100644 src/ahttpx/_urlencode.py create mode 100644 src/ahttpx/_urlparse.py create mode 100644 src/ahttpx/_urls.py create mode 100644 src/httpx/__init__.py create mode 100644 src/httpx/__version__.py create mode 100644 src/httpx/_client.py create mode 100644 src/httpx/_content.py create mode 100644 src/httpx/_headers.py create mode 100644 src/httpx/_network.py create mode 100644 src/httpx/_parsers.py create mode 100644 src/httpx/_pool.py create mode 100644 src/httpx/_quickstart.py create mode 100644 src/httpx/_request.py create mode 100644 src/httpx/_response.py create mode 100644 src/httpx/_server.py create mode 100644 src/httpx/_streams.py create mode 100644 src/httpx/_urlencode.py create mode 100644 src/httpx/_urlparse.py create mode 100644 src/httpx/_urls.py create mode 100644 tests/__init__.py create mode 100644 tests/test_client.py create mode 100644 tests/test_content.py create mode 100644 tests/test_headers.py create mode 100644 tests/test_network.py create mode 100644 tests/test_parsers.py create mode 100644 tests/test_pool.py create mode 100644 tests/test_quickstart.py create mode 100644 tests/test_request.py create mode 100644 tests/test_response.py create mode 100644 tests/test_streams.py create mode 100644 tests/test_urlencode.py create mode 100644 tests/test_urls.py diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..3ba13e0cec --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/read-only-issues.md b/.github/ISSUE_TEMPLATE/read-only-issues.md new file mode 100644 index 0000000000..2ea56183c3 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/read-only-issues.md @@ -0,0 +1,10 @@ +--- +name: Read-only issues +about: Restricted Zone ⛔️ +title: '' +labels: '' +assignees: '' + +--- + +Issues on this repository are considered read-only, and currently reserved for the maintenance team. diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml new file mode 100644 index 0000000000..7fed9368f3 --- /dev/null +++ b/.github/workflows/test-suite.yml @@ -0,0 +1,28 @@ +--- +name: Test Suite + +on: + push: + branches: ["dev"] + pull_request: + branches: ["dev", "version-*"] + +jobs: + tests: + name: "Python ${{ matrix.python-version }}" + runs-on: "ubuntu-latest" + + strategy: + matrix: + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + + steps: + - uses: "actions/checkout@v4" + - uses: "actions/setup-python@v5" + with: + python-version: "${{ matrix.python-version }}" + allow-prereleases: true + - name: "Install dependencies" + run: "scripts/install" + - name: "Run tests" + run: "scripts/test" diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..f9d43a11d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +*.pyc +.coverage +.mypy_cache/ +.pytest_cache/ +__pycache__/ +dist/ +venv/ +build/ diff --git a/README.md b/README.md new file mode 100644 index 0000000000..f6f99268ae --- /dev/null +++ b/README.md @@ -0,0 +1,72 @@ +

+ HTTPX +

+ +

HTTPX 1.0 — Design proposal.

+ +--- + +A complete HTTP framework for Python. + +*Installation...* + +```shell +$ pip install --pre httpx +``` + +*Making requests as a client...* + +```python +>>> r = httpx.get('https://www.example.org/') +>>> r + +>>> r.status_code +200 +>>> r.headers['content-type'] +'text/html; charset=UTF-8' +>>> r.text +'\n\n\nExample Domain...' +``` + +*Serving responses as the server...* + +```python +>>> def app(request): +... content = httpx.HTML('hello, world.') +... return httpx.Response(200, content=content) + +>>> httpx.run(app) +Serving on http://127.0.0.1:8080/ (Press CTRL+C to quit) +``` + +--- + +# Documentation + +The [HTTPX 1.0 design proposal](https://www.encode.io/httpnext/) is now available. + +* [Quickstart](https://www.encode.io/httpnext/quickstart) +* [Clients](https://www.encode.io/httpnext/clients) +* [Servers](https://www.encode.io/httpnext/servers) +* [Requests](https://www.encode.io/httpnext/requests) +* [Responses](https://www.encode.io/httpnext/responses) +* [URLs](https://www.encode.io/httpnext/urls) +* [Headers](https://www.encode.io/httpnext/headers) +* [Content Types](https://www.encode.io/httpnext/content-types) +* [Connections](https://www.encode.io/httpnext/connections) +* [Parsers](https://www.encode.io/httpnext/parsers) +* [Network Backends](https://www.encode.io/httpnext/networking) + +--- + +# Collaboration + +The repository for this project is currently private. + +We’re looking at creating paid opportunities for working on open source software *which are properly compensated, flexible & well balanced.* + +If you're interested in a position working on this project, please send an intro. + +--- + +

This provisional design work is not currently licensed for reuse.
Designed & crafted with care.

— 🦋 —

diff --git a/docs/about.md b/docs/about.md new file mode 100644 index 0000000000..46d756484f --- /dev/null +++ b/docs/about.md @@ -0,0 +1,19 @@ +# About + +This work is a design proposal for an `httpx` 1.0 release. + +--- + +## Sponsorship + +We are currently seeking forward-looking investment that recognises the value of the infrastructure development on it's own merit. Sponsorships may be [made through GitHub](https://github.com/encode). + +We do not offer equity, placements, or endorsments. + +## License + +The rights of the author have been asserted. + +--- + +

home

diff --git a/docs/clients.md b/docs/clients.md new file mode 100644 index 0000000000..7de41615fb --- /dev/null +++ b/docs/clients.md @@ -0,0 +1,311 @@ +# Clients + +HTTP requests are sent by using a `Client` instance. Client instances are thread safe interfaces that maintain a pool of HTTP connections. + + + +```{ .python .httpx } +>>> cli = httpx.Client() +>>> cli + +``` + +```{ .python .ahttpx .hidden } +>>> cli = ahttpx.Client() +>>> cli + +``` + +The client representation provides an indication of how many connections are currently in the pool. + + + +```{ .python .httpx } +>>> r = cli.get("https://www.example.com") +>>> r = cli.get("https://www.wikipedia.com") +>>> r = cli.get("https://www.theguardian.com/uk") +>>> cli + +``` + +```{ .python .ahttpx .hidden } +>>> r = await cli.get("https://www.example.com") +>>> r = await cli.get("https://www.wikipedia.com") +>>> r = await cli.get("https://www.theguardian.com/uk") +>>> cli + +``` + +The connections in the pool can be explicitly closed, using the `close()` method... + + + +```{ .python .httpx } +>>> cli.close() +>>> cli + +``` + +```{ .python .ahttpx .hidden } +>>> await cli.close() +>>> cli + +``` + +Client instances support being used in a context managed scope. You can use this style to enforce properly scoped resources, ensuring that the connection pool is cleanly closed when no longer required. + + + +```{ .python .httpx } +>>> with httpx.Client() as cli: +... r = cli.get("https://www.example.com") +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.Client() as cli: +... r = await cli.get("https://www.example.com") +``` + +It is important to scope the use of client instances as widely as possible. + +Typically you should have a single client instance that is used throughout the lifespan of your application. This ensures that connection pooling is maximised, and minmises unneccessary reloading of SSL certificate stores. + +The recommened usage is to *either* a have single global instance created at import time, *or* a single context scoped instance that is passed around wherever it is required. + +## Setting a base URL + +Client instances can be configured with a base URL that is used when constructing requests... + + + +```{ .python .httpx } +>>> with httpx.Client(url="https://www.httpbin.org") as cli: +>>> r = cli.get("/json") +>>> print(r) + +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.Client(url="https://www.httpbin.org") as cli: +>>> r = cli.get("/json") +>>> print(r) + +``` + +## Setting client headers + +Client instances include a set of headers that are used on every outgoing request. + +The default headers are: + +* `Accept: */*` - Indicates to servers that any media type may be returned. +* `Accept-Encoding: gzip` - Indicates to servers that gzip compression may be used on responses. +* `Connection: keep-alive` - Indicates that HTTP/1.1 connections should be reused over multiple requests. +* `User-Agent: python-httpx/1.0` - Identify the client as `httpx`. + +You can override this behavior by explicitly specifying the default headers... + + + +```{ .python .httpx } +>>> headers = {"User-Agent": "dev", "Accept-Encoding": "gzip"} +>>> with httpx.Client(headers=headers) as cli: +>>> r = cli.get("https://www.example.com/") +``` + +```{ .python .ahttpx .hidden } +>>> headers = {"User-Agent": "dev", "Accept-Encoding": "gzip"} +>>> async with ahttpx.Client(headers=headers) as cli: +>>> r = await cli.get("https://www.example.com/") +``` + +## Configuring the connection pool + +The connection pool used by the client can be configured in order to customise the SSL context, the maximum number of concurrent connections, or the network backend. + + + +```{ .python .httpx } +>>> # Setup an SSL context to allow connecting to improperly configured SSL. +>>> no_verify = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) +>>> no_verify.check_hostname = False +>>> no_verify.verify_mode = ssl.CERT_NONE +>>> # Instantiate a client with our custom SSL context. +>>> pool = httpx.ConnectionPool(ssl_context=no_verify) +>>> with httpx.Client(transport=pool) as cli: +>>> ... +``` + +```{ .python .ahttpx .hidden } +>>> # Setup an SSL context to allow connecting to improperly configured SSL. +>>> no_verify = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) +>>> no_verify.check_hostname = False +>>> no_verify.verify_mode = ssl.CERT_NONE +>>> # Instantiate a client with our custom SSL context. +>>> pool = ahttpx.ConnectionPool(ssl_context=no_verify) +>>> async with ahttpx.Client(transport=pool) as cli: +>>> ... +``` + +## Sending requests + +* `.request()` - Send an HTTP request, reading the response to completion. +* `.stream()` - Send an HTTP request, streaming the response. + +Shortcut methods... + +* `.get()` - Send an HTTP `GET` request. +* `.post()` - Send an HTTP `POST` request. +* `.put()` - Send an HTTP `PUT` request. +* `.delete()` - Send an HTTP `DELETE` request. + +--- + +## Transports + +By default requests are sent using the `ConnectionPool` class. Alternative implementations for sending requests can be created by subclassing the `Transport` interface. + +For example, a mock transport class that doesn't make any network requests and instead always returns a fixed response. + + + +```{ .python .httpx } +class MockTransport(httpx.Transport): + def __init__(self, response): + self._response = response + + @contextlib.contextmanager + def send(self, request): + yield response + + def close(self): + pass + +response = httpx.Response(200, content=httpx.Text('Hello, world')) +transport = MockTransport(response=response) +with httpx.Client(transport=transport) as cli: + r = cli.get('https://www.example.com') + print(r) +``` + +```{ .python .ahttpx .hidden } +class MockTransport(ahttpx.Transport): + def __init__(self, response): + self._response = response + + @contextlib.contextmanager + def send(self, request): + yield response + + def close(self): + pass + +response = ahttpx.Response(200, content=httpx.Text('Hello, world')) +transport = MockTransport(response=response) +async with ahttpx.Client(transport=transport) as cli: + r = await cli.get('https://www.example.com') + print(r) +``` + +--- + +## Middleware + +In addition to maintaining an HTTP connection pool, client instances are responsible for two other pieces of functionality... + +* Dealing with HTTP redirects. +* Maintaining an HTTP cookie store. + +### `RedirectMiddleware` + +Wraps a transport class, adding support for HTTP redirect handling. + +### `CookieMiddleware` + +Wraps a transport class, adding support for HTTP cookie persistence. + +--- + +## Custom client implementations + +The `Client` implementation in `httpx` is intentionally lightweight. + +If you're working with a large codebase you might want to create a custom client implementation in order to constrain the types of request that are sent. + +The following example demonstrates a custom API client that only exposes `GET` and `POST` requests, and always uses JSON payloads. + + + +```{ .python .httpx } +class APIClient: + def __init__(self): + self.url = httpx.URL('https://www.example.com') + self.headers = httpx.Headers({ + 'Accept-Encoding': 'gzip', + 'Connection': 'keep-alive', + 'User-Agent': 'dev' + }) + self.via = httpx.RedirectMiddleware(httpx.ConnectionPool()) + + def get(self, path: str) -> Response: + request = httpx.Request( + method="GET", + url=self.url.join(path), + headers=self.headers, + ) + with self.via.send(request) as response: + response.read() + return response + + def post(self, path: str, payload: Any) -> httpx.Response: + request = httpx.Request( + method="POST", + url=self.url.join(path), + headers=self.headers, + content=httpx.JSON(payload), + ) + with self.via.send(request) as response: + response.read() + return response +``` + +```{ .python .ahttpx .hidden } +class APIClient: + def __init__(self): + self.url = ahttpx.URL('https://www.example.com') + self.headers = ahttpx.Headers({ + 'Accept-Encoding': 'gzip', + 'Connection': 'keep-alive', + 'User-Agent': 'dev' + }) + self.via = ahttpx.RedirectMiddleware(ahttpx.ConnectionPool()) + + async def get(self, path: str) -> Response: + request = ahttpx.Request( + method="GET", + url=self.url.join(path), + headers=self.headers, + ) + async with self.via.send(request) as response: + await response.read() + return response + + async def post(self, path: str, payload: Any) -> ahttpx.Response: + request = ahttpx.Request( + method="POST", + url=self.url.join(path), + headers=self.headers, + content=httpx.JSON(payload), + ) + async with self.via.send(request) as response: + await response.read() + return response +``` + +You can expand on this pattern to provide behavior such as request or response schema validation, consistent timeouts, or standardised logging and exception handling. + +--- + +← [Quickstart](quickstart.md) +[Servers](servers.md) → +  diff --git a/docs/connections.md b/docs/connections.md new file mode 100644 index 0000000000..602641a18a --- /dev/null +++ b/docs/connections.md @@ -0,0 +1,245 @@ +# Connections + +The mechanics of sending HTTP requests is dealt with by the `ConnectionPool` and `Connection` classes. + +We can introspect a `Client` instance to get some visibility onto the state of the connection pool. + + + +```{ .python .httpx } +>>> with httpx.Client() as cli +>>> urls = [ +... "https://www.wikipedia.org/", +... "https://www.theguardian.com/", +... "https://news.ycombinator.com/", +... ] +... for url in urls: +... cli.get(url) +... print(cli.transport) +... # +... print(cli.transport.connections) +... # [ +... # , +... # , +... # , +... # ] +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.Client() as cli +>>> urls = [ +... "https://www.wikipedia.org/", +... "https://www.theguardian.com/", +... "https://news.ycombinator.com/", +... ] +... for url in urls: +... await cli.get(url) +... print(cli.transport) +... # +... print(cli.transport.connections) +... # [ +... # , +... # , +... # , +... # ] +``` + +--- + +## Understanding the stack + +The `Client` class is responsible for handling redirects and cookies. + +It also ensures that outgoing requests include a default set of headers such as `User-Agent` and `Accept-Encoding`. + + + +```{ .python .httpx } +>>> with httpx.Client() as cli: +>>> r = cli.request("GET", "https://www.example.com/") +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.Client() as cli: +>>> r = await cli.request("GET", "https://www.example.com/") +``` + +The `Client` class sends requests using a `ConnectionPool`, which is responsible for managing a pool of HTTP connections. This ensures quicker and more efficient use of resources than opening and closing a TCP connection with each request. The connection pool also handles HTTP proxying if required. + +A single connection pool is able to handle multiple concurrent requests, with locking in place to ensure that the pool does not become over-saturated. + + + +```{ .python .httpx } +>>> with httpx.ConnectionPool() as pool: +>>> r = pool.request("GET", "https://www.example.com/") +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.ConnectionPool() as pool: +>>> r = await pool.request("GET", "https://www.example.com/") +``` + +Individual HTTP connections can be managed directly with the `Connection` class. A single connection can only handle requests sequentially. Locking is provided to ensure that requests are strictly queued sequentially. + + + +```{ .python .httpx } +>>> with httpx.open_connection("https://www.example.com/") as conn: +>>> r = conn.request("GET", "/") +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.open_connection("https://www.example.com/") as conn: +>>> r = await conn.request("GET", "/") +``` + +The `NetworkBackend` is responsible for managing the TCP stream, providing a raw byte-wise interface onto the underlying socket. + +--- + +## ConnectionPool + + + +```{ .python .httpx } +>>> pool = httpx.ConnectionPool() +>>> pool + +``` + +```{ .python .ahttpx .hidden } +>>> pool = ahttpx.ConnectionPool() +>>> pool + +``` + +### `.request(method, url, headers=None, content=None)` + + + +```{ .python .httpx } +>>> with httpx.ConnectionPool() as pool: +>>> res = pool.request("GET", "https://www.example.com") +>>> res, pool +, +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.ConnectionPool() as pool: +>>> res = await pool.request("GET", "https://www.example.com") +>>> res, pool +, +``` + +### `.stream(method, url, headers=None, content=None)` + + + +```{ .python .httpx } +>>> with httpx.ConnectionPool() as pool: +>>> with pool.stream("GET", "https://www.example.com") as res: +>>> res, pool +, +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.ConnectionPool() as pool: +>>> async with await pool.stream("GET", "https://www.example.com") as res: +>>> res, pool +, +``` + +### `.send(request)` + + + +```{ .python .httpx } +>>> with httpx.ConnectionPool() as pool: +>>> req = httpx.Request("GET", "https://www.example.com") +>>> with pool.send(req) as res: +>>> res.read() +>>> res, pool +, +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.ConnectionPool() as pool: +>>> req = ahttpx.Request("GET", "https://www.example.com") +>>> async with await pool.send(req) as res: +>>> await res.read() +>>> res, pool +, +``` + +### `.close()` + + + +```{ .python .httpx } +>>> with httpx.ConnectionPool() as pool: +>>> pool.close() + +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.ConnectionPool() as pool: +>>> await pool.close() + +``` + +--- + +## Connection + +*TODO* + +--- + +## Protocol upgrades + + + +```{ .python .httpx } +with httpx.open_connection("https://www.example.com/") as conn: + with conn.upgrade("GET", "/feed", {"Upgrade": "WebSocket"}) as stream: + ... +``` + +```{ .python .ahttpx .hidden } +async with await ahttpx.open_connection("https://www.example.com/") as conn: + async with await conn.upgrade("GET", "/feed", {"Upgrade": "WebSocket"}) as stream: + ... +``` + +`` + +## Proxy `CONNECT` requests + + + +```{ .python .httpx } +with httpx.open_connection("http://127.0.0.1:8080") as conn: + with conn.upgrade("CONNECT", "www.encode.io:443") as stream: + stream.start_tls(ctx, hostname="www.encode.io") + ... +``` + +```{ .python .ahttpx .hidden } +async with await ahttpx.open_connection("http://127.0.0.1:8080") as conn: + async with await conn.upgrade("CONNECT", "www.encode.io:443") as stream: + await stream.start_tls(ctx, hostname="www.encode.io") + ... +``` + +`` + +--- + +*Describe the `Transport` interface.* + +--- + +← [Streams](streams.md) +[Parsers](parsers.md) → +  diff --git a/docs/content-types.md b/docs/content-types.md new file mode 100644 index 0000000000..091aa8b8ee --- /dev/null +++ b/docs/content-types.md @@ -0,0 +1,174 @@ +# Content Types + +Some HTTP requests including `POST`, `PUT` and `PATCH` can include content in the body of the request. + +The most common content types for upload data are... + +* HTML form submissions use the `application/x-www-form-urlencoded` content type. +* HTML form submissions including file uploads use the `multipart/form-data` content type. +* JSON data uses the `application/json` content type. + +Content can be included directly in a request by using bytes or a byte iterator and setting the appropriate `Content-Type` header. + + + +```{ .python .httpx } +>>> headers = {'Content-Type': 'application/json'} +>>> content = json.dumps({"number": 123.5, "bool": [True, False], "text": "hello"}) +>>> response = cli.put(url, headers=headers, content=content) +``` + +```{ .python .ahttpx .hidden } +>>> headers = {'Content-Type': 'application/json'} +>>> content = json.dumps({"number": 123.5, "bool": [True, False], "text": "hello"}) +>>> response = await cli.put(url, headers=headers, content=content) +``` + +There are also several classes provided for setting the request content. These implement either the `Content` or `StreamingContent` API, and handle constructing the content and setting the relevant headers. + +* `
` +* `` +* `` +* `` +* `` + +For example, sending a JSON request... + + + +```{ .python .httpx } +>>> data = httpx.JSON({"number": 123.5, "bool": [True, False], "text": "hello"}) +>>> cli.post(url, content=data) +``` + +```{ .python .ahttpx .hidden } +>>> data = httpx.JSON({"number": 123.5, "bool": [True, False], "text": "hello"}) +>>> await cli.post(url, content=data) +``` + +--- + +## Form + +The `Form` class provides an immutable multi-dict for accessing HTML form data. This class implements the `Content` interface, allowing for HTML form uploads. + + + +```{ .python .httpx } +>>> form = httpx.Form({'name': '...'}) +>>> form +... +>>> form['name'] +... +>>> res = cli.post(url, content=form) +... +``` + +```{ .python .ahttpx .hidden } +>>> form = httpx.Form({'name': '...'}) +>>> form +... +>>> form['name'] +... +>>> res = await cli.post(url, content=form) +... +``` + +## Files + +The `Files` class provides an immutable multi-dict for accessing HTML form file uploads. This class implements the `StreamingContent` interface, allowing for HTML form file uploads. + + + +```{ .python .httpx } +>>> files = httpx.Files({'upload': httpx.File('data.json')}) +>>> files +... +>>> files['upload'] +... +>>> res = cli.post(url, content=files) +... +``` + +```{ .python .ahttpx .hidden } +>>> files = httpx.Files({'upload': httpx.File('data.json')}) +>>> files +... +>>> files['upload'] +... +>>> res = await cli.post(url, content=files) +... +``` + +## MultiPart + +The `MultiPart` class provides a wrapper for HTML form and files uploads. This class implements the `StreamingContent` interface, allowing for allowing for HTML form uploads including both data and file uploads. + + + +```{ .python .httpx } +>>> multipart = httpx.MultiPart(form={'name': '...'}, files={'avatar': httpx.File('image.png')}) +>>> multipart.form['name'] +... +>>> multipart.files['avatar'] +... +>>> res = cli.post(url, content=multipart) +``` + +```{ .python .ahttpx .hidden } +>>> multipart = httpx.MultiPart(form={'name': '...'}, files={'avatar': httpx.File('image.png')}) +>>> multipart.form['name'] +... +>>> multipart.files['avatar'] +... +>>> res = await cli.post(url, content=multipart) +``` + +## File + +The `File` class provides a wrapper for file uploads, and is used for uploads instead of passing a file object directly. + + + +```{ .python .httpx } +>>> file = httpx.File('upload.json') +>>> cli.post(url, content=file) +``` + +```{ .python .ahttpx .hidden } +>>> file = httpx.File('upload.json') +>>> await cli.post(url, content=file) +``` + +## JSON + +The `JSON` class provides a wrapper for JSON uploads. This class implements the `Content` interface, allowing for HTTP JSON uploads. + + + +```{ .python .httpx } +>>> data = httpx.JSON({...}) +>>> cli.put(url, content=data) +``` + +```{ .python .ahttpx .hidden } +>>> data = httpx.JSON({...}) +>>> await cli.put(url, content=data) +``` + +--- + +## Content + +An interface for constructing HTTP content, along with relevant headers. + +The following method must be implemented... + +* `.encode()` - Returns an `httx.Stream` representing the encoded data. +* `.content_type()` - Returns a `str` indicating the content type. + +--- + +← [Headers](headers.md) +[Streams](streams.md) → +  diff --git a/docs/headers.md b/docs/headers.md new file mode 100644 index 0000000000..3b84e27088 --- /dev/null +++ b/docs/headers.md @@ -0,0 +1,54 @@ +# Headers + +The `Headers` class provides an immutable case-insensitive multidict interface for accessing HTTP headers. + + + +```{ .python .httpx } +>>> headers = httpx.Headers({"Accept": "*/*"}) +>>> headers + +>>> headers['accept'] +'*/*' +``` + +```{ .python .ahttpx .hidden } +>>> headers = ahttpx.Headers({"Accept": "*/*"}) +>>> headers + +>>> headers['accept'] +'*/*' +``` + +Header values should always be printable ASCII strings. Attempting to set invalid header name or value strings will raise a `ValueError`. + +### Accessing headers + +Headers are accessed using a standard dictionary style interface... + +* `.get(key, default=None)` - *Return the value for a given key, or a default value. If multiple values for the key are present, only the first will be returned.* +* `.keys()` - *Return the unique keys of the headers. Each key will be a `str`.* +* `.values()` - *Return the values of the headers. Each value will be a `str`. If multiple values for a key are present, only the first will be returned.* +* `.items()` - *Return the key value pairs of the headers. Each item will be a two-tuple `(str, str)`. If multiple values for a key are present, only the first will be returned.* + +The following methods are also available for accessing headers as a multidict... + +* `.get_all(key, comma_delimited=False)` - *Return all the values for a given key. Returned as a list of zero or more `str` instances. If `comma_delimited` is set to `True` then any comma separated header values are split into a list of strings.* +* `.multi_items()` - *Return the key value pairs of the headers. Each item will be a two-tuple `(str, str)`. Repeated keys may occur.* +* `.multi_dict()` - *Return the headers as a dictionary, with each value being a list of one or more `str` instances.* + +### Modifying headers + +The following methods can be used to create modified header instances... + +* `.copy_set(key, value)` - *Return a new `Headers` instances, setting a header. Eg. `headers = headers.copy_set("Connection": "close")`*. +* `.copy_setdefault(key, value)` - *Return a new `Headers` instances, setting a header if it does not yet exist. Eg. `headers = headers.copy_setdefault("Content-Type": "text/html")`*. +* `.copy_append(key, value, comma_delimited=False)` - *Return a new `Headers` instances, setting or appending a header. If `comma_delimited` is set to `True`, then the append will be handled using comma delimiting instead of creating a new header. Eg. `headers = headers.copy_append("Accept-Encoding", "gzip", comma_delimited=True)`*. +* `.copy_remove(key)` - *Return a new `Headers` instances, removing a header. Eg. `headers = headers.copy_remove("User-Agent")`*. +* `.copy_update(headers)` - *Return a new `Headers` instances, updating multiple headers. Eg. `headers = headers.copy_update({"Authorization": "top secret"})`*. + +--- + +← [URLs](urls.md) +[Content Types](content-types.md) → +  \ No newline at end of file diff --git a/docs/img/butterfly.png b/docs/img/butterfly.png new file mode 100644 index 0000000000000000000000000000000000000000..5e5f6b68be369230264f6bd766fb09ef7746209d GIT binary patch literal 683778 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

?A|*c%&vSr#OXeuMqz+bjjFESAIW z-pzYDxIbo(*OYC%<;~wZf9Tj9|Kh=Se=jX1!WvHUUmJsiXDoT*iID7ikiigFuB1Qp z%Rk*SKf2g+_2zI769$gb=&ZN0rt(0dG}W=awMKOqOgo(9N+$&Y2&hv9Bn`^cPc~W; zbTXI{@H8t~u1-~Ukx|c@0f<^&{gEMf)6SN27VQII>A)KFbq-KGgR(mW@aM_88XPbY zgdQwRsJVVE>Tz{PAC2T*zIr`O0jMinu5BHFpCE7lz(8adtt`L@;X0Nh?L@)$yu5rK-;3P%}VI$>4`~=HFQf3 zD)b_{THBkWB+T`<_l$GyV*tkQ(_Jv&9BR(T1=N2B-Q~#kKL7USVdi_Ud6@E3m`NJeR@*jZi9wvW#Yeae7u^ z9gPBz3j&_WusH>Q1b(N2^0F#yM12DdE^+qsK{nBU_EWMsaV0j~hO-9L%aoXz{kO!j zjfK%G<`UV;h znEhv8IH&4NKg9R=@qRTC^`D>H5(?Kr87%e%@jd#J+N#?nxw2Wkhj=9aP8`)_-EgN1L45oBlw1E0FT!>i_`QM+Cxd% zJ`xDclsk2h=(!$7hKAz#xz#^HGieh#=n0fQ3z(*YPPfka_)V zU#^Qf(fc;>;J=GL73B@s44>6~@tJInYB{bx+HJphi}4KX(;%w$E44K>U;Kd||KZE+ z550HsnADqBUw@}(?>DZu&hcnRf{Tk=U&cGU|%;V2-JbW2Y>wt^As_e~T_<7}IVNjDIK-aO0b&=6A zCF7z43tK?B%GAJ2fGw~xJA#t|i$O&Wr2uw7iN8fwh=ypv{t|#wLLzp^)|wf#IpbLR zSS`Rn+-Drn1f?Z9nR9>(HcqOnZ$~~E@5XwTVrU8*%woQN4u_e5o@|I{`YzWrgHa2> zR8_|~FPwtmp&RTQ&Mme2FI^shUOUaK;UTDg(4J|YG>-!S_dYs{+m2Y|e>+fNcA(S> zj&0G{Q;ihLeF!+q7EsBfeRDdKH#?Kz1cq3gi=bcAmoS)DP15BI-> zvs+z*{y4ZV-1~+H0C~tD^ZhnPvU+~5U%4I|s-|)3UOIoCd&lqtAdQcXKx3aKkiw$xZA}e8>ELc-h6YCMe^{ZELR>&|BP$U2xeYsBl zuy`H>r3kcH7tegu#W<^idj%XB-y0oL?o%+$T3DMi>hMX0U0S8P_~PP1Cb@g5zPj>> zBS#KB@g48}_KOdF-w&_ysCt2X*nj`4u&_{j`t)Oe|N6z3{}(>|H5V_O4KF_ZY*?fW zZCQtoPsySW*nF~}d~zAiEudvN-*u40U5mWN`1}5+pE&rQ-9eW5?$Yw~iDaRqp3d>*4b7ClAXh1Dg!+6Au%rS9xIp$@ zny%;90)}05v|8Jypz3(H*36hw3)=VYK|cwE5kylztPS!U+IK`5D!&b^RRXJ20?da1Xi{PZcEXT zPGBl!IZ}HF4z{+u<^Xl8bBGJOV;1= z#uD-dpi2`s%i>lEP$wsr=z*{t*=KVzfLxqk^@Zya0~zdhWC^kyvIh+O&9u8Z>QMt! z^^~BZYz#rMYW%7#_ROElK=2%R2n20nFvscgthiPL-lFEuqM8z+@lRk+`WNTP-`R9;&)Fdu5S^)9jrL6r$(&er=oUZ&rG8 ze1!Kb@SMmh_hYZ4H9++|a$UK8ef&%}2Xr@_?;J2SPJv9aFGW)dM^V zAEPYGz=92lpA>uNaKDz-2@=MJjexv%=GP}P$pOR?19*W39+7|J0kOcbWP|$>aC0xU z7f#4=I#O)#%jXLAMj%?*<2te%cCdNsWP2XP@v-POeUsIdVt=2Q?KTO)XPY##Ji|U= zXg>A>z=E|>_W6}4SUQRy{xZ5=Bs< zI7-ofyRWiZcF-ltgAZ?`NS%=w6!U@lk?IrI#g}KsB$Le;v*<{JZ_5ajOZ|@s=CQtl zRQeHG7ygBfZi>FTY(UQhRH!gMG=Oed4!yl?F!$_gj%3=m!ATn%uKJBYzt@?DRkGSVN97!_#Rrc3!%CI&8Ci}*hED?brb&ca) zS>qMJ>noI6KX&KI*F5pV|NKYK_VnDj!r4)szWVwmU4d7``>{50LOr=ffIKdbtGXk3^$|W)sBKqyE4FutZ&_K4cr;~9xbnrdKNX7yPA}nSyPp=Pk2TrJ| zc$rv30b~5}Oo_@k)UzlmGTardJ@hreNsN|;2l9oI@jZNaD1b;yi*;6Sf+)eX)W`PqpMk1;1p$=t{qUE)r_ObSSI!2^Or!#D605xu*j?uMm zgEn3(V8Fczgc#6!?Mkw(c8^}B8?n@}3sOIxc=x7sTlq4wANm`hniB3XG&r$Y-PSo=gtQC%H&#_qcaP$15k$wo86h>g0oPOy> z_~MtJ;0)mW(MQ8t!DP(p*fkjN14qg1ogjhTyvuA3#r@edREqFA1}sxmO3=8Uj?goV zIh=~){33M}xm;Qx;549OZHvw@0FN@jHI<2CAPsE~XHmyM=QN(hC^d+7bPNTNq|d`1 zz?t>TYUgy^rC^@8^GG}jc1o^+EntHr%M%Xn+ZU%Q3=a>GVH?CTWeNq3n+CrW<83Ws z6YPN4=#YJLwBFGp$8eI#q}bRL@Md&moNUo%IDPso{Xd=~IKYwQ-066v$>ijqa+Xu# zAw3ykjlhN3c{B3Ls!p%YNGo0M&8V%BtuYg#qwYGCa0U>@2vStD?lm;yT46+Lc4rBC zbuk;=+t(A09lL{C`IAMq15TBUlK%c%lryz*-g4p3zVZdmr4(f|3pmY=JHx??Sr_h1 zhcA1((G-j)Wi3)eIU|-i$g-5yEoE_?_cLe25XFc9%W4jPY~80 z*l8V)IIiOcB|G+;DYr)q_duf(?k~?+F&c2PZ#z7nK{Sr_>fG$ih5GvH$L=_M=(~{4pI3o)D=JVzgdrzS^6KKk`9{HJtnV^f$I8Dz9s1KGp&Si&_p zFcfAfhuLLMEy;-Tsw<_xN;5SZoY?3JzBay^71;)TFw#0&!#m#j&M-J|GmH!%r(>)W zx>}}`Ac^mZE;ZLu7xW;n3h@bg`CiAA;LWJ3jVccC7WSO+Kq6l-zf zO9Q&B6-s&sK@Q_c0p&)A`oqgFoN0|=g!8t_Yth%8ammtv-XK#Hag`WSpwk= z05eC?MxdJ@!42??m=X|hnR_(* z2kVaWu|sK*jhA;3D4$8DU!+sBcFLgoUY%)4n8Cp=eE#Y8{aOrxu@G>lo$+>Xj+CZ>ZjNnBx*K$nt0_R0J zUtR~;<#-xAx+mId9wP#Z0zU?B+TdaanVNinQJH4Sh|grBMHyIv7V0m78NW*FcQ>}t zhsud1sFp8kn|ASg(!5W9OE)S@&?RkM)=vp`z6>ADz7%GW+uIpSOpe9-gpI`Bv7gbdV>2y9Fxe0TO#(CP+LhG^76J0A4`qu8zRQ{^ zunF32?Tc$-XV4V#V6$W=FW9fdrkswnw!BThNg!WFV>u0i1&~%@HYKzz$^rWlL4H0* zpDAsInf>vev=hp%cGI&X6K@4wZ1PN>CbB#8X|m#uKO|^&&H0_^Yw#@6_iYwvd75%8 zU?4c5J@Kr{j_?`uyG*(WN^5(4uVA@4Ql^i=y|&1EQ8(y++W=bISftR)&IORM+#+6& z=Xyot17M;|=4!7FcbqsJ4jerS zuw&UCzA;QwHi=(Vf#W-P-+~%w?RaouTG5G_fAT%fLXL7)OJH( za(kSI1m|&vlAv6eT38NOu3p0~A&Vr5+}rhd#*lZ;mwtB&0eoAt}Hx5$;D?++;P|GpZ>XD82{Yo!p5s39$B7mvKP|% z>g&I?0s;oL8=tHHg1Isu6|W2}(cHKaL?YQ!SlN+O*yN(|`@2`Y7+ThZgE~bz@Xs$$ zGYlOuPiOrn9)Bjh_&l`CTDm9G`M3&nU5c8GUx+p_zy|ozx1jH1Bx)#~u*O;AXHcpV z5)3fgg*(Xm)PdA`>jZKC(&kiF%TOY5mH4-gmCEiFM~Cm3VYEr2Mkh8qVo%C3aw=@c zNx4VX4oksAW3x8Yd`HDboh9GX0VzizOSRI`G-NLUR4JgCGu(d)$2w+p-D{R3!Je5d zP>H7jk}xsR>8{{@1%S$6j$odV4?d6ewGP<^bn7%Ciq09&EIM4(yoc)%$Wu?Zi*YN# z8Q7-3#LD0$u8A?=^GZR~y=QwcXaH*)2)-#Pv1|9@!b~VEsO!0{ zAs7JmmRJhY0~bS$SqUzuVb(x%yP=#0ie<>PhBJZ?T(1f?f=b`o=?uLX>R~2qBR8{G z&&1EGgkHIwD~`V^gSNaS=z!c+(ZEZil@Pok5UnL!mxCE&P+Eda;LFjR3F;z~KJ>H% z19oWK>68cKF&*J1N^5TP_eaC5j2AY|Y)~#hnT*au2@9|DVsID(L=12=-uz6t@}=Vt zjT1lfrE}pQzh?tP*H3352KQB6F%xgFV1EL<0G_P~F33!|c=_e9r>i?sY;7zhbv~7( z-v;FwZ0R{JN)~&65 zPw4Dr&>UxZc7{yD+*J75R|lv!eilP+!?wQo8I7=)T4`){?AY;e;Mifx8LpD~pNR}7 zpQS>lgL9>`pJClAXxin!WfMP7zyJ*mhnTI z9NHYSn*Jww)(Kai9xo$|4I5(tO87d#NV?k45FJtI+5{xs)ONOTuQzY>M@P|x@|@}v z%Jgx)?5*I-`yzsf@?m*W^qTlq6YLTJ!zFq@#M*SjV$RwodQXOpL8;{@1e4WG9i6XV zTUvPi6OTUmqj&9X`a(y0*W*9>-3Ld0_1EXmf2^Tl?W2Fm?8s~Oy{Y?$KJWwIyEMO$ zUS(hD0uv6OJRIKquJ_P&z9mxJU%qfL4AD`3ob{TKwSzO5N&v*53wKjAvPAuQ|7N8N z9ApFKo?dFrd-{0xs_>q__i%Xj*{8$U^jAX3rkNkkUUWF_2~42^jIc(5?3Oktur&0eH-IB%n>hz%WR<0nTUs(b zH5FbyfBu2r{KSXv`_d!7arIq)|AW(uQGv10{n2lCU{4h@%2RwkTAqFt%S zw%W7BplccVt3)@|kXbWu@qEcBGD{X4gt2A@hE+Pe1b=lhw}d zF4$-7UjzeCjb^c}D>qQI=3XE;3mw^Pxj_fN5cR7*g2791%7$?RC9QPROrUA(pva_MSwI+0Tw^4@=Xan<5fOG{gahgd0Ht&s76nN%Z0RX@Q zfx$xu_ETEf9&F^0}o+fax84B2ZQOGj)bK03tz-TZ8oLLEk(2ctiFT;J&(8 zz(ZTU0vo}TFOxAx)}0V72B`kqXPBe;qWV|rdk#^R16Pi{mVFoP3fGWbu+F*&A_!h? zu^;vZN^mx?6tG#iFZ8W;paA%5uN;H@P4>#9iuS||{1QG#3CWXLzE^@S+Xi6HP?D-Y zW2RP6c$OOa>?Y*_yjOc~|Cv1R-_29^kL>HuG1WWTQeBx^N);?OXkmnN3qEBWtq2fd zkZ(U4_evH+Eu%df>KY=$Y74nCQNkh-(4j-3orBrXAd5}_mcCZ{POM$AmR(jS`k$W& zW{I2XOF5yzdz3k%e6l>qCAOM%)&{TRzY5%%ys)p)Iwe>OE8B6z>lCFfc|J=}AkY49 zAyWGyyRgZT70TX7-e*j((~^ukxY~nL}}!WZ3p$IV1MKh%fYJ z1P=IY_b{>pxwdE0>kB;CpGS6!Nefx40+RZ}zHIPWj~(3G+sk^chnpAsLz-m6(B<}U z;;tj1q52?eunoX&(?h1NOpb=G1IL)s0%)L$wWNf^j(eK2q?kTq#TSl*3kdke1MUc9C9Kc3mdwkIm(yd zN1SZLbE-R~#QD8l&Vb;idlEmIwUw=qLT?Mc*ndnGf@jW+)z;EqrJB8X=k~_d+n#&& ziIMld?SYHvs{j4esXu+{!3W>7%APDXVt zevR7Q&Zs~#1e+NQgpKjqI|#VR(AjCd23qfiH1k6Tar6i*aA*$fKN7yZrZwF9_21^g z(BE- z%@Me5-y#cZW`KZwlmZx|x0WiQqtlQ%m z4HB(6+?2kGQucQ=uA895>rA|ehK)dwTaBNw3b$FCEn$0XhYx0Cj$yAaj<-X%g5l z8|F({zjEysa;nTC&y3c4>HJIK?Af#28`=cNrU-nXD|p3wM#eqM(lrf+eYPy+AOdTZ zj6SpOH;cSGvPsrN1=lwFYzO6avY2)<-yl=KWI{?&(yZ%U;dS@jO|9`{IDh_3T>oW) zgxR_2@Z$OB0RH9yYMRk4M>)%YPXwBlhunGcE{^*S&ppOHQm>2b*5NE>k-_3r3gjI* za0-W=mn{d-q2`Cknk5B3g+Pr*ixFuAwK`lWWX{Z21g?0Wz>Mo)(>L{|V@#uy&iSoG zM>W*Z8v)>MVr-m@<78A-mRJ;>x&z>nV9)InW41^~HwI;_r4Dp%*X$krUz#c!w%3=xe`I3zANF7GU%vB>gO43N z-20h}Pk-_0Yp;Lz%6Exm{a0S-m-OXlP96Qd-~RN6Mu(;jS;M`D(v2f`!Tz}O1ovq+ zHcMl)nsDEP-x9hedc)}#PKSlF3o(0}K!2bTVH)vVILc?2nI4AO9nOgP&wc{;SLb*X56Y z)HjLEpOXJPY4!UvX%x+^qi`DY6w=+*e%Oc zO3))UO%2E+*-t<`o1H2jmf4so&T*zq%&8L%0(ZFP9Aknl!)W9)id13(W7bAcx`Lp& zp6j#&HZ?ZYhAB#r)D_zJQ;$Cpx+!m3=PX@3^CGg83pdVPB`Buv1VK{`XEVRL6K)J& zi8|2{!p)QeDYu~lU5JiSPCeg1;8A)sL+VP;PLxBwTh4e*-;*PNv}8i|VGcV~jvY`x zvGJ@003N?1fM&v>65Dh5@G)eZF^-q7#Z0&BWm2NIw=Z0}bd5lLj(w+5UKRanRsr4k z-3IiVlT)N~$ILwIrfu{*I;liEYLm+Nz#WDRsDd^$k;)@H!!n=OqrnUfHST<@DWiS zO!E0`f*yYEZQx)NKq?FSV+DY16LyJZVkKP6QQTfrriXSrOC}!CV$Cc?wxp4AD9(|i zDQ#?RqQVjwWjsd$#phC%mGu;M)H6OaGs&9J6d2}{J-3!%(g?6AH`=l}#`O+fyAb`Y zN^C|;^=lD&Y#Hbwh)s5jNJ`WGd46O-r+JP$kbG&021mHPm!gkd5n}e2Hrqq zwP-_3vZd&6;wX5*FGomgQw026Lvu>w{fBCbQKGpQg zkA3pvAO6D+|C3J+28M^RUh&BKIIq6`=2zfV;Nbsb&Ci}Kq(@);#qNjhIPoD|sqe3D zZO=&EU4vejlg^KiXf|JGbeC*%319W;fFfdVRZdCP1xK|>o^*G_(d(jCj)+M7DF(L+OB`Cq_I=bk0**X&hr{EG;l|K(ICpUfbwe!_j&{Hab`n4d z&KHkKT|Jq{@+PiH7wSrzEy0T5Gt46B6!0!?2d9pp(ozcn0JFi;qEzCdyasJ*jKWT_ zi@m6`j&!UG2u z&}bVv;yM{y8)XV6`EvhsY}UEoB#Jbao{&wkw%j#XStPs6y_MsHDii*0QKq0(@;*^; z>yOs~5E@!KaTs!xJxn44JPR^ty`aX)=QT@LP9SE`9qEf03Z0tfHo9OF3~vHl`Chy4 z$8rrlY}T%U-W3(xkG&sa768_ZovAko&;&zT0lP}L50(k1gqhD6SJzR8-E639W9`0% zQKysb;d?f2+@;}DEqwu+8Bewn4j@W zeJTch6;LtP*9CQO5V@|vfDX9^TnEWL_h<3NV`NxEM>RPrb1Owz1oBdegH}N%)qVHe zYAj>6gJ+T*;hC(WzSQxTm6Y3frrMdczCaVXDYC28tciiWe{8PkTH8;doPHK9IKu)Y z0(Jsb0~3RB++bCCLwNoh&lbxr2!8!+?>h$OoX5f|RAO9jeplzmF4s6;>joGAaX1J` z)}#a~xtUkTD!NC;t!9p@2`blDXX821*~)DRa!?zMhqG^gA6Y3!zd<)dURNW{V4Zb~BwE!`h z9Wpd@?_ME@lEpGN514?g){qg|-eUX~`%*wJ*|<@;<}F+o@ChJMec24awoIL`UBUgg zLCzxC-PwhU;nL+x(TQ6G;An?!B@mTJ(Q|=yQzvx81o14|lc56kQYExogGfP!6dr6_ zTLU$n^zc9z84N{-l4}&fCDz{YH>|CRLqoXOCEcKu^)WlO19daOeL5DBK&_;tE?2j@ zIQ71f@yU1n$OnJqxxSu%^J~c4S9$;cYmm&(I2ju)zxKA7*-gG=a0H_cVzP*hZQDEBL-PE^D9dO!bTZ)ucEuf!?FLkJ|+vmcQ;qxn>*REdWKK6yo@nhlqi)YAwL3>7CI0Bpq z-p3inTESSEAu}GrJ+Hk7pozXXoD*hu!{A^{EH*4lz_stdK~!!@9pw^lc>If>Y2eq1 zB>v0SBT(zs|NSTTy!~}YzioDE;d{y}Tkfgr=uRXlf3VS7q+#Ryt8Y99S!ve z8mXEhQp01}AUMrg7SJ`Tm`4xS!iGu!sI7C}*O3K*1RI)d8WD1xNV8{;b(pKw0m!EI zMxQi-n_NAG(|`2%9kEY|S?8glAy@;GQ01>P!G`lmF!2oXpCgcToUOrI1A$&WI-{yu zRsumJpI6GBxvzo^mLpk0$G1WX&{_X415;Da>`O_?ik_h~>}dH{8H#J1 zp-FTLx^^B}gp!WlS%#%EjlVHNK;_G%f#r|t4DFqPoVwKMFl-3xiwyBI*U^_CfPsvs z!9CAmzx|1sa;Mt(uM+fd1YtNcX2PxiF0enF0F3&6^#pZm02kYWC43)vj<~IsfQ@V` zdQKUVny<}ONRy)ed}1kJj#TeTS!!l-RbT0V=#r--iNG7@w3=AaB|*HXmP(#>g-b5xwXy@#Yw0 z+xw^r_K{>m_;J@!m{Zjz}Y&&X|TtEC9~ZLDhay#*{iL$U+QxZecp;2v9Qs*ZEt?WbcR zXGgFfIh8$=DFKMYt_fhJkY#sB(3GCloQdK@1t$t=&v(#kUQc~#*{Up(Ja$^0pdTe0 zHBaxTa`wwVs#@0|$|k^c9vz%Ya&`fZW=WWMcJx;S`J#^C(`_uM&0JUY6gv5x@@Z5zzcdtKbPm+ldQ%#+EA z(BH)If}OfGaV;d!BkA@7#2)zS$d9|Q1K>GuZ77W190sf#4wv~l3V4?Q?39@UwUsmL zWHZVnu@N?j6*zP+)T08M0&KDkOr|FIrfeH!#&N6K)jGyKsuPRly(U}H*MdCUE60ib zN3WnOmn=Wg0QGQ#gQWqnqqw4KE!Kw0NezLKs3w3j zcwdLUyn(mnT=OI~`rErS4nk?Ez(mCjATD0GM0fQe5O$iVF_&06atkAj9{u{)!oW~J zqr-4AxJDD%xi{SV0fNr9aQfLH4C5;_C$g`@0}~u}kUbQHUC>1)&HRbDMumlASwlC| zimEbcFcjQWrG@>Or1N& z|LL@4s6q8Z*U3Z^n)6&JP(F7ZhiL&vq5$b3NA>&Uxb z?u&mc!SE{~Q(T)YOq0dA(fB@V1g!;>(X!2ci^x|JwEFL2{UQbkWt(DcEJYFd7XV-- z;(H9>7GVi!$l~|;oMK~1)|Gt_cn~c&h%l(sm{3D_oAA)SJ*+9nJlS)}p!@b6h)v(t==5B|x|O;wWI(hV%7{kT`!vWfbIk|Ewe)-O z@Nu7IGNB0q%_#f6*z634W^rjY{@eGOb=1*P76mj`0Dq=1rUo4X3OaLkNVjgZ3GmJ9 zXyo`319Roc;G>FKRx@bU%$m_TeCQ6G-~-_zOoJyLdkj56))Gh2ee~u1D+}&V?BM_x z9ox$h$MK{b!trm?lecnA8CWQmVOWD4>$8!iq8t~qGl(}biqYn#{JtZ$E?;;l^zLg7 z$EptzOzKE8RuZ;_z~}yh2LUg82|%c4B?z%k%GBt17#O`kU1T_ zB^VNM54eu>Y=hne(nT7bn!S08-z6i*Ug-G6k}$3z`(j{dFn&+a;mF}5 zF$kI^dzK}rwsZRurCy8B$<3C?_DLoT6shA!#`4Hh8oGN5fX=#E10>I*<7@>zyq^U? z4YRowfJimf`}oX!CY|4Y%axng?tb{8*ZljZo_ge$-uTAvnvI+K7yk3>Klh`@2-H3? zI(Xxu6L;SaP|yKGDoalXN`C;Iq_hiQN_$=9{!-ju1YB+naIc6hVxqnfB;BD)Jx|Sf zT?;LgmK;BElE6$_s$(sSeI4v>t^=nG81N}yzO)yA@ulM`6@RFIFtpKd>*4SGZUUFr zgwK5X59zxA_{i}wFmliBguaG;YrgAv1V+7*v*BY6Il9Ik6=JR4|Mjac6JQTlRhGSl zL;qjC9(kmYeCbF2@yXA9{`0@t(AIWu=h36sQnS4R#Hcvc|Ob0>s5ksC`5If~{n{DEn}&-4lB(m^kp|*^#}Ythql1^Xf3c3rh>s)9N06fOC#c zM@MN7b=SQ@9m$4+hx^#05+>Y?a-Dp5$G3iK=)k8~0>qsoGyMmD^!wqNXP*t7G}5hr znITBg(b3Lc8RX^2iZlHHKcK)`>=2k4bSjJPvG--5>!)qtA81!qs=>tS((*EFI9x9qcRDpl+Q0T{6ErDiojL#Rv*NCObG0@4 znf;&m5XuUmnX`AwL7Fw|J=6nWO3;lw;xdJv?p^@A zUO*uMCv*Yl%?2Y)_=@WC82IC3XxBh>_b<&7OYyT*d&LeK3|TDmlkJ%&Z%Jy+3d z$i&DF`bHLlC6VR$cM%-HZ#DZ|0QlLNV>~uemB$7oSZjmQvX)-bz(w7H(750zBm6;v zK?H=qBMStq`i0qv8+={Ct})3AUqDb@0B4&XDfVkHE8fg>h%IDhVtRqH6$9XA&dfSx zu9U{&%OzPC88U(cX8qlBbvXx?hNe6s3dwSk2>PJ!Q}~)O$mI9(=;#9HKTi)BbzTys zDMLaAi2<$HO&aEfO-uCw^w$JU^xf2zo-rpjB@!|N032n9s7DbUi2EVO`+OeXm&87A zv8Ik6_PpvFIx^uuPC7(J9@?Elbe9z_Tg}k)FaX7 z^nN&}0@2(_eEHK@MvMGpXwr=x=;K>`ljGwL|J+Z1c@Wk;3I$hg->L+x8Ge|-(m8;Z1$;KMV$#a4Te%Eax`^(zGxse z3E))}7`_5urH=aE{+F+W$De*03ONXDWeB zuhJ1P@tRUsxd`uPe^6#3)@Z8e;M$1KIzknzbSaw|;f6+sK&9wR=oIx`j&+JoWpqGr zcJjqcRG#|~Auhu?@Yi&z3OI>2VlpGIgJAc48$y|NUS60bJ2K0<ilRgIL#nFqF~rAUi!spB$JVB`Xo_ZD{ME^E=lhn3p9GGeE4V zHDvCQz>v%W>3n82brQ`4#rx%H<5$0M|2kX6=13Sm4FL|U^xR#kYy7ViBdHTe$MVnw zD}j|JsH=(@p@CZifC+Pq$fI%32%rK$*5w;hyhmr(pp}4w{mVnilb$Ld7CTw9cI(vD zx=raaWCL00>FvZALRDuJsx_sRE}VK#H4gW%f8PVxDzxz})c7U#)&&4)S8 z1^dOj1&^lJsJUk!?I)pwp5!{R47S!_U*IgdrZsgsE6`?fEOe+HA>|s+&W-aGsz1)& z@)YNAgZ1Wql?N%2K8HqBueO}EFaT2C+%KCkZSz@?5{V8nh&8w{=!q13-eiE0MJ8(K zDYB6*vUQXZXDctxO@tSodkUw9uFU%nMyFd)WP;#m5(bBXYIk=}XzQXM0$Dz1bT7`$ zhq2MoFfufXvreCl1=vo!_rke7kZc4106+jqL_t(D01;;?K_b9ru{Ll93_IbB?>c}p<#m%RFg_U1g~NxlZ|2b~Mk$$MM}iqF8ih7cmsIO4gAZMTY|})Hbk^uA|_L69X1FS5*mr?^0Tee|OR8moWsp3_f!{XN}%2g8vQ$Eind ziXf;B3fETv9a*17)@BJN*VNPu3=V>D^j{^cnqntwCuLBUggkHaJF&+K3s_4)vA3_6 z^V1vt-GBHLJ#wb$5it?{M%Sk3_#!~Olrvw-YZTNd>Ffb^td>lcwXULi_uYFR^!u*x z2fzFKp&uJHK|@mfL)>2iGqO)Jl;gs@Ob|;fCx;aPG7_(>b%wuz8-z=7wZ#A}d z{W$|e7T?`WMhMNx#K(T@2akU7i+}RJr7F|+R>ELeLGBG|42<%W0hSSz+4EwVj`2Ag09@2r0^hEk3<`lEWl>oWKrmycEsW)KTvtHd z>}nFmp1@jlT}>R*cN}?Y>ulv*ZN+{h7cQI&mtVdV{_N4OlEH-~M6i&D&VT#}nMmS1 z?Z3SU?8t8*WJyw0C7>Lv3w6mF=ULFhen^5I2Ii|wPBM#_u0R(eFZOZ}cyZ0l3~uLO z5fb$*%+AHNaFRtM=e>eVrS_)^pe?on;qzii1H7Y8 zO+42w#aEh~lTCrnMNZ0CTON?0mntWM#}%8Y}Zz%y;ZKFe}u)Df~)^ozWXWfPn1=_Wy>A)SHpEB z*x=f}PzeIU;zR>vWML+r1zBJMfpsuTY5_R}61HILtl@_(Elv?cqfZGurL9+yXkbZs ze(a#n%Q=zRwg|gKkjMqK!Do@lhwp39ngrq{=4YeW<5$)eAE1==Z-kxKFiEpi)~yVXDTmJAz#r^R_rNs92D5hR>F9EC zN0Ir(xt577@M0;iV4Mv)EmKKX2$W*8xW0Z_bo54-}B4A@EhO$Z-4PqU;D_1e(Y;M|8M^770&ga+naci zSO4?ZvI2yxufALXdl~$|cfRfY=g*%0iTaj~qZPGHWXi~X;Jipf){v!X3?d4>O~ymx zE`n{HlZwe^Q&K1^Fal6%C9T>eX1Eb?iVd8Jrp@k(Z-0B0bgSG&ZiW{@yW(2m9K?*;}K0pCFdmz;;cpq={h$ z<=I>h`iL_mdfx?U=>dW)uR(YjJXfV5Ew&1(c3K3(twygBJu~pw;8K z?C#3V#^>8W$(+A>Eqwk@z8X$HcZ)Rwpg_57u?UqsM`wF2?-Nidj&6yDm|hSGvU)nP z36y|Afa-gBh3DXcj~g7|44a6`b9VBb7>n>hEC;@|L4u zAgxoEx~!oyh_lII6CgpP?DO;LD!M{rcQ5EGxRmi0B`uG4NH8SB7VOAWP# zOUJ6Bxht%U-H1lq&s?1vM3GY?2w1Ydvp|1}=?E}1?>U0wUR*;BT@s3Q>_x!Vt&$bX zAY-n9nRA`fbwCHp8EP;p8fOJoTVYv;_anX5XS4H~MpuI~NdRK!`PNnf$-X-PM0NqN zo(Cit2~z+CgEy~*v5^t()tT}*nEW~=_MsHVZjB&1!z2$`0UE|6nOrHoX)&%RKdL(#ktjRNQw&S>C1uHSAj{Ni7noTk|AkhK6uN?yoI|woDV);G_(`MLG%-x~X>95pvLQeM=~Rag*yFV+gv zZ0q2`L)1Jk(meEenzH#Zyr00qwGcQ^4#-pT3CNrHxr&8XQhFc;le>xmi86y|;@Gf` zWKo^KAX~74YqasX8R~F#m{%xkG0?WJz>zx+hu7SFcMPf>H74y;dT&KJS)YovSZYA0 zdS-u5!e$zXJs|e)I}q-B?Y#uwck^Deb_rtsQYjLZ{f zSWs}wfP-MoV55SwxlKaAGnk?@L%<|oI`c^9?B@XX$rSM zFe=cs#y*<$hu0p@kJ(*&SybtC`wTd^Whl&5WVaGWC&3l&b0b8{VMtC;|> zEYfeSSr^<|hep1zIL8rW^eo_tQBIOh*7hHv#a7g<9#wtAj<%NY{_p*MvU!{nSZJ+v zZQ=2+KIumycE}6s<+(;Y_*x8FU-@BCv{-Mn9@nSA8fRj9c09~5rm+&;UBen5IdBl* zfcjU35n1%hD(fX9rKYJFS!Q2xuyu^<$rL+jL*UVF<+pBJf!aEg+<)*8W%G0cULGm` zhu{19_g=qz<9qTYC7apZoja%i>#L=lM>dj~XS@GraFTP}yX*qT-buXonp-@}mL1y3 zz*f;G$C`4_t!E*(Yy&}>%c4h0VWlBSyhosvpZW0ot~N(!wvux%=&`@A7xPW?O+b)2 z0;8$v^gQ6`bm+fzGqgbIE?{S7N2kK(0*zp?VFDEfBAzckAnuEn z$&8{541UbdWd-m)eeYcf)@Hmf_Ih@?%zw2Kw_zq~bDb`S*-4xH3xPSM)PyYf;;Q z4M}5XtXn-|Xgvzhm+(17%;mG^V0sw4r1~%7Mxe@K7zk|Kz{oco# z{s8w^fz0>q?G4rF;>8(&eRSPndXl~V4R1mIQKx`GDS(ay_B4^M1K61jyV$i#8N|pM z6aXCu{*L@q)Q3#_k$4ukY4(htt)sU9jpBRJHJk`g0sw_35;zr8G;5WalK`BXrvxey zj-EUb!TOswM<`3CbOul!%fvlkAJG%~e>rS~w!0G9SmOCC2{wVc0|2{#9d||WFgaH| zGyX{mKy$N%kskRM>+kl9!bhIEn52{&lhj9i3#ZQMzCI;-7?j z9(XGO9S#D7iW32y5U(Ylr*$ahO{}XKNQ7wEGzM zqamRQ%g7YoO|fn+J8}g80Qwq~AT%?21O%67G^jSf+eYb@px|b+`Ecs_m%`vQ!6;P7 zZF)XrF@#cgEA9G@^3=&G(qmBwc!$*lGIl6-X07XHmSUNPQLcr(3^ZzX#m=&Rn>YbB zJu^!o5-v+(oA0Y^wqbgh;g#Oy%WO=f8=`b|jr$fx~COu<$v2c22;9-;0hA?*qGFKh2_(MFR1))3plU0Lo6(^K^;s zA~U5iU#3)`32?@GaE-kzh&3peg*-;0+N?NPGCo&hWd=Y+xkY0{QCb_r3D|7F7FeLs zkPeoe`!n>5aO}|nl)(7A{IVUYlYkk1-;9mU%`%4G21=z;)^G;=8k^|>Ac%O!3_6Zl zT}MxxmLZ5E+hluj0*WoY5_q1K4fbgR8M)FQoZz3B~ z)w4J3-Os2-rg5Bo@j@5?0IO~0KG_r8GMpUNFv=0n$9XBk5!ERb1h8AQ+0?#1j2$mC zz#3eeBsEhC;q%VT%^|zJ(Qw!_XpCl@9o>yMu_wd%mrj!rpGOX4n&9M-sWkZX&z24} zYi?%8mi>ZFJmoY^~ms`^RU< z^f8Fn$!myo*9_-WS!l=61jxex&hQ);F1*b8CS$g48`;tEP`13@?NSAMez0ZH!A1yh z-ZC%%+M_{^**u(TM|7F}TA^8_*&TmBjgfa;mAwzxO75Kih4XL5bx%)kEUQp9mFG*B zFY>vR)4--OGpb%wt_=V$o;w>^2EBj=Ipn|~`g;G>*v$c>x&)fK*S+%~Jb` zydfM27!5hcCOLa$Fm@JVpsPbED5|F0f+BCJMV56mn=J#xpv8{mBO^nxv2844VV!KA z<{1aNat>> zXN=z7&Nz`{Z0;8K1wbo!%6@HfE^gesjy-9Q0gTS0RD3QDVBUZ{=EK2bcZH3Y&UC)z z{yRUhxD2U!W4#v!!AY7g*3`hPXm06YooVEWsmbGn7enhJHD4RScCe?MY1bI}#*jpt z;^(X51r2Pd=_DWZz2|v(#jGd6B)ZbQx8bez$Y$a@V8R^Ozdr`WE0n=i5x5B$T)T3W zekF?poidkT=X6klbM02_S0J-wFOIZ5dIn(|*dWdObo86|<=M5l9?KZdf%jO3ENgo# zn=1xU22#b0x`Bvi^>(-Q+x9DhALw|2ZO^5kxi5iNufgS_ZZU~ro$xA|x>;zk_1`3sLehcf@mcL1B7o42JP875>pd6iYr~8a9VO6GC#cjy>~W)h zK74RL`+>hhkaqgaCBQaE2m?}bJwd-sd>EFSeZqG^kNGkV!a1U7P=F6_FpmqZuWVXIoP@oTU@SFx`qgKF@_w0>qt z1!4T7zqU#;v>eo;oV7Hox`WLqgRWm*RTa;vAbcg|ST+ib(_MI<>nIbmgv`E4kCgI& z&C0_Bu!m8(Q?Zc2-PQ4!>=2mI7g(AZ;SK;j8rms61)yYYSZK})j1ug;^nC++;* zt)FsOP9KFd$%-VP#U{YdCTBuj0qel<2l&lG$%`PRJ8?Z9GcUkMnC0|HadRx>Uz^3FO$qp3`=zAP4B z-B6?!kgv1%FbO&IJO}&|dT*48P)nPRDJ_d-n);G5EZ_-pHj5?PSZd^)rj!7`EC;F( ze-htMFq7^R(T5`ai2UN`k52QkCfU%_t}&k<`}yEc;*G~Yeulb4rgqUsE6Sg8DBHxI zAtoL+vE3$AVS#p0X8DtkKl=6epLy=-M}GXrzyGtp@+-f4g^#q6qFemx>#uMHl$^h_ zuR>w5?w>yVj&}`QfBD0OMCwGk3Um}BvP=+53L$3FX!1nBs8a|ciTF8&3EfNJ2t5~} zt+9?>G!@Tw?;h&;2p-IA%;S_?ynGpDL9-nWfZ4@TuDtG{(Wn0Enn2>ysnx zTcrBXC@vZ(6e{muo@Yifj)PhD2Ht1S0}rl>Du;pCp=n2Dp6jELl2MVM=FD!t-j{WKD$*FN zp(Jty)f>xX_%YOLI0725+XiY02TA9|z^yoT4^idcIwmT79Wm)&8oUOO|Dw~ZLx%%T z0AMg>rdG#RdTFsfs|W^Zz;;p2I-nXi9a5cfk!|0Piww#us$SGNW|DLg-3LLDGV96I z-hfNPP`RxO&EaX?x-}5dbUpJOz#_Zwwh-V{;1Ia>(%fY;XsCQnpCeE!n(5c->d zzM+ZWa*<$tKK?9?k~Cu)X>P2i&uRUkYZ|-KVl3nL2=Z*F#Jg}dKBPA=ydKAk7bV#=evY>VDAsA=c!pXaig>&aFg(shUnwskgeh=Cn zPL6?LK9-gg*&G^00TzQhSt|$(1|6f1jN3axXCylL%DhI^e@DY;g0JYj#riv*$6gqD z=j@D2_(=}^e-kR&0sJZ1#^S>ps z7!_nNWJsNR@%hl(yN~G)z6EIKQv&ETtbPqvTODowGo#2%)Ly*0|y32;zVvRC5_;vLi zoPEv{08d+c2idJ5WERH=eT>J=`3Jn@^Ihk4)~Uv_GuF-Voqnc{WGr1E;L(vy)90m@ zMxRr|{onJE4}Ca%_=7+A8=w3aKRI>i*s=4Yqf;xGfTl)*Sj9(&O+7Xyl2<-Shf<$c*%g-L$v@_%UcPQtB+i07daNulk0pBHLqOGZs@;_>?(I@I;9mqbwOKvbM1DdK2=dpD* z32kIgyXXPY*wDrr&eJgRGK=4cY|ezIPJNyC;9KM9*66(Qc{aYRAmCYsb>TR*0u-g` zVW`wl`!m=Evys|}5(0L0hfJml&Y2Fb!M5X4SJ1EZjMtN0XJG7_r(g`JUn0nb&UZfq znIZ!Y8P>O0#MW7+r(U>|?4BbvUp#$2%E=NsaR-M#hix!0u0m&3)mHEw=zLp|`;rdnDs<5nx1y+?^*5Q#LmiUiiifbT60ns7(e)B~Z7S;}U?I zy^=Nw+yv5;>q2%9D0Q*IwJEoC!kvERli1bE)$@7Y1@XG}m0f->47Goh`@} z(-FqTLIc_PR_wzBY$bciG*NbGv&bc6S*F=8eOwku1V~{Q_|R7FxNgX+ws#*4IKkn$ zS?cOJ`wi5DNBTJTBak|YUGv^+@Nev-um1PU=GPH$_QQ!#1}I4qJ{9bnL8g0RA}40j z&H9?qK(`6C2x`_6kTtj0hXdWM=*jB%JpqXY`U2zu+e__SPYrnr%6mS+7(#66*w{pr z4fk0vqJ+SGJqGE;q=-P(6ae$lqdfq@B$D{q;yjsTWL>|c*fdT?559`iaroR4WRy@8 zhG+}&$^DvS@M+N3>t>xRH8#Q)$76d2D}4b413W;?e{IReQD%N9z}>Gn|Zc`c7j za}KmeC9qe`z1#CZHfGcjoPF2bzvtrjbF2?+%T@wcem_5_e?VZz`Pa9}bB6pp*Hthc zGyt~lF6CLx*rzf&^D}ZYI~w(To}j*EFAb1+zsgNnw;5zB4T#&C8^Vnn{UlE&coxo! z&yBokCn+Vy*IbV4D<~4DW7xZg)hGZ^8(^04X9u0V3Sg1tux}%eRjg}{^>uCZ5$)4q z2rQVRKe@@DBz{5x-LeWG;wyoUvvIQJQ}#`W-{YL>-#SXNjJ2_}Kt`H=#TI^`z?w|j z96od@*Q+fnPIvK~=*y*u9h?%g3K*FoiDzR+r-7KXvze>bcav;CRxyGdJV3a5^;Q@i zx(Uj$77icZ&))CGCdS<)C1&wSwR58eNCV@vaYdi2ppAA9Jbhi1`V zF2t*^zk(I`I|&?o^rMBuyYBy5=X)P`=;Jffl@eL~}%h-cdG| zDM*Kvs^pI#bp65KLe9!lsQ&H1MmR$NG>;ovI`3KAC z{N*dD=JaKZ6UK21_5g-FI#%XLwcIAL>-S$4?px16}kq?`5MrDXoGIQr0kD5tNb9CQvGXUWuvM1 zBdFRMT>%5NrS$R)%#ljgy_DeZF>)T+Uno(2o=%en#$d|~dH@$VJF-l6QJx~s*3GFz z^JH!CiP>7w)tGzUeY`J>aUKR;9j#-fa#R`a6IdQm-eAVWF9T#Qkf6Mhe`DMLIHb^P zjC_pT)efZ! zHtbo%A)BF>#^y3LXnaNuGl2!F`p)%$e6yZ7opm^^l{l}RU37;hFnjqAzXxUdAhAC^yrv zF2Z@kVQ>a{><9N$R^A#;oZ!XP*RQ4FfeF?D8Q}?@SI<{u$qY=*aF+shu}+RJG+TGT zdC1nZW;12Ma^YNh&ZA^O@PIF`L3*Qd;{KEyL}(NN0d0^}AT^MOnLz(;Gr3yUC;CKi zD7IOjZ-3)k>CwY+UI(=oS<`sy7}|B%{qZ4Kq0_C?D?p$l9Y2$a&*if^y1L>%JV(}< zZ^BH{(UxT*m9YZaehz_@Sq3L?6f&l7lex@Yb=~14O^uJI(`U~HO}L2jI@~{$a(Zx5 zZE8xtg{h?(^iw&YKm$w}7$49^GdMX7=#L6$;Ijm`^PWcn>D)X52g)svwd{nE?HJVl?^EI?vG@#$H{9dzb05$?M%a88I`{ zQ(4deP|*gcX1}*tr&++~4{m*s*7+QkG%{K;q7HE4HaM4S?E5HoW_Wa*_2OLMxUsA} z;)M8*&$Zzk5!6C~M(S@$)!#Wb8YWjKw?-P}M=OVVII-J6Myui@Ywe&QG^p zjBLTrr*2A8>{33%ImzMq zyV!~!UB4D3EQh>qhM>-7m;gS%-oM%D?X!$pCiTziXdlz^F$Y+D0MBi35F%=0~dv9+~>N{}~T`2f)6eUru0E;;Y#m)EMqx41)xD=KO`!_L?&Ye9U z!S)`(iwp=S*BlZQ6z-GFV@+*NYi85_B$fmjgj)A5L&0*OCO}8oboMidWCVNQbt^B* zlc4?qGHhUAPZ(`XIQ%T6&$IDyE$6_7qL`LQUJMO944u~A%6qdW0t@qtG$W)Dfag}$ zkvjX>v7Xcf>(VasGVTNo!nX0blT#BRN3jR2_m#^R0(`SErE6@Dml;5B%Mx5$UK}hz znOu%ZRDT4}z_FGAkaEr**3`lzLr`2>$@R%@mh7k zE_Nb^`h1g6>RtVc@H4o76DmQWM=o7=KeLSH*fK5LWB*r5>8y-I`yeQ<>g*zXkQ_kZ z9Q3IDnVh6xd6oK0f5z+8cJ46oM+Sw#tIJ%39WE=uUSX%&+S}9m2<1TixA7Nw57u8G zqnZ9j_A+w9%)aHGY+NJ#GB)w+HYn?m;ox;~Qvq_W;wzYR6SUK(%mCmD?D1|{rh+oy zIp+SBwpK#7m?)|i0MZBN>UNL`UJ~zfgbXWVHQy5tlPsx z(-d|5JpTy$yC+MI=gVTySF<0Q;EwBC4x?G!=Y$%^dlz7z@~~k$=yc?pUOf83S9;8*J8{jGj+%Y!R*tNB^g>sYvT!m9& z!!V7`Yp=eRUU``g?4W?99L~n(Hb4u{r|F7x# zjfWUavP0Dd5cL?As%To%-P;?AdJVd$r3gCFQjk^ND>x$abJSdM-!^3muc|L%L}VTsU%xmNruHIFU(Ei1W=!el6G3f^1=+y#`*F+xMm+Z zD-qoCej=t-ZO22|i#}J<^Pq%%7wO$4b8lwK(uk_2ZtlB;fOIuv(f1OFP(~daXn-5< z%^x&=ewg1632qKBs%tAS3m6GxJ@f4B26WKP^k{gTnb=clXmkM3K!l%J+O<{b+{H`j zL|-@i*36`X=G5NWM3$CXIC>N8k^PlYnVtARAUZM}P0T6*8g}6zOO>=X-CAGKd1OS7X>tPpQJX|ZCY1h=C+L4D-1XWnlFjVz*7&YWc!)~)oYx)IK?%%(| z*(AtkU!>n|L*bXIZvgJSYy39>e9YuHZp`dzOwYieY20G1ye_U$=ghNhMpNUbk1xHf(rSqe%^1h_{I#R8av1f&3?`s=s(xs=K zVed}D%(#q>>0or~NYr^cGIn#__Xd=LW-Qfjb8VAr9F5GJ|3Ka9@RZPC&bNw1QuUS8e%gz4%CwgoXyD~qu zknY^N$r>r!S!WOx5|c)3kaqk;A9kP?xy0ecA@yEtDq9SzXBs9X9{mBT>gw1R`V_D~G7vng>O|#NTVaz!FGlM48fzRBepXSP;F*(tB9n|`2cTny z{#3ej;S9ELDRtARv4M50L)OXw(&wh8)0?loo`wg92y*w+)c6Fl?x;ywFVx+loAy{| zfgq(wmOC+8~a=drJrx3ssmhyGHx>ia~Oe`~RkP5T(APn83MG*&e9vSm$p#8@0rE<+mFf?UBCk>p(;$_kh3g?;=-KrgcqZZ)px1-ZiLTJjtB18gKFXPXP(sDg{3t8w3&52fMXteA|T~d1{0(O(A(|1vNSi2-Nt`Jz8vSR-!u(O+aA3i$Cd_Y;G`Z#^BNGVzIOG{1ZPAf5r9n zZ~ostI_|yxNGWVnZSo!rhh3&O=#!W@%Eu=uD5)Z2y#c^651_pgw$s;neF7%iOng`b zz{Lv-ps%*6nQH~~<$l#u0@lrd#?>{|afZ|_MaV`y!Lw6O)QL_lvuwmOw85FO50X06 zz;oBLM8;luEkoCP3!Xt`tq6Uawe8#^G9YtF7O?x_y2e;a7S(bC^|0^nx`YqF=XoD8 z6_kHjZBAhFA>dcT_1bJ(wyo1~iV6Dd^^(ti>~UT8__EZ?>0!J0K{i--ZymR}Pr^`t zq!QoX*gl`m2Xe|vw!l>cE9qKuf+a+^q+tG6+n9a>^$a2-hJ|G|KRWaS1-Tv z!(XB~-ILCwJ;H%FBBSMqr)bE8qT1&mZ0MMyz%v-p1rYNL^@i1C<#Rxdk8tFUaJocY zMR=WEt+8ytp+=q4MD9MFYx^yCgKpkA^l8$lQ#Av9@)Dp!QlEdYV)C85!5r$i2 zMg|`ZLSb7ZSRv*76Mr!q)YfhK1 zoJnUc9Y=ZLkfD^C8yZlgMX9Z`8Hb8;3_6V;0_|BFF70p`)OMC&a$%YI_Im|sg0Ao1 z{?Tjc=AB0zUNW5(WFT<@V6+1waQ`SJGxmW%>pT%?sZgz5(@3g_kLXe^HM|HVQ4AIR z#OY({=@ZV0@LoEwshf%GwI@$3+dTUJWB(&KF~&*7eU>s#zCvZP@g$_B3&kU zsHnnm0Of7%Y^7Us9Y%>PEXJ!Ch2+>AJa_+(g5p2yf{ld^psOFC7?0S`eFB;zu1#9L z6^qy)kXj6g#s()!&Ic+p42A|w@I&PjHSRhn7+UKgEj!Vu>|s>AcNL`X5gl|fa5^^b zi4zq{7`55c-Ahv_GUr^!0RhzxpJkS13ujD+Q&7Udw4Cf#WzX3xT8#eQ1F2u8iP1Kc zQ?nxmwbHc;aE1+zMD-nuDTVdOMlmRTuSwd6HKIpkFB}oX!jKuK%w=UKjV~;w5gh5e z_xjTZHy@_4$rZ{^767`W=F$WQgC_O7y|X=?y>K=?dEp#QIy-36(*WhSA=m~i3Gc`~ zqnvdP*Xg!AH)*3esG0M#X%?`ACL!UZ*)XZdavZMLb+KXLKCc5}Pi17oyG|TS&%N+; z>gs7n_OrlKA!o|kwJF}y;M5GAnJ10GrXU4@pqUnf3!NdGIVqPlIKKw*p2g|8WdMOJ z;OD05P)MUIp(DP)ga0=8vrm9vmrjPe?|w*uvuUJ8PJ@StalZ%){|~@}dogfR#sn4& z9I^lfzv1^9G)EfRD9a|PvKuDGCeqN*1oy-w6C53$m51^Z?GfSfA^3NW5NZ2Dy*+U zgCq2q`)2^7bLPGXRyne;l=pS4pTMIIm_Sw`B@ybcH2{$hZ@!95Zk*+bToF zjMyP(YhiH)hm~4O*2Um8f?Lk4&T!~D6i@6C_bK((GpH_<6;VoA$RY1JMV54Caw3Ap zuCBhch8&baDfOBcak5LGraOUR8NDWZq>OCJ6g1|C5ATNq-{0lASd2s4>_6VjCHgNBm!o04h2y*sI}h!h`Mw8HV!#^3Hxmo)`r2fv|Z1Q z0a`V|K_Pm^rkN}gK|4V+7pwCbPC5VfM9Ov$^b2s6^Y6Yypvt+k1ASXtW%~Gwm(s^x zc#5;8JTq31QHgnng)}$3mTrA;6XwJ?;OHD{#d|^gt)_;%j6F0!tz`Xc0SRg-4U>^l z!Pq*R)YkE{BY%}yue*T>7=j3)SJep-=m7fjcje57V3Dit&w>VKKWEUXE2{=Iel~!T z&OZpvCc1ltjI{Pf$G4%rhI0TF9$Be}-P6+1lAgpao;uf^PM_}!uwP)?{zem{L&2gj zC?7yJ7G~)I(|(N1?s~d??{;MD%dt1j+>85aE%H9=`v_K7|DBthUHir?hMupjrE~=Q z*?Wq{X^|-=Si(8q=FA9)tpYAOfhgEP1RIvHsE4!tb2w|f*89!nwfV5@^6-≪~4< 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ℑ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%0DSJxd$$}wUFvn& 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ⅆQbb=&2}6{FgwJ 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

HgWgVa&! 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 z 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

QIXY4 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 A3;+NC literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000000..ded29f7b9c --- /dev/null +++ b/docs/index.md @@ -0,0 +1,112 @@ +

+ HTTPX +

+ +

HTTPX 1.0 — Prelease.

+ +--- + +A complete HTTP toolkit for Python. Supporting both client & server, and available in either sync or async flavors. + +--- + +*Installation...* + +
+ +```{ .shell .httpx } +$ pip install --pre httpx +``` + +```{ .shell .ahttpx .hidden } +$ pip install --pre ahttpx +``` + +*Making requests as a client...* + + + +```{ .python .httpx } +>>> import httpx + +>>> r = httpx.get('https://www.example.org/') +>>> r + +>>> r.status_code +200 +>>> r.headers['content-type'] +'text/html; charset=UTF-8' +>>> r.text +'\n\n\nExample Domain...' +``` + +```{ .python .ahttpx .hidden } +>>> import ahttpx + +>>> r = await ahttpx.get('https://www.example.org/') +>>> r + +>>> r.status_code +200 +>>> r.headers['content-type'] +'text/html; charset=UTF-8' +>>> r.text +'\n\n\nExample Domain...' +``` + +*Serving responses as the server...* + + + +```{ .python .httpx } +>>> import httpx + +>>> def app(request): +... content = httpx.HTML('hello, world.') +... return httpx.Response(200, content=content) + +>>> httpx.run(app) +Serving on http://127.0.0.1:8080/ (Press CTRL+C to quit) +``` + +```{ .python .ahttpx .hidden } +>>> import ahttpx + +>>> async def app(request): +... content = httpx.HTML('hello, world.') +... return httpx.Response(200, content=content) + +>>> await httpx.run(app) +Serving on http://127.0.0.1:8080/ (Press CTRL+C to quit) +``` + +--- + +# Documentation + +* [Quickstart](quickstart.md) +* [Clients](clients.md) +* [Servers](servers.md) +* [Requests](requests.md) +* [Responses](responses.md) +* [URLs](urls.md) +* [Headers](headers.md) +* [Content Types](content-types.md) +* [Streams](streams.md) +* [Connections](connections.md) +* [Parsers](parsers.md) +* [Network Backends](networking.md) + +--- + +# Collaboration + +The repository for this project is currently private. + +We’re looking at creating paid opportunities for working on open source software *which are properly compensated, flexible & well balanced.* + +If you're interested in a position working on this project, please send an intro: *kim@encode.io* + +--- + +

This design work is not yet licensed for reuse.
— 🦋 —

diff --git a/docs/networking.md b/docs/networking.md new file mode 100644 index 0000000000..6375fdf291 --- /dev/null +++ b/docs/networking.md @@ -0,0 +1,381 @@ +# Network Backends + +The lowest level network abstractions in `httpx` are the `NetworkBackend` and `NetworkStream` classes. These provide a consistent interface onto the operations for working with a network stream, typically over a TCP connection. Different runtimes (threaded, trio & asyncio) are supported via alternative implementations of the core interface. + +--- + +## `NetworkBackend()` + +The default backend is instantiated via the `NetworkBackend` class... + + + +```{ .python .httpx } +>>> net = httpx.NetworkBackend() +>>> net + +``` + +```{ .python .ahttpx .hidden } +>>> net = ahttpx.NetworkBackend() +>>> net + +``` + +### `.connect(host, port)` + +A TCP stream is created using the `connect` method... + + + +```{ .python .httpx } +>>> net = httpx.NetworkBackend() +>>> stream = net.connect("www.encode.io", 80) +>>> stream + +``` + +```{ .python .ahttpx .hidden } +>>> net = ahttpx.NetworkBackend() +>>> stream = await net.connect("www.encode.io", 80) +>>> stream + +``` + +Streams support being used in a context managed style. The cleanest approach to resource management is to use `.connect(...)` in the context of a `with` block. + + + +```{ .python .httpx } +>>> net = httpx.NetworkBackend() +>>> with net.connect("dev.encode.io", 80) as stream: +>>> ... +>>> stream + +``` + +```{ .python .ahttpx .hidden } +>>> net = ahttpx.NetworkBackend() +>>> async with await net.connect("dev.encode.io", 80) as stream: +>>> ... +>>> stream + +``` + +## `NetworkStream(sock)` + +The `NetworkStream` class provides TCP stream abstraction, by providing a thin wrapper around a socket instance. + +Network streams do not provide any built-in thread or task locking. +Within `httpx` thread and task saftey is handled at the `Connection` layer. + +### `.read(max_bytes=None)` + +Read up to `max_bytes` bytes of data from the network stream. +If no limit is provided a default value of 64KB will be used. + +### `.write(data)` + +Write the given bytes of `data` to the network stream. + +### `.start_tls(ctx, hostname)` + +Upgrade a stream to TLS (SSL) connection for sending secure `https://` requests. + +`` + +### `.get_extra_info(key)` + +Return information about the underlying resource. May include... + +* `"client_addr"` - Return the client IP and port. +* `"server_addr"` - Return the server IP and port. +* `"ssl_object"` - Return an `ssl.SSLObject` instance. +* `"socket"` - Access the raw socket instance. + +### `.close()` + +Close the network stream. For TLS streams this will attempt to send a closing handshake before terminating the conmection. + + + +```{ .python .httpx } +>>> net = httpx.NetworkBackend() +>>> stream = net.connect("dev.encode.io", 80) +>>> try: +>>> ... +>>> finally: +>>> stream.close() +>>> stream + +``` + +```{ .python .ahttpx .hidden } +>>> net = ahttpx.NetworkBackend() +>>> stream = await net.connect("dev.encode.io", 80) +>>> try: +>>> ... +>>> finally: +>>> await stream.close() +>>> stream + +``` + +--- + +## Timeouts + +Network timeouts are handled using a context block API. + +This [design approach](https://vorpus.org/blog/timeouts-and-cancellation-for-humans) avoids timeouts needing to passed around throughout the stack, and provides an obvious and natural API to dealing with timeout contexts. + +### timeout(duration) + +The timeout context manager can be used to wrap socket operations anywhere in the stack. + +Here's an example of enforcing an overall 3 second timeout on a request. + + + +```{ .python .httpx } +>>> with httpx.Client() as cli: +>>> with httpx.timeout(3.0): +>>> res = cli.get('https://www.example.com') +>>> print(res) +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.Client() as cli: +>>> async with ahttpx.timeout(3.0): +>>> res = await cli.get('https://www.example.com') +>>> print(res) +``` + +Timeout contexts provide an API allowing for deadlines to be cancelled. + +### .cancel() + +In this example we enforce a 3 second timeout on *receiving the start of* a streaming HTTP response... + + + +```{ .python .httpx } +>>> with httpx.Client() as cli: +>>> with httpx.timeout(3.0) as t: +>>> with cli.stream('https://www.example.com') as r: +>>> t.cancel() +>>> print(">>>", res) +>>> for chunk in r.stream: +>>> print("...", chunk) +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.Client() as cli: +>>> async with ahttpx.timeout(3.0) as t: +>>> async with await cli.stream('https://www.example.com') as r: +>>> t.cancel() +>>> print(">>>", res) +>>> async for chunk in r.stream: +>>> print("...", chunk) +``` + +--- + +## Sending HTTP requests + +Let's take a look at how we can work directly with a network backend to send an HTTP request, and recieve an HTTP response. + + + +```{ .python .httpx } +import httpx +import ssl +import truststore + +net = httpx.NetworkBackend() +ctx = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT) +req = b'\r\n'.join([ + b'GET / HTTP/1.1', + b'Host: www.example.com', + b'User-Agent: python/dev', + b'Connection: close', + b'', + b'', +]) + +# Use a 10 second overall timeout for the entire request/response. +with httpx.timeout(10.0): + # Use a 3 second timeout for the initial connection. + with httpx.timeout(3.0) as t: + # Open the connection & establish SSL. + with net.connect("www.example.com", 443) as stream: + stream.start_tls(ctx, hostname="www.example.com") + t.cancel() + # Send the request & read the response. + stream.write(req) + buffer = [] + while part := stream.read(): + buffer.append(part) + resp = b''.join(buffer) +``` + +```{ .python .ahttpx .hidden } +import ahttpx +import ssl +import truststore + +net = ahttpx.NetworkBackend() +ctx = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT) +req = b'\r\n'.join([ + b'GET / HTTP/1.1', + b'Host: www.example.com', + b'User-Agent: python/dev', + b'Connection: close', + b'', + b'', +]) + +# Use a 10 second overall timeout for the entire request/response. +async with ahttpx.timeout(10.0): + # Use a 3 second timeout for the initial connection. + async with ahttpx.timeout(3.0) as t: + # Open the connection & establish SSL. + async with await net.connect("www.example.com", 443) as stream: + await stream.start_tls(ctx, hostname="www.example.com") + t.cancel() + # Send the request & read the response. + await stream.write(req) + buffer = [] + while part := await stream.read(): + buffer.append(part) + resp = b''.join(buffer) +``` + +The example above is somewhat contrived, there's no HTTP parsing implemented so we can't actually determine when the response is complete. We're using a `Connection: close` header to request that the server close the connection once the response is complete. + +A more complete example would require proper HTTP parsing. The `Connection` class implements an HTTP request/response interface, layered over a `NetworkStream`. + +--- + +## Custom network backends + +The interface for implementing custom network backends is provided by two classes... + +### `NetworkBackendInterface` + +The abstract interface implemented by `NetworkBackend`. See above for details. + +### `NetworkStreamInterface` + +The abstract interface implemented by `NetworkStream`. See above for details. + +### An example backend + +We can use these interfaces to implement custom functionality. For example, here we're providing a network backend that logs all the ingoing and outgoing bytes. + + + +```{ .python .httpx } +class RecordingBackend(httpx.NetworkBackendInterface): + def __init__(self): + self._backend = NetworkBackend() + + def connect(self, host, port): + # Delegate creating connections to the default + # network backend, and return a wrapped stream. + stream = self._backend.connect(host, port) + return RecordingStream(stream) + + +class RecordingStream(httpx.NetworkStreamInterface): + def __init__(self, stream): + self._stream = stream + + def read(self, max_bytes: int = None): + # Print all incoming data to the terminal. + data = self._stream.read(max_bytes) + lines = data.decode('ascii', errors='replace').splitlines() + for line in lines: + print("<<< ", line) + return data + + def write(self, data): + # Print all outgoing data to the terminal. + lines = data.decode('ascii', errors='replace').splitlines() + for line in lines: + print(">>> ", line) + self._stream.write(data) + + def start_tls(ctx, hostname): + self._stream.start_tls(ctx, hostname) + + def get_extra_info(key): + return self._stream.get_extra_info(key) + + def close(): + self._stream.close() +``` + +```{ .python .ahttpx .hidden } +class RecordingBackend(ahhtpx.NetworkBackendInterface): + def __init__(self): + self._backend = NetworkBackend() + + async def connect(self, host, port): + # Delegate creating connections to the default + # network backend, and return a wrapped stream. + stream = await self._backend.connect(host, port) + return RecordingStream(stream) + + +class RecordingStream(ahttpx.NetworkStreamInterface): + def __init__(self, stream): + self._stream = stream + + async def read(self, max_bytes: int = None): + # Print all incoming data to the terminal. + data = await self._stream.read(max_bytes) + lines = data.decode('ascii', errors='replace').splitlines() + for line in lines: + print("<<< ", line) + return data + + async def write(self, data): + # Print all outgoing data to the terminal. + lines = data.decode('ascii', errors='replace').splitlines() + for line in lines: + print(">>> ", line) + await self._stream.write(data) + + async def start_tls(ctx, hostname): + await self._stream.start_tls(ctx, hostname) + + def get_extra_info(key): + return self._stream.get_extra_info(key) + + async def close(): + await self._stream.close() +``` + +We can now instantiate a client using this network backend. + + + +```{ .python .httpx } +>>> transport = httpx.ConnectionPool(backend=RecordingBackend()) +>>> cli = httpx.Client(transport=transport) +>>> cli.get('https://www.example.com') +``` + +```{ .python .ahttpx .hidden } +>>> transport = ahttpx.ConnectionPool(backend=RecordingBackend()) +>>> cli = ahttpx.Client(transport=transport) +>>> await cli.get('https://www.example.com') +``` + +Custom network backends can also be used to provide functionality such as handling DNS caching for name lookups, or connecting via a UNIX domain socket instead of a TCP connection. + +--- + +← [Parsers](parsers.md) +  diff --git a/docs/parsers.md b/docs/parsers.md new file mode 100644 index 0000000000..3416c923f4 --- /dev/null +++ b/docs/parsers.md @@ -0,0 +1,110 @@ +# Parsers + +### Client + + + +```{ .python .httpx } +stream = httpx.DuplexStream( + b'HTTP/1.1 200 OK\r\n' + b'Content-Length: 23\r\n' + b'Content-Type: application/json\r\n' + b'\r\n' + b'{"msg": "hello, world"}' +) +p = ahttpx.HTTPParser(stream, mode='CLIENT') + +# Send the request... +p.send_method_line(b'GET', b'/', b'HTTP/1.1') +p.send_headers([(b'Host', b'www.example.com')]) +p.send_body(b'') + +# Receive the response... +protocol, code, reason_phase = p.recv_status_line() +headers = p.recv_headers() +body = b'' +while buffer := p.recv_body(): + body += buffer +``` + +```{ .python .ahttpx .hidden } +stream = ahttpx.DuplexStream( + b'HTTP/1.1 200 OK\r\n' + b'Content-Length: 23\r\n' + b'Content-Type: application/json\r\n' + b'\r\n' + b'{"msg": "hello, world"}' +) +p = ahttpx.HTTPParser(stream, mode='CLIENT') + +# Send the request... +await p.send_method_line(b'GET', b'/', b'HTTP/1.1') +await p.send_headers([(b'Host', b'www.example.com')]) +await p.send_body(b'') + +# Receive the response... +protocol, code, reason_phase = await p.recv_status_line() +headers = await p.recv_headers() +body = b'' +while buffer := await p.recv_body(): + body += buffer +``` + +### Server + + + +```{ .python .httpx } +stream = httpx.DuplexStream( + b'GET / HTTP/1.1\r\n' + b'Host: www.example.com\r\n' + b'\r\n' +) +p = httpx.HTTPParser(stream, mode='SERVER') + +# Receive the request... +method, target, protocol = p.recv_method_line() +headers = p.recv_headers() +body = b'' +while buffer := p.recv_body(): + body += buffer + +# Send the response... +p.send_status_line(b'HTTP/1.1', 200, b'OK') +p.send_headers([ + (b'Content-Length', b'23'), + (b'Content-Type', b'application/json') +]) +p.send_body(b'{"msg": "hello, world"}') +p.send_body(b'') +``` + +```{ .python .ahttpx .hidden } +stream = ahttpx.DuplexStream( + b'GET / HTTP/1.1\r\n' + b'Host: www.example.com\r\n' + b'\r\n' +) +p = ahttpx.HTTPParser(stream, mode='SERVER') + +# Receive the request... +method, target, protocol = await p.recv_method_line() +headers = await p.recv_headers() +body = b'' +while buffer := await p.recv_body(): + body += buffer + +# Send the response... +await p.send_status_line(b'HTTP/1.1', 200, b'OK') +await p.send_headers([ + (b'Content-Length', b'23'), + (b'Content-Type', b'application/json') +]) +await p.send_body(b'{"msg": "hello, world"}') +await p.send_body(b'') +``` + +--- + +← [Connections](connections.md) +[Low Level Networking](networking.md) → diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 0000000000..c3a6068253 --- /dev/null +++ b/docs/quickstart.md @@ -0,0 +1,484 @@ +# QuickStart + +Install using ... + + + +```{ .shell .httpx } +$ pip install --pre httpx +``` + +```{ .shell .ahttpx .hidden } +$ pip install --pre ahttpx +``` + +First, start by importing `httpx`... + + + +```{ .python .httpx } +>>> import httpx +``` + +```{ .python .ahttpx .hidden } +>>> import ahttpx +``` + +Now, let’s try to get a webpage. + + + +```{ .python .httpx } +>>> r = httpx.get('https://httpbin.org/get') +>>> r + +``` + +```{ .python .ahttpx .hidden } +>>> r = await ahttpx.get('https://httpbin.org/get') +>>> r + +``` + +To make an HTTP `POST` request, including some content... + + + +```{ .python .httpx } +>>> form = httpx.Form({'key': 'value'}) +>>> r = httpx.post('https://httpbin.org/post', content=form) +``` + +```{ .python .ahttpx .hidden } +>>> form = httpx.Form({'key': 'value'}) +>>> r = await ahttpx.post('https://httpbin.org/post', content=form) +``` + +Shortcut methods for `PUT`, `PATCH`, and `DELETE` requests follow the same style... + + + +```{ .python .httpx } +>>> r = httpx.put('https://httpbin.org/put', content=form) +>>> r = httpx.patch('https://httpbin.org/patch', content=form) +>>> r = httpx.delete('https://httpbin.org/delete') +``` + +```{ .python .ahttpx .hidden } +>>> r = await ahttpx.put('https://httpbin.org/put', content=form) +>>> r = await ahttpx.patch('https://httpbin.org/patch', content=form) +>>> r = await ahttpx.delete('https://httpbin.org/delete') +``` + +## Passing Parameters in URLs + +To include URL query parameters in the request, construct a URL using the `params` keyword... + + + +```{ .python .httpx } +>>> params = {'key1': 'value1', 'key2': 'value2'} +>>> url = httpx.URL('https://httpbin.org/get', params=params) +>>> r = httpx.get(url) +``` + +```{ .python .ahttpx .hidden } +>>> params = {'key1': 'value1', 'key2': 'value2'} +>>> url = ahttpx.URL('https://httpbin.org/get', params=params) +>>> r = await ahttpx.get(url) +``` + +You can also pass a list of items as a value... + + + +```{ .python .httpx } +>>> params = {'key1': 'value1', 'key2': ['value2', 'value3']} +>>> url = httpx.URL('https://httpbin.org/get', params=params) +>>> r = httpx.get(url) +``` + +```{ .python .ahttpx .hidden } +>>> params = {'key1': 'value1', 'key2': ['value2', 'value3']} +>>> url = ahttpx.URL('https://httpbin.org/get', params=params) +>>> r = await ahttpx.get(url) +``` + +## Custom Headers + +To include additional headers in the outgoing request, use the `headers` keyword argument... + + + +```{ .python .httpx } +>>> url = 'https://httpbin.org/headers' +>>> headers = {'User-Agent': 'my-app/0.0.1'} +>>> r = httpx.get(url, headers=headers) +``` + +```{ .python .ahttpx .hidden } +>>> url = 'https://httpbin.org/headers' +>>> headers = {'User-Agent': 'my-app/0.0.1'} +>>> r = await ahttpx.get(url, headers=headers) +``` + +--- + +## Response Content + +HTTPX will automatically handle decoding the response content into unicode text. + + + +```{ .python .httpx } +>>> r = httpx.get('https://www.example.org/') +>>> r.text +'\n\n\nExample Domain...' +``` + +```{ .python .ahttpx .hidden } +>>> r = await ahttpx.get('https://www.example.org/') +>>> r.text +'\n\n\nExample Domain...' +``` + +## Binary Response Content + +The response content can also be accessed as bytes, for non-text responses. + + + +```{ .python .httpx } +>>> r.body +b'\n\n\nExample Domain...' +``` + +```{ .python .ahttpx .hidden } +>>> r.body +b'\n\n\nExample Domain...' +``` + +## JSON Response Content + +Often Web API responses will be encoded as JSON. + + + +```{ .python .httpx } +>>> r = httpx.get('https://httpbin.org/get') +>>> r.json() +{'args': {}, 'headers': {'Host': 'httpbin.org', 'User-Agent': 'dev', 'X-Amzn-Trace-Id': 'Root=1-679814d5-0f3d46b26686f5013e117085'}, 'origin': '21.35.60.128', 'url': 'https://httpbin.org/get'} +``` + +```{ .python .ahttpx .hidden } +>>> r = await ahttpx.get('https://httpbin.org/get') +>>> await r.json() +{'args': {}, 'headers': {'Host': 'httpbin.org', 'User-Agent': 'dev', 'X-Amzn-Trace-Id': 'Root=1-679814d5-0f3d46b26686f5013e117085'}, 'origin': '21.35.60.128', 'url': 'https://httpbin.org/get'} +``` + +--- + +## Sending Form Encoded Data + +Some types of HTTP requests, such as `POST` and `PUT` requests, can include data in the request body. One common way of including that is as form-encoded data, which is used for HTML forms. + + + +```{ .python .httpx } +>>> form = httpx.Form({'key1': 'value1', 'key2': 'value2'}) +>>> r = httpx.post("https://httpbin.org/post", content=form) +>>> r.json() +{ + ... + "form": { + "key2": "value2", + "key1": "value1" + }, + ... +} +``` + +```{ .python .ahttpx .hidden } +>>> form = ahttpx.Form({'key1': 'value1', 'key2': 'value2'}) +>>> r = await ahttpx.post("https://httpbin.org/post", content=form) +>>> await r.json() +{ + ... + "form": { + "key2": "value2", + "key1": "value1" + }, + ... +} +``` + +Form encoded data can also include multiple values from a given key. + + + +```{ .python .httpx } +>>> form = httpx.Form({'key1': ['value1', 'value2']}) +>>> r = httpx.post("https://httpbin.org/post", content=form) +>>> r.json() +{ + ... + "form": { + "key1": [ + "value1", + "value2" + ] + }, + ... +} +``` + +```{ .python .ahttpx .hidden } +>>> form = ahttpx.Form({'key1': ['value1', 'value2']}) +>>> r = await ahttpx.post("https://httpbin.org/post", content=form) +>>> await r.json() +{ + ... + "form": { + "key1": [ + "value1", + "value2" + ] + }, + ... +} +``` + +## Sending Multipart File Uploads + +You can also upload files, using HTTP multipart encoding. + + + +```{ .python .httpx } +>>> files = httpx.Files({'upload': httpx.File('uploads/report.xls')}) +>>> r = httpx.post("https://httpbin.org/post", content=files) +>>> r.json() +{ + ... + "files": { + "upload": "<... binary content ...>" + }, + ... +} +``` + +```{ .python .ahttpx .hidden } +>>> files = ahttpx.Files({'upload': httpx.File('uploads/report.xls')}) +>>> r = await ahttpx.post("https://httpbin.org/post", content=files) +>>> await r.json() +{ + ... + "files": { + "upload": "<... binary content ...>" + }, + ... +} +``` + +If you need to include non-file data fields in the multipart form, use the `data=...` parameter: + + + +```{ .python .httpx } +>>> form = {'message': 'Hello, world!'} +>>> files = {'upload': httpx.File('uploads/report.xls')} +>>> data = httpx.MultiPart(form=form, files=files) +>>> r = httpx.post("https://httpbin.org/post", content=data) +>>> r.json() +{ + ... + "files": { + "upload": "<... binary content ...>" + }, + "form": { + "message": "Hello, world!", + }, + ... +} +``` + +```{ .python .ahttpx .hidden } +>>> form = {'message': 'Hello, world!'} +>>> files = {'upload': httpx.File('uploads/report.xls')} +>>> data = ahttpx.MultiPart(form=form, files=files) +>>> r = await ahttpx.post("https://httpbin.org/post", content=data) +>>> await r.json() +{ + ... + "files": { + "upload": "<... binary content ...>" + }, + "form": { + "message": "Hello, world!", + }, + ... +} +``` + +## Sending JSON Encoded Data + +Form encoded data is okay if all you need is a simple key-value data structure. +For more complicated data structures you'll often want to use JSON encoding instead. + + + +```{ .python .httpx } +>>> data = {'integer': 123, 'boolean': True, 'list': ['a', 'b', 'c']} +>>> r = httpx.post("https://httpbin.org/post", content=httpx.JSON(data)) +>>> r.json() +{ + ... + "json": { + "boolean": true, + "integer": 123, + "list": [ + "a", + "b", + "c" + ] + }, + ... +} +``` + +```{ .python .ahttpx .hidden } +>>> data = {'integer': 123, 'boolean': True, 'list': ['a', 'b', 'c']} +>>> r = await ahttpx.post("https://httpbin.org/post", content=httpx.JSON(data)) +>>> await r.json() +{ + ... + "json": { + "boolean": true, + "integer": 123, + "list": [ + "a", + "b", + "c" + ] + }, + ... +} +``` + +## Sending Binary Request Data + +For other encodings, you should use the `content=...` parameter, passing +either a `bytes` type or a generator that yields `bytes`. + + + +```{ .python .httpx } +>>> content = b'Hello, world' +>>> r = httpx.post("https://httpbin.org/post", content=content) +``` + +```{ .python .ahttpx .hidden } +>>> content = b'Hello, world' +>>> r = await ahttpx.post("https://httpbin.org/post", content=content) +``` + +You may also want to set a custom `Content-Type` header when uploading +binary data. + +--- + +## Response Status Codes + +We can inspect the HTTP status code of the response: + + + +```{ .python .httpx } +>>> r = httpx.get('https://httpbin.org/get') +>>> r.status_code +200 +``` + +```{ .python .ahttpx .hidden } +>>> r = await ahttpx.get('https://httpbin.org/get') +>>> r.status_code +200 +``` + +## Response Headers + +The response headers are available as a dictionary-like interface. + + + +```{ .python .httpx } +>>> r.headers + +``` + +```{ .python .ahttpx .hidden } +>>> r.headers + +``` + +The `Headers` data type is case-insensitive, so you can use any capitalization. + + + +```{ .python .httpx } +>>> r.headers.get('Content-Type') +'application/json' + +>>> r.headers.get('content-type') +'application/json' +``` + +```{ .python .ahttpx .hidden } +>>> r.headers.get('Content-Type') +'application/json' + +>>> r.headers.get('content-type') +'application/json' +``` + +--- + +## Streaming Responses + +For large downloads you may want to use streaming responses that do not load the entire response body into memory at once. + +You can stream the binary content of the response... + + + +```{ .python .httpx } +>>> with httpx.stream("GET", "https://www.example.com") as r: +... for data in r.stream: +... print(data) +``` + +```{ .python .ahttpx .hidden } +>>> async with ahttpx.stream("GET", "https://www.example.com") as r: +... async for data in r.stream: +... print(data) +``` + +--- + +← [Home](index.md) +[Clients](clients.md) → +  \ No newline at end of file diff --git a/docs/requests.md b/docs/requests.md new file mode 100644 index 0000000000..7f27125189 --- /dev/null +++ b/docs/requests.md @@ -0,0 +1,178 @@ +# Requests + +The core elements of an HTTP request are the `method`, `url`, `headers` and `body`. + + + +```{ .python .httpx } +>>> req = httpx.Request('GET', 'https://www.example.com/') +>>> req + +>>> req.method +'GET' +>>> req.url + +>>> req.headers + +>>> req.body +b'' +``` + +```{ .python .ahttpx .hidden } +>>> req = ahttpx.Request('GET', 'https://www.example.com/') +>>> req + +>>> req.method +'GET' +>>> req.url + +>>> req.headers + +>>> req.body +b'' +``` + +## Working with the request headers + +The following headers have automatic behavior with `Requests` instances... + +* `Host` - A `Host` header must always be included on a request. This header is automatically populated from the `url`, using the `url.netloc` property. +* `Content-Length` - Requests including a request body must always include either a `Content-Length` header or a `Transfer-Encoding: chunked` header. This header is automatically populated if `content` is not `None` and the content is a known size. +* `Transfer-Encoding` - Requests automatically include a `Transfer-Encoding: chunked` header if `content` is not `None` and the content is an unkwown size. +* `Content-Type` - Requests automatically include a `Content-Type` header if `content` is set using the [Content Type] API. + +## Working with the request body + +Including binary data directly... + + + +```{ .python .httpx } +>>> headers = {'Content-Type': 'application/json'} +>>> content = json.dumps(...) +>>> httpx.Request('POST', 'https://echo.encode.io/', content=content) +``` + +```{ .python .ahttpx .hidden } +>>> headers = {'Content-Type': 'application/json'} +>>> content = json.dumps(...) +>>> ahttpx.Request('POST', 'https://echo.encode.io/', content=content) +``` + +## Working with content types + +Including JSON request content... + + + +```{ .python .httpx } +>>> data = httpx.JSON(...) +>>> httpx.Request('POST', 'https://echo.encode.io/', content=data) +``` + +```{ .python .ahttpx .hidden } +>>> data = ahttpx.JSON(...) +>>> ahttpx.Request('POST', 'https://echo.encode.io/', content=data) +``` + +Including form encoded request content... + + + +```{ .python .httpx } +>>> data = httpx.Form(...) +>>> httpx.Request('PUT', 'https://echo.encode.io/', content=data) +``` + +```{ .python .ahttpx .hidden } +>>> data = ahttpx.Form(...) +>>> ahttpx.Request('PUT', 'https://echo.encode.io/', content=data) +``` + +Including multipart file uploads... + + + +```{ .python .httpx } +>>> form = httpx.MultiPart(form={...}, files={...}) +>>> with httpx.Request('POST', 'https://echo.encode.io/', content=form) as req: +>>> req.headers +{...} +>>> req.stream + +``` + +```{ .python .ahttpx .hidden } +>>> form = ahttpx.MultiPart(form={...}, files={...}) +>>> async with ahttpx.Request('POST', 'https://echo.encode.io/', content=form) as req: +>>> req.headers +{...} +>>> req.stream + +``` + +Including direct file uploads... + + + +```{ .python .httpx } +>>> file = httpx.File('upload.json') +>>> with httpx.Request('POST', 'https://echo.encode.io/', content=file) as req: +>>> req.headers +{...} +>>> req.stream + +``` + +```{ .python .ahttpx .hidden } +>>> file = ahttpx.File('upload.json') +>>> async with ahttpx.Request('POST', 'https://echo.encode.io/', content=file) as req: +>>> req.headers +{...} +>>> req.stream + +``` + +## Accessing request content + +*In progress...* + + + +```{ .python .httpx } +>>> data = request.json() +``` + +```{ .python .ahttpx .hidden } +>>> data = await request.json() +``` + +... + + + +```{ .python .httpx } +>>> form = request.form() +``` + +```{ .python .ahttpx .hidden } +>>> form = await request.form() +``` + +... + + + +```{ .python .httpx } +>>> files = request.files() +``` + +```{ .python .ahttpx .hidden } +>>> files = await request.files() +``` + +--- + +← [Servers](servers.md) +[Responses](responses.md) → +  diff --git a/docs/responses.md b/docs/responses.md new file mode 100644 index 0000000000..58ef2e494d --- /dev/null +++ b/docs/responses.md @@ -0,0 +1,131 @@ +# Responses + +The core elements of an HTTP response are the `status_code`, `headers` and `body`. + + + +```{ .python .httpx } +>>> resp = httpx.Response(200, headers={'Content-Type': 'text/plain'}, content=b'hello, world') +>>> resp + +>>> resp.status_code +200 +>>> resp.headers + +>>> resp.body +b'hello, world' +``` + +```{ .python .ahttpx .hidden } +>>> resp = ahttpx.Response(200, headers={'Content-Type': 'text/plain'}, content=b'hello, world') +>>> resp + +>>> resp.status_code +200 +>>> resp.headers + +>>> resp.body +b'hello, world' +``` + +## Working with the response headers + +The following headers have automatic behavior with `Response` instances... + +* `Content-Length` - Responses including a response body must always include either a `Content-Length` header or a `Transfer-Encoding: chunked` header. This header is automatically populated if `content` is not `None` and the content is a known size. +* `Transfer-Encoding` - Responses automatically include a `Transfer-Encoding: chunked` header if `content` is not `None` and the content is an unkwown size. +* `Content-Type` - Responses automatically include a `Content-Type` header if `content` is set using the [Content Type] API. + +## Working with content types + +Including HTML content... + + + +```{ .python .httpx } +>>> content = httpx.HTML('......') +>>> response = httpx.Response(200, content=content) +``` + +```{ .python .ahttpx .hidden } +>>> content = ahttpx.HTML('......') +>>> response = ahttpx.Response(200, content=content) +``` + +Including plain text content... + + + +```{ .python .httpx } +>>> content = httpx.Text('hello, world') +>>> response = httpx.Response(200, content=content) +``` + +```{ .python .ahttpx .hidden } +>>> content = ahttpx.Text('hello, world') +>>> response = ahttpx.Response(200, content=content) +``` + +Including JSON data... + + + +```{ .python .httpx } +>>> content = httpx.JSON({'message': 'hello, world'}) +>>> response = httpx.Response(200, content=content) +``` + +```{ .python .ahttpx .hidden } +>>> content = ahttpx.JSON({'message': 'hello, world'}) +>>> response = ahttpx.Response(200, content=content) +``` + +Including content from a file... + + + +```{ .python .httpx } +>>> content = httpx.File('index.html') +>>> with httpx.Response(200, content=content) as response: +... pass +``` + +```{ .python .ahttpx .hidden } +>>> content = ahttpx.File('index.html') +>>> async with ahttpx.Response(200, content=content) as response: +... pass +``` + +## Accessing response content + +... + + + +```{ .python .httpx } +>>> response.body +``` + +```{ .python .ahttpx .hidden } +>>> response.body +``` + +... + + + +```{ .python .httpx } +>>> response.text +... +``` + +```{ .python .ahttpx .hidden } +>>> response.text +... +``` + +--- + +← [Requests](requests.md) +[URLs](urls.md) → +  diff --git a/docs/servers.md b/docs/servers.md new file mode 100644 index 0000000000..57e79c33b8 --- /dev/null +++ b/docs/servers.md @@ -0,0 +1,85 @@ +# Servers + +The HTTP server provides a simple request/response API. +This gives you a lightweight way to build web applications or APIs. + +### `serve_http(endpoint)` + + + +```{ .python .httpx } +>>> website = """ +... +... +... +... +... +...
hello, world
+... +... +... """ + +>>> def hello_world(request): +... content = httpx.HTML(website) +... return httpx.Response(200, content=content) + +>>> with httpx.serve_http(hello_world) as server: +... print(f"Serving on {server.url} (Press CTRL+C to quit)") +... server.wait() +Serving on http://127.0.0.1:8080/ (Press CTRL+C to quit) +``` + +```{ .python .ahttpx .hidden } +>>> import httpx + +>>> website = """ +... +... +... +... +... +...
hello, world
+... +... +... """ + +>>> async def hello_world(request): +... if request.path != '/': +... content = httpx.Text("Not found") +... return httpx.Response(404, content=content) +... content = httpx.HTML(website) +... return httpx.Response(200, content=content) + +>>> async with httpx.serve_http(hello_world) as server: +... print(f"Serving on {server.url} (Press CTRL+C to quit)") +... await server.wait() +Serving on http://127.0.0.1:8080/ (Press CTRL+C to quit) +``` + +--- + +*Docs in progress...* + +--- + +← [Clients](clients.md) +[Requests](requests.md) → +  diff --git a/docs/streams.md b/docs/streams.md new file mode 100644 index 0000000000..53c32d6821 --- /dev/null +++ b/docs/streams.md @@ -0,0 +1,88 @@ +# Streams + +Streams provide a minimal file-like interface for reading bytes from a data source. They are used as the abstraction for reading the body of a request or response. + +The interfaces here are simplified versions of Python's standard I/O operations. + +## Stream + +The base `Stream` class. The core of the interface is a subset of Python's `io.IOBase`... + +* `.read(size=-1)` - *(bytes)* Return the bytes from the data stream. If the `size` argument is omitted or negative then the entire stream will be read. If `size` is an positive integer then the call returns at most `size` bytes. A return value of `b''` indicates the end of the stream has been reached. +* `.write(self, data: bytes)` - *None* Write the given bytes to the data stream. May raise `NotImplmentedError` if this is not a writeable stream. +* `.close()` - Close the stream. Any further operations will raise a `ValueError`. + +Additionally, the following property is also defined... + +* `.size` - *(int or None)* Return an integer indicating the size of the stream, or `None` if the size is unknown. When working with HTTP this is used to either set a `Content-Length: ` header, or a `Content-Encoding: chunked` header. + +The `Stream` interface and `ContentType` interface are related, with streams being used as the abstraction for the bytewise representation, and content types being used to encapsulate the parsed data structure. + +For example, encoding some `JSON` data... + +```python +>>> data = httpx.JSON({'name': 'zelda', 'score': '478'}) +>>> stream = data.encode() +>>> stream.read() +b'{"name":"zelda","score":"478"}' +>>> stream.content_type +'application/json' +``` + +--- + +## ByteStream + +A byte stream returning fixed byte content. Similar to Python's `io.BytesIO` class. + +```python +>>> s = httpx.ByteStream(b'{"msg": "Hello, world!"}') +>>> s.read() +b'{"msg": "Hello, world!"}' +``` + +## FileStream + +A byte stream returning content from a file. + +The standard pattern for instantiating a `FileStream` is to use `File` as a context manager: + +```python +>>> with httpx.File('upload.json') as s: +... s.read() +b'{"msg": "Hello, world!"}' +``` + +## MultiPartStream + +A byte stream returning multipart upload data. + +The standard pattern for instantiating a `MultiPartStream` is to use `MultiPart` as a context manager: + +```python +>>> files = {'avatar-upload': 'image.png'} +>>> with httpx.MultiPart(files=files) as s: +... s.read() +# ... +``` + +## HTTPStream + +A byte stream returning unparsed content from an HTTP request or response. + +```python +>>> with httpx.Client() as cli: +... r = cli.get('https://www.example.com/') +... r.stream.read() +# ... +``` + +## GZipStream + +... + +--- + +← [Content Types](content-types.md) +[Connections](connections.md) → +  diff --git a/docs/templates/base.html b/docs/templates/base.html new file mode 100644 index 0000000000..22fe4d3796 --- /dev/null +++ b/docs/templates/base.html @@ -0,0 +1,186 @@ + + + + + + httpx + + + + + + + + + + + + + +
+ {{ content }} +
+ + \ No newline at end of file diff --git a/docs/urls.md b/docs/urls.md new file mode 100644 index 0000000000..ef56b18495 --- /dev/null +++ b/docs/urls.md @@ -0,0 +1,240 @@ +# URLs + +The `URL` class handles URL validation and parsing. + + + +```{ .python .httpx } +>>> url = httpx.URL('https://www.example.com/') +>>> url + +``` + +```{ .python .ahttpx .hidden } +>>> url = ahttpx.URL('https://www.example.com/') +>>> url + +``` + +URL components are normalised, following the same rules as internet browsers. + + + +```{ .python .httpx } +>>> url = httpx.URL('https://www.EXAMPLE.com:443/path/../main') +>>> url + +``` + +```{ .python .ahttpx .hidden } +>>> url = ahttpx.URL('https://www.EXAMPLE.com:443/path/../main') +>>> url + +``` + +Both absolute and relative URLs are valid. + + + +```{ .python .httpx } +>>> url = httpx.URL('/README.md') +>>> url + +``` + +```{ .python .ahttpx .hidden } +>>> url = ahttpx.URL('/README.md') +>>> url + +``` + +Coercing a URL to a `str` will always result in a printable ASCII string. + + + +```{ .python .httpx } +>>> url = httpx.URL('https://example.com/path to here?search=🦋') +>>> str(url) +'https://example.com/path%20to%20here?search=%F0%9F%A6%8B' +``` + +```{ .python .ahttpx .hidden } +>>> url = ahttpx.URL('https://example.com/path to here?search=🦋') +>>> str(url) +'https://example.com/path%20to%20here?search=%F0%9F%A6%8B' +``` + +### URL components + +The following properties are available for accessing the component parts of a URL. + +* `.scheme` - *str. ASCII. Normalised to lowercase.* +* `.userinfo` - *str. ASCII. URL encoded.* +* `.username` - *str. Unicode.* +* `.password` - *str. Unicode.* +* `.host` - *str. ASCII. IDNA encoded.* +* `.port` - *int or None. Scheme default ports are normalised to None.* +* `.authority` - *str. ASCII. IDNA encoded. Eg. "example.com", "example.com:1337", "xn--p1ai".* +* `.path` - *str. Unicode.* +* `.query` - *str. ASCII. URL encoded.* +* `.target` - *str. ASCII. URL encoded.* +* `.fragment` - *str. ASCII. URL encoded.* + +A parsed representation of the query parameters is accessible with the `.params` property. + +* `.params` - [`QueryParams`](#query-parameters) + +URLs can be instantiated from their components... + + + +```{ .python .httpx } +>>> httpx.URL(scheme="https", host="example.com", path="/") + +``` + +```{ .python .ahttpx .hidden } +>>> ahttpx.URL(scheme="https", host="example.com", path="/") + +``` + +Or using both the string form and query parameters... + + + +```{ .python .httpx } +>>> httpx.URL("https://example.com/", params={"search": "some text"}) + +``` + +```{ .python .ahttpx .hidden } +>>> ahttpx.URL("https://example.com/", params={"search": "some text"}) + +``` + +### Modifying URLs + +Instances of `URL` are immutable, meaning their value cannot be changed. Instead new modified instances may be created. + +* `.copy_with(**components)` - *Return a new URL, updating one or more components. Eg. `url = url.copy_with(scheme="https")`*. +* `.copy_set_param(key, value)` - *Return a new URL, setting a query parameter. Eg. `url = url.copy_set_param("sort_by", "price")`*. +* `.copy_append_param(key, value)` - *Return a new URL, setting or appending a query parameter. Eg. `url = url.copy_append_param("tag", "sale")`*. +* `.copy_remove_param(key)` - *Return a new URL, removing a query parameter. Eg. `url = url.copy_remove_param("max_price")`*. +* `.copy_update_params(params)` - *Return a new URL, updating the query parameters. Eg. `url = url.copy_update_params({"color_scheme": "dark"})`*. +* `.join(url)` - *Return a new URL, given this URL as the base and another URL as the target. Eg. `url = url.join("../navigation")`*. + +--- + +## Query Parameters + +The `QueryParams` class provides an immutable multi-dict for accessing URL query parameters. + +They can be instantiated from a dictionary. + + + +```{ .python .httpx } +>>> params = httpx.QueryParams({"color": "black", "size": "medium"}) +>>> params + +``` + +```{ .python .ahttpx .hidden } +>>> params = ahttpx.QueryParams({"color": "black", "size": "medium"}) +>>> params + +``` + +Multiple values for a single key are valid. + + + +```{ .python .httpx } +>>> params = httpx.QueryParams({"filter": ["60GHz", "75GHz", "100GHz"]}) +>>> params + +``` + +```{ .python .ahttpx .hidden } +>>> params = ahttpx.QueryParams({"filter": ["60GHz", "75GHz", "100GHz"]}) +>>> params + +``` + +They can also be instantiated directly from a query string. + + + +```{ .python .httpx } +>>> params = httpx.QueryParams("color=black&size=medium") +>>> params + +``` + +```{ .python .ahttpx .hidden } +>>> params = ahttpx.QueryParams("color=black&size=medium") +>>> params + +``` + +Keys and values are always represented as strings. + + + +```{ .python .httpx } +>>> params = httpx.QueryParams("sort_by=published&author=natalie") +>>> params["sort_by"] +'published' +``` + +```{ .python .ahttpx .hidden } +>>> params = ahttpx.QueryParams("sort_by=published&author=natalie") +>>> params["sort_by"] +'published' +``` + +When coercing query parameters to strings you'll see the same escaping behavior as HTML form submissions. The result will always be a printable ASCII string. + + + +```{ .python .httpx } +>>> params = httpx.QueryParams({"email": "user@example.com", "search": "How HTTP works!"}) +>>> str(params) +'email=user%40example.com&search=How+HTTP+works%21' +``` + +```{ .python .ahttpx .hidden } +>>> params = ahttpx.QueryParams({"email": "user@example.com", "search": "How HTTP works!"}) +>>> str(params) +'email=user%40example.com&search=How+HTTP+works%21' +``` + +### Accessing query parameters + +Query parameters are accessed using a standard dictionary style interface... + +* `.get(key, default=None)` - *Return the value for a given key, or a default value. If multiple values for the key are present, only the first will be returned.* +* `.keys()` - *Return the unique keys of the query parameters. Each key will be a `str` instance.* +* `.values()` - *Return the values of the query parameters. Each value will be a list of one or more `str` instances.* +* `.items()` - *Return the key value pairs of the query parameters. Each item will be a two-tuple including a `str` instance as the key, and a list of one or more `str` instances as the value.* + +The following methods are also available for accessing query parameters as a multidict... + +* `.get_all(key)` - *Return all the values for a given key. Returned as a list of zero or more `str` instances.* +* `.multi_items()` - *Return the key value pairs of the query parameters. Each item will be a two-tuple `(str, str)`. Repeated keys may occur.* +* `.multi_dict()` - *Return the query parameters as a dictionary, with each value being a list of one or more `str` instances.* + +### Modifying query parameters + +The following methods can be used to create modified query parameter instances... + +* `.copy_set(key, value)` +* `.copy_append(key, value)` +* `.copy_remove(key)` +* `.copy_update(params)` + +--- + +← [Responses](responses.md) +[Headers](headers.md) → +  \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000..e708b5d962 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,30 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "httpx" +description = "HTTP, for Python." +requires-python = ">=3.10" +authors = [ + { name = "Tom Christie", email = "tom@tomchristie.com" }, +] +classifiers = [ + "Development Status :: 4 - Beta", + "Environment :: Web Environment", + "Intended Audience :: Developers", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Internet :: WWW/HTTP", +] +dependencies = [ + "certifi", +] +dynamic = ["version"] + +[tool.hatch.version] +path = "src/httpx/__version__.py" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000..f4d4bb3809 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,17 @@ +-e . + +# Build... +build==1.2.2 + +# Test... +mypy==1.15.0 +pytest==8.3.5 +pytest-cov==6.1.1 + +# Sync & Async mirroring... +unasync==0.6.0 + +# Documentation... +click==8.2.1 +jinja2==3.1.6 +markdown==3.8 diff --git a/scripts/build b/scripts/build new file mode 100755 index 0000000000..c7e14690a0 --- /dev/null +++ b/scripts/build @@ -0,0 +1,32 @@ +#!/bin/sh + +PKG=$1 + +if [ "$PKG" != "httpx" ] && [ "$PKG" != "ahttpx" ] ; then + echo "build [httpx|ahttpx]" + exit 1 +fi + +export PREFIX="" +if [ -d 'venv' ] ; then + export PREFIX="venv/bin/" +fi + +# Create pyproject-httpx.toml and pyproject-ahttpx.toml +cp pyproject.toml pyproject-httpx.toml +cat pyproject-httpx.toml | sed 's/name = "httpx"/name = "ahttpx"/' > pyproject-ahttpx.toml + +# Build the releases +if [ "$PKG" == "httpx" ]; then + ${PREFIX}python -m build +fi +if [ "$PKG" == "ahttpx" ]; then + cp pyproject-ahttpx.toml pyproject.toml + ${PREFIX}python -m build + cp pyproject-httpx.toml pyproject.toml +fi + +# Clean up +rm pyproject-httpx.toml pyproject-ahttpx.toml + +echo $PKG \ No newline at end of file diff --git a/scripts/docs b/scripts/docs new file mode 100755 index 0000000000..8c53da4786 --- /dev/null +++ b/scripts/docs @@ -0,0 +1,153 @@ +#!venv/bin/python +import pathlib +import posixpath + +import click +import ghp_import +import logging +import httpx +import jinja2 +import markdown + +import xml.etree.ElementTree as etree + + +pages = { + '/': 'docs/index.md', + '/quickstart': 'docs/quickstart.md', + '/clients': 'docs/clients.md', + '/servers': 'docs/servers.md', + '/requests': 'docs/requests.md', + '/responses': 'docs/responses.md', + '/urls': 'docs/urls.md', + '/headers': 'docs/headers.md', + '/content-types': 'docs/content-types.md', + '/streams': 'docs/streams.md', + '/connections': 'docs/connections.md', + '/parsers': 'docs/parsers.md', + '/networking': 'docs/networking.md', + '/about': 'docs/about.md', +} + +def path_to_url(path): + if path == "index.md": + return "/" + return f"/{path[:-3]}" + + +class URLsProcessor(markdown.treeprocessors.Treeprocessor): + def __init__(self, state): + self.state = state + + def run(self, root: etree.Element) -> etree.Element: + for element in root.iter(): + if element.tag == 'a': + key = 'href' + elif element.tag == 'img': + key = 'src' + else: + continue + + url_or_path = element.get(key) + if url_or_path is not None: + output_url = self.rewrite_url(url_or_path) + element.set(key, output_url) + + return root + + def rewrite_url(self, href: str) -> str: + if not href.endswith('.md'): + return href + + current_url = path_to_url(self.state.file) + linked_url = path_to_url(href) + return posixpath.relpath(linked_url, start=current_url) + + +class BuildState: + def __init__(self): + self.file = '' + + +state = BuildState() +env = jinja2.Environment( + loader=jinja2.FileSystemLoader('docs/templates'), + autoescape=False +) +template = env.get_template('base.html') +md = markdown.Markdown(extensions=['fenced_code']) +md.treeprocessors.register( + item=URLsProcessor(state), + name='urls', + priority=10, +) + + +def not_found(): + text = httpx.Text('Not Found') + return httpx.Response(404, content=text) + + +def web_server(request): + if request.url.path not in pages: + return not_found() + + file = pages[request.url.path] + text = pathlib.Path(file).read_text() + + state.file = file + content = md.convert(text) + html = template.render(content=content).encode('utf-8') + content = httpx.HTML(html) + return httpx.Response(200, content=html) + + +@click.group() +def main(): + pass + + +@main.command() +def build(): + pathlib.Path("build").mkdir(exist_ok=True) + + for url, path in pages.items(): + basename = url.lstrip("/") + output = f"build/{basename}.html" if basename else "build/index.html" + text = pathlib.Path(path).read_text() + content = md.convert(text) + html = template.render(content=content) + pathlib.Path(output).write_text(html) + print(f"Built {output}") + + +@main.command() +def serve(): + logging.basicConfig( + format="%(levelname)s [%(asctime)s] %(name)s - %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + level=logging.INFO + ) + + with httpx.serve_http(web_server) as server: + server.wait() + + +@main.command() +def deploy(): + ghp_import.ghp_import( + "build", + mesg="Documentation deploy", + remote="origin", + branch="gh-pages", + push=True, + force=False, + use_shell=False, + no_history=False, + nojekyll=True, + ) + print(f"Deployed to GitHub") + + +if __name__ == "__main__": + main() diff --git a/scripts/install b/scripts/install new file mode 100755 index 0000000000..1b531e57cd --- /dev/null +++ b/scripts/install @@ -0,0 +1,13 @@ +#!/bin/sh + +set -x + +if [ -z "$GITHUB_ACTIONS" ]; then + python3 -m venv venv + PIP="venv/bin/pip" +else + PIP="pip" +fi + +"$PIP" install -U pip +"$PIP" install -r requirements.txt diff --git a/scripts/publish b/scripts/publish new file mode 100755 index 0000000000..6e6955f5e3 --- /dev/null +++ b/scripts/publish @@ -0,0 +1,15 @@ +#!/bin/sh + +PKG=$1 + +if [ "$PKG" != "httpx" ] && [ "$PKG" != "ahttpx" ] ; then + echo "publish [httpx|ahttpx]" + exit 1 +fi + +export PREFIX="" +if [ -d 'venv' ] ; then + export PREFIX="venv/bin/" +fi +${PREFIX}pip install -q twine +${PREFIX}twine upload dist/$PKG-* diff --git a/scripts/test b/scripts/test new file mode 100755 index 0000000000..1e0812cd07 --- /dev/null +++ b/scripts/test @@ -0,0 +1,10 @@ +#!/bin/sh + +export PREFIX="" +if [ -d 'venv' ] ; then + export PREFIX="venv/bin/" +fi + +${PREFIX}mypy src/httpx +${PREFIX}mypy src/ahttpx +${PREFIX}pytest --cov src/httpx tests diff --git a/scripts/unasync b/scripts/unasync new file mode 100755 index 0000000000..67d66b5c88 --- /dev/null +++ b/scripts/unasync @@ -0,0 +1,29 @@ +#!venv/bin/python +import unasync + +unasync.unasync_files( + fpath_list = [ + "src/ahttpx/__init__.py", + "src/ahttpx/__version__.py", + "src/ahttpx/_client.py", + "src/ahttpx/_content.py", + "src/ahttpx/_headers.py", + "src/ahttpx/_parsers.py", + "src/ahttpx/_pool.py", + "src/ahttpx/_quickstart.py", + "src/ahttpx/_response.py", + "src/ahttpx/_request.py", + "src/ahttpx/_server.py", + "src/ahttpx/_streams.py", + "src/ahttpx/_urlencode.py", + "src/ahttpx/_urlparse.py", + "src/ahttpx/_urls.py", + ], + rules = [ + unasync.Rule( + "src/ahttpx/", + "src/httpx/", + additional_replacements={"ahttpx": "httpx"} + ), + ] +) diff --git a/src/ahttpx/__init__.py b/src/ahttpx/__init__.py new file mode 100644 index 0000000000..9e589ab6cd --- /dev/null +++ b/src/ahttpx/__init__.py @@ -0,0 +1,65 @@ +from .__version__ import __title__, __version__ +from ._client import * # Client +from ._content import * # Content, File, Files, Form, HTML, JSON, MultiPart, Text +from ._headers import * # Headers +from ._network import * # NetworkBackend, NetworkStream, timeout +from ._parsers import * # HTTPParser, ProtocolError +from ._pool import * # Connection, ConnectionPool, Transport +from ._quickstart import * # get, post, put, patch, delete +from ._response import * # Response +from ._request import * # Request +from ._streams import * # ByteStream, DuplexStream, FileStream, HTTPStream, Stream +from ._server import * # serve_http, run +from ._urlencode import * # quote, unquote, urldecode, urlencode +from ._urls import * # QueryParams, URL + + +__all__ = [ + "__title__", + "__version__", + "ByteStream", + "Client", + "Connection", + "ConnectionPool", + "Content", + "delete", + "DuplexStream", + "File", + "FileStream", + "Files", + "Form", + "get", + "Headers", + "HTML", + "HTTPParser", + "HTTPStream", + "JSON", + "MultiPart", + "NetworkBackend", + "NetworkStream", + "open_connection", + "post", + "ProtocolError", + "put", + "patch", + "Response", + "Request", + "run", + "serve_http", + "Stream", + "Text", + "timeout", + "Transport", + "QueryParams", + "quote", + "unquote", + "URL", + "urldecode", + "urlencode", +] + + +__locals = locals() +for __name in __all__: + if not __name.startswith('__'): + setattr(__locals[__name], "__module__", "httpx") diff --git a/src/ahttpx/__version__.py b/src/ahttpx/__version__.py new file mode 100644 index 0000000000..309fcb32b6 --- /dev/null +++ b/src/ahttpx/__version__.py @@ -0,0 +1,2 @@ +__title__ = "ahttpx" +__version__ = "1.0.dev3" \ No newline at end of file diff --git a/src/ahttpx/_client.py b/src/ahttpx/_client.py new file mode 100644 index 0000000000..6326ac5de9 --- /dev/null +++ b/src/ahttpx/_client.py @@ -0,0 +1,156 @@ +import types +import typing + +from ._content import Content +from ._headers import Headers +from ._pool import ConnectionPool, Transport +from ._request import Request +from ._response import Response +from ._streams import Stream +from ._urls import URL + +__all__ = ["Client"] + + +class Client: + def __init__( + self, + url: URL | str | None = None, + headers: Headers | typing.Mapping[str, str] | None = None, + transport: Transport | None = None, + ): + if url is None: + url = "" + if headers is None: + headers = {"User-Agent": "dev"} + if transport is None: + transport = ConnectionPool() + + self.url = URL(url) + self.headers = Headers(headers) + self.transport = transport + self.via = RedirectMiddleware(self.transport) + + def build_request( + self, + method: str, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Request: + return Request( + method=method, + url=self.url.join(url), + headers=self.headers.copy_update(headers), + content=content, + ) + + async def request( + self, + method: str, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Response: + request = self.build_request(method, url, headers=headers, content=content) + async with await self.via.send(request) as response: + await response.read() + return response + + async def stream( + self, + method: str, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Response: + request = self.build_request(method, url, headers=headers, content=content) + return await self.via.send(request) + + async def get( + self, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + ): + return await self.request("GET", url, headers=headers) + + async def post( + self, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ): + return await self.request("POST", url, headers=headers, content=content) + + async def put( + self, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ): + return await self.request("PUT", url, headers=headers, content=content) + + async def patch( + self, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ): + return await self.request("PATCH", url, headers=headers, content=content) + + async def delete( + self, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + ): + return await self.request("DELETE", url, headers=headers) + + async def close(self): + await self.transport.close() + + async def __aenter__(self): + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None + ): + await self.close() + + def __repr__(self): + return f"" + + +class RedirectMiddleware(Transport): + def __init__(self, transport: Transport) -> None: + self._transport = transport + + def is_redirect(self, response: Response) -> bool: + return ( + response.status_code in (301, 302, 303, 307, 308) + and "Location" in response.headers + ) + + def build_redirect_request(self, request: Request, response: Response) -> Request: + raise NotImplementedError() + + async def send(self, request: Request) -> Response: + while True: + response = await self._transport.send(request) + + if not self.is_redirect(response): + return response + + # If we have a redirect, then we read the body of the response. + # Ensures that the HTTP connection is available for a new + # request/response cycle. + await response.read() + await response.close() + + # We've made a request-response and now need to issue a redirect request. + request = self.build_redirect_request(request, response) + + async def close(self): + pass diff --git a/src/ahttpx/_content.py b/src/ahttpx/_content.py new file mode 100644 index 0000000000..e2c4aaa935 --- /dev/null +++ b/src/ahttpx/_content.py @@ -0,0 +1,378 @@ +import json +import os +import typing + +from ._streams import Stream, ByteStream, FileStream, MultiPartStream +from ._urlencode import urldecode, urlencode + +__all__ = [ + "Content", + "Form", + "File", + "Files", + "JSON", + "MultiPart", + "Text", + "HTML", +] + +# https://github.com/nginx/nginx/blob/master/conf/mime.types +_content_types = { + ".json": "application/json", + ".js": "application/javascript", + ".html": "text/html", + ".css": "text/css", + ".png": "image/png", + ".jpeg": "image/jpeg", + ".jpg": "image/jpeg", + ".gif": "image/gif", +} + + +class Content: + def encode(self) -> Stream: + raise NotImplementedError() + + def content_type(self) -> str: + raise NotImplementedError() + + +class Form(typing.Mapping[str, str], Content): + """ + HTML form data, as an immutable multi-dict. + Form parameters, as a multi-dict. + """ + + def __init__( + self, + form: ( + typing.Mapping[str, str | typing.Sequence[str]] + | typing.Sequence[tuple[str, str]] + | str + | None + ) = None, + ) -> None: + d: dict[str, list[str]] = {} + + if form is None: + d = {} + elif isinstance(form, str): + d = urldecode(form) + elif isinstance(form, typing.Mapping): + # Convert dict inputs like: + # {"a": "123", "b": ["456", "789"]} + # To dict inputs where values are always lists, like: + # {"a": ["123"], "b": ["456", "789"]} + d = {k: [v] if isinstance(v, str) else list(v) for k, v in form.items()} + else: + # Convert list inputs like: + # [("a", "123"), ("a", "456"), ("b", "789")] + # To a dict representation, like: + # {"a": ["123", "456"], "b": ["789"]} + for k, v in form: + d.setdefault(k, []).append(v) + + self._dict = d + + # Content API + + def encode(self) -> Stream: + content = str(self).encode("ascii") + return ByteStream(content) + + def content_type(self) -> str: + return "application/x-www-form-urlencoded" + + # Dict operations + + def keys(self) -> typing.KeysView[str]: + return self._dict.keys() + + def values(self) -> typing.ValuesView[str]: + return {k: v[0] for k, v in self._dict.items()}.values() + + def items(self) -> typing.ItemsView[str, str]: + return {k: v[0] for k, v in self._dict.items()}.items() + + def get(self, key: str, default: typing.Any = None) -> typing.Any: + if key in self._dict: + return self._dict[key][0] + return default + + # Multi-dict operations + + def multi_items(self) -> list[tuple[str, str]]: + multi_items: list[tuple[str, str]] = [] + for k, v in self._dict.items(): + multi_items.extend([(k, i) for i in v]) + return multi_items + + def multi_dict(self) -> dict[str, list[str]]: + return {k: list(v) for k, v in self._dict.items()} + + def get_list(self, key: str) -> list[str]: + return list(self._dict.get(key, [])) + + # Update operations + + def copy_set(self, key: str, value: str) -> "Form": + d = self.multi_dict() + d[key] = [value] + return Form(d) + + def copy_append(self, key: str, value: str) -> "Form": + d = self.multi_dict() + d[key] = d.get(key, []) + [value] + return Form(d) + + def copy_remove(self, key: str) -> "Form": + d = self.multi_dict() + d.pop(key, None) + return Form(d) + + # Accessors & built-ins + + def __getitem__(self, key: str) -> str: + return self._dict[key][0] + + def __contains__(self, key: typing.Any) -> bool: + return key in self._dict + + def __iter__(self) -> typing.Iterator[str]: + return iter(self.keys()) + + def __len__(self) -> int: + return len(self._dict) + + def __bool__(self) -> bool: + return bool(self._dict) + + def __hash__(self) -> int: + return hash(str(self)) + + def __eq__(self, other: typing.Any) -> bool: + return ( + isinstance(other, Form) and + sorted(self.multi_items()) == sorted(other.multi_items()) + ) + + def __str__(self) -> str: + return urlencode(self.multi_dict()) + + def __repr__(self) -> str: + return f"" + + +class File(Content): + """ + Wrapper class used for files in uploads and multipart requests. + """ + + def __init__(self, path: str): + self._path = path + + def name(self) -> str: + return os.path.basename(self._path) + + def size(self) -> int: + return os.path.getsize(self._path) + + def encode(self) -> Stream: + return FileStream(self._path) + + def content_type(self) -> str: + _, ext = os.path.splitext(self._path) + ct = _content_types.get(ext, "application/octet-stream") + if ct.startswith('text/'): + ct += "; charset='utf-8'" + return ct + + def __lt__(self, other: typing.Any) -> bool: + return isinstance(other, File) and other._path < self._path + + def __eq__(self, other: typing.Any) -> bool: + return isinstance(other, File) and other._path == self._path + + def __repr__(self) -> str: + return f"" + + +class Files(typing.Mapping[str, File], Content): + """ + File parameters, as a multi-dict. + """ + + def __init__( + self, + files: ( + typing.Mapping[str, File | typing.Sequence[File]] + | typing.Sequence[tuple[str, File]] + | None + ) = None, + boundary: str = '' + ) -> None: + d: dict[str, list[File]] = {} + + if files is None: + d = {} + elif isinstance(files, typing.Mapping): + d = {k: [v] if isinstance(v, File) else list(v) for k, v in files.items()} + else: + d = {} + for k, v in files: + d.setdefault(k, []).append(v) + + self._dict = d + self._boundary = boundary or os.urandom(16).hex() + + # Standard dict interface + def keys(self) -> typing.KeysView[str]: + return self._dict.keys() + + def values(self) -> typing.ValuesView[File]: + return {k: v[0] for k, v in self._dict.items()}.values() + + def items(self) -> typing.ItemsView[str, File]: + return {k: v[0] for k, v in self._dict.items()}.items() + + def get(self, key: str, default: typing.Any = None) -> typing.Any: + if key in self._dict: + return self._dict[key][0] + return None + + # Multi dict interface + def multi_items(self) -> list[tuple[str, File]]: + multi_items: list[tuple[str, File]] = [] + for k, v in self._dict.items(): + multi_items.extend([(k, i) for i in v]) + return multi_items + + def multi_dict(self) -> dict[str, list[File]]: + return {k: list(v) for k, v in self._dict.items()} + + def get_list(self, key: str) -> list[File]: + return list(self._dict.get(key, [])) + + # Content interface + def encode(self) -> Stream: + return MultiPart(files=self).encode() + + def content_type(self) -> str: + return f"multipart/form-data; boundary={self._boundary}" + + # Builtins + def __getitem__(self, key: str) -> File: + return self._dict[key][0] + + def __contains__(self, key: typing.Any) -> bool: + return key in self._dict + + def __iter__(self) -> typing.Iterator[str]: + return iter(self.keys()) + + def __len__(self) -> int: + return len(self._dict) + + def __bool__(self) -> bool: + return bool(self._dict) + + def __eq__(self, other: typing.Any) -> bool: + return ( + isinstance(other, Files) and + sorted(self.multi_items()) == sorted(other.multi_items()) + ) + + def __repr__(self) -> str: + return f"" + + +class JSON(Content): + def __init__(self, data: typing.Any) -> None: + self._data = data + + def encode(self) -> Stream: + content = json.dumps( + self._data, + ensure_ascii=False, + separators=(",", ":"), + allow_nan=False + ).encode("utf-8") + return ByteStream(content) + + def content_type(self) -> str: + return "application/json" + + def __repr__(self) -> str: + return f"" + + +class Text(Content): + def __init__(self, text: str) -> None: + self._text = text + + def encode(self) -> Stream: + content = self._text.encode("utf-8") + return ByteStream(content) + + def content_type(self) -> str: + return "text/plain; charset='utf-8'" + + def __repr__(self) -> str: + return f"" + + +class HTML(Content): + def __init__(self, text: str) -> None: + self._text = text + + def encode(self) -> Stream: + content = self._text.encode("utf-8") + return ByteStream(content) + + def content_type(self) -> str: + return "text/html; charset='utf-8'" + + def __repr__(self) -> str: + return f"" + + +class MultiPart(Content): + def __init__( + self, + form: ( + Form + | typing.Mapping[str, str | typing.Sequence[str]] + | typing.Sequence[tuple[str, str]] + | str + | None + ) = None, + files: ( + Files + | typing.Mapping[str, File | typing.Sequence[File]] + | typing.Sequence[tuple[str, File]] + | None + ) = None, + boundary: str | None = None + ): + self._form = form if isinstance(form , Form) else Form(form) + self._files = files if isinstance(files, Files) else Files(files) + self._boundary = os.urandom(16).hex() if boundary is None else boundary + + @property + def form(self) -> Form: + return self._form + + @property + def files(self) -> Files: + return self._files + + def encode(self) -> Stream: + form = [(key, value) for key, value in self._form.items()] + files = [(key, file._path) for key, file in self._files.items()] + return MultiPartStream(form, files, boundary=self._boundary) + + def content_type(self) -> str: + return f"multipart/form-data; boundary={self._boundary}" + + def __repr__(self) -> str: + return f"" diff --git a/src/ahttpx/_headers.py b/src/ahttpx/_headers.py new file mode 100644 index 0000000000..dade8058d0 --- /dev/null +++ b/src/ahttpx/_headers.py @@ -0,0 +1,243 @@ +import re +import typing + + +__all__ = ["Headers"] + + +VALID_HEADER_CHARS = ( + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "!#$%&'*+-.^_`|~" +) + + +# TODO... +# +# * Comma folded values, eg. `Vary: ...` +# * Multiple Set-Cookie headers. +# * Non-ascii support. +# * Ordering, including `Host` header exception. + + +def headername(name: str) -> str: + if name.strip(VALID_HEADER_CHARS) or not name: + raise ValueError(f"Invalid HTTP header name {name!r}.") + return name + + +def headervalue(value: str) -> str: + value = value.strip(" ") + if not value or not value.isascii() or not value.isprintable(): + raise ValueError(f"Invalid HTTP header value {value!r}.") + return value + + +class Headers(typing.Mapping[str, str]): + def __init__( + self, + headers: typing.Mapping[str, str] | typing.Sequence[tuple[str, str]] | None = None, + ) -> None: + # {'accept': ('Accept', '*/*')} + d: dict[str, str] = {} + + if isinstance(headers, typing.Mapping): + # Headers({ + # 'Content-Length': '1024', + # 'Content-Type': 'text/plain; charset=utf-8', + # ) + d = {headername(k): headervalue(v) for k, v in headers.items()} + elif headers is not None: + # Headers([ + # ('Location', 'https://www.example.com'), + # ('Set-Cookie', 'session_id=3498jj489jhb98jn'), + # ]) + d = {headername(k): headervalue(v) for k, v in headers} + + self._dict = d + + def keys(self) -> typing.KeysView[str]: + """ + Return all the header keys. + + Usage: + + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert list(h.keys()) == ["Accept", "User-Agent"] + """ + return self._dict.keys() + + def values(self) -> typing.ValuesView[str]: + """ + Return all the header values. + + Usage: + + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert list(h.values()) == ["*/*", "python/httpx"] + """ + return self._dict.values() + + def items(self) -> typing.ItemsView[str, str]: + """ + Return all headers as (key, value) tuples. + + Usage: + + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert list(h.items()) == [("Accept", "*/*"), ("User-Agent", "python/httpx")] + """ + return self._dict.items() + + def get(self, key: str, default: typing.Any = None) -> typing.Any: + """ + Get a value from the query param for a given key. If the key occurs + more than once, then only the first value is returned. + + Usage: + + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert h.get("User-Agent") == "python/httpx" + """ + for k, v in self._dict.items(): + if k.lower() == key.lower(): + return v + return default + + def copy_set(self, key: str, value: str) -> "Headers": + """ + Return a new Headers instance, setting the value of a key. + + Usage: + + h = httpx.Headers({"Expires": "0"}) + h = h.copy_set("Expires", "Wed, 21 Oct 2015 07:28:00 GMT") + assert h == httpx.Headers({"Expires": "Wed, 21 Oct 2015 07:28:00 GMT"}) + """ + l = [] + seen = False + + # Either insert... + for k, v in self._dict.items(): + if k.lower() == key.lower(): + l.append((key, value)) + seen = True + else: + l.append((k, v)) + + # Or append... + if not seen: + l.append((key, value)) + + return Headers(l) + + def copy_remove(self, key: str) -> "Headers": + """ + Return a new Headers instance, removing the value of a key. + + Usage: + + h = httpx.Headers({"Accept": "*/*"}) + h = h.copy_remove("Accept") + assert h == httpx.Headers({}) + """ + h = {k: v for k, v in self._dict.items() if k.lower() != key.lower()} + return Headers(h) + + def copy_update(self, update: "Headers" | typing.Mapping[str, str] | None) -> "Headers": + """ + Return a new Headers instance, removing the value of a key. + + Usage: + + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + h = h.copy_update({"Accept-Encoding": "gzip"}) + assert h == httpx.Headers({"Accept": "*/*", "Accept-Encoding": "gzip", "User-Agent": "python/httpx"}) + """ + if update is None: + return self + + new = update if isinstance(update, Headers) else Headers(update) + + # Remove updated items using a case-insensitive approach... + keys = set([key.lower() for key in new.keys()]) + h = {k: v for k, v in self._dict.items() if k.lower() not in keys} + + # Perform the actual update... + h.update(dict(new)) + + return Headers(h) + + def __getitem__(self, key: str) -> str: + match = key.lower() + for k, v in self._dict.items(): + if k.lower() == match: + return v + raise KeyError(key) + + def __contains__(self, key: typing.Any) -> bool: + match = key.lower() + return any(k.lower() == match for k in self._dict.keys()) + + def __iter__(self) -> typing.Iterator[str]: + return iter(self.keys()) + + def __len__(self) -> int: + return len(self._dict) + + def __bool__(self) -> bool: + return bool(self._dict) + + def __eq__(self, other: typing.Any) -> bool: + self_lower = {k.lower(): v for k, v in self.items()} + other_lower = {k.lower(): v for k, v in Headers(other).items()} + return self_lower == other_lower + + def __repr__(self) -> str: + return f"" + + +def parse_opts_header(header: str) -> tuple[str, dict[str, str]]: + # The Content-Type header is described in RFC 2616 'Content-Type' + # https://datatracker.ietf.org/doc/html/rfc2616#section-14.17 + + # The 'type/subtype; parameter' format is described in RFC 2616 'Media Types' + # https://datatracker.ietf.org/doc/html/rfc2616#section-3.7 + + # Parameter quoting is described in RFC 2616 'Transfer Codings' + # https://datatracker.ietf.org/doc/html/rfc2616#section-3.6 + + header = header.strip() + content_type = '' + params = {} + + # Match the content type (up to the first semicolon or end) + match = re.match(r'^([^;]+)', header) + if match: + content_type = match.group(1).strip().lower() + rest = header[match.end():] + else: + return '', {} + + # Parse parameters, accounting for quoted strings + param_pattern = re.compile(r''' + ;\s* # Semicolon + optional whitespace + (?P[^=;\s]+) # Parameter key + = # Equal sign + (?P # Parameter value: + "(?:[^"\\]|\\.)*" # Quoted string with escapes + | # OR + [^;]* # Unquoted string (until semicolon) + ) + ''', re.VERBOSE) + + for match in param_pattern.finditer(rest): + key = match.group('key').lower() + value = match.group('value').strip() + if value.startswith('"') and value.endswith('"'): + # Remove surrounding quotes and unescape + value = re.sub(r'\\(.)', r'\1', value[1:-1]) + params[key] = value + + return content_type, params diff --git a/src/ahttpx/_network.py b/src/ahttpx/_network.py new file mode 100644 index 0000000000..957e036167 --- /dev/null +++ b/src/ahttpx/_network.py @@ -0,0 +1,120 @@ +import asyncio +import ssl +import types +import typing + +import certifi + +from ._streams import Stream + + +__all__ = ["NetworkBackend", "NetworkStream", "timeout"] + + +class NetworkStream(Stream): + def __init__( + self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter, address: str = '' + ) -> None: + self._reader = reader + self._writer = writer + self._address = address + self._tls = False + self._closed = False + + async def read(self, size: int = -1) -> bytes: + if size < 0: + size = 64 * 1024 + return await self._reader.read(size) + + async def write(self, buffer: bytes) -> None: + self._writer.write(buffer) + await self._writer.drain() + + async def close(self) -> None: + if not self._closed: + self._writer.close() + await self._writer.wait_closed() + self._closed = True + + def __repr__(self): + description = "" + description += " TLS" if self._tls else "" + description += " CLOSED" if self._closed else "" + return f"" + + def __del__(self): + if not self._closed: + import warnings + warnings.warn("NetworkStream was garbage collected without being closed.") + + # Context managed usage... + async def __aenter__(self) -> "NetworkStream": + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ): + await self.close() + + +class NetworkServer: + def __init__(self, host: str, port: int, server: asyncio.Server): + self.host = host + self.port = port + self._server = server + + # Context managed usage... + async def __aenter__(self) -> "NetworkServer": + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ): + self._server.close() + await self._server.wait_closed() + + +class NetworkBackend: + def __init__(self, ssl_ctx: ssl.SSLContext | None = None): + self._ssl_ctx = self.create_default_context() if ssl_ctx is None else ssl_ctx + + def create_default_context(self) -> ssl.SSLContext: + import certifi + return ssl.create_default_context(cafile=certifi.where()) + + async def connect(self, host: str, port: int) -> NetworkStream: + """ + Connect to the given address, returning a Stream instance. + """ + address = f"{host}:{port}" + reader, writer = await asyncio.open_connection(host, port) + return NetworkStream(reader, writer, address=address) + + async def connect_tls(self, host: str, port: int, hostname: str = '') -> NetworkStream: + """ + Connect to the given address, returning a Stream instance. + """ + address = f"{host}:{port}" + reader, writer = await asyncio.open_connection(host, port) + await writer.start_tls(self._ssl_ctx, server_hostname=hostname) + return NetworkStream(reader, writer, address=address) + + async def serve(self, host: str, port: int, handler: typing.Callable[[NetworkStream], None]) -> NetworkServer: + async def callback(reader, writer): + stream = NetworkStream(reader, writer) + await handler(stream) + + server = await asyncio.start_server(callback, host, port) + return NetworkServer(host, port, server) + + +Semaphore = asyncio.Semaphore +Lock = asyncio.Lock +timeout = asyncio.timeout +sleep = asyncio.sleep diff --git a/src/ahttpx/_parsers.py b/src/ahttpx/_parsers.py new file mode 100644 index 0000000000..8a52a56fdf --- /dev/null +++ b/src/ahttpx/_parsers.py @@ -0,0 +1,515 @@ +import enum + +from ._streams import Stream + +__all__ = ['HTTPParser', 'Mode', 'ProtocolError'] + + +# TODO... + +# * Upgrade +# * CONNECT + +# * Support 'Expect: 100 Continue' +# * Add 'Error' state transitions +# * Add tests to trickle data +# * Add type annotations + +# * Optional... HTTP/1.0 support +# * Read trailing headers on Transfer-Encoding: chunked. Not just '\r\n'. +# * When writing Transfer-Encoding: chunked, split large writes into buffer size. +# * When reading Transfer-Encoding: chunked, handle incomplete reads from large chunk sizes. +# * .read() doesn't document if will always return maximum available. + +# * validate method, target, protocol in request line +# * validate protocol, status_code, reason_phrase in response line +# * validate name, value on headers + + +class State(enum.Enum): + WAIT = 0 + SEND_METHOD_LINE = 1 + SEND_STATUS_LINE = 2 + SEND_HEADERS = 3 + SEND_BODY = 4 + RECV_METHOD_LINE = 5 + RECV_STATUS_LINE = 6 + RECV_HEADERS = 7 + RECV_BODY = 8 + DONE = 9 + CLOSED = 10 + + +class Mode(enum.Enum): + CLIENT = 0 + SERVER = 1 + + +# The usual transitions will be... + +# IDLE, IDLE +# SEND_HEADERS, IDLE +# SEND_BODY, IDLE +# DONE, IDLE +# DONE, SEND_HEADERS +# DONE, SEND_BODY +# DONE, DONE + +# Then either back to IDLE, IDLE +# or move to CLOSED, CLOSED + +# 1. It is also valid for the server to start +# sending the response without waiting for the +# complete request. +# 2. 1xx status codes are interim states, and +# transition from SEND_HEADERS back to IDLE +# 3. ... + +class ProtocolError(Exception): + pass + + +class HTTPParser: + """ + Usage... + + client = HTTPParser(writer, reader) + client.send_method_line() + client.send_headers() + client.send_body() + client.recv_status_line() + client.recv_headers() + client.recv_body() + client.complete() + client.close() + """ + def __init__(self, stream: Stream, mode: str) -> None: + self.stream = stream + self.parser = ReadAheadParser(stream) + self.mode = {'CLIENT': Mode.CLIENT, 'SERVER': Mode.SERVER}[mode] + + # Track state... + if self.mode == Mode.CLIENT: + self.send_state: State = State.SEND_METHOD_LINE + self.recv_state: State = State.WAIT + else: + self.recv_state = State.RECV_METHOD_LINE + self.send_state = State.WAIT + + # Track message framing... + self.send_content_length: int | None = 0 + self.recv_content_length: int | None = 0 + self.send_seen_length = 0 + self.recv_seen_length = 0 + + # Track connection keep alive... + self.send_keep_alive = True + self.recv_keep_alive = True + + # Special states... + self.processing_1xx = False + + async def send_method_line(self, method: bytes, target: bytes, protocol: bytes) -> None: + """ + Send the initial request line: + + >>> p.send_method_line(b'GET', b'/', b'HTTP/1.1') + + Sending state will switch to SEND_HEADERS state. + """ + if self.send_state != State.SEND_METHOD_LINE: + msg = f"Called 'send_method_line' in invalid state {self.send_state}" + raise ProtocolError(msg) + + # Send initial request line, eg. "GET / HTTP/1.1" + if protocol != b'HTTP/1.1': + raise ProtocolError("Sent unsupported protocol version") + data = b" ".join([method, target, protocol]) + b"\r\n" + await self.stream.write(data) + + self.send_state = State.SEND_HEADERS + self.recv_state = State.RECV_STATUS_LINE + + async def send_status_line(self, protocol: bytes, status_code: int, reason: bytes) -> None: + """ + Send the initial response line: + + >>> p.send_method_line(b'HTTP/1.1', 200, b'OK') + + Sending state will switch to SEND_HEADERS state. + """ + if self.send_state != State.SEND_STATUS_LINE: + msg = f"Called 'send_status_line' in invalid state {self.send_state}" + raise ProtocolError(msg) + + # Send initial request line, eg. "GET / HTTP/1.1" + if protocol != b'HTTP/1.1': + raise ProtocolError("Sent unsupported protocol version") + status_code_bytes = str(status_code).encode('ascii') + data = b" ".join([protocol, status_code_bytes, reason]) + b"\r\n" + await self.stream.write(data) + + self.send_state = State.SEND_HEADERS + + async def send_headers(self, headers: list[tuple[bytes, bytes]]) -> None: + """ + Send the request headers: + + >>> p.send_headers([(b'Host', b'www.example.com')]) + + Sending state will switch to SEND_BODY state. + """ + if self.send_state != State.SEND_HEADERS: + msg = f"Called 'send_headers' in invalid state {self.send_state}" + raise ProtocolError(msg) + + # Update header state + seen_host = False + for name, value in headers: + lname = name.lower() + if lname == b'host': + seen_host = True + elif lname == b'content-length': + self.send_content_length = bounded_int( + value, + max_digits=20, + exc_text="Sent invalid Content-Length" + ) + elif lname == b'connection' and value == b'close': + self.send_keep_alive = False + elif lname == b'transfer-encoding' and value == b'chunked': + self.send_content_length = None + + if self.mode == Mode.CLIENT and not seen_host: + raise ProtocolError("Request missing 'Host' header") + + # Send request headers + lines = [name + b": " + value + b"\r\n" for name, value in headers] + data = b"".join(lines) + b"\r\n" + await self.stream.write(data) + + self.send_state = State.SEND_BODY + + async def send_body(self, body: bytes) -> None: + """ + Send the request body. An empty bytes argument indicates the end of the stream: + + >>> p.send_body(b'') + + Sending state will switch to DONE. + """ + if self.send_state != State.SEND_BODY: + msg = f"Called 'send_body' in invalid state {self.send_state}" + raise ProtocolError(msg) + + if self.send_content_length is None: + # Transfer-Encoding: chunked + self.send_seen_length += len(body) + marker = f'{len(body):x}\r\n'.encode('ascii') + await self.stream.write(marker + body + b'\r\n') + + else: + # Content-Length: xxx + self.send_seen_length += len(body) + if self.send_seen_length > self.send_content_length: + msg = 'Too much data sent for declared Content-Length' + raise ProtocolError(msg) + if self.send_seen_length < self.send_content_length and body == b'': + msg = 'Not enough data sent for declared Content-Length' + raise ProtocolError(msg) + if body: + await self.stream.write(body) + + if body == b'': + # Handle body close + self.send_state = State.DONE + + async def recv_method_line(self) -> tuple[bytes, bytes, bytes]: + """ + Receive the initial request method line: + + >>> method, target, protocol = p.recv_status_line() + + Receive state will switch to RECV_HEADERS. + """ + if self.recv_state != State.RECV_METHOD_LINE: + msg = f"Called 'recv_method_line' in invalid state {self.recv_state}" + raise ProtocolError(msg) + + # Read initial response line, eg. "GET / HTTP/1.1" + exc_text = "reading request method line" + line = await self.parser.read_until(b"\r\n", max_size=4096, exc_text=exc_text) + method, target, protocol = line.split(b" ", 2) + if protocol != b'HTTP/1.1': + raise ProtocolError("Received unsupported protocol version") + + self.recv_state = State.RECV_HEADERS + self.send_state = State.SEND_STATUS_LINE + return method, target, protocol + + async def recv_status_line(self) -> tuple[bytes, int, bytes]: + """ + Receive the initial response status line: + + >>> protocol, status_code, reason_phrase = p.recv_status_line() + + Receive state will switch to RECV_HEADERS. + """ + if self.recv_state != State.RECV_STATUS_LINE: + msg = f"Called 'recv_status_line' in invalid state {self.recv_state}" + raise ProtocolError(msg) + + # Read initial response line, eg. "HTTP/1.1 200 OK" + exc_text = "reading response status line" + line = await self.parser.read_until(b"\r\n", max_size=4096, exc_text=exc_text) + protocol, status_code_str, reason_phrase = line.split(b" ", 2) + if protocol != b'HTTP/1.1': + raise ProtocolError("Received unsupported protocol version") + + status_code = bounded_int( + status_code_str, + max_digits=3, + exc_text="Received invalid status code" + ) + if status_code < 100: + raise ProtocolError("Received invalid status code") + # 1xx status codes preceed the final response status code + self.processing_1xx = status_code < 200 + + self.recv_state = State.RECV_HEADERS + return protocol, status_code, reason_phrase + + async def recv_headers(self) -> list[tuple[bytes, bytes]]: + """ + Receive the response headers: + + >>> headers = p.recv_status_line() + + Receive state will switch to RECV_BODY by default. + Receive state will revert to RECV_STATUS_CODE for interim 1xx responses. + """ + if self.recv_state != State.RECV_HEADERS: + msg = f"Called 'recv_headers' in invalid state {self.recv_state}" + raise ProtocolError(msg) + + # Read response headers + headers = [] + exc_text = "reading response headers" + while line := await self.parser.read_until(b"\r\n", max_size=4096, exc_text=exc_text): + name, value = line.split(b":", 1) + value = value.strip(b" ") + headers.append((name, value)) + + # Update header state + seen_host = False + for name, value in headers: + lname = name.lower() + if lname == b'host': + seen_host = True + elif lname == b'content-length': + self.recv_content_length = bounded_int( + value, + max_digits=20, + exc_text="Received invalid Content-Length" + ) + elif lname == b'connection' and value == b'close': + self.recv_keep_alive = False + elif lname == b'transfer-encoding' and value == b'chunked': + self.recv_content_length = None + + if self.mode == Mode.SERVER and not seen_host: + raise ProtocolError("Request missing 'Host' header") + + if self.processing_1xx: + # 1xx status codes preceed the final response status code + self.processing_1xx = False + self.recv_state = State.RECV_STATUS_LINE + else: + self.recv_state = State.RECV_BODY + return headers + + async def recv_body(self) -> bytes: + """ + Receive the response body. An empty byte string indicates the end of the stream: + + >>> buffer = bytearray() + >>> while body := p.recv_body() + >>> buffer.extend(body) + + The server will switch to DONE. + """ + if self.recv_state != State.RECV_BODY: + msg = f"Called 'recv_body' in invalid state {self.recv_state}" + raise ProtocolError(msg) + + if self.recv_content_length is None: + # Transfer-Encoding: chunked + exc_text = 'reading chunk size' + line = await self.parser.read_until(b"\r\n", max_size=4096, exc_text=exc_text) + sizestr, _, _ = line.partition(b";") + + exc_text = "Received invalid chunk size" + size = bounded_hex(sizestr, max_digits=8, exc_text=exc_text) + if size > 0: + body = await self.parser.read(size=size) + exc_text = 'reading chunk data' + await self.parser.read_until(b"\r\n", max_size=2, exc_text=exc_text) + self.recv_seen_length += len(body) + else: + body = b'' + exc_text = 'reading chunk termination' + await self.parser.read_until(b"\r\n", max_size=2, exc_text=exc_text) + + else: + # Content-Length: xxx + remaining = self.recv_content_length - self.recv_seen_length + size = min(remaining, 4096) + body = await self.parser.read(size=size) + self.recv_seen_length += len(body) + if self.recv_seen_length < self.recv_content_length and body == b'': + msg = 'Not enough data received for declared Content-Length' + raise ProtocolError(msg) + + if body == b'': + # Handle body close + self.recv_state = State.DONE + return body + + async def complete(self): + is_fully_complete = self.send_state == State.DONE and self.recv_state == State.DONE + is_keepalive = self.send_keep_alive and self.recv_keep_alive + + if not (is_fully_complete and is_keepalive): + await self.close() + return + + if self.mode == Mode.CLIENT: + self.send_state = State.SEND_METHOD_LINE + self.recv_state = State.WAIT + else: + self.recv_state = State.RECV_METHOD_LINE + self.send_state = State.WAIT + + self.send_content_length = 0 + self.recv_content_length = 0 + self.send_seen_length = 0 + self.recv_seen_length = 0 + self.send_keep_alive = True + self.recv_keep_alive = True + self.processing_1xx = False + + async def close(self): + if self.send_state != State.CLOSED: + self.send_state = State.CLOSED + self.recv_state = State.CLOSED + await self.stream.close() + + def is_idle(self) -> bool: + return ( + self.send_state == State.SEND_METHOD_LINE or + self.recv_state == State.RECV_METHOD_LINE + ) + + def is_closed(self) -> bool: + return self.send_state == State.CLOSED + + def description(self) -> str: + return { + State.SEND_METHOD_LINE: "idle", + State.CLOSED: "closed", + }.get(self.send_state, "active") + + def __repr__(self) -> str: + cl_state = self.send_state.name + sr_state = self.recv_state.name + detail = f"client {cl_state}, server {sr_state}" + return f'' + + +class ReadAheadParser: + """ + A buffered I/O stream, with methods for read-ahead parsing. + """ + def __init__(self, stream: Stream) -> None: + self._buffer = b'' + self._stream = stream + self._chunk_size = 4096 + + async def _read_some(self) -> bytes: + if self._buffer: + ret, self._buffer = self._buffer, b'' + return ret + return await self._stream.read(self._chunk_size) + + def _push_back(self, buffer): + assert self._buffer == b'' + self._buffer = buffer + + async def read(self, size: int) -> bytes: + """ + Read and return up to 'size' bytes from the stream, with I/O buffering provided. + + * Returns b'' to indicate connection close. + """ + buffer = bytearray() + while len(buffer) < size: + chunk = await self._read_some() + if not chunk: + break + buffer.extend(chunk) + + if len(buffer) > size: + buffer, push_back = buffer[:size], buffer[size:] + self._push_back(bytes(push_back)) + return bytes(buffer) + + async def read_until(self, marker: bytes, max_size: int, exc_text: str) -> bytes: + """ + Read and return bytes from the stream, delimited by marker. + + * The marker is not included in the return bytes. + * The marker is consumed from the I/O stream. + * Raises `ProtocolError` if the stream closes before a marker occurance. + * Raises `ProtocolError` if marker did not occur within 'max_size + len(marker)' bytes. + """ + buffer = bytearray() + while len(buffer) <= max_size: + chunk = await self._read_some() + if not chunk: + # stream closed before marker found. + raise ProtocolError(f"Stream closed early {exc_text}") + start_search = max(len(buffer) - len(marker), 0) + buffer.extend(chunk) + index = buffer.find(marker, start_search) + + if index > max_size: + # marker was found, though 'max_size' exceeded. + raise ProtocolError(f"Exceeded maximum size {exc_text}") + elif index >= 0: + endindex = index + len(marker) + self._push_back(bytes(buffer[endindex:])) + return bytes(buffer[:index]) + + raise ProtocolError(f"Exceeded maximum size {exc_text}") + + +def bounded_int(intstr: bytes, max_digits: int, exc_text: str): + if len(intstr) > max_digits: + # Length of bytestring exceeds maximum. + raise ProtocolError(exc_text) + if len(intstr.strip(b'0123456789')) != 0: + # Contains invalid characters. + raise ProtocolError(exc_text) + + return int(intstr) + + +def bounded_hex(hexstr: bytes, max_digits: int, exc_text: str): + if len(hexstr) > max_digits: + # Length of bytestring exceeds maximum. + raise ProtocolError(exc_text) + if len(hexstr.strip(b'0123456789abcdefABCDEF')) != 0: + # Contains invalid characters. + raise ProtocolError(exc_text) + + return int(hexstr, base=16) diff --git a/src/ahttpx/_pool.py b/src/ahttpx/_pool.py new file mode 100644 index 0000000000..f712cfac27 --- /dev/null +++ b/src/ahttpx/_pool.py @@ -0,0 +1,284 @@ +import time +import typing +import types + +from ._content import Content +from ._headers import Headers +from ._network import Lock, NetworkBackend, Semaphore +from ._parsers import HTTPParser +from ._response import Response +from ._request import Request +from ._streams import HTTPStream, Stream +from ._urls import URL + + +__all__ = [ + "Transport", + "ConnectionPool", + "Connection", + "open_connection", +] + + +class Transport: + async def send(self, request: Request) -> Response: + raise NotImplementedError() + + async def close(self): + pass + + async def request( + self, + method: str, + url: URL | str, + headers: Headers | dict[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Response: + request = Request(method, url, headers=headers, content=content) + async with await self.send(request) as response: + await response.read() + return response + + async def stream( + self, + method: str, + url: URL | str, + headers: Headers | dict[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Response: + request = Request(method, url, headers=headers, content=content) + response = await self.send(request) + return response + + +class ConnectionPool(Transport): + def __init__(self, backend: NetworkBackend | None = None): + if backend is None: + backend = NetworkBackend() + + self._connections: list[Connection] = [] + self._network_backend = backend + self._limit_concurrency = Semaphore(100) + self._closed = False + + # Public API... + async def send(self, request: Request) -> Response: + if self._closed: + raise RuntimeError("ConnectionPool is closed.") + + # TODO: concurrency limiting + await self._cleanup() + connection = await self._get_connection(request) + response = await connection.send(request) + return response + + async def close(self): + self._closed = True + closing = list(self._connections) + self._connections = [] + for conn in closing: + await conn.close() + + # Create or reuse connections as required... + async def _get_connection(self, request: Request) -> "Connection": + # Attempt to reuse an existing connection. + url = request.url + origin = URL(scheme=url.scheme, host=url.host, port=url.port) + now = time.monotonic() + for conn in self._connections: + if conn.origin() == origin and conn.is_idle() and not conn.is_expired(now): + return conn + + # Or else create a new connection. + conn = await open_connection( + origin, + hostname=request.headers["Host"], + backend=self._network_backend + ) + self._connections.append(conn) + return conn + + # Connection pool management... + async def _cleanup(self) -> None: + now = time.monotonic() + for conn in list(self._connections): + if conn.is_expired(now): + await conn.close() + if conn.is_closed(): + self._connections.remove(conn) + + @property + def connections(self) -> typing.List['Connection']: + return [c for c in self._connections] + + def description(self) -> str: + counts = {"active": 0} + for status in [c.description() for c in self._connections]: + counts[status] = counts.get(status, 0) + 1 + return ", ".join(f"{count} {status}" for status, count in counts.items()) + + # Builtins... + def __repr__(self) -> str: + return f"" + + def __del__(self): + if not self._closed: + import warnings + warnings.warn("ConnectionPool was garbage collected without being closed.") + + async def __aenter__(self) -> "ConnectionPool": + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + await self.close() + + +class Connection(Transport): + def __init__(self, stream: Stream, origin: URL | str): + self._stream = stream + self._origin = URL(origin) + self._keepalive_duration = 5.0 + self._idle_expiry = time.monotonic() + self._keepalive_duration + self._request_lock = Lock() + self._parser = HTTPParser(stream, mode='CLIENT') + + # API for connection pool management... + def origin(self) -> URL: + return self._origin + + def is_idle(self) -> bool: + return self._parser.is_idle() + + def is_expired(self, when: float) -> bool: + return self._parser.is_idle() and when > self._idle_expiry + + def is_closed(self) -> bool: + return self._parser.is_closed() + + def description(self) -> str: + return self._parser.description() + + # API entry points... + async def send(self, request: Request) -> Response: + #async with self._request_lock: + # try: + await self._send_head(request) + await self._send_body(request) + code, headers = await self._recv_head() + stream = HTTPStream(self._recv_body, self._complete) + # TODO... + return Response(code, headers=headers, content=stream) + # finally: + # await self._cycle_complete() + + async def close(self) -> None: + async with self._request_lock: + await self._close() + + # Top-level API for working directly with a connection. + async def request( + self, + method: str, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Response: + url = self._origin.join(url) + request = Request(method, url, headers=headers, content=content) + async with await self.send(request) as response: + await response.read() + return response + + async def stream( + self, + method: str, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Response: + url = self._origin.join(url) + request = Request(method, url, headers=headers, content=content) + return await self.send(request) + + # Send the request... + async def _send_head(self, request: Request) -> None: + method = request.method.encode('ascii') + target = request.url.target.encode('ascii') + protocol = b'HTTP/1.1' + await self._parser.send_method_line(method, target, protocol) + headers = [ + (k.encode('ascii'), v.encode('ascii')) + for k, v in request.headers.items() + ] + await self._parser.send_headers(headers) + + async def _send_body(self, request: Request) -> None: + while data := await request.stream.read(64 * 1024): + await self._parser.send_body(data) + await self._parser.send_body(b'') + + # Receive the response... + async def _recv_head(self) -> tuple[int, Headers]: + _, code, _ = await self._parser.recv_status_line() + h = await self._parser.recv_headers() + headers = Headers([ + (k.decode('ascii'), v.decode('ascii')) + for k, v in h + ]) + return code, headers + + async def _recv_body(self) -> bytes: + return await self._parser.recv_body() + + # Request/response cycle complete... + async def _complete(self) -> None: + await self._parser.complete() + self._idle_expiry = time.monotonic() + self._keepalive_duration + + async def _close(self) -> None: + await self._parser.close() + + # Builtins... + def __repr__(self) -> str: + return f"" + + async def __aenter__(self) -> "Connection": + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ): + await self.close() + + +async def open_connection( + url: URL | str, + hostname: str = '', + backend: NetworkBackend | None = None, + ) -> Connection: + + if isinstance(url, str): + url = URL(url) + + if url.scheme not in ("http", "https"): + raise ValueError("URL scheme must be 'http://' or 'https://'.") + if backend is None: + backend = NetworkBackend() + + host = url.host + port = url.port or {"http": 80, "https": 443}[url.scheme] + + if url.scheme == "https": + stream = await backend.connect_tls(host, port, hostname) + else: + stream = await backend.connect(host, port) + + return Connection(stream, url) diff --git a/src/ahttpx/_quickstart.py b/src/ahttpx/_quickstart.py new file mode 100644 index 0000000000..8b6e12ff4c --- /dev/null +++ b/src/ahttpx/_quickstart.py @@ -0,0 +1,49 @@ +import typing + +from ._client import Client +from ._content import Content +from ._headers import Headers +from ._streams import Stream +from ._urls import URL + + +__all__ = ['get', 'post', 'put', 'patch', 'delete'] + + +async def get( + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, +): + async with Client() as client: + return await client.request("GET", url=url, headers=headers) + +async def post( + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, +): + async with Client() as client: + return await client.request("POST", url, headers=headers, content=content) + +async def put( + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, +): + async with Client() as client: + return await client.request("PUT", url, headers=headers, content=content) + +async def patch( + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, +): + async with Client() as client: + return await client.request("PATCH", url, headers=headers, content=content) + +async def delete( + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, +): + async with Client() as client: + return await client.request("DELETE", url=url, headers=headers) diff --git a/src/ahttpx/_request.py b/src/ahttpx/_request.py new file mode 100644 index 0000000000..78b82282d0 --- /dev/null +++ b/src/ahttpx/_request.py @@ -0,0 +1,93 @@ +import types +import typing + +from ._content import Content +from ._streams import ByteStream, Stream +from ._headers import Headers +from ._urls import URL + +__all__ = ["Request"] + + +class Request: + def __init__( + self, + method: str, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ): + self.method = method + self.url = URL(url) + self.headers = Headers(headers) + self.stream: Stream = ByteStream(b"") + + # https://datatracker.ietf.org/doc/html/rfc2616#section-14.23 + # RFC 2616, Section 14.23, Host. + # + # A client MUST include a Host header field in all HTTP/1.1 request messages. + if "Host" not in self.headers: + self.headers = self.headers.copy_set("Host", self.url.netloc) + + if content is not None: + if isinstance(content, bytes): + self.stream = ByteStream(content) + elif isinstance(content, Stream): + self.stream = content + elif isinstance(content, Content): + ct = content.content_type() + self.stream = content.encode() + self.headers = self.headers.copy_set("Content-Type", ct) + else: + raise TypeError(f'Expected `Content | Stream | bytes | None` got {type(content)}') + + # https://datatracker.ietf.org/doc/html/rfc2616#section-4.3 + # RFC 2616, Section 4.3, Message Body. + # + # The presence of a message-body in a request is signaled by the + # inclusion of a Content-Length or Transfer-Encoding header field in + # the request's message-headers. + content_length: int | None = self.stream.size + if content_length is None: + self.headers = self.headers.copy_set("Transfer-Encoding", "chunked") + elif content_length > 0: + self.headers = self.headers.copy_set("Content-Length", str(content_length)) + + elif method in ("POST", "PUT", "PATCH"): + # https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2 + # RFC 7230, Section 3.3.2, Content Length. + # + # A user agent SHOULD send a Content-Length in a request message when no + # Transfer-Encoding is sent and the request method defines a meaning for + # an enclosed payload body. For example, a Content-Length header field is + # normally sent in a POST request even when the value is 0. + # (indicating an empty payload body). + self.headers = self.headers.copy_set("Content-Length", "0") + + @property + def body(self) -> bytes: + if not hasattr(self, '_body'): + raise RuntimeError("'.body' cannot be accessed without calling '.read()'") + return self._body + + async def read(self) -> bytes: + if not hasattr(self, '_body'): + self._body = await self.stream.read() + self.stream = ByteStream(self._body) + return self._body + + async def close(self) -> None: + await self.stream.close() + + async def __aenter__(self): + return self + + async def __aexit__(self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None + ): + await self.close() + + def __repr__(self): + return f"" diff --git a/src/ahttpx/_response.py b/src/ahttpx/_response.py new file mode 100644 index 0000000000..db1de832e4 --- /dev/null +++ b/src/ahttpx/_response.py @@ -0,0 +1,158 @@ +import types +import typing + +from ._content import Content +from ._streams import ByteStream, Stream +from ._headers import Headers, parse_opts_header + +__all__ = ["Response"] + +# We're using the same set as stdlib `http.HTTPStatus` here... +# +# https://github.com/python/cpython/blob/main/Lib/http/__init__.py +_codes = { + 100: "Continue", + 101: "Switching Protocols", + 102: "Processing", + 103: "Early Hints", + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non-Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi-Status", + 208: "Already Reported", + 226: "IM Used", + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 307: "Temporary Redirect", + 308: "Permanent Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Content Too Large", + 414: "URI Too Long", + 415: "Unsupported Media Type", + 416: "Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a Teapot", + 421: "Misdirected Request", + 422: "Unprocessable Content", + 423: "Locked", + 424: "Failed Dependency", + 425: "Too Early", + 426: "Upgrade Required", + 428: "Precondition Required", + 429: "Too Many Requests", + 431: "Request Header Fields Too Large", + 451: "Unavailable For Legal Reasons", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 506: "Variant Also Negotiates", + 507: "Insufficient Storage", + 508: "Loop Detected", + 510: "Not Extended", + 511: "Network Authentication Required", +} + + +class Response: + def __init__( + self, + status_code: int, + *, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ): + self.status_code = status_code + self.headers = Headers(headers) + self.stream: Stream = ByteStream(b"") + + if content is not None: + if isinstance(content, bytes): + self.stream = ByteStream(content) + elif isinstance(content, Stream): + self.stream = content + elif isinstance(content, Content): + ct = content.content_type() + self.stream = content.encode() + self.headers = self.headers.copy_set("Content-Type", ct) + else: + raise TypeError(f'Expected `Content | Stream | bytes | None` got {type(content)}') + + # https://datatracker.ietf.org/doc/html/rfc2616#section-4.3 + # RFC 2616, Section 4.3, Message Body. + # + # All 1xx (informational), 204 (no content), and 304 (not modified) responses + # MUST NOT include a message-body. All other responses do include a + # message-body, although it MAY be of zero length. + if status_code >= 200 and status_code != 204 and status_code != 304: + content_length: int | None = self.stream.size + if content_length is None: + self.headers = self.headers.copy_set("Transfer-Encoding", "chunked") + else: + self.headers = self.headers.copy_set("Content-Length", str(content_length)) + + @property + def reason_phrase(self): + return _codes.get(self.status_code, "Unknown Status Code") + + @property + def body(self) -> bytes: + if not hasattr(self, '_body'): + raise RuntimeError("'.body' cannot be accessed without calling '.read()'") + return self._body + + @property + def text(self) -> str: + if not hasattr(self, '_body'): + raise RuntimeError("'.text' cannot be accessed without calling '.read()'") + if not hasattr(self, '_text'): + ct = self.headers.get('Content-Type', '') + media, opts = parse_opts_header(ct) + charset = 'utf-8' + if media.startswith('text/'): + charset = opts.get('charset', 'utf-8') + self._text = self._body.decode(charset) + return self._text + + async def read(self) -> bytes: + if not hasattr(self, '_body'): + self._body = await self.stream.read() + return self._body + + async def close(self) -> None: + await self.stream.close() + + async def __aenter__(self): + return self + + async def __aexit__(self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None + ): + await self.close() + + def __repr__(self): + return f"" diff --git a/src/ahttpx/_server.py b/src/ahttpx/_server.py new file mode 100644 index 0000000000..a9103cc97f --- /dev/null +++ b/src/ahttpx/_server.py @@ -0,0 +1,126 @@ +import contextlib +import logging +import time + +from ._content import Text +from ._parsers import HTTPParser +from ._request import Request +from ._response import Response +from ._network import NetworkBackend, sleep +from ._streams import HTTPStream + +__all__ = [ + "serve_http", "run" +] + +logger = logging.getLogger("httpx.server") + + +class ConnectionClosed(Exception): + pass + + +class HTTPConnection: + def __init__(self, stream, endpoint): + self._stream = stream + self._endpoint = endpoint + self._parser = HTTPParser(stream, mode='SERVER') + self._keepalive_duration = 5.0 + self._idle_expiry = time.monotonic() + self._keepalive_duration + + # API entry points... + async def handle_requests(self): + try: + while not self._parser.is_closed(): + method, url, headers = await self._recv_head() + stream = HTTPStream(self._recv_body, self._complete) + # TODO: Handle endpoint exceptions + async with Request(method, url, headers=headers, content=stream) as request: + try: + response = await self._endpoint(request) + status_line = f"{request.method} {request.url.target} [{response.status_code} {response.reason_phrase}]" + logger.info(status_line) + except Exception: + logger.error("Internal Server Error", exc_info=True) + content = Text("Internal Server Error") + err = Response(code=500, content=content) + await self._send_head(err) + await self._send_body(err) + else: + await self._send_head(response) + await self._send_body(response) + except Exception: + logger.error("Internal Server Error", exc_info=True) + + async def close(self): + self._parser.close() + + # Receive the request... + async def _recv_head(self) -> tuple[str, str, list[tuple[str, str]]]: + method, target, _ = await self._parser.recv_method_line() + m = method.decode('ascii') + t = target.decode('ascii') + headers = await self._parser.recv_headers() + h = [ + (k.decode('latin-1'), v.decode('latin-1')) + for k, v in headers + ] + return m, t, h + + async def _recv_body(self): + return await self._parser.recv_body() + + # Return the response... + async def _send_head(self, response: Response): + protocol = b"HTTP/1.1" + status = response.status_code + reason = response.reason_phrase.encode('ascii') + await self._parser.send_status_line(protocol, status, reason) + headers = [ + (k.encode('ascii'), v.encode('ascii')) + for k, v in response.headers.items() + ] + await self._parser.send_headers(headers) + + async def _send_body(self, response: Response): + while data := await response.stream.read(64 * 1024): + await self._parser.send_body(data) + await self._parser.send_body(b'') + + # Start it all over again... + async def _complete(self): + await self._parser.complete + self._idle_expiry = time.monotonic() + self._keepalive_duration + + +class HTTPServer: + def __init__(self, host, port): + self.url = f"http://{host}:{port}/" + + async def wait(self): + while(True): + await sleep(1) + + +@contextlib.asynccontextmanager +async def serve_http(endpoint): + async def handler(stream): + connection = HTTPConnection(stream, endpoint) + await connection.handle_requests() + + logging.basicConfig( + format="%(levelname)s [%(asctime)s] %(name)s - %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + level=logging.DEBUG + ) + + backend = NetworkBackend() + async with await backend.serve("127.0.0.1", 8080, handler) as server: + server = HTTPServer(server.host, server.port) + logger.info(f"Serving on {server.url} (Press CTRL+C to quit)") + yield server + + +async def run(app): + async with await serve_http(app) as server: + server.wait() diff --git a/src/ahttpx/_streams.py b/src/ahttpx/_streams.py new file mode 100644 index 0000000000..d5e5ad0d4c --- /dev/null +++ b/src/ahttpx/_streams.py @@ -0,0 +1,235 @@ +import io +import types +import os + + +class Stream: + async def read(self, size: int=-1) -> bytes: + raise NotImplementedError() + + async def write(self, data: bytes) -> None: + raise NotImplementedError() + + async def close(self) -> None: + raise NotImplementedError() + + @property + def size(self) -> int | None: + return None + + async def __aenter__(self): + return self + + async def __aexit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None + ): + await self.close() + + +class ByteStream(Stream): + def __init__(self, data: bytes = b''): + self._buffer = io.BytesIO(data) + self._size = len(data) + + async def read(self, size: int=-1) -> bytes: + return self._buffer.read(size) + + async def close(self) -> None: + self._buffer.close() + + @property + def size(self) -> int | None: + return self._size + + +class DuplexStream(Stream): + """ + DuplexStream supports both `read` and `write` operations, + which are applied to seperate buffers. + + This stream can be used for testing network parsers. + """ + + def __init__(self, data: bytes = b''): + self._read_buffer = io.BytesIO(data) + self._write_buffer = io.BytesIO() + + async def read(self, size: int=-1) -> bytes: + return self._read_buffer.read(size) + + async def write(self, buffer: bytes): + return self._write_buffer.write(buffer) + + async def close(self) -> None: + self._read_buffer.close() + self._write_buffer.close() + + def input_bytes(self) -> bytes: + return self._read_buffer.getvalue() + + def output_bytes(self) -> bytes: + return self._write_buffer.getvalue() + + +class FileStream(Stream): + def __init__(self, path): + self._path = path + self._fileobj = None + self._size = None + + async def read(self, size: int=-1) -> bytes: + if self._fileobj is None: + raise ValueError('I/O operation on unopened file') + return self._fileobj.read(size) + + async def open(self): + self._fileobj = open(self._path, 'rb') + self._size = os.path.getsize(self._path) + return self + + async def close(self) -> None: + if self._fileobj is not None: + self._fileobj.close() + + @property + def size(self) -> int | None: + return self._size + + async def __aenter__(self): + await self.open() + return self + + +class HTTPStream(Stream): + def __init__(self, next_chunk, complete): + self._next_chunk = next_chunk + self._complete = complete + self._buffer = io.BytesIO() + + async def read(self, size=-1) -> bytes: + sections = [] + length = 0 + + # If we have any data in the buffer read that and clear the buffer. + buffered = self._buffer.read() + if buffered: + sections.append(buffered) + length += len(buffered) + self._buffer.seek(0) + self._buffer.truncate(0) + + # Read each chunk in turn. + while (size < 0) or (length < size): + section = await self._next_chunk() + sections.append(section) + length += len(section) + if section == b'': + break + + # If we've more data than requested, then push some back into the buffer. + output = b''.join(sections) + if size > -1 and len(output) > size: + output, remainder = output[:size], output[size:] + self._buffer.write(remainder) + self._buffer.seek(0) + + return output + + async def close(self) -> None: + self._buffer.close() + if self._complete is not None: + await self._complete() + + +class MultiPartStream(Stream): + def __init__(self, form: list[tuple[str, str]], files: list[tuple[str, str]], boundary=''): + self._form = list(form) + self._files = list(files) + self._boundary = boundary or os.urandom(16).hex() + # Mutable state... + self._form_progress = list(self._form) + self._files_progress = list(self._files) + self._filestream: FileStream | None = None + self._complete = False + self._buffer = io.BytesIO() + + async def read(self, size=-1) -> bytes: + sections = [] + length = 0 + + # If we have any data in the buffer read that and clear the buffer. + buffered = self._buffer.read() + if buffered: + sections.append(buffered) + length += len(buffered) + self._buffer.seek(0) + self._buffer.truncate(0) + + # Read each multipart section in turn. + while (size < 0) or (length < size): + section = await self._read_next_section() + sections.append(section) + length += len(section) + if section == b'': + break + + # If we've more data than requested, then push some back into the buffer. + output = b''.join(sections) + if size > -1 and len(output) > size: + output, remainder = output[:size], output[size:] + self._buffer.write(remainder) + self._buffer.seek(0) + + return output + + async def _read_next_section(self) -> bytes: + if self._form_progress: + # return a form item + key, value = self._form_progress.pop(0) + name = key.translate({10: "%0A", 13: "%0D", 34: "%22"}) + return ( + f"--{self._boundary}\r\n" + f'Content-Disposition: form-data; name="{name}"\r\n' + f"\r\n" + f"{value}\r\n" + ).encode("utf-8") + elif self._files_progress and self._filestream is None: + # return start of a file item + key, value = self._files_progress.pop(0) + self._filestream = await FileStream(value).open() + name = key.translate({10: "%0A", 13: "%0D", 34: "%22"}) + filename = os.path.basename(value) + return ( + f"--{self._boundary}\r\n" + f'Content-Disposition: form-data; name="{name}"; filename="{filename}"\r\n' + f"\r\n" + ).encode("utf-8") + elif self._filestream is not None: + chunk = await self._filestream.read(64*1024) + if chunk != b'': + # return some bytes from file + return chunk + else: + # return end of file item + await self._filestream.close() + self._filestream = None + return b"\r\n" + elif not self._complete: + # return final section of multipart + self._complete = True + return f"--{self._boundary}--\r\n".encode("utf-8") + # return EOF marker + return b"" + + async def close(self) -> None: + if self._filestream is not None: + await self._filestream.close() + self._filestream = None + self._buffer.close() + + @property + def size(self) -> int | None: + return None diff --git a/src/ahttpx/_urlencode.py b/src/ahttpx/_urlencode.py new file mode 100644 index 0000000000..1a83b620a6 --- /dev/null +++ b/src/ahttpx/_urlencode.py @@ -0,0 +1,85 @@ +import re + +__all__ = ["quote", "unquote", "urldecode", "urlencode"] + + +# Matchs a sequence of one or more '%xx' escapes. +PERCENT_ENCODED_REGEX = re.compile("(%[A-Fa-f0-9][A-Fa-f0-9])+") + +# https://datatracker.ietf.org/doc/html/rfc3986#section-2.3 +SAFE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~" + + +def urlencode(multidict, safe=SAFE): + pairs = [] + for key, values in multidict.items(): + pairs.extend([(key, value) for value in values]) + + safe += "+" + pairs = [(k.replace(" ", "+"), v.replace(" ", "+")) for k, v in pairs] + + return "&".join( + f"{quote(key, safe)}={quote(val, safe)}" + for key, val in pairs + ) + + +def urldecode(string): + parts = [part.partition("=") for part in string.split("&") if part] + pairs = [ + (unquote(key), unquote(val)) + for key, _, val in parts + ] + + pairs = [(k.replace("+", " "), v.replace("+", " ")) for k, v in pairs] + + ret = {} + for k, v in pairs: + ret.setdefault(k, []).append(v) + return ret + + +def quote(string, safe=SAFE): + # Fast path if the string is already safe. + if not string.strip(safe): + return string + + # Replace any characters not in the safe set with '%xx' escape sequences. + return "".join([ + char if char in safe else percent(char) + for char in string + ]) + + +def unquote(string): + # Fast path if the string is not quoted. + if '%' not in string: + return string + + # Unquote. + parts = [] + current_position = 0 + for match in re.finditer(PERCENT_ENCODED_REGEX, string): + start_position, end_position = match.start(), match.end() + matched_text = match.group(0) + # Include any text up to the '%xx' escape sequence. + if start_position != current_position: + leading_text = string[current_position:start_position] + parts.append(leading_text) + + # Decode the '%xx' escape sequence. + hex = matched_text.replace('%', '') + decoded = bytes.fromhex(hex).decode('utf-8') + parts.append(decoded) + current_position = end_position + + # Include any text after the final '%xx' escape sequence. + if current_position != len(string): + trailing_text = string[current_position:] + parts.append(trailing_text) + + return "".join(parts) + + +def percent(c): + return ''.join(f"%{b:02X}" for b in c.encode("utf-8")) diff --git a/src/ahttpx/_urlparse.py b/src/ahttpx/_urlparse.py new file mode 100644 index 0000000000..612892fa8b --- /dev/null +++ b/src/ahttpx/_urlparse.py @@ -0,0 +1,534 @@ +""" +An implementation of `urlparse` that provides URL validation and normalization +as described by RFC3986. + +We rely on this implementation rather than the one in Python's stdlib, because: + +* It provides more complete URL validation. +* It properly differentiates between an empty querystring and an absent querystring, + to distinguish URLs with a trailing '?'. +* It handles scheme, hostname, port, and path normalization. +* It supports IDNA hostnames, normalizing them to their encoded form. +* The API supports passing individual components, as well as the complete URL string. + +Previously we relied on the excellent `rfc3986` package to handle URL parsing and +validation, but this module provides a simpler alternative, with less indirection +required. +""" + +import ipaddress +import re +import typing + + +class InvalidURL(ValueError): + pass + + +MAX_URL_LENGTH = 65536 + +# https://datatracker.ietf.org/doc/html/rfc3986.html#section-2.3 +UNRESERVED_CHARACTERS = ( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~" +) +SUB_DELIMS = "!$&'()*+,;=" + +PERCENT_ENCODED_REGEX = re.compile("%[A-Fa-f0-9]{2}") + +# https://url.spec.whatwg.org/#percent-encoded-bytes + +# The fragment percent-encode set is the C0 control percent-encode set +# and U+0020 SPACE, U+0022 ("), U+003C (<), U+003E (>), and U+0060 (`). +FRAG_SAFE = "".join( + [chr(i) for i in range(0x20, 0x7F) if i not in (0x20, 0x22, 0x3C, 0x3E, 0x60)] +) + +# The query percent-encode set is the C0 control percent-encode set +# and U+0020 SPACE, U+0022 ("), U+0023 (#), U+003C (<), and U+003E (>). +QUERY_SAFE = "".join( + [chr(i) for i in range(0x20, 0x7F) if i not in (0x20, 0x22, 0x23, 0x3C, 0x3E)] +) + +# The path percent-encode set is the query percent-encode set +# and U+003F (?), U+0060 (`), U+007B ({), and U+007D (}). +PATH_SAFE = "".join( + [ + chr(i) + for i in range(0x20, 0x7F) + if i not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + (0x3F, 0x60, 0x7B, 0x7D) + ] +) + +# The userinfo percent-encode set is the path percent-encode set +# and U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+0040 (@), +# U+005B ([) to U+005E (^), inclusive, and U+007C (|). +USERNAME_SAFE = "".join( + [ + chr(i) + for i in range(0x20, 0x7F) + if i + not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + + (0x3F, 0x60, 0x7B, 0x7D) + + (0x2F, 0x3A, 0x3B, 0x3D, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x7C) + ] +) +PASSWORD_SAFE = "".join( + [ + chr(i) + for i in range(0x20, 0x7F) + if i + not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + + (0x3F, 0x60, 0x7B, 0x7D) + + (0x2F, 0x3A, 0x3B, 0x3D, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x7C) + ] +) +# Note... The terminology 'userinfo' percent-encode set in the WHATWG document +# is used for the username and password quoting. For the joint userinfo component +# we remove U+003A (:) from the safe set. +USERINFO_SAFE = "".join( + [ + chr(i) + for i in range(0x20, 0x7F) + if i + not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + + (0x3F, 0x60, 0x7B, 0x7D) + + (0x2F, 0x3B, 0x3D, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x7C) + ] +) + + +# {scheme}: (optional) +# //{authority} (optional) +# {path} +# ?{query} (optional) +# #{fragment} (optional) +URL_REGEX = re.compile( + ( + r"(?:(?P{scheme}):)?" + r"(?://(?P{authority}))?" + r"(?P{path})" + r"(?:\?(?P{query}))?" + r"(?:#(?P{fragment}))?" + ).format( + scheme="([a-zA-Z][a-zA-Z0-9+.-]*)?", + authority="[^/?#]*", + path="[^?#]*", + query="[^#]*", + fragment=".*", + ) +) + +# {userinfo}@ (optional) +# {host} +# :{port} (optional) +AUTHORITY_REGEX = re.compile( + ( + r"(?:(?P{userinfo})@)?" r"(?P{host})" r":?(?P{port})?" + ).format( + userinfo=".*", # Any character sequence. + host="(\\[.*\\]|[^:@]*)", # Either any character sequence excluding ':' or '@', + # or an IPv6 address enclosed within square brackets. + port=".*", # Any character sequence. + ) +) + + +# If we call urlparse with an individual component, then we need to regex +# validate that component individually. +# Note that we're duplicating the same strings as above. Shock! Horror!! +COMPONENT_REGEX = { + "scheme": re.compile("([a-zA-Z][a-zA-Z0-9+.-]*)?"), + "authority": re.compile("[^/?#]*"), + "path": re.compile("[^?#]*"), + "query": re.compile("[^#]*"), + "fragment": re.compile(".*"), + "userinfo": re.compile("[^@]*"), + "host": re.compile("(\\[.*\\]|[^:]*)"), + "port": re.compile(".*"), +} + + +# We use these simple regexs as a first pass before handing off to +# the stdlib 'ipaddress' module for IP address validation. +IPv4_STYLE_HOSTNAME = re.compile(r"^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$") +IPv6_STYLE_HOSTNAME = re.compile(r"^\[.*\]$") + + +class ParseResult(typing.NamedTuple): + scheme: str + userinfo: str + host: str + port: int | None + path: str + query: str | None + fragment: str | None + + @property + def authority(self) -> str: + return "".join( + [ + f"{self.userinfo}@" if self.userinfo else "", + f"[{self.host}]" if ":" in self.host else self.host, + f":{self.port}" if self.port is not None else "", + ] + ) + + @property + def netloc(self) -> str: + return "".join( + [ + f"[{self.host}]" if ":" in self.host else self.host, + f":{self.port}" if self.port is not None else "", + ] + ) + + def copy_with(self, **kwargs: str | None) -> "ParseResult": + if not kwargs: + return self + + defaults = { + "scheme": self.scheme, + "authority": self.authority, + "path": self.path, + "query": self.query, + "fragment": self.fragment, + } + defaults.update(kwargs) + return urlparse("", **defaults) + + def __str__(self) -> str: + authority = self.authority + return "".join( + [ + f"{self.scheme}:" if self.scheme else "", + f"//{authority}" if authority else "", + self.path, + f"?{self.query}" if self.query is not None else "", + f"#{self.fragment}" if self.fragment is not None else "", + ] + ) + + +def urlparse(url: str = "", **kwargs: str | None) -> ParseResult: + # Initial basic checks on allowable URLs. + # --------------------------------------- + + # Hard limit the maximum allowable URL length. + if len(url) > MAX_URL_LENGTH: + raise InvalidURL("URL too long") + + # If a URL includes any ASCII control characters including \t, \r, \n, + # then treat it as invalid. + if any(char.isascii() and not char.isprintable() for char in url): + char = next(char for char in url if char.isascii() and not char.isprintable()) + idx = url.find(char) + error = ( + f"Invalid non-printable ASCII character in URL, {char!r} at position {idx}." + ) + raise InvalidURL(error) + + # Some keyword arguments require special handling. + # ------------------------------------------------ + + # Coerce "port" to a string, if it is provided as an integer. + if "port" in kwargs: + port = kwargs["port"] + kwargs["port"] = str(port) if isinstance(port, int) else port + + # Replace "netloc" with "host and "port". + if "netloc" in kwargs: + netloc = kwargs.pop("netloc") or "" + kwargs["host"], _, kwargs["port"] = netloc.partition(":") + + # Replace "username" and/or "password" with "userinfo". + if "username" in kwargs or "password" in kwargs: + username = quote(kwargs.pop("username", "") or "", safe=USERNAME_SAFE) + password = quote(kwargs.pop("password", "") or "", safe=PASSWORD_SAFE) + kwargs["userinfo"] = f"{username}:{password}" if password else username + + # Replace "raw_path" with "path" and "query". + if "raw_path" in kwargs: + raw_path = kwargs.pop("raw_path") or "" + kwargs["path"], seperator, kwargs["query"] = raw_path.partition("?") + if not seperator: + kwargs["query"] = None + + # Ensure that IPv6 "host" addresses are always escaped with "[...]". + if "host" in kwargs: + host = kwargs.get("host") or "" + if ":" in host and not (host.startswith("[") and host.endswith("]")): + kwargs["host"] = f"[{host}]" + + # If any keyword arguments are provided, ensure they are valid. + # ------------------------------------------------------------- + + for key, value in kwargs.items(): + if value is not None: + if len(value) > MAX_URL_LENGTH: + raise InvalidURL(f"URL component '{key}' too long") + + # If a component includes any ASCII control characters including \t, \r, \n, + # then treat it as invalid. + if any(char.isascii() and not char.isprintable() for char in value): + char = next( + char for char in value if char.isascii() and not char.isprintable() + ) + idx = value.find(char) + error = ( + f"Invalid non-printable ASCII character in URL {key} component, " + f"{char!r} at position {idx}." + ) + raise InvalidURL(error) + + # Ensure that keyword arguments match as a valid regex. + if not COMPONENT_REGEX[key].fullmatch(value): + raise InvalidURL(f"Invalid URL component '{key}'") + + # The URL_REGEX will always match, but may have empty components. + url_match = URL_REGEX.match(url) + assert url_match is not None + url_dict = url_match.groupdict() + + # * 'scheme', 'authority', and 'path' may be empty strings. + # * 'query' may be 'None', indicating no trailing "?" portion. + # Any string including the empty string, indicates a trailing "?". + # * 'fragment' may be 'None', indicating no trailing "#" portion. + # Any string including the empty string, indicates a trailing "#". + scheme = kwargs.get("scheme", url_dict["scheme"]) or "" + authority = kwargs.get("authority", url_dict["authority"]) or "" + path = kwargs.get("path", url_dict["path"]) or "" + query = kwargs.get("query", url_dict["query"]) + frag = kwargs.get("fragment", url_dict["fragment"]) + + # The AUTHORITY_REGEX will always match, but may have empty components. + authority_match = AUTHORITY_REGEX.match(authority) + assert authority_match is not None + authority_dict = authority_match.groupdict() + + # * 'userinfo' and 'host' may be empty strings. + # * 'port' may be 'None'. + userinfo = kwargs.get("userinfo", authority_dict["userinfo"]) or "" + host = kwargs.get("host", authority_dict["host"]) or "" + port = kwargs.get("port", authority_dict["port"]) + + # Normalize and validate each component. + # We end up with a parsed representation of the URL, + # with components that are plain ASCII bytestrings. + parsed_scheme: str = scheme.lower() + parsed_userinfo: str = quote(userinfo, safe=USERINFO_SAFE) + parsed_host: str = encode_host(host) + parsed_port: int | None = normalize_port(port, scheme) + + has_scheme = parsed_scheme != "" + has_authority = ( + parsed_userinfo != "" or parsed_host != "" or parsed_port is not None + ) + validate_path(path, has_scheme=has_scheme, has_authority=has_authority) + if has_scheme or has_authority: + path = normalize_path(path) + + parsed_path: str = quote(path, safe=PATH_SAFE) + parsed_query: str | None = None if query is None else quote(query, safe=QUERY_SAFE) + parsed_frag: str | None = None if frag is None else quote(frag, safe=FRAG_SAFE) + + # The parsed ASCII bytestrings are our canonical form. + # All properties of the URL are derived from these. + return ParseResult( + parsed_scheme, + parsed_userinfo, + parsed_host, + parsed_port, + parsed_path, + parsed_query, + parsed_frag, + ) + + +def encode_host(host: str) -> str: + if not host: + return "" + + elif IPv4_STYLE_HOSTNAME.match(host): + # Validate IPv4 hostnames like #.#.#.# + # + # From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2 + # + # IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet + try: + ipaddress.IPv4Address(host) + except ipaddress.AddressValueError: + raise InvalidURL(f"Invalid IPv4 address: {host!r}") + return host + + elif IPv6_STYLE_HOSTNAME.match(host): + # Validate IPv6 hostnames like [...] + # + # From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2 + # + # "A host identified by an Internet Protocol literal address, version 6 + # [RFC3513] or later, is distinguished by enclosing the IP literal + # within square brackets ("[" and "]"). This is the only place where + # square bracket characters are allowed in the URI syntax." + try: + ipaddress.IPv6Address(host[1:-1]) + except ipaddress.AddressValueError: + raise InvalidURL(f"Invalid IPv6 address: {host!r}") + return host[1:-1] + + elif not host.isascii(): + try: + import idna # type: ignore + except ImportError: + raise InvalidURL( + f"Cannot handle URL with IDNA hostname: {host!r}. " + f"Package 'idna' is not installed." + ) + + # IDNA hostnames + try: + return idna.encode(host.lower()).decode("ascii") + except idna.IDNAError: + raise InvalidURL(f"Invalid IDNA hostname: {host!r}") + + # Regular ASCII hostnames + # + # From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2 + # + # reg-name = *( unreserved / pct-encoded / sub-delims ) + WHATWG_SAFE = '"`{}%|\\' + return quote(host.lower(), safe=SUB_DELIMS + WHATWG_SAFE) + + +def normalize_port(port: str | int | None, scheme: str) -> int | None: + # From https://tools.ietf.org/html/rfc3986#section-3.2.3 + # + # "A scheme may define a default port. For example, the "http" scheme + # defines a default port of "80", corresponding to its reserved TCP + # port number. The type of port designated by the port number (e.g., + # TCP, UDP, SCTP) is defined by the URI scheme. URI producers and + # normalizers should omit the port component and its ":" delimiter if + # port is empty or if its value would be the same as that of the + # scheme's default." + if port is None or port == "": + return None + + try: + port_as_int = int(port) + except ValueError: + raise InvalidURL(f"Invalid port: {port!r}") + + # See https://url.spec.whatwg.org/#url-miscellaneous + default_port = {"ftp": 21, "http": 80, "https": 443, "ws": 80, "wss": 443}.get( + scheme + ) + if port_as_int == default_port: + return None + return port_as_int + + +def validate_path(path: str, has_scheme: bool, has_authority: bool) -> None: + """ + Path validation rules that depend on if the URL contains + a scheme or authority component. + + See https://datatracker.ietf.org/doc/html/rfc3986.html#section-3.3 + """ + if has_authority: + # If a URI contains an authority component, then the path component + # must either be empty or begin with a slash ("/") character." + if path and not path.startswith("/"): + raise InvalidURL("For absolute URLs, path must be empty or begin with '/'") + + if not has_scheme and not has_authority: + # If a URI does not contain an authority component, then the path cannot begin + # with two slash characters ("//"). + if path.startswith("//"): + raise InvalidURL("Relative URLs cannot have a path starting with '//'") + + # In addition, a URI reference (Section 4.1) may be a relative-path reference, + # in which case the first path segment cannot contain a colon (":") character. + if path.startswith(":"): + raise InvalidURL("Relative URLs cannot have a path starting with ':'") + + +def normalize_path(path: str) -> str: + """ + Drop "." and ".." segments from a URL path. + + For example: + + normalize_path("/path/./to/somewhere/..") == "/path/to" + """ + # Fast return when no '.' characters in the path. + if "." not in path: + return path + + components = path.split("/") + + # Fast return when no '.' or '..' components in the path. + if "." not in components and ".." not in components: + return path + + # https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4 + output: list[str] = [] + for component in components: + if component == ".": + pass + elif component == "..": + if output and output != [""]: + output.pop() + else: + output.append(component) + return "/".join(output) + + +def PERCENT(string: str) -> str: + return "".join([f"%{byte:02X}" for byte in string.encode("utf-8")]) + + +def percent_encoded(string: str, safe: str) -> str: + """ + Use percent-encoding to quote a string. + """ + NON_ESCAPED_CHARS = UNRESERVED_CHARACTERS + safe + + # Fast path for strings that don't need escaping. + if not string.rstrip(NON_ESCAPED_CHARS): + return string + + return "".join( + [char if char in NON_ESCAPED_CHARS else PERCENT(char) for char in string] + ) + + +def quote(string: str, safe: str) -> str: + """ + Use percent-encoding to quote a string, omitting existing '%xx' escape sequences. + + See: https://www.rfc-editor.org/rfc/rfc3986#section-2.1 + + * `string`: The string to be percent-escaped. + * `safe`: A string containing characters that may be treated as safe, and do not + need to be escaped. Unreserved characters are always treated as safe. + See: https://www.rfc-editor.org/rfc/rfc3986#section-2.3 + """ + parts = [] + current_position = 0 + for match in re.finditer(PERCENT_ENCODED_REGEX, string): + start_position, end_position = match.start(), match.end() + matched_text = match.group(0) + # Add any text up to the '%xx' escape sequence. + if start_position != current_position: + leading_text = string[current_position:start_position] + parts.append(percent_encoded(leading_text, safe=safe)) + + # Add the '%xx' escape sequence. + parts.append(matched_text) + current_position = end_position + + # Add any text after the final '%xx' escape sequence. + if current_position != len(string): + trailing_text = string[current_position:] + parts.append(percent_encoded(trailing_text, safe=safe)) + + return "".join(parts) diff --git a/src/ahttpx/_urls.py b/src/ahttpx/_urls.py new file mode 100644 index 0000000000..4ae4464e25 --- /dev/null +++ b/src/ahttpx/_urls.py @@ -0,0 +1,552 @@ +from __future__ import annotations + +import typing + +from ._urlparse import urlparse +from ._urlencode import unquote, urldecode, urlencode + +__all__ = ["QueryParams", "URL"] + + +class URL: + """ + url = httpx.URL("HTTPS://jo%40email.com:a%20secret@müller.de:1234/pa%20th?search=ab#anchorlink") + + assert url.scheme == "https" + assert url.username == "jo@email.com" + assert url.password == "a secret" + assert url.userinfo == b"jo%40email.com:a%20secret" + assert url.host == "müller.de" + assert url.raw_host == b"xn--mller-kva.de" + assert url.port == 1234 + assert url.netloc == b"xn--mller-kva.de:1234" + assert url.path == "/pa th" + assert url.query == b"?search=ab" + assert url.raw_path == b"/pa%20th?search=ab" + assert url.fragment == "anchorlink" + + The components of a URL are broken down like this: + + https://jo%40email.com:a%20secret@müller.de:1234/pa%20th?search=ab#anchorlink + [scheme] [ username ] [password] [ host ][port][ path ] [ query ] [fragment] + [ userinfo ] [ netloc ][ raw_path ] + + Note that: + + * `url.scheme` is normalized to always be lowercased. + + * `url.host` is normalized to always be lowercased. Internationalized domain + names are represented in unicode, without IDNA encoding applied. For instance: + + url = httpx.URL("http://中国.icom.museum") + assert url.host == "中国.icom.museum" + url = httpx.URL("http://xn--fiqs8s.icom.museum") + assert url.host == "中国.icom.museum" + + * `url.raw_host` is normalized to always be lowercased, and is IDNA encoded. + + url = httpx.URL("http://中国.icom.museum") + assert url.raw_host == b"xn--fiqs8s.icom.museum" + url = httpx.URL("http://xn--fiqs8s.icom.museum") + assert url.raw_host == b"xn--fiqs8s.icom.museum" + + * `url.port` is either None or an integer. URLs that include the default port for + "http", "https", "ws", "wss", and "ftp" schemes have their port + normalized to `None`. + + assert httpx.URL("http://example.com") == httpx.URL("http://example.com:80") + assert httpx.URL("http://example.com").port is None + assert httpx.URL("http://example.com:80").port is None + + * `url.userinfo` is raw bytes, without URL escaping. Usually you'll want to work + with `url.username` and `url.password` instead, which handle the URL escaping. + + * `url.raw_path` is raw bytes of both the path and query, without URL escaping. + This portion is used as the target when constructing HTTP requests. Usually you'll + want to work with `url.path` instead. + + * `url.query` is raw bytes, without URL escaping. A URL query string portion can + only be properly URL escaped when decoding the parameter names and values + themselves. + """ + + def __init__(self, url: "URL" | str = "", **kwargs: typing.Any) -> None: + if kwargs: + allowed = { + "scheme": str, + "username": str, + "password": str, + "userinfo": bytes, + "host": str, + "port": int, + "netloc": str, + "path": str, + "query": bytes, + "raw_path": bytes, + "fragment": str, + "params": object, + } + + # Perform type checking for all supported keyword arguments. + for key, value in kwargs.items(): + if key not in allowed: + message = f"{key!r} is an invalid keyword argument for URL()" + raise TypeError(message) + if value is not None and not isinstance(value, allowed[key]): + expected = allowed[key].__name__ + seen = type(value).__name__ + message = f"Argument {key!r} must be {expected} but got {seen}" + raise TypeError(message) + if isinstance(value, bytes): + kwargs[key] = value.decode("ascii") + + if "params" in kwargs: + # Replace any "params" keyword with the raw "query" instead. + # + # Ensure that empty params use `kwargs["query"] = None` rather + # than `kwargs["query"] = ""`, so that generated URLs do not + # include an empty trailing "?". + params = kwargs.pop("params") + kwargs["query"] = None if not params else str(QueryParams(params)) + + if isinstance(url, str): + self._uri_reference = urlparse(url, **kwargs) + elif isinstance(url, URL): + self._uri_reference = url._uri_reference.copy_with(**kwargs) + else: + raise TypeError( + "Invalid type for url. Expected str or httpx.URL," + f" got {type(url)}: {url!r}" + ) + + @property + def scheme(self) -> str: + """ + The URL scheme, such as "http", "https". + Always normalised to lowercase. + """ + return self._uri_reference.scheme + + @property + def userinfo(self) -> bytes: + """ + The URL userinfo as a raw bytestring. + For example: b"jo%40email.com:a%20secret". + """ + return self._uri_reference.userinfo.encode("ascii") + + @property + def username(self) -> str: + """ + The URL username as a string, with URL decoding applied. + For example: "jo@email.com" + """ + userinfo = self._uri_reference.userinfo + return unquote(userinfo.partition(":")[0]) + + @property + def password(self) -> str: + """ + The URL password as a string, with URL decoding applied. + For example: "a secret" + """ + userinfo = self._uri_reference.userinfo + return unquote(userinfo.partition(":")[2]) + + @property + def host(self) -> str: + """ + The URL host as a string. + Always normalized to lowercase. Possibly IDNA encoded. + + Examples: + + url = httpx.URL("http://www.EXAMPLE.org") + assert url.host == "www.example.org" + + url = httpx.URL("http://中国.icom.museum") + assert url.host == "xn--fiqs8s" + + url = httpx.URL("http://xn--fiqs8s.icom.museum") + assert url.host == "xn--fiqs8s" + + url = httpx.URL("https://[::ffff:192.168.0.1]") + assert url.host == "::ffff:192.168.0.1" + """ + return self._uri_reference.host + + @property + def port(self) -> int | None: + """ + The URL port as an integer. + + Note that the URL class performs port normalization as per the WHATWG spec. + Default ports for "http", "https", "ws", "wss", and "ftp" schemes are always + treated as `None`. + + For example: + + assert httpx.URL("http://www.example.com") == httpx.URL("http://www.example.com:80") + assert httpx.URL("http://www.example.com:80").port is None + """ + return self._uri_reference.port + + @property + def netloc(self) -> str: + """ + Either `` or `:` as bytes. + Always normalized to lowercase, and IDNA encoded. + + This property may be used for generating the value of a request + "Host" header. + """ + return self._uri_reference.netloc + + @property + def path(self) -> str: + """ + The URL path as a string. Excluding the query string, and URL decoded. + + For example: + + url = httpx.URL("https://example.com/pa%20th") + assert url.path == "/pa th" + """ + path = self._uri_reference.path or "/" + return unquote(path) + + @property + def query(self) -> bytes: + """ + The URL query string, as raw bytes, excluding the leading b"?". + + This is necessarily a bytewise interface, because we cannot + perform URL decoding of this representation until we've parsed + the keys and values into a QueryParams instance. + + For example: + + url = httpx.URL("https://example.com/?filter=some%20search%20terms") + assert url.query == b"filter=some%20search%20terms" + """ + query = self._uri_reference.query or "" + return query.encode("ascii") + + @property + def params(self) -> "QueryParams": + """ + The URL query parameters, neatly parsed and packaged into an immutable + multidict representation. + """ + return QueryParams(self._uri_reference.query) + + @property + def target(self) -> str: + """ + The complete URL path and query string as raw bytes. + Used as the target when constructing HTTP requests. + + For example: + + GET /users?search=some%20text HTTP/1.1 + Host: www.example.org + Connection: close + """ + target = self._uri_reference.path or "/" + if self._uri_reference.query is not None: + target += "?" + self._uri_reference.query + return target + + @property + def fragment(self) -> str: + """ + The URL fragments, as used in HTML anchors. + As a string, without the leading '#'. + """ + return unquote(self._uri_reference.fragment or "") + + @property + def is_absolute_url(self) -> bool: + """ + Return `True` for absolute URLs such as 'http://example.com/path', + and `False` for relative URLs such as '/path'. + """ + # We don't use `.is_absolute` from `rfc3986` because it treats + # URLs with a fragment portion as not absolute. + # What we actually care about is if the URL provides + # a scheme and hostname to which connections should be made. + return bool(self._uri_reference.scheme and self._uri_reference.host) + + @property + def is_relative_url(self) -> bool: + """ + Return `False` for absolute URLs such as 'http://example.com/path', + and `True` for relative URLs such as '/path'. + """ + return not self.is_absolute_url + + def copy_with(self, **kwargs: typing.Any) -> "URL": + """ + Copy this URL, returning a new URL with some components altered. + Accepts the same set of parameters as the components that are made + available via properties on the `URL` class. + + For example: + + url = httpx.URL("https://www.example.com").copy_with( + username="jo@gmail.com", password="a secret" + ) + assert url == "https://jo%40email.com:a%20secret@www.example.com" + """ + return URL(self, **kwargs) + + def copy_set_param(self, key: str, value: typing.Any = None) -> "URL": + return self.copy_with(params=self.params.copy_set(key, value)) + + def copy_append_param(self, key: str, value: typing.Any = None) -> "URL": + return self.copy_with(params=self.params.copy_append(key, value)) + + def copy_remove_param(self, key: str) -> "URL": + return self.copy_with(params=self.params.copy_remove(key)) + + def copy_merge_params( + self, + params: "QueryParams" | dict[str, str | list[str]] | list[tuple[str, str]] | None, + ) -> "URL": + return self.copy_with(params=self.params.copy_update(params)) + + def join(self, url: "URL" | str) -> "URL": + """ + Return an absolute URL, using this URL as the base. + + Eg. + + url = httpx.URL("https://www.example.com/test") + url = url.join("/new/path") + assert url == "https://www.example.com/new/path" + """ + from urllib.parse import urljoin + + return URL(urljoin(str(self), str(URL(url)))) + + def __hash__(self) -> int: + return hash(str(self)) + + def __eq__(self, other: typing.Any) -> bool: + return isinstance(other, (URL, str)) and str(self) == str(URL(other)) + + def __str__(self) -> str: + return str(self._uri_reference) + + def __repr__(self) -> str: + return f"" + + +class QueryParams(typing.Mapping[str, str]): + """ + URL query parameters, as a multi-dict. + """ + + def __init__( + self, + params: ( + "QueryParams" | dict[str, str | list[str]] | list[tuple[str, str]] | str | None + ) = None, + ) -> None: + d: dict[str, list[str]] = {} + + if params is None: + d = {} + elif isinstance(params, str): + d = urldecode(params) + elif isinstance(params, QueryParams): + d = params.multi_dict() + elif isinstance(params, dict): + # Convert dict inputs like: + # {"a": "123", "b": ["456", "789"]} + # To dict inputs where values are always lists, like: + # {"a": ["123"], "b": ["456", "789"]} + d = {k: [v] if isinstance(v, str) else list(v) for k, v in params.items()} + else: + # Convert list inputs like: + # [("a", "123"), ("a", "456"), ("b", "789")] + # To a dict representation, like: + # {"a": ["123", "456"], "b": ["789"]} + for k, v in params: + d.setdefault(k, []).append(v) + + self._dict = d + + def keys(self) -> typing.KeysView[str]: + """ + Return all the keys in the query params. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert list(q.keys()) == ["a", "b"] + """ + return self._dict.keys() + + def values(self) -> typing.ValuesView[str]: + """ + Return all the values in the query params. If a key occurs more than once + only the first item for that key is returned. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert list(q.values()) == ["123", "789"] + """ + return {k: v[0] for k, v in self._dict.items()}.values() + + def items(self) -> typing.ItemsView[str, str]: + """ + Return all items in the query params. If a key occurs more than once + only the first item for that key is returned. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert list(q.items()) == [("a", "123"), ("b", "789")] + """ + return {k: v[0] for k, v in self._dict.items()}.items() + + def multi_items(self) -> list[tuple[str, str]]: + """ + Return all items in the query params. Allow duplicate keys to occur. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert list(q.multi_items()) == [("a", "123"), ("a", "456"), ("b", "789")] + """ + multi_items: list[tuple[str, str]] = [] + for k, v in self._dict.items(): + multi_items.extend([(k, i) for i in v]) + return multi_items + + def multi_dict(self) -> dict[str, list[str]]: + return {k: list(v) for k, v in self._dict.items()} + + def get(self, key: str, default: typing.Any = None) -> typing.Any: + """ + Get a value from the query param for a given key. If the key occurs + more than once, then only the first value is returned. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert q.get("a") == "123" + """ + if key in self._dict: + return self._dict[key][0] + return default + + def get_list(self, key: str) -> list[str]: + """ + Get all values from the query param for a given key. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert q.get_list("a") == ["123", "456"] + """ + return list(self._dict.get(key, [])) + + def copy_set(self, key: str, value: str) -> "QueryParams": + """ + Return a new QueryParams instance, setting the value of a key. + + Usage: + + q = httpx.QueryParams("a=123") + q = q.set("a", "456") + assert q == httpx.QueryParams("a=456") + """ + q = QueryParams() + q._dict = dict(self._dict) + q._dict[key] = [value] + return q + + def copy_append(self, key: str, value: str) -> "QueryParams": + """ + Return a new QueryParams instance, setting or appending the value of a key. + + Usage: + + q = httpx.QueryParams("a=123") + q = q.append("a", "456") + assert q == httpx.QueryParams("a=123&a=456") + """ + q = QueryParams() + q._dict = dict(self._dict) + q._dict[key] = q.get_list(key) + [value] + return q + + def copy_remove(self, key: str) -> QueryParams: + """ + Return a new QueryParams instance, removing the value of a key. + + Usage: + + q = httpx.QueryParams("a=123") + q = q.remove("a") + assert q == httpx.QueryParams("") + """ + q = QueryParams() + q._dict = dict(self._dict) + q._dict.pop(str(key), None) + return q + + def copy_update( + self, + params: ( + "QueryParams" | dict[str, str | list[str]] | list[tuple[str, str]] | None + ) = None, + ) -> "QueryParams": + """ + Return a new QueryParams instance, updated with. + + Usage: + + q = httpx.QueryParams("a=123") + q = q.copy_update({"b": "456"}) + assert q == httpx.QueryParams("a=123&b=456") + + q = httpx.QueryParams("a=123") + q = q.copy_update({"a": "456", "b": "789"}) + assert q == httpx.QueryParams("a=456&b=789") + """ + q = QueryParams(params) + q._dict = {**self._dict, **q._dict} + return q + + def __getitem__(self, key: str) -> str: + return self._dict[key][0] + + def __contains__(self, key: typing.Any) -> bool: + return key in self._dict + + def __iter__(self) -> typing.Iterator[str]: + return iter(self.keys()) + + def __len__(self) -> int: + return len(self._dict) + + def __bool__(self) -> bool: + return bool(self._dict) + + def __hash__(self) -> int: + return hash(str(self)) + + def __eq__(self, other: typing.Any) -> bool: + if not isinstance(other, self.__class__): + return False + return sorted(self.multi_items()) == sorted(other.multi_items()) + + def __str__(self) -> str: + return urlencode(self.multi_dict()) + + def __repr__(self) -> str: + return f"" diff --git a/src/httpx/__init__.py b/src/httpx/__init__.py new file mode 100644 index 0000000000..9e589ab6cd --- /dev/null +++ b/src/httpx/__init__.py @@ -0,0 +1,65 @@ +from .__version__ import __title__, __version__ +from ._client import * # Client +from ._content import * # Content, File, Files, Form, HTML, JSON, MultiPart, Text +from ._headers import * # Headers +from ._network import * # NetworkBackend, NetworkStream, timeout +from ._parsers import * # HTTPParser, ProtocolError +from ._pool import * # Connection, ConnectionPool, Transport +from ._quickstart import * # get, post, put, patch, delete +from ._response import * # Response +from ._request import * # Request +from ._streams import * # ByteStream, DuplexStream, FileStream, HTTPStream, Stream +from ._server import * # serve_http, run +from ._urlencode import * # quote, unquote, urldecode, urlencode +from ._urls import * # QueryParams, URL + + +__all__ = [ + "__title__", + "__version__", + "ByteStream", + "Client", + "Connection", + "ConnectionPool", + "Content", + "delete", + "DuplexStream", + "File", + "FileStream", + "Files", + "Form", + "get", + "Headers", + "HTML", + "HTTPParser", + "HTTPStream", + "JSON", + "MultiPart", + "NetworkBackend", + "NetworkStream", + "open_connection", + "post", + "ProtocolError", + "put", + "patch", + "Response", + "Request", + "run", + "serve_http", + "Stream", + "Text", + "timeout", + "Transport", + "QueryParams", + "quote", + "unquote", + "URL", + "urldecode", + "urlencode", +] + + +__locals = locals() +for __name in __all__: + if not __name.startswith('__'): + setattr(__locals[__name], "__module__", "httpx") diff --git a/src/httpx/__version__.py b/src/httpx/__version__.py new file mode 100644 index 0000000000..ba1c14e7ec --- /dev/null +++ b/src/httpx/__version__.py @@ -0,0 +1,2 @@ +__title__ = "httpx" +__version__ = "1.0.dev3" \ No newline at end of file diff --git a/src/httpx/_client.py b/src/httpx/_client.py new file mode 100644 index 0000000000..2dd54fd34d --- /dev/null +++ b/src/httpx/_client.py @@ -0,0 +1,156 @@ +import types +import typing + +from ._content import Content +from ._headers import Headers +from ._pool import ConnectionPool, Transport +from ._request import Request +from ._response import Response +from ._streams import Stream +from ._urls import URL + +__all__ = ["Client"] + + +class Client: + def __init__( + self, + url: URL | str | None = None, + headers: Headers | typing.Mapping[str, str] | None = None, + transport: Transport | None = None, + ): + if url is None: + url = "" + if headers is None: + headers = {"User-Agent": "dev"} + if transport is None: + transport = ConnectionPool() + + self.url = URL(url) + self.headers = Headers(headers) + self.transport = transport + self.via = RedirectMiddleware(self.transport) + + def build_request( + self, + method: str, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Request: + return Request( + method=method, + url=self.url.join(url), + headers=self.headers.copy_update(headers), + content=content, + ) + + def request( + self, + method: str, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Response: + request = self.build_request(method, url, headers=headers, content=content) + with self.via.send(request) as response: + response.read() + return response + + def stream( + self, + method: str, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Response: + request = self.build_request(method, url, headers=headers, content=content) + return self.via.send(request) + + def get( + self, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + ): + return self.request("GET", url, headers=headers) + + def post( + self, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ): + return self.request("POST", url, headers=headers, content=content) + + def put( + self, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ): + return self.request("PUT", url, headers=headers, content=content) + + def patch( + self, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ): + return self.request("PATCH", url, headers=headers, content=content) + + def delete( + self, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + ): + return self.request("DELETE", url, headers=headers) + + def close(self): + self.transport.close() + + def __enter__(self): + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None + ): + self.close() + + def __repr__(self): + return f"" + + +class RedirectMiddleware(Transport): + def __init__(self, transport: Transport) -> None: + self._transport = transport + + def is_redirect(self, response: Response) -> bool: + return ( + response.status_code in (301, 302, 303, 307, 308) + and "Location" in response.headers + ) + + def build_redirect_request(self, request: Request, response: Response) -> Request: + raise NotImplementedError() + + def send(self, request: Request) -> Response: + while True: + response = self._transport.send(request) + + if not self.is_redirect(response): + return response + + # If we have a redirect, then we read the body of the response. + # Ensures that the HTTP connection is available for a new + # request/response cycle. + response.read() + response.close() + + # We've made a request-response and now need to issue a redirect request. + request = self.build_redirect_request(request, response) + + def close(self): + pass diff --git a/src/httpx/_content.py b/src/httpx/_content.py new file mode 100644 index 0000000000..e2c4aaa935 --- /dev/null +++ b/src/httpx/_content.py @@ -0,0 +1,378 @@ +import json +import os +import typing + +from ._streams import Stream, ByteStream, FileStream, MultiPartStream +from ._urlencode import urldecode, urlencode + +__all__ = [ + "Content", + "Form", + "File", + "Files", + "JSON", + "MultiPart", + "Text", + "HTML", +] + +# https://github.com/nginx/nginx/blob/master/conf/mime.types +_content_types = { + ".json": "application/json", + ".js": "application/javascript", + ".html": "text/html", + ".css": "text/css", + ".png": "image/png", + ".jpeg": "image/jpeg", + ".jpg": "image/jpeg", + ".gif": "image/gif", +} + + +class Content: + def encode(self) -> Stream: + raise NotImplementedError() + + def content_type(self) -> str: + raise NotImplementedError() + + +class Form(typing.Mapping[str, str], Content): + """ + HTML form data, as an immutable multi-dict. + Form parameters, as a multi-dict. + """ + + def __init__( + self, + form: ( + typing.Mapping[str, str | typing.Sequence[str]] + | typing.Sequence[tuple[str, str]] + | str + | None + ) = None, + ) -> None: + d: dict[str, list[str]] = {} + + if form is None: + d = {} + elif isinstance(form, str): + d = urldecode(form) + elif isinstance(form, typing.Mapping): + # Convert dict inputs like: + # {"a": "123", "b": ["456", "789"]} + # To dict inputs where values are always lists, like: + # {"a": ["123"], "b": ["456", "789"]} + d = {k: [v] if isinstance(v, str) else list(v) for k, v in form.items()} + else: + # Convert list inputs like: + # [("a", "123"), ("a", "456"), ("b", "789")] + # To a dict representation, like: + # {"a": ["123", "456"], "b": ["789"]} + for k, v in form: + d.setdefault(k, []).append(v) + + self._dict = d + + # Content API + + def encode(self) -> Stream: + content = str(self).encode("ascii") + return ByteStream(content) + + def content_type(self) -> str: + return "application/x-www-form-urlencoded" + + # Dict operations + + def keys(self) -> typing.KeysView[str]: + return self._dict.keys() + + def values(self) -> typing.ValuesView[str]: + return {k: v[0] for k, v in self._dict.items()}.values() + + def items(self) -> typing.ItemsView[str, str]: + return {k: v[0] for k, v in self._dict.items()}.items() + + def get(self, key: str, default: typing.Any = None) -> typing.Any: + if key in self._dict: + return self._dict[key][0] + return default + + # Multi-dict operations + + def multi_items(self) -> list[tuple[str, str]]: + multi_items: list[tuple[str, str]] = [] + for k, v in self._dict.items(): + multi_items.extend([(k, i) for i in v]) + return multi_items + + def multi_dict(self) -> dict[str, list[str]]: + return {k: list(v) for k, v in self._dict.items()} + + def get_list(self, key: str) -> list[str]: + return list(self._dict.get(key, [])) + + # Update operations + + def copy_set(self, key: str, value: str) -> "Form": + d = self.multi_dict() + d[key] = [value] + return Form(d) + + def copy_append(self, key: str, value: str) -> "Form": + d = self.multi_dict() + d[key] = d.get(key, []) + [value] + return Form(d) + + def copy_remove(self, key: str) -> "Form": + d = self.multi_dict() + d.pop(key, None) + return Form(d) + + # Accessors & built-ins + + def __getitem__(self, key: str) -> str: + return self._dict[key][0] + + def __contains__(self, key: typing.Any) -> bool: + return key in self._dict + + def __iter__(self) -> typing.Iterator[str]: + return iter(self.keys()) + + def __len__(self) -> int: + return len(self._dict) + + def __bool__(self) -> bool: + return bool(self._dict) + + def __hash__(self) -> int: + return hash(str(self)) + + def __eq__(self, other: typing.Any) -> bool: + return ( + isinstance(other, Form) and + sorted(self.multi_items()) == sorted(other.multi_items()) + ) + + def __str__(self) -> str: + return urlencode(self.multi_dict()) + + def __repr__(self) -> str: + return f"" + + +class File(Content): + """ + Wrapper class used for files in uploads and multipart requests. + """ + + def __init__(self, path: str): + self._path = path + + def name(self) -> str: + return os.path.basename(self._path) + + def size(self) -> int: + return os.path.getsize(self._path) + + def encode(self) -> Stream: + return FileStream(self._path) + + def content_type(self) -> str: + _, ext = os.path.splitext(self._path) + ct = _content_types.get(ext, "application/octet-stream") + if ct.startswith('text/'): + ct += "; charset='utf-8'" + return ct + + def __lt__(self, other: typing.Any) -> bool: + return isinstance(other, File) and other._path < self._path + + def __eq__(self, other: typing.Any) -> bool: + return isinstance(other, File) and other._path == self._path + + def __repr__(self) -> str: + return f"" + + +class Files(typing.Mapping[str, File], Content): + """ + File parameters, as a multi-dict. + """ + + def __init__( + self, + files: ( + typing.Mapping[str, File | typing.Sequence[File]] + | typing.Sequence[tuple[str, File]] + | None + ) = None, + boundary: str = '' + ) -> None: + d: dict[str, list[File]] = {} + + if files is None: + d = {} + elif isinstance(files, typing.Mapping): + d = {k: [v] if isinstance(v, File) else list(v) for k, v in files.items()} + else: + d = {} + for k, v in files: + d.setdefault(k, []).append(v) + + self._dict = d + self._boundary = boundary or os.urandom(16).hex() + + # Standard dict interface + def keys(self) -> typing.KeysView[str]: + return self._dict.keys() + + def values(self) -> typing.ValuesView[File]: + return {k: v[0] for k, v in self._dict.items()}.values() + + def items(self) -> typing.ItemsView[str, File]: + return {k: v[0] for k, v in self._dict.items()}.items() + + def get(self, key: str, default: typing.Any = None) -> typing.Any: + if key in self._dict: + return self._dict[key][0] + return None + + # Multi dict interface + def multi_items(self) -> list[tuple[str, File]]: + multi_items: list[tuple[str, File]] = [] + for k, v in self._dict.items(): + multi_items.extend([(k, i) for i in v]) + return multi_items + + def multi_dict(self) -> dict[str, list[File]]: + return {k: list(v) for k, v in self._dict.items()} + + def get_list(self, key: str) -> list[File]: + return list(self._dict.get(key, [])) + + # Content interface + def encode(self) -> Stream: + return MultiPart(files=self).encode() + + def content_type(self) -> str: + return f"multipart/form-data; boundary={self._boundary}" + + # Builtins + def __getitem__(self, key: str) -> File: + return self._dict[key][0] + + def __contains__(self, key: typing.Any) -> bool: + return key in self._dict + + def __iter__(self) -> typing.Iterator[str]: + return iter(self.keys()) + + def __len__(self) -> int: + return len(self._dict) + + def __bool__(self) -> bool: + return bool(self._dict) + + def __eq__(self, other: typing.Any) -> bool: + return ( + isinstance(other, Files) and + sorted(self.multi_items()) == sorted(other.multi_items()) + ) + + def __repr__(self) -> str: + return f"" + + +class JSON(Content): + def __init__(self, data: typing.Any) -> None: + self._data = data + + def encode(self) -> Stream: + content = json.dumps( + self._data, + ensure_ascii=False, + separators=(",", ":"), + allow_nan=False + ).encode("utf-8") + return ByteStream(content) + + def content_type(self) -> str: + return "application/json" + + def __repr__(self) -> str: + return f"" + + +class Text(Content): + def __init__(self, text: str) -> None: + self._text = text + + def encode(self) -> Stream: + content = self._text.encode("utf-8") + return ByteStream(content) + + def content_type(self) -> str: + return "text/plain; charset='utf-8'" + + def __repr__(self) -> str: + return f"" + + +class HTML(Content): + def __init__(self, text: str) -> None: + self._text = text + + def encode(self) -> Stream: + content = self._text.encode("utf-8") + return ByteStream(content) + + def content_type(self) -> str: + return "text/html; charset='utf-8'" + + def __repr__(self) -> str: + return f"" + + +class MultiPart(Content): + def __init__( + self, + form: ( + Form + | typing.Mapping[str, str | typing.Sequence[str]] + | typing.Sequence[tuple[str, str]] + | str + | None + ) = None, + files: ( + Files + | typing.Mapping[str, File | typing.Sequence[File]] + | typing.Sequence[tuple[str, File]] + | None + ) = None, + boundary: str | None = None + ): + self._form = form if isinstance(form , Form) else Form(form) + self._files = files if isinstance(files, Files) else Files(files) + self._boundary = os.urandom(16).hex() if boundary is None else boundary + + @property + def form(self) -> Form: + return self._form + + @property + def files(self) -> Files: + return self._files + + def encode(self) -> Stream: + form = [(key, value) for key, value in self._form.items()] + files = [(key, file._path) for key, file in self._files.items()] + return MultiPartStream(form, files, boundary=self._boundary) + + def content_type(self) -> str: + return f"multipart/form-data; boundary={self._boundary}" + + def __repr__(self) -> str: + return f"" diff --git a/src/httpx/_headers.py b/src/httpx/_headers.py new file mode 100644 index 0000000000..dade8058d0 --- /dev/null +++ b/src/httpx/_headers.py @@ -0,0 +1,243 @@ +import re +import typing + + +__all__ = ["Headers"] + + +VALID_HEADER_CHARS = ( + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "!#$%&'*+-.^_`|~" +) + + +# TODO... +# +# * Comma folded values, eg. `Vary: ...` +# * Multiple Set-Cookie headers. +# * Non-ascii support. +# * Ordering, including `Host` header exception. + + +def headername(name: str) -> str: + if name.strip(VALID_HEADER_CHARS) or not name: + raise ValueError(f"Invalid HTTP header name {name!r}.") + return name + + +def headervalue(value: str) -> str: + value = value.strip(" ") + if not value or not value.isascii() or not value.isprintable(): + raise ValueError(f"Invalid HTTP header value {value!r}.") + return value + + +class Headers(typing.Mapping[str, str]): + def __init__( + self, + headers: typing.Mapping[str, str] | typing.Sequence[tuple[str, str]] | None = None, + ) -> None: + # {'accept': ('Accept', '*/*')} + d: dict[str, str] = {} + + if isinstance(headers, typing.Mapping): + # Headers({ + # 'Content-Length': '1024', + # 'Content-Type': 'text/plain; charset=utf-8', + # ) + d = {headername(k): headervalue(v) for k, v in headers.items()} + elif headers is not None: + # Headers([ + # ('Location', 'https://www.example.com'), + # ('Set-Cookie', 'session_id=3498jj489jhb98jn'), + # ]) + d = {headername(k): headervalue(v) for k, v in headers} + + self._dict = d + + def keys(self) -> typing.KeysView[str]: + """ + Return all the header keys. + + Usage: + + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert list(h.keys()) == ["Accept", "User-Agent"] + """ + return self._dict.keys() + + def values(self) -> typing.ValuesView[str]: + """ + Return all the header values. + + Usage: + + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert list(h.values()) == ["*/*", "python/httpx"] + """ + return self._dict.values() + + def items(self) -> typing.ItemsView[str, str]: + """ + Return all headers as (key, value) tuples. + + Usage: + + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert list(h.items()) == [("Accept", "*/*"), ("User-Agent", "python/httpx")] + """ + return self._dict.items() + + def get(self, key: str, default: typing.Any = None) -> typing.Any: + """ + Get a value from the query param for a given key. If the key occurs + more than once, then only the first value is returned. + + Usage: + + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert h.get("User-Agent") == "python/httpx" + """ + for k, v in self._dict.items(): + if k.lower() == key.lower(): + return v + return default + + def copy_set(self, key: str, value: str) -> "Headers": + """ + Return a new Headers instance, setting the value of a key. + + Usage: + + h = httpx.Headers({"Expires": "0"}) + h = h.copy_set("Expires", "Wed, 21 Oct 2015 07:28:00 GMT") + assert h == httpx.Headers({"Expires": "Wed, 21 Oct 2015 07:28:00 GMT"}) + """ + l = [] + seen = False + + # Either insert... + for k, v in self._dict.items(): + if k.lower() == key.lower(): + l.append((key, value)) + seen = True + else: + l.append((k, v)) + + # Or append... + if not seen: + l.append((key, value)) + + return Headers(l) + + def copy_remove(self, key: str) -> "Headers": + """ + Return a new Headers instance, removing the value of a key. + + Usage: + + h = httpx.Headers({"Accept": "*/*"}) + h = h.copy_remove("Accept") + assert h == httpx.Headers({}) + """ + h = {k: v for k, v in self._dict.items() if k.lower() != key.lower()} + return Headers(h) + + def copy_update(self, update: "Headers" | typing.Mapping[str, str] | None) -> "Headers": + """ + Return a new Headers instance, removing the value of a key. + + Usage: + + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + h = h.copy_update({"Accept-Encoding": "gzip"}) + assert h == httpx.Headers({"Accept": "*/*", "Accept-Encoding": "gzip", "User-Agent": "python/httpx"}) + """ + if update is None: + return self + + new = update if isinstance(update, Headers) else Headers(update) + + # Remove updated items using a case-insensitive approach... + keys = set([key.lower() for key in new.keys()]) + h = {k: v for k, v in self._dict.items() if k.lower() not in keys} + + # Perform the actual update... + h.update(dict(new)) + + return Headers(h) + + def __getitem__(self, key: str) -> str: + match = key.lower() + for k, v in self._dict.items(): + if k.lower() == match: + return v + raise KeyError(key) + + def __contains__(self, key: typing.Any) -> bool: + match = key.lower() + return any(k.lower() == match for k in self._dict.keys()) + + def __iter__(self) -> typing.Iterator[str]: + return iter(self.keys()) + + def __len__(self) -> int: + return len(self._dict) + + def __bool__(self) -> bool: + return bool(self._dict) + + def __eq__(self, other: typing.Any) -> bool: + self_lower = {k.lower(): v for k, v in self.items()} + other_lower = {k.lower(): v for k, v in Headers(other).items()} + return self_lower == other_lower + + def __repr__(self) -> str: + return f"" + + +def parse_opts_header(header: str) -> tuple[str, dict[str, str]]: + # The Content-Type header is described in RFC 2616 'Content-Type' + # https://datatracker.ietf.org/doc/html/rfc2616#section-14.17 + + # The 'type/subtype; parameter' format is described in RFC 2616 'Media Types' + # https://datatracker.ietf.org/doc/html/rfc2616#section-3.7 + + # Parameter quoting is described in RFC 2616 'Transfer Codings' + # https://datatracker.ietf.org/doc/html/rfc2616#section-3.6 + + header = header.strip() + content_type = '' + params = {} + + # Match the content type (up to the first semicolon or end) + match = re.match(r'^([^;]+)', header) + if match: + content_type = match.group(1).strip().lower() + rest = header[match.end():] + else: + return '', {} + + # Parse parameters, accounting for quoted strings + param_pattern = re.compile(r''' + ;\s* # Semicolon + optional whitespace + (?P[^=;\s]+) # Parameter key + = # Equal sign + (?P # Parameter value: + "(?:[^"\\]|\\.)*" # Quoted string with escapes + | # OR + [^;]* # Unquoted string (until semicolon) + ) + ''', re.VERBOSE) + + for match in param_pattern.finditer(rest): + key = match.group('key').lower() + value = match.group('value').strip() + if value.startswith('"') and value.endswith('"'): + # Remove surrounding quotes and unescape + value = re.sub(r'\\(.)', r'\1', value[1:-1]) + params[key] = value + + return content_type, params diff --git a/src/httpx/_network.py b/src/httpx/_network.py new file mode 100644 index 0000000000..5ea9bb5472 --- /dev/null +++ b/src/httpx/_network.py @@ -0,0 +1,243 @@ +import concurrent.futures +import contextlib +import contextvars +import select +import socket +import ssl +import threading +import time +import types +import typing + +from ._streams import Stream + + +__all__ = ["NetworkBackend", "NetworkStream", "timeout"] + +_timeout_stack: contextvars.ContextVar[list[float]] = contextvars.ContextVar("timeout_context", default=[]) + + +@contextlib.contextmanager +def timeout(duration: float) -> typing.Iterator[None]: + """ + A context managed timeout API. + + with timeout(1.0): + ... + """ + now = time.monotonic() + until = now + duration + stack = typing.cast(list[float], _timeout_stack.get()) + stack = [until] + stack + token = _timeout_stack.set(stack) + try: + yield + finally: + _timeout_stack.reset(token) + + +def get_current_timeout() -> float | None: + stack = _timeout_stack.get() + if not stack: + return None + soonest = min(stack) + now = time.monotonic() + remaining = soonest - now + if remaining <= 0.0: + raise TimeoutError() + return remaining + + +class NetworkStream(Stream): + def __init__(self, sock: socket.socket, address: tuple[str, int]) -> None: + self._socket = sock + self._address = address + self._is_tls = False + self._is_closed = False + + @property + def host(self) -> str: + return self._address[0] + + @property + def port(self) -> int: + return self._address[1] + + def read(self, size: int = -1) -> bytes: + if size < 0: + size = 64 * 1024 + timeout = get_current_timeout() + self._socket.settimeout(timeout) + content = self._socket.recv(size) + return content + + def write(self, buffer: bytes) -> None: + while buffer: + timeout = get_current_timeout() + self._socket.settimeout(timeout) + n = self._socket.send(buffer) + buffer = buffer[n:] + + def close(self) -> None: + if not self._is_closed: + self._is_closed = True + self._socket.close() + + def __repr__(self): + description = "" + description += " TLS" if self._is_tls else "" + description += " CLOSED" if self._is_closed else "" + return f"" + + def __del__(self): + if not self._is_closed: + import warnings + warnings.warn(f"NetworkStream was garbage collected without being closed.") + + def __enter__(self) -> "NetworkStream": + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ): + self.close() + + +class NetworkListener: + def __init__(self, sock: socket.socket, address: tuple[str, int]) -> None: + self._server_socket = sock + self._address = address + self._is_closed = False + + @property + def host(self): + return self._address[0] + + @property + def port(self): + return self._address[1] + + def accept(self) -> NetworkStream | None: + """ + Blocks until an incoming connection is accepted, and returns the NetworkStream. + Stops blocking and returns `None` once the listener is closed. + """ + while not self._is_closed: + r, _, _ = select.select([self._server_socket], [], [], 3) + if r: + sock, address = self._server_socket.accept() + return NetworkStream(sock, address) + return None + + def close(self): + self._is_closed = True + self._server_socket.close() + + def __del__(self): + if not self._is_closed: + import warnings + warnings.warn("NetworkListener was garbage collected without being closed.") + + def __enter__(self) -> "NetworkListener": + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ): + self.close() + + +class NetworkServer: + def __init__(self, listener: NetworkListener, handler: typing.Callable[[NetworkStream], None]) -> None: + self.listener = listener + self.handler = handler + self._max_workers = 5 + self._executor = None + self._thread = None + self._streams = list[NetworkStream] + + @property + def host(self): + return self.listener.host + + @property + def port(self): + return self.listener.port + + def __enter__(self): + self._executor = concurrent.futures.ThreadPoolExecutor(max_workers=self._max_workers) + self._executor.submit(self._serve) + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.listener.close() + self._executor.shutdown(wait=True) + + def _serve(self): + while stream := self.listener.accept(): + self._executor.submit(self._handler, stream) + + def _handler(self, stream): + try: + self.handler(stream) + finally: + stream.close() + + +class NetworkBackend: + def __init__(self, ssl_ctx: ssl.SSLContext | None = None): + self._ssl_ctx = self.create_default_context() if ssl_ctx is None else ssl_ctx + + def create_default_context(self) -> ssl.SSLContext: + import certifi + return ssl.create_default_context(cafile=certifi.where()) + + def connect(self, host: str, port: int) -> NetworkStream: + """ + Connect to the given address, returning a NetworkStream instance. + """ + address = (host, port) + timeout = get_current_timeout() + sock = socket.create_connection(address, timeout=timeout) + return NetworkStream(sock, address) + + def connect_tls(self, host: str, port: int, hostname: str = '') -> NetworkStream: + """ + Connect to the given address, returning a NetworkStream instance. + """ + address = (host, port) + hostname = hostname or host + timeout = get_current_timeout() + sock = socket.create_connection(address, timeout=timeout) + sock = self._ssl_ctx.wrap_socket(sock, server_hostname=hostname) + return NetworkStream(sock, address) + + def listen(self, host: str, port: int) -> NetworkListener: + """ + List on the given address, returning a NetworkListener instance. + """ + address = (host, port) + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.bind(address) + sock.listen(5) + sock.setblocking(False) + return NetworkListener(sock, address) + + def serve(self, host: str, port: int, handler: typing.Callable[[NetworkStream], None]) -> NetworkServer: + listener = self.listen(host, port) + return NetworkServer(listener, handler) + + def __repr__(self): + return "" + + +Semaphore = threading.Semaphore +Lock = threading.Lock +sleep = time.sleep diff --git a/src/httpx/_parsers.py b/src/httpx/_parsers.py new file mode 100644 index 0000000000..830fccd901 --- /dev/null +++ b/src/httpx/_parsers.py @@ -0,0 +1,515 @@ +import enum + +from ._streams import Stream + +__all__ = ['HTTPParser', 'Mode', 'ProtocolError'] + + +# TODO... + +# * Upgrade +# * CONNECT + +# * Support 'Expect: 100 Continue' +# * Add 'Error' state transitions +# * Add tests to trickle data +# * Add type annotations + +# * Optional... HTTP/1.0 support +# * Read trailing headers on Transfer-Encoding: chunked. Not just '\r\n'. +# * When writing Transfer-Encoding: chunked, split large writes into buffer size. +# * When reading Transfer-Encoding: chunked, handle incomplete reads from large chunk sizes. +# * .read() doesn't document if will always return maximum available. + +# * validate method, target, protocol in request line +# * validate protocol, status_code, reason_phrase in response line +# * validate name, value on headers + + +class State(enum.Enum): + WAIT = 0 + SEND_METHOD_LINE = 1 + SEND_STATUS_LINE = 2 + SEND_HEADERS = 3 + SEND_BODY = 4 + RECV_METHOD_LINE = 5 + RECV_STATUS_LINE = 6 + RECV_HEADERS = 7 + RECV_BODY = 8 + DONE = 9 + CLOSED = 10 + + +class Mode(enum.Enum): + CLIENT = 0 + SERVER = 1 + + +# The usual transitions will be... + +# IDLE, IDLE +# SEND_HEADERS, IDLE +# SEND_BODY, IDLE +# DONE, IDLE +# DONE, SEND_HEADERS +# DONE, SEND_BODY +# DONE, DONE + +# Then either back to IDLE, IDLE +# or move to CLOSED, CLOSED + +# 1. It is also valid for the server to start +# sending the response without waiting for the +# complete request. +# 2. 1xx status codes are interim states, and +# transition from SEND_HEADERS back to IDLE +# 3. ... + +class ProtocolError(Exception): + pass + + +class HTTPParser: + """ + Usage... + + client = HTTPParser(writer, reader) + client.send_method_line() + client.send_headers() + client.send_body() + client.recv_status_line() + client.recv_headers() + client.recv_body() + client.complete() + client.close() + """ + def __init__(self, stream: Stream, mode: str) -> None: + self.stream = stream + self.parser = ReadAheadParser(stream) + self.mode = {'CLIENT': Mode.CLIENT, 'SERVER': Mode.SERVER}[mode] + + # Track state... + if self.mode == Mode.CLIENT: + self.send_state: State = State.SEND_METHOD_LINE + self.recv_state: State = State.WAIT + else: + self.recv_state = State.RECV_METHOD_LINE + self.send_state = State.WAIT + + # Track message framing... + self.send_content_length: int | None = 0 + self.recv_content_length: int | None = 0 + self.send_seen_length = 0 + self.recv_seen_length = 0 + + # Track connection keep alive... + self.send_keep_alive = True + self.recv_keep_alive = True + + # Special states... + self.processing_1xx = False + + def send_method_line(self, method: bytes, target: bytes, protocol: bytes) -> None: + """ + Send the initial request line: + + >>> p.send_method_line(b'GET', b'/', b'HTTP/1.1') + + Sending state will switch to SEND_HEADERS state. + """ + if self.send_state != State.SEND_METHOD_LINE: + msg = f"Called 'send_method_line' in invalid state {self.send_state}" + raise ProtocolError(msg) + + # Send initial request line, eg. "GET / HTTP/1.1" + if protocol != b'HTTP/1.1': + raise ProtocolError("Sent unsupported protocol version") + data = b" ".join([method, target, protocol]) + b"\r\n" + self.stream.write(data) + + self.send_state = State.SEND_HEADERS + self.recv_state = State.RECV_STATUS_LINE + + def send_status_line(self, protocol: bytes, status_code: int, reason: bytes) -> None: + """ + Send the initial response line: + + >>> p.send_method_line(b'HTTP/1.1', 200, b'OK') + + Sending state will switch to SEND_HEADERS state. + """ + if self.send_state != State.SEND_STATUS_LINE: + msg = f"Called 'send_status_line' in invalid state {self.send_state}" + raise ProtocolError(msg) + + # Send initial request line, eg. "GET / HTTP/1.1" + if protocol != b'HTTP/1.1': + raise ProtocolError("Sent unsupported protocol version") + status_code_bytes = str(status_code).encode('ascii') + data = b" ".join([protocol, status_code_bytes, reason]) + b"\r\n" + self.stream.write(data) + + self.send_state = State.SEND_HEADERS + + def send_headers(self, headers: list[tuple[bytes, bytes]]) -> None: + """ + Send the request headers: + + >>> p.send_headers([(b'Host', b'www.example.com')]) + + Sending state will switch to SEND_BODY state. + """ + if self.send_state != State.SEND_HEADERS: + msg = f"Called 'send_headers' in invalid state {self.send_state}" + raise ProtocolError(msg) + + # Update header state + seen_host = False + for name, value in headers: + lname = name.lower() + if lname == b'host': + seen_host = True + elif lname == b'content-length': + self.send_content_length = bounded_int( + value, + max_digits=20, + exc_text="Sent invalid Content-Length" + ) + elif lname == b'connection' and value == b'close': + self.send_keep_alive = False + elif lname == b'transfer-encoding' and value == b'chunked': + self.send_content_length = None + + if self.mode == Mode.CLIENT and not seen_host: + raise ProtocolError("Request missing 'Host' header") + + # Send request headers + lines = [name + b": " + value + b"\r\n" for name, value in headers] + data = b"".join(lines) + b"\r\n" + self.stream.write(data) + + self.send_state = State.SEND_BODY + + def send_body(self, body: bytes) -> None: + """ + Send the request body. An empty bytes argument indicates the end of the stream: + + >>> p.send_body(b'') + + Sending state will switch to DONE. + """ + if self.send_state != State.SEND_BODY: + msg = f"Called 'send_body' in invalid state {self.send_state}" + raise ProtocolError(msg) + + if self.send_content_length is None: + # Transfer-Encoding: chunked + self.send_seen_length += len(body) + marker = f'{len(body):x}\r\n'.encode('ascii') + self.stream.write(marker + body + b'\r\n') + + else: + # Content-Length: xxx + self.send_seen_length += len(body) + if self.send_seen_length > self.send_content_length: + msg = 'Too much data sent for declared Content-Length' + raise ProtocolError(msg) + if self.send_seen_length < self.send_content_length and body == b'': + msg = 'Not enough data sent for declared Content-Length' + raise ProtocolError(msg) + if body: + self.stream.write(body) + + if body == b'': + # Handle body close + self.send_state = State.DONE + + def recv_method_line(self) -> tuple[bytes, bytes, bytes]: + """ + Receive the initial request method line: + + >>> method, target, protocol = p.recv_status_line() + + Receive state will switch to RECV_HEADERS. + """ + if self.recv_state != State.RECV_METHOD_LINE: + msg = f"Called 'recv_method_line' in invalid state {self.recv_state}" + raise ProtocolError(msg) + + # Read initial response line, eg. "GET / HTTP/1.1" + exc_text = "reading request method line" + line = self.parser.read_until(b"\r\n", max_size=4096, exc_text=exc_text) + method, target, protocol = line.split(b" ", 2) + if protocol != b'HTTP/1.1': + raise ProtocolError("Received unsupported protocol version") + + self.recv_state = State.RECV_HEADERS + self.send_state = State.SEND_STATUS_LINE + return method, target, protocol + + def recv_status_line(self) -> tuple[bytes, int, bytes]: + """ + Receive the initial response status line: + + >>> protocol, status_code, reason_phrase = p.recv_status_line() + + Receive state will switch to RECV_HEADERS. + """ + if self.recv_state != State.RECV_STATUS_LINE: + msg = f"Called 'recv_status_line' in invalid state {self.recv_state}" + raise ProtocolError(msg) + + # Read initial response line, eg. "HTTP/1.1 200 OK" + exc_text = "reading response status line" + line = self.parser.read_until(b"\r\n", max_size=4096, exc_text=exc_text) + protocol, status_code_str, reason_phrase = line.split(b" ", 2) + if protocol != b'HTTP/1.1': + raise ProtocolError("Received unsupported protocol version") + + status_code = bounded_int( + status_code_str, + max_digits=3, + exc_text="Received invalid status code" + ) + if status_code < 100: + raise ProtocolError("Received invalid status code") + # 1xx status codes preceed the final response status code + self.processing_1xx = status_code < 200 + + self.recv_state = State.RECV_HEADERS + return protocol, status_code, reason_phrase + + def recv_headers(self) -> list[tuple[bytes, bytes]]: + """ + Receive the response headers: + + >>> headers = p.recv_status_line() + + Receive state will switch to RECV_BODY by default. + Receive state will revert to RECV_STATUS_CODE for interim 1xx responses. + """ + if self.recv_state != State.RECV_HEADERS: + msg = f"Called 'recv_headers' in invalid state {self.recv_state}" + raise ProtocolError(msg) + + # Read response headers + headers = [] + exc_text = "reading response headers" + while line := self.parser.read_until(b"\r\n", max_size=4096, exc_text=exc_text): + name, value = line.split(b":", 1) + value = value.strip(b" ") + headers.append((name, value)) + + # Update header state + seen_host = False + for name, value in headers: + lname = name.lower() + if lname == b'host': + seen_host = True + elif lname == b'content-length': + self.recv_content_length = bounded_int( + value, + max_digits=20, + exc_text="Received invalid Content-Length" + ) + elif lname == b'connection' and value == b'close': + self.recv_keep_alive = False + elif lname == b'transfer-encoding' and value == b'chunked': + self.recv_content_length = None + + if self.mode == Mode.SERVER and not seen_host: + raise ProtocolError("Request missing 'Host' header") + + if self.processing_1xx: + # 1xx status codes preceed the final response status code + self.processing_1xx = False + self.recv_state = State.RECV_STATUS_LINE + else: + self.recv_state = State.RECV_BODY + return headers + + def recv_body(self) -> bytes: + """ + Receive the response body. An empty byte string indicates the end of the stream: + + >>> buffer = bytearray() + >>> while body := p.recv_body() + >>> buffer.extend(body) + + The server will switch to DONE. + """ + if self.recv_state != State.RECV_BODY: + msg = f"Called 'recv_body' in invalid state {self.recv_state}" + raise ProtocolError(msg) + + if self.recv_content_length is None: + # Transfer-Encoding: chunked + exc_text = 'reading chunk size' + line = self.parser.read_until(b"\r\n", max_size=4096, exc_text=exc_text) + sizestr, _, _ = line.partition(b";") + + exc_text = "Received invalid chunk size" + size = bounded_hex(sizestr, max_digits=8, exc_text=exc_text) + if size > 0: + body = self.parser.read(size=size) + exc_text = 'reading chunk data' + self.parser.read_until(b"\r\n", max_size=2, exc_text=exc_text) + self.recv_seen_length += len(body) + else: + body = b'' + exc_text = 'reading chunk termination' + self.parser.read_until(b"\r\n", max_size=2, exc_text=exc_text) + + else: + # Content-Length: xxx + remaining = self.recv_content_length - self.recv_seen_length + size = min(remaining, 4096) + body = self.parser.read(size=size) + self.recv_seen_length += len(body) + if self.recv_seen_length < self.recv_content_length and body == b'': + msg = 'Not enough data received for declared Content-Length' + raise ProtocolError(msg) + + if body == b'': + # Handle body close + self.recv_state = State.DONE + return body + + def complete(self): + is_fully_complete = self.send_state == State.DONE and self.recv_state == State.DONE + is_keepalive = self.send_keep_alive and self.recv_keep_alive + + if not (is_fully_complete and is_keepalive): + self.close() + return + + if self.mode == Mode.CLIENT: + self.send_state = State.SEND_METHOD_LINE + self.recv_state = State.WAIT + else: + self.recv_state = State.RECV_METHOD_LINE + self.send_state = State.WAIT + + self.send_content_length = 0 + self.recv_content_length = 0 + self.send_seen_length = 0 + self.recv_seen_length = 0 + self.send_keep_alive = True + self.recv_keep_alive = True + self.processing_1xx = False + + def close(self): + if self.send_state != State.CLOSED: + self.send_state = State.CLOSED + self.recv_state = State.CLOSED + self.stream.close() + + def is_idle(self) -> bool: + return ( + self.send_state == State.SEND_METHOD_LINE or + self.recv_state == State.RECV_METHOD_LINE + ) + + def is_closed(self) -> bool: + return self.send_state == State.CLOSED + + def description(self) -> str: + return { + State.SEND_METHOD_LINE: "idle", + State.CLOSED: "closed", + }.get(self.send_state, "active") + + def __repr__(self) -> str: + cl_state = self.send_state.name + sr_state = self.recv_state.name + detail = f"client {cl_state}, server {sr_state}" + return f'' + + +class ReadAheadParser: + """ + A buffered I/O stream, with methods for read-ahead parsing. + """ + def __init__(self, stream: Stream) -> None: + self._buffer = b'' + self._stream = stream + self._chunk_size = 4096 + + def _read_some(self) -> bytes: + if self._buffer: + ret, self._buffer = self._buffer, b'' + return ret + return self._stream.read(self._chunk_size) + + def _push_back(self, buffer): + assert self._buffer == b'' + self._buffer = buffer + + def read(self, size: int) -> bytes: + """ + Read and return up to 'size' bytes from the stream, with I/O buffering provided. + + * Returns b'' to indicate connection close. + """ + buffer = bytearray() + while len(buffer) < size: + chunk = self._read_some() + if not chunk: + break + buffer.extend(chunk) + + if len(buffer) > size: + buffer, push_back = buffer[:size], buffer[size:] + self._push_back(bytes(push_back)) + return bytes(buffer) + + def read_until(self, marker: bytes, max_size: int, exc_text: str) -> bytes: + """ + Read and return bytes from the stream, delimited by marker. + + * The marker is not included in the return bytes. + * The marker is consumed from the I/O stream. + * Raises `ProtocolError` if the stream closes before a marker occurance. + * Raises `ProtocolError` if marker did not occur within 'max_size + len(marker)' bytes. + """ + buffer = bytearray() + while len(buffer) <= max_size: + chunk = self._read_some() + if not chunk: + # stream closed before marker found. + raise ProtocolError(f"Stream closed early {exc_text}") + start_search = max(len(buffer) - len(marker), 0) + buffer.extend(chunk) + index = buffer.find(marker, start_search) + + if index > max_size: + # marker was found, though 'max_size' exceeded. + raise ProtocolError(f"Exceeded maximum size {exc_text}") + elif index >= 0: + endindex = index + len(marker) + self._push_back(bytes(buffer[endindex:])) + return bytes(buffer[:index]) + + raise ProtocolError(f"Exceeded maximum size {exc_text}") + + +def bounded_int(intstr: bytes, max_digits: int, exc_text: str): + if len(intstr) > max_digits: + # Length of bytestring exceeds maximum. + raise ProtocolError(exc_text) + if len(intstr.strip(b'0123456789')) != 0: + # Contains invalid characters. + raise ProtocolError(exc_text) + + return int(intstr) + + +def bounded_hex(hexstr: bytes, max_digits: int, exc_text: str): + if len(hexstr) > max_digits: + # Length of bytestring exceeds maximum. + raise ProtocolError(exc_text) + if len(hexstr.strip(b'0123456789abcdefABCDEF')) != 0: + # Contains invalid characters. + raise ProtocolError(exc_text) + + return int(hexstr, base=16) diff --git a/src/httpx/_pool.py b/src/httpx/_pool.py new file mode 100644 index 0000000000..7193f8d81c --- /dev/null +++ b/src/httpx/_pool.py @@ -0,0 +1,284 @@ +import time +import typing +import types + +from ._content import Content +from ._headers import Headers +from ._network import Lock, NetworkBackend, Semaphore +from ._parsers import HTTPParser +from ._response import Response +from ._request import Request +from ._streams import HTTPStream, Stream +from ._urls import URL + + +__all__ = [ + "Transport", + "ConnectionPool", + "Connection", + "open_connection", +] + + +class Transport: + def send(self, request: Request) -> Response: + raise NotImplementedError() + + def close(self): + pass + + def request( + self, + method: str, + url: URL | str, + headers: Headers | dict[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Response: + request = Request(method, url, headers=headers, content=content) + with self.send(request) as response: + response.read() + return response + + def stream( + self, + method: str, + url: URL | str, + headers: Headers | dict[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Response: + request = Request(method, url, headers=headers, content=content) + response = self.send(request) + return response + + +class ConnectionPool(Transport): + def __init__(self, backend: NetworkBackend | None = None): + if backend is None: + backend = NetworkBackend() + + self._connections: list[Connection] = [] + self._network_backend = backend + self._limit_concurrency = Semaphore(100) + self._closed = False + + # Public API... + def send(self, request: Request) -> Response: + if self._closed: + raise RuntimeError("ConnectionPool is closed.") + + # TODO: concurrency limiting + self._cleanup() + connection = self._get_connection(request) + response = connection.send(request) + return response + + def close(self): + self._closed = True + closing = list(self._connections) + self._connections = [] + for conn in closing: + conn.close() + + # Create or reuse connections as required... + def _get_connection(self, request: Request) -> "Connection": + # Attempt to reuse an existing connection. + url = request.url + origin = URL(scheme=url.scheme, host=url.host, port=url.port) + now = time.monotonic() + for conn in self._connections: + if conn.origin() == origin and conn.is_idle() and not conn.is_expired(now): + return conn + + # Or else create a new connection. + conn = open_connection( + origin, + hostname=request.headers["Host"], + backend=self._network_backend + ) + self._connections.append(conn) + return conn + + # Connection pool management... + def _cleanup(self) -> None: + now = time.monotonic() + for conn in list(self._connections): + if conn.is_expired(now): + conn.close() + if conn.is_closed(): + self._connections.remove(conn) + + @property + def connections(self) -> typing.List['Connection']: + return [c for c in self._connections] + + def description(self) -> str: + counts = {"active": 0} + for status in [c.description() for c in self._connections]: + counts[status] = counts.get(status, 0) + 1 + return ", ".join(f"{count} {status}" for status, count in counts.items()) + + # Builtins... + def __repr__(self) -> str: + return f"" + + def __del__(self): + if not self._closed: + import warnings + warnings.warn("ConnectionPool was garbage collected without being closed.") + + def __enter__(self) -> "ConnectionPool": + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ) -> None: + self.close() + + +class Connection(Transport): + def __init__(self, stream: Stream, origin: URL | str): + self._stream = stream + self._origin = URL(origin) + self._keepalive_duration = 5.0 + self._idle_expiry = time.monotonic() + self._keepalive_duration + self._request_lock = Lock() + self._parser = HTTPParser(stream, mode='CLIENT') + + # API for connection pool management... + def origin(self) -> URL: + return self._origin + + def is_idle(self) -> bool: + return self._parser.is_idle() + + def is_expired(self, when: float) -> bool: + return self._parser.is_idle() and when > self._idle_expiry + + def is_closed(self) -> bool: + return self._parser.is_closed() + + def description(self) -> str: + return self._parser.description() + + # API entry points... + def send(self, request: Request) -> Response: + #async with self._request_lock: + # try: + self._send_head(request) + self._send_body(request) + code, headers = self._recv_head() + stream = HTTPStream(self._recv_body, self._complete) + # TODO... + return Response(code, headers=headers, content=stream) + # finally: + # await self._cycle_complete() + + def close(self) -> None: + with self._request_lock: + self._close() + + # Top-level API for working directly with a connection. + def request( + self, + method: str, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Response: + url = self._origin.join(url) + request = Request(method, url, headers=headers, content=content) + with self.send(request) as response: + response.read() + return response + + def stream( + self, + method: str, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ) -> Response: + url = self._origin.join(url) + request = Request(method, url, headers=headers, content=content) + return self.send(request) + + # Send the request... + def _send_head(self, request: Request) -> None: + method = request.method.encode('ascii') + target = request.url.target.encode('ascii') + protocol = b'HTTP/1.1' + self._parser.send_method_line(method, target, protocol) + headers = [ + (k.encode('ascii'), v.encode('ascii')) + for k, v in request.headers.items() + ] + self._parser.send_headers(headers) + + def _send_body(self, request: Request) -> None: + while data := request.stream.read(64 * 1024): + self._parser.send_body(data) + self._parser.send_body(b'') + + # Receive the response... + def _recv_head(self) -> tuple[int, Headers]: + _, code, _ = self._parser.recv_status_line() + h = self._parser.recv_headers() + headers = Headers([ + (k.decode('ascii'), v.decode('ascii')) + for k, v in h + ]) + return code, headers + + def _recv_body(self) -> bytes: + return self._parser.recv_body() + + # Request/response cycle complete... + def _complete(self) -> None: + self._parser.complete() + self._idle_expiry = time.monotonic() + self._keepalive_duration + + def _close(self) -> None: + self._parser.close() + + # Builtins... + def __repr__(self) -> str: + return f"" + + def __enter__(self) -> "Connection": + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None, + ): + self.close() + + +def open_connection( + url: URL | str, + hostname: str = '', + backend: NetworkBackend | None = None, + ) -> Connection: + + if isinstance(url, str): + url = URL(url) + + if url.scheme not in ("http", "https"): + raise ValueError("URL scheme must be 'http://' or 'https://'.") + if backend is None: + backend = NetworkBackend() + + host = url.host + port = url.port or {"http": 80, "https": 443}[url.scheme] + + if url.scheme == "https": + stream = backend.connect_tls(host, port, hostname) + else: + stream = backend.connect(host, port) + + return Connection(stream, url) diff --git a/src/httpx/_quickstart.py b/src/httpx/_quickstart.py new file mode 100644 index 0000000000..1a975301a3 --- /dev/null +++ b/src/httpx/_quickstart.py @@ -0,0 +1,49 @@ +import typing + +from ._client import Client +from ._content import Content +from ._headers import Headers +from ._streams import Stream +from ._urls import URL + + +__all__ = ['get', 'post', 'put', 'patch', 'delete'] + + +def get( + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, +): + with Client() as client: + return client.request("GET", url=url, headers=headers) + +def post( + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, +): + with Client() as client: + return client.request("POST", url, headers=headers, content=content) + +def put( + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, +): + with Client() as client: + return client.request("PUT", url, headers=headers, content=content) + +def patch( + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, +): + with Client() as client: + return client.request("PATCH", url, headers=headers, content=content) + +def delete( + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, +): + with Client() as client: + return client.request("DELETE", url=url, headers=headers) diff --git a/src/httpx/_request.py b/src/httpx/_request.py new file mode 100644 index 0000000000..1b739b1872 --- /dev/null +++ b/src/httpx/_request.py @@ -0,0 +1,93 @@ +import types +import typing + +from ._content import Content +from ._streams import ByteStream, Stream +from ._headers import Headers +from ._urls import URL + +__all__ = ["Request"] + + +class Request: + def __init__( + self, + method: str, + url: URL | str, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ): + self.method = method + self.url = URL(url) + self.headers = Headers(headers) + self.stream: Stream = ByteStream(b"") + + # https://datatracker.ietf.org/doc/html/rfc2616#section-14.23 + # RFC 2616, Section 14.23, Host. + # + # A client MUST include a Host header field in all HTTP/1.1 request messages. + if "Host" not in self.headers: + self.headers = self.headers.copy_set("Host", self.url.netloc) + + if content is not None: + if isinstance(content, bytes): + self.stream = ByteStream(content) + elif isinstance(content, Stream): + self.stream = content + elif isinstance(content, Content): + ct = content.content_type() + self.stream = content.encode() + self.headers = self.headers.copy_set("Content-Type", ct) + else: + raise TypeError(f'Expected `Content | Stream | bytes | None` got {type(content)}') + + # https://datatracker.ietf.org/doc/html/rfc2616#section-4.3 + # RFC 2616, Section 4.3, Message Body. + # + # The presence of a message-body in a request is signaled by the + # inclusion of a Content-Length or Transfer-Encoding header field in + # the request's message-headers. + content_length: int | None = self.stream.size + if content_length is None: + self.headers = self.headers.copy_set("Transfer-Encoding", "chunked") + elif content_length > 0: + self.headers = self.headers.copy_set("Content-Length", str(content_length)) + + elif method in ("POST", "PUT", "PATCH"): + # https://datatracker.ietf.org/doc/html/rfc7230#section-3.3.2 + # RFC 7230, Section 3.3.2, Content Length. + # + # A user agent SHOULD send a Content-Length in a request message when no + # Transfer-Encoding is sent and the request method defines a meaning for + # an enclosed payload body. For example, a Content-Length header field is + # normally sent in a POST request even when the value is 0. + # (indicating an empty payload body). + self.headers = self.headers.copy_set("Content-Length", "0") + + @property + def body(self) -> bytes: + if not hasattr(self, '_body'): + raise RuntimeError("'.body' cannot be accessed without calling '.read()'") + return self._body + + def read(self) -> bytes: + if not hasattr(self, '_body'): + self._body = self.stream.read() + self.stream = ByteStream(self._body) + return self._body + + def close(self) -> None: + self.stream.close() + + def __enter__(self): + return self + + def __exit__(self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None + ): + self.close() + + def __repr__(self): + return f"" diff --git a/src/httpx/_response.py b/src/httpx/_response.py new file mode 100644 index 0000000000..abfec81029 --- /dev/null +++ b/src/httpx/_response.py @@ -0,0 +1,158 @@ +import types +import typing + +from ._content import Content +from ._streams import ByteStream, Stream +from ._headers import Headers, parse_opts_header + +__all__ = ["Response"] + +# We're using the same set as stdlib `http.HTTPStatus` here... +# +# https://github.com/python/cpython/blob/main/Lib/http/__init__.py +_codes = { + 100: "Continue", + 101: "Switching Protocols", + 102: "Processing", + 103: "Early Hints", + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non-Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi-Status", + 208: "Already Reported", + 226: "IM Used", + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 307: "Temporary Redirect", + 308: "Permanent Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Content Too Large", + 414: "URI Too Long", + 415: "Unsupported Media Type", + 416: "Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a Teapot", + 421: "Misdirected Request", + 422: "Unprocessable Content", + 423: "Locked", + 424: "Failed Dependency", + 425: "Too Early", + 426: "Upgrade Required", + 428: "Precondition Required", + 429: "Too Many Requests", + 431: "Request Header Fields Too Large", + 451: "Unavailable For Legal Reasons", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 506: "Variant Also Negotiates", + 507: "Insufficient Storage", + 508: "Loop Detected", + 510: "Not Extended", + 511: "Network Authentication Required", +} + + +class Response: + def __init__( + self, + status_code: int, + *, + headers: Headers | typing.Mapping[str, str] | None = None, + content: Content | Stream | bytes | None = None, + ): + self.status_code = status_code + self.headers = Headers(headers) + self.stream: Stream = ByteStream(b"") + + if content is not None: + if isinstance(content, bytes): + self.stream = ByteStream(content) + elif isinstance(content, Stream): + self.stream = content + elif isinstance(content, Content): + ct = content.content_type() + self.stream = content.encode() + self.headers = self.headers.copy_set("Content-Type", ct) + else: + raise TypeError(f'Expected `Content | Stream | bytes | None` got {type(content)}') + + # https://datatracker.ietf.org/doc/html/rfc2616#section-4.3 + # RFC 2616, Section 4.3, Message Body. + # + # All 1xx (informational), 204 (no content), and 304 (not modified) responses + # MUST NOT include a message-body. All other responses do include a + # message-body, although it MAY be of zero length. + if status_code >= 200 and status_code != 204 and status_code != 304: + content_length: int | None = self.stream.size + if content_length is None: + self.headers = self.headers.copy_set("Transfer-Encoding", "chunked") + else: + self.headers = self.headers.copy_set("Content-Length", str(content_length)) + + @property + def reason_phrase(self): + return _codes.get(self.status_code, "Unknown Status Code") + + @property + def body(self) -> bytes: + if not hasattr(self, '_body'): + raise RuntimeError("'.body' cannot be accessed without calling '.read()'") + return self._body + + @property + def text(self) -> str: + if not hasattr(self, '_body'): + raise RuntimeError("'.text' cannot be accessed without calling '.read()'") + if not hasattr(self, '_text'): + ct = self.headers.get('Content-Type', '') + media, opts = parse_opts_header(ct) + charset = 'utf-8' + if media.startswith('text/'): + charset = opts.get('charset', 'utf-8') + self._text = self._body.decode(charset) + return self._text + + def read(self) -> bytes: + if not hasattr(self, '_body'): + self._body = self.stream.read() + return self._body + + def close(self) -> None: + self.stream.close() + + def __enter__(self): + return self + + def __exit__(self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None + ): + self.close() + + def __repr__(self): + return f"" diff --git a/src/httpx/_server.py b/src/httpx/_server.py new file mode 100644 index 0000000000..95226d9914 --- /dev/null +++ b/src/httpx/_server.py @@ -0,0 +1,126 @@ +import contextlib +import logging +import time + +from ._content import Text +from ._parsers import HTTPParser +from ._request import Request +from ._response import Response +from ._network import NetworkBackend, sleep +from ._streams import HTTPStream + +__all__ = [ + "serve_http", "run" +] + +logger = logging.getLogger("httpx.server") + + +class ConnectionClosed(Exception): + pass + + +class HTTPConnection: + def __init__(self, stream, endpoint): + self._stream = stream + self._endpoint = endpoint + self._parser = HTTPParser(stream, mode='SERVER') + self._keepalive_duration = 5.0 + self._idle_expiry = time.monotonic() + self._keepalive_duration + + # API entry points... + def handle_requests(self): + try: + while not self._parser.is_closed(): + method, url, headers = self._recv_head() + stream = HTTPStream(self._recv_body, self._complete) + # TODO: Handle endpoint exceptions + with Request(method, url, headers=headers, content=stream) as request: + try: + response = self._endpoint(request) + status_line = f"{request.method} {request.url.target} [{response.status_code} {response.reason_phrase}]" + logger.info(status_line) + except Exception: + logger.error("Internal Server Error", exc_info=True) + content = Text("Internal Server Error") + err = Response(code=500, content=content) + self._send_head(err) + self._send_body(err) + else: + self._send_head(response) + self._send_body(response) + except Exception: + logger.error("Internal Server Error", exc_info=True) + + def close(self): + self._parser.close() + + # Receive the request... + def _recv_head(self) -> tuple[str, str, list[tuple[str, str]]]: + method, target, _ = self._parser.recv_method_line() + m = method.decode('ascii') + t = target.decode('ascii') + headers = self._parser.recv_headers() + h = [ + (k.decode('latin-1'), v.decode('latin-1')) + for k, v in headers + ] + return m, t, h + + def _recv_body(self): + return self._parser.recv_body() + + # Return the response... + def _send_head(self, response: Response): + protocol = b"HTTP/1.1" + status = response.status_code + reason = response.reason_phrase.encode('ascii') + self._parser.send_status_line(protocol, status, reason) + headers = [ + (k.encode('ascii'), v.encode('ascii')) + for k, v in response.headers.items() + ] + self._parser.send_headers(headers) + + def _send_body(self, response: Response): + while data := response.stream.read(64 * 1024): + self._parser.send_body(data) + self._parser.send_body(b'') + + # Start it all over again... + def _complete(self): + self._parser.complete + self._idle_expiry = time.monotonic() + self._keepalive_duration + + +class HTTPServer: + def __init__(self, host, port): + self.url = f"http://{host}:{port}/" + + def wait(self): + while(True): + sleep(1) + + +@contextlib.contextmanager +def serve_http(endpoint): + def handler(stream): + connection = HTTPConnection(stream, endpoint) + connection.handle_requests() + + logging.basicConfig( + format="%(levelname)s [%(asctime)s] %(name)s - %(message)s", + datefmt="%Y-%m-%d %H:%M:%S", + level=logging.DEBUG + ) + + backend = NetworkBackend() + with backend.serve("127.0.0.1", 8080, handler) as server: + server = HTTPServer(server.host, server.port) + logger.info(f"Serving on {server.url} (Press CTRL+C to quit)") + yield server + + +def run(app): + with serve_http(app) as server: + server.wait() diff --git a/src/httpx/_streams.py b/src/httpx/_streams.py new file mode 100644 index 0000000000..1fc6cde073 --- /dev/null +++ b/src/httpx/_streams.py @@ -0,0 +1,235 @@ +import io +import types +import os + + +class Stream: + def read(self, size: int=-1) -> bytes: + raise NotImplementedError() + + def write(self, data: bytes) -> None: + raise NotImplementedError() + + def close(self) -> None: + raise NotImplementedError() + + @property + def size(self) -> int | None: + return None + + def __enter__(self): + return self + + def __exit__( + self, + exc_type: type[BaseException] | None = None, + exc_value: BaseException | None = None, + traceback: types.TracebackType | None = None + ): + self.close() + + +class ByteStream(Stream): + def __init__(self, data: bytes = b''): + self._buffer = io.BytesIO(data) + self._size = len(data) + + def read(self, size: int=-1) -> bytes: + return self._buffer.read(size) + + def close(self) -> None: + self._buffer.close() + + @property + def size(self) -> int | None: + return self._size + + +class DuplexStream(Stream): + """ + DuplexStream supports both `read` and `write` operations, + which are applied to seperate buffers. + + This stream can be used for testing network parsers. + """ + + def __init__(self, data: bytes = b''): + self._read_buffer = io.BytesIO(data) + self._write_buffer = io.BytesIO() + + def read(self, size: int=-1) -> bytes: + return self._read_buffer.read(size) + + def write(self, buffer: bytes): + return self._write_buffer.write(buffer) + + def close(self) -> None: + self._read_buffer.close() + self._write_buffer.close() + + def input_bytes(self) -> bytes: + return self._read_buffer.getvalue() + + def output_bytes(self) -> bytes: + return self._write_buffer.getvalue() + + +class FileStream(Stream): + def __init__(self, path): + self._path = path + self._fileobj = None + self._size = None + + def read(self, size: int=-1) -> bytes: + if self._fileobj is None: + raise ValueError('I/O operation on unopened file') + return self._fileobj.read(size) + + def open(self): + self._fileobj = open(self._path, 'rb') + self._size = os.path.getsize(self._path) + return self + + def close(self) -> None: + if self._fileobj is not None: + self._fileobj.close() + + @property + def size(self) -> int | None: + return self._size + + def __enter__(self): + self.open() + return self + + +class HTTPStream(Stream): + def __init__(self, next_chunk, complete): + self._next_chunk = next_chunk + self._complete = complete + self._buffer = io.BytesIO() + + def read(self, size=-1) -> bytes: + sections = [] + length = 0 + + # If we have any data in the buffer read that and clear the buffer. + buffered = self._buffer.read() + if buffered: + sections.append(buffered) + length += len(buffered) + self._buffer.seek(0) + self._buffer.truncate(0) + + # Read each chunk in turn. + while (size < 0) or (length < size): + section = self._next_chunk() + sections.append(section) + length += len(section) + if section == b'': + break + + # If we've more data than requested, then push some back into the buffer. + output = b''.join(sections) + if size > -1 and len(output) > size: + output, remainder = output[:size], output[size:] + self._buffer.write(remainder) + self._buffer.seek(0) + + return output + + def close(self) -> None: + self._buffer.close() + if self._complete is not None: + self._complete() + + +class MultiPartStream(Stream): + def __init__(self, form: list[tuple[str, str]], files: list[tuple[str, str]], boundary=''): + self._form = list(form) + self._files = list(files) + self._boundary = boundary or os.urandom(16).hex() + # Mutable state... + self._form_progress = list(self._form) + self._files_progress = list(self._files) + self._filestream: FileStream | None = None + self._complete = False + self._buffer = io.BytesIO() + + def read(self, size=-1) -> bytes: + sections = [] + length = 0 + + # If we have any data in the buffer read that and clear the buffer. + buffered = self._buffer.read() + if buffered: + sections.append(buffered) + length += len(buffered) + self._buffer.seek(0) + self._buffer.truncate(0) + + # Read each multipart section in turn. + while (size < 0) or (length < size): + section = self._read_next_section() + sections.append(section) + length += len(section) + if section == b'': + break + + # If we've more data than requested, then push some back into the buffer. + output = b''.join(sections) + if size > -1 and len(output) > size: + output, remainder = output[:size], output[size:] + self._buffer.write(remainder) + self._buffer.seek(0) + + return output + + def _read_next_section(self) -> bytes: + if self._form_progress: + # return a form item + key, value = self._form_progress.pop(0) + name = key.translate({10: "%0A", 13: "%0D", 34: "%22"}) + return ( + f"--{self._boundary}\r\n" + f'Content-Disposition: form-data; name="{name}"\r\n' + f"\r\n" + f"{value}\r\n" + ).encode("utf-8") + elif self._files_progress and self._filestream is None: + # return start of a file item + key, value = self._files_progress.pop(0) + self._filestream = FileStream(value).open() + name = key.translate({10: "%0A", 13: "%0D", 34: "%22"}) + filename = os.path.basename(value) + return ( + f"--{self._boundary}\r\n" + f'Content-Disposition: form-data; name="{name}"; filename="{filename}"\r\n' + f"\r\n" + ).encode("utf-8") + elif self._filestream is not None: + chunk = self._filestream.read(64*1024) + if chunk != b'': + # return some bytes from file + return chunk + else: + # return end of file item + self._filestream.close() + self._filestream = None + return b"\r\n" + elif not self._complete: + # return final section of multipart + self._complete = True + return f"--{self._boundary}--\r\n".encode("utf-8") + # return EOF marker + return b"" + + def close(self) -> None: + if self._filestream is not None: + self._filestream.close() + self._filestream = None + self._buffer.close() + + @property + def size(self) -> int | None: + return None diff --git a/src/httpx/_urlencode.py b/src/httpx/_urlencode.py new file mode 100644 index 0000000000..1a83b620a6 --- /dev/null +++ b/src/httpx/_urlencode.py @@ -0,0 +1,85 @@ +import re + +__all__ = ["quote", "unquote", "urldecode", "urlencode"] + + +# Matchs a sequence of one or more '%xx' escapes. +PERCENT_ENCODED_REGEX = re.compile("(%[A-Fa-f0-9][A-Fa-f0-9])+") + +# https://datatracker.ietf.org/doc/html/rfc3986#section-2.3 +SAFE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~" + + +def urlencode(multidict, safe=SAFE): + pairs = [] + for key, values in multidict.items(): + pairs.extend([(key, value) for value in values]) + + safe += "+" + pairs = [(k.replace(" ", "+"), v.replace(" ", "+")) for k, v in pairs] + + return "&".join( + f"{quote(key, safe)}={quote(val, safe)}" + for key, val in pairs + ) + + +def urldecode(string): + parts = [part.partition("=") for part in string.split("&") if part] + pairs = [ + (unquote(key), unquote(val)) + for key, _, val in parts + ] + + pairs = [(k.replace("+", " "), v.replace("+", " ")) for k, v in pairs] + + ret = {} + for k, v in pairs: + ret.setdefault(k, []).append(v) + return ret + + +def quote(string, safe=SAFE): + # Fast path if the string is already safe. + if not string.strip(safe): + return string + + # Replace any characters not in the safe set with '%xx' escape sequences. + return "".join([ + char if char in safe else percent(char) + for char in string + ]) + + +def unquote(string): + # Fast path if the string is not quoted. + if '%' not in string: + return string + + # Unquote. + parts = [] + current_position = 0 + for match in re.finditer(PERCENT_ENCODED_REGEX, string): + start_position, end_position = match.start(), match.end() + matched_text = match.group(0) + # Include any text up to the '%xx' escape sequence. + if start_position != current_position: + leading_text = string[current_position:start_position] + parts.append(leading_text) + + # Decode the '%xx' escape sequence. + hex = matched_text.replace('%', '') + decoded = bytes.fromhex(hex).decode('utf-8') + parts.append(decoded) + current_position = end_position + + # Include any text after the final '%xx' escape sequence. + if current_position != len(string): + trailing_text = string[current_position:] + parts.append(trailing_text) + + return "".join(parts) + + +def percent(c): + return ''.join(f"%{b:02X}" for b in c.encode("utf-8")) diff --git a/src/httpx/_urlparse.py b/src/httpx/_urlparse.py new file mode 100644 index 0000000000..612892fa8b --- /dev/null +++ b/src/httpx/_urlparse.py @@ -0,0 +1,534 @@ +""" +An implementation of `urlparse` that provides URL validation and normalization +as described by RFC3986. + +We rely on this implementation rather than the one in Python's stdlib, because: + +* It provides more complete URL validation. +* It properly differentiates between an empty querystring and an absent querystring, + to distinguish URLs with a trailing '?'. +* It handles scheme, hostname, port, and path normalization. +* It supports IDNA hostnames, normalizing them to their encoded form. +* The API supports passing individual components, as well as the complete URL string. + +Previously we relied on the excellent `rfc3986` package to handle URL parsing and +validation, but this module provides a simpler alternative, with less indirection +required. +""" + +import ipaddress +import re +import typing + + +class InvalidURL(ValueError): + pass + + +MAX_URL_LENGTH = 65536 + +# https://datatracker.ietf.org/doc/html/rfc3986.html#section-2.3 +UNRESERVED_CHARACTERS = ( + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~" +) +SUB_DELIMS = "!$&'()*+,;=" + +PERCENT_ENCODED_REGEX = re.compile("%[A-Fa-f0-9]{2}") + +# https://url.spec.whatwg.org/#percent-encoded-bytes + +# The fragment percent-encode set is the C0 control percent-encode set +# and U+0020 SPACE, U+0022 ("), U+003C (<), U+003E (>), and U+0060 (`). +FRAG_SAFE = "".join( + [chr(i) for i in range(0x20, 0x7F) if i not in (0x20, 0x22, 0x3C, 0x3E, 0x60)] +) + +# The query percent-encode set is the C0 control percent-encode set +# and U+0020 SPACE, U+0022 ("), U+0023 (#), U+003C (<), and U+003E (>). +QUERY_SAFE = "".join( + [chr(i) for i in range(0x20, 0x7F) if i not in (0x20, 0x22, 0x23, 0x3C, 0x3E)] +) + +# The path percent-encode set is the query percent-encode set +# and U+003F (?), U+0060 (`), U+007B ({), and U+007D (}). +PATH_SAFE = "".join( + [ + chr(i) + for i in range(0x20, 0x7F) + if i not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + (0x3F, 0x60, 0x7B, 0x7D) + ] +) + +# The userinfo percent-encode set is the path percent-encode set +# and U+002F (/), U+003A (:), U+003B (;), U+003D (=), U+0040 (@), +# U+005B ([) to U+005E (^), inclusive, and U+007C (|). +USERNAME_SAFE = "".join( + [ + chr(i) + for i in range(0x20, 0x7F) + if i + not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + + (0x3F, 0x60, 0x7B, 0x7D) + + (0x2F, 0x3A, 0x3B, 0x3D, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x7C) + ] +) +PASSWORD_SAFE = "".join( + [ + chr(i) + for i in range(0x20, 0x7F) + if i + not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + + (0x3F, 0x60, 0x7B, 0x7D) + + (0x2F, 0x3A, 0x3B, 0x3D, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x7C) + ] +) +# Note... The terminology 'userinfo' percent-encode set in the WHATWG document +# is used for the username and password quoting. For the joint userinfo component +# we remove U+003A (:) from the safe set. +USERINFO_SAFE = "".join( + [ + chr(i) + for i in range(0x20, 0x7F) + if i + not in (0x20, 0x22, 0x23, 0x3C, 0x3E) + + (0x3F, 0x60, 0x7B, 0x7D) + + (0x2F, 0x3B, 0x3D, 0x40, 0x5B, 0x5C, 0x5D, 0x5E, 0x7C) + ] +) + + +# {scheme}: (optional) +# //{authority} (optional) +# {path} +# ?{query} (optional) +# #{fragment} (optional) +URL_REGEX = re.compile( + ( + r"(?:(?P{scheme}):)?" + r"(?://(?P{authority}))?" + r"(?P{path})" + r"(?:\?(?P{query}))?" + r"(?:#(?P{fragment}))?" + ).format( + scheme="([a-zA-Z][a-zA-Z0-9+.-]*)?", + authority="[^/?#]*", + path="[^?#]*", + query="[^#]*", + fragment=".*", + ) +) + +# {userinfo}@ (optional) +# {host} +# :{port} (optional) +AUTHORITY_REGEX = re.compile( + ( + r"(?:(?P{userinfo})@)?" r"(?P{host})" r":?(?P{port})?" + ).format( + userinfo=".*", # Any character sequence. + host="(\\[.*\\]|[^:@]*)", # Either any character sequence excluding ':' or '@', + # or an IPv6 address enclosed within square brackets. + port=".*", # Any character sequence. + ) +) + + +# If we call urlparse with an individual component, then we need to regex +# validate that component individually. +# Note that we're duplicating the same strings as above. Shock! Horror!! +COMPONENT_REGEX = { + "scheme": re.compile("([a-zA-Z][a-zA-Z0-9+.-]*)?"), + "authority": re.compile("[^/?#]*"), + "path": re.compile("[^?#]*"), + "query": re.compile("[^#]*"), + "fragment": re.compile(".*"), + "userinfo": re.compile("[^@]*"), + "host": re.compile("(\\[.*\\]|[^:]*)"), + "port": re.compile(".*"), +} + + +# We use these simple regexs as a first pass before handing off to +# the stdlib 'ipaddress' module for IP address validation. +IPv4_STYLE_HOSTNAME = re.compile(r"^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$") +IPv6_STYLE_HOSTNAME = re.compile(r"^\[.*\]$") + + +class ParseResult(typing.NamedTuple): + scheme: str + userinfo: str + host: str + port: int | None + path: str + query: str | None + fragment: str | None + + @property + def authority(self) -> str: + return "".join( + [ + f"{self.userinfo}@" if self.userinfo else "", + f"[{self.host}]" if ":" in self.host else self.host, + f":{self.port}" if self.port is not None else "", + ] + ) + + @property + def netloc(self) -> str: + return "".join( + [ + f"[{self.host}]" if ":" in self.host else self.host, + f":{self.port}" if self.port is not None else "", + ] + ) + + def copy_with(self, **kwargs: str | None) -> "ParseResult": + if not kwargs: + return self + + defaults = { + "scheme": self.scheme, + "authority": self.authority, + "path": self.path, + "query": self.query, + "fragment": self.fragment, + } + defaults.update(kwargs) + return urlparse("", **defaults) + + def __str__(self) -> str: + authority = self.authority + return "".join( + [ + f"{self.scheme}:" if self.scheme else "", + f"//{authority}" if authority else "", + self.path, + f"?{self.query}" if self.query is not None else "", + f"#{self.fragment}" if self.fragment is not None else "", + ] + ) + + +def urlparse(url: str = "", **kwargs: str | None) -> ParseResult: + # Initial basic checks on allowable URLs. + # --------------------------------------- + + # Hard limit the maximum allowable URL length. + if len(url) > MAX_URL_LENGTH: + raise InvalidURL("URL too long") + + # If a URL includes any ASCII control characters including \t, \r, \n, + # then treat it as invalid. + if any(char.isascii() and not char.isprintable() for char in url): + char = next(char for char in url if char.isascii() and not char.isprintable()) + idx = url.find(char) + error = ( + f"Invalid non-printable ASCII character in URL, {char!r} at position {idx}." + ) + raise InvalidURL(error) + + # Some keyword arguments require special handling. + # ------------------------------------------------ + + # Coerce "port" to a string, if it is provided as an integer. + if "port" in kwargs: + port = kwargs["port"] + kwargs["port"] = str(port) if isinstance(port, int) else port + + # Replace "netloc" with "host and "port". + if "netloc" in kwargs: + netloc = kwargs.pop("netloc") or "" + kwargs["host"], _, kwargs["port"] = netloc.partition(":") + + # Replace "username" and/or "password" with "userinfo". + if "username" in kwargs or "password" in kwargs: + username = quote(kwargs.pop("username", "") or "", safe=USERNAME_SAFE) + password = quote(kwargs.pop("password", "") or "", safe=PASSWORD_SAFE) + kwargs["userinfo"] = f"{username}:{password}" if password else username + + # Replace "raw_path" with "path" and "query". + if "raw_path" in kwargs: + raw_path = kwargs.pop("raw_path") or "" + kwargs["path"], seperator, kwargs["query"] = raw_path.partition("?") + if not seperator: + kwargs["query"] = None + + # Ensure that IPv6 "host" addresses are always escaped with "[...]". + if "host" in kwargs: + host = kwargs.get("host") or "" + if ":" in host and not (host.startswith("[") and host.endswith("]")): + kwargs["host"] = f"[{host}]" + + # If any keyword arguments are provided, ensure they are valid. + # ------------------------------------------------------------- + + for key, value in kwargs.items(): + if value is not None: + if len(value) > MAX_URL_LENGTH: + raise InvalidURL(f"URL component '{key}' too long") + + # If a component includes any ASCII control characters including \t, \r, \n, + # then treat it as invalid. + if any(char.isascii() and not char.isprintable() for char in value): + char = next( + char for char in value if char.isascii() and not char.isprintable() + ) + idx = value.find(char) + error = ( + f"Invalid non-printable ASCII character in URL {key} component, " + f"{char!r} at position {idx}." + ) + raise InvalidURL(error) + + # Ensure that keyword arguments match as a valid regex. + if not COMPONENT_REGEX[key].fullmatch(value): + raise InvalidURL(f"Invalid URL component '{key}'") + + # The URL_REGEX will always match, but may have empty components. + url_match = URL_REGEX.match(url) + assert url_match is not None + url_dict = url_match.groupdict() + + # * 'scheme', 'authority', and 'path' may be empty strings. + # * 'query' may be 'None', indicating no trailing "?" portion. + # Any string including the empty string, indicates a trailing "?". + # * 'fragment' may be 'None', indicating no trailing "#" portion. + # Any string including the empty string, indicates a trailing "#". + scheme = kwargs.get("scheme", url_dict["scheme"]) or "" + authority = kwargs.get("authority", url_dict["authority"]) or "" + path = kwargs.get("path", url_dict["path"]) or "" + query = kwargs.get("query", url_dict["query"]) + frag = kwargs.get("fragment", url_dict["fragment"]) + + # The AUTHORITY_REGEX will always match, but may have empty components. + authority_match = AUTHORITY_REGEX.match(authority) + assert authority_match is not None + authority_dict = authority_match.groupdict() + + # * 'userinfo' and 'host' may be empty strings. + # * 'port' may be 'None'. + userinfo = kwargs.get("userinfo", authority_dict["userinfo"]) or "" + host = kwargs.get("host", authority_dict["host"]) or "" + port = kwargs.get("port", authority_dict["port"]) + + # Normalize and validate each component. + # We end up with a parsed representation of the URL, + # with components that are plain ASCII bytestrings. + parsed_scheme: str = scheme.lower() + parsed_userinfo: str = quote(userinfo, safe=USERINFO_SAFE) + parsed_host: str = encode_host(host) + parsed_port: int | None = normalize_port(port, scheme) + + has_scheme = parsed_scheme != "" + has_authority = ( + parsed_userinfo != "" or parsed_host != "" or parsed_port is not None + ) + validate_path(path, has_scheme=has_scheme, has_authority=has_authority) + if has_scheme or has_authority: + path = normalize_path(path) + + parsed_path: str = quote(path, safe=PATH_SAFE) + parsed_query: str | None = None if query is None else quote(query, safe=QUERY_SAFE) + parsed_frag: str | None = None if frag is None else quote(frag, safe=FRAG_SAFE) + + # The parsed ASCII bytestrings are our canonical form. + # All properties of the URL are derived from these. + return ParseResult( + parsed_scheme, + parsed_userinfo, + parsed_host, + parsed_port, + parsed_path, + parsed_query, + parsed_frag, + ) + + +def encode_host(host: str) -> str: + if not host: + return "" + + elif IPv4_STYLE_HOSTNAME.match(host): + # Validate IPv4 hostnames like #.#.#.# + # + # From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2 + # + # IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet + try: + ipaddress.IPv4Address(host) + except ipaddress.AddressValueError: + raise InvalidURL(f"Invalid IPv4 address: {host!r}") + return host + + elif IPv6_STYLE_HOSTNAME.match(host): + # Validate IPv6 hostnames like [...] + # + # From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2 + # + # "A host identified by an Internet Protocol literal address, version 6 + # [RFC3513] or later, is distinguished by enclosing the IP literal + # within square brackets ("[" and "]"). This is the only place where + # square bracket characters are allowed in the URI syntax." + try: + ipaddress.IPv6Address(host[1:-1]) + except ipaddress.AddressValueError: + raise InvalidURL(f"Invalid IPv6 address: {host!r}") + return host[1:-1] + + elif not host.isascii(): + try: + import idna # type: ignore + except ImportError: + raise InvalidURL( + f"Cannot handle URL with IDNA hostname: {host!r}. " + f"Package 'idna' is not installed." + ) + + # IDNA hostnames + try: + return idna.encode(host.lower()).decode("ascii") + except idna.IDNAError: + raise InvalidURL(f"Invalid IDNA hostname: {host!r}") + + # Regular ASCII hostnames + # + # From https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2.2 + # + # reg-name = *( unreserved / pct-encoded / sub-delims ) + WHATWG_SAFE = '"`{}%|\\' + return quote(host.lower(), safe=SUB_DELIMS + WHATWG_SAFE) + + +def normalize_port(port: str | int | None, scheme: str) -> int | None: + # From https://tools.ietf.org/html/rfc3986#section-3.2.3 + # + # "A scheme may define a default port. For example, the "http" scheme + # defines a default port of "80", corresponding to its reserved TCP + # port number. The type of port designated by the port number (e.g., + # TCP, UDP, SCTP) is defined by the URI scheme. URI producers and + # normalizers should omit the port component and its ":" delimiter if + # port is empty or if its value would be the same as that of the + # scheme's default." + if port is None or port == "": + return None + + try: + port_as_int = int(port) + except ValueError: + raise InvalidURL(f"Invalid port: {port!r}") + + # See https://url.spec.whatwg.org/#url-miscellaneous + default_port = {"ftp": 21, "http": 80, "https": 443, "ws": 80, "wss": 443}.get( + scheme + ) + if port_as_int == default_port: + return None + return port_as_int + + +def validate_path(path: str, has_scheme: bool, has_authority: bool) -> None: + """ + Path validation rules that depend on if the URL contains + a scheme or authority component. + + See https://datatracker.ietf.org/doc/html/rfc3986.html#section-3.3 + """ + if has_authority: + # If a URI contains an authority component, then the path component + # must either be empty or begin with a slash ("/") character." + if path and not path.startswith("/"): + raise InvalidURL("For absolute URLs, path must be empty or begin with '/'") + + if not has_scheme and not has_authority: + # If a URI does not contain an authority component, then the path cannot begin + # with two slash characters ("//"). + if path.startswith("//"): + raise InvalidURL("Relative URLs cannot have a path starting with '//'") + + # In addition, a URI reference (Section 4.1) may be a relative-path reference, + # in which case the first path segment cannot contain a colon (":") character. + if path.startswith(":"): + raise InvalidURL("Relative URLs cannot have a path starting with ':'") + + +def normalize_path(path: str) -> str: + """ + Drop "." and ".." segments from a URL path. + + For example: + + normalize_path("/path/./to/somewhere/..") == "/path/to" + """ + # Fast return when no '.' characters in the path. + if "." not in path: + return path + + components = path.split("/") + + # Fast return when no '.' or '..' components in the path. + if "." not in components and ".." not in components: + return path + + # https://datatracker.ietf.org/doc/html/rfc3986#section-5.2.4 + output: list[str] = [] + for component in components: + if component == ".": + pass + elif component == "..": + if output and output != [""]: + output.pop() + else: + output.append(component) + return "/".join(output) + + +def PERCENT(string: str) -> str: + return "".join([f"%{byte:02X}" for byte in string.encode("utf-8")]) + + +def percent_encoded(string: str, safe: str) -> str: + """ + Use percent-encoding to quote a string. + """ + NON_ESCAPED_CHARS = UNRESERVED_CHARACTERS + safe + + # Fast path for strings that don't need escaping. + if not string.rstrip(NON_ESCAPED_CHARS): + return string + + return "".join( + [char if char in NON_ESCAPED_CHARS else PERCENT(char) for char in string] + ) + + +def quote(string: str, safe: str) -> str: + """ + Use percent-encoding to quote a string, omitting existing '%xx' escape sequences. + + See: https://www.rfc-editor.org/rfc/rfc3986#section-2.1 + + * `string`: The string to be percent-escaped. + * `safe`: A string containing characters that may be treated as safe, and do not + need to be escaped. Unreserved characters are always treated as safe. + See: https://www.rfc-editor.org/rfc/rfc3986#section-2.3 + """ + parts = [] + current_position = 0 + for match in re.finditer(PERCENT_ENCODED_REGEX, string): + start_position, end_position = match.start(), match.end() + matched_text = match.group(0) + # Add any text up to the '%xx' escape sequence. + if start_position != current_position: + leading_text = string[current_position:start_position] + parts.append(percent_encoded(leading_text, safe=safe)) + + # Add the '%xx' escape sequence. + parts.append(matched_text) + current_position = end_position + + # Add any text after the final '%xx' escape sequence. + if current_position != len(string): + trailing_text = string[current_position:] + parts.append(percent_encoded(trailing_text, safe=safe)) + + return "".join(parts) diff --git a/src/httpx/_urls.py b/src/httpx/_urls.py new file mode 100644 index 0000000000..4ae4464e25 --- /dev/null +++ b/src/httpx/_urls.py @@ -0,0 +1,552 @@ +from __future__ import annotations + +import typing + +from ._urlparse import urlparse +from ._urlencode import unquote, urldecode, urlencode + +__all__ = ["QueryParams", "URL"] + + +class URL: + """ + url = httpx.URL("HTTPS://jo%40email.com:a%20secret@müller.de:1234/pa%20th?search=ab#anchorlink") + + assert url.scheme == "https" + assert url.username == "jo@email.com" + assert url.password == "a secret" + assert url.userinfo == b"jo%40email.com:a%20secret" + assert url.host == "müller.de" + assert url.raw_host == b"xn--mller-kva.de" + assert url.port == 1234 + assert url.netloc == b"xn--mller-kva.de:1234" + assert url.path == "/pa th" + assert url.query == b"?search=ab" + assert url.raw_path == b"/pa%20th?search=ab" + assert url.fragment == "anchorlink" + + The components of a URL are broken down like this: + + https://jo%40email.com:a%20secret@müller.de:1234/pa%20th?search=ab#anchorlink + [scheme] [ username ] [password] [ host ][port][ path ] [ query ] [fragment] + [ userinfo ] [ netloc ][ raw_path ] + + Note that: + + * `url.scheme` is normalized to always be lowercased. + + * `url.host` is normalized to always be lowercased. Internationalized domain + names are represented in unicode, without IDNA encoding applied. For instance: + + url = httpx.URL("http://中国.icom.museum") + assert url.host == "中国.icom.museum" + url = httpx.URL("http://xn--fiqs8s.icom.museum") + assert url.host == "中国.icom.museum" + + * `url.raw_host` is normalized to always be lowercased, and is IDNA encoded. + + url = httpx.URL("http://中国.icom.museum") + assert url.raw_host == b"xn--fiqs8s.icom.museum" + url = httpx.URL("http://xn--fiqs8s.icom.museum") + assert url.raw_host == b"xn--fiqs8s.icom.museum" + + * `url.port` is either None or an integer. URLs that include the default port for + "http", "https", "ws", "wss", and "ftp" schemes have their port + normalized to `None`. + + assert httpx.URL("http://example.com") == httpx.URL("http://example.com:80") + assert httpx.URL("http://example.com").port is None + assert httpx.URL("http://example.com:80").port is None + + * `url.userinfo` is raw bytes, without URL escaping. Usually you'll want to work + with `url.username` and `url.password` instead, which handle the URL escaping. + + * `url.raw_path` is raw bytes of both the path and query, without URL escaping. + This portion is used as the target when constructing HTTP requests. Usually you'll + want to work with `url.path` instead. + + * `url.query` is raw bytes, without URL escaping. A URL query string portion can + only be properly URL escaped when decoding the parameter names and values + themselves. + """ + + def __init__(self, url: "URL" | str = "", **kwargs: typing.Any) -> None: + if kwargs: + allowed = { + "scheme": str, + "username": str, + "password": str, + "userinfo": bytes, + "host": str, + "port": int, + "netloc": str, + "path": str, + "query": bytes, + "raw_path": bytes, + "fragment": str, + "params": object, + } + + # Perform type checking for all supported keyword arguments. + for key, value in kwargs.items(): + if key not in allowed: + message = f"{key!r} is an invalid keyword argument for URL()" + raise TypeError(message) + if value is not None and not isinstance(value, allowed[key]): + expected = allowed[key].__name__ + seen = type(value).__name__ + message = f"Argument {key!r} must be {expected} but got {seen}" + raise TypeError(message) + if isinstance(value, bytes): + kwargs[key] = value.decode("ascii") + + if "params" in kwargs: + # Replace any "params" keyword with the raw "query" instead. + # + # Ensure that empty params use `kwargs["query"] = None` rather + # than `kwargs["query"] = ""`, so that generated URLs do not + # include an empty trailing "?". + params = kwargs.pop("params") + kwargs["query"] = None if not params else str(QueryParams(params)) + + if isinstance(url, str): + self._uri_reference = urlparse(url, **kwargs) + elif isinstance(url, URL): + self._uri_reference = url._uri_reference.copy_with(**kwargs) + else: + raise TypeError( + "Invalid type for url. Expected str or httpx.URL," + f" got {type(url)}: {url!r}" + ) + + @property + def scheme(self) -> str: + """ + The URL scheme, such as "http", "https". + Always normalised to lowercase. + """ + return self._uri_reference.scheme + + @property + def userinfo(self) -> bytes: + """ + The URL userinfo as a raw bytestring. + For example: b"jo%40email.com:a%20secret". + """ + return self._uri_reference.userinfo.encode("ascii") + + @property + def username(self) -> str: + """ + The URL username as a string, with URL decoding applied. + For example: "jo@email.com" + """ + userinfo = self._uri_reference.userinfo + return unquote(userinfo.partition(":")[0]) + + @property + def password(self) -> str: + """ + The URL password as a string, with URL decoding applied. + For example: "a secret" + """ + userinfo = self._uri_reference.userinfo + return unquote(userinfo.partition(":")[2]) + + @property + def host(self) -> str: + """ + The URL host as a string. + Always normalized to lowercase. Possibly IDNA encoded. + + Examples: + + url = httpx.URL("http://www.EXAMPLE.org") + assert url.host == "www.example.org" + + url = httpx.URL("http://中国.icom.museum") + assert url.host == "xn--fiqs8s" + + url = httpx.URL("http://xn--fiqs8s.icom.museum") + assert url.host == "xn--fiqs8s" + + url = httpx.URL("https://[::ffff:192.168.0.1]") + assert url.host == "::ffff:192.168.0.1" + """ + return self._uri_reference.host + + @property + def port(self) -> int | None: + """ + The URL port as an integer. + + Note that the URL class performs port normalization as per the WHATWG spec. + Default ports for "http", "https", "ws", "wss", and "ftp" schemes are always + treated as `None`. + + For example: + + assert httpx.URL("http://www.example.com") == httpx.URL("http://www.example.com:80") + assert httpx.URL("http://www.example.com:80").port is None + """ + return self._uri_reference.port + + @property + def netloc(self) -> str: + """ + Either `` or `:` as bytes. + Always normalized to lowercase, and IDNA encoded. + + This property may be used for generating the value of a request + "Host" header. + """ + return self._uri_reference.netloc + + @property + def path(self) -> str: + """ + The URL path as a string. Excluding the query string, and URL decoded. + + For example: + + url = httpx.URL("https://example.com/pa%20th") + assert url.path == "/pa th" + """ + path = self._uri_reference.path or "/" + return unquote(path) + + @property + def query(self) -> bytes: + """ + The URL query string, as raw bytes, excluding the leading b"?". + + This is necessarily a bytewise interface, because we cannot + perform URL decoding of this representation until we've parsed + the keys and values into a QueryParams instance. + + For example: + + url = httpx.URL("https://example.com/?filter=some%20search%20terms") + assert url.query == b"filter=some%20search%20terms" + """ + query = self._uri_reference.query or "" + return query.encode("ascii") + + @property + def params(self) -> "QueryParams": + """ + The URL query parameters, neatly parsed and packaged into an immutable + multidict representation. + """ + return QueryParams(self._uri_reference.query) + + @property + def target(self) -> str: + """ + The complete URL path and query string as raw bytes. + Used as the target when constructing HTTP requests. + + For example: + + GET /users?search=some%20text HTTP/1.1 + Host: www.example.org + Connection: close + """ + target = self._uri_reference.path or "/" + if self._uri_reference.query is not None: + target += "?" + self._uri_reference.query + return target + + @property + def fragment(self) -> str: + """ + The URL fragments, as used in HTML anchors. + As a string, without the leading '#'. + """ + return unquote(self._uri_reference.fragment or "") + + @property + def is_absolute_url(self) -> bool: + """ + Return `True` for absolute URLs such as 'http://example.com/path', + and `False` for relative URLs such as '/path'. + """ + # We don't use `.is_absolute` from `rfc3986` because it treats + # URLs with a fragment portion as not absolute. + # What we actually care about is if the URL provides + # a scheme and hostname to which connections should be made. + return bool(self._uri_reference.scheme and self._uri_reference.host) + + @property + def is_relative_url(self) -> bool: + """ + Return `False` for absolute URLs such as 'http://example.com/path', + and `True` for relative URLs such as '/path'. + """ + return not self.is_absolute_url + + def copy_with(self, **kwargs: typing.Any) -> "URL": + """ + Copy this URL, returning a new URL with some components altered. + Accepts the same set of parameters as the components that are made + available via properties on the `URL` class. + + For example: + + url = httpx.URL("https://www.example.com").copy_with( + username="jo@gmail.com", password="a secret" + ) + assert url == "https://jo%40email.com:a%20secret@www.example.com" + """ + return URL(self, **kwargs) + + def copy_set_param(self, key: str, value: typing.Any = None) -> "URL": + return self.copy_with(params=self.params.copy_set(key, value)) + + def copy_append_param(self, key: str, value: typing.Any = None) -> "URL": + return self.copy_with(params=self.params.copy_append(key, value)) + + def copy_remove_param(self, key: str) -> "URL": + return self.copy_with(params=self.params.copy_remove(key)) + + def copy_merge_params( + self, + params: "QueryParams" | dict[str, str | list[str]] | list[tuple[str, str]] | None, + ) -> "URL": + return self.copy_with(params=self.params.copy_update(params)) + + def join(self, url: "URL" | str) -> "URL": + """ + Return an absolute URL, using this URL as the base. + + Eg. + + url = httpx.URL("https://www.example.com/test") + url = url.join("/new/path") + assert url == "https://www.example.com/new/path" + """ + from urllib.parse import urljoin + + return URL(urljoin(str(self), str(URL(url)))) + + def __hash__(self) -> int: + return hash(str(self)) + + def __eq__(self, other: typing.Any) -> bool: + return isinstance(other, (URL, str)) and str(self) == str(URL(other)) + + def __str__(self) -> str: + return str(self._uri_reference) + + def __repr__(self) -> str: + return f"" + + +class QueryParams(typing.Mapping[str, str]): + """ + URL query parameters, as a multi-dict. + """ + + def __init__( + self, + params: ( + "QueryParams" | dict[str, str | list[str]] | list[tuple[str, str]] | str | None + ) = None, + ) -> None: + d: dict[str, list[str]] = {} + + if params is None: + d = {} + elif isinstance(params, str): + d = urldecode(params) + elif isinstance(params, QueryParams): + d = params.multi_dict() + elif isinstance(params, dict): + # Convert dict inputs like: + # {"a": "123", "b": ["456", "789"]} + # To dict inputs where values are always lists, like: + # {"a": ["123"], "b": ["456", "789"]} + d = {k: [v] if isinstance(v, str) else list(v) for k, v in params.items()} + else: + # Convert list inputs like: + # [("a", "123"), ("a", "456"), ("b", "789")] + # To a dict representation, like: + # {"a": ["123", "456"], "b": ["789"]} + for k, v in params: + d.setdefault(k, []).append(v) + + self._dict = d + + def keys(self) -> typing.KeysView[str]: + """ + Return all the keys in the query params. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert list(q.keys()) == ["a", "b"] + """ + return self._dict.keys() + + def values(self) -> typing.ValuesView[str]: + """ + Return all the values in the query params. If a key occurs more than once + only the first item for that key is returned. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert list(q.values()) == ["123", "789"] + """ + return {k: v[0] for k, v in self._dict.items()}.values() + + def items(self) -> typing.ItemsView[str, str]: + """ + Return all items in the query params. If a key occurs more than once + only the first item for that key is returned. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert list(q.items()) == [("a", "123"), ("b", "789")] + """ + return {k: v[0] for k, v in self._dict.items()}.items() + + def multi_items(self) -> list[tuple[str, str]]: + """ + Return all items in the query params. Allow duplicate keys to occur. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert list(q.multi_items()) == [("a", "123"), ("a", "456"), ("b", "789")] + """ + multi_items: list[tuple[str, str]] = [] + for k, v in self._dict.items(): + multi_items.extend([(k, i) for i in v]) + return multi_items + + def multi_dict(self) -> dict[str, list[str]]: + return {k: list(v) for k, v in self._dict.items()} + + def get(self, key: str, default: typing.Any = None) -> typing.Any: + """ + Get a value from the query param for a given key. If the key occurs + more than once, then only the first value is returned. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert q.get("a") == "123" + """ + if key in self._dict: + return self._dict[key][0] + return default + + def get_list(self, key: str) -> list[str]: + """ + Get all values from the query param for a given key. + + Usage: + + q = httpx.QueryParams("a=123&a=456&b=789") + assert q.get_list("a") == ["123", "456"] + """ + return list(self._dict.get(key, [])) + + def copy_set(self, key: str, value: str) -> "QueryParams": + """ + Return a new QueryParams instance, setting the value of a key. + + Usage: + + q = httpx.QueryParams("a=123") + q = q.set("a", "456") + assert q == httpx.QueryParams("a=456") + """ + q = QueryParams() + q._dict = dict(self._dict) + q._dict[key] = [value] + return q + + def copy_append(self, key: str, value: str) -> "QueryParams": + """ + Return a new QueryParams instance, setting or appending the value of a key. + + Usage: + + q = httpx.QueryParams("a=123") + q = q.append("a", "456") + assert q == httpx.QueryParams("a=123&a=456") + """ + q = QueryParams() + q._dict = dict(self._dict) + q._dict[key] = q.get_list(key) + [value] + return q + + def copy_remove(self, key: str) -> QueryParams: + """ + Return a new QueryParams instance, removing the value of a key. + + Usage: + + q = httpx.QueryParams("a=123") + q = q.remove("a") + assert q == httpx.QueryParams("") + """ + q = QueryParams() + q._dict = dict(self._dict) + q._dict.pop(str(key), None) + return q + + def copy_update( + self, + params: ( + "QueryParams" | dict[str, str | list[str]] | list[tuple[str, str]] | None + ) = None, + ) -> "QueryParams": + """ + Return a new QueryParams instance, updated with. + + Usage: + + q = httpx.QueryParams("a=123") + q = q.copy_update({"b": "456"}) + assert q == httpx.QueryParams("a=123&b=456") + + q = httpx.QueryParams("a=123") + q = q.copy_update({"a": "456", "b": "789"}) + assert q == httpx.QueryParams("a=456&b=789") + """ + q = QueryParams(params) + q._dict = {**self._dict, **q._dict} + return q + + def __getitem__(self, key: str) -> str: + return self._dict[key][0] + + def __contains__(self, key: typing.Any) -> bool: + return key in self._dict + + def __iter__(self) -> typing.Iterator[str]: + return iter(self.keys()) + + def __len__(self) -> int: + return len(self._dict) + + def __bool__(self) -> bool: + return bool(self._dict) + + def __hash__(self) -> int: + return hash(str(self)) + + def __eq__(self, other: typing.Any) -> bool: + if not isinstance(other, self.__class__): + return False + return sorted(self.multi_items()) == sorted(other.multi_items()) + + def __str__(self) -> str: + return urlencode(self.multi_dict()) + + def __repr__(self) -> str: + return f"" diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/test_client.py b/tests/test_client.py new file mode 100644 index 0000000000..c26f6ba8db --- /dev/null +++ b/tests/test_client.py @@ -0,0 +1,112 @@ +import json +import httpx +import pytest + + +def echo(request): + request.read() + response = httpx.Response(200, content=httpx.JSON({ + 'method': request.method, + 'query-params': dict(request.url.params.items()), + 'content-type': request.headers.get('Content-Type'), + 'json': json.loads(request.body) if request.body else None, + })) + return response + + +@pytest.fixture +def client(): + with httpx.Client() as client: + yield client + + +@pytest.fixture +def server(): + with httpx.serve_http(echo) as server: + yield server + + +def test_client(client): + assert repr(client) == "" + + +def test_get(client, server): + r = client.get(server.url) + assert r.status_code == 200 + assert r.body == b'{"method":"GET","query-params":{},"content-type":null,"json":null}' + assert r.text == '{"method":"GET","query-params":{},"content-type":null,"json":null}' + + +def test_post(client, server): + data = httpx.JSON({"data": 123}) + r = client.post(server.url, content=data) + assert r.status_code == 200 + assert json.loads(r.body) == { + 'method': 'POST', + 'query-params': {}, + 'content-type': 'application/json', + 'json': {"data": 123}, + } + + +def test_put(client, server): + data = httpx.JSON({"data": 123}) + r = client.put(server.url, content=data) + assert r.status_code == 200 + assert json.loads(r.body) == { + 'method': 'PUT', + 'query-params': {}, + 'content-type': 'application/json', + 'json': {"data": 123}, + } + + +def test_patch(client, server): + data = httpx.JSON({"data": 123}) + r = client.patch(server.url, content=data) + assert r.status_code == 200 + assert json.loads(r.body) == { + 'method': 'PATCH', + 'query-params': {}, + 'content-type': 'application/json', + 'json': {"data": 123}, + } + + +def test_delete(client, server): + r = client.delete(server.url) + assert r.status_code == 200 + assert json.loads(r.body) == { + 'method': 'DELETE', + 'query-params': {}, + 'content-type': None, + 'json': None, + } + + +def test_request(client, server): + r = client.request("GET", server.url) + assert r.status_code == 200 + assert json.loads(r.body) == { + 'method': 'GET', + 'query-params': {}, + 'content-type': None, + 'json': None, + } + + +def test_stream(client, server): + with client.stream("GET", server.url) as r: + assert r.status_code == 200 + r.read() + assert json.loads(r.body) == { + 'method': 'GET', + 'query-params': {}, + 'content-type': None, + 'json': None, + } + + +def test_get_with_invalid_scheme(client): + with pytest.raises(ValueError): + client.get("nope://www.example.com") diff --git a/tests/test_content.py b/tests/test_content.py new file mode 100644 index 0000000000..ae3158e916 --- /dev/null +++ b/tests/test_content.py @@ -0,0 +1,285 @@ +import httpx +import os +import tempfile + + + +# HTML + +def test_html(): + html = httpx.HTML("Hello, world") + + stream = html.encode() + content_type = html.content_type() + + assert stream.read() == b'Hello, world' + assert content_type == "text/html; charset='utf-8'" + + +# Text + +def test_text(): + text = httpx.Text("Hello, world") + + stream = text.encode() + content_type = text.content_type() + + assert stream.read() == b'Hello, world' + assert content_type == "text/plain; charset='utf-8'" + + +# JSON + +def test_json(): + data = httpx.JSON({'data': 123}) + + stream = data.encode() + content_type = data.content_type() + + assert stream.read() == b'{"data":123}' + assert content_type == "application/json" + + +# Form + +def test_form(): + f = httpx.Form("a=123&a=456&b=789") + assert str(f) == "a=123&a=456&b=789" + assert repr(f) == "" + assert f.multi_dict() == { + "a": ["123", "456"], + "b": ["789"] + } + + +def test_form_from_dict(): + f = httpx.Form({ + "a": ["123", "456"], + "b": "789" + }) + assert str(f) == "a=123&a=456&b=789" + assert repr(f) == "" + assert f.multi_dict() == { + "a": ["123", "456"], + "b": ["789"] + } + + +def test_form_from_list(): + f = httpx.Form([("a", "123"), ("a", "456"), ("b", "789")]) + assert str(f) == "a=123&a=456&b=789" + assert repr(f) == "" + assert f.multi_dict() == { + "a": ["123", "456"], + "b": ["789"] + } + + +def test_empty_form(): + f = httpx.Form() + assert str(f) == '' + assert repr(f) == "" + assert f.multi_dict() == {} + + +def test_form_accessors(): + f = httpx.Form([("a", "123"), ("a", "456"), ("b", "789")]) + assert "a" in f + assert "A" not in f + assert "c" not in f + assert f["a"] == "123" + assert f.get("a") == "123" + assert f.get("nope", default=None) is None + + +def test_form_dict(): + f = httpx.Form([("a", "123"), ("a", "456"), ("b", "789")]) + assert list(f.keys()) == ["a", "b"] + assert list(f.values()) == ["123", "789"] + assert list(f.items()) == [("a", "123"), ("b", "789")] + assert list(f) == ["a", "b"] + assert dict(f) == {"a": "123", "b": "789"} + + +def test_form_multidict(): + f = httpx.Form([("a", "123"), ("a", "456"), ("b", "789")]) + assert f.get_list("a") == ["123", "456"] + assert f.multi_items() == [("a", "123"), ("a", "456"), ("b", "789")] + assert f.multi_dict() == {"a": ["123", "456"], "b": ["789"]} + + +def test_form_builtins(): + f = httpx.Form([("a", "123"), ("a", "456"), ("b", "789")]) + assert len(f) == 2 + assert bool(f) + assert hash(f) + assert f == httpx.Form([("a", "123"), ("a", "456"), ("b", "789")]) + + +def test_form_copy_operations(): + f = httpx.Form([("a", "123"), ("a", "456"), ("b", "789")]) + assert f.copy_set("a", "abc") == httpx.Form([("a", "abc"), ("b", "789")]) + assert f.copy_append("a", "abc") == httpx.Form([("a", "123"), ("a", "456"), ("a", "abc"), ("b", "789")]) + assert f.copy_remove("a") == httpx.Form([("b", "789")]) + + +def test_form_encode(): + form = httpx.Form({'email': 'address@example.com'}) + assert form['email'] == "address@example.com" + + stream = form.encode() + content_type = form.content_type() + + assert stream.read() == b"email=address%40example.com" + assert content_type == "application/x-www-form-urlencoded" + + +# Files + +def test_files(): + f = httpx.Files() + assert f.multi_dict() == {} + assert repr(f) == "" + + +def test_files_from_dict(): + f = httpx.Files({ + "a": [ + httpx.File("123.json"), + httpx.File("456.json"), + ], + "b": httpx.File("789.json") + }) + assert f.multi_dict() == { + "a": [ + httpx.File("123.json"), + httpx.File("456.json"), + ], + "b": [ + httpx.File("789.json"), + ] + } + assert repr(f) == ( + "), ('a', ), ('b', )]>" + ) + + + +def test_files_from_list(): + f = httpx.Files([ + ("a", httpx.File("123.json")), + ("a", httpx.File("456.json")), + ("b", httpx.File("789.json")) + ]) + assert f.multi_dict() == { + "a": [ + httpx.File("123.json"), + httpx.File("456.json"), + ], + "b": [ + httpx.File("789.json"), + ] + } + assert repr(f) == ( + "), ('a', ), ('b', )]>" + ) + + +def test_files_accessors(): + f = httpx.Files([ + ("a", httpx.File("123.json")), + ("a", httpx.File("456.json")), + ("b", httpx.File("789.json")) + ]) + assert "a" in f + assert "A" not in f + assert "c" not in f + assert f["a"] == httpx.File("123.json") + assert f.get("a") == httpx.File("123.json") + assert f.get("nope", default=None) is None + + +def test_files_dict(): + f = httpx.Files([ + ("a", httpx.File("123.json")), + ("a", httpx.File("456.json")), + ("b", httpx.File("789.json")) + ]) + assert list(f.keys()) == ["a", "b"] + assert list(f.values()) == [httpx.File("123.json"), httpx.File("789.json")] + assert list(f.items()) == [("a", httpx.File("123.json")), ("b", httpx.File("789.json"))] + assert list(f) == ["a", "b"] + assert dict(f) == {"a": httpx.File("123.json"), "b": httpx.File("789.json")} + + +def test_files_multidict(): + f = httpx.Files([ + ("a", httpx.File("123.json")), + ("a", httpx.File("456.json")), + ("b", httpx.File("789.json")) + ]) + assert f.get_list("a") == [ + httpx.File("123.json"), + httpx.File("456.json"), + ] + assert f.multi_items() == [ + ("a", httpx.File("123.json")), + ("a", httpx.File("456.json")), + ("b", httpx.File("789.json")), + ] + assert f.multi_dict() == { + "a": [ + httpx.File("123.json"), + httpx.File("456.json"), + ], + "b": [ + httpx.File("789.json"), + ] + } + + +def test_files_builtins(): + f = httpx.Files([ + ("a", httpx.File("123.json")), + ("a", httpx.File("456.json")), + ("b", httpx.File("789.json")) + ]) + assert len(f) == 2 + assert bool(f) + assert f == httpx.Files([ + ("a", httpx.File("123.json")), + ("a", httpx.File("456.json")), + ("b", httpx.File("789.json")), + ]) + + +def test_multipart(): + with tempfile.NamedTemporaryFile() as f: + f.write(b"Hello, world") + f.seek(0) + + multipart = httpx.MultiPart( + form={'email': 'me@example.com'}, + files={'upload': httpx.File(f.name)}, + boundary='BOUNDARY', + ) + assert multipart.form['email'] == "me@example.com" + assert multipart.files['upload'] == httpx.File(f.name) + + fname = os.path.basename(f.name).encode('utf-8') + stream = multipart.encode() + content_type = multipart.content_type() + + content_type == "multipart/form-data; boundary=BOUNDARY" + content = stream.read() + assert content == ( + b'--BOUNDARY\r\n' + b'Content-Disposition: form-data; name="email"\r\n' + b'\r\n' + b'me@example.com\r\n' + b'--BOUNDARY\r\n' + b'Content-Disposition: form-data; name="upload"; filename="' + fname + b'"\r\n' + b'\r\n' + b'Hello, world\r\n' + b'--BOUNDARY--\r\n' + ) diff --git a/tests/test_headers.py b/tests/test_headers.py new file mode 100644 index 0000000000..6ebb99dca2 --- /dev/null +++ b/tests/test_headers.py @@ -0,0 +1,109 @@ +import httpx +import pytest + + +def test_headers_from_dict(): + headers = httpx.Headers({ + 'Content-Length': '1024', + 'Content-Type': 'text/plain; charset=utf-8', + }) + assert headers['Content-Length'] == '1024' + assert headers['Content-Type'] == 'text/plain; charset=utf-8' + + +def test_headers_from_list(): + headers = httpx.Headers([ + ('Location', 'https://www.example.com'), + ('Set-Cookie', 'session_id=3498jj489jhb98jn'), + ]) + assert headers['Location'] == 'https://www.example.com' + assert headers['Set-Cookie'] == 'session_id=3498jj489jhb98jn' + + +def test_header_keys(): + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert list(h.keys()) == ["Accept", "User-Agent"] + + +def test_header_values(): + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert list(h.values()) == ["*/*", "python/httpx"] + + +def test_header_items(): + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert list(h.items()) == [("Accept", "*/*"), ("User-Agent", "python/httpx")] + + +def test_header_get(): + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert h.get("User-Agent") == "python/httpx" + assert h.get("user-agent") == "python/httpx" + assert h.get("missing") is None + + +def test_header_copy_set(): + h = httpx.Headers({"Expires": "0"}) + h = h.copy_set("Expires", "Wed, 21 Oct 2015 07:28:00 GMT") + assert h == httpx.Headers({"Expires": "Wed, 21 Oct 2015 07:28:00 GMT"}) + + h = httpx.Headers({"Expires": "0"}) + h = h.copy_set("expires", "Wed, 21 Oct 2015 07:28:00 GMT") + assert h == httpx.Headers({"Expires": "Wed, 21 Oct 2015 07:28:00 GMT"}) + + +def test_header_copy_remove(): + h = httpx.Headers({"Accept": "*/*"}) + h = h.copy_remove("Accept") + assert h == httpx.Headers({}) + + h = httpx.Headers({"Accept": "*/*"}) + h = h.copy_remove("accept") + assert h == httpx.Headers({}) + + +def test_header_getitem(): + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert h["User-Agent"] == "python/httpx" + assert h["user-agent"] == "python/httpx" + with pytest.raises(KeyError): + h["missing"] + + +def test_header_contains(): + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert "User-Agent" in h + assert "user-agent" in h + assert "missing" not in h + + +def test_header_bool(): + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert bool(h) + h = httpx.Headers() + assert not bool(h) + + +def test_header_iter(): + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert [k for k in h] == ["Accept", "User-Agent"] + + +def test_header_len(): + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert len(h) == 2 + + +def test_header_repr(): + h = httpx.Headers({"Accept": "*/*", "User-Agent": "python/httpx"}) + assert repr(h) == "" + + +def test_header_invalid_name(): + with pytest.raises(ValueError): + httpx.Headers({"Accept\n": "*/*"}) + + +def test_header_invalid_value(): + with pytest.raises(ValueError): + httpx.Headers({"Accept": "*/*\n"}) diff --git a/tests/test_network.py b/tests/test_network.py new file mode 100644 index 0000000000..e6ce92563b --- /dev/null +++ b/tests/test_network.py @@ -0,0 +1,101 @@ +import httpx +import pytest + + +def echo(stream): + while buffer := stream.read(): + stream.write(buffer) + + +@pytest.fixture +def server(): + net = httpx.NetworkBackend() + with net.serve("127.0.0.1", 8080, echo) as server: + yield server + + +def test_network_backend(): + net = httpx.NetworkBackend() + assert repr(net) == "" + + +def test_network_backend_connect(server): + net = httpx.NetworkBackend() + stream = net.connect(server.host, server.port) + try: + assert repr(stream) == f"" + stream.write(b"Hello, world.") + content = stream.read() + assert content == b"Hello, world." + finally: + stream.close() + + +def test_network_backend_context_managed(server): + net = httpx.NetworkBackend() + with net.connect(server.host, server.port) as stream: + stream.write(b"Hello, world.") + content = stream.read() + assert content == b"Hello, world." + assert repr(stream) == f"" + + +def test_network_backend_timeout(server): + net = httpx.NetworkBackend() + with httpx.timeout(0.0): + with pytest.raises(TimeoutError): + with net.connect(server.host, server.port) as stream: + pass + + with httpx.timeout(10.0): + with net.connect(server.host, server.port) as stream: + pass + + +# >>> net = httpx.NetworkBackend() +# >>> stream = net.connect("dev.encode.io", 80) +# >>> try: +# >>> ... +# >>> finally: +# >>> stream.close() +# >>> stream +# + +# import httpx +# import ssl +# import truststore + +# net = httpx.NetworkBackend() +# ctx = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT) +# req = b'\r\n'.join([ +# b'GET / HTTP/1.1', +# b'Host: www.example.com', +# b'User-Agent: python/dev', +# b'Connection: close', +# b'', +# ]) + +# # Use a 10 second overall timeout for the entire request/response. +# with timeout(10.0): +# # Use a 3 second timeout for the initial connection. +# with timeout(3.0) as t: +# # Open the connection & establish SSL. +# with net.open_stream("www.example.com", 443) as stream: +# stream.start_tls(ctx, hostname="www.example.com") +# t.cancel() +# # Send the request & read the response. +# stream.write(req) +# buffer = [] +# while part := stream.read(): +# buffer.append(part) +# resp = b''.join(buffer) + + +# def test_fixture(tcp_echo_server): +# host, port = (tcp_echo_server.host, tcp_echo_server.port) + +# net = httpx.NetworkBackend() +# with net.connect(host, port) as stream: +# stream.write(b"123") +# buffer = stream.read() +# assert buffer == b"123" diff --git a/tests/test_parsers.py b/tests/test_parsers.py new file mode 100644 index 0000000000..e2a321e2a2 --- /dev/null +++ b/tests/test_parsers.py @@ -0,0 +1,748 @@ +import httpx +import pytest + + +class TrickleIO(httpx.Stream): + def __init__(self, stream: httpx.Stream): + self._stream = stream + + def read(self, size) -> bytes: + return self._stream.read(1) + + def write(self, data: bytes) -> None: + self._stream.write(data) + + def close(self) -> None: + self._stream.close() + + +def test_parser(): + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Content-Length: 12\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + b"hello, world" + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"POST", b"/", b"HTTP/1.1") + p.send_headers([ + (b"Host", b"example.com"), + (b"Content-Type", b"application/json"), + (b"Content-Length", b"23"), + ]) + p.send_body(b'{"msg": "hello, world"}') + p.send_body(b'') + + assert stream.input_bytes() == ( + b"HTTP/1.1 200 OK\r\n" + b"Content-Length: 12\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + b"hello, world" + ) + assert stream.output_bytes() == ( + b"POST / HTTP/1.1\r\n" + b"Host: example.com\r\n" + b"Content-Type: application/json\r\n" + b"Content-Length: 23\r\n" + b"\r\n" + b'{"msg": "hello, world"}' + ) + + protocol, code, reason_phase = p.recv_status_line() + headers = p.recv_headers() + body = p.recv_body() + terminator = p.recv_body() + + assert protocol == b'HTTP/1.1' + assert code == 200 + assert reason_phase == b'OK' + assert headers == [ + (b'Content-Length', b'12'), + (b'Content-Type', b'text/plain'), + ] + assert body == b'hello, world' + assert terminator == b'' + + assert not p.is_idle() + p.complete() + assert p.is_idle() + + +def test_parser_server(): + stream = httpx.DuplexStream( + b"GET / HTTP/1.1\r\n" + b"Host: www.example.com\r\n" + b"\r\n" + ) + + p = httpx.HTTPParser(stream, mode='SERVER') + method, target, protocol = p.recv_method_line() + headers = p.recv_headers() + body = p.recv_body() + + assert method == b'GET' + assert target == b'/' + assert protocol == b'HTTP/1.1' + assert headers == [ + (b'Host', b'www.example.com'), + ] + assert body == b'' + + p.send_status_line(b"HTTP/1.1", 200, b"OK") + p.send_headers([ + (b"Content-Type", b"application/json"), + (b"Content-Length", b"23"), + ]) + p.send_body(b'{"msg": "hello, world"}') + p.send_body(b'') + + assert stream.input_bytes() == ( + b"GET / HTTP/1.1\r\n" + b"Host: www.example.com\r\n" + b"\r\n" + ) + assert stream.output_bytes() == ( + b"HTTP/1.1 200 OK\r\n" + b"Content-Type: application/json\r\n" + b"Content-Length: 23\r\n" + b"\r\n" + b'{"msg": "hello, world"}' + ) + + assert not p.is_idle() + p.complete() + assert p.is_idle() + + +def test_parser_trickle(): + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Content-Length: 12\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + b"hello, world" + ) + + p = httpx.HTTPParser(TrickleIO(stream), mode='CLIENT') + p.send_method_line(b"POST", b"/", b"HTTP/1.1") + p.send_headers([ + (b"Host", b"example.com"), + (b"Content-Type", b"application/json"), + (b"Content-Length", b"23"), + ]) + p.send_body(b'{"msg": "hello, world"}') + p.send_body(b'') + + assert stream.input_bytes() == ( + b"HTTP/1.1 200 OK\r\n" + b"Content-Length: 12\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + b"hello, world" + ) + assert stream.output_bytes() == ( + b"POST / HTTP/1.1\r\n" + b"Host: example.com\r\n" + b"Content-Type: application/json\r\n" + b"Content-Length: 23\r\n" + b"\r\n" + b'{"msg": "hello, world"}' + ) + + protocol, code, reason_phase = p.recv_status_line() + headers = p.recv_headers() + body = p.recv_body() + terminator = p.recv_body() + + assert protocol == b'HTTP/1.1' + assert code == 200 + assert reason_phase == b'OK' + assert headers == [ + (b'Content-Length', b'12'), + (b'Content-Type', b'text/plain'), + ] + assert body == b'hello, world' + assert terminator == b'' + + +def test_parser_transfer_encoding_chunked(): + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Content-Type: text/plain\r\n" + b"Transfer-Encoding: chunked\r\n" + b"\r\n" + b"c\r\n" + b"hello, world\r\n" + b"0\r\n\r\n" + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"POST", b"/", b"HTTP/1.1") + p.send_headers([ + (b"Host", b"example.com"), + (b"Content-Type", b"application/json"), + (b"Transfer-Encoding", b"chunked"), + ]) + p.send_body(b'{"msg": "hello, world"}') + p.send_body(b'') + + assert stream.input_bytes() == ( + b"HTTP/1.1 200 OK\r\n" + b"Content-Type: text/plain\r\n" + b"Transfer-Encoding: chunked\r\n" + b"\r\n" + b"c\r\n" + b"hello, world\r\n" + b"0\r\n\r\n" + ) + assert stream.output_bytes() == ( + b"POST / HTTP/1.1\r\n" + b"Host: example.com\r\n" + b"Content-Type: application/json\r\n" + b"Transfer-Encoding: chunked\r\n" + b"\r\n" + b'17\r\n' + b'{"msg": "hello, world"}\r\n' + b'0\r\n\r\n' + ) + + protocol, code, reason_phase = p.recv_status_line() + headers = p.recv_headers() + body = p.recv_body() + terminator = p.recv_body() + + assert protocol == b'HTTP/1.1' + assert code == 200 + assert reason_phase == b'OK' + assert headers == [ + (b'Content-Type', b'text/plain'), + (b'Transfer-Encoding', b'chunked'), + ] + assert body == b'hello, world' + assert terminator == b'' + + +def test_parser_transfer_encoding_chunked_trickle(): + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Content-Type: text/plain\r\n" + b"Transfer-Encoding: chunked\r\n" + b"\r\n" + b"c\r\n" + b"hello, world\r\n" + b"0\r\n\r\n" + ) + + p = httpx.HTTPParser(TrickleIO(stream), mode='CLIENT') + p.send_method_line(b"POST", b"/", b"HTTP/1.1") + p.send_headers([ + (b"Host", b"example.com"), + (b"Content-Type", b"application/json"), + (b"Transfer-Encoding", b"chunked"), + ]) + p.send_body(b'{"msg": "hello, world"}') + p.send_body(b'') + + assert stream.input_bytes() == ( + b"HTTP/1.1 200 OK\r\n" + b"Content-Type: text/plain\r\n" + b"Transfer-Encoding: chunked\r\n" + b"\r\n" + b"c\r\n" + b"hello, world\r\n" + b"0\r\n\r\n" + ) + assert stream.output_bytes() == ( + b"POST / HTTP/1.1\r\n" + b"Host: example.com\r\n" + b"Content-Type: application/json\r\n" + b"Transfer-Encoding: chunked\r\n" + b"\r\n" + b'17\r\n' + b'{"msg": "hello, world"}\r\n' + b'0\r\n\r\n' + ) + + protocol, code, reason_phase = p.recv_status_line() + headers = p.recv_headers() + body = p.recv_body() + terminator = p.recv_body() + + assert protocol == b'HTTP/1.1' + assert code == 200 + assert reason_phase == b'OK' + assert headers == [ + (b'Content-Type', b'text/plain'), + (b'Transfer-Encoding', b'chunked'), + ] + assert body == b'hello, world' + assert terminator == b'' + + +def test_parser_repr(): + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Content-Type: application/json\r\n" + b"Content-Length: 23\r\n" + b"\r\n" + b'{"msg": "hello, world"}' + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + assert repr(p) == "" + + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + assert repr(p) == "" + + p.send_headers([(b"Host", b"example.com")]) + assert repr(p) == "" + + p.send_body(b'') + assert repr(p) == "" + + p.recv_status_line() + assert repr(p) == "" + + p.recv_headers() + assert repr(p) == "" + + p.recv_body() + assert repr(p) == "" + + p.recv_body() + assert repr(p) == "" + + p.complete() + assert repr(p) == "" + + +def test_parser_invalid_transitions(): + stream = httpx.DuplexStream() + + with pytest.raises(httpx.ProtocolError): + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b'GET', b'/', b'HTTP/1.1') + p.send_method_line(b'GET', b'/', b'HTTP/1.1') + + with pytest.raises(httpx.ProtocolError): + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_headers([]) + + with pytest.raises(httpx.ProtocolError): + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_body(b'') + + with pytest.raises(httpx.ProtocolError): + reader = httpx.ByteStream(b'HTTP/1.1 200 OK\r\n') + p = httpx.HTTPParser(stream, mode='CLIENT') + p.recv_status_line() + + with pytest.raises(httpx.ProtocolError): + p = httpx.HTTPParser(stream, mode='CLIENT') + p.recv_headers() + + with pytest.raises(httpx.ProtocolError): + p = httpx.HTTPParser(stream, mode='CLIENT') + p.recv_body() + + +def test_parser_invalid_status_line(): + # ... + stream = httpx.DuplexStream(b'...') + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([(b"Host", b"example.com")]) + p.send_body(b'') + + msg = 'Stream closed early reading response status line' + with pytest.raises(httpx.ProtocolError, match=msg): + p.recv_status_line() + + # ... + stream = httpx.DuplexStream(b'HTTP/1.1' + b'x' * 5000) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([(b"Host", b"example.com")]) + p.send_body(b'') + + msg = 'Exceeded maximum size reading response status line' + with pytest.raises(httpx.ProtocolError, match=msg): + p.recv_status_line() + + # ... + stream = httpx.DuplexStream(b'HTTP/1.1' + b'x' * 5000 + b'\r\n') + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([(b"Host", b"example.com")]) + p.send_body(b'') + + msg = 'Exceeded maximum size reading response status line' + with pytest.raises(httpx.ProtocolError, match=msg): + p.recv_status_line() + + +def test_parser_sent_unsupported_protocol(): + # Currently only HTTP/1.1 is supported. + stream = httpx.DuplexStream() + + p = httpx.HTTPParser(stream, mode='CLIENT') + msg = 'Sent unsupported protocol version' + with pytest.raises(httpx.ProtocolError, match=msg): + p.send_method_line(b"GET", b"/", b"HTTP/1.0") + + +def test_parser_recv_unsupported_protocol(): + # Currently only HTTP/1.1 is supported. + stream = httpx.DuplexStream(b"HTTP/1.0 200 OK\r\n") + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + msg = 'Received unsupported protocol version' + with pytest.raises(httpx.ProtocolError, match=msg): + p.recv_status_line() + + +def test_parser_large_body(): + body = b"x" * 6988 + + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Content-Length: 6988\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + body + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([(b"Host", b"example.com")]) + p.send_body(b'') + + # Checkout our buffer sizes. + p.recv_status_line() + p.recv_headers() + assert len(p.recv_body()) == 4096 + assert len(p.recv_body()) == 2892 + assert len(p.recv_body()) == 0 + + +def test_parser_stream_large_body(): + body = b"x" * 6956 + + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Transfer-Encoding: chunked\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + b"1b2c\r\n" + body + b'\r\n0\r\n\r\n' + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([(b"Host", b"example.com")]) + p.send_body(b'') + + # Checkout our buffer sizes. + p.recv_status_line() + p.recv_headers() + # assert len(p.recv_body()) == 4096 + # assert len(p.recv_body()) == 2860 + assert len(p.recv_body()) == 6956 + assert len(p.recv_body()) == 0 + + +def test_parser_not_enough_data_received(): + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Content-Length: 188\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + b"truncated" + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([(b"Host", b"example.com")]) + p.send_body(b'') + + # Checkout our buffer sizes. + p.recv_status_line() + p.recv_headers() + p.recv_body() + msg = 'Not enough data received for declared Content-Length' + with pytest.raises(httpx.ProtocolError, match=msg): + p.recv_body() + + +def test_parser_not_enough_data_sent(): + stream = httpx.DuplexStream() + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"POST", b"/", b"HTTP/1.1") + p.send_headers([ + (b"Host", b"example.com"), + (b"Content-Type", b"application/json"), + (b"Content-Length", b"23"), + ]) + p.send_body(b'{"msg": "too smol"}') + msg = 'Not enough data sent for declared Content-Length' + with pytest.raises(httpx.ProtocolError, match=msg): + p.send_body(b'') + + +def test_parser_too_much_data_sent(): + stream = httpx.DuplexStream() + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"POST", b"/", b"HTTP/1.1") + p.send_headers([ + (b"Host", b"example.com"), + (b"Content-Type", b"application/json"), + (b"Content-Length", b"19"), + ]) + msg = 'Too much data sent for declared Content-Length' + with pytest.raises(httpx.ProtocolError, match=msg): + p.send_body(b'{"msg": "too chonky"}') + + +def test_parser_missing_host_header(): + stream = httpx.DuplexStream() + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + msg = "Request missing 'Host' header" + with pytest.raises(httpx.ProtocolError, match=msg): + p.send_headers([]) + + +def test_client_connection_close(): + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Content-Length: 12\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + b"hello, world" + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([ + (b"Host", b"example.com"), + (b"Connection", b"close"), + ]) + p.send_body(b'') + + protocol, code, reason_phase = p.recv_status_line() + headers = p.recv_headers() + body = p.recv_body() + terminator = p.recv_body() + + assert protocol == b'HTTP/1.1' + assert code == 200 + assert reason_phase == b"OK" + assert headers == [ + (b'Content-Length', b'12'), + (b'Content-Type', b'text/plain'), + ] + assert body == b"hello, world" + assert terminator == b"" + + assert repr(p) == "" + + p.complete() + assert repr(p) == "" + assert p.is_closed() + + +def test_server_connection_close(): + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Content-Length: 12\r\n" + b"Content-Type: text/plain\r\n" + b"Connection: close\r\n" + b"\r\n" + b"hello, world" + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([(b"Host", b"example.com")]) + p.send_body(b'') + + protocol, code, reason_phase = p.recv_status_line() + headers = p.recv_headers() + body = p.recv_body() + terminator = p.recv_body() + + assert protocol == b'HTTP/1.1' + assert code == 200 + assert reason_phase == b"OK" + assert headers == [ + (b'Content-Length', b'12'), + (b'Content-Type', b'text/plain'), + (b'Connection', b'close'), + ] + assert body == b"hello, world" + assert terminator == b"" + + assert repr(p) == "" + p.complete() + assert repr(p) == "" + + +def test_invalid_status_code(): + stream = httpx.DuplexStream( + b"HTTP/1.1 99 OK\r\n" + b"Content-Length: 12\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + b"hello, world" + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([ + (b"Host", b"example.com"), + (b"Connection", b"close"), + ]) + p.send_body(b'') + + msg = "Received invalid status code" + with pytest.raises(httpx.ProtocolError, match=msg): + p.recv_status_line() + + +def test_1xx_status_code(): + stream = httpx.DuplexStream( + b"HTTP/1.1 103 Early Hints\r\n" + b"Link: ; rel=preload; as=style\r\n" + b"Link: ; rel=preload; as=script\r\n" + b"\r\n" + b"HTTP/1.1 200 OK\r\n" + b"Content-Length: 12\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + b"hello, world" + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([(b"Host", b"example.com")]) + p.send_body(b'') + + protocol, code, reason_phase = p.recv_status_line() + headers = p.recv_headers() + + assert protocol == b'HTTP/1.1' + assert code == 103 + assert reason_phase == b'Early Hints' + assert headers == [ + (b'Link', b'; rel=preload; as=style'), + (b'Link', b'; rel=preload; as=script'), + ] + + protocol, code, reason_phase = p.recv_status_line() + headers = p.recv_headers() + body = p.recv_body() + terminator = p.recv_body() + + assert protocol == b'HTTP/1.1' + assert code == 200 + assert reason_phase == b"OK" + assert headers == [ + (b'Content-Length', b'12'), + (b'Content-Type', b'text/plain'), + ] + assert body == b"hello, world" + assert terminator == b"" + + +def test_received_invalid_content_length(): + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Content-Length: -999\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + b"hello, world" + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([ + (b"Host", b"example.com"), + (b"Connection", b"close"), + ]) + p.send_body(b'') + + p.recv_status_line() + msg = "Received invalid Content-Length" + with pytest.raises(httpx.ProtocolError, match=msg): + p.recv_headers() + + +def test_sent_invalid_content_length(): + stream = httpx.DuplexStream() + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + msg = "Sent invalid Content-Length" + with pytest.raises(httpx.ProtocolError, match=msg): + # Limited to 20 digits. + # 100 million terabytes should be enough for anyone. + p.send_headers([ + (b"Host", b"example.com"), + (b"Content-Length", b"100000000000000000000"), + ]) + + +def test_received_invalid_characters_in_chunk_size(): + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Transfer-Encoding: chunked\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + b"0xFF\r\n..." + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([ + (b"Host", b"example.com"), + (b"Connection", b"close"), + ]) + p.send_body(b'') + + p.recv_status_line() + p.recv_headers() + msg = "Received invalid chunk size" + with pytest.raises(httpx.ProtocolError, match=msg): + p.recv_body() + + +def test_received_oversized_chunk(): + stream = httpx.DuplexStream( + b"HTTP/1.1 200 OK\r\n" + b"Transfer-Encoding: chunked\r\n" + b"Content-Type: text/plain\r\n" + b"\r\n" + b"FFFFFFFFFF\r\n..." + ) + + p = httpx.HTTPParser(stream, mode='CLIENT') + p.send_method_line(b"GET", b"/", b"HTTP/1.1") + p.send_headers([ + (b"Host", b"example.com"), + (b"Connection", b"close"), + ]) + p.send_body(b'') + + p.recv_status_line() + p.recv_headers() + msg = "Received invalid chunk size" + with pytest.raises(httpx.ProtocolError, match=msg): + p.recv_body() diff --git a/tests/test_pool.py b/tests/test_pool.py new file mode 100644 index 0000000000..04cd0246e5 --- /dev/null +++ b/tests/test_pool.py @@ -0,0 +1,126 @@ +import httpx +import pytest + + +def hello_world(request): + content = httpx.Text('Hello, world.') + return httpx.Response(200, content=content) + + +@pytest.fixture +def server(): + with httpx.serve_http(hello_world) as server: + yield server + + +def test_connection_pool_request(server): + with httpx.ConnectionPool() as pool: + assert repr(pool) == "" + assert len(pool.connections) == 0 + + r = pool.request("GET", server.url) + + assert r.status_code == 200 + assert repr(pool) == "" + assert len(pool.connections) == 1 + + +def test_connection_pool_connection_close(server): + with httpx.ConnectionPool() as pool: + assert repr(pool) == "" + assert len(pool.connections) == 0 + + r = pool.request("GET", server.url, headers={"Connection": "close"}) + + # TODO: Really we want closed connections proactively removed from the pool, + assert r.status_code == 200 + assert repr(pool) == "" + assert len(pool.connections) == 1 + + +def test_connection_pool_stream(server): + with httpx.ConnectionPool() as pool: + assert repr(pool) == "" + assert len(pool.connections) == 0 + + with pool.stream("GET", server.url) as r: + assert r.status_code == 200 + assert repr(pool) == "" + assert len(pool.connections) == 1 + r.read() + + assert repr(pool) == "" + assert len(pool.connections) == 1 + + +def test_connection_pool_cannot_request_after_closed(server): + with httpx.ConnectionPool() as pool: + pool + + with pytest.raises(RuntimeError): + pool.request("GET", server.url) + + +def test_connection_pool_should_have_managed_lifespan(server): + pool = httpx.ConnectionPool() + with pytest.warns(UserWarning): + del pool + + +def test_connection_request(server): + with httpx.open_connection(server.url) as conn: + assert repr(conn) == f"" + + r = conn.request("GET", "/") + + assert r.status_code == 200 + assert repr(conn) == f"" + + +def test_connection_stream(server): + with httpx.open_connection(server.url) as conn: + assert repr(conn) == f"" + with conn.stream("GET", "/") as r: + assert r.status_code == 200 + assert repr(conn) == f"" + r.read() + assert repr(conn) == f"" + + +# # with httpx.open_connection("https://www.example.com/") as conn: +# # r = conn.request("GET", "/") + +# # >>> pool = httpx.ConnectionPool() +# # >>> pool +# # + +# # >>> with httpx.open_connection_pool() as pool: +# # >>> res = pool.request("GET", "https://www.example.com") +# # >>> res, pool +# # , + +# # >>> with httpx.open_connection_pool() as pool: +# # >>> with pool.stream("GET", "https://www.example.com") as res: +# # >>> res, pool +# # , + +# # >>> with httpx.open_connection_pool() as pool: +# # >>> req = httpx.Request("GET", "https://www.example.com") +# # >>> with pool.send(req) as res: +# # >>> res.body() +# # >>> res, pool +# # , + +# # >>> with httpx.open_connection_pool() as pool: +# # >>> pool.close() +# # + +# # with httpx.open_connection("https://www.example.com/") as conn: +# # with conn.upgrade("GET", "/feed", {"Upgrade": "WebSocket") as stream: +# # ... + +# # with httpx.open_connection("http://127.0.0.1:8080") as conn: +# # with conn.upgrade("CONNECT", "www.encode.io:443") as stream: +# # stream.start_tls(ctx, hostname="www.encode.io") +# # ... + diff --git a/tests/test_quickstart.py b/tests/test_quickstart.py new file mode 100644 index 0000000000..55c34b1b5a --- /dev/null +++ b/tests/test_quickstart.py @@ -0,0 +1,78 @@ +import json +import httpx +import pytest + + +def echo(request): + request.read() + response = httpx.Response(200, content=httpx.JSON({ + 'method': request.method, + 'query-params': dict(request.url.params.items()), + 'content-type': request.headers.get('Content-Type'), + 'json': json.loads(request.body) if request.body else None, + })) + return response + + +@pytest.fixture +def server(): + with httpx.serve_http(echo) as server: + yield server + + +def test_get(server): + r = httpx.get(server.url) + assert r.status_code == 200 + assert json.loads(r.body) == { + 'method': 'GET', + 'query-params': {}, + 'content-type': None, + 'json': None, + } + + +def test_post(server): + data = httpx.JSON({"data": 123}) + r = httpx.post(server.url, content=data) + assert r.status_code == 200 + assert json.loads(r.body) == { + 'method': 'POST', + 'query-params': {}, + 'content-type': 'application/json', + 'json': {"data": 123}, + } + + +def test_put(server): + data = httpx.JSON({"data": 123}) + r = httpx.put(server.url, content=data) + assert r.status_code == 200 + assert json.loads(r.body) == { + 'method': 'PUT', + 'query-params': {}, + 'content-type': 'application/json', + 'json': {"data": 123}, + } + + +def test_patch(server): + data = httpx.JSON({"data": 123}) + r = httpx.patch(server.url, content=data) + assert r.status_code == 200 + assert json.loads(r.body) == { + 'method': 'PATCH', + 'query-params': {}, + 'content-type': 'application/json', + 'json': {"data": 123}, + } + + +def test_delete(server): + r = httpx.delete(server.url) + assert r.status_code == 200 + assert json.loads(r.body) == { + 'method': 'DELETE', + 'query-params': {}, + 'content-type': None, + 'json': None, + } diff --git a/tests/test_request.py b/tests/test_request.py new file mode 100644 index 0000000000..a69e1d1358 --- /dev/null +++ b/tests/test_request.py @@ -0,0 +1,79 @@ +import httpx + + +class ByteIterator: + def __init__(self, buffer=b""): + self._buffer = buffer + + def next(self) -> bytes: + buffer = self._buffer + self._buffer = b'' + return buffer + + +def test_request(): + r = httpx.Request("GET", "https://example.com") + + assert repr(r) == "" + assert r.method == "GET" + assert r.url == "https://example.com" + assert r.headers == { + "Host": "example.com" + } + assert r.read() == b"" + +def test_request_bytes(): + content = b"Hello, world" + r = httpx.Request("POST", "https://example.com", content=content) + + assert repr(r) == "" + assert r.method == "POST" + assert r.url == "https://example.com" + assert r.headers == { + "Host": "example.com", + "Content-Length": "12", + } + assert r.read() == b"Hello, world" + + +def test_request_stream(): + i = ByteIterator(b"Hello, world") + stream = httpx.HTTPStream(i.next, None) + r = httpx.Request("POST", "https://example.com", content=stream) + + assert repr(r) == "" + assert r.method == "POST" + assert r.url == "https://example.com" + assert r.headers == { + "Host": "example.com", + "Transfer-Encoding": "chunked", + } + assert r.read() == b"Hello, world" + + +def test_request_json(): + data = httpx.JSON({"msg": "Hello, world"}) + r = httpx.Request("POST", "https://example.com", content=data) + + assert repr(r) == "" + assert r.method == "POST" + assert r.url == "https://example.com" + assert r.headers == { + "Host": "example.com", + "Content-Length": "22", + "Content-Type": "application/json", + } + assert r.read() == b'{"msg":"Hello, world"}' + + +def test_request_empty_post(): + r = httpx.Request("POST", "https://example.com") + + assert repr(r) == "" + assert r.method == "POST" + assert r.url == "https://example.com" + assert r.headers == { + "Host": "example.com", + "Content-Length": "0", + } + assert r.read() == b'' diff --git a/tests/test_response.py b/tests/test_response.py new file mode 100644 index 0000000000..d25ebeb211 --- /dev/null +++ b/tests/test_response.py @@ -0,0 +1,64 @@ +import httpx + + +class ByteIterator: + def __init__(self, buffer=b""): + self._buffer = buffer + + def next(self) -> bytes: + buffer = self._buffer + self._buffer = b'' + return buffer + + +def test_response(): + r = httpx.Response(200) + + assert repr(r) == "" + assert r.status_code == 200 + assert r.headers == {'Content-Length': '0'} + assert r.read() == b"" + + +def test_response_204(): + r = httpx.Response(204) + + assert repr(r) == "" + assert r.status_code == 204 + assert r.headers == {} + assert r.read() == b"" + + +def test_response_bytes(): + content = b"Hello, world" + r = httpx.Response(200, content=content) + + assert repr(r) == "" + assert r.headers == { + "Content-Length": "12", + } + assert r.read() == b"Hello, world" + + +def test_response_stream(): + i = ByteIterator(b"Hello, world") + stream = httpx.HTTPStream(i.next, None) + r = httpx.Response(200, content=stream) + + assert repr(r) == "" + assert r.headers == { + "Transfer-Encoding": "chunked", + } + assert r.read() == b"Hello, world" + + +def test_response_json(): + data = httpx.JSON({"msg": "Hello, world"}) + r = httpx.Response(200, content=data) + + assert repr(r) == "" + assert r.headers == { + "Content-Length": "22", + "Content-Type": "application/json", + } + assert r.read() == b'{"msg":"Hello, world"}' diff --git a/tests/test_streams.py b/tests/test_streams.py new file mode 100644 index 0000000000..8053761056 --- /dev/null +++ b/tests/test_streams.py @@ -0,0 +1,82 @@ +import pytest +import httpx + + +def test_stream(): + i = httpx.Stream() + with pytest.raises(NotImplementedError): + i.read() + + with pytest.raises(NotImplementedError): + i.close() + + i.size == None + + +def test_bytestream(): + data = b'abc' + s = httpx.ByteStream(data) + assert s.size == 3 + assert s.read() == b'abc' + + s = httpx.ByteStream(data) + assert s.read(1) == b'a' + assert s.read(1) == b'b' + assert s.read(1) == b'c' + assert s.read(1) == b'' + + +def test_filestream(tmp_path): + path = tmp_path / "example.txt" + path.write_bytes(b"hello world") + + with httpx.FileStream(path) as s: + assert s.size == 11 + assert s.read() == b'hello world' + + with httpx.FileStream(path) as s: + assert s.read(5) == b'hello' + assert s.read(5) == b' worl' + assert s.read(5) == b'd' + assert s.read(5) == b'' + + with httpx.FileStream(path) as s: + assert s.read(5) == b'hello' + + + +def test_multipartstream(tmp_path): + path = tmp_path / 'example.txt' + path.write_bytes(b'hello world' + b'x' * 50) + + expected = b''.join([ + b'--boundary\r\n', + b'Content-Disposition: form-data; name="email"\r\n', + b'\r\n', + b'heya@example.com\r\n', + b'--boundary\r\n', + b'Content-Disposition: form-data; name="upload"; filename="example.txt"\r\n', + b'\r\n', + b'hello world' + ( b'x' * 50) + b'\r\n', + b'--boundary--\r\n', + ]) + + form = [('email', 'heya@example.com')] + files = [('upload', str(path))] + with httpx.MultiPartStream(form, files, boundary='boundary') as s: + assert s.size is None + assert s.read() == expected + + with httpx.MultiPartStream(form, files, boundary='boundary') as s: + assert s.read(50) == expected[:50] + assert s.read(50) == expected[50:100] + assert s.read(50) == expected[100:150] + assert s.read(50) == expected[150:200] + assert s.read(50) == expected[200:250] + + with httpx.MultiPartStream(form, files, boundary='boundary') as s: + assert s.read(50) == expected[:50] + assert s.read(50) == expected[50:100] + assert s.read(50) == expected[100:150] + assert s.read(50) == expected[150:200] + s.close() # test close during open file diff --git a/tests/test_urlencode.py b/tests/test_urlencode.py new file mode 100644 index 0000000000..42ba45ac37 --- /dev/null +++ b/tests/test_urlencode.py @@ -0,0 +1,33 @@ +import httpx + + +def test_urlencode(): + qs = "a=name%40example.com&a=456&b=7+8+9&c" + d = httpx.urldecode(qs) + assert d == { + "a": ["name@example.com", "456"], + "b": ["7 8 9"], + "c": [""] + } + + +def test_urldecode(): + d = { + "a": ["name@example.com", "456"], + "b": ["7 8 9"], + "c": [""] + } + qs = httpx.urlencode(d) + assert qs == "a=name%40example.com&a=456&b=7+8+9&c=" + + +def test_urlencode_empty(): + qs = "" + d = httpx.urldecode(qs) + assert d == {} + + +def test_urldecode_empty(): + d = {} + qs = httpx.urlencode(d) + assert qs == "" diff --git a/tests/test_urls.py b/tests/test_urls.py new file mode 100644 index 0000000000..ad72935273 --- /dev/null +++ b/tests/test_urls.py @@ -0,0 +1,164 @@ +import httpx +import pytest + + +def test_url(): + url = httpx.URL('https://www.example.com/') + assert str(url) == "https://www.example.com/" + + +def test_url_repr(): + url = httpx.URL('https://www.example.com/') + assert repr(url) == "" + + +def test_url_params(): + url = httpx.URL('https://www.example.com/', params={"a": "b", "c": "d"}) + assert str(url) == "https://www.example.com/?a=b&c=d" + + +def test_url_normalisation(): + url = httpx.URL('https://www.EXAMPLE.com:443/path/../main') + assert str(url) == 'https://www.example.com/main' + + +def test_url_relative(): + url = httpx.URL('/README.md') + assert str(url) == '/README.md' + + +def test_url_escaping(): + url = httpx.URL('https://example.com/path to here?search=🦋') + assert str(url) == 'https://example.com/path%20to%20here?search=%F0%9F%A6%8B' + + +def test_url_components(): + url = httpx.URL(scheme="https", host="example.com", path="/") + assert str(url) == 'https://example.com/' + + +# QueryParams + +def test_queryparams(): + params = httpx.QueryParams({"color": "black", "size": "medium"}) + assert str(params) == 'color=black&size=medium' + + +def test_queryparams_repr(): + params = httpx.QueryParams({"color": "black", "size": "medium"}) + assert repr(params) == "" + + +def test_queryparams_list_of_values(): + params = httpx.QueryParams({"filter": ["60GHz", "75GHz", "100GHz"]}) + assert str(params) == 'filter=60GHz&filter=75GHz&filter=100GHz' + + +def test_queryparams_from_str(): + params = httpx.QueryParams("color=black&size=medium") + assert str(params) == 'color=black&size=medium' + + +def test_queryparams_access(): + params = httpx.QueryParams("sort_by=published&author=natalie") + assert params["sort_by"] == 'published' + + +def test_queryparams_escaping(): + params = httpx.QueryParams({"email": "user@example.com", "search": "How HTTP works!"}) + assert str(params) == 'email=user%40example.com&search=How+HTTP+works%21' + + +def test_queryparams_empty(): + q = httpx.QueryParams({"a": ""}) + assert str(q) == "a=" + + q = httpx.QueryParams("a=") + assert str(q) == "a=" + + q = httpx.QueryParams("a") + assert str(q) == "a=" + + +def test_queryparams_set(): + q = httpx.QueryParams("a=123") + q = q.copy_set("a", "456") + assert q == httpx.QueryParams("a=456") + + +def test_queryparams_append(): + q = httpx.QueryParams("a=123") + q = q.copy_append("a", "456") + assert q == httpx.QueryParams("a=123&a=456") + + +def test_queryparams_remove(): + q = httpx.QueryParams("a=123") + q = q.copy_remove("a") + assert q == httpx.QueryParams("") + + +def test_queryparams_merge(): + q = httpx.QueryParams("a=123") + q = q.copy_update({"b": "456"}) + assert q == httpx.QueryParams("a=123&b=456") + q = q.copy_update({"a": "000", "c": "789"}) + assert q == httpx.QueryParams("a=000&b=456&c=789") + + +def test_queryparams_are_hashable(): + params = ( + httpx.QueryParams("a=123"), + httpx.QueryParams({"a": "123"}), + httpx.QueryParams("b=456"), + httpx.QueryParams({"b": "456"}), + ) + + assert len(set(params)) == 2 + + +@pytest.mark.parametrize( + "source", + [ + "a=123&a=456&b=789", + {"a": ["123", "456"], "b": "789"}, + {"a": ("123", "456"), "b": "789"}, + [("a", "123"), ("a", "456"), ("b", "789")], + (("a", "123"), ("a", "456"), ("b", "789")), + ], +) +def test_queryparams_misc(source): + q = httpx.QueryParams(source) + assert "a" in q + assert "A" not in q + assert "c" not in q + assert q["a"] == "123" + assert q.get("a") == "123" + assert q.get("nope", default=None) is None + assert q.get_list("a") == ["123", "456"] + assert bool(q) + + assert list(q.keys()) == ["a", "b"] + assert list(q.values()) == ["123", "789"] + assert list(q.items()) == [("a", "123"), ("b", "789")] + assert len(q) == 2 + assert list(q) == ["a", "b"] + assert dict(q) == {"a": "123", "b": "789"} + assert str(q) == "a=123&a=456&b=789" + assert httpx.QueryParams({"a": "123", "b": "456"}) == httpx.QueryParams( + [("a", "123"), ("b", "456")] + ) + assert httpx.QueryParams({"a": "123", "b": "456"}) == httpx.QueryParams( + "a=123&b=456" + ) + assert httpx.QueryParams({"a": "123", "b": "456"}) == httpx.QueryParams( + {"b": "456", "a": "123"} + ) + assert httpx.QueryParams() == httpx.QueryParams({}) + assert httpx.QueryParams([("a", "123"), ("a", "456")]) == httpx.QueryParams( + "a=123&a=456" + ) + assert httpx.QueryParams({"a": "123", "b": "456"}) != "invalid" + + q = httpx.QueryParams([("a", "123"), ("a", "456")]) + assert httpx.QueryParams(q) == q From 7b03e3def040983fb29fe82d9fd3d4ce9b058284 Mon Sep 17 00:00:00 2001 From: Kim Christie Date: Tue, 16 Sep 2025 22:18:01 +0100 Subject: [PATCH 2/5] Update README (#3667) --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f6f99268ae..d77f12505e 100644 --- a/README.md +++ b/README.md @@ -61,11 +61,11 @@ The [HTTPX 1.0 design proposal](https://www.encode.io/httpnext/) is now availabl # Collaboration -The repository for this project is currently private. +We are not currently accepting unsolicted pull requests against the 1.0 pre-release branch. We’re looking at creating paid opportunities for working on open source software *which are properly compensated, flexible & well balanced.* -If you're interested in a position working on this project, please send an intro. +If you're interested in a working on this project, please send an intro. --- From f9d5e1204978c0c66666fa169edada1bf719f8ba Mon Sep 17 00:00:00 2001 From: Kim Christie Date: Tue, 16 Sep 2025 22:30:20 +0100 Subject: [PATCH 3/5] Test suite for v1. (#3668) --- .github/workflows/test-suite.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 7fed9368f3..1d9dcd34b3 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -3,9 +3,9 @@ name: Test Suite on: push: - branches: ["dev"] + branches: ["v1"] pull_request: - branches: ["dev", "version-*"] + branches: ["v1"] jobs: tests: From 4acf5c2c37714cc63b5cf71b3e284fca83c90311 Mon Sep 17 00:00:00 2001 From: Kim Christie Date: Thu, 18 Sep 2025 13:15:06 +0100 Subject: [PATCH 4/5] Update FileStream API (#3670) --- src/ahttpx/_content.py | 3 ++- src/ahttpx/_streams.py | 44 +++++++++++++++--------------------------- src/httpx/_content.py | 3 ++- src/httpx/_streams.py | 44 +++++++++++++++--------------------------- tests/test_streams.py | 6 +++--- 5 files changed, 39 insertions(+), 61 deletions(-) diff --git a/src/ahttpx/_content.py b/src/ahttpx/_content.py index e2c4aaa935..45774fbfb8 100644 --- a/src/ahttpx/_content.py +++ b/src/ahttpx/_content.py @@ -178,7 +178,8 @@ def size(self) -> int: return os.path.getsize(self._path) def encode(self) -> Stream: - return FileStream(self._path) + fin = open(self._path, 'rb') + return FileStream(self._path, fin) def content_type(self) -> str: _, ext = os.path.splitext(self._path) diff --git a/src/ahttpx/_streams.py b/src/ahttpx/_streams.py index d5e5ad0d4c..3cf779898c 100644 --- a/src/ahttpx/_streams.py +++ b/src/ahttpx/_streams.py @@ -1,4 +1,5 @@ import io +import typing import types import os @@ -75,32 +76,19 @@ def output_bytes(self) -> bytes: class FileStream(Stream): - def __init__(self, path): + def __init__(self, path: str, fin: typing.Any) -> None: self._path = path - self._fileobj = None - self._size = None + self._fin = fin async def read(self, size: int=-1) -> bytes: - if self._fileobj is None: - raise ValueError('I/O operation on unopened file') - return self._fileobj.read(size) - - async def open(self): - self._fileobj = open(self._path, 'rb') - self._size = os.path.getsize(self._path) - return self + return self._fin.read(size) async def close(self) -> None: - if self._fileobj is not None: - self._fileobj.close() + self._fin.close() @property def size(self) -> int | None: - return self._size - - async def __aenter__(self): - await self.open() - return self + return os.path.getsize(self._path) class HTTPStream(Stream): @@ -152,7 +140,7 @@ def __init__(self, form: list[tuple[str, str]], files: list[tuple[str, str]], bo # Mutable state... self._form_progress = list(self._form) self._files_progress = list(self._files) - self._filestream: FileStream | None = None + self._fin: typing.Any = None self._complete = False self._buffer = io.BytesIO() @@ -196,10 +184,10 @@ async def _read_next_section(self) -> bytes: f"\r\n" f"{value}\r\n" ).encode("utf-8") - elif self._files_progress and self._filestream is None: + elif self._files_progress and self._fin is None: # return start of a file item key, value = self._files_progress.pop(0) - self._filestream = await FileStream(value).open() + self._fin = open(value, 'rb') name = key.translate({10: "%0A", 13: "%0D", 34: "%22"}) filename = os.path.basename(value) return ( @@ -207,15 +195,15 @@ async def _read_next_section(self) -> bytes: f'Content-Disposition: form-data; name="{name}"; filename="{filename}"\r\n' f"\r\n" ).encode("utf-8") - elif self._filestream is not None: - chunk = await self._filestream.read(64*1024) + elif self._fin is not None: + chunk = await self._fin.read(64*1024) if chunk != b'': # return some bytes from file return chunk else: # return end of file item - await self._filestream.close() - self._filestream = None + await self._fin.close() + self._fin = None return b"\r\n" elif not self._complete: # return final section of multipart @@ -225,9 +213,9 @@ async def _read_next_section(self) -> bytes: return b"" async def close(self) -> None: - if self._filestream is not None: - await self._filestream.close() - self._filestream = None + if self._fin is not None: + await self._fin.close() + self._fin = None self._buffer.close() @property diff --git a/src/httpx/_content.py b/src/httpx/_content.py index e2c4aaa935..45774fbfb8 100644 --- a/src/httpx/_content.py +++ b/src/httpx/_content.py @@ -178,7 +178,8 @@ def size(self) -> int: return os.path.getsize(self._path) def encode(self) -> Stream: - return FileStream(self._path) + fin = open(self._path, 'rb') + return FileStream(self._path, fin) def content_type(self) -> str: _, ext = os.path.splitext(self._path) diff --git a/src/httpx/_streams.py b/src/httpx/_streams.py index 1fc6cde073..c88a63f6f8 100644 --- a/src/httpx/_streams.py +++ b/src/httpx/_streams.py @@ -1,4 +1,5 @@ import io +import typing import types import os @@ -75,32 +76,19 @@ def output_bytes(self) -> bytes: class FileStream(Stream): - def __init__(self, path): + def __init__(self, path: str, fin: typing.Any) -> None: self._path = path - self._fileobj = None - self._size = None + self._fin = fin def read(self, size: int=-1) -> bytes: - if self._fileobj is None: - raise ValueError('I/O operation on unopened file') - return self._fileobj.read(size) - - def open(self): - self._fileobj = open(self._path, 'rb') - self._size = os.path.getsize(self._path) - return self + return self._fin.read(size) def close(self) -> None: - if self._fileobj is not None: - self._fileobj.close() + self._fin.close() @property def size(self) -> int | None: - return self._size - - def __enter__(self): - self.open() - return self + return os.path.getsize(self._path) class HTTPStream(Stream): @@ -152,7 +140,7 @@ def __init__(self, form: list[tuple[str, str]], files: list[tuple[str, str]], bo # Mutable state... self._form_progress = list(self._form) self._files_progress = list(self._files) - self._filestream: FileStream | None = None + self._fin: typing.Any = None self._complete = False self._buffer = io.BytesIO() @@ -196,10 +184,10 @@ def _read_next_section(self) -> bytes: f"\r\n" f"{value}\r\n" ).encode("utf-8") - elif self._files_progress and self._filestream is None: + elif self._files_progress and self._fin is None: # return start of a file item key, value = self._files_progress.pop(0) - self._filestream = FileStream(value).open() + self._fin = open(value, 'rb') name = key.translate({10: "%0A", 13: "%0D", 34: "%22"}) filename = os.path.basename(value) return ( @@ -207,15 +195,15 @@ def _read_next_section(self) -> bytes: f'Content-Disposition: form-data; name="{name}"; filename="{filename}"\r\n' f"\r\n" ).encode("utf-8") - elif self._filestream is not None: - chunk = self._filestream.read(64*1024) + elif self._fin is not None: + chunk = self._fin.read(64*1024) if chunk != b'': # return some bytes from file return chunk else: # return end of file item - self._filestream.close() - self._filestream = None + self._fin.close() + self._fin = None return b"\r\n" elif not self._complete: # return final section of multipart @@ -225,9 +213,9 @@ def _read_next_section(self) -> bytes: return b"" def close(self) -> None: - if self._filestream is not None: - self._filestream.close() - self._filestream = None + if self._fin is not None: + self._fin.close() + self._fin = None self._buffer.close() @property diff --git a/tests/test_streams.py b/tests/test_streams.py index 8053761056..70c7244099 100644 --- a/tests/test_streams.py +++ b/tests/test_streams.py @@ -30,17 +30,17 @@ def test_filestream(tmp_path): path = tmp_path / "example.txt" path.write_bytes(b"hello world") - with httpx.FileStream(path) as s: + with httpx.File(path).encode() as s: assert s.size == 11 assert s.read() == b'hello world' - with httpx.FileStream(path) as s: + with httpx.File(path).encode() as s: assert s.read(5) == b'hello' assert s.read(5) == b' worl' assert s.read(5) == b'd' assert s.read(5) == b'' - with httpx.FileStream(path) as s: + with httpx.File(path).encode() as s: assert s.read(5) == b'hello' From 5e054470f1baec3e1feeac89554e48218e35b5e7 Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Thu, 18 Sep 2025 13:24:02 +0100 Subject: [PATCH 5/5] Drop __title__ and __version__ --- pyproject.toml | 7 ++----- src/ahttpx/__init__.py | 3 --- src/ahttpx/__version__.py | 2 -- src/httpx/__init__.py | 3 --- src/httpx/__version__.py | 2 -- 5 files changed, 2 insertions(+), 15 deletions(-) delete mode 100644 src/ahttpx/__version__.py delete mode 100644 src/httpx/__version__.py diff --git a/pyproject.toml b/pyproject.toml index e708b5d962..dec723e8bd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,8 @@ build-backend = "hatchling.build" [project] name = "httpx" description = "HTTP, for Python." -requires-python = ">=3.10" +version = "1.0.dev3" +requires-python = ">=3.11" authors = [ { name = "Tom Christie", email = "tom@tomchristie.com" }, ] @@ -24,7 +25,3 @@ classifiers = [ dependencies = [ "certifi", ] -dynamic = ["version"] - -[tool.hatch.version] -path = "src/httpx/__version__.py" diff --git a/src/ahttpx/__init__.py b/src/ahttpx/__init__.py index 9e589ab6cd..2a2e58acd8 100644 --- a/src/ahttpx/__init__.py +++ b/src/ahttpx/__init__.py @@ -1,4 +1,3 @@ -from .__version__ import __title__, __version__ from ._client import * # Client from ._content import * # Content, File, Files, Form, HTML, JSON, MultiPart, Text from ._headers import * # Headers @@ -15,8 +14,6 @@ __all__ = [ - "__title__", - "__version__", "ByteStream", "Client", "Connection", diff --git a/src/ahttpx/__version__.py b/src/ahttpx/__version__.py deleted file mode 100644 index 309fcb32b6..0000000000 --- a/src/ahttpx/__version__.py +++ /dev/null @@ -1,2 +0,0 @@ -__title__ = "ahttpx" -__version__ = "1.0.dev3" \ No newline at end of file diff --git a/src/httpx/__init__.py b/src/httpx/__init__.py index 9e589ab6cd..2a2e58acd8 100644 --- a/src/httpx/__init__.py +++ b/src/httpx/__init__.py @@ -1,4 +1,3 @@ -from .__version__ import __title__, __version__ from ._client import * # Client from ._content import * # Content, File, Files, Form, HTML, JSON, MultiPart, Text from ._headers import * # Headers @@ -15,8 +14,6 @@ __all__ = [ - "__title__", - "__version__", "ByteStream", "Client", "Connection", diff --git a/src/httpx/__version__.py b/src/httpx/__version__.py deleted file mode 100644 index ba1c14e7ec..0000000000 --- a/src/httpx/__version__.py +++ /dev/null @@ -1,2 +0,0 @@ -__title__ = "httpx" -__version__ = "1.0.dev3" \ No newline at end of file