mirror of
https://github.com/frappe/gunicorn.git
synced 2026-07-02 10:41:30 +08:00
Address PR #3468 review feedback
- Guard early_hints callback against calls after response started - Fix :authority precedence over Host header per RFC 9113 section 8.3.1 - Add nginx early_hints documentation link - Use standard port 443 in curl examples
This commit is contained in:
parent
ed94da449c
commit
66d0880c74
@ -225,7 +225,7 @@ server {
|
|||||||
|
|
||||||
!!! note
|
!!! note
|
||||||
For nginx to forward 103 Early Hints from upstream, you need nginx 1.29+
|
For nginx to forward 103 Early Hints from upstream, you need nginx 1.29+
|
||||||
and the `early_hints` directive.
|
and the [`early_hints`](https://nginx.org/en/docs/http/ngx_http_core_module.html#early_hints) directive.
|
||||||
|
|
||||||
### Direct TLS Termination
|
### Direct TLS Termination
|
||||||
|
|
||||||
@ -312,10 +312,10 @@ http2_max_concurrent_streams = 200 # Increase from default 100
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Check HTTP/2 support
|
# Check HTTP/2 support
|
||||||
curl -v --http2 https://localhost:8443/
|
curl -v --http2 https://localhost:443/
|
||||||
|
|
||||||
# Force HTTP/2
|
# Force HTTP/2
|
||||||
curl --http2-prior-knowledge https://localhost:8443/
|
curl --http2-prior-knowledge https://localhost:443/
|
||||||
```
|
```
|
||||||
|
|
||||||
### Using Python
|
### Using Python
|
||||||
|
|||||||
@ -107,7 +107,7 @@ def proxy_environ(req):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _make_early_hints_callback(req, sock):
|
def _make_early_hints_callback(req, sock, resp):
|
||||||
"""Create a wsgi.early_hints callback for sending 103 Early Hints.
|
"""Create a wsgi.early_hints callback for sending 103 Early Hints.
|
||||||
|
|
||||||
This allows WSGI applications to send 103 Early Hints responses
|
This allows WSGI applications to send 103 Early Hints responses
|
||||||
@ -116,6 +116,7 @@ def _make_early_hints_callback(req, sock):
|
|||||||
Args:
|
Args:
|
||||||
req: The request object
|
req: The request object
|
||||||
sock: The socket to write to
|
sock: The socket to write to
|
||||||
|
resp: The Response object to check if headers have been sent
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A callback function that accepts a list of (name, value) header tuples
|
A callback function that accepts a list of (name, value) header tuples
|
||||||
@ -125,6 +126,7 @@ def _make_early_hints_callback(req, sock):
|
|||||||
- Early hints are only sent for HTTP/1.1 or later clients
|
- Early hints are only sent for HTTP/1.1 or later clients
|
||||||
- HTTP/1.0 clients will silently ignore the callback
|
- HTTP/1.0 clients will silently ignore the callback
|
||||||
- Multiple calls are allowed (sending multiple 103 responses)
|
- Multiple calls are allowed (sending multiple 103 responses)
|
||||||
|
- Calls after response has started are silently ignored
|
||||||
"""
|
"""
|
||||||
def send_early_hints(headers):
|
def send_early_hints(headers):
|
||||||
"""Send 103 Early Hints response.
|
"""Send 103 Early Hints response.
|
||||||
@ -133,6 +135,10 @@ def _make_early_hints_callback(req, sock):
|
|||||||
headers: List of (name, value) header tuples, typically Link headers
|
headers: List of (name, value) header tuples, typically Link headers
|
||||||
Example: [('Link', '</style.css>; rel=preload; as=style')]
|
Example: [('Link', '</style.css>; rel=preload; as=style')]
|
||||||
"""
|
"""
|
||||||
|
# Don't send after response has started - would break framing
|
||||||
|
if resp.headers_sent:
|
||||||
|
return
|
||||||
|
|
||||||
# Don't send to HTTP/1.0 clients - they don't support 1xx responses
|
# Don't send to HTTP/1.0 clients - they don't support 1xx responses
|
||||||
if req.version < (1, 1):
|
if req.version < (1, 1):
|
||||||
return
|
return
|
||||||
@ -242,7 +248,7 @@ def create(req, sock, client, server, cfg):
|
|||||||
environ.update(proxy_environ(req))
|
environ.update(proxy_environ(req))
|
||||||
|
|
||||||
# Add wsgi.early_hints callback for sending 103 Early Hints
|
# Add wsgi.early_hints callback for sending 103 Early Hints
|
||||||
environ['wsgi.early_hints'] = _make_early_hints_callback(req, sock)
|
environ['wsgi.early_hints'] = _make_early_hints_callback(req, sock, resp)
|
||||||
|
|
||||||
return resp, environ
|
return resp, environ
|
||||||
|
|
||||||
|
|||||||
@ -133,8 +133,10 @@ class HTTP2Request:
|
|||||||
# Convert to uppercase for WSGI compatibility
|
# Convert to uppercase for WSGI compatibility
|
||||||
self.headers.append((name.upper(), value))
|
self.headers.append((name.upper(), value))
|
||||||
|
|
||||||
# Add Host header if not present (from :authority)
|
# Set Host header from :authority (RFC 9113 section 8.3.1)
|
||||||
if authority and not any(h[0] == 'HOST' for h in self.headers):
|
# :authority MUST take precedence over Host header
|
||||||
|
if authority:
|
||||||
|
self.headers = [(n, v) for n, v in self.headers if n != 'HOST']
|
||||||
self.headers.append(('HOST', authority))
|
self.headers.append(('HOST', authority))
|
||||||
|
|
||||||
# Trailers (if any)
|
# Trailers (if any)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user