Skip to content

Commit c4dcca9

Browse files
authored
Revert "dynamic_modules: add gRPC capability to HTTP module (#43827)" (#43897)
This reverts commit 559dfff. We have a consensus on moving these to a utility instead. Signed-off-by: Rohit Agrawal <rohit.agrawal@databricks.com>
1 parent faeb256 commit c4dcca9

File tree

22 files changed

+78
-724
lines changed

22 files changed

+78
-724
lines changed

changelogs/current.yaml

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,6 @@ new_features:
262262
and added brotli and zlib to TCP TLS. Controlled by runtime flag
263263
``envoy.reloadable_features.tls_certificate_compression_brotli`` (defaults to ``true``).
264264
When disabled, QUIC retains zlib-only compression, while TCP TLS has no compression.
265-
- area: dynamic_modules
266-
change: |
267-
Added gRPC status support for the HTTP dynamic module filter SDKs. The ``send_response`` SDK
268-
methods now accept an optional gRPC status code which is passed as a ``grpc-status`` header,
269-
and the ``ResponseGrpcStatus`` attribute is now available to read gRPC status from responses.
270265
- area: dynamic_modules
271266
change: |
272267
Added custom metrics (counters, gauges, histograms) support to load balancer dynamic modules.

source/extensions/dynamic_modules/sdk/cpp/sdk.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -470,15 +470,11 @@ class HttpFilterHandle {
470470
/**
471471
* Sends a local response with status code, body, and detail.
472472
* @param status The HTTP status code.
473-
* @param headers The response headers.
474473
* @param body The response body.
475-
* @param grpc_status The gRPC status code for gRPC requests. Use -1 to indicate no gRPC status
476-
* (Envoy will infer from the HTTP status code). Values 0-16 are standard gRPC status codes.
477474
* @param detail The response detail.
478475
*/
479476
virtual void sendLocalResponse(uint32_t status, std::span<const HeaderView> headers,
480-
std::string_view body, int32_t grpc_status,
481-
std::string_view detail) = 0;
477+
std::string_view body, std::string_view detail) = 0;
482478

483479
/**
484480
* Sends response headers. This is used for streaming local replies.

source/extensions/dynamic_modules/sdk/cpp/sdk_internal.cc

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -384,26 +384,12 @@ class HttpFilterHandleImpl : public HttpFilterHandle {
384384
}
385385

386386
void sendLocalResponse(uint32_t status, std::span<const HeaderView> headers,
387-
std::string_view body, int32_t grpc_status,
388-
std::string_view detail) override {
389-
// When gRPC status is specified, include it as a grpc-status header so Envoy's sendLocalReply
390-
// picks it up via modify_headers without requiring an ABI change.
391-
std::string grpc_status_str;
392-
std::vector<HeaderView> merged_headers;
393-
const HeaderView* headers_ptr = headers.data();
394-
size_t headers_size = headers.size();
395-
if (grpc_status >= 0) {
396-
grpc_status_str = std::to_string(grpc_status);
397-
merged_headers.assign(headers.begin(), headers.end());
398-
merged_headers.emplace_back("grpc-status", grpc_status_str);
399-
headers_ptr = merged_headers.data();
400-
headers_size = merged_headers.size();
401-
}
387+
std::string_view body, std::string_view detail) override {
402388
envoy_dynamic_module_callback_http_send_response(
403389
host_plugin_ptr_, status,
404390
const_cast<envoy_dynamic_module_type_module_http_header*>(
405-
reinterpret_cast<const envoy_dynamic_module_type_module_http_header*>(headers_ptr)),
406-
headers_size, envoy_dynamic_module_type_module_buffer{body.data(), body.size()},
391+
reinterpret_cast<const envoy_dynamic_module_type_module_http_header*>(headers.data())),
392+
headers.size(), envoy_dynamic_module_type_module_buffer{body.data(), body.size()},
407393
envoy_dynamic_module_type_module_buffer{detail.data(), detail.size()});
408394
}
409395

source/extensions/dynamic_modules/sdk/go/abi/internal.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -720,17 +720,11 @@ func (h *dymHttpFilterHandle) SendLocalResponse(
720720
statusCode uint32,
721721
headers [][2]string,
722722
body []byte,
723-
grpcStatus int32,
724723
detail string,
725724
) {
726725
h.localResponseSent = true
727726

728-
// When gRPC status is specified, include it as a grpc-status header so Envoy's sendLocalReply
729-
// picks it up via modify_headers without requiring an ABI change.
730-
if grpcStatus >= 0 {
731-
headers = append(headers, [2]string{"grpc-status", strconv.Itoa(int(grpcStatus))})
732-
}
733-
727+
// Prepare headers.
734728
headerViews := headersToModuleHttpHeaderSlice(headers)
735729
C.envoy_dynamic_module_callback_http_send_response(
736730
h.hostPluginPtr,

source/extensions/dynamic_modules/sdk/go/shared/base.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -414,10 +414,8 @@ type HttpFilterHandle interface {
414414
// @Param status the HTTP status code.
415415
// @Param headers the response headers.
416416
// @Param body the response body.
417-
// @Param grpcStatus the gRPC status code for gRPC requests. Use -1 to indicate no gRPC status
418-
// (Envoy will infer from the HTTP status code). Values 0-16 are standard gRPC status codes.
419417
// @Param detail a short description to the response for debugging purposes.
420-
SendLocalResponse(status uint32, headers [][2]string, body []byte, grpcStatus int32, detail string)
418+
SendLocalResponse(status uint32, headers [][2]string, body []byte, detail string)
421419

422420
// SendResponseHeaders sends response headers to the client. This is used for
423421
// streaming local replies.

source/extensions/dynamic_modules/sdk/go/shared/mocks/mock_base.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

source/extensions/dynamic_modules/sdk/rust/src/http.rs

Lines changed: 3 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -846,16 +846,11 @@ pub trait EnvoyHttpFilter {
846846
/// Send a response to the downstream with the given status code, headers, and body.
847847
///
848848
/// The headers are passed as a list of key-value pairs.
849-
///
850-
/// The `grpc_status` parameter is the gRPC status code for gRPC requests. Use `None` to indicate
851-
/// no gRPC status (Envoy will infer from the HTTP status code). Values 0-16 are standard gRPC
852-
/// status codes. This is only meaningful when the downstream request is a gRPC request.
853849
fn send_response<'a>(
854850
&mut self,
855851
status_code: u32,
856852
headers: &'a [(&'a str, &'a [u8])],
857853
body: Option<&'a [u8]>,
858-
grpc_status: Option<i32>,
859854
details: Option<&'a str>,
860855
);
861856

@@ -1221,14 +1216,6 @@ pub trait EnvoyHttpFilter {
12211216
attribute_id: abi::envoy_dynamic_module_type_attribute_id,
12221217
) -> Option<bool>;
12231218

1224-
/// Get the gRPC status code from the response.
1225-
///
1226-
/// This checks response trailers, response headers, and infers from the HTTP status code.
1227-
/// Returns `None` if no gRPC status is available (e.g., the response is not a gRPC response).
1228-
fn get_response_grpc_status(&self) -> Option<i64> {
1229-
self.get_attribute_int(abi::envoy_dynamic_module_type_attribute_id::ResponseGrpcStatus)
1230-
}
1231-
12321219
/// Send an HTTP callout to the given cluster with the given headers and body.
12331220
/// Multiple callouts can be made from the same filter. Different callouts can be
12341221
/// distinguished by the returned callout id.
@@ -2140,37 +2127,21 @@ impl EnvoyHttpFilter for EnvoyHttpFilterImpl {
21402127
status_code: u32,
21412128
headers: &[(&str, &[u8])],
21422129
body: Option<&[u8]>,
2143-
grpc_status: Option<i32>,
21442130
details: Option<&str>,
21452131
) {
21462132
let body_ptr = body.map(|s| s.as_ptr()).unwrap_or(std::ptr::null());
21472133
let body_length = body.map(|s| s.len()).unwrap_or(0);
21482134
let details_ptr = details.map(|s| s.as_ptr()).unwrap_or(std::ptr::null());
21492135
let details_length = details.map(|s| s.len()).unwrap_or(0);
21502136

2151-
// When gRPC status is specified, include it as a grpc-status header so Envoy's sendLocalReply
2152-
// picks it up via modify_headers without requiring an ABI change.
2153-
let grpc_status_str;
2154-
let merged_headers;
2155-
let (final_headers_ptr, final_headers_len) = if let Some(status) = grpc_status {
2156-
grpc_status_str = status.to_string();
2157-
let mut h: Vec<(&str, &[u8])> = Vec::with_capacity(headers.len() + 1);
2158-
h.extend_from_slice(headers);
2159-
h.push(("grpc-status", grpc_status_str.as_bytes()));
2160-
merged_headers = h;
2161-
let HeaderPairSlice(ptr, len) = merged_headers.as_slice().into();
2162-
(ptr, len)
2163-
} else {
2164-
let HeaderPairSlice(ptr, len) = headers.into();
2165-
(ptr, len)
2166-
};
2137+
let HeaderPairSlice(headers_ptr, headers_len) = headers.into();
21672138

21682139
unsafe {
21692140
abi::envoy_dynamic_module_callback_http_send_response(
21702141
self.raw_ptr,
21712142
status_code,
2172-
final_headers_ptr as *mut _,
2173-
final_headers_len,
2143+
headers_ptr as *mut _,
2144+
headers_len,
21742145
abi::envoy_dynamic_module_type_module_buffer {
21752146
ptr: body_ptr as *mut _,
21762147
length: body_length,

source/extensions/filters/http/dynamic_modules/BUILD

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ envoy_cc_library(
5858
deps = [
5959
":filter_lib",
6060
"//envoy/registry",
61-
"//source/common/grpc:common_lib",
6261
"//source/common/http:utility_lib",
6362
"//source/common/network:upstream_socket_options_filter_state_lib",
6463
"//source/common/router:string_accessor_lib",

source/extensions/filters/http/dynamic_modules/abi_impl.cc

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "envoy/config/core/v3/socket_option.pb.h"
66
#include "envoy/registry/registry.h"
77

8-
#include "source/common/grpc/common.h"
98
#include "source/common/http/header_map_impl.h"
109
#include "source/common/http/message_impl.h"
1110
#include "source/common/http/utility.h"
@@ -666,8 +665,8 @@ void envoy_dynamic_module_callback_http_send_response(
666665
details_view = "dynamic_module";
667666
}
668667

669-
filter->sendLocalReply(static_cast<Http::Code>(status_code), body_view, modify_headers,
670-
absl::nullopt, details_view);
668+
filter->sendLocalReply(static_cast<Http::Code>(status_code), body_view, modify_headers, 0,
669+
details_view);
671670
}
672671

673672
void envoy_dynamic_module_callback_http_send_response_headers(
@@ -1426,22 +1425,6 @@ bool envoy_dynamic_module_callback_http_filter_get_attribute_int(
14261425
}
14271426
break;
14281427
}
1429-
case envoy_dynamic_module_type_attribute_id_ResponseGrpcStatus: {
1430-
auto* stream_info = filter->streamInfo();
1431-
if (stream_info) {
1432-
auto trailers = filter->responseTrailers();
1433-
auto headers = filter->responseHeaders();
1434-
auto grpc_status = Grpc::Common::getGrpcStatus(
1435-
trailers.has_value() ? *trailers : *Http::StaticEmptyHeaders::get().response_trailers,
1436-
headers.has_value() ? *headers : *Http::StaticEmptyHeaders::get().response_headers,
1437-
*stream_info);
1438-
if (grpc_status.has_value()) {
1439-
*result = grpc_status.value();
1440-
ok = true;
1441-
}
1442-
}
1443-
break;
1444-
}
14451428
default:
14461429
ENVOY_LOG_TO_LOGGER(Envoy::Logger::Registry::getLog(Envoy::Logger::Id::dynamic_modules), error,
14471430
"Unsupported attribute ID {} as int", static_cast<int64_t>(attribute_id));

test/extensions/dynamic_modules/http/abi_impl_test.cc

Lines changed: 10 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -403,9 +403,8 @@ TEST_P(DynamicModuleHttpFilterHeaderTest, GetHeaders) {
403403
}
404404

405405
TEST_F(DynamicModuleHttpFilterTest, SendResponseNullptr) {
406-
EXPECT_CALL(decoder_callbacks_,
407-
sendLocalReply(Envoy::Http::Code::OK, testing::Eq(""), _, testing::Eq(absl::nullopt),
408-
testing::Eq("dynamic_module")));
406+
EXPECT_CALL(decoder_callbacks_, sendLocalReply(Envoy::Http::Code::OK, testing::Eq(""), _,
407+
testing::Eq(0), testing::Eq("dynamic_module")));
409408
envoy_dynamic_module_callback_http_send_response(filter_.get(), 200, nullptr, 0, {nullptr, 0},
410409
{nullptr, 0});
411410
}
@@ -416,9 +415,8 @@ TEST_F(DynamicModuleHttpFilterTest, SendResponseEmptyResponse) {
416415
.WillRepeatedly(testing::Return(makeOptRef<ResponseHeaderMap>(response_headers)));
417416

418417
// Test with empty response.
419-
EXPECT_CALL(decoder_callbacks_,
420-
sendLocalReply(Envoy::Http::Code::OK, testing::Eq(""), _, testing::Eq(absl::nullopt),
421-
testing::Eq("dynamic_module")));
418+
EXPECT_CALL(decoder_callbacks_, sendLocalReply(Envoy::Http::Code::OK, testing::Eq(""), _,
419+
testing::Eq(0), testing::Eq("dynamic_module")));
422420
EXPECT_CALL(decoder_callbacks_, encodeHeaders_(_, _));
423421

424422
envoy_dynamic_module_callback_http_send_response(filter_.get(), 200, nullptr, 0, {nullptr, 0},
@@ -440,9 +438,8 @@ TEST_F(DynamicModuleHttpFilterTest, SendResponse) {
440438
header_array[index].value_ptr = const_cast<char*>(value.c_str());
441439
++index;
442440
}
443-
EXPECT_CALL(decoder_callbacks_,
444-
sendLocalReply(Envoy::Http::Code::OK, testing::Eq(""), _, testing::Eq(absl::nullopt),
445-
testing::Eq("dynamic_module")));
441+
EXPECT_CALL(decoder_callbacks_, sendLocalReply(Envoy::Http::Code::OK, testing::Eq(""), _,
442+
testing::Eq(0), testing::Eq("dynamic_module")));
446443
EXPECT_CALL(decoder_callbacks_, encodeHeaders_(_, _)).WillOnce(Invoke([](auto& headers, auto) {
447444
EXPECT_EQ(headers.get(Http::LowerCaseString("single"))[0]->value().getStringView(), "value");
448445
EXPECT_EQ(headers.get(Http::LowerCaseString("multi"))[0]->value().getStringView(), "value1");
@@ -470,9 +467,8 @@ TEST_F(DynamicModuleHttpFilterTest, SendResponseWithBody) {
470467
}
471468

472469
const std::string body_str = "body";
473-
EXPECT_CALL(decoder_callbacks_,
474-
sendLocalReply(Envoy::Http::Code::OK, testing::Eq("body"), _,
475-
testing::Eq(absl::nullopt), testing::Eq("dynamic_module")));
470+
EXPECT_CALL(decoder_callbacks_, sendLocalReply(Envoy::Http::Code::OK, testing::Eq("body"), _,
471+
testing::Eq(0), testing::Eq("dynamic_module")));
476472
EXPECT_CALL(decoder_callbacks_, encodeHeaders_(_, _)).WillOnce(Invoke([](auto& headers, auto) {
477473
EXPECT_EQ(headers.get(Http::LowerCaseString("single"))[0]->value().getStringView(), "value");
478474
EXPECT_EQ(headers.get(Http::LowerCaseString("multi"))[0]->value().getStringView(), "value1");
@@ -485,41 +481,13 @@ TEST_F(DynamicModuleHttpFilterTest, SendResponseWithBody) {
485481
TEST_F(DynamicModuleHttpFilterTest, SendResponseWithCustomResponseCodeDetails) {
486482
const std::string body_str = "body";
487483
absl::string_view test_details = "test_details";
488-
EXPECT_CALL(decoder_callbacks_,
489-
sendLocalReply(Envoy::Http::Code::OK, testing::Eq("body"), _,
490-
testing::Eq(absl::nullopt), testing::Eq("test_details")));
484+
EXPECT_CALL(decoder_callbacks_, sendLocalReply(Envoy::Http::Code::OK, testing::Eq("body"), _,
485+
testing::Eq(0), testing::Eq("test_details")));
491486
envoy_dynamic_module_callback_http_send_response(filter_.get(), 200, nullptr, 0,
492487
{body_str.data(), body_str.size()},
493488
{test_details.data(), test_details.size()});
494489
}
495490

496-
TEST_F(DynamicModuleHttpFilterTest, SendResponseWithGrpcStatusHeader) {
497-
// Verify that grpc-status passed as a header is forwarded via modify_headers.
498-
std::string grpc_status_key = "grpc-status";
499-
std::string grpc_status_value = "14";
500-
envoy_dynamic_module_type_module_http_header header_array[1];
501-
header_array[0].key_ptr = grpc_status_key.data();
502-
header_array[0].key_length = grpc_status_key.size();
503-
header_array[0].value_ptr = grpc_status_value.data();
504-
header_array[0].value_length = grpc_status_value.size();
505-
506-
EXPECT_CALL(decoder_callbacks_,
507-
sendLocalReply(Envoy::Http::Code::ServiceUnavailable, testing::Eq(""), _,
508-
testing::Eq(absl::nullopt), testing::Eq("dynamic_module")))
509-
.WillOnce(Invoke([](Http::Code, absl::string_view,
510-
std::function<void(Http::ResponseHeaderMap & headers)> modify_headers,
511-
absl::optional<Grpc::Status::GrpcStatus>, absl::string_view) {
512-
Http::TestResponseHeaderMapImpl headers;
513-
if (modify_headers) {
514-
modify_headers(headers);
515-
}
516-
EXPECT_EQ(headers.get(Http::LowerCaseString("grpc-status"))[0]->value().getStringView(),
517-
"14");
518-
}));
519-
envoy_dynamic_module_callback_http_send_response(filter_.get(), 503, header_array, 1,
520-
{nullptr, 0}, {nullptr, 0});
521-
}
522-
523491
TEST_F(DynamicModuleHttpFilterTest, AddCustomFlag) {
524492
// Test with empty response.
525493
EXPECT_CALL(decoder_callbacks_.stream_info_, addCustomFlag(testing::Eq("XXX")));
@@ -2016,67 +1984,6 @@ TEST(ABIImpl, GetAttributes) {
20161984
EXPECT_EQ(result_number, 8386);
20171985
}
20181986

2019-
TEST(ABIImpl, GetAttributeResponseGrpcStatus) {
2020-
Stats::SymbolTableImpl symbol_table;
2021-
DynamicModuleHttpFilter filter{nullptr, symbol_table, 0};
2022-
NiceMock<Http::MockStreamDecoderFilterCallbacks> decoder_callbacks;
2023-
NiceMock<Http::MockStreamEncoderFilterCallbacks> encoder_callbacks;
2024-
StreamInfo::MockStreamInfo stream_info;
2025-
EXPECT_CALL(decoder_callbacks, streamInfo()).WillRepeatedly(testing::ReturnRef(stream_info));
2026-
filter.setDecoderFilterCallbacks(decoder_callbacks);
2027-
filter.setEncoderFilterCallbacks(encoder_callbacks);
2028-
2029-
uint64_t result = 0;
2030-
2031-
// Without response trailers or headers, gRPC status should be inferred from HTTP response code.
2032-
EXPECT_CALL(encoder_callbacks, responseTrailers())
2033-
.WillRepeatedly(testing::Return(ResponseTrailerMapOptRef()));
2034-
EXPECT_CALL(encoder_callbacks, responseHeaders())
2035-
.WillRepeatedly(testing::Return(ResponseHeaderMapOptRef()));
2036-
EXPECT_CALL(stream_info, responseCode()).WillRepeatedly(testing::Return(503));
2037-
EXPECT_TRUE(envoy_dynamic_module_callback_http_filter_get_attribute_int(
2038-
&filter, envoy_dynamic_module_type_attribute_id_ResponseGrpcStatus, &result));
2039-
// HTTP 503 maps to gRPC Unavailable (14).
2040-
EXPECT_EQ(result, 14);
2041-
}
2042-
2043-
TEST(ABIImpl, GetAttributeResponseGrpcStatusFromTrailers) {
2044-
Stats::SymbolTableImpl symbol_table;
2045-
DynamicModuleHttpFilter filter{nullptr, symbol_table, 0};
2046-
NiceMock<Http::MockStreamDecoderFilterCallbacks> decoder_callbacks;
2047-
NiceMock<Http::MockStreamEncoderFilterCallbacks> encoder_callbacks;
2048-
StreamInfo::MockStreamInfo stream_info;
2049-
EXPECT_CALL(decoder_callbacks, streamInfo()).WillRepeatedly(testing::ReturnRef(stream_info));
2050-
filter.setDecoderFilterCallbacks(decoder_callbacks);
2051-
filter.setEncoderFilterCallbacks(encoder_callbacks);
2052-
2053-
uint64_t result = 0;
2054-
2055-
// With grpc-status in response trailers, that should take precedence.
2056-
Http::TestResponseTrailerMapImpl trailers{{"grpc-status", "7"}};
2057-
EXPECT_CALL(encoder_callbacks, responseTrailers())
2058-
.WillRepeatedly(testing::Return(makeOptRef<ResponseTrailerMap>(trailers)));
2059-
EXPECT_CALL(encoder_callbacks, responseHeaders())
2060-
.WillRepeatedly(testing::Return(ResponseHeaderMapOptRef()));
2061-
EXPECT_CALL(stream_info, responseCode()).WillRepeatedly(testing::Return(200));
2062-
EXPECT_TRUE(envoy_dynamic_module_callback_http_filter_get_attribute_int(
2063-
&filter, envoy_dynamic_module_type_attribute_id_ResponseGrpcStatus, &result));
2064-
// grpc-status: 7 = PermissionDenied.
2065-
EXPECT_EQ(result, 7);
2066-
}
2067-
2068-
TEST(ABIImpl, GetAttributeResponseGrpcStatusNotAvailable) {
2069-
Stats::SymbolTableImpl symbol_table;
2070-
DynamicModuleHttpFilter filter_without_callbacks{nullptr, symbol_table, 0};
2071-
2072-
uint64_t result = 0;
2073-
2074-
// Without callbacks, stream info is not available.
2075-
EXPECT_FALSE(envoy_dynamic_module_callback_http_filter_get_attribute_int(
2076-
&filter_without_callbacks, envoy_dynamic_module_type_attribute_id_ResponseGrpcStatus,
2077-
&result));
2078-
}
2079-
20801987
TEST(ABIImpl, HttpCallout) {
20811988
Stats::SymbolTableImpl symbol_table;
20821989
DynamicModuleHttpFilter filter{nullptr, symbol_table, 0};

0 commit comments

Comments
 (0)