forked from envoyproxy/envoy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
extensions: add grpc_http1_reverse_bridge filter (envoyproxy#5315)
Adds a filter that allows converting a gRPC request into an HTTP/1.1 request with a custom content-type. Allows a vanilla HTTP/1.1 upstream to handle incoming requests by reading and responding with protobuf messages in binary octet format. For now this shields the upstream from any gRPC association: the filter removes the gRPC specific message prefix and manages the conversion of the HTTP status code into grpc-status. Signed-off-by: Snow Pettersen <[email protected]> Signed-off-by: Fred Douglas <[email protected]>
- Loading branch information
Showing
18 changed files
with
1,056 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
api/envoy/config/filter/http/grpc_http1_reverse_bridge/v2alpha1/BUILD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
load("//bazel:api_build_system.bzl", "api_proto_library") | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
api_proto_library( | ||
name = "config", | ||
srcs = ["config.proto"], | ||
) |
22 changes: 22 additions & 0 deletions
22
api/envoy/config/filter/http/grpc_http1_reverse_bridge/v2alpha1/config.proto
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
syntax = "proto3"; | ||
|
||
package envoy.extensions.filter.http.grpc_http1_reverse_bridge.v2alpha1; | ||
option java_package = "io.envoyproxy.envoy.extensions.filter.http.grpc_http1_reverse_bridge.v2alpha1"; | ||
option java_multiple_files = true; | ||
option go_package = "v2"; | ||
|
||
import "validate/validate.proto"; | ||
|
||
// [#protodoc-title: Extensions gRPC Http1 Reverse Bridge] | ||
// gRPC reverse bridge filter configuration | ||
message FilterConfig { | ||
// The content-type to pass to the upstream when the gRPC bridge filter is applied. | ||
// The filter will also validate that the upstream responds with the same content type. | ||
string content_type = 1 [(validate.rules).string.min_bytes = 1]; | ||
|
||
// If true, Envoy will assume that the upstream doesn't understand gRPC frames and | ||
// strip the gRPC frame from the request, and add it back in to the response. This will | ||
// hide the gRPC semantics from the upstream, allowing it to receive and respond with a | ||
// simple binary encoded protobuf. | ||
bool withhold_grpc_frames = 2; | ||
} |
40 changes: 40 additions & 0 deletions
40
docs/root/configuration/http_filters/grpc_http1_reverse_bridge_filter.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
.. _config_http_filters_grpc_reverse_bridge: | ||
|
||
gRPC HTTP/1.1 reverse bridge | ||
============================ | ||
|
||
* gRPC :ref:`architecture overview <arch_overview_grpc>` | ||
* :ref:`v2 API reference <envoy_api_field_config.filter.network.http_connection_manager.v2.HttpFilter.name>` | ||
* This filter should be configured with the name *envoy.grpc_http1_reverse_bridge*. | ||
|
||
This is a filter that enables converting an incoming gRPC request into a HTTP/1.1 request to allow | ||
a server that does not understand HTTP/2 or gRPC semantics to handle the request. | ||
|
||
The filter works by: | ||
|
||
* Checking the content type of the incoming request. If it's a gRPC request, the filter is enabled. | ||
* The content type is modified to a configurable value. This can be a noop by configuring | ||
``application/grpc``. | ||
* The gRPC frame header is optionally stripped from the request body. The content length header | ||
will be adjusted if so. | ||
* On receiving a response, the content type of the response is validated and the status code is | ||
mapped to a grpc-status which is inserted into the response trailers. | ||
* The response body is optionally prefixed by the gRPC frame header, again adjusting the content | ||
length header if necessary. | ||
|
||
Due to being mapped to HTTP/1.1, this filter will only work with unary gRPC calls. | ||
|
||
gRPC frame header management | ||
---------------------------- | ||
|
||
By setting the withhold_grpc_frame option, the filter will assume that the upstream does not | ||
understand any gRPC semantics and will convert the request body into a simple binary encoding | ||
of the request body and perform the reverse conversion on the response body. This ends up | ||
simplifying the server side handling of these requests, as they no longer need to be concerned | ||
with parsing and generating gRPC formatted data. | ||
|
||
This works by stripping the gRPC frame header from the request body, while injecting a gRPC | ||
frame header in the response. | ||
|
||
If this feature is not used, the upstream must be ready to receive HTTP/1.1 requests prefixed | ||
with the gRPC frame header and respond with gRPC formatted responses. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
source/extensions/filters/http/grpc_http1_reverse_bridge/BUILD
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
licenses(["notice"]) # Apache 2 | ||
|
||
load( | ||
"//bazel:envoy_build_system.bzl", | ||
"envoy_cc_library", | ||
"envoy_package", | ||
) | ||
|
||
envoy_package() | ||
|
||
envoy_cc_library( | ||
name = "filter_lib", | ||
srcs = ["filter.cc"], | ||
hdrs = ["filter.h"], | ||
deps = [ | ||
"//include/envoy/http:filter_interface", | ||
"//source/common/common:enum_to_int", | ||
"//source/common/grpc:codec_lib", | ||
"//source/common/grpc:common_lib", | ||
"//source/common/grpc:status_lib", | ||
"//source/common/http:header_map_lib", | ||
"//source/extensions/filters/http:well_known_names", | ||
"//source/extensions/filters/http/common:pass_through_filter_lib", | ||
], | ||
) | ||
|
||
envoy_cc_library( | ||
name = "config", | ||
srcs = ["config.cc"], | ||
hdrs = ["config.h"], | ||
deps = [ | ||
":filter_lib", | ||
"//include/envoy/http:filter_interface", | ||
"//include/envoy/registry", | ||
"//include/envoy/server:filter_config_interface", | ||
"//source/extensions/filters/http:well_known_names", | ||
"//source/extensions/filters/http/common:factory_base_lib", | ||
"@envoy_api//envoy/config/filter/http/grpc_http1_reverse_bridge/v2alpha1:config_cc", | ||
], | ||
) |
30 changes: 30 additions & 0 deletions
30
source/extensions/filters/http/grpc_http1_reverse_bridge/config.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#include "extensions/filters/http/grpc_http1_reverse_bridge/config.h" | ||
|
||
#include "envoy/registry/registry.h" | ||
|
||
#include "extensions/filters/http/grpc_http1_reverse_bridge/filter.h" | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace HttpFilters { | ||
namespace GrpcHttp1ReverseBridge { | ||
|
||
Http::FilterFactoryCb Config::createFilterFactoryFromProtoTyped( | ||
const envoy::extensions::filter::http::grpc_http1_reverse_bridge::v2alpha1::FilterConfig& | ||
config, | ||
const std::string&, Server::Configuration::FactoryContext&) { | ||
return [config](Envoy::Http::FilterChainFactoryCallbacks& callbacks) -> void { | ||
callbacks.addStreamFilter( | ||
std::make_unique<Filter>(config.content_type(), config.withhold_grpc_frames())); | ||
}; | ||
} | ||
|
||
/** | ||
* Static registration for the grpc http1 reverse bridge filter. @see RegisterFactory. | ||
*/ | ||
static Envoy::Registry::RegisterFactory<Config, Server::Configuration::NamedHttpFilterConfigFactory> | ||
register_; | ||
} // namespace GrpcHttp1ReverseBridge | ||
} // namespace HttpFilters | ||
} // namespace Extensions | ||
} // namespace Envoy |
29 changes: 29 additions & 0 deletions
29
source/extensions/filters/http/grpc_http1_reverse_bridge/config.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#pragma once | ||
|
||
#include "envoy/config/filter/http/grpc_http1_reverse_bridge/v2alpha1/config.pb.validate.h" | ||
#include "envoy/server/filter_config.h" | ||
|
||
#include "extensions/filters/http/common/factory_base.h" | ||
#include "extensions/filters/http/well_known_names.h" | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace HttpFilters { | ||
namespace GrpcHttp1ReverseBridge { | ||
|
||
class Config | ||
: public Common::FactoryBase< | ||
envoy::extensions::filter::http::grpc_http1_reverse_bridge::v2alpha1::FilterConfig> { | ||
public: | ||
Config() : FactoryBase(HttpFilterNames::get().GrpcHttp1ReverseBridge) {} | ||
|
||
Http::FilterFactoryCb createFilterFactoryFromProtoTyped( | ||
const envoy::extensions::filter::http::grpc_http1_reverse_bridge::v2alpha1::FilterConfig& | ||
config, | ||
const std::string& stat_prefix, | ||
Envoy::Server::Configuration::FactoryContext& context) override; | ||
}; | ||
} // namespace GrpcHttp1ReverseBridge | ||
} // namespace HttpFilters | ||
} // namespace Extensions | ||
} // namespace Envoy |
Oops, something went wrong.