Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions sdk-python/src/apip_sdk_core/policy/v1alpha2/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
AuthContext,
Body,
BodyProcessingMode,
DownstreamContext,
ExecutionContext,
ExecutionPhase,
HeaderProcessingMode,
Expand All @@ -58,12 +59,14 @@
ResponseStreamContext,
SharedContext,
StreamBody,
UpstreamContext,
)

__all__ = [
"AuthContext",
"Body",
"BodyProcessingMode",
"DownstreamContext",
"DownstreamResponseHeaderModifications",
"DownstreamResponseModifications",
"DropHeaderAction",
Expand Down Expand Up @@ -98,6 +101,7 @@
"StreamingResponseAction",
"StreamingResponsePolicy",
"TerminateResponseChunk",
"UpstreamContext",
"UpstreamRequestHeaderModifications",
"UpstreamRequestModifications",
]
40 changes: 40 additions & 0 deletions sdk-python/src/apip_sdk_core/policy/v1alpha2/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,37 @@ class StreamBody:
index: int = 0


@dataclass(slots=True)
class DownstreamContext:
"""Immutable snapshot of the original client request headers, captured
before any policy mutation.

``None`` on older gateways that predate this field. Policies MUST treat a
``None`` ``downstream`` (or a ``None`` ``headers``) as "not available" and
fall back to legacy validation against the mutable headers.

``headers`` is ``Headers | None`` (defaulting to ``None``) to mirror the Go
SDK's nilable ``Headers *Headers``: the kernel leaves it ``None`` when no
snapshot is available, rather than substituting an empty ``Headers()`` that
a policy could not distinguish from "the client sent no headers".
"""

headers: Headers | None = None


@dataclass(slots=True)
class UpstreamContext:
"""Immutable snapshot of the original upstream response headers, captured
before any policy mutation. ``None`` on older gateways; see
:class:`DownstreamContext` for the backward-compat contract.

``headers`` is ``Headers | None`` (defaulting to ``None``), mirroring the Go
SDK's nilable ``Headers *Headers`` — see :class:`DownstreamContext`.
"""

headers: Headers | None = None

Comment thread
coderabbitai[bot] marked this conversation as resolved.

@dataclass(slots=True)
class RequestHeaderContext:
shared: SharedContext
Expand All @@ -138,6 +169,7 @@ class RequestHeaderContext:
authority: str = ""
scheme: str = ""
vhost: str = ""
downstream: DownstreamContext | None = None


@dataclass(slots=True)
Expand All @@ -150,6 +182,7 @@ class RequestContext:
authority: str = ""
scheme: str = ""
vhost: str = ""
downstream: DownstreamContext | None = None


@dataclass(slots=True)
Expand All @@ -161,6 +194,8 @@ class ResponseHeaderContext:
request_method: str = ""
response_headers: Headers = field(default_factory=Headers)
response_status: int = 200
downstream: DownstreamContext | None = None
upstream: UpstreamContext | None = None


@dataclass(slots=True)
Expand All @@ -173,6 +208,8 @@ class ResponseContext:
response_headers: Headers = field(default_factory=Headers)
response_body: Body | None = None
response_status: int = 200
downstream: DownstreamContext | None = None
upstream: UpstreamContext | None = None


@dataclass(slots=True)
Expand All @@ -184,6 +221,7 @@ class RequestStreamContext:
authority: str = ""
scheme: str = ""
vhost: str = ""
downstream: DownstreamContext | None = None


@dataclass(slots=True)
Expand All @@ -195,6 +233,8 @@ class ResponseStreamContext:
request_method: str = ""
response_headers: Headers = field(default_factory=Headers)
response_status: int = 200
downstream: DownstreamContext | None = None
upstream: UpstreamContext | None = None


@dataclass(slots=True)
Expand Down
59 changes: 59 additions & 0 deletions sdk/core/policy/v1alpha2/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,29 @@ type Body struct {
Present bool
}

// DownstreamContext holds an immutable snapshot of data as received from the
// downstream client, captured before any policy mutation is applied.
//
// Downstream is nil on older gateways that predate this field. Policies MUST
// nil-check before use and fall back to legacy validation.
//
type DownstreamContext struct {
// Headers is the original request headers exactly as received from the
// downstream client, before any policy mutation.
Headers *Headers
}

// UpstreamContext holds an immutable snapshot of data as received from the
// upstream backend, captured before any policy mutation is applied.
//
// Upstream is nil on older gateways that predate this field. Policies MUST
// nil-check before use and fall back to legacy validation.
type UpstreamContext struct {
// Headers is the original response headers exactly as received from the
// upstream backend, before any policy mutation. Read-only.
Headers *Headers
}

// SharedContext contains data shared across request and response phases
type SharedContext struct {
// ProjectID is the project ID which the API is associated with
Expand Down Expand Up @@ -75,6 +98,10 @@ type RequestHeaderContext struct {
Authority string
Scheme string
Vhost string

// Downstream holds the immutable snapshot of the original client request
// headers, captured before any policy mutation. Nil on older gateways.
Downstream *DownstreamContext
}

// RequestContext is passed to RequestPolicy.OnRequestBody.
Expand All @@ -99,6 +126,10 @@ type RequestContext struct {
// used to address the actual upstream (e.g. for request signing) — use
// UpstreamInfo.URL instead.
UpstreamInfo *policyenginev1.UpstreamInfo

// Downstream holds the immutable snapshot of the original client request
// headers, captured before any policy mutation. Nil on older gateways.
Downstream *DownstreamContext
}

// ─── Response-phase contexts ─────────────────────────────────────────────────
Expand All @@ -119,6 +150,14 @@ type ResponseHeaderContext struct {

// Current response status code
ResponseStatus int

// Downstream holds the immutable snapshot of the original client request
// headers, captured before any policy mutation. Nil on older gateways.
Downstream *DownstreamContext

// Upstream holds the immutable snapshot of the original upstream response
// headers, captured before any policy mutation. Nil on older gateways.
Upstream *UpstreamContext
}

// ResponseContext is passed to ResponsePolicy.OnResponseBody.
Expand All @@ -143,6 +182,14 @@ type ResponseContext struct {

// Current response status code
ResponseStatus int

// Downstream holds the immutable snapshot of the original client request
// headers, captured before any policy mutation. Nil on older gateways.
Downstream *DownstreamContext

// Upstream holds the immutable snapshot of the original upstream response
// headers, captured before any policy mutation. Nil on older gateways.
Upstream *UpstreamContext
}

// ─── Streaming contexts ──────────────────────────────────────────────────────
Expand Down Expand Up @@ -180,6 +227,10 @@ type RequestStreamContext struct {
Authority string
Scheme string
Vhost string

// Downstream holds the immutable snapshot of the original client request
// headers, captured before any policy mutation. Nil on older gateways.
Downstream *DownstreamContext
}

// ResponseStreamContext is the per-chunk context passed to StreamingResponseBodyPolicy.
Expand All @@ -199,4 +250,12 @@ type ResponseStreamContext struct {

// Current response status code
ResponseStatus int

// Downstream holds the immutable snapshot of the original client request
// headers, captured before any policy mutation. Nil on older gateways.
Downstream *DownstreamContext

// Upstream holds the immutable snapshot of the original upstream response
// headers, captured before any policy mutation. Nil on older gateways.
Upstream *UpstreamContext
}
Loading