Skip to content
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
5d98848
router: Use gRPC message for local responses when the request is gRPC
jrajahalme May 10, 2018
7896b64
grpc: Move utility functions to http/utility.
jrajahalme May 10, 2018
29ba376
http: Make Utility::sendLocalResponse() aware of gRPC.
jrajahalme May 10, 2018
2c264bf
http: add StreamDecoderFilter callback sendLocalReply().
jrajahalme May 9, 2018
c21e507
http: Add a missing include.
jrajahalme May 10, 2018
4c6b212
http: Mark local complete also when sending local gRPC response.
jrajahalme May 11, 2018
0903339
http: Add comment for clarification (needed)
jrajahalme May 11, 2018
ae9c406
http: Move gRPC utilities back to grpc/common
jrajahalme May 11, 2018
52f9baf
test/grpc: Revert unnecessary namespace prefix changes.
jrajahalme May 11, 2018
42327a3
Merge branch 'master' into grpc-local-responses
jrajahalme May 11, 2018
04f23a6
http: Use sendLocalReply() for all local replies in ConnectionManager…
jrajahalme May 11, 2018
a47b2a1
filters: Use sendLocalReply() decoder callback for local replies.
jrajahalme May 11, 2018
6bd512a
conn_manager_impl: Fix format.
jrajahalme May 11, 2018
26aa335
filters: Remove unnecessary tracking of stream status.
jrajahalme May 14, 2018
dea2787
http: Clarify comments on sendLocalReply()
jrajahalme May 14, 2018
06b22a7
conn_manager_impl: Remove nullptr parameter and add TODOs.
jrajahalme May 14, 2018
e125f63
filter: Add comment about gRPC encoding of local responses.
jrajahalme May 14, 2018
2860297
common/grpc: Add status_lib
jrajahalme May 14, 2018
74724fd
test: http mock cleanup.
jrajahalme May 15, 2018
2b57fc4
http: Final review comment fixes.
jrajahalme May 15, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/root/intro/version_history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ Version history
local configuration.
* http: added the ability to pass DNS type Subject Alternative Names of the client certificate in the
:ref:`config_http_conn_man_headers_x-forwarded-client-cert` header.
* http: local responses to gRPC requests are now sent as trailers-only gRPC responses instead of plain HTTP responses.
Notably the HTTP response code is always "200" in this case, and the gRPC error code is carried in "grpc-status"
header, optionally accompanied with a text message in "grpc-message" header.
* listeners: added :ref:`tcp_fast_open_queue_length <envoy_api_field_Listener.tcp_fast_open_queue_length>` option.
* load balancing: added :ref:`weighted round robin
<arch_overview_load_balancing_types_round_robin>` support. The round robin
Expand Down
11 changes: 11 additions & 0 deletions include/envoy/http/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,17 @@ class StreamDecoderFilterCallbacks : public virtual StreamFilterCallbacks {
*/
virtual void addDecodedData(Buffer::Instance& data, bool streaming_filter) PURE;

/**
* Create a locally generated response using the provided lambdas.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you provide some docs/indication that this may be transparently converted to a gRPC response in certain cases? Some of the param text might also need to be altered so that it describes gRPC also.

* @param response_code supplies the HTTP response code.
* @param body_text supplies the optional body text which is sent using the text/plain content
* type.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "... or encoded in the grpc-message header."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added.

* @param modify_headers supplies an optional callback function that can modify the
* response headers.
*/
virtual void sendLocalReply(Code response_code, const std::string& body_text,
std::function<void(HeaderMap& headers)> modify_headers) PURE;

/**
* Called with 100-Continue headers to be encoded.
*
Expand Down
2 changes: 1 addition & 1 deletion source/common/grpc/async_client_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ void AsyncStreamImpl::onHeaders(Http::HeaderMapPtr&& headers, bool end_stream) {
}
// Technically this should be
// https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md
// as given by Common::httpToGrpcStatus(), but the Google gRPC client treats
// as given by Http::Utility::httpToGrpcStatus(), but the Google gRPC client treats
// this as GrpcStatus::Canceled.
streamError(Status::GrpcStatus::Canceled);
return;
Expand Down
82 changes: 0 additions & 82 deletions source/common/grpc/common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -124,88 +124,6 @@ bool Common::resolveServiceAndMethod(const Http::HeaderEntry* path, std::string*
return true;
}

Status::GrpcStatus Common::httpToGrpcStatus(uint64_t http_response_status) {
// From
// https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md.
switch (http_response_status) {
case 400:
return Status::GrpcStatus::Internal;
case 401:
return Status::GrpcStatus::Unauthenticated;
case 403:
return Status::GrpcStatus::PermissionDenied;
case 404:
return Status::GrpcStatus::Unimplemented;
case 429:
case 502:
case 503:
case 504:
return Status::GrpcStatus::Unavailable;
default:
return Status::GrpcStatus::Unknown;
}
}

uint64_t Common::grpcToHttpStatus(Status::GrpcStatus grpc_status) {
// From https://cloud.google.com/apis/design/errors#handling_errors.
switch (grpc_status) {
case Status::GrpcStatus::Ok:
return 200;
case Status::GrpcStatus::Canceled:
// Client closed request.
return 499;
case Status::GrpcStatus::Unknown:
// Internal server error.
return 500;
case Status::GrpcStatus::InvalidArgument:
// Bad request.
return 400;
case Status::GrpcStatus::DeadlineExceeded:
// Gateway Time-out.
return 504;
case Status::GrpcStatus::NotFound:
// Not found.
return 404;
case Status::GrpcStatus::AlreadyExists:
// Conflict.
return 409;
case Status::GrpcStatus::PermissionDenied:
// Forbidden.
return 403;
case Status::GrpcStatus::ResourceExhausted:
// Too many requests.
return 429;
case Status::GrpcStatus::FailedPrecondition:
// Bad request.
return 400;
case Status::GrpcStatus::Aborted:
// Conflict.
return 409;
case Status::GrpcStatus::OutOfRange:
// Bad request.
return 400;
case Status::GrpcStatus::Unimplemented:
// Not implemented.
return 501;
case Status::GrpcStatus::Internal:
// Internal server error.
return 500;
case Status::GrpcStatus::Unavailable:
// Service unavailable.
return 503;
case Status::GrpcStatus::DataLoss:
// Internal server error.
return 500;
case Status::GrpcStatus::Unauthenticated:
// Unauthorized.
return 401;
case Status::GrpcStatus::InvalidCode:
default:
// Internal server error.
return 500;
}
}

Buffer::InstancePtr Common::serializeBody(const Protobuf::Message& message) {
// http://www.grpc.io/docs/guides/wire.html
// Reserve enough space for the entire message and the 5 byte header.
Expand Down
15 changes: 0 additions & 15 deletions source/common/grpc/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,6 @@ class Common {
*/
static std::string getGrpcMessage(const Http::HeaderMap& trailers);

/**
* Returns the gRPC status code from a given HTTP response status code. Ordinarily, it is expected
* that a 200 response is provided, but gRPC defines a mapping for intermediaries that are not
* gRPC aware, see https://github.com/grpc/grpc/blob/master/doc/http-grpc-status-mapping.md.
* @param http_response_status HTTP status code.
* @return Status::GrpcStatus corresponding gRPC status code.
*/
static Status::GrpcStatus httpToGrpcStatus(uint64_t http_response_status);

/**
* @param grpc_status gRPC status from grpc-status header.
* @return uint64_t the canonical HTTP status code corresponding to a gRPC status code.
*/
static uint64_t grpcToHttpStatus(Status::GrpcStatus grpc_status);

/**
* Charge a success/failure stat to a cluster/service/method.
* @param cluster supplies the target cluster.
Expand Down
1 change: 1 addition & 0 deletions source/common/http/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ envoy_cc_library(
":exception_lib",
":header_map_lib",
":headers_lib",
"//include/envoy/grpc:status",
"//include/envoy/http:codes_interface",
"//include/envoy/http:filter_interface",
"//include/envoy/http:header_map_interface",
Expand Down
2 changes: 2 additions & 0 deletions source/common/http/async_client_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <string>
#include <vector>

#include "common/grpc/common.h"
#include "common/http/utility.h"

namespace Envoy {
Expand Down Expand Up @@ -110,6 +111,7 @@ void AsyncStreamImpl::encodeTrailers(HeaderMapPtr&& trailers) {
}

void AsyncStreamImpl::sendHeaders(HeaderMap& headers, bool end_stream) {
is_grpc_request_ = Grpc::Common::hasGrpcContentType(headers);
headers.insertEnvoyInternalRequest().value().setReference(
Headers::get().EnvoyInternalRequestValues.True);
Utility::appendXff(headers, *parent_.config_.local_info_.address());
Expand Down
14 changes: 14 additions & 0 deletions source/common/http/async_client_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,19 @@ class AsyncStreamImpl : public AsyncClient::Stream,
void continueDecoding() override { NOT_IMPLEMENTED; }
void addDecodedData(Buffer::Instance&, bool) override { NOT_IMPLEMENTED; }
const Buffer::Instance* decodingBuffer() override { return buffered_body_.get(); }
void sendLocalReply(Code code, const std::string& body,
std::function<void(HeaderMap& headers)> modify_headers) override {
Utility::sendLocalReply(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is correct for an HTTP client; do we ever hit this in the configured client filter stack? I.e. could it be NOT_IMPLEMENTED?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I initially left this empty, and when tests failed put NOT_REACHED and it was reached. With this it works, and I did not dig deeper.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested it again, these fail if this is just {}:

//test/integration:legacy_json_integration_test                         TIMEOUT in 315.1s
  /home/vagrant/.cache/bazel/_bazel_vagrant/c7b138b989b4d12d83f51d45caa4ff0e/execroot/envoy/bazel-out/k8-fastbuild/testlogs/test/integration/legacy_json_integration_test/test.log
//test/integration:ratelimit_integration_test                           TIMEOUT in 315.1s
  /home/vagrant/.cache/bazel/_bazel_vagrant/c7b138b989b4d12d83f51d45caa4ff0e/execroot/envoy/bazel-out/k8-fastbuild/testlogs/test/integration/ratelimit_integration_test/test.log
//test/common/http:async_client_impl_test                                FAILED in 0.3s
  /home/vagrant/.cache/bazel/_bazel_vagrant/c7b138b989b4d12d83f51d45caa4ff0e/execroot/envoy/bazel-out/k8-fastbuild/testlogs/test/common/http/async_client_impl_test/test.log
//test/integration:hotrestart_test                                       FAILED in 35.0s
  /home/vagrant/.cache/bazel/_bazel_vagrant/c7b138b989b4d12d83f51d45caa4ff0e/execroot/envoy/bazel-out/k8-fastbuild/testlogs/test/integration/hotrestart_test/test.log

Executed 52 out of 239 tests: 235 tests pass and 4 fail locally.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we can definitely hit this for AsyncClient, since it goes through router and can return 503 for no healthy upstream and a bunch of other reasons.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, that makes sense.

is_grpc_request_,
[this, modify_headers](HeaderMapPtr&& headers, bool end_stream) -> void {
if (headers != nullptr && modify_headers != nullptr) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can headers ever be nullptr here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, removed test for non-null.

modify_headers(*headers);
}
encodeHeaders(std::move(headers), end_stream);
},
[this](Buffer::Instance& data, bool end_stream) -> void { encodeData(data, end_stream); },
remote_closed_, code, body);
}
// The async client won't pause if sending an Expect: 100-Continue so simply
// swallows any incoming encode100Continue.
void encode100ContinueHeaders(HeaderMapPtr&&) override {}
Expand All @@ -284,6 +297,7 @@ class AsyncStreamImpl : public AsyncClient::Stream,
bool local_closed_{};
bool remote_closed_{};
Buffer::InstancePtr buffered_body_;
bool is_grpc_request_{};
friend class AsyncClientImpl;
};

Expand Down
73 changes: 45 additions & 28 deletions source/common/http/conn_manager_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -473,10 +473,9 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers,
// The protocol may have shifted in the HTTP/1.0 case so reset it.
request_info_.protocol(protocol);
if (!connection_manager_.config_.http1Settings().accept_http_10_) {
// Send "Upgrade Required" if HTTP/1.0 support is not expliictly configured on.
HeaderMapImpl headers{
{Headers::get().Status, std::to_string(enumToInt(Code::UpgradeRequired))}};
encodeHeaders(nullptr, headers, true);
// Send "Upgrade Required" if HTTP/1.0 support is not explictly configured on.
sendLocalReply(nullptr, Grpc::Common::hasGrpcContentType(*request_headers_),
Code::UpgradeRequired, "", nullptr);
return;
} else {
// HTTP/1.0 defaults to single-use connections. Make sure the connection
Expand All @@ -499,8 +498,8 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers,
connection_manager_.config_.http1Settings().default_host_for_http_10_);
} else {
// Require host header. For HTTP/1.1 Host has already been translated to :authority.
HeaderMapImpl headers{{Headers::get().Status, std::to_string(enumToInt(Code::BadRequest))}};
encodeHeaders(nullptr, headers, true);
sendLocalReply(nullptr, Grpc::Common::hasGrpcContentType(*request_headers_), Code::BadRequest,
"", nullptr);
return;
}
}
Expand All @@ -513,9 +512,8 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers,
// header size http_parser and nghttp2 will allow, down to 16k or 8k for
// envoy users who do not wish to proxy large headers.
if (request_headers_->byteSize() > (60 * 1024)) {
HeaderMapImpl headers{
{Headers::get().Status, std::to_string(enumToInt(Code::RequestHeaderFieldsTooLarge))}};
encodeHeaders(nullptr, headers, true);
sendLocalReply(nullptr, Grpc::Common::hasGrpcContentType(*request_headers_),
Code::RequestHeaderFieldsTooLarge, "", nullptr);
return;
}

Expand All @@ -526,8 +524,8 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers,
// don't support that currently.
if (!request_headers_->Path() || request_headers_->Path()->value().c_str()[0] != '/') {
connection_manager_.stats_.named_.downstream_rq_non_relative_path_.inc();
HeaderMapImpl headers{{Headers::get().Status, std::to_string(enumToInt(Code::NotFound))}};
encodeHeaders(nullptr, headers, true);
sendLocalReply(nullptr, Grpc::Common::hasGrpcContentType(*request_headers_), Code::NotFound, "",
nullptr);
return;
}

Expand Down Expand Up @@ -570,8 +568,8 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(HeaderMapPtr&& headers,
} else if (websocket_requested) {
// Do not allow WebSocket upgrades if the route does not support it.
connection_manager_.stats_.named_.downstream_rq_ws_on_non_ws_route_.inc();
HeaderMapImpl headers{{Headers::get().Status, std::to_string(enumToInt(Code::Forbidden))}};
encodeHeaders(nullptr, headers, true);
sendLocalReply(nullptr, Grpc::Common::hasGrpcContentType(*request_headers_), Code::Forbidden,
"", nullptr);
return;
}
// Allow non websocket requests to go through websocket enabled routes.
Expand Down Expand Up @@ -653,7 +651,7 @@ void ConnectionManagerImpl::ActiveStream::decodeHeaders(ActiveStreamDecoderFilte
for (; entry != decoder_filters_.end(); entry++) {
ASSERT(!(state_.filter_call_state_ & FilterCallState::DecodeHeaders));
state_.filter_call_state_ |= FilterCallState::DecodeHeaders;
FilterHeadersStatus status = (*entry)->handle_->decodeHeaders(
FilterHeadersStatus status = (*entry)->decodeHeaders(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is not intuitive. Can you add some comments. Is the idea that you want to recompute gRPC status before each filter? I think that makes sense, but worth some comments here and in the wrapper to forwards to parent.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, in case a filter bridges to/from gRPC, for example.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add comments.

headers, end_stream && continue_data_entry == decoder_filters_.end());
state_.filter_call_state_ &= ~FilterCallState::DecodeHeaders;
ENVOY_STREAM_LOG(trace, "decode headers called: filter={} status={}", *this,
Expand Down Expand Up @@ -821,6 +819,24 @@ void ConnectionManagerImpl::ActiveStream::refreshCachedRoute() {
cached_route_ = std::move(route);
}

void ConnectionManagerImpl::ActiveStream::sendLocalReply(
ActiveStreamEncoderFilter* filter, bool is_grpc_request, Code code, const std::string& body,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I really like where this is going!

My one question for APIs is id we think sendLocalReply should instead take a reference to the request headers so is_grpc_request can be calculated locally in just one place, and in case we eventually end up with other transformations which might be based on request headers. We can just push this as-is and iterate, but I'd be interested in @mattklein123's take now since I think this is likely to be used in many places here and in downstream filters so it'd be nice to get it right on first pass.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alyssawilk I think this is internal code and not the main API, right? (So I think the code does what you are asking?)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is what happens when I do reviews before caffeine :-/

I think we could avoid latching is_grpc_request_ in the two places we do, but that's a smaller request.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean having is_grpc_request_ in both ConnManagerImpl and AsyncStreamImpl? Right now I don't have a clear picture of the relation between the two, so I don't know if tracking in one of them can be eliminated or not.

std::function<void(HeaderMap& headers)> modify_headers) {
Utility::sendLocalReply(
is_grpc_request,
[this, filter, modify_headers](HeaderMapPtr&& headers, bool end_stream) -> void {
if (headers != nullptr && modify_headers != nullptr) {
modify_headers(*headers);
}
response_headers_ = std::move(headers);
encodeHeaders(filter, *response_headers_, end_stream);
},
[this, filter](Buffer::Instance& data, bool end_stream) -> void {
encodeData(filter, data, end_stream);
},
state_.destroyed_, code, body);
}

void ConnectionManagerImpl::ActiveStream::encode100ContinueHeaders(
ActiveStreamEncoderFilter* filter, HeaderMap& headers) {
ASSERT(connection_manager_.config_.proxy100Continue());
Expand Down Expand Up @@ -1316,8 +1332,7 @@ void ConnectionManagerImpl::ActiveStreamDecoderFilter::requestDataTooLarge() {
onDecoderFilterAboveWriteBufferHighWatermark();
} else {
parent_.connection_manager_.stats_.named_.downstream_rq_too_large_.inc();
Http::Utility::sendLocalReply(*this, parent_.state_.destroyed_, Http::Code::PayloadTooLarge,
CodeUtility::toString(Http::Code::PayloadTooLarge));
sendLocalReply(Code::PayloadTooLarge, CodeUtility::toString(Code::PayloadTooLarge), nullptr);
}
}

Expand Down Expand Up @@ -1389,18 +1404,20 @@ void ConnectionManagerImpl::ActiveStreamEncoderFilter::responseDataTooLarge() {
parent_.state_.encoder_filters_streaming_ = true;
stopped_ = false;

Http::Utility::sendLocalReply(
[&](HeaderMapPtr&& response_headers, bool end_stream) -> void {
parent_.response_headers_ = std::move(response_headers);
parent_.response_encoder_->encodeHeaders(*parent_.response_headers_, end_stream);
},
[&](Buffer::Instance& data, bool end_stream) -> void {
parent_.response_encoder_->encodeData(data, end_stream);
parent_.state_.local_complete_ = end_stream;
parent_.maybeEndEncode(end_stream);
},
parent_.state_.destroyed_, Http::Code::InternalServerError,
CodeUtility::toString(Http::Code::InternalServerError));
Http::Utility::sendLocalReply(Grpc::Common::hasGrpcContentType(*parent_.request_headers_),
[&](HeaderMapPtr&& response_headers, bool end_stream) -> void {
parent_.response_headers_ = std::move(response_headers);
parent_.response_encoder_->encodeHeaders(
*parent_.response_headers_, end_stream);
parent_.state_.local_complete_ = end_stream;
},
[&](Buffer::Instance& data, bool end_stream) -> void {
parent_.response_encoder_->encodeData(data, end_stream);
parent_.state_.local_complete_ = end_stream;
},
parent_.state_.destroyed_, Http::Code::InternalServerError,
CodeUtility::toString(Http::Code::InternalServerError));
parent_.maybeEndEncode(parent_.state_.local_complete_);
} else {
resetStream();
}
Expand Down
15 changes: 15 additions & 0 deletions source/common/http/conn_manager_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@

#include "common/buffer/watermark_buffer.h"
#include "common/common/linked_object.h"
#include "common/grpc/common.h"
#include "common/http/conn_manager_config.h"
#include "common/http/user_agent.h"
#include "common/http/utility.h"
#include "common/request_info/request_info_impl.h"
#include "common/tracing/http_tracer_impl.h"

Expand Down Expand Up @@ -164,6 +166,10 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>,
const Buffer::Instance* decodingBuffer() override {
return parent_.buffered_request_data_.get();
}
void sendLocalReply(Code code, const std::string& body,
std::function<void(HeaderMap& headers)> modify_headers) override {
parent_.sendLocalReply(nullptr, is_grpc_request_, code, body, modify_headers);
}
void encode100ContinueHeaders(HeaderMapPtr&& headers) override;
void encodeHeaders(HeaderMapPtr&& headers, bool end_stream) override;
void encodeData(Buffer::Instance& data, bool end_stream) override;
Expand All @@ -177,10 +183,16 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>,
void setDecoderBufferLimit(uint32_t limit) override { parent_.setBufferLimit(limit); }
uint32_t decoderBufferLimit() override { return parent_.buffer_limit_; }

FilterHeadersStatus decodeHeaders(HeaderMap& headers, bool end_stream) {
is_grpc_request_ = Grpc::Common::hasGrpcContentType(headers);
return handle_->decodeHeaders(headers, end_stream);
}

void requestDataTooLarge();
void requestDataDrained();

StreamDecoderFilterSharedPtr handle_;
bool is_grpc_request_{};
};

typedef std::unique_ptr<ActiveStreamDecoderFilter> ActiveStreamDecoderFilterPtr;
Expand Down Expand Up @@ -257,6 +269,9 @@ class ConnectionManagerImpl : Logger::Loggable<Logger::Id::http>,
void decodeTrailers(ActiveStreamDecoderFilter* filter, HeaderMap& trailers);
void maybeEndDecode(bool end_stream);
void addEncodedData(ActiveStreamEncoderFilter& filter, Buffer::Instance& data, bool streaming);
void sendLocalReply(ActiveStreamEncoderFilter* filter, bool is_grpc_request, Code code,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the first param here is always set to nullptr? What is the intention to eventually allow proper restart for filters downstream? For now, I would just remove the parameter and add TODOs around allowing proper restart if the filter is also an encoding filter?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but as it is still a TODO, I'll remove it and add the comments to the encodeHeaders() and encodeData() calls that take the nullptr filter pointer as the first parameter in the implementation of sendLocalReply().

const std::string& body,
std::function<void(HeaderMap& headers)> modify_headers);
void encode100ContinueHeaders(ActiveStreamEncoderFilter* filter, HeaderMap& headers);
void encodeHeaders(ActiveStreamEncoderFilter* filter, HeaderMap& headers, bool end_stream);
void encodeData(ActiveStreamEncoderFilter* filter, Buffer::Instance& data, bool end_stream);
Expand Down
Loading