refactor: resolve once per HTTPS connection, not per inner request
tracker-policy-pr / check-pr (pull_request) Successful in 1m18s
test / integration-docker (pull_request) Successful in 1m31s
lint / lint (push) Successful in 2m55s
test / integration-firecracker (pull_request) Successful in 4m17s
test / unit (pull_request) Failing after 13m18s
test / coverage (pull_request) Has been skipped
test / publish-infra (pull_request) Has been skipped
tracker-policy-pr / check-pr (pull_request) Successful in 1m18s
test / integration-docker (pull_request) Successful in 1m31s
lint / lint (push) Successful in 2m55s
test / integration-firecracker (pull_request) Successful in 4m17s
test / unit (pull_request) Failing after 13m18s
test / coverage (pull_request) Has been skipped
test / publish-infra (pull_request) Has been skipped
http_connect now stashes the resolved (config, slug, env) under _FLOW_CTX_KEY after resolving, so request() can reuse it without a second orchestrator round-trip. Plain-HTTP flows (no prior CONNECT stash) still resolve in request() as before.
This commit is contained in:
@@ -324,12 +324,13 @@ class EgressAddon:
|
|||||||
if conn_id:
|
if conn_id:
|
||||||
self._conn_tokens[conn_id] = token
|
self._conn_tokens[conn_id] = token
|
||||||
|
|
||||||
# Resolve once to check if this host is a dlp: false route. For
|
# Resolve the policy here for all HTTPS connections and stash it so
|
||||||
# non-passthrough hosts nothing changes — the allowlist check happens
|
# request() reuses it without a second orchestrator round-trip. For
|
||||||
# in request() as normal. For passthrough hosts we must decide here
|
# passthrough hosts we also make the allowlist decision now because
|
||||||
# because the inner requests never reach request() after the bypass.
|
# inner requests never reach request() after the TLS bypass.
|
||||||
client_ip = conn.peername[0] if conn is not None and conn.peername else ""
|
client_ip = conn.peername[0] if conn is not None and conn.peername else ""
|
||||||
config, _slug, env = resolve_client_context(self._resolver, client_ip, token)
|
config, slug, env = resolve_client_context(self._resolver, client_ip, token)
|
||||||
|
self._stash_flow_ctx(flow, config, slug, env)
|
||||||
host = flow.request.pretty_host
|
host = flow.request.pretty_host
|
||||||
route = match_route(config.routes, host)
|
route = match_route(config.routes, host)
|
||||||
if route is not None and route.dlp_passthrough:
|
if route is not None and route.dlp_passthrough:
|
||||||
@@ -361,10 +362,16 @@ class EgressAddon:
|
|||||||
async def request(self, flow: http.HTTPFlow) -> None:
|
async def request(self, flow: http.HTTPFlow) -> None:
|
||||||
request_path, _, query = flow.request.path.partition("?")
|
request_path, _, query = flow.request.path.partition("?")
|
||||||
|
|
||||||
config, slug, env = self._resolve_flow(flow)
|
# Reuse the context stashed by http_connect for HTTPS flows (one
|
||||||
# Stash for the response / websocket hooks so their DLP scans reuse this
|
# orchestrator round-trip per connection). Plain-HTTP flows have no
|
||||||
# bottle's resolved policy (one /resolve per flow — see _flow_ctx).
|
# prior CONNECT stash, so resolve now and stash for response/websocket.
|
||||||
self._stash_flow_ctx(flow, config, slug, env)
|
meta = getattr(flow, "metadata", None)
|
||||||
|
if isinstance(meta, dict) and _FLOW_CTX_KEY in meta:
|
||||||
|
config, slug, env = meta[_FLOW_CTX_KEY]
|
||||||
|
self._request_token(flow) # strip identity headers; token already resolved
|
||||||
|
else:
|
||||||
|
config, slug, env = self._resolve_flow(flow)
|
||||||
|
self._stash_flow_ctx(flow, config, slug, env)
|
||||||
|
|
||||||
# Introspection ("_egress.local/allowlist") reports the calling bottle's
|
# Introspection ("_egress.local/allowlist") reports the calling bottle's
|
||||||
# own resolved routes — served after resolution so it reflects this
|
# own resolved routes — served after resolution so it reflects this
|
||||||
|
|||||||
Reference in New Issue
Block a user