geventhttpclient 2.5.1__tar.gz → 2.6.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- geventhttpclient-2.6.1/.github/workflows/publish.yml +110 -0
- geventhttpclient-2.6.1/.github/workflows/test.yml +76 -0
- geventhttpclient-2.6.1/.gitignore +20 -0
- geventhttpclient-2.6.1/.gitmodules +3 -0
- geventhttpclient-2.6.1/.pre-commit-config.yaml +48 -0
- geventhttpclient-2.6.1/CHANGELOG.md +161 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/MANIFEST.in +3 -2
- geventhttpclient-2.6.1/PKG-INFO +373 -0
- geventhttpclient-2.6.1/README.md +336 -0
- geventhttpclient-2.6.1/RELEASING.md +65 -0
- geventhttpclient-2.6.1/SECURITY.md +18 -0
- geventhttpclient-2.6.1/benchmarks/README.md +79 -0
- geventhttpclient-2.6.1/benchmarks/benchmark.py +162 -0
- geventhttpclient-2.6.1/benchmarks/geventhttpclient_bench.py +36 -0
- geventhttpclient-2.6.1/benchmarks/httplib2_patched_bench.py +40 -0
- geventhttpclient-2.6.1/benchmarks/httpx_async_bench.py +44 -0
- geventhttpclient-2.6.1/benchmarks/httpx_bench.py +36 -0
- geventhttpclient-2.6.1/benchmarks/requests_bench.py +29 -0
- geventhttpclient-2.6.1/benchmarks/urllib3_bench.py +29 -0
- geventhttpclient-2.6.1/examples/download.py +23 -0
- geventhttpclient-2.6.1/examples/download_raw.py +27 -0
- geventhttpclient-2.6.1/examples/facebook.py +50 -0
- geventhttpclient-2.6.1/examples/httplib2_patched.py +26 -0
- geventhttpclient-2.6.1/examples/oauth2.py +54 -0
- geventhttpclient-2.6.1/examples/urllib_patched.py +12 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/ext/_parser.c +3 -31
- geventhttpclient-2.6.1/llhttp/.gitignore +1 -0
- geventhttpclient-2.6.1/llhttp/CMakeLists.txt +135 -0
- geventhttpclient-2.6.1/llhttp/LICENSE +22 -0
- geventhttpclient-2.6.1/llhttp/README.md +518 -0
- geventhttpclient-2.6.1/llhttp/cmake/llhttpConfig.cmake.in +19 -0
- geventhttpclient-2.6.1/llhttp/common.gypi +46 -0
- geventhttpclient-2.6.1/llhttp/libllhttp.pc.in +10 -0
- geventhttpclient-2.6.1/llhttp/llhttp.gyp +22 -0
- geventhttpclient-2.6.1/pyproject.toml +144 -0
- geventhttpclient-2.6.1/src/geventhttpclient/__init__.py +33 -0
- geventhttpclient-2.6.1/src/geventhttpclient/_parser.pyi +12 -0
- geventhttpclient-2.6.1/src/geventhttpclient/_version.py +24 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/api.py +13 -8
- geventhttpclient-2.6.1/src/geventhttpclient/auth.py +92 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/client.py +97 -33
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/connectionpool.py +37 -20
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/header.py +143 -65
- geventhttpclient-2.6.1/src/geventhttpclient/httplib.py +358 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/httplib2.py +19 -8
- geventhttpclient-2.6.1/src/geventhttpclient/httpx.py +539 -0
- geventhttpclient-2.6.1/src/geventhttpclient/py.typed +0 -0
- geventhttpclient-2.6.1/src/geventhttpclient/requests.py +521 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/response.py +52 -10
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient/url.py +160 -24
- geventhttpclient-2.6.1/src/geventhttpclient/useragent.py +1000 -0
- geventhttpclient-2.6.1/src/geventhttpclient.egg-info/PKG-INFO +373 -0
- geventhttpclient-2.6.1/src/geventhttpclient.egg-info/SOURCES.txt +91 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient.egg-info/requires.txt +1 -10
- geventhttpclient-2.6.1/src/geventhttpclient.egg-info/scm_file_list.json +87 -0
- geventhttpclient-2.6.1/src/geventhttpclient.egg-info/scm_version.json +8 -0
- geventhttpclient-2.6.1/tests/__init__.py +2 -0
- geventhttpclient-2.6.1/tests/common.py +86 -0
- geventhttpclient-2.6.1/tests/conftest.py +17 -0
- geventhttpclient-2.6.1/tests/gevent_only/__init__.py +0 -0
- geventhttpclient-2.6.1/tests/gevent_only/conftest.py +7 -0
- geventhttpclient-2.6.1/tests/gevent_only/test_httplib2.py +31 -0
- geventhttpclient-2.6.1/tests/gevent_only/test_httplib2_compat.py +133 -0
- geventhttpclient-2.6.1/tests/gevent_only/test_proxy.py +75 -0
- geventhttpclient-2.6.1/tests/gevent_only/test_ssl.py +43 -0
- geventhttpclient-2.6.1/tests/oncert.pem +20 -0
- geventhttpclient-2.6.1/tests/server.crt +22 -0
- geventhttpclient-2.6.1/tests/server.key +28 -0
- geventhttpclient-2.6.1/tests/test_auth.py +93 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_client.py +178 -1
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_headers.py +83 -0
- geventhttpclient-2.6.1/tests/test_httplib.py +141 -0
- geventhttpclient-2.6.1/tests/test_httpx.py +176 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_keep_alive.py +2 -6
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_parser.py +17 -0
- geventhttpclient-2.6.1/tests/test_requests.py +536 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_ssl.py +170 -1
- geventhttpclient-2.6.1/tests/test_url.py +361 -0
- geventhttpclient-2.6.1/tests/test_useragent.py +798 -0
- geventhttpclient-2.6.1/uv.lock +950 -0
- geventhttpclient-2.5.1/PKG-INFO +0 -296
- geventhttpclient-2.5.1/README.md +0 -255
- geventhttpclient-2.5.1/ext/Python_compat.h +0 -5
- geventhttpclient-2.5.1/pyproject.toml +0 -108
- geventhttpclient-2.5.1/src/geventhttpclient/__init__.py +0 -9
- geventhttpclient-2.5.1/src/geventhttpclient/httplib.py +0 -244
- geventhttpclient-2.5.1/src/geventhttpclient/requests.py +0 -250
- geventhttpclient-2.5.1/src/geventhttpclient/useragent.py +0 -699
- geventhttpclient-2.5.1/src/geventhttpclient.egg-info/PKG-INFO +0 -296
- geventhttpclient-2.5.1/src/geventhttpclient.egg-info/SOURCES.txt +0 -40
- geventhttpclient-2.5.1/tests/test_httplib.py +0 -73
- geventhttpclient-2.5.1/tests/test_requests.py +0 -14
- geventhttpclient-2.5.1/tests/test_url.py +0 -173
- geventhttpclient-2.5.1/tests/test_useragent.py +0 -364
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/LICENSE-MIT +0 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/llhttp/LICENSE-MIT +0 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/llhttp/include/llhttp.h +0 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/llhttp/src/api.c +0 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/llhttp/src/http.c +0 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/llhttp/src/llhttp.c +0 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/setup.cfg +0 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/setup.py +0 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient.egg-info/dependency_links.txt +0 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/src/geventhttpclient.egg-info/top_level.txt +0 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_continue.py +0 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_network_failures.py +0 -0
- {geventhttpclient-2.5.1 → geventhttpclient-2.6.1}/tests/test_proxy.py +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
name: Publish
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
release:
|
|
6
|
+
types:
|
|
7
|
+
- published
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
build-wheels:
|
|
11
|
+
name: Build wheels (${{ matrix.label }})
|
|
12
|
+
runs-on: ${{ matrix.os }}
|
|
13
|
+
timeout-minutes: ${{ matrix.timeout || 45 }}
|
|
14
|
+
strategy:
|
|
15
|
+
fail-fast: false
|
|
16
|
+
matrix:
|
|
17
|
+
include:
|
|
18
|
+
- {label: linux-x86_64, os: ubuntu-24.04, archs: x86_64}
|
|
19
|
+
- {label: linux-aarch64, os: ubuntu-24.04-arm, archs: aarch64}
|
|
20
|
+
- {label: linux-ppc64le, os: ubuntu-24.04, archs: ppc64le, skip: "cp3*-musllinux_*", qemu: true, timeout: 60}
|
|
21
|
+
- {label: macos, os: macos-latest}
|
|
22
|
+
- {label: windows-x86, os: windows-latest}
|
|
23
|
+
- {label: windows-arm64, os: windows-11-arm}
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v6
|
|
26
|
+
with:
|
|
27
|
+
fetch-depth: 0
|
|
28
|
+
submodules: recursive
|
|
29
|
+
- uses: actions/setup-python@v6
|
|
30
|
+
# Host interpreter only: cibuildwheel downloads its own CPython
|
|
31
|
+
# 3.11-3.15 builds for the wheels. setup-python lags brand-new
|
|
32
|
+
# CPython releases, so this stays on the newest available image.
|
|
33
|
+
with:
|
|
34
|
+
python-version: '3.14'
|
|
35
|
+
- uses: docker/setup-qemu-action@v3
|
|
36
|
+
if: ${{ matrix.qemu }}
|
|
37
|
+
name: Set up QEMU
|
|
38
|
+
- name: Install uv
|
|
39
|
+
uses: astral-sh/setup-uv@v10.2.0
|
|
40
|
+
- run: |
|
|
41
|
+
args=(--output-dir wheelhouse)
|
|
42
|
+
if [ -n "${{ matrix.archs }}" ]; then
|
|
43
|
+
args+=(--archs "${{ matrix.archs }}")
|
|
44
|
+
fi
|
|
45
|
+
if [ -n "${{ matrix.skip }}" ]; then
|
|
46
|
+
export CIBW_SKIP="${{ matrix.skip }}"
|
|
47
|
+
fi
|
|
48
|
+
uvx cibuildwheel==4.2.1 "${args[@]}"
|
|
49
|
+
shell: bash
|
|
50
|
+
name: Run build wheel
|
|
51
|
+
- uses: actions/upload-artifact@v4
|
|
52
|
+
with:
|
|
53
|
+
name: dist-wheels-${{ matrix.label }}
|
|
54
|
+
path: ./wheelhouse/*.whl
|
|
55
|
+
if-no-files-found: error
|
|
56
|
+
|
|
57
|
+
build-sdist:
|
|
58
|
+
name: Build source distribution
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@v6
|
|
62
|
+
with:
|
|
63
|
+
fetch-depth: 0
|
|
64
|
+
submodules: recursive
|
|
65
|
+
- name: Install uv
|
|
66
|
+
uses: astral-sh/setup-uv@v10.2.0
|
|
67
|
+
- run: uv build --sdist
|
|
68
|
+
name: Build source tarball
|
|
69
|
+
- name: Refuse to publish unless the sdist version matches the ref name
|
|
70
|
+
run: |
|
|
71
|
+
test "$(ls dist/*.tar.gz | wc -l)" = 1
|
|
72
|
+
test "geventhttpclient-${GITHUB_REF_NAME}.tar.gz" = "$(basename dist/*.tar.gz)"
|
|
73
|
+
- uses: actions/upload-artifact@v4
|
|
74
|
+
with:
|
|
75
|
+
name: dist-source
|
|
76
|
+
path: dist/*.tar.gz
|
|
77
|
+
if-no-files-found: error
|
|
78
|
+
|
|
79
|
+
test-publish:
|
|
80
|
+
if: github.repository == 'geventhttpclient/geventhttpclient'
|
|
81
|
+
runs-on: ubuntu-latest
|
|
82
|
+
needs: [build-wheels, build-sdist]
|
|
83
|
+
steps:
|
|
84
|
+
- uses: actions/download-artifact@v4
|
|
85
|
+
with:
|
|
86
|
+
pattern: dist-*
|
|
87
|
+
path: dist
|
|
88
|
+
merge-multiple: true
|
|
89
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
90
|
+
name: Publish package to TestPyPI
|
|
91
|
+
with:
|
|
92
|
+
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
|
|
93
|
+
repository-url: https://test.pypi.org/legacy/
|
|
94
|
+
skip-existing: true
|
|
95
|
+
|
|
96
|
+
publish:
|
|
97
|
+
if: github.repository == 'geventhttpclient/geventhttpclient'
|
|
98
|
+
runs-on: ubuntu-latest
|
|
99
|
+
needs: test-publish
|
|
100
|
+
steps:
|
|
101
|
+
- uses: actions/download-artifact@v4
|
|
102
|
+
with:
|
|
103
|
+
pattern: dist-*
|
|
104
|
+
path: dist
|
|
105
|
+
merge-multiple: true
|
|
106
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
107
|
+
name: Publish package to PyPI
|
|
108
|
+
with:
|
|
109
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
110
|
+
skip-existing: true
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
name: Tests
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
mypy:
|
|
7
|
+
name: mypy
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
steps:
|
|
10
|
+
- uses: actions/checkout@v6
|
|
11
|
+
with:
|
|
12
|
+
fetch-depth: 0
|
|
13
|
+
submodules: recursive
|
|
14
|
+
- name: Install uv
|
|
15
|
+
uses: astral-sh/setup-uv@v10.2.0
|
|
16
|
+
with:
|
|
17
|
+
python-version: '3.12'
|
|
18
|
+
enable-cache: true
|
|
19
|
+
- name: Install project and dependencies
|
|
20
|
+
run: uv sync
|
|
21
|
+
- name: Run mypy
|
|
22
|
+
run: uv run mypy
|
|
23
|
+
|
|
24
|
+
tests:
|
|
25
|
+
name: ${{ matrix.name }}
|
|
26
|
+
runs-on: ${{ matrix.os }}
|
|
27
|
+
|
|
28
|
+
strategy:
|
|
29
|
+
fail-fast: false
|
|
30
|
+
matrix:
|
|
31
|
+
include:
|
|
32
|
+
- {name: Windows, python: '3.15', os: windows-latest}
|
|
33
|
+
# Windows ARM64 disabled: the windows-11-arm runner is chronically
|
|
34
|
+
# flaky (spurious test timeouts and socket permission errors on
|
|
35
|
+
# otherwise green runs). Re-enable once the runner is stable.
|
|
36
|
+
- {name: Mac, python: '3.15', os: macos-latest}
|
|
37
|
+
- {name: '3.15', python: '3.15', os: ubuntu-latest}
|
|
38
|
+
- {name: '3.14', python: '3.14', os: ubuntu-latest}
|
|
39
|
+
- {name: '3.13', python: '3.13', os: ubuntu-latest}
|
|
40
|
+
- {name: '3.12', python: '3.12', os: ubuntu-latest}
|
|
41
|
+
- {name: '3.11', python: '3.11', os: ubuntu-latest}
|
|
42
|
+
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v6
|
|
45
|
+
with:
|
|
46
|
+
fetch-depth: 0
|
|
47
|
+
submodules: recursive
|
|
48
|
+
- name: Install uv
|
|
49
|
+
uses: astral-sh/setup-uv@v10.2.0
|
|
50
|
+
with:
|
|
51
|
+
python-version: ${{ matrix.python }}
|
|
52
|
+
enable-cache: true
|
|
53
|
+
- name: Install project and dependencies
|
|
54
|
+
run: uv sync
|
|
55
|
+
- name: Run tests
|
|
56
|
+
run: uv run pytest
|
|
57
|
+
|
|
58
|
+
tests-nongevent:
|
|
59
|
+
name: non-gevent (3.15)
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
steps:
|
|
62
|
+
- uses: actions/checkout@v6
|
|
63
|
+
with:
|
|
64
|
+
fetch-depth: 0
|
|
65
|
+
submodules: recursive
|
|
66
|
+
- name: Install uv
|
|
67
|
+
uses: astral-sh/setup-uv@v10.2.0
|
|
68
|
+
with:
|
|
69
|
+
python-version: '3.15'
|
|
70
|
+
enable-cache: true
|
|
71
|
+
- name: Install project and dependencies
|
|
72
|
+
run: uv sync
|
|
73
|
+
- name: Run tests without monkey patching
|
|
74
|
+
env:
|
|
75
|
+
NON_GEVENT: '1'
|
|
76
|
+
run: uv run pytest
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
3
|
+
rev: v6.0.0
|
|
4
|
+
hooks:
|
|
5
|
+
- id: end-of-file-fixer
|
|
6
|
+
- id: trailing-whitespace
|
|
7
|
+
- id: debug-statements
|
|
8
|
+
- id: detect-private-key
|
|
9
|
+
exclude: ^tests/(server\.key|oncert\.pem)$
|
|
10
|
+
- id: check-builtin-literals
|
|
11
|
+
- id: check-case-conflict
|
|
12
|
+
- id: check-executables-have-shebangs
|
|
13
|
+
- id: check-json
|
|
14
|
+
- id: check-merge-conflict
|
|
15
|
+
- id: check-symlinks
|
|
16
|
+
- id: check-toml
|
|
17
|
+
- id: check-xml
|
|
18
|
+
- id: check-yaml
|
|
19
|
+
exclude: (.pre-commit-config\.yaml)
|
|
20
|
+
|
|
21
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
22
|
+
rev: v0.16.10
|
|
23
|
+
hooks:
|
|
24
|
+
- id: ruff
|
|
25
|
+
- id: ruff-format
|
|
26
|
+
|
|
27
|
+
- repo: local
|
|
28
|
+
hooks:
|
|
29
|
+
- id: mypy
|
|
30
|
+
name: mypy (via uv)
|
|
31
|
+
entry: uv run mypy
|
|
32
|
+
language: system
|
|
33
|
+
types: [python]
|
|
34
|
+
pass_filenames: false
|
|
35
|
+
files: ^src/
|
|
36
|
+
|
|
37
|
+
- repo: https://github.com/codespell-project/codespell
|
|
38
|
+
rev: v2.4.3
|
|
39
|
+
hooks:
|
|
40
|
+
- id: codespell
|
|
41
|
+
|
|
42
|
+
- repo: https://github.com/rvben/rumdl-pre-commit
|
|
43
|
+
rev: v0.2.78
|
|
44
|
+
hooks:
|
|
45
|
+
- id: rumdl-check
|
|
46
|
+
# llhttp is a git submodule (upstream files). pre-commit never traverses
|
|
47
|
+
# submodules, so this is belt-and-braces for hand-run configs.
|
|
48
|
+
exclude: ^llhttp/
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
API changes, deprecations and notable fixes. CI and packaging noise is
|
|
4
|
+
left out unless it affects users of the package.
|
|
5
|
+
|
|
6
|
+
## 2.6.1 (2026-10-09)
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- Python 3.15 is supported explicitly
|
|
11
|
+
|
|
12
|
+
## 2.6.0 (2026-10-05)
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Type annotations across the package, with a `py.typed` marker
|
|
17
|
+
- Basic auth added: `BasicAuth("user", "pass")`, or the `requests`-style
|
|
18
|
+
`("user", "pass")` tuple, on a `Session` or a single request
|
|
19
|
+
- `geventhttpclient.httpx`, an httpx-compatible client on the same engine
|
|
20
|
+
- Requests compatibility improved: `history`, `elapsed`, `cookies`,
|
|
21
|
+
`links`, `encoding`, `iter_content()`, `iter_lines()`, `json()`,
|
|
22
|
+
`bool()`, `close()` and `raise_for_status` with the response attached
|
|
23
|
+
- `insecure` on `UserAgent`, for TLS targets without a verified chain
|
|
24
|
+
- `CompatRequest` derives from `urllib.request.Request`, so cookie jars
|
|
25
|
+
work without workarounds
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- Header field names and values are `str` instead of `bytes`
|
|
30
|
+
- Multi-value headers send one field line per element (RFC 9110)
|
|
31
|
+
- Redirect resolution follows RFC 3986; other schemes raise
|
|
32
|
+
`UnsupportedRedirectSchemeError`
|
|
33
|
+
- Retries after a transmission error are limited to idempotent methods
|
|
34
|
+
- Empty bodies on POST, PUT and PATCH send `Content-Length: 0`
|
|
35
|
+
- `check_hostname`, `cert_file` and `key_file` are deprecated in favour of
|
|
36
|
+
a custom SSL context; `check_hostname` now defaults to `True`
|
|
37
|
+
- Require `gevent>=25.9`
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- The request head is validated and encoded as latin-1, like
|
|
42
|
+
`http.client`, instead of allowing header smuggling
|
|
43
|
+
- `requests` and `urllib3` work again through the `httplib` shim
|
|
44
|
+
- Error statuses and redirects come through the httplib2 wrapper
|
|
45
|
+
- 307/308 redirects resend the body, and `Authorization` is dropped when
|
|
46
|
+
a redirect leaves the origin
|
|
47
|
+
- `URL.redirect` keeps the base path and query
|
|
48
|
+
- Requests retain semicolon path parameters, including after redirects
|
|
49
|
+
- `follow_redirects=False` is honoured by the `httpx.Client` shortcuts
|
|
50
|
+
|
|
51
|
+
### Removed
|
|
52
|
+
|
|
53
|
+
- `Headers.iteroriginal()` and `Headers.iget()`; use `items()` and
|
|
54
|
+
`getlist()`
|
|
55
|
+
- The unmaintained `oauth2` extra
|
|
56
|
+
|
|
57
|
+
## 2.5.1 (2026-09-30)
|
|
58
|
+
|
|
59
|
+
### Fixed
|
|
60
|
+
|
|
61
|
+
- Requests with `body=None` sent an empty chunked body
|
|
62
|
+
|
|
63
|
+
## 2.5.0 (2026-09-28)
|
|
64
|
+
|
|
65
|
+
### Added
|
|
66
|
+
|
|
67
|
+
- Type annotations for the core modules, checked by `mypy` in CI
|
|
68
|
+
|
|
69
|
+
### Changed
|
|
70
|
+
|
|
71
|
+
- Require Python 3.11 or newer and a working `ssl` module; `urllib3` is
|
|
72
|
+
no longer a dependency
|
|
73
|
+
- `read()` and `readline()` return `bytes` instead of `bytearray`,
|
|
74
|
+
`readline()` on a released response raises `HTTPConnectionClosed`
|
|
75
|
+
- Header fragments decode as latin-1; the previous UTF-8 decoding
|
|
76
|
+
crashed the interpreter on non-UTF-8 header bytes
|
|
77
|
+
|
|
78
|
+
### Fixed
|
|
79
|
+
|
|
80
|
+
- The body parameter of `delete()` and `trace()` works again
|
|
81
|
+
|
|
82
|
+
## 2.4.0 (2026-09-28)
|
|
83
|
+
|
|
84
|
+
### Added
|
|
85
|
+
|
|
86
|
+
- `Expect: 100-continue` handling and interim 1xx responses
|
|
87
|
+
- CONNECT tunneling with Basic proxy authentication via `proxy_user` and
|
|
88
|
+
`proxy_password`
|
|
89
|
+
- Chunked transfer encoding for request bodies, used automatically for
|
|
90
|
+
bodies of unknown length
|
|
91
|
+
- 308 redirects
|
|
92
|
+
|
|
93
|
+
### Changed
|
|
94
|
+
|
|
95
|
+
- The llhttp parser moved to v9.4.3, including the CVE-2024-27982 fix
|
|
96
|
+
|
|
97
|
+
## 2.3.9 (2026-03-03)
|
|
98
|
+
|
|
99
|
+
### Fixed
|
|
100
|
+
|
|
101
|
+
- Stale-connection validation works with the stdlib SSL implementation
|
|
102
|
+
|
|
103
|
+
## 2.3.8 (2026-02-22)
|
|
104
|
+
|
|
105
|
+
### Added
|
|
106
|
+
|
|
107
|
+
- Connection validation before reuse, so pooled connections closed by
|
|
108
|
+
the server are no longer handed out
|
|
109
|
+
|
|
110
|
+
## 2.3.6 (2025-12-07)
|
|
111
|
+
|
|
112
|
+
### Changed
|
|
113
|
+
|
|
114
|
+
- Python 3.13 and 3.14 are supported explicitly
|
|
115
|
+
|
|
116
|
+
## 2.3.5 (2025-10-26)
|
|
117
|
+
|
|
118
|
+
### Fixed
|
|
119
|
+
|
|
120
|
+
- `Headers.extend()` overwrote values of duplicate fields instead of
|
|
121
|
+
appending them
|
|
122
|
+
|
|
123
|
+
## 2.3.4 (2025-06-11)
|
|
124
|
+
|
|
125
|
+
### Fixed
|
|
126
|
+
|
|
127
|
+
- URL quoting for path and query components
|
|
128
|
+
|
|
129
|
+
## 2.3.3 (2024-11-24)
|
|
130
|
+
|
|
131
|
+
### Fixed
|
|
132
|
+
|
|
133
|
+
- `ssl_options` handling in the connection pool
|
|
134
|
+
|
|
135
|
+
## 2.3.1 (2024-04-18)
|
|
136
|
+
|
|
137
|
+
### Fixed
|
|
138
|
+
|
|
139
|
+
- Backwards compatibility with locust after the 2.3.0 restructuring
|
|
140
|
+
|
|
141
|
+
## 2.3.0 (2024-04-18)
|
|
142
|
+
|
|
143
|
+
### Added
|
|
144
|
+
|
|
145
|
+
- A thin `requests` compatibility layer (`geventhttpclient.requests`)
|
|
146
|
+
with a `Session` speaking the requests-style API subset
|
|
147
|
+
|
|
148
|
+
## 2.2.1 (2024-04-16)
|
|
149
|
+
|
|
150
|
+
### Changed
|
|
151
|
+
|
|
152
|
+
- URL parsing is delegated to the standard library
|
|
153
|
+
- `max_retries` and `max_redirects` no longer count the initial attempt
|
|
154
|
+
|
|
155
|
+
## 2.2.0 (2024-04-12)
|
|
156
|
+
|
|
157
|
+
### Fixed
|
|
158
|
+
|
|
159
|
+
- `Headers` preserves the original case even for headers with duplicate
|
|
160
|
+
field names
|
|
161
|
+
- Patching `http.client` worked only partially
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
include src/geventhttpclient/*.py
|
|
2
|
+
include src/geventhttpclient/py.typed
|
|
2
3
|
include ext/*.c
|
|
3
|
-
include
|
|
4
|
-
|
|
4
|
+
recursive-include llhttp *.h *.c LICENSE LICENSE-MIT
|
|
5
|
+
graft tests
|
|
5
6
|
global-exclude __pycache__
|
|
6
7
|
global-exclude *.py[co]
|
|
7
8
|
include pyproject.toml
|