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.
Adding http client support for ext_proc filter (envoyproxy#35676)
Risk Level: low Testing: n/a Docs Changes: n/a Release Notes: inline Fixes: Description: This is to address the 2st step of envoyproxy#35488, i.e, the ext_proc HTTP client framework. --------- Signed-off-by: Yanjun Xiang <yanjunxiang@google.com>
- Loading branch information
1 parent
157a4b2
commit dbb35fa
Showing
6 changed files
with
245 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
load( | ||
"//bazel:envoy_build_system.bzl", | ||
"envoy_cc_library", | ||
"envoy_extension_package", | ||
) | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
envoy_extension_package() | ||
|
||
envoy_cc_library( | ||
name = "client_base_interface", | ||
hdrs = ["client_base.h"], | ||
tags = ["skip_on_windows"], | ||
deps = [], | ||
) | ||
|
||
envoy_cc_library( | ||
name = "http_client_lib", | ||
srcs = ["http_client_impl.cc"], | ||
hdrs = ["http_client_impl.h"], | ||
tags = ["skip_on_windows"], | ||
deps = [ | ||
"client_base_interface", | ||
"//source/common/common:enum_to_int", | ||
"//source/common/http:utility_lib", | ||
"//source/extensions/filters/http/ext_proc", | ||
], | ||
) |
33 changes: 33 additions & 0 deletions
33
source/extensions/filters/http/ext_proc/http_client/client_base.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,33 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace HttpFilters { | ||
namespace ExternalProcessing { | ||
|
||
/** | ||
* Async callbacks used during external processing. | ||
*/ | ||
class RequestCallbacks { | ||
public: | ||
virtual ~RequestCallbacks() = default; | ||
virtual void onComplete() PURE; | ||
}; | ||
|
||
/** | ||
* Async client base class used during external processing. | ||
*/ | ||
class ClientBase { | ||
public: | ||
virtual ~ClientBase() = default; | ||
|
||
virtual void sendRequest() PURE; | ||
virtual void cancel() PURE; | ||
}; | ||
|
||
} // namespace ExternalProcessing | ||
} // namespace HttpFilters | ||
} // namespace Extensions | ||
} // namespace Envoy |
45 changes: 45 additions & 0 deletions
45
source/extensions/filters/http/ext_proc/http_client/http_client_impl.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,45 @@ | ||
#include "source/extensions/filters/http/ext_proc/http_client/http_client_impl.h" | ||
|
||
#include "source/common/common/enum_to_int.h" | ||
#include "source/common/http/utility.h" | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace HttpFilters { | ||
namespace ExternalProcessing { | ||
|
||
void ExtProcHttpClient::onSuccess(const Http::AsyncClient::Request&, | ||
Http::ResponseMessagePtr&& response) { | ||
auto status = Envoy::Http::Utility::getResponseStatusOrNullopt(response->headers()); | ||
if (status.has_value()) { | ||
uint64_t status_code = status.value(); | ||
if (status_code == Envoy::enumToInt(Envoy::Http::Code::OK)) { | ||
ENVOY_LOG(error, "Response status is OK"); | ||
} else { | ||
ENVOY_LOG(error, "Response status is not OK, status: {}", status_code); | ||
onError(); | ||
} | ||
} else { | ||
// This occurs if the response headers are invalid. | ||
ENVOY_LOG(error, "Failed to get the response because response headers are not valid."); | ||
onError(); | ||
} | ||
} | ||
|
||
void ExtProcHttpClient::onFailure(const Http::AsyncClient::Request&, | ||
Http::AsyncClient::FailureReason reason) { | ||
ASSERT(reason == Http::AsyncClient::FailureReason::Reset || | ||
reason == Http::AsyncClient::FailureReason::ExceedResponseBufferLimit); | ||
ENVOY_LOG(error, "Request failed: stream has been reset"); | ||
onError(); | ||
} | ||
|
||
void ExtProcHttpClient::onError() { | ||
// Cancel if the request is active. | ||
cancel(); | ||
} | ||
|
||
} // namespace ExternalProcessing | ||
} // namespace HttpFilters | ||
} // namespace Extensions | ||
} // namespace Envoy |
47 changes: 47 additions & 0 deletions
47
source/extensions/filters/http/ext_proc/http_client/http_client_impl.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,47 @@ | ||
#pragma once | ||
|
||
#include <memory> | ||
|
||
#include "envoy/http/async_client.h" | ||
|
||
#include "source/common/common/logger.h" | ||
#include "source/extensions/filters/http/ext_proc/ext_proc.h" | ||
#include "source/extensions/filters/http/ext_proc/http_client/client_base.h" | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace HttpFilters { | ||
namespace ExternalProcessing { | ||
|
||
class ExtProcHttpClient : public ClientBase, | ||
public Http::AsyncClient::Callbacks, | ||
public Logger::Loggable<Logger::Id::init> { | ||
public: | ||
ExtProcHttpClient(const envoy::extensions::filters::http::ext_proc::v3::ExternalProcessor& config, | ||
Server::Configuration::ServerFactoryContext& context) | ||
: config_(config), context_(context) {} | ||
|
||
~ExtProcHttpClient() { cancel(); } | ||
|
||
void sendRequest() override {} | ||
void cancel() override {} | ||
void onBeforeFinalizeUpstreamSpan(Tracing::Span&, const Http::ResponseHeaderMap*) override {} | ||
|
||
// Http::AsyncClient::Callbacks implemented by this class. | ||
void onSuccess(const Http::AsyncClient::Request& request, | ||
Http::ResponseMessagePtr&& response) override; | ||
void onFailure(const Http::AsyncClient::Request& request, | ||
Http::AsyncClient::FailureReason reason) override; | ||
|
||
Server::Configuration::ServerFactoryContext& context() const { return context_; } | ||
|
||
private: | ||
void onError(); | ||
envoy::extensions::filters::http::ext_proc::v3::ExternalProcessor config_; | ||
Server::Configuration::ServerFactoryContext& context_; | ||
}; | ||
|
||
} // namespace ExternalProcessing | ||
} // namespace HttpFilters | ||
} // namespace Extensions | ||
} // namespace Envoy |
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,26 @@ | ||
load( | ||
"//bazel:envoy_build_system.bzl", | ||
"envoy_package", | ||
) | ||
load( | ||
"//test/extensions:extensions_build_system.bzl", | ||
"envoy_extension_cc_test", | ||
) | ||
|
||
licenses(["notice"]) # Apache 2 | ||
|
||
envoy_package() | ||
|
||
envoy_extension_cc_test( | ||
name = "http_client_test", | ||
size = "small", | ||
srcs = ["http_client_test.cc"], | ||
extension_names = ["envoy.filters.http.ext_proc"], | ||
tags = ["skip_on_windows"], | ||
deps = [ | ||
"//source/common/http:message_lib", | ||
"//source/extensions/filters/http/ext_proc/http_client:http_client_lib", | ||
"//test/mocks/server:factory_context_mocks", | ||
"@envoy_api//envoy/extensions/filters/http/ext_proc/v3:pkg_cc_proto", | ||
], | ||
) |
65 changes: 65 additions & 0 deletions
65
test/extensions/filters/http/ext_proc/http_client/http_client_test.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,65 @@ | ||
#include "envoy/extensions/filters/http/ext_proc/v3/ext_proc.pb.h" | ||
|
||
#include "source/common/http/message_impl.h" | ||
#include "source/extensions/filters/http/ext_proc/http_client/http_client_impl.h" | ||
|
||
#include "test/mocks/server/server_factory_context.h" | ||
|
||
#include "gmock/gmock.h" | ||
#include "gtest/gtest.h" | ||
|
||
namespace Envoy { | ||
namespace Extensions { | ||
namespace HttpFilters { | ||
namespace ExternalProcessing { | ||
namespace { | ||
|
||
class ExtProcHttpClientTest : public testing::Test { | ||
public: | ||
~ExtProcHttpClientTest() override = default; | ||
|
||
void SetUp() override { client_ = std::make_unique<ExtProcHttpClient>(config_, context_); } | ||
|
||
protected: | ||
envoy::extensions::filters::http::ext_proc::v3::ExternalProcessor config_; | ||
testing::NiceMock<Server::Configuration::MockServerFactoryContext> context_; | ||
Upstream::MockClusterManager& cm_{context_.cluster_manager_}; | ||
std::unique_ptr<ExtProcHttpClient> client_; | ||
testing::NiceMock<Http::MockAsyncClientRequest> async_request_{ | ||
&cm_.thread_local_cluster_.async_client_}; | ||
}; | ||
|
||
TEST_F(ExtProcHttpClientTest, Basic) { | ||
SetUp(); | ||
client_->sendRequest(); | ||
client_->cancel(); | ||
client_->context(); | ||
Tracing::MockSpan parent_span; | ||
client_->onBeforeFinalizeUpstreamSpan(parent_span, nullptr); | ||
Http::AsyncClient::FailureReason reason = Envoy::Http::AsyncClient::FailureReason::Reset; | ||
client_->onFailure(async_request_, reason); | ||
|
||
Http::ResponseHeaderMapPtr resp_headers_ok(new Http::TestResponseHeaderMapImpl({ | ||
{":status", "200"}, | ||
})); | ||
Http::ResponseMessagePtr response_ok(new Http::ResponseMessageImpl(std::move(resp_headers_ok))); | ||
client_->onSuccess(async_request_, std::move(response_ok)); | ||
|
||
Http::ResponseHeaderMapPtr resp_headers(new Http::TestResponseHeaderMapImpl({ | ||
{":status", "403"}, | ||
})); | ||
Http::ResponseMessagePtr response(new Http::ResponseMessageImpl(std::move(resp_headers))); | ||
client_->onSuccess(async_request_, std::move(response)); | ||
|
||
Http::ResponseHeaderMapPtr resp_headers_foo(new Http::TestResponseHeaderMapImpl({ | ||
{":status", "foo"}, | ||
})); | ||
Http::ResponseMessagePtr response_foo(new Http::ResponseMessageImpl(std::move(resp_headers_foo))); | ||
client_->onSuccess(async_request_, std::move(response_foo)); | ||
} | ||
|
||
} // namespace | ||
} // namespace ExternalProcessing | ||
} // namespace HttpFilters | ||
} // namespace Extensions | ||
} // namespace Envoy |