Repository: envoyproxy/envoy
File: api/envoy/service/ext_proc/v3/external_processor.proto (Protocol Buffers)

Code before:
// 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 header value is encoded in the
  // :ref:`raw_value <envoy_v3_api_field_config.core.v3.HeaderValue.raw_value>` field.
  config.core.v3.HeaderMap headers = 1;

  // [#not-implemented-hide:]
  // This field is deprecated and not implemented. Attributes will be sent in
  // the  top-level :ref:`attributes <envoy_v3_api_field_service.ext_proc.v3.ProcessingRequest.attributes`
  // field.
  map<string, google.protobuf.Struct> attributes = 2
      [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

  // If ``true``, then there is no message body associated with this
  // request or response.
  bool end_of_stream = 3;
}

// This message is sent to the external server when the HTTP request and
// response bodies are received.
message HttpBody {
  // The contents of the body in the HTTP request/response. Note that in
  // streaming mode multiple ``HttpBody`` messages may be sent.
  //
  // In ``GRPC`` body send mode, a separate ``HttpBody`` message will be
  // sent for each message in the gRPC stream.
  bytes body = 1;

  // If ``true``, this will be the last ``HttpBody`` message that will be sent and no
  // trailers will be sent for the current request/response.
  bool end_of_stream = 2;

  // This field is used in ``GRPC`` body send mode when ``end_of_stream`` is
  // true and ``body`` is empty. Those values would normally indicate an
  // empty message on the stream with the end-of-stream bit set.
  // However, if the half-close happens after the last message on the
  // stream was already sent, then this field will be true to indicate an
  // end-of-stream with *no* message (as opposed to an empty message).
  bool end_of_stream_without_message = 3;
}

// This message is sent to the external server when the HTTP request and
// response trailers are received.
message HttpTrailers {
  // The header value is encoded in the
  // :ref:`raw_value <envoy_v3_api_field_config.core.v3.HeaderValue.raw_value>` field.

Review comment (suggestion):
This message is named HttpBody, but it does not contain any bytes or metadata related to HTTP in GRPC mode. It seems as though we should instead have a message like the following:
```
message GrpcMessage {

  google.type.Any payload = 1;

  // End of stream booleans  
}
```

This would also avoid the pitfall of a GRPC specific boolean in the HttpBody message.

Code after:
// 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 header value is encoded in the
  // :ref:`raw_value <envoy_v3_api_field_config.core.v3.HeaderValue.raw_value>` field.
  config.core.v3.HeaderMap headers = 1;

  // [#not-implemented-hide:]
  // This field is deprecated and not implemented. Attributes will be sent in
  // the  top-level :ref:`attributes <envoy_v3_api_field_service.ext_proc.v3.ProcessingRequest.attributes`
  // field.
  map<string, google.protobuf.Struct> attributes = 2
      [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

  // If ``true``, then there is no message body associated with this
  // request or response.
  bool end_of_stream = 3;
}

// This message is sent to the external server when the HTTP request and
// response bodies are received.
message HttpBody {
  // The contents of the body in the HTTP request/response. Note that in
  // streaming mode multiple ``HttpBody`` messages may be sent.
  //
  // In ``GRPC`` body send mode, a separate ``HttpBody`` message will be
  // sent for each message in the gRPC stream.
  bytes body = 1;

  // If ``true``, this will be the last ``HttpBody`` message that will be sent and no
  // trailers will be sent for the current request/response.
  bool end_of_stream = 2;

  // This field is used in ``GRPC`` body send mode when ``end_of_stream`` is
  // true and ``body`` is empty. Those values would normally indicate an
  // empty message on the stream with the end-of-stream bit set.
  // However, if the half-close happens after the last message on the
  // stream was already sent, then this field will be true to indicate an
  // end-of-stream with *no* message (as opposed to an empty message).
  bool end_of_stream_without_message = 3;

  // This field is used in ``GRPC`` body send mode to indicate whether
  // the message is compressed. This will never be set to true by gRPC
  // but may be set to true by a proxy like Envoy.
  bool grpc_message_compressed = 4;
}