Skip to content

feat(middleware): define HTTP response pre-return interface - #3073

Draft
pimlock wants to merge 9 commits into
2691-middleware-header-authority/pimlockfrom
2691-http-response-interface/pimlock
Draft

feat(middleware): define HTTP response pre-return interface#3073
pimlock wants to merge 9 commits into
2691-middleware-header-authority/pimlockfrom
2691-http-response-interface/pimlock

Conversation

@pimlock

@pimlock pimlock commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

Define the public HTTP_RESPONSE/PRE_RETURN contract without enabling response processing in the proxy. This lets reviewers evaluate the protobuf lifecycle, naming, extensibility, and transport shape independently from the runtime implementation.

The proposed stream begins with a preflight action, uses lockstep pass-through or transform actions for body units, marks the final unit with end_of_stream, and ends with a shared middleware session-end reason plus typed protocol-error detail.

API interaction examples

See HTTP response pre-return middleware API interaction examples for whole-body, streaming, skip, and block-delivery exchanges, failure scenarios, and an illustrative Rust/tonic middleware implementation.

Related Issue

Part of #2691

Changes

  • Add the bidirectional HttpResponsePreReturn.Evaluate service with preflight, body unit, body result, and terminal event messages.
  • Preflight returns skip, inspect, or block_delivery; body results return pass_through or transform. OpenShell tells each stage which body modes it may select and whether it may defer bytes across units.
  • The final body unit carries end_of_stream. Response trailers are deferred from V1 with field numbers reserved.
  • Share MiddlewareSessionEnd and its reason enum across streaming middleware APIs, with disconnects split by direction and typed protocol-error detail.
  • Accept the HTTP_RESPONSE/PRE_RETURN manifest binding and add in-process and remote gRPC stream interfaces.
  • Compile the content-guard example in lint and branch checks.

Breaking changes

WebSocketSessionEndReason and WebSocketSessionEnd are replaced by the shared MiddlewareSessionEndReason and MiddlewareSessionEnd. NORMAL_CLOSE is now NORMAL, UPSTREAM_REJECTED is now UPSTREAM_FAILURE, and PEER_DISCONNECT is split into DOWNSTREAM_DISCONNECT and UPSTREAM_DISCONNECT. Enum numbers are unchanged, so binary wire compatibility is preserved; generated symbols and JSON names change. This lands in the pre-0.1.0 window.

Testing

Checklist

Stack

  1. feat(middleware): broaden HTTP header mutation authority #3072 - shared header mutation authority
  2. feat(middleware): define HTTP response pre-return interface #3073 - response protobuf and transport interface
  3. feat(network): inspect HTTP responses before return #3074 - response runtime, relay integration, and existing example
  4. docs(middleware): document response pre-return workflow #3075 - documentation and middleware guide reorganization

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Sep 1, 2026

Copy link
Copy Markdown

Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually.

Contributors can view more details about this message here.

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
Replace the separate body_end event with HttpResponseBodyUnit.end_of_stream.
Every body-inspecting stage receives exactly one flagged unit, which may be
empty; a zero-byte body is one empty flagged unit and OpenShell never reads
ahead to set the flag.

Defer response trailers from V1 and reserve their field numbers. HTTP/1.0
clients and Content-Length bodies cannot carry trailers and that behavior was
undefined.

Add HttpResponsePreflight.permitted_body_modes, computed once from the
original upstream head so every stage sees the same list, and make an
unlisted selection a failure rather than a downgrade. Add the block_delivery
preflight action as a successful decision enforced regardless of on_error.

Expose Content-Length, Content-Encoding, and Content-Range read-only in
preflight. Cap STREAM_BYTES input units at half of max_payload_bytes and
permit deferring bytes across replacements only for fail_closed bindings,
surfaced as deferral_permitted.

Split PEER_DISCONNECT into DOWNSTREAM_DISCONNECT and UPSTREAM_DISCONNECT and
attribute WebSocket relay failures by direction instead of a generic peer
error. Compile the content-guard example in lint and branch checks so proto
renames cannot break it silently.

BREAKING CHANGE: WebSocketSessionEndReason and WebSocketSessionEnd are
replaced by the shared MiddlewareSessionEndReason and MiddlewareSessionEnd.
NORMAL_CLOSE is now NORMAL, UPSTREAM_REJECTED is now UPSTREAM_FAILURE, and
PEER_DISCONNECT is split into DOWNSTREAM_DISCONNECT and UPSTREAM_DISCONNECT.
Enum numbers are unchanged so binary wire compatibility is preserved;
generated symbols and JSON names change.

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
…tions

Body results may now stop delivery or opt out of inspecting the rest of the
response after a prefix. One HttpResponseBlockDelivery message is shared by
preflight and body results and documents the difference between blocking
before and after head commitment. Drop the field reservations, since nothing
in this contract has shipped, and renumber session_end to close the gap.

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
HttpBodyUnit, HttpBodyPassThrough, HttpBodyTransform, HttpBodySkipRemaining,
and HttpBodyMode carry no response-specific semantics, so name them for reuse
by the streaming request hook. Envelopes, results, preflight, and
block_delivery stay response-specific because commitment semantics differ.

Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com>
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.

1 participant