forked from envoyproxy/envoy
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhttp_integration.h
204 lines (178 loc) · 8.56 KB
/
http_integration.h
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
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#pragma once
#include <cstdint>
#include <memory>
#include <string>
#include "common/http/codec_client.h"
#include "common/network/filter_impl.h"
#include "test/integration/integration.h"
#include "test/integration/utility.h"
#include "test/test_common/printers.h"
namespace Envoy {
/**
* HTTP codec client used during integration testing.
*/
class IntegrationCodecClient : public Http::CodecClientProd {
public:
IntegrationCodecClient(Event::Dispatcher& dispatcher, Network::ClientConnectionPtr&& conn,
Upstream::HostDescriptionConstSharedPtr host_description,
Http::CodecClient::Type type);
IntegrationStreamDecoderPtr makeHeaderOnlyRequest(const Http::HeaderMap& headers);
IntegrationStreamDecoderPtr makeRequestWithBody(const Http::HeaderMap& headers,
uint64_t body_size);
bool sawGoAway() const { return saw_goaway_; }
bool connected() const { return connected_; }
void sendData(Http::StreamEncoder& encoder, absl::string_view data, bool end_stream);
void sendData(Http::StreamEncoder& encoder, Buffer::Instance& data, bool end_stream);
void sendData(Http::StreamEncoder& encoder, uint64_t size, bool end_stream);
void sendTrailers(Http::StreamEncoder& encoder, const Http::HeaderMap& trailers);
void sendReset(Http::StreamEncoder& encoder);
std::pair<Http::StreamEncoder&, IntegrationStreamDecoderPtr>
startRequest(const Http::HeaderMap& headers);
bool waitForDisconnect(std::chrono::milliseconds time_to_wait = std::chrono::milliseconds(0));
Network::ClientConnection* connection() const { return connection_.get(); }
Network::ConnectionEvent last_connection_event() const { return last_connection_event_; }
private:
struct ConnectionCallbacks : public Network::ConnectionCallbacks {
ConnectionCallbacks(IntegrationCodecClient& parent) : parent_(parent) {}
// Network::ConnectionCallbacks
void onEvent(Network::ConnectionEvent event) override;
void onAboveWriteBufferHighWatermark() override {}
void onBelowWriteBufferLowWatermark() override {}
IntegrationCodecClient& parent_;
};
struct CodecCallbacks : public Http::ConnectionCallbacks {
CodecCallbacks(IntegrationCodecClient& parent) : parent_(parent) {}
// Http::ConnectionCallbacks
void onGoAway() override { parent_.saw_goaway_ = true; }
IntegrationCodecClient& parent_;
};
void flushWrite();
Event::Dispatcher& dispatcher_;
ConnectionCallbacks callbacks_;
CodecCallbacks codec_callbacks_;
bool connected_{};
bool disconnected_{};
bool saw_goaway_{};
Network::ConnectionEvent last_connection_event_;
};
typedef std::unique_ptr<IntegrationCodecClient> IntegrationCodecClientPtr;
/**
* Test fixture for HTTP and HTTP/2 integration tests.
*/
class HttpIntegrationTest : public BaseIntegrationTest {
public:
HttpIntegrationTest(Http::CodecClient::Type downstream_protocol,
Network::Address::IpVersion version, TestTimeSystemPtr time_system,
const std::string& config = ConfigHelper::HTTP_PROXY_CONFIG);
virtual ~HttpIntegrationTest();
protected:
IntegrationCodecClientPtr makeHttpConnection(uint32_t port);
// Makes a http connection object without checking its connected state.
IntegrationCodecClientPtr makeRawHttpConnection(Network::ClientConnectionPtr&& conn);
// Makes a http connection object with asserting a connected state.
IntegrationCodecClientPtr makeHttpConnection(Network::ClientConnectionPtr&& conn);
// Sets downstream_protocol_ and alters the HTTP connection manager codec type in the
// config_helper_.
void setDownstreamProtocol(Http::CodecClient::Type type);
// Sends |request_headers| and |request_body_size| bytes of body upstream.
// Configured upstream to send |response_headers| and |response_body_size|
// bytes of body downstream.
//
// Waits for the complete downstream response before returning.
// Requires |codec_client_| to be initialized.
IntegrationStreamDecoderPtr sendRequestAndWaitForResponse(
const Http::TestHeaderMapImpl& request_headers, uint32_t request_body_size,
const Http::TestHeaderMapImpl& response_headers, uint32_t response_body_size);
// Wait for the end of stream on the next upstream stream on any of the provided fake upstreams.
// Sets fake_upstream_connection_ to the connection and upstream_request_ to stream.
// In cases where the upstream that will receive the request is not deterministic, a second
// upstream index may be provided, in which case both upstreams will be checked for requests.
uint64_t waitForNextUpstreamRequest(const std::vector<uint64_t>& upstream_indices);
void waitForNextUpstreamRequest(uint64_t upstream_index = 0);
// Close |codec_client_| and |fake_upstream_connection_| cleanly.
void cleanupUpstreamAndDownstream();
typedef std::function<Network::ClientConnectionPtr()> ConnectionCreationFunction;
void testRouterRedirect();
void testRouterDirectResponse();
void testRouterNotFound();
void testRouterNotFoundWithBody();
void testRouterClusterNotFound404();
void testRouterClusterNotFound503();
void testRouterRequestAndResponseWithBody(uint64_t request_size, uint64_t response_size,
bool big_header,
ConnectionCreationFunction* creator = nullptr);
void testRouterHeaderOnlyRequestAndResponse(bool close_upstream,
ConnectionCreationFunction* creator = nullptr);
void testRouterUpstreamDisconnectBeforeRequestComplete();
void
testRouterUpstreamDisconnectBeforeResponseComplete(ConnectionCreationFunction* creator = nullptr);
void testRouterDownstreamDisconnectBeforeRequestComplete(
ConnectionCreationFunction* creator = nullptr);
void testRouterDownstreamDisconnectBeforeResponseComplete(
ConnectionCreationFunction* creator = nullptr);
void testRouterUpstreamResponseBeforeRequestComplete();
void testTwoRequests(bool force_network_backup = false);
void testOverlyLongHeaders();
void testIdleTimeoutBasic();
void testIdleTimeoutWithTwoRequests();
void testIdleTimerDisabled();
void testUpstreamDisconnectWithTwoRequests();
// HTTP/1 tests
void testBadFirstline();
void testMissingDelimiter();
void testInvalidCharacterInFirstline();
void testInvalidVersion();
void testHttp10Disabled();
void testHttp09Enabled();
void testHttp10Enabled();
void testHttp10WithHostAndKeepAlive();
void testUpstreamProtocolError();
void testBadPath();
void testAbsolutePath();
void testAbsolutePathWithPort();
void testAbsolutePathWithoutPort();
void testConnect();
void testInlineHeaders();
void testAllowAbsoluteSameRelative();
// Test that a request returns the same content with both allow_absolute_urls enabled and
// allow_absolute_urls disabled
void testEquivalent(const std::string& request);
void testNoHost();
void testDefaultHost();
void testValidZeroLengthContent();
void testInvalidContentLength();
void testMultipleContentLengths();
void testComputedHealthCheck();
void testAddEncodedTrailers();
void testDrainClose();
void testRetry();
void testRetryHittingBufferLimit();
void testRetryAttemptCountHeader();
void testGrpcRouterNotFound();
void testGrpcRetry();
void testRetryPriority();
void testRetryHostPredicateFilter();
void testHittingDecoderFilterLimit();
void testHittingEncoderFilterLimit();
void testEnvoyHandling100Continue(bool additional_continue_from_upstream = false,
const std::string& via = "");
void testEnvoyProxying100Continue(bool continue_before_upstream_complete = false,
bool with_encoder_filter = false);
// HTTP/2 client tests.
void testDownstreamResetBeforeResponseComplete();
void testTrailers(uint64_t request_size, uint64_t response_size);
Http::CodecClient::Type downstreamProtocol() const { return downstream_protocol_; }
// The client making requests to Envoy.
IntegrationCodecClientPtr codec_client_;
// A placeholder for the first upstream connection.
FakeHttpConnectionPtr fake_upstream_connection_;
// A placeholder for the first request received at upstream.
FakeStreamPtr upstream_request_;
// A pointer to the request encoder, if used.
Http::StreamEncoder* request_encoder_{nullptr};
// The response headers sent by sendRequestAndWaitForResponse() by default.
Http::TestHeaderMapImpl default_response_headers_{{":status", "200"}};
// The codec type for the client-to-Envoy connection
Http::CodecClient::Type downstream_protocol_{Http::CodecClient::Type::HTTP1};
};
} // namespace Envoy