Skip to content

feat: add -L flag for HTTP redirect following - #2

Merged
daniil-brd merged 3 commits into
masterfrom
follow-redirects
Apr 6, 2026
Merged

daniil-brd merged 3 commits into
masterfrom
follow-redirects

Conversation

@vladislavs-brd

Copy link
Copy Markdown
Contributor

Summary

Adds --follow-redirects / -L flag to automatically follow HTTP 3xx redirects, matching curl -L behaviour.

Changes

src/h3/__init__.py

  • Add MAX_REDIRECTS = 10 constant
  • Add urljoin import for relative URL resolution
  • Add -L / --follow-redirects argument to parse_args()
  • Refactor send_request() into a redirect loop:
    • 301 / 302 / 303 → method downgraded to GET, body dropped
    • 307 / 308 → method and body preserved
    • Relative and absolute-path Location values resolved via urljoin
    • Non-https:// redirect targets rejected with an error
    • Loop capped at MAX_REDIRECTS hops
  • Add docstrings to module, Http3ClientError, ProxyBadStatus, create_quic_configuration, send_request

Tests

  • tests/test_follow_redirects.py — 13 tests: no-redirect default, single 301/302/307 follow, relative/absolute location resolution, POST→GET method downgrade, redirect loop guard
  • tests/test_send_request.py — 29 tests: general send_request behaviour, main() arg-parsing, error paths, helper validation functions

CI

  • .github/workflows/ci.yml — flake8 lint + both test suites on Python 3.9 / 3.11 / 3.13
  • .flake8 — per-file ignores for pre-existing style in src/

README

  • Added -L example and a short redirect-following behaviour section

- Add --follow-redirects / -L flag to follow 3xx responses automatically
- 301/302/303: method downgraded to GET, body dropped
- 307/308: method and body preserved
- Relative and absolute-path Location values resolved via urljoin
- Max 10 redirect hops; non-https redirects rejected
- Binary-safe output via sys.stdout.buffer.write

Tests:
- tests/test_follow_redirects.py: 13 tests covering all redirect cases
- tests/test_send_request.py: 29 tests covering general send_request/main behaviour

CI:
- .github/workflows/ci.yml: flake8 lint + tests on Python 3.9/3.11/3.13
- .flake8: config with per-file ignores for pre-existing style in src/
@daniil-brd
daniil-brd merged commit ae8c226 into master Apr 6, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants