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