Enhance ext_proc filter to support MXN streaming (#34942)

This PR is for issue: https://github.com/envoyproxy/envoy/issues/32090.
One of the use case is, like compression by the external processing.

This is to let the ext_proc server be able to buffer M request body
chunks from Envoy first, processing them, then send N chunks back to
Envoy in the STREAMED mode. It also let the server buffer the entire
message, i.e, header, body, trailer, before sending back any response.

The ext_proc MXN streaming works this way:

1) Enable the MXN streaming by configuring the body mode to be
FULL_DUPLEX_STREAMED in the ext_proc filter config.
2) Config the trailer mode to be SEND  in the ext_proc filter config.

With above config, Envoy will send body to the ext_proc server as they
arrival. The server can buffer the entire or partial of the body (M
chunks) then streaming the mutated body(may need to split into N
chunks), back to Envoy.

---------

Signed-off-by: Yanjun Xiang <yanjunxiang@google.com>

Mirrored from https://github.com/envoyproxy/envoy @ 72a20671ae70db520226388bfd351e817393d66e
main
update-envoy[bot] 2 weeks ago
parent 2f2e77908f
commit 6ac3cd177b
  1. 34
      envoy/extensions/filters/http/ext_proc/v3/processing_mode.proto
  2. 28
      envoy/service/ext_proc/v3/external_processor.proto

@ -36,11 +36,12 @@ message ProcessingMode {
// Control how the request and response bodies are handled
// When body mutation by external processor is enabled, ext_proc filter will always remove
// the content length header in three cases below because content length can not be guaranteed
// the content length header in four cases below because content length can not be guaranteed
// to be set correctly:
// 1) STREAMED BodySendMode: header processing completes before body mutation comes back.
// 2) BUFFERED_PARTIAL BodySendMode: body is buffered and could be injected in different phases.
// 3) BUFFERED BodySendMode + SKIP HeaderSendMode: header processing (e.g., update content-length) is skipped.
// 4) FULL_DUPLEX_STREAMED BodySendMode: header processing completes before body mutation comes back.
//
// In Envoy's http1 codec implementation, removing content length will enable chunked transfer
// encoding whenever feasible. The recipient (either client or server) must be able
@ -68,6 +69,37 @@ message ProcessingMode {
// chunk. If the body exceeds the configured buffer limit, then the body contents
// up to the buffer limit will be sent.
BUFFERED_PARTIAL = 3;
// [#not-implemented-hide:]
// Envoy streams the body to the server in pieces as they arrive.
//
// 1) The server may choose to buffer any number chunks of data before processing them.
// After it finishes buffering, the server processes the buffered data. Then it splits the processed
// data into any number of chunks, and streams them back to Envoy one by one.
// The server may continuously do so until the complete body is processed.
// The individual response chunk size is recommended to be no greater than 64K bytes, or
// :ref:`max_receive_message_length <envoy_v3_api_field_config.core.v3.GrpcService.EnvoyGrpc.max_receive_message_length>`
// if EnvoyGrpc is used.
//
// 2) The server may also choose to buffer the entire message, including the headers (if header mode is
// ``SEND``), the entire body, and the trailers (if present), before sending back any response.
// The server response has to maintain the headers-body-trailers ordering.
//
// 3) Note that the server might also choose not to buffer data. That is, upon receiving a
// body request, it could process the data and send back a body response immediately.
//
// In this body mode:
// * The corresponding trailer mode has to be set to ``SEND``.
// * Envoy will send body and trailers (if present) to the server as they arrive.
// Sending the trailers (if present) is to inform the server the complete body arrives.
// In case there are no trailers, then Envoy will set
// :ref:`end_of_stream <envoy_v3_api_field_service.ext_proc.v3.HttpBody.end_of_stream>`
// to true as part of the last body chunk request to notify the server that no other data is to be sent.
// * The server needs to send
// :ref:`StreamedBodyResponse <envoy_v3_api_msg_service.ext_proc.v3.StreamedBodyResponse>`
// to Envoy in the body response.
// * Envoy will stream the body chunks in the responses from the server to the upstream/downstream as they arrive.
FULL_DUPLEX_STREAMED = 4;
}
// How to handle the request header. Default is "SEND".

@ -377,15 +377,39 @@ message HeaderMutation {
repeated string remove_headers = 2;
}
// Replace the entire message body chunk received in the corresponding
// HttpBody message with this new body, or clear the body.
// [#not-implemented-hide:]
// The body response message corresponding to FULL_DUPLEX_STREAMED body mode.
message StreamedBodyResponse {
// The body response chunk that will be passed to the upstream/downstream by Envoy.
bytes body = 1;
// The server sets this flag to true if it has received a body request with
// :ref:`end_of_stream <envoy_v3_api_field_service.ext_proc.v3.HttpBody.end_of_stream>` set to true,
// and this is the last chunk of body responses.
bool end_of_stream = 2;
}
// This message specifies the body mutation the server sends to Envoy.
message BodyMutation {
// The type of mutation for the body.
oneof mutation {
// The entire body to replace.
// Should only be used when the corresponding ``BodySendMode`` in the
// :ref:`processing_mode <envoy_v3_api_field_extensions.filters.http.ext_proc.v3.ExternalProcessor.processing_mode>`
// is not set to ``FULL_DUPLEX_STREAMED``.
bytes body = 1;
// Clear the corresponding body chunk.
// Should only be used when the corresponding ``BodySendMode`` in the
// :ref:`processing_mode <envoy_v3_api_field_extensions.filters.http.ext_proc.v3.ExternalProcessor.processing_mode>`
// is not set to ``FULL_DUPLEX_STREAMED``.
// Clear the corresponding body chunk.
bool clear_body = 2;
// [#not-implemented-hide:]
// Must be used when the corresponding ``BodySendMode`` in the
// :ref:`processing_mode <envoy_v3_api_field_extensions.filters.http.ext_proc.v3.ExternalProcessor.processing_mode>`
// is set to ``FULL_DUPLEX_STREAMED``.
StreamedBodyResponse streamed_response = 3;
}
}

Loading…
Cancel
Save