Requests — Spec vs Reality
Spec source: README.md
Scope: Source code only — infrastructure config files (Docker, CI/CD, YAML) not analysed
Coverage: ████████░░ 13/16 features fully implemented, 2 partial, 1 missing
Feature Coverage
| Feature | Spec Intent | Code Reality | Status |
|---|---|---|---|
| Keep-Alive & Connection Pooling | Keep-Alive & Connection Pooling | Implemented via urllib3 pool management in adapters.py, with init_poolmanager, proxy_manager_for, and get_connection_... | ✅ Implemented |
| International Domains and URLs | International Domains and URLs | Implements IDNA encoding via _get_idna_encoded_host method in models.py and imports the idna package. | ✅ Implemented |
| Sessions with Cookie Persistence | Sessions with Cookie Persistence | Session class in sessions.py maintains a RequestsCookieJar, with methods to merge and persist cookies across requests. | ✅ Implemented |
| Browser-style TLS/SSL Verification | Browser-style TLS/SSL Verification | Uses cert_verify in adapters.py to set cert_reqs='CERT_REQUIRED' and configure CA certs from certifi or env vars; sup... | ✅ Implemented |
| Basic & Digest Authentication | Basic & Digest Authentication | Provides HTTPBasicAuth, HTTPDigestAuth, and HTTPProxyAuth classes in auth.py with full digest challenge handling. | ✅ Implemented |
| Familiar dict–like Cookies | Familiar dict–like Cookies | RequestsCookieJar inherits from MutableMapping, providing dict-like getitem, setitem, keys, values, items, etc. | ✅ Implemented |
| Automatic Content Decompression and Decoding | Automatic Content Decompression and Decoding | Decompression is handled transparently by urllib3; character decoding is done via the text property and encoding dete... | ✅ Implemented |
| Multi-part File Uploads | Multi-part File Uploads | Implemented via _encode_files static method in models.py, which builds multipart/form-data body from files and data. | ✅ Implemented |
| SOCKS Proxy Support | SOCKS Proxy Support | Provides a fallback SOCKSProxyManager in adapters.py that raises InvalidSchema if urllib3.contrib.socks is unavailabl... | ⚠️ Partial |
| Connection Timeouts | Connection Timeouts | Timeout parameter is passed through to urllib3's urlopen in adapters.py send method. | ✅ Implemented |
| Streaming Downloads | Streaming Downloads | Provides iter_content and iter_lines methods on Response objects (models.py) for streaming download. | ✅ Implemented |
| Automatic honoring of .netrc | Automatic honoring of .netrc | No code evidence found for .netrc reading or usage. | ❌ Not found |
| Chunked HTTP Requests | Chunked HTTP Requests | No explicit chunked transfer encoding support found; redirect handling in sessions.py removes Transfer-Encoding but d... | ⚠️ Partial |
| Automatic Query String Encoding | There’s no need to manually add query strings to your URLs | _encode_params method (models.py) encodes parameters using urlencode with doseq=True; prepare_url incorporates them i... | ✅ Implemented |
| Automatic Form Encoding | no need to form-encode your PUT & POST data | prepare_body in models.py encodes data dicts via _encode_params, and _encode_files handles multipart encoding. | ✅ Implemented |
| JSON Method | use the json method | Response.json() method parses JSON body; request() accepts a json parameter to send JSON data. | ✅ Implemented |
What the code does that the spec never mentioned
These behaviors exist in the codebase but have no entry in any spec document. They represent implicit engineering decisions — security contracts, undocumented constraints, behavioral choices — that the spec author either assumed, forgot, or decided after writing the spec.
1. is_unverifiable always true
MockRequest.is_unverifiable (cookies.py:L80) always returns True, meaning all cookie requests are treated as unverifiable, which may affect cookie acceptance policy for third-party origins.
Evidence: cookies.py:L80
Why it matters: This could silently alter cookie behavior for cross-origin requests, potentially breaking cookie-based authentication or security policies.
2. Proxy-Authorization only for non-HTTPS
rebuild_proxies (sessions.py:L334) only adds Proxy-Authorization header when the scheme is not https, preventing credential leakage on encrypted proxy connections.
Evidence: sessions.py:L334
Why it matters: An intentional security design choice that may surprise developers expecting unconditional proxy auth.
3. set_cookie strips escaped quotes
set_cookie (cookies.py:L229) strips leading and trailing double quotes from cookie values, altering the value stored in the cookiejar.
Evidence: cookies.py:L229
Why it matters: Can silently modify cookie values sent by servers, potentially leading to signature validation failures or data corruption.
4. Redirect strips content headers
In resolve_redirects (sessions.py:L186), for non-307/308 redirects, the Content-Length, Content-Type, and Transfer-Encoding headers are removed, affecting redirect bodies.
Evidence: sessions.py:L186
Why it matters: May cause upstream services to misinterpret redirected requests if they rely on these headers.
5. Auth stripped on port/scheme change
should_strip_auth (sessions.py:L154) strips authentication if the port or scheme changes, even when the host remains the same.
Evidence: sessions.py:L154
Why it matters: Prevents credential reuse across different protocol/port boundaries, but could break redirect flows where auth is expected.
Security Observations
Behaviors with security implications that are not documented in the spec. These are not CVEs — they are undocumented security contracts, auth edge cases, and trust-boundary decisions found directly in the code.
🟡 is_unverifiable always true MEDIUM
MockRequest.is_unverifiable (cookies.py:L80) always returns True, marking all HTTP requests as unverifiable. This affects cookie jar's policy for secure cookies and third-party cookies.
Evidence: cookies.py:L80
Risk: Cookies may be incorrectly handled for secure or third-party origins, potentially weakening cookie security policies (e.g., SameSite enforcement).
🟢 set_cookie strips quotes LOW
set_cookie (cookies.py:L229) removes leading and trailing double quotes from cookie values before storing. This can alter the actual cookie value received from the server.
Evidence: cookies.py:L229
Risk: Cookie values with intentional quotes could be silently modified, causing authentication token mismatches or data corruption in downstream use.
🟢 TLSServer mutual TLS optional LOW
TLSServer (server.py:L139) sets verify_mode to CERT_OPTIONAL for mutual TLS, meaning client certificates are requested but not required.
Evidence: server.py:L139
Risk: In test environments where mutual TLS is expected to be mandatory, optional verification could mask configuration errors.
Gaps and Risks
🔴 Automatic honoring of .netrc HIGH
No code implementation found for reading .netrc files; users expecting automatic credential resolution from .netrc will not get it.
Question for the team: Is .netrc support intentionally omitted or planned for a future release?
🟡 Chunked HTTP Requests MEDIUM
No explicit support for sending chunked transfer encoding; the library relies on urllib3 which may support it, but it is not exposed or documented.
Question for the team: Does the library support sending chunked request bodies, and if so, how should users enable it?
🟢 SOCKS Proxy Support LOW
SOCKS support is conditional on urllib3.contrib.socks being importable; without it, SOCKS proxies raise InvalidSchema.
Question for the team: Should SOCKS support be documented as optional and require an extra dependency?
Questions for the Engineering Team
- Is .netrc support intentionally absent? If not, what is the preferred mechanism for automatic credential resolution?
- How should users send chunked HTTP request bodies? Does the library support it through urllib3?
- What is the rationale behind MockRequest.is_unverifiable always returning True? Could this be changed to reflect actual request verifiability?
- Why does set_cookie strip escaped quotes from cookie values? Is this behavior documented?
- Are there any plans to make SOCKS proxy support a default dependency or to document its optional nature more clearly?
Generated by Verifiably — every finding is grounded in file:line evidence from the codebase, not training data.