forked from envoyproxy/envoy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
autonomous_upstream.cc
125 lines (102 loc) · 4.84 KB
/
autonomous_upstream.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "test/integration/autonomous_upstream.h"
namespace Envoy {
namespace {
void HeaderToInt(const char header_name[], int32_t& return_int, Http::TestHeaderMapImpl& headers) {
const std::string header_value(headers.get_(header_name));
if (!header_value.empty()) {
uint64_t parsed_value;
RELEASE_ASSERT(absl::SimpleAtoi(header_value, &parsed_value) &&
parsed_value < static_cast<uint32_t>(std::numeric_limits<int32_t>::max()),
"");
return_int = parsed_value;
}
}
} // namespace
const char AutonomousStream::RESPONSE_SIZE_BYTES[] = "response_size_bytes";
const char AutonomousStream::EXPECT_REQUEST_SIZE_BYTES[] = "expect_request_size_bytes";
const char AutonomousStream::RESET_AFTER_REQUEST[] = "reset_after_request";
AutonomousStream::AutonomousStream(FakeHttpConnection& parent, Http::ResponseEncoder& encoder,
AutonomousUpstream& upstream, bool allow_incomplete_streams)
: FakeStream(parent, encoder, upstream.timeSystem()), upstream_(upstream),
allow_incomplete_streams_(allow_incomplete_streams) {}
AutonomousStream::~AutonomousStream() {
if (!allow_incomplete_streams_) {
RELEASE_ASSERT(complete(), "Found that end_stream is not true");
}
}
// By default, automatically send a response when the request is complete.
void AutonomousStream::setEndStream(bool end_stream) {
FakeStream::setEndStream(end_stream);
if (end_stream) {
sendResponse();
}
}
// Check all the special headers and send a customized response based on them.
void AutonomousStream::sendResponse() {
Http::TestHeaderMapImpl headers(*headers_);
upstream_.setLastRequestHeaders(*headers_);
int32_t request_body_length = -1;
HeaderToInt(EXPECT_REQUEST_SIZE_BYTES, request_body_length, headers);
if (request_body_length >= 0) {
EXPECT_EQ(request_body_length, bodyLength());
}
if (!headers.get_(RESET_AFTER_REQUEST).empty()) {
encodeResetStream();
return;
}
int32_t response_body_length = 10;
HeaderToInt(RESPONSE_SIZE_BYTES, response_body_length, headers);
encodeHeaders(upstream_.responseHeaders(), false);
encodeData(response_body_length, true);
}
AutonomousHttpConnection::AutonomousHttpConnection(SharedConnectionWrapper& shared_connection,
Stats::Store& store, Type type,
AutonomousUpstream& upstream)
: FakeHttpConnection(shared_connection, store, type, upstream.timeSystem(),
Http::DEFAULT_MAX_REQUEST_HEADERS_KB, Http::DEFAULT_MAX_HEADERS_COUNT,
envoy::config::core::v3::HttpProtocolOptions::ALLOW),
upstream_(upstream) {}
Http::RequestDecoder& AutonomousHttpConnection::newStream(Http::ResponseEncoder& response_encoder,
bool) {
auto stream =
new AutonomousStream(*this, response_encoder, upstream_, upstream_.allow_incomplete_streams_);
streams_.push_back(FakeStreamPtr{stream});
return *(stream);
}
AutonomousUpstream::~AutonomousUpstream() {
// Make sure the dispatcher is stopped before the connections are destroyed.
cleanUp();
http_connections_.clear();
}
bool AutonomousUpstream::createNetworkFilterChain(Network::Connection& connection,
const std::vector<Network::FilterFactoryCb>&) {
shared_connections_.emplace_back(new SharedConnectionWrapper(connection, true));
AutonomousHttpConnectionPtr http_connection(
new AutonomousHttpConnection(*shared_connections_.back(), stats_store_, http_type_, *this));
testing::AssertionResult result = http_connection->initialize();
RELEASE_ASSERT(result, result.message());
http_connections_.push_back(std::move(http_connection));
return true;
}
bool AutonomousUpstream::createListenerFilterChain(Network::ListenerFilterManager&) { return true; }
void AutonomousUpstream::createUdpListenerFilterChain(Network::UdpListenerFilterManager&,
Network::UdpReadFilterCallbacks&) {}
void AutonomousUpstream::setLastRequestHeaders(const Http::HeaderMap& headers) {
Thread::LockGuard lock(headers_lock_);
last_request_headers_ = std::make_unique<Http::TestRequestHeaderMapImpl>(headers);
}
std::unique_ptr<Http::TestRequestHeaderMapImpl> AutonomousUpstream::lastRequestHeaders() {
Thread::LockGuard lock(headers_lock_);
return std::move(last_request_headers_);
}
void AutonomousUpstream::setResponseHeaders(
std::unique_ptr<Http::TestResponseHeaderMapImpl>&& response_headers) {
Thread::LockGuard lock(headers_lock_);
response_headers_ = std::move(response_headers);
}
Http::TestHeaderMapImpl AutonomousUpstream::responseHeaders() {
Thread::LockGuard lock(headers_lock_);
Http::TestHeaderMapImpl return_headers = *response_headers_;
return return_headers;
}
} // namespace Envoy