|
| 1 | +syntax = "proto3"; |
| 2 | + |
| 3 | +package envoy.service.ext_proc.v3; |
| 4 | + |
| 5 | +import "envoy/config/core/v3/base.proto"; |
| 6 | +import "envoy/extensions/filters/http/ext_proc/v3/processing_mode.proto"; |
| 7 | +import "envoy/type/v3/http_status.proto"; |
| 8 | + |
| 9 | +import "google/protobuf/duration.proto"; |
| 10 | +import "google/protobuf/struct.proto"; |
| 11 | + |
| 12 | +import "xds/annotations/v3/status.proto"; |
| 13 | + |
| 14 | +import "udpa/annotations/status.proto"; |
| 15 | +import "validate/validate.proto"; |
| 16 | + |
| 17 | +option java_package = "io.envoyproxy.envoy.service.ext_proc.v3"; |
| 18 | +option java_outer_classname = "ExternalProcessorProto"; |
| 19 | +option java_multiple_files = true; |
| 20 | +option go_package = "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3;ext_procv3"; |
| 21 | +option (udpa.annotations.file_status).package_version_status = ACTIVE; |
| 22 | +option (xds.annotations.v3.file_status).work_in_progress = true; |
| 23 | + |
| 24 | +// [#protodoc-title: External processing service] |
| 25 | + |
| 26 | +// A service that can access and modify HTTP requests and responses |
| 27 | +// as part of a filter chain. |
| 28 | +// The overall external processing protocol works like this: |
| 29 | +// |
| 30 | +// 1. Envoy sends to the service information about the HTTP request. |
| 31 | +// 2. The service sends back a ProcessingResponse message that directs Envoy |
| 32 | +// to either stop processing, continue without it, or send it the |
| 33 | +// next chunk of the message body. |
| 34 | +// 3. If so requested, Envoy sends the server chunks of the message body, |
| 35 | +// or the entire body at once. In either case, the server sends back |
| 36 | +// a ProcessingResponse after each message it receives. |
| 37 | +// 4. If so requested, Envoy sends the server the HTTP trailers, |
| 38 | +// and the server sends back a ProcessingResponse. |
| 39 | +// 5. At this point, request processing is done, and we pick up again |
| 40 | +// at step 1 when Envoy receives a response from the upstream server. |
| 41 | +// 6. At any point above, if the server closes the gRPC stream cleanly, |
| 42 | +// then Envoy proceeds without consulting the server. |
| 43 | +// 7. At any point above, if the server closes the gRPC stream with an error, |
| 44 | +// then Envoy returns a 500 error to the client, unless the filter |
| 45 | +// was configured to ignore errors. |
| 46 | +// |
| 47 | +// In other words, the process is a request/response conversation, but |
| 48 | +// using a gRPC stream to make it easier for the server to |
| 49 | +// maintain state. |
| 50 | + |
| 51 | +service ExternalProcessor { |
| 52 | + // This begins the bidirectional stream that Envoy will use to |
| 53 | + // give the server control over what the filter does. The actual |
| 54 | + // protocol is described by the ProcessingRequest and ProcessingResponse |
| 55 | + // messages below. |
| 56 | + rpc Process(stream ProcessingRequest) returns (stream ProcessingResponse) { |
| 57 | + } |
| 58 | +} |
| 59 | + |
| 60 | +// This represents the different types of messages that Envoy can send |
| 61 | +// to an external processing server. |
| 62 | +// [#next-free-field: 8] |
| 63 | +message ProcessingRequest { |
| 64 | + // Specify whether the filter that sent this request is running in synchronous |
| 65 | + // or asynchronous mode. The choice of synchronous or asynchronous mode |
| 66 | + // can be set in the filter configuration, and defaults to false. |
| 67 | + // |
| 68 | + // * A value of ``false`` indicates that the server must respond |
| 69 | + // to this message by either sending back a matching ProcessingResponse message, |
| 70 | + // or by closing the stream. |
| 71 | + // * A value of ``true`` indicates that the server must not respond to this |
| 72 | + // message, although it may still close the stream to indicate that no more messages |
| 73 | + // are needed. |
| 74 | + // |
| 75 | + bool async_mode = 1; |
| 76 | + |
| 77 | + // Each request message will include one of the following sub-messages. Which |
| 78 | + // ones are set for a particular HTTP request/response depend on the |
| 79 | + // processing mode. |
| 80 | + oneof request { |
| 81 | + option (validate.required) = true; |
| 82 | + |
| 83 | + // Information about the HTTP request headers, as well as peer info and additional |
| 84 | + // properties. Unless ``async_mode`` is ``true``, the server must send back a |
| 85 | + // HeaderResponse message, an ImmediateResponse message, or close the stream. |
| 86 | + HttpHeaders request_headers = 2; |
| 87 | + |
| 88 | + // Information about the HTTP response headers, as well as peer info and additional |
| 89 | + // properties. Unless ``async_mode`` is ``true``, the server must send back a |
| 90 | + // HeaderResponse message or close the stream. |
| 91 | + HttpHeaders response_headers = 3; |
| 92 | + |
| 93 | + // A chunk of the HTTP request body. Unless ``async_mode`` is true, the server must send back |
| 94 | + // a BodyResponse message, an ImmediateResponse message, or close the stream. |
| 95 | + HttpBody request_body = 4; |
| 96 | + |
| 97 | + // A chunk of the HTTP request body. Unless ``async_mode`` is ``true``, the server must send back |
| 98 | + // a BodyResponse message or close the stream. |
| 99 | + HttpBody response_body = 5; |
| 100 | + |
| 101 | + // The HTTP trailers for the request path. Unless ``async_mode`` is ``true``, the server |
| 102 | + // must send back a TrailerResponse message or close the stream. |
| 103 | + // |
| 104 | + // This message is only sent if the trailers processing mode is set to ``SEND``. |
| 105 | + // If there are no trailers on the original downstream request, then this message |
| 106 | + // will only be sent (with empty trailers waiting to be populated) if the |
| 107 | + // processing mode is set before the request headers are sent, such as |
| 108 | + // in the filter configuration. |
| 109 | + HttpTrailers request_trailers = 6; |
| 110 | + |
| 111 | + // The HTTP trailers for the response path. Unless ``async_mode`` is ``true``, the server |
| 112 | + // must send back a TrailerResponse message or close the stream. |
| 113 | + // |
| 114 | + // This message is only sent if the trailers processing mode is set to ``SEND``. |
| 115 | + // If there are no trailers on the original downstream request, then this message |
| 116 | + // will only be sent (with empty trailers waiting to be populated) if the |
| 117 | + // processing mode is set before the request headers are sent, such as |
| 118 | + // in the filter configuration. |
| 119 | + HttpTrailers response_trailers = 7; |
| 120 | + } |
| 121 | +} |
| 122 | + |
| 123 | +// For every ProcessingRequest received by the server with the ``async_mode`` field |
| 124 | +// set to false, the server must send back exactly one ProcessingResponse message. |
| 125 | +// [#next-free-field: 11] |
| 126 | +message ProcessingResponse { |
| 127 | + oneof response { |
| 128 | + option (validate.required) = true; |
| 129 | + |
| 130 | + // The server must send back this message in response to a message with the |
| 131 | + // ``request_headers`` field set. |
| 132 | + HeadersResponse request_headers = 1; |
| 133 | + |
| 134 | + // The server must send back this message in response to a message with the |
| 135 | + // ``response_headers`` field set. |
| 136 | + HeadersResponse response_headers = 2; |
| 137 | + |
| 138 | + // The server must send back this message in response to a message with |
| 139 | + // the ``request_body`` field set. |
| 140 | + BodyResponse request_body = 3; |
| 141 | + |
| 142 | + // The server must send back this message in response to a message with |
| 143 | + // the ``response_body`` field set. |
| 144 | + BodyResponse response_body = 4; |
| 145 | + |
| 146 | + // The server must send back this message in response to a message with |
| 147 | + // the ``request_trailers`` field set. |
| 148 | + TrailersResponse request_trailers = 5; |
| 149 | + |
| 150 | + // The server must send back this message in response to a message with |
| 151 | + // the ``response_trailers`` field set. |
| 152 | + TrailersResponse response_trailers = 6; |
| 153 | + |
| 154 | + // If specified, attempt to create a locally generated response, send it |
| 155 | + // downstream, and stop processing additional filters and ignore any |
| 156 | + // additional messages received from the remote server for this request or |
| 157 | + // response. If a response has already started -- for example, if this |
| 158 | + // message is sent response to a ``response_body`` message -- then |
| 159 | + // this will either ship the reply directly to the downstream codec, |
| 160 | + // or reset the stream. |
| 161 | + ImmediateResponse immediate_response = 7; |
| 162 | + } |
| 163 | + |
| 164 | + // [#not-implemented-hide:] |
| 165 | + // Optional metadata that will be emitted as dynamic metadata to be consumed by the next |
| 166 | + // filter. This metadata will be placed in the namespace ``envoy.filters.http.ext_proc``. |
| 167 | + google.protobuf.Struct dynamic_metadata = 8; |
| 168 | + |
| 169 | + // Override how parts of the HTTP request and response are processed |
| 170 | + // for the duration of this particular request/response only. Servers |
| 171 | + // may use this to intelligently control how requests are processed |
| 172 | + // based on the headers and other metadata that they see. |
| 173 | + // This field is ignored by Envoy when the ext_proc filter config |
| 174 | + // :ref:`allow_mode_override |
| 175 | + // <envoy_v3_api_field_extensions.filters.http.ext_proc.v3.ExternalProcessor.allow_mode_override>` |
| 176 | + // is set to false. |
| 177 | + envoy.extensions.filters.http.ext_proc.v3.ProcessingMode mode_override = 9; |
| 178 | + |
| 179 | + // When ext_proc server receives a request message, in case it needs more |
| 180 | + // time to process the message, it sends back a ProcessingResponse message |
| 181 | + // with a new timeout value. When Envoy receives this response message, |
| 182 | + // it ignores other fields in the response, just stop the original timer, |
| 183 | + // which has the timeout value specified in |
| 184 | + // :ref:`message_timeout |
| 185 | + // <envoy_v3_api_field_extensions.filters.http.ext_proc.v3.ExternalProcessor.message_timeout>` |
| 186 | + // and start a new timer with this ``override_message_timeout`` value and keep the |
| 187 | + // Envoy ext_proc filter state machine intact. |
| 188 | + // Has to be >= 1ms and <= |
| 189 | + // :ref:`max_message_timeout <envoy_v3_api_field_extensions.filters.http.ext_proc.v3.ExternalProcessor.max_message_timeout>` |
| 190 | + // Such message can be sent at most once in a particular Envoy ext_proc filter processing state. |
| 191 | + // To enable this API, one has to set ``max_message_timeout`` to a number >= 1ms. |
| 192 | + google.protobuf.Duration override_message_timeout = 10; |
| 193 | +} |
| 194 | + |
| 195 | +// The following are messages that are sent to the server. |
| 196 | + |
| 197 | +// This message is sent to the external server when the HTTP request and responses |
| 198 | +// are first received. |
| 199 | +message HttpHeaders { |
| 200 | + // The HTTP request headers. All header keys will be |
| 201 | + // lower-cased, because HTTP header keys are case-insensitive. |
| 202 | + config.core.v3.HeaderMap headers = 1; |
| 203 | + |
| 204 | + // [#not-implemented-hide:] |
| 205 | + // The values of properties selected by the ``request_attributes`` |
| 206 | + // or ``response_attributes`` list in the configuration. Each entry |
| 207 | + // in the list is populated |
| 208 | + // from the standard :ref:`attributes <arch_overview_attributes>` |
| 209 | + // supported across Envoy. |
| 210 | + map<string, google.protobuf.Struct> attributes = 2; |
| 211 | + |
| 212 | + // If true, then there is no message body associated with this |
| 213 | + // request or response. |
| 214 | + bool end_of_stream = 3; |
| 215 | +} |
| 216 | + |
| 217 | +// This message contains the message body that Envoy sends to the external server. |
| 218 | +message HttpBody { |
| 219 | + bytes body = 1; |
| 220 | + |
| 221 | + bool end_of_stream = 2; |
| 222 | +} |
| 223 | + |
| 224 | +// This message contains the trailers. |
| 225 | +message HttpTrailers { |
| 226 | + config.core.v3.HeaderMap trailers = 1; |
| 227 | +} |
| 228 | + |
| 229 | +// The following are messages that may be sent back by the server. |
| 230 | + |
| 231 | +// This message must be sent in response to an HttpHeaders message. |
| 232 | +message HeadersResponse { |
| 233 | + CommonResponse response = 1; |
| 234 | +} |
| 235 | + |
| 236 | +// This message must be sent in response to an HttpTrailers message. |
| 237 | +message TrailersResponse { |
| 238 | + // Instructions on how to manipulate the trailers |
| 239 | + HeaderMutation header_mutation = 1; |
| 240 | +} |
| 241 | + |
| 242 | +// This message must be sent in response to an HttpBody message. |
| 243 | +message BodyResponse { |
| 244 | + CommonResponse response = 1; |
| 245 | +} |
| 246 | + |
| 247 | +// This message contains common fields between header and body responses. |
| 248 | +// [#next-free-field: 6] |
| 249 | +message CommonResponse { |
| 250 | + enum ResponseStatus { |
| 251 | + // Apply the mutation instructions in this message to the |
| 252 | + // request or response, and then continue processing the filter |
| 253 | + // stream as normal. This is the default. |
| 254 | + CONTINUE = 0; |
| 255 | + |
| 256 | + // Apply the specified header mutation, replace the body with the body |
| 257 | + // specified in the body mutation (if present), and do not send any |
| 258 | + // further messages for this request or response even if the processing |
| 259 | + // mode is configured to do so. |
| 260 | + // |
| 261 | + // When used in response to a request_headers or response_headers message, |
| 262 | + // this status makes it possible to either completely replace the body |
| 263 | + // while discarding the original body, or to add a body to a message that |
| 264 | + // formerly did not have one. |
| 265 | + // |
| 266 | + // In other words, this response makes it possible to turn an HTTP GET |
| 267 | + // into a POST, PUT, or PATCH. |
| 268 | + CONTINUE_AND_REPLACE = 1; |
| 269 | + } |
| 270 | + |
| 271 | + // If set, provide additional direction on how the Envoy proxy should |
| 272 | + // handle the rest of the HTTP filter chain. |
| 273 | + ResponseStatus status = 1 [(validate.rules).enum = {defined_only: true}]; |
| 274 | + |
| 275 | + // Instructions on how to manipulate the headers. When responding to an |
| 276 | + // HttpBody request, header mutations will only take effect if |
| 277 | + // the current processing mode for the body is BUFFERED. |
| 278 | + HeaderMutation header_mutation = 2; |
| 279 | + |
| 280 | + // Replace the body of the last message sent to the remote server on this |
| 281 | + // stream. If responding to an HttpBody request, simply replace or clear |
| 282 | + // the body chunk that was sent with that request. Body mutations may take |
| 283 | + // effect in response either to ``header`` or ``body`` messages. When it is |
| 284 | + // in response to ``header`` messages, it only take effect if the |
| 285 | + // :ref:`status <envoy_v3_api_field_service.ext_proc.v3.CommonResponse.status>` |
| 286 | + // is set to CONTINUE_AND_REPLACE. |
| 287 | + BodyMutation body_mutation = 3; |
| 288 | + |
| 289 | + // [#not-implemented-hide:] |
| 290 | + // Add new trailers to the message. This may be used when responding to either a |
| 291 | + // HttpHeaders or HttpBody message, but only if this message is returned |
| 292 | + // along with the CONTINUE_AND_REPLACE status. |
| 293 | + config.core.v3.HeaderMap trailers = 4; |
| 294 | + |
| 295 | + // Clear the route cache for the current client request. This is necessary |
| 296 | + // if the remote server modified headers that are used to calculate the route. |
| 297 | + // This field is ignored in the response direction. |
| 298 | + bool clear_route_cache = 5; |
| 299 | +} |
| 300 | + |
| 301 | +// This message causes the filter to attempt to create a locally |
| 302 | +// generated response, send it downstream, stop processing |
| 303 | +// additional filters, and ignore any additional messages received |
| 304 | +// from the remote server for this request or response. If a response |
| 305 | +// has already started, then this will either ship the reply directly |
| 306 | +// to the downstream codec, or reset the stream. |
| 307 | +// [#next-free-field: 6] |
| 308 | +message ImmediateResponse { |
| 309 | + // The response code to return |
| 310 | + type.v3.HttpStatus status = 1 [(validate.rules).message = {required: true}]; |
| 311 | + |
| 312 | + // Apply changes to the default headers, which will include content-type. |
| 313 | + HeaderMutation headers = 2; |
| 314 | + |
| 315 | + // The message body to return with the response which is sent using the |
| 316 | + // text/plain content type, or encoded in the grpc-message header. |
| 317 | + string body = 3; |
| 318 | + |
| 319 | + // If set, then include a gRPC status trailer. |
| 320 | + GrpcStatus grpc_status = 4; |
| 321 | + |
| 322 | + // A string detailing why this local reply was sent, which may be included |
| 323 | + // in log and debug output (e.g. this populates the %RESPONSE_CODE_DETAILS% |
| 324 | + // command operator field for use in access logging). |
| 325 | + string details = 5; |
| 326 | +} |
| 327 | + |
| 328 | +// This message specifies a gRPC status for an ImmediateResponse message. |
| 329 | +message GrpcStatus { |
| 330 | + // The actual gRPC status |
| 331 | + uint32 status = 1; |
| 332 | +} |
| 333 | + |
| 334 | +// Change HTTP headers or trailers by appending, replacing, or removing |
| 335 | +// headers. |
| 336 | +message HeaderMutation { |
| 337 | + // Add or replace HTTP headers. Attempts to set the value of |
| 338 | + // any ``x-envoy`` header, and attempts to set the ``:method``, |
| 339 | + // ``:authority``, ``:scheme``, or ``host`` headers will be ignored. |
| 340 | + repeated config.core.v3.HeaderValueOption set_headers = 1; |
| 341 | + |
| 342 | + // Remove these HTTP headers. Attempts to remove system headers -- |
| 343 | + // any header starting with ``:``, plus ``host`` -- will be ignored. |
| 344 | + repeated string remove_headers = 2; |
| 345 | +} |
| 346 | + |
| 347 | +// Replace the entire message body chunk received in the corresponding |
| 348 | +// HttpBody message with this new body, or clear the body. |
| 349 | +message BodyMutation { |
| 350 | + oneof mutation { |
| 351 | + // The entire body to replace |
| 352 | + bytes body = 1; |
| 353 | + |
| 354 | + // Clear the corresponding body chunk |
| 355 | + bool clear_body = 2; |
| 356 | + } |
| 357 | +} |
0 commit comments