23 #include <gtest/gtest.h>
24 #include "absl/memory/memory.h"
25 #include "tensorflow_serving/util/net_http/client/test_client/internal/evhttp_connection.h"
26 #include "tensorflow_serving/util/net_http/compression/gzip_zlib.h"
27 #include "tensorflow_serving/util/net_http/internal/fixed_thread_pool.h"
28 #include "tensorflow_serving/util/net_http/public/response_code_enum.h"
29 #include "tensorflow_serving/util/net_http/server/internal/evhttp_server.h"
30 #include "tensorflow_serving/util/net_http/server/public/httpserver.h"
31 #include "tensorflow_serving/util/net_http/server/public/httpserver_interface.h"
32 #include "tensorflow_serving/util/net_http/server/public/server_request_interface.h"
34 namespace tensorflow {
39 class MyExecutor final :
public EventExecutor {
41 explicit MyExecutor(
int num_threads) : thread_pool_(num_threads) {}
43 void Schedule(std::function<
void()> fn)
override {
44 thread_pool_.Schedule(fn);
48 FixedThreadPool thread_pool_;
51 class EvHTTPRequestTest :
public ::testing::Test {
53 void SetUp()
override { InitServer(); }
55 void TearDown()
override {
56 if (!server->is_terminating()) {
58 server->WaitForTermination();
63 std::unique_ptr<HTTPServerInterface> server;
67 auto options = absl::make_unique<ServerOptions>();
69 options->SetExecutor(absl::make_unique<MyExecutor>(4));
71 server = CreateEvHTTPServer(std::move(options));
73 ASSERT_TRUE(server !=
nullptr);
78 TEST_F(EvHTTPRequestTest, SimpleGETNotFound) {
79 server->StartAcceptingRequests();
82 TestEvHTTPConnection::Connect(
"localhost", server->listen_port());
83 ASSERT_TRUE(connection !=
nullptr);
85 TestClientRequest request = {
"/noop",
"GET", {},
""};
86 TestClientResponse response = {};
88 EXPECT_TRUE(connection->BlockingSendRequest(request, &response));
89 EXPECT_EQ(response.status, HTTPStatusCode::NOT_FOUND);
90 EXPECT_FALSE(response.body.empty());
93 server->WaitForTermination();
97 TEST_F(EvHTTPRequestTest, SimpleGETOK) {
98 auto handler = [](ServerRequestInterface* request) {
99 request->WriteResponseString(
"OK");
102 server->RegisterRequestHandler(
"/ok", std::move(handler),
103 RequestHandlerOptions());
104 server->StartAcceptingRequests();
107 TestEvHTTPConnection::Connect(
"localhost", server->listen_port());
108 ASSERT_TRUE(connection !=
nullptr);
110 TestClientRequest request = {
"/ok",
"GET", {},
""};
111 TestClientResponse response = {};
113 EXPECT_TRUE(connection->BlockingSendRequest(request, &response));
114 EXPECT_EQ(response.status, HTTPStatusCode::OK);
115 EXPECT_EQ(response.body,
"OK");
118 server->WaitForTermination();
122 TEST_F(EvHTTPRequestTest, SimplePOST) {
123 auto handler = [](ServerRequestInterface* request) {
125 auto request_chunk = request->ReadRequestBytes(&num_bytes);
126 while (request_chunk !=
nullptr) {
127 request->WriteResponseBytes(request_chunk.get(), num_bytes);
128 request_chunk = request->ReadRequestBytes(&num_bytes);
132 server->RegisterRequestHandler(
"/ok", std::move(handler),
133 RequestHandlerOptions());
134 server->StartAcceptingRequests();
137 TestEvHTTPConnection::Connect(
"localhost", server->listen_port());
138 ASSERT_TRUE(connection !=
nullptr);
140 TestClientRequest request = {
"/ok",
"POST", {},
"abcde"};
141 TestClientResponse response = {};
143 EXPECT_TRUE(connection->BlockingSendRequest(request, &response));
144 EXPECT_EQ(response.status, HTTPStatusCode::OK);
145 EXPECT_EQ(response.body,
"abcde");
148 server->WaitForTermination();
152 TEST_F(EvHTTPRequestTest, RequestUri) {
153 static const char*
const kUriPath[] = {
159 "/path?param=value#fragment",
160 "/path?param=value%20value",
164 auto handler = [&counter](ServerRequestInterface* request) {
165 EXPECT_EQ(kUriPath[counter++], request->uri_path());
168 server->RegisterRequestDispatcher(
169 [&handler](ServerRequestInterface* request) -> RequestHandler {
172 RequestHandlerOptions());
174 server->StartAcceptingRequests();
177 TestEvHTTPConnection::Connect(
"localhost", server->listen_port());
178 ASSERT_TRUE(connection !=
nullptr);
180 for (
const char* path : kUriPath) {
181 TestClientRequest request = {path,
"GET", {},
""};
182 TestClientResponse response = {};
184 EXPECT_TRUE(connection->BlockingSendRequest(request, &response));
188 server->WaitForTermination();
192 TEST_F(EvHTTPRequestTest, RequestHeaders) {
193 auto handler = [](ServerRequestInterface* request) {
194 EXPECT_GT(request->request_headers().size(), 2);
195 EXPECT_EQ(request->GetRequestHeader(
"H1"),
"v1");
196 EXPECT_EQ(request->GetRequestHeader(
"h1"),
"v1");
197 EXPECT_EQ(request->GetRequestHeader(
"H2"),
"v2");
198 request->WriteResponseString(
"OK");
201 server->RegisterRequestHandler(
"/ok", std::move(handler),
202 RequestHandlerOptions());
203 server->StartAcceptingRequests();
206 TestEvHTTPConnection::Connect(
"localhost", server->listen_port());
207 ASSERT_TRUE(connection !=
nullptr);
209 TestClientRequest request = {
"/ok",
211 {TestClientRequest::HeaderKeyValue(
"H1",
"v1"),
212 TestClientRequest::HeaderKeyValue(
"H2",
"v2")},
214 TestClientResponse response = {};
216 EXPECT_TRUE(connection->BlockingSendRequest(request, &response));
217 EXPECT_EQ(response.status, HTTPStatusCode::OK);
218 EXPECT_EQ(response.body,
"OK");
221 server->WaitForTermination();
225 TEST_F(EvHTTPRequestTest, ResponseHeaders) {
226 auto handler = [](ServerRequestInterface* request) {
227 request->AppendResponseHeader(
"H1",
"V1");
228 request->AppendResponseHeader(
"H2",
"V2");
229 request->OverwriteResponseHeader(
"h2",
"v2");
230 request->WriteResponseString(
"OK");
233 server->RegisterRequestHandler(
"/ok", std::move(handler),
234 RequestHandlerOptions());
235 server->StartAcceptingRequests();
238 TestEvHTTPConnection::Connect(
"localhost", server->listen_port());
239 ASSERT_TRUE(connection !=
nullptr);
241 TestClientRequest request = {
"/ok",
"GET", {},
""};
242 TestClientResponse response = {};
244 EXPECT_TRUE(connection->BlockingSendRequest(request, &response));
245 for (
auto keyvalue : response.headers) {
246 if (keyvalue.first ==
"H1") {
247 EXPECT_EQ(keyvalue.second,
"V1");
248 }
else if (keyvalue.first ==
"H2") {
249 FAIL() <<
"H2 should have been overwritten by h2";
250 }
else if (keyvalue.first ==
"h2") {
251 EXPECT_EQ(keyvalue.second,
"v2");
254 EXPECT_EQ(response.status, HTTPStatusCode::OK);
255 EXPECT_EQ(response.body,
"OK");
258 server->WaitForTermination();
264 TEST_F(EvHTTPRequestTest, InvalidGzipPost) {
265 auto handler = [](ServerRequestInterface* request) {
267 auto request_body = request->ReadRequestBytes(&num_bytes);
268 EXPECT_TRUE(request_body ==
nullptr);
269 EXPECT_EQ(0, num_bytes);
273 server->RegisterRequestHandler(
"/ok", std::move(handler),
274 RequestHandlerOptions());
275 server->StartAcceptingRequests();
278 TestEvHTTPConnection::Connect(
"localhost", server->listen_port());
279 ASSERT_TRUE(connection !=
nullptr);
281 TestClientRequest request = {
"/ok",
"POST", {},
"abcde"};
282 request.headers.emplace_back(
"Content-Encoding",
"my_gzip");
283 TestClientResponse response = {};
285 EXPECT_TRUE(connection->BlockingSendRequest(request, &response));
286 EXPECT_EQ(response.status, HTTPStatusCode::OK);
289 server->WaitForTermination();
293 TEST_F(EvHTTPRequestTest, DisableGzipPost) {
294 auto handler = [](ServerRequestInterface* request) {
296 auto request_body = request->ReadRequestBytes(&num_bytes);
297 EXPECT_EQ(5, num_bytes);
301 RequestHandlerOptions options;
302 options.set_auto_uncompress_input(
false);
303 server->RegisterRequestHandler(
"/ok", std::move(handler), options);
304 server->StartAcceptingRequests();
307 TestEvHTTPConnection::Connect(
"localhost", server->listen_port());
308 ASSERT_TRUE(connection !=
nullptr);
310 TestClientRequest request = {
"/ok",
"POST", {},
"abcde"};
311 request.headers.emplace_back(
"Content-Encoding",
"my_gzip");
312 TestClientResponse response = {};
314 EXPECT_TRUE(connection->BlockingSendRequest(request, &response));
315 EXPECT_EQ(response.status, HTTPStatusCode::OK);
318 server->WaitForTermination();
321 std::string CompressLargeString(
const char* data,
size_t size,
324 std::string buf(buf_size,
'\0');
325 size_t compressed_size = buf.size();
326 zlib.Compress((Bytef*)buf.data(), &compressed_size, (Bytef*)data, size);
328 return std::string(buf.data(), compressed_size);
331 std::string CompressString(
const char* data,
size_t size) {
332 return CompressLargeString(data, size, 1024);
336 TEST_F(EvHTTPRequestTest, ValidGzipPost) {
337 constexpr
char kBody[] =
"abcdefg12345";
338 std::string compressed = CompressString(kBody,
sizeof(kBody) - 1);
340 auto handler = [&](ServerRequestInterface* request) {
342 auto request_body = request->ReadRequestBytes(&num_bytes);
344 std::string body_str(request_body.get(),
static_cast<size_t>(num_bytes));
345 EXPECT_EQ(body_str, std::string(kBody));
346 EXPECT_EQ(
sizeof(kBody) - 1, num_bytes);
348 EXPECT_EQ(
nullptr, request->ReadRequestBytes(&num_bytes));
349 EXPECT_EQ(0, num_bytes);
353 server->RegisterRequestHandler(
"/ok", std::move(handler),
354 RequestHandlerOptions());
355 server->StartAcceptingRequests();
358 TestEvHTTPConnection::Connect(
"localhost", server->listen_port());
359 ASSERT_TRUE(connection !=
nullptr);
361 TestClientRequest request = {
"/ok",
"POST", {}, compressed};
362 request.headers.emplace_back(
"Content-Encoding",
"my_gzip");
363 TestClientResponse response = {};
365 EXPECT_TRUE(connection->BlockingSendRequest(request, &response));
366 EXPECT_EQ(response.status, HTTPStatusCode::OK);
369 server->WaitForTermination();
373 TEST_F(EvHTTPRequestTest, GzipExceedingLimit) {
374 constexpr
char kBody[] =
"abcdefg12345";
375 constexpr
int bodySize =
sizeof(kBody) - 1;
376 std::string compressed = CompressString(kBody,
static_cast<size_t>(bodySize));
378 auto handler = [&](ServerRequestInterface* request) {
380 auto request_body = request->ReadRequestBytes(&num_bytes);
382 std::string body_str(request_body.get(),
static_cast<size_t>(num_bytes));
383 EXPECT_TRUE(request_body ==
nullptr);
384 EXPECT_EQ(0, num_bytes);
389 RequestHandlerOptions options;
390 options.set_auto_uncompress_max_size(bodySize - 1);
391 server->RegisterRequestHandler(
"/ok", std::move(handler), options);
392 server->StartAcceptingRequests();
395 TestEvHTTPConnection::Connect(
"localhost", server->listen_port());
396 ASSERT_TRUE(connection !=
nullptr);
398 TestClientRequest request = {
"/ok",
"POST", {}, compressed};
399 request.headers.emplace_back(
"Content-Encoding",
"my_gzip");
400 TestClientResponse response = {};
402 EXPECT_TRUE(connection->BlockingSendRequest(request, &response));
403 EXPECT_EQ(response.status, HTTPStatusCode::OK);
406 server->WaitForTermination();
409 std::string MakeRandomString(int64_t len) {
410 std::random_device rd;
411 std::mt19937_64 gen(rd());
412 std::uniform_int_distribution<> dis(
'a',
'z');
413 std::string s(len,
'0');
421 TEST_F(EvHTTPRequestTest, LargeGzipPost) {
422 constexpr int64_t uncompress_len = 1024 * 1024;
423 std::string uncompressed = MakeRandomString(uncompress_len);
424 std::string compressed = CompressLargeString(
425 uncompressed.data(), uncompressed.size(), 2 * uncompress_len);
427 auto handler = [&](ServerRequestInterface* request) {
429 auto request_body = request->ReadRequestBytes(&num_bytes);
431 std::string body_str(request_body.get(),
static_cast<size_t>(num_bytes));
432 EXPECT_EQ(body_str, uncompressed);
433 EXPECT_EQ(uncompressed.size(), num_bytes);
435 EXPECT_EQ(
nullptr, request->ReadRequestBytes(&num_bytes));
436 EXPECT_EQ(0, num_bytes);
440 server->RegisterRequestHandler(
"/ok", std::move(handler),
441 RequestHandlerOptions());
442 server->StartAcceptingRequests();
445 TestEvHTTPConnection::Connect(
"localhost", server->listen_port());
446 ASSERT_TRUE(connection !=
nullptr);
448 TestClientRequest request = {
"/ok",
"POST", {}, compressed};
449 request.headers.emplace_back(
"Content-Encoding",
"my_gzip");
450 TestClientResponse response = {};
452 EXPECT_TRUE(connection->BlockingSendRequest(request, &response));
453 EXPECT_EQ(response.status, HTTPStatusCode::OK);
456 server->WaitForTermination();