xref: /aosp_15_r20/external/cronet/net/server/http_server_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/server/http_server.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
8*6777b538SAndroid Build Coastguard Worker 
9*6777b538SAndroid Build Coastguard Worker #include <algorithm>
10*6777b538SAndroid Build Coastguard Worker #include <memory>
11*6777b538SAndroid Build Coastguard Worker #include <string_view>
12*6777b538SAndroid Build Coastguard Worker #include <unordered_map>
13*6777b538SAndroid Build Coastguard Worker #include <utility>
14*6777b538SAndroid Build Coastguard Worker #include <vector>
15*6777b538SAndroid Build Coastguard Worker 
16*6777b538SAndroid Build Coastguard Worker #include "base/auto_reset.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/compiler_specific.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/format_macros.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback_helpers.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/memory/ptr_util.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/memory/ref_counted.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/memory/weak_ptr.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/numerics/safe_conversions.h"
28*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
29*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
30*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
31*6777b538SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
32*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
33*6777b538SAndroid Build Coastguard Worker #include "base/test/test_future.h"
34*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
35*6777b538SAndroid Build Coastguard Worker #include "net/base/address_list.h"
36*6777b538SAndroid Build Coastguard Worker #include "net/base/io_buffer.h"
37*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_endpoint.h"
38*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
39*6777b538SAndroid Build Coastguard Worker #include "net/base/test_completion_callback.h"
40*6777b538SAndroid Build Coastguard Worker #include "net/http/http_response_headers.h"
41*6777b538SAndroid Build Coastguard Worker #include "net/http/http_util.h"
42*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_source.h"
43*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_with_source.h"
44*6777b538SAndroid Build Coastguard Worker #include "net/server/http_server_request_info.h"
45*6777b538SAndroid Build Coastguard Worker #include "net/socket/tcp_client_socket.h"
46*6777b538SAndroid Build Coastguard Worker #include "net/socket/tcp_server_socket.h"
47*6777b538SAndroid Build Coastguard Worker #include "net/test/gtest_util.h"
48*6777b538SAndroid Build Coastguard Worker #include "net/test/test_with_task_environment.h"
49*6777b538SAndroid Build Coastguard Worker #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
50*6777b538SAndroid Build Coastguard Worker #include "net/websockets/websocket_frame.h"
51*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
52*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
53*6777b538SAndroid Build Coastguard Worker 
54*6777b538SAndroid Build Coastguard Worker using net::test::IsOk;
55*6777b538SAndroid Build Coastguard Worker 
56*6777b538SAndroid Build Coastguard Worker namespace net {
57*6777b538SAndroid Build Coastguard Worker 
58*6777b538SAndroid Build Coastguard Worker namespace {
59*6777b538SAndroid Build Coastguard Worker 
60*6777b538SAndroid Build Coastguard Worker const int kMaxExpectedResponseLength = 2048;
61*6777b538SAndroid Build Coastguard Worker 
62*6777b538SAndroid Build Coastguard Worker class TestHttpClient {
63*6777b538SAndroid Build Coastguard Worker  public:
64*6777b538SAndroid Build Coastguard Worker   TestHttpClient() = default;
65*6777b538SAndroid Build Coastguard Worker 
ConnectAndWait(const IPEndPoint & address)66*6777b538SAndroid Build Coastguard Worker   int ConnectAndWait(const IPEndPoint& address) {
67*6777b538SAndroid Build Coastguard Worker     AddressList addresses(address);
68*6777b538SAndroid Build Coastguard Worker     NetLogSource source;
69*6777b538SAndroid Build Coastguard Worker     socket_ = std::make_unique<TCPClientSocket>(addresses, nullptr, nullptr,
70*6777b538SAndroid Build Coastguard Worker                                                 nullptr, source);
71*6777b538SAndroid Build Coastguard Worker 
72*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
73*6777b538SAndroid Build Coastguard Worker     int rv = socket_->Connect(callback.callback());
74*6777b538SAndroid Build Coastguard Worker     return callback.GetResult(rv);
75*6777b538SAndroid Build Coastguard Worker   }
76*6777b538SAndroid Build Coastguard Worker 
Send(const std::string & data)77*6777b538SAndroid Build Coastguard Worker   void Send(const std::string& data) {
78*6777b538SAndroid Build Coastguard Worker     write_buffer_ = base::MakeRefCounted<DrainableIOBuffer>(
79*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<StringIOBuffer>(data), data.length());
80*6777b538SAndroid Build Coastguard Worker     Write();
81*6777b538SAndroid Build Coastguard Worker   }
82*6777b538SAndroid Build Coastguard Worker 
Read(std::string * message,int expected_bytes)83*6777b538SAndroid Build Coastguard Worker   bool Read(std::string* message, int expected_bytes) {
84*6777b538SAndroid Build Coastguard Worker     int total_bytes_received = 0;
85*6777b538SAndroid Build Coastguard Worker     message->clear();
86*6777b538SAndroid Build Coastguard Worker     while (total_bytes_received < expected_bytes) {
87*6777b538SAndroid Build Coastguard Worker       TestCompletionCallback callback;
88*6777b538SAndroid Build Coastguard Worker       ReadInternal(&callback);
89*6777b538SAndroid Build Coastguard Worker       int bytes_received = callback.WaitForResult();
90*6777b538SAndroid Build Coastguard Worker       if (bytes_received <= 0) {
91*6777b538SAndroid Build Coastguard Worker         return false;
92*6777b538SAndroid Build Coastguard Worker       }
93*6777b538SAndroid Build Coastguard Worker 
94*6777b538SAndroid Build Coastguard Worker       total_bytes_received += bytes_received;
95*6777b538SAndroid Build Coastguard Worker       message->append(read_buffer_->data(), bytes_received);
96*6777b538SAndroid Build Coastguard Worker     }
97*6777b538SAndroid Build Coastguard Worker     return true;
98*6777b538SAndroid Build Coastguard Worker   }
99*6777b538SAndroid Build Coastguard Worker 
ReadResponse(std::string * message)100*6777b538SAndroid Build Coastguard Worker   bool ReadResponse(std::string* message) {
101*6777b538SAndroid Build Coastguard Worker     if (!Read(message, 1)) {
102*6777b538SAndroid Build Coastguard Worker       return false;
103*6777b538SAndroid Build Coastguard Worker     }
104*6777b538SAndroid Build Coastguard Worker     while (!IsCompleteResponse(*message)) {
105*6777b538SAndroid Build Coastguard Worker       std::string chunk;
106*6777b538SAndroid Build Coastguard Worker       if (!Read(&chunk, 1)) {
107*6777b538SAndroid Build Coastguard Worker         return false;
108*6777b538SAndroid Build Coastguard Worker       }
109*6777b538SAndroid Build Coastguard Worker       message->append(chunk);
110*6777b538SAndroid Build Coastguard Worker     }
111*6777b538SAndroid Build Coastguard Worker     return true;
112*6777b538SAndroid Build Coastguard Worker   }
113*6777b538SAndroid Build Coastguard Worker 
ExpectUsedThenDisconnectedWithNoData()114*6777b538SAndroid Build Coastguard Worker   void ExpectUsedThenDisconnectedWithNoData() {
115*6777b538SAndroid Build Coastguard Worker     // Check that the socket was opened...
116*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(socket_->WasEverUsed());
117*6777b538SAndroid Build Coastguard Worker 
118*6777b538SAndroid Build Coastguard Worker     // ...then closed when the server disconnected. Verify that the socket was
119*6777b538SAndroid Build Coastguard Worker     // closed by checking that a Read() fails.
120*6777b538SAndroid Build Coastguard Worker     std::string response;
121*6777b538SAndroid Build Coastguard Worker     ASSERT_FALSE(Read(&response, 1u));
122*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(response.empty());
123*6777b538SAndroid Build Coastguard Worker   }
124*6777b538SAndroid Build Coastguard Worker 
socket()125*6777b538SAndroid Build Coastguard Worker   TCPClientSocket& socket() { return *socket_; }
126*6777b538SAndroid Build Coastguard Worker 
127*6777b538SAndroid Build Coastguard Worker  private:
Write()128*6777b538SAndroid Build Coastguard Worker   void Write() {
129*6777b538SAndroid Build Coastguard Worker     int result = socket_->Write(
130*6777b538SAndroid Build Coastguard Worker         write_buffer_.get(), write_buffer_->BytesRemaining(),
131*6777b538SAndroid Build Coastguard Worker         base::BindOnce(&TestHttpClient::OnWrite, base::Unretained(this)),
132*6777b538SAndroid Build Coastguard Worker         TRAFFIC_ANNOTATION_FOR_TESTS);
133*6777b538SAndroid Build Coastguard Worker     if (result != ERR_IO_PENDING) {
134*6777b538SAndroid Build Coastguard Worker       OnWrite(result);
135*6777b538SAndroid Build Coastguard Worker     }
136*6777b538SAndroid Build Coastguard Worker   }
137*6777b538SAndroid Build Coastguard Worker 
OnWrite(int result)138*6777b538SAndroid Build Coastguard Worker   void OnWrite(int result) {
139*6777b538SAndroid Build Coastguard Worker     ASSERT_GT(result, 0);
140*6777b538SAndroid Build Coastguard Worker     write_buffer_->DidConsume(result);
141*6777b538SAndroid Build Coastguard Worker     if (write_buffer_->BytesRemaining()) {
142*6777b538SAndroid Build Coastguard Worker       Write();
143*6777b538SAndroid Build Coastguard Worker     }
144*6777b538SAndroid Build Coastguard Worker   }
145*6777b538SAndroid Build Coastguard Worker 
ReadInternal(TestCompletionCallback * callback)146*6777b538SAndroid Build Coastguard Worker   void ReadInternal(TestCompletionCallback* callback) {
147*6777b538SAndroid Build Coastguard Worker     read_buffer_ =
148*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<IOBufferWithSize>(kMaxExpectedResponseLength);
149*6777b538SAndroid Build Coastguard Worker     int result = socket_->Read(read_buffer_.get(), kMaxExpectedResponseLength,
150*6777b538SAndroid Build Coastguard Worker                                callback->callback());
151*6777b538SAndroid Build Coastguard Worker     if (result != ERR_IO_PENDING) {
152*6777b538SAndroid Build Coastguard Worker       callback->callback().Run(result);
153*6777b538SAndroid Build Coastguard Worker     }
154*6777b538SAndroid Build Coastguard Worker   }
155*6777b538SAndroid Build Coastguard Worker 
IsCompleteResponse(const std::string & response)156*6777b538SAndroid Build Coastguard Worker   bool IsCompleteResponse(const std::string& response) {
157*6777b538SAndroid Build Coastguard Worker     // Check end of headers first.
158*6777b538SAndroid Build Coastguard Worker     size_t end_of_headers =
159*6777b538SAndroid Build Coastguard Worker         HttpUtil::LocateEndOfHeaders(response.data(), response.size());
160*6777b538SAndroid Build Coastguard Worker     if (end_of_headers == std::string::npos) {
161*6777b538SAndroid Build Coastguard Worker       return false;
162*6777b538SAndroid Build Coastguard Worker     }
163*6777b538SAndroid Build Coastguard Worker 
164*6777b538SAndroid Build Coastguard Worker     // Return true if response has data equal to or more than content length.
165*6777b538SAndroid Build Coastguard Worker     int64_t body_size = static_cast<int64_t>(response.size()) - end_of_headers;
166*6777b538SAndroid Build Coastguard Worker     DCHECK_LE(0, body_size);
167*6777b538SAndroid Build Coastguard Worker     auto headers =
168*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<HttpResponseHeaders>(HttpUtil::AssembleRawHeaders(
169*6777b538SAndroid Build Coastguard Worker             std::string_view(response.data(), end_of_headers)));
170*6777b538SAndroid Build Coastguard Worker     return body_size >= headers->GetContentLength();
171*6777b538SAndroid Build Coastguard Worker   }
172*6777b538SAndroid Build Coastguard Worker 
173*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> read_buffer_;
174*6777b538SAndroid Build Coastguard Worker   scoped_refptr<DrainableIOBuffer> write_buffer_;
175*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<TCPClientSocket> socket_;
176*6777b538SAndroid Build Coastguard Worker };
177*6777b538SAndroid Build Coastguard Worker 
178*6777b538SAndroid Build Coastguard Worker struct ReceivedRequest {
179*6777b538SAndroid Build Coastguard Worker   HttpServerRequestInfo info;
180*6777b538SAndroid Build Coastguard Worker   int connection_id;
181*6777b538SAndroid Build Coastguard Worker };
182*6777b538SAndroid Build Coastguard Worker 
183*6777b538SAndroid Build Coastguard Worker }  // namespace
184*6777b538SAndroid Build Coastguard Worker 
185*6777b538SAndroid Build Coastguard Worker class HttpServerTest : public TestWithTaskEnvironment,
186*6777b538SAndroid Build Coastguard Worker                        public HttpServer::Delegate {
187*6777b538SAndroid Build Coastguard Worker  public:
188*6777b538SAndroid Build Coastguard Worker   HttpServerTest() = default;
189*6777b538SAndroid Build Coastguard Worker 
SetUp()190*6777b538SAndroid Build Coastguard Worker   void SetUp() override {
191*6777b538SAndroid Build Coastguard Worker     auto server_socket =
192*6777b538SAndroid Build Coastguard Worker         std::make_unique<TCPServerSocket>(nullptr, NetLogSource());
193*6777b538SAndroid Build Coastguard Worker     server_socket->ListenWithAddressAndPort("127.0.0.1", 0, 1);
194*6777b538SAndroid Build Coastguard Worker     server_ = std::make_unique<HttpServer>(std::move(server_socket), this);
195*6777b538SAndroid Build Coastguard Worker     ASSERT_THAT(server_->GetLocalAddress(&server_address_), IsOk());
196*6777b538SAndroid Build Coastguard Worker   }
197*6777b538SAndroid Build Coastguard Worker 
TearDown()198*6777b538SAndroid Build Coastguard Worker   void TearDown() override {
199*6777b538SAndroid Build Coastguard Worker     // Run the event loop some to make sure that the memory handed over to
200*6777b538SAndroid Build Coastguard Worker     // DeleteSoon gets fully freed.
201*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
202*6777b538SAndroid Build Coastguard Worker   }
203*6777b538SAndroid Build Coastguard Worker 
OnConnect(int connection_id)204*6777b538SAndroid Build Coastguard Worker   void OnConnect(int connection_id) override {
205*6777b538SAndroid Build Coastguard Worker     DCHECK(connection_map_.find(connection_id) == connection_map_.end());
206*6777b538SAndroid Build Coastguard Worker     connection_map_[connection_id] = true;
207*6777b538SAndroid Build Coastguard Worker     // This is set in CreateConnection(), which must be invoked once for every
208*6777b538SAndroid Build Coastguard Worker     // expected connection.
209*6777b538SAndroid Build Coastguard Worker     quit_on_create_loop_->Quit();
210*6777b538SAndroid Build Coastguard Worker   }
211*6777b538SAndroid Build Coastguard Worker 
OnHttpRequest(int connection_id,const HttpServerRequestInfo & info)212*6777b538SAndroid Build Coastguard Worker   void OnHttpRequest(int connection_id,
213*6777b538SAndroid Build Coastguard Worker                      const HttpServerRequestInfo& info) override {
214*6777b538SAndroid Build Coastguard Worker     received_request_.SetValue({.info = info, .connection_id = connection_id});
215*6777b538SAndroid Build Coastguard Worker   }
216*6777b538SAndroid Build Coastguard Worker 
OnWebSocketRequest(int connection_id,const HttpServerRequestInfo & info)217*6777b538SAndroid Build Coastguard Worker   void OnWebSocketRequest(int connection_id,
218*6777b538SAndroid Build Coastguard Worker                           const HttpServerRequestInfo& info) override {
219*6777b538SAndroid Build Coastguard Worker     NOTREACHED();
220*6777b538SAndroid Build Coastguard Worker   }
221*6777b538SAndroid Build Coastguard Worker 
OnWebSocketMessage(int connection_id,std::string data)222*6777b538SAndroid Build Coastguard Worker   void OnWebSocketMessage(int connection_id, std::string data) override {
223*6777b538SAndroid Build Coastguard Worker     NOTREACHED();
224*6777b538SAndroid Build Coastguard Worker   }
225*6777b538SAndroid Build Coastguard Worker 
OnClose(int connection_id)226*6777b538SAndroid Build Coastguard Worker   void OnClose(int connection_id) override {
227*6777b538SAndroid Build Coastguard Worker     DCHECK(connection_map_.find(connection_id) != connection_map_.end());
228*6777b538SAndroid Build Coastguard Worker     connection_map_[connection_id] = false;
229*6777b538SAndroid Build Coastguard Worker     if (connection_id == quit_on_close_connection_) {
230*6777b538SAndroid Build Coastguard Worker       std::move(run_loop_quit_func_).Run();
231*6777b538SAndroid Build Coastguard Worker     }
232*6777b538SAndroid Build Coastguard Worker   }
233*6777b538SAndroid Build Coastguard Worker 
WaitForRequest()234*6777b538SAndroid Build Coastguard Worker   ReceivedRequest WaitForRequest() { return received_request_.Take(); }
235*6777b538SAndroid Build Coastguard Worker 
HasRequest() const236*6777b538SAndroid Build Coastguard Worker   bool HasRequest() const { return received_request_.IsReady(); }
237*6777b538SAndroid Build Coastguard Worker 
238*6777b538SAndroid Build Coastguard Worker   // Connections should only be created using this method, which waits until
239*6777b538SAndroid Build Coastguard Worker   // both the server and the client have received the connected socket.
CreateConnection(TestHttpClient * client)240*6777b538SAndroid Build Coastguard Worker   void CreateConnection(TestHttpClient* client) {
241*6777b538SAndroid Build Coastguard Worker     ASSERT_FALSE(quit_on_create_loop_);
242*6777b538SAndroid Build Coastguard Worker     quit_on_create_loop_ = std::make_unique<base::RunLoop>();
243*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(client->ConnectAndWait(server_address_), IsOk());
244*6777b538SAndroid Build Coastguard Worker     quit_on_create_loop_->Run();
245*6777b538SAndroid Build Coastguard Worker     quit_on_create_loop_.reset();
246*6777b538SAndroid Build Coastguard Worker   }
247*6777b538SAndroid Build Coastguard Worker 
RunUntilConnectionIdClosed(int connection_id)248*6777b538SAndroid Build Coastguard Worker   void RunUntilConnectionIdClosed(int connection_id) {
249*6777b538SAndroid Build Coastguard Worker     quit_on_close_connection_ = connection_id;
250*6777b538SAndroid Build Coastguard Worker     auto iter = connection_map_.find(connection_id);
251*6777b538SAndroid Build Coastguard Worker     if (iter != connection_map_.end() && !iter->second) {
252*6777b538SAndroid Build Coastguard Worker       // Already disconnected.
253*6777b538SAndroid Build Coastguard Worker       return;
254*6777b538SAndroid Build Coastguard Worker     }
255*6777b538SAndroid Build Coastguard Worker 
256*6777b538SAndroid Build Coastguard Worker     base::RunLoop run_loop;
257*6777b538SAndroid Build Coastguard Worker     base::AutoReset<base::OnceClosure> run_loop_quit_func(
258*6777b538SAndroid Build Coastguard Worker         &run_loop_quit_func_, run_loop.QuitClosure());
259*6777b538SAndroid Build Coastguard Worker     run_loop.Run();
260*6777b538SAndroid Build Coastguard Worker 
261*6777b538SAndroid Build Coastguard Worker     iter = connection_map_.find(connection_id);
262*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(iter != connection_map_.end());
263*6777b538SAndroid Build Coastguard Worker     ASSERT_FALSE(iter->second);
264*6777b538SAndroid Build Coastguard Worker   }
265*6777b538SAndroid Build Coastguard Worker 
HandleAcceptResult(std::unique_ptr<StreamSocket> socket)266*6777b538SAndroid Build Coastguard Worker   void HandleAcceptResult(std::unique_ptr<StreamSocket> socket) {
267*6777b538SAndroid Build Coastguard Worker     ASSERT_FALSE(quit_on_create_loop_);
268*6777b538SAndroid Build Coastguard Worker     quit_on_create_loop_ = std::make_unique<base::RunLoop>();
269*6777b538SAndroid Build Coastguard Worker     server_->accepted_socket_ = std::move(socket);
270*6777b538SAndroid Build Coastguard Worker     server_->HandleAcceptResult(OK);
271*6777b538SAndroid Build Coastguard Worker     quit_on_create_loop_->Run();
272*6777b538SAndroid Build Coastguard Worker     quit_on_create_loop_.reset();
273*6777b538SAndroid Build Coastguard Worker   }
274*6777b538SAndroid Build Coastguard Worker 
connection_map()275*6777b538SAndroid Build Coastguard Worker   std::unordered_map<int, bool>& connection_map() { return connection_map_; }
276*6777b538SAndroid Build Coastguard Worker 
277*6777b538SAndroid Build Coastguard Worker  protected:
278*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<HttpServer> server_;
279*6777b538SAndroid Build Coastguard Worker   IPEndPoint server_address_;
280*6777b538SAndroid Build Coastguard Worker   base::OnceClosure run_loop_quit_func_;
281*6777b538SAndroid Build Coastguard Worker   std::unordered_map<int /* connection_id */, bool /* connected */>
282*6777b538SAndroid Build Coastguard Worker       connection_map_;
283*6777b538SAndroid Build Coastguard Worker 
284*6777b538SAndroid Build Coastguard Worker  private:
285*6777b538SAndroid Build Coastguard Worker   base::test::TestFuture<ReceivedRequest> received_request_;
286*6777b538SAndroid Build Coastguard Worker   std::unique_ptr<base::RunLoop> quit_on_create_loop_;
287*6777b538SAndroid Build Coastguard Worker   int quit_on_close_connection_ = -1;
288*6777b538SAndroid Build Coastguard Worker };
289*6777b538SAndroid Build Coastguard Worker 
290*6777b538SAndroid Build Coastguard Worker namespace {
291*6777b538SAndroid Build Coastguard Worker 
292*6777b538SAndroid Build Coastguard Worker class WebSocketTest : public HttpServerTest {
OnHttpRequest(int connection_id,const HttpServerRequestInfo & info)293*6777b538SAndroid Build Coastguard Worker   void OnHttpRequest(int connection_id,
294*6777b538SAndroid Build Coastguard Worker                      const HttpServerRequestInfo& info) override {
295*6777b538SAndroid Build Coastguard Worker     NOTREACHED();
296*6777b538SAndroid Build Coastguard Worker   }
297*6777b538SAndroid Build Coastguard Worker 
OnWebSocketRequest(int connection_id,const HttpServerRequestInfo & info)298*6777b538SAndroid Build Coastguard Worker   void OnWebSocketRequest(int connection_id,
299*6777b538SAndroid Build Coastguard Worker                           const HttpServerRequestInfo& info) override {
300*6777b538SAndroid Build Coastguard Worker     HttpServerTest::OnHttpRequest(connection_id, info);
301*6777b538SAndroid Build Coastguard Worker   }
302*6777b538SAndroid Build Coastguard Worker 
OnWebSocketMessage(int connection_id,std::string data)303*6777b538SAndroid Build Coastguard Worker   void OnWebSocketMessage(int connection_id, std::string data) override {}
304*6777b538SAndroid Build Coastguard Worker };
305*6777b538SAndroid Build Coastguard Worker 
306*6777b538SAndroid Build Coastguard Worker class WebSocketAcceptingTest : public WebSocketTest {
307*6777b538SAndroid Build Coastguard Worker  public:
OnWebSocketRequest(int connection_id,const HttpServerRequestInfo & info)308*6777b538SAndroid Build Coastguard Worker   void OnWebSocketRequest(int connection_id,
309*6777b538SAndroid Build Coastguard Worker                           const HttpServerRequestInfo& info) override {
310*6777b538SAndroid Build Coastguard Worker     HttpServerTest::OnHttpRequest(connection_id, info);
311*6777b538SAndroid Build Coastguard Worker     server_->AcceptWebSocket(connection_id, info, TRAFFIC_ANNOTATION_FOR_TESTS);
312*6777b538SAndroid Build Coastguard Worker   }
313*6777b538SAndroid Build Coastguard Worker 
OnWebSocketMessage(int connection_id,std::string data)314*6777b538SAndroid Build Coastguard Worker   void OnWebSocketMessage(int connection_id, std::string data) override {
315*6777b538SAndroid Build Coastguard Worker     last_message_.SetValue(data);
316*6777b538SAndroid Build Coastguard Worker   }
317*6777b538SAndroid Build Coastguard Worker 
GetMessage()318*6777b538SAndroid Build Coastguard Worker   std::string GetMessage() { return last_message_.Take(); }
319*6777b538SAndroid Build Coastguard Worker 
320*6777b538SAndroid Build Coastguard Worker  private:
321*6777b538SAndroid Build Coastguard Worker   base::test::TestFuture<std::string> last_message_;
322*6777b538SAndroid Build Coastguard Worker };
323*6777b538SAndroid Build Coastguard Worker 
EncodeFrame(std::string message,WebSocketFrameHeader::OpCodeEnum op_code,bool mask,bool finish)324*6777b538SAndroid Build Coastguard Worker std::string EncodeFrame(std::string message,
325*6777b538SAndroid Build Coastguard Worker                         WebSocketFrameHeader::OpCodeEnum op_code,
326*6777b538SAndroid Build Coastguard Worker                         bool mask,
327*6777b538SAndroid Build Coastguard Worker                         bool finish) {
328*6777b538SAndroid Build Coastguard Worker   WebSocketFrameHeader header(op_code);
329*6777b538SAndroid Build Coastguard Worker   header.final = finish;
330*6777b538SAndroid Build Coastguard Worker   header.masked = mask;
331*6777b538SAndroid Build Coastguard Worker   header.payload_length = message.size();
332*6777b538SAndroid Build Coastguard Worker   const size_t header_size = GetWebSocketFrameHeaderSize(header);
333*6777b538SAndroid Build Coastguard Worker   std::string frame_header;
334*6777b538SAndroid Build Coastguard Worker   frame_header.resize(header_size);
335*6777b538SAndroid Build Coastguard Worker   if (mask) {
336*6777b538SAndroid Build Coastguard Worker     WebSocketMaskingKey masking_key = GenerateWebSocketMaskingKey();
337*6777b538SAndroid Build Coastguard Worker     WriteWebSocketFrameHeader(header, &masking_key, &frame_header[0],
338*6777b538SAndroid Build Coastguard Worker                               base::checked_cast<int>(header_size));
339*6777b538SAndroid Build Coastguard Worker     MaskWebSocketFramePayload(masking_key, 0, &message[0], message.size());
340*6777b538SAndroid Build Coastguard Worker   } else {
341*6777b538SAndroid Build Coastguard Worker     WriteWebSocketFrameHeader(header, nullptr, &frame_header[0],
342*6777b538SAndroid Build Coastguard Worker                               base::checked_cast<int>(header_size));
343*6777b538SAndroid Build Coastguard Worker   }
344*6777b538SAndroid Build Coastguard Worker   return frame_header + message;
345*6777b538SAndroid Build Coastguard Worker }
346*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpServerTest,Request)347*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, Request) {
348*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
349*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
350*6777b538SAndroid Build Coastguard Worker   client.Send("GET /test HTTP/1.1\r\n\r\n");
351*6777b538SAndroid Build Coastguard Worker   ReceivedRequest request = WaitForRequest();
352*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ("GET", request.info.method);
353*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ("/test", request.info.path);
354*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ("", request.info.data);
355*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0u, request.info.headers.size());
356*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(request.info.peer.ToString().starts_with("127.0.0.1"));
357*6777b538SAndroid Build Coastguard Worker }
358*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpServerTest,RequestBrokenTermination)359*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, RequestBrokenTermination) {
360*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
361*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
362*6777b538SAndroid Build Coastguard Worker   client.Send("GET /test HTTP/1.1\r\n\r)");
363*6777b538SAndroid Build Coastguard Worker   RunUntilConnectionIdClosed(1);
364*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(HasRequest());
365*6777b538SAndroid Build Coastguard Worker   client.ExpectUsedThenDisconnectedWithNoData();
366*6777b538SAndroid Build Coastguard Worker }
367*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpServerTest,RequestWithHeaders)368*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, RequestWithHeaders) {
369*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
370*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
371*6777b538SAndroid Build Coastguard Worker   const char* const kHeaders[][3] = {
372*6777b538SAndroid Build Coastguard Worker       {"Header", ": ", "1"},
373*6777b538SAndroid Build Coastguard Worker       {"HeaderWithNoWhitespace", ":", "1"},
374*6777b538SAndroid Build Coastguard Worker       {"HeaderWithWhitespace", "   :  \t   ", "1 1 1 \t  "},
375*6777b538SAndroid Build Coastguard Worker       {"HeaderWithColon", ": ", "1:1"},
376*6777b538SAndroid Build Coastguard Worker       {"EmptyHeader", ":", ""},
377*6777b538SAndroid Build Coastguard Worker       {"EmptyHeaderWithWhitespace", ":  \t  ", ""},
378*6777b538SAndroid Build Coastguard Worker       {"HeaderWithNonASCII", ":  ", "\xf7"},
379*6777b538SAndroid Build Coastguard Worker   };
380*6777b538SAndroid Build Coastguard Worker   std::string headers;
381*6777b538SAndroid Build Coastguard Worker   for (const auto& header : kHeaders) {
382*6777b538SAndroid Build Coastguard Worker     headers += std::string(header[0]) + header[1] + header[2] + "\r\n";
383*6777b538SAndroid Build Coastguard Worker   }
384*6777b538SAndroid Build Coastguard Worker 
385*6777b538SAndroid Build Coastguard Worker   client.Send("GET /test HTTP/1.1\r\n" + headers + "\r\n");
386*6777b538SAndroid Build Coastguard Worker   auto request = WaitForRequest();
387*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ("", request.info.data);
388*6777b538SAndroid Build Coastguard Worker 
389*6777b538SAndroid Build Coastguard Worker   for (const auto& header : kHeaders) {
390*6777b538SAndroid Build Coastguard Worker     std::string field = base::ToLowerASCII(std::string(header[0]));
391*6777b538SAndroid Build Coastguard Worker     std::string value = header[2];
392*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(1u, request.info.headers.count(field)) << field;
393*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(value, request.info.headers[field]) << header[0];
394*6777b538SAndroid Build Coastguard Worker   }
395*6777b538SAndroid Build Coastguard Worker }
396*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpServerTest,RequestWithDuplicateHeaders)397*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, RequestWithDuplicateHeaders) {
398*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
399*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
400*6777b538SAndroid Build Coastguard Worker   const char* const kHeaders[][3] = {
401*6777b538SAndroid Build Coastguard Worker       // clang-format off
402*6777b538SAndroid Build Coastguard Worker       {"FirstHeader", ": ", "1"},
403*6777b538SAndroid Build Coastguard Worker       {"DuplicateHeader", ": ", "2"},
404*6777b538SAndroid Build Coastguard Worker       {"MiddleHeader", ": ", "3"},
405*6777b538SAndroid Build Coastguard Worker       {"DuplicateHeader", ": ", "4"},
406*6777b538SAndroid Build Coastguard Worker       {"LastHeader", ": ", "5"},
407*6777b538SAndroid Build Coastguard Worker       // clang-format on
408*6777b538SAndroid Build Coastguard Worker   };
409*6777b538SAndroid Build Coastguard Worker   std::string headers;
410*6777b538SAndroid Build Coastguard Worker   for (const auto& header : kHeaders) {
411*6777b538SAndroid Build Coastguard Worker     headers += std::string(header[0]) + header[1] + header[2] + "\r\n";
412*6777b538SAndroid Build Coastguard Worker   }
413*6777b538SAndroid Build Coastguard Worker 
414*6777b538SAndroid Build Coastguard Worker   client.Send("GET /test HTTP/1.1\r\n" + headers + "\r\n");
415*6777b538SAndroid Build Coastguard Worker   auto request = WaitForRequest();
416*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ("", request.info.data);
417*6777b538SAndroid Build Coastguard Worker 
418*6777b538SAndroid Build Coastguard Worker   for (const auto& header : kHeaders) {
419*6777b538SAndroid Build Coastguard Worker     std::string field = base::ToLowerASCII(std::string(header[0]));
420*6777b538SAndroid Build Coastguard Worker     std::string value = (field == "duplicateheader") ? "2,4" : header[2];
421*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(1u, request.info.headers.count(field)) << field;
422*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(value, request.info.headers[field]) << header[0];
423*6777b538SAndroid Build Coastguard Worker   }
424*6777b538SAndroid Build Coastguard Worker }
425*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpServerTest,HasHeaderValueTest)426*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, HasHeaderValueTest) {
427*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
428*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
429*6777b538SAndroid Build Coastguard Worker   const char* const kHeaders[] = {
430*6777b538SAndroid Build Coastguard Worker       "Header: Abcd",
431*6777b538SAndroid Build Coastguard Worker       "HeaderWithNoWhitespace:E",
432*6777b538SAndroid Build Coastguard Worker       "HeaderWithWhitespace   :  \t   f \t  ",
433*6777b538SAndroid Build Coastguard Worker       "DuplicateHeader: g",
434*6777b538SAndroid Build Coastguard Worker       "HeaderWithComma: h, i ,j",
435*6777b538SAndroid Build Coastguard Worker       "DuplicateHeader: k",
436*6777b538SAndroid Build Coastguard Worker       "EmptyHeader:",
437*6777b538SAndroid Build Coastguard Worker       "EmptyHeaderWithWhitespace:  \t  ",
438*6777b538SAndroid Build Coastguard Worker       "HeaderWithNonASCII:  \xf7",
439*6777b538SAndroid Build Coastguard Worker   };
440*6777b538SAndroid Build Coastguard Worker   std::string headers;
441*6777b538SAndroid Build Coastguard Worker   for (const char* header : kHeaders) {
442*6777b538SAndroid Build Coastguard Worker     headers += std::string(header) + "\r\n";
443*6777b538SAndroid Build Coastguard Worker   }
444*6777b538SAndroid Build Coastguard Worker 
445*6777b538SAndroid Build Coastguard Worker   client.Send("GET /test HTTP/1.1\r\n" + headers + "\r\n");
446*6777b538SAndroid Build Coastguard Worker   auto request = WaitForRequest();
447*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ("", request.info.data);
448*6777b538SAndroid Build Coastguard Worker 
449*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(request.info.HasHeaderValue("header", "abcd"));
450*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(request.info.HasHeaderValue("header", "bc"));
451*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(request.info.HasHeaderValue("headerwithnowhitespace", "e"));
452*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(request.info.HasHeaderValue("headerwithwhitespace", "f"));
453*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(request.info.HasHeaderValue("duplicateheader", "g"));
454*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(request.info.HasHeaderValue("headerwithcomma", "h"));
455*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(request.info.HasHeaderValue("headerwithcomma", "i"));
456*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(request.info.HasHeaderValue("headerwithcomma", "j"));
457*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(request.info.HasHeaderValue("duplicateheader", "k"));
458*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(request.info.HasHeaderValue("emptyheader", "x"));
459*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(request.info.HasHeaderValue("emptyheaderwithwhitespace", "x"));
460*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(request.info.HasHeaderValue("headerwithnonascii", "\xf7"));
461*6777b538SAndroid Build Coastguard Worker }
462*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpServerTest,RequestWithBody)463*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, RequestWithBody) {
464*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
465*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
466*6777b538SAndroid Build Coastguard Worker   std::string body = "a" + std::string(1 << 10, 'b') + "c";
467*6777b538SAndroid Build Coastguard Worker   client.Send(
468*6777b538SAndroid Build Coastguard Worker       base::StringPrintf("GET /test HTTP/1.1\r\n"
469*6777b538SAndroid Build Coastguard Worker                          "SomeHeader: 1\r\n"
470*6777b538SAndroid Build Coastguard Worker                          "Content-Length: %" PRIuS "\r\n\r\n%s",
471*6777b538SAndroid Build Coastguard Worker                          body.length(), body.c_str()));
472*6777b538SAndroid Build Coastguard Worker   auto request = WaitForRequest();
473*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(2u, request.info.headers.size());
474*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(body.length(), request.info.data.length());
475*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ('a', body[0]);
476*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ('c', *body.rbegin());
477*6777b538SAndroid Build Coastguard Worker }
478*6777b538SAndroid Build Coastguard Worker 
479*6777b538SAndroid Build Coastguard Worker // Tests that |HttpServer::HandleReadResult| will ignore Upgrade header if value
480*6777b538SAndroid Build Coastguard Worker // is not WebSocket.
TEST_F(HttpServerTest,UpgradeIgnored)481*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, UpgradeIgnored) {
482*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
483*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
484*6777b538SAndroid Build Coastguard Worker   client.Send(
485*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
486*6777b538SAndroid Build Coastguard Worker       "Upgrade: h2c\r\n"
487*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
488*6777b538SAndroid Build Coastguard Worker       "\r\n");
489*6777b538SAndroid Build Coastguard Worker   WaitForRequest();
490*6777b538SAndroid Build Coastguard Worker }
491*6777b538SAndroid Build Coastguard Worker 
TEST_F(WebSocketTest,RequestWebSocket)492*6777b538SAndroid Build Coastguard Worker TEST_F(WebSocketTest, RequestWebSocket) {
493*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
494*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
495*6777b538SAndroid Build Coastguard Worker   client.Send(
496*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
497*6777b538SAndroid Build Coastguard Worker       "Upgrade: WebSocket\r\n"
498*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
499*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Version: 8\r\n"
500*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Key: key\r\n"
501*6777b538SAndroid Build Coastguard Worker       "\r\n");
502*6777b538SAndroid Build Coastguard Worker   WaitForRequest();
503*6777b538SAndroid Build Coastguard Worker }
504*6777b538SAndroid Build Coastguard Worker 
TEST_F(WebSocketTest,RequestWebSocketTrailingJunk)505*6777b538SAndroid Build Coastguard Worker TEST_F(WebSocketTest, RequestWebSocketTrailingJunk) {
506*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
507*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
508*6777b538SAndroid Build Coastguard Worker   client.Send(
509*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
510*6777b538SAndroid Build Coastguard Worker       "Upgrade: WebSocket\r\n"
511*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
512*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Version: 8\r\n"
513*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Key: key\r\n"
514*6777b538SAndroid Build Coastguard Worker       "\r\nHello? Anyone");
515*6777b538SAndroid Build Coastguard Worker   RunUntilConnectionIdClosed(1);
516*6777b538SAndroid Build Coastguard Worker   client.ExpectUsedThenDisconnectedWithNoData();
517*6777b538SAndroid Build Coastguard Worker }
518*6777b538SAndroid Build Coastguard Worker 
TEST_F(WebSocketAcceptingTest,SendPingFrameWithNoMessage)519*6777b538SAndroid Build Coastguard Worker TEST_F(WebSocketAcceptingTest, SendPingFrameWithNoMessage) {
520*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
521*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
522*6777b538SAndroid Build Coastguard Worker   std::string response;
523*6777b538SAndroid Build Coastguard Worker   client.Send(
524*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
525*6777b538SAndroid Build Coastguard Worker       "Upgrade: WebSocket\r\n"
526*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
527*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Version: 8\r\n"
528*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Key: key\r\n\r\n");
529*6777b538SAndroid Build Coastguard Worker   WaitForRequest();
530*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response));
531*6777b538SAndroid Build Coastguard Worker   const std::string message = "";
532*6777b538SAndroid Build Coastguard Worker   const std::string ping_frame =
533*6777b538SAndroid Build Coastguard Worker       EncodeFrame(message, WebSocketFrameHeader::OpCodeEnum::kOpCodePing,
534*6777b538SAndroid Build Coastguard Worker                   /* mask= */ true, /* finish= */ true);
535*6777b538SAndroid Build Coastguard Worker   const std::string pong_frame =
536*6777b538SAndroid Build Coastguard Worker       EncodeFrame(message, WebSocketFrameHeader::OpCodeEnum::kOpCodePong,
537*6777b538SAndroid Build Coastguard Worker                   /* mask= */ false, /* finish= */ true);
538*6777b538SAndroid Build Coastguard Worker   client.Send(ping_frame);
539*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.Read(&response, pong_frame.length()));
540*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(response, pong_frame);
541*6777b538SAndroid Build Coastguard Worker }
542*6777b538SAndroid Build Coastguard Worker 
TEST_F(WebSocketAcceptingTest,SendPingFrameWithMessage)543*6777b538SAndroid Build Coastguard Worker TEST_F(WebSocketAcceptingTest, SendPingFrameWithMessage) {
544*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
545*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
546*6777b538SAndroid Build Coastguard Worker   std::string response;
547*6777b538SAndroid Build Coastguard Worker   client.Send(
548*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
549*6777b538SAndroid Build Coastguard Worker       "Upgrade: WebSocket\r\n"
550*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
551*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Version: 8\r\n"
552*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Key: key\r\n\r\n");
553*6777b538SAndroid Build Coastguard Worker   WaitForRequest();
554*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response));
555*6777b538SAndroid Build Coastguard Worker   const std::string message = "hello";
556*6777b538SAndroid Build Coastguard Worker   const std::string ping_frame =
557*6777b538SAndroid Build Coastguard Worker       EncodeFrame(message, WebSocketFrameHeader::OpCodeEnum::kOpCodePing,
558*6777b538SAndroid Build Coastguard Worker                   /* mask= */ true, /* finish= */ true);
559*6777b538SAndroid Build Coastguard Worker   const std::string pong_frame =
560*6777b538SAndroid Build Coastguard Worker       EncodeFrame(message, WebSocketFrameHeader::OpCodeEnum::kOpCodePong,
561*6777b538SAndroid Build Coastguard Worker                   /* mask= */ false, /* finish= */ true);
562*6777b538SAndroid Build Coastguard Worker   client.Send(ping_frame);
563*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.Read(&response, pong_frame.length()));
564*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(response, pong_frame);
565*6777b538SAndroid Build Coastguard Worker }
566*6777b538SAndroid Build Coastguard Worker 
TEST_F(WebSocketAcceptingTest,SendPongFrame)567*6777b538SAndroid Build Coastguard Worker TEST_F(WebSocketAcceptingTest, SendPongFrame) {
568*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
569*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
570*6777b538SAndroid Build Coastguard Worker   std::string response;
571*6777b538SAndroid Build Coastguard Worker   client.Send(
572*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
573*6777b538SAndroid Build Coastguard Worker       "Upgrade: WebSocket\r\n"
574*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
575*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Version: 8\r\n"
576*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Key: key\r\n\r\n");
577*6777b538SAndroid Build Coastguard Worker   WaitForRequest();
578*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response));
579*6777b538SAndroid Build Coastguard Worker   const std::string ping_frame = EncodeFrame(
580*6777b538SAndroid Build Coastguard Worker       /* message= */ "", WebSocketFrameHeader::OpCodeEnum::kOpCodePing,
581*6777b538SAndroid Build Coastguard Worker       /* mask= */ true, /* finish= */ true);
582*6777b538SAndroid Build Coastguard Worker   const std::string pong_frame_send = EncodeFrame(
583*6777b538SAndroid Build Coastguard Worker       /* message= */ "", WebSocketFrameHeader::OpCodeEnum::kOpCodePong,
584*6777b538SAndroid Build Coastguard Worker       /* mask= */ true, /* finish= */ true);
585*6777b538SAndroid Build Coastguard Worker   const std::string pong_frame_receive = EncodeFrame(
586*6777b538SAndroid Build Coastguard Worker       /* message= */ "", WebSocketFrameHeader::OpCodeEnum::kOpCodePong,
587*6777b538SAndroid Build Coastguard Worker       /* mask= */ false, /* finish= */ true);
588*6777b538SAndroid Build Coastguard Worker   client.Send(pong_frame_send);
589*6777b538SAndroid Build Coastguard Worker   client.Send(ping_frame);
590*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.Read(&response, pong_frame_receive.length()));
591*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(response, pong_frame_receive);
592*6777b538SAndroid Build Coastguard Worker }
593*6777b538SAndroid Build Coastguard Worker 
TEST_F(WebSocketAcceptingTest,SendLongTextFrame)594*6777b538SAndroid Build Coastguard Worker TEST_F(WebSocketAcceptingTest, SendLongTextFrame) {
595*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
596*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
597*6777b538SAndroid Build Coastguard Worker   std::string response;
598*6777b538SAndroid Build Coastguard Worker   client.Send(
599*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
600*6777b538SAndroid Build Coastguard Worker       "Upgrade: WebSocket\r\n"
601*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
602*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Version: 8\r\n"
603*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Key: key\r\n\r\n");
604*6777b538SAndroid Build Coastguard Worker   WaitForRequest();
605*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response));
606*6777b538SAndroid Build Coastguard Worker   constexpr int kFrameSize = 100000;
607*6777b538SAndroid Build Coastguard Worker   const std::string text_frame(kFrameSize, 'a');
608*6777b538SAndroid Build Coastguard Worker   const std::string continuation_frame(kFrameSize, 'b');
609*6777b538SAndroid Build Coastguard Worker   const std::string text_encoded_frame =
610*6777b538SAndroid Build Coastguard Worker       EncodeFrame(text_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeText,
611*6777b538SAndroid Build Coastguard Worker                   /* mask= */ true,
612*6777b538SAndroid Build Coastguard Worker                   /* finish= */ false);
613*6777b538SAndroid Build Coastguard Worker   const std::string continuation_encoded_frame = EncodeFrame(
614*6777b538SAndroid Build Coastguard Worker       continuation_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation,
615*6777b538SAndroid Build Coastguard Worker       /* mask= */ true, /* finish= */ true);
616*6777b538SAndroid Build Coastguard Worker   client.Send(text_encoded_frame);
617*6777b538SAndroid Build Coastguard Worker   client.Send(continuation_encoded_frame);
618*6777b538SAndroid Build Coastguard Worker   std::string received_message = GetMessage();
619*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(received_message.size(),
620*6777b538SAndroid Build Coastguard Worker             text_frame.size() + continuation_frame.size());
621*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(received_message, text_frame + continuation_frame);
622*6777b538SAndroid Build Coastguard Worker }
623*6777b538SAndroid Build Coastguard Worker 
TEST_F(WebSocketAcceptingTest,SendTwoTextFrame)624*6777b538SAndroid Build Coastguard Worker TEST_F(WebSocketAcceptingTest, SendTwoTextFrame) {
625*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
626*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
627*6777b538SAndroid Build Coastguard Worker   std::string response;
628*6777b538SAndroid Build Coastguard Worker   client.Send(
629*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
630*6777b538SAndroid Build Coastguard Worker       "Upgrade: WebSocket\r\n"
631*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
632*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Version: 8\r\n"
633*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Key: key\r\n\r\n");
634*6777b538SAndroid Build Coastguard Worker   WaitForRequest();
635*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response));
636*6777b538SAndroid Build Coastguard Worker   const std::string text_frame_first = "foo";
637*6777b538SAndroid Build Coastguard Worker   const std::string continuation_frame_first = "bar";
638*6777b538SAndroid Build Coastguard Worker   const std::string text_encoded_frame_first = EncodeFrame(
639*6777b538SAndroid Build Coastguard Worker       text_frame_first, WebSocketFrameHeader::OpCodeEnum::kOpCodeText,
640*6777b538SAndroid Build Coastguard Worker       /* mask= */ true,
641*6777b538SAndroid Build Coastguard Worker       /* finish= */ false);
642*6777b538SAndroid Build Coastguard Worker   const std::string continuation_encoded_frame_first =
643*6777b538SAndroid Build Coastguard Worker       EncodeFrame(continuation_frame_first,
644*6777b538SAndroid Build Coastguard Worker                   WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation,
645*6777b538SAndroid Build Coastguard Worker                   /* mask= */ true, /* finish= */ true);
646*6777b538SAndroid Build Coastguard Worker 
647*6777b538SAndroid Build Coastguard Worker   const std::string text_frame_second = "FOO";
648*6777b538SAndroid Build Coastguard Worker   const std::string continuation_frame_second = "BAR";
649*6777b538SAndroid Build Coastguard Worker   const std::string text_encoded_frame_second = EncodeFrame(
650*6777b538SAndroid Build Coastguard Worker       text_frame_second, WebSocketFrameHeader::OpCodeEnum::kOpCodeText,
651*6777b538SAndroid Build Coastguard Worker       /* mask= */ true,
652*6777b538SAndroid Build Coastguard Worker       /* finish= */ false);
653*6777b538SAndroid Build Coastguard Worker   const std::string continuation_encoded_frame_second =
654*6777b538SAndroid Build Coastguard Worker       EncodeFrame(continuation_frame_second,
655*6777b538SAndroid Build Coastguard Worker                   WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation,
656*6777b538SAndroid Build Coastguard Worker                   /* mask= */ true, /* finish= */ true);
657*6777b538SAndroid Build Coastguard Worker 
658*6777b538SAndroid Build Coastguard Worker   // text_encoded_frame_first -> text_encoded_frame_second
659*6777b538SAndroid Build Coastguard Worker   client.Send(text_encoded_frame_first);
660*6777b538SAndroid Build Coastguard Worker   client.Send(continuation_encoded_frame_first);
661*6777b538SAndroid Build Coastguard Worker   std::string received_message = GetMessage();
662*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(received_message, "foobar");
663*6777b538SAndroid Build Coastguard Worker   client.Send(text_encoded_frame_second);
664*6777b538SAndroid Build Coastguard Worker   client.Send(continuation_encoded_frame_second);
665*6777b538SAndroid Build Coastguard Worker   received_message = GetMessage();
666*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(received_message, "FOOBAR");
667*6777b538SAndroid Build Coastguard Worker }
668*6777b538SAndroid Build Coastguard Worker 
TEST_F(WebSocketAcceptingTest,SendPingPongFrame)669*6777b538SAndroid Build Coastguard Worker TEST_F(WebSocketAcceptingTest, SendPingPongFrame) {
670*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
671*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
672*6777b538SAndroid Build Coastguard Worker   std::string response;
673*6777b538SAndroid Build Coastguard Worker   client.Send(
674*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
675*6777b538SAndroid Build Coastguard Worker       "Upgrade: WebSocket\r\n"
676*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
677*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Version: 8\r\n"
678*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Key: key\r\n\r\n");
679*6777b538SAndroid Build Coastguard Worker   WaitForRequest();
680*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response));
681*6777b538SAndroid Build Coastguard Worker 
682*6777b538SAndroid Build Coastguard Worker   const std::string ping_message_first = "";
683*6777b538SAndroid Build Coastguard Worker   const std::string ping_frame_first = EncodeFrame(
684*6777b538SAndroid Build Coastguard Worker       ping_message_first, WebSocketFrameHeader::OpCodeEnum::kOpCodePing,
685*6777b538SAndroid Build Coastguard Worker       /* mask= */ true, /* finish= */ true);
686*6777b538SAndroid Build Coastguard Worker   const std::string pong_frame_receive_first = EncodeFrame(
687*6777b538SAndroid Build Coastguard Worker       ping_message_first, WebSocketFrameHeader::OpCodeEnum::kOpCodePong,
688*6777b538SAndroid Build Coastguard Worker       /* mask= */ false, /* finish= */ true);
689*6777b538SAndroid Build Coastguard Worker   const std::string pong_frame_send = EncodeFrame(
690*6777b538SAndroid Build Coastguard Worker       /* message= */ "", WebSocketFrameHeader::OpCodeEnum::kOpCodePong,
691*6777b538SAndroid Build Coastguard Worker       /* mask= */ true, /* finish= */ true);
692*6777b538SAndroid Build Coastguard Worker   const std::string ping_message_second = "hello";
693*6777b538SAndroid Build Coastguard Worker   const std::string ping_frame_second = EncodeFrame(
694*6777b538SAndroid Build Coastguard Worker       ping_message_second, WebSocketFrameHeader::OpCodeEnum::kOpCodePing,
695*6777b538SAndroid Build Coastguard Worker       /* mask= */ true, /* finish= */ true);
696*6777b538SAndroid Build Coastguard Worker   const std::string pong_frame_receive_second = EncodeFrame(
697*6777b538SAndroid Build Coastguard Worker       ping_message_second, WebSocketFrameHeader::OpCodeEnum::kOpCodePong,
698*6777b538SAndroid Build Coastguard Worker       /* mask= */ false, /* finish= */ true);
699*6777b538SAndroid Build Coastguard Worker 
700*6777b538SAndroid Build Coastguard Worker   // ping_frame_first -> pong_frame_send -> ping_frame_second
701*6777b538SAndroid Build Coastguard Worker   client.Send(ping_frame_first);
702*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.Read(&response, pong_frame_receive_first.length()));
703*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(response, pong_frame_receive_first);
704*6777b538SAndroid Build Coastguard Worker   client.Send(pong_frame_send);
705*6777b538SAndroid Build Coastguard Worker   client.Send(ping_frame_second);
706*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.Read(&response, pong_frame_receive_second.length()));
707*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(response, pong_frame_receive_second);
708*6777b538SAndroid Build Coastguard Worker }
709*6777b538SAndroid Build Coastguard Worker 
TEST_F(WebSocketAcceptingTest,SendTextAndPingFrame)710*6777b538SAndroid Build Coastguard Worker TEST_F(WebSocketAcceptingTest, SendTextAndPingFrame) {
711*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
712*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
713*6777b538SAndroid Build Coastguard Worker   std::string response;
714*6777b538SAndroid Build Coastguard Worker   client.Send(
715*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
716*6777b538SAndroid Build Coastguard Worker       "Upgrade: WebSocket\r\n"
717*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
718*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Version: 8\r\n"
719*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Key: key\r\n\r\n");
720*6777b538SAndroid Build Coastguard Worker   WaitForRequest();
721*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response));
722*6777b538SAndroid Build Coastguard Worker 
723*6777b538SAndroid Build Coastguard Worker   const std::string text_frame = "foo";
724*6777b538SAndroid Build Coastguard Worker   const std::string continuation_frame = "bar";
725*6777b538SAndroid Build Coastguard Worker   const std::string text_encoded_frame =
726*6777b538SAndroid Build Coastguard Worker       EncodeFrame(text_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeText,
727*6777b538SAndroid Build Coastguard Worker                   /* mask= */ true,
728*6777b538SAndroid Build Coastguard Worker                   /* finish= */ false);
729*6777b538SAndroid Build Coastguard Worker   const std::string continuation_encoded_frame = EncodeFrame(
730*6777b538SAndroid Build Coastguard Worker       continuation_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation,
731*6777b538SAndroid Build Coastguard Worker       /* mask= */ true, /* finish= */ true);
732*6777b538SAndroid Build Coastguard Worker   const std::string ping_message = "ping";
733*6777b538SAndroid Build Coastguard Worker   const std::string ping_frame =
734*6777b538SAndroid Build Coastguard Worker       EncodeFrame(ping_message, WebSocketFrameHeader::OpCodeEnum::kOpCodePing,
735*6777b538SAndroid Build Coastguard Worker                   /* mask= */ true, /* finish= */ true);
736*6777b538SAndroid Build Coastguard Worker   const std::string pong_frame =
737*6777b538SAndroid Build Coastguard Worker       EncodeFrame(ping_message, WebSocketFrameHeader::OpCodeEnum::kOpCodePong,
738*6777b538SAndroid Build Coastguard Worker                   /* mask= */ false, /* finish= */ true);
739*6777b538SAndroid Build Coastguard Worker 
740*6777b538SAndroid Build Coastguard Worker   // text_encoded_frame -> ping_frame -> continuation_encoded_frame
741*6777b538SAndroid Build Coastguard Worker   client.Send(text_encoded_frame);
742*6777b538SAndroid Build Coastguard Worker   client.Send(ping_frame);
743*6777b538SAndroid Build Coastguard Worker   client.Send(continuation_encoded_frame);
744*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.Read(&response, pong_frame.length()));
745*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(response, pong_frame);
746*6777b538SAndroid Build Coastguard Worker   std::string received_message = GetMessage();
747*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(received_message, "foobar");
748*6777b538SAndroid Build Coastguard Worker }
749*6777b538SAndroid Build Coastguard Worker 
TEST_F(WebSocketAcceptingTest,SendTextAndPingFrameWithMessage)750*6777b538SAndroid Build Coastguard Worker TEST_F(WebSocketAcceptingTest, SendTextAndPingFrameWithMessage) {
751*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
752*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
753*6777b538SAndroid Build Coastguard Worker   std::string response;
754*6777b538SAndroid Build Coastguard Worker   client.Send(
755*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
756*6777b538SAndroid Build Coastguard Worker       "Upgrade: WebSocket\r\n"
757*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
758*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Version: 8\r\n"
759*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Key: key\r\n\r\n");
760*6777b538SAndroid Build Coastguard Worker   WaitForRequest();
761*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response));
762*6777b538SAndroid Build Coastguard Worker 
763*6777b538SAndroid Build Coastguard Worker   const std::string text_frame = "foo";
764*6777b538SAndroid Build Coastguard Worker   const std::string continuation_frame = "bar";
765*6777b538SAndroid Build Coastguard Worker   const std::string text_encoded_frame =
766*6777b538SAndroid Build Coastguard Worker       EncodeFrame(text_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeText,
767*6777b538SAndroid Build Coastguard Worker                   /* mask= */ true,
768*6777b538SAndroid Build Coastguard Worker                   /* finish= */ false);
769*6777b538SAndroid Build Coastguard Worker   const std::string continuation_encoded_frame = EncodeFrame(
770*6777b538SAndroid Build Coastguard Worker       continuation_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation,
771*6777b538SAndroid Build Coastguard Worker       /* mask= */ true, /* finish= */ true);
772*6777b538SAndroid Build Coastguard Worker   const std::string ping_message = "hello";
773*6777b538SAndroid Build Coastguard Worker   const std::string ping_frame =
774*6777b538SAndroid Build Coastguard Worker       EncodeFrame(ping_message, WebSocketFrameHeader::OpCodeEnum::kOpCodePing,
775*6777b538SAndroid Build Coastguard Worker                   /* mask= */ true, /* finish= */ true);
776*6777b538SAndroid Build Coastguard Worker   const std::string pong_frame =
777*6777b538SAndroid Build Coastguard Worker       EncodeFrame(ping_message, WebSocketFrameHeader::OpCodeEnum::kOpCodePong,
778*6777b538SAndroid Build Coastguard Worker                   /* mask= */ false, /* finish= */ true);
779*6777b538SAndroid Build Coastguard Worker 
780*6777b538SAndroid Build Coastguard Worker   // text_encoded_frame -> ping_frame -> continuation_frame
781*6777b538SAndroid Build Coastguard Worker   client.Send(text_encoded_frame);
782*6777b538SAndroid Build Coastguard Worker   client.Send(ping_frame);
783*6777b538SAndroid Build Coastguard Worker   client.Send(continuation_encoded_frame);
784*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.Read(&response, pong_frame.length()));
785*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(response, pong_frame);
786*6777b538SAndroid Build Coastguard Worker   std::string received_message = GetMessage();
787*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(received_message, "foobar");
788*6777b538SAndroid Build Coastguard Worker }
789*6777b538SAndroid Build Coastguard Worker 
TEST_F(WebSocketAcceptingTest,SendTextAndPongFrame)790*6777b538SAndroid Build Coastguard Worker TEST_F(WebSocketAcceptingTest, SendTextAndPongFrame) {
791*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
792*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
793*6777b538SAndroid Build Coastguard Worker   std::string response;
794*6777b538SAndroid Build Coastguard Worker   client.Send(
795*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
796*6777b538SAndroid Build Coastguard Worker       "Upgrade: WebSocket\r\n"
797*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
798*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Version: 8\r\n"
799*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Key: key\r\n\r\n");
800*6777b538SAndroid Build Coastguard Worker   WaitForRequest();
801*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response));
802*6777b538SAndroid Build Coastguard Worker 
803*6777b538SAndroid Build Coastguard Worker   const std::string text_frame = "foo";
804*6777b538SAndroid Build Coastguard Worker   const std::string continuation_frame = "bar";
805*6777b538SAndroid Build Coastguard Worker   const std::string text_encoded_frame =
806*6777b538SAndroid Build Coastguard Worker       EncodeFrame(text_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeText,
807*6777b538SAndroid Build Coastguard Worker                   /* mask= */ true,
808*6777b538SAndroid Build Coastguard Worker                   /* finish= */ false);
809*6777b538SAndroid Build Coastguard Worker   const std::string continuation_encoded_frame = EncodeFrame(
810*6777b538SAndroid Build Coastguard Worker       continuation_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation,
811*6777b538SAndroid Build Coastguard Worker       /* mask= */ true, /* finish= */ true);
812*6777b538SAndroid Build Coastguard Worker   const std::string pong_message = "pong";
813*6777b538SAndroid Build Coastguard Worker   const std::string pong_frame =
814*6777b538SAndroid Build Coastguard Worker       EncodeFrame(pong_message, WebSocketFrameHeader::OpCodeEnum::kOpCodePong,
815*6777b538SAndroid Build Coastguard Worker                   /* mask= */ true, /* finish= */ true);
816*6777b538SAndroid Build Coastguard Worker 
817*6777b538SAndroid Build Coastguard Worker   // text_encoded_frame -> pong_frame -> continuation_encoded_frame
818*6777b538SAndroid Build Coastguard Worker   client.Send(text_encoded_frame);
819*6777b538SAndroid Build Coastguard Worker   client.Send(pong_frame);
820*6777b538SAndroid Build Coastguard Worker   client.Send(continuation_encoded_frame);
821*6777b538SAndroid Build Coastguard Worker   std::string received_message = GetMessage();
822*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(received_message, "foobar");
823*6777b538SAndroid Build Coastguard Worker }
824*6777b538SAndroid Build Coastguard Worker 
TEST_F(WebSocketAcceptingTest,SendTextPingPongFrame)825*6777b538SAndroid Build Coastguard Worker TEST_F(WebSocketAcceptingTest, SendTextPingPongFrame) {
826*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
827*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
828*6777b538SAndroid Build Coastguard Worker   std::string response;
829*6777b538SAndroid Build Coastguard Worker   client.Send(
830*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
831*6777b538SAndroid Build Coastguard Worker       "Upgrade: WebSocket\r\n"
832*6777b538SAndroid Build Coastguard Worker       "Connection: SomethingElse, Upgrade\r\n"
833*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Version: 8\r\n"
834*6777b538SAndroid Build Coastguard Worker       "Sec-WebSocket-Key: key\r\n\r\n");
835*6777b538SAndroid Build Coastguard Worker   WaitForRequest();
836*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response));
837*6777b538SAndroid Build Coastguard Worker 
838*6777b538SAndroid Build Coastguard Worker   const std::string text_frame = "foo";
839*6777b538SAndroid Build Coastguard Worker   const std::string continuation_frame = "bar";
840*6777b538SAndroid Build Coastguard Worker   const std::string text_encoded_frame =
841*6777b538SAndroid Build Coastguard Worker       EncodeFrame(text_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeText,
842*6777b538SAndroid Build Coastguard Worker                   /* mask= */ true,
843*6777b538SAndroid Build Coastguard Worker                   /* finish= */ false);
844*6777b538SAndroid Build Coastguard Worker   const std::string continuation_encoded_frame = EncodeFrame(
845*6777b538SAndroid Build Coastguard Worker       continuation_frame, WebSocketFrameHeader::OpCodeEnum::kOpCodeContinuation,
846*6777b538SAndroid Build Coastguard Worker       /* mask= */ true, /* finish= */ true);
847*6777b538SAndroid Build Coastguard Worker 
848*6777b538SAndroid Build Coastguard Worker   const std::string ping_message_first = "hello";
849*6777b538SAndroid Build Coastguard Worker   const std::string ping_frame_first = EncodeFrame(
850*6777b538SAndroid Build Coastguard Worker       ping_message_first, WebSocketFrameHeader::OpCodeEnum::kOpCodePing,
851*6777b538SAndroid Build Coastguard Worker       /* mask= */ true, /* finish= */ true);
852*6777b538SAndroid Build Coastguard Worker   const std::string pong_frame_first = EncodeFrame(
853*6777b538SAndroid Build Coastguard Worker       ping_message_first, WebSocketFrameHeader::OpCodeEnum::kOpCodePong,
854*6777b538SAndroid Build Coastguard Worker       /* mask= */ false, /* finish= */ true);
855*6777b538SAndroid Build Coastguard Worker 
856*6777b538SAndroid Build Coastguard Worker   const std::string ping_message_second = "HELLO";
857*6777b538SAndroid Build Coastguard Worker   const std::string ping_frame_second = EncodeFrame(
858*6777b538SAndroid Build Coastguard Worker       ping_message_second, WebSocketFrameHeader::OpCodeEnum::kOpCodePing,
859*6777b538SAndroid Build Coastguard Worker       /* mask= */ true, /* finish= */ true);
860*6777b538SAndroid Build Coastguard Worker   const std::string pong_frame_second = EncodeFrame(
861*6777b538SAndroid Build Coastguard Worker       ping_message_second, WebSocketFrameHeader::OpCodeEnum::kOpCodePong,
862*6777b538SAndroid Build Coastguard Worker       /* mask= */ false, /* finish= */ true);
863*6777b538SAndroid Build Coastguard Worker 
864*6777b538SAndroid Build Coastguard Worker   // text_encoded_frame -> ping_frame_first -> ping_frame_second ->
865*6777b538SAndroid Build Coastguard Worker   // continuation_encoded_frame
866*6777b538SAndroid Build Coastguard Worker   client.Send(text_encoded_frame);
867*6777b538SAndroid Build Coastguard Worker   client.Send(ping_frame_first);
868*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.Read(&response, pong_frame_first.length()));
869*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(response, pong_frame_first);
870*6777b538SAndroid Build Coastguard Worker   client.Send(ping_frame_second);
871*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.Read(&response, pong_frame_second.length()));
872*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(response, pong_frame_second);
873*6777b538SAndroid Build Coastguard Worker   client.Send(continuation_encoded_frame);
874*6777b538SAndroid Build Coastguard Worker   std::string received_message = GetMessage();
875*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(received_message, "foobar");
876*6777b538SAndroid Build Coastguard Worker }
877*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpServerTest,RequestWithTooLargeBody)878*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, RequestWithTooLargeBody) {
879*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
880*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
881*6777b538SAndroid Build Coastguard Worker   client.Send(
882*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
883*6777b538SAndroid Build Coastguard Worker       "Content-Length: 1073741824\r\n\r\n");
884*6777b538SAndroid Build Coastguard Worker   std::string response;
885*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response));
886*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(
887*6777b538SAndroid Build Coastguard Worker       "HTTP/1.1 500 Internal Server Error\r\n"
888*6777b538SAndroid Build Coastguard Worker       "Content-Length:42\r\n"
889*6777b538SAndroid Build Coastguard Worker       "Content-Type:text/html\r\n\r\n"
890*6777b538SAndroid Build Coastguard Worker       "request content-length too big or unknown.",
891*6777b538SAndroid Build Coastguard Worker       response);
892*6777b538SAndroid Build Coastguard Worker }
893*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpServerTest,Send200)894*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, Send200) {
895*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
896*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
897*6777b538SAndroid Build Coastguard Worker   client.Send("GET /test HTTP/1.1\r\n\r\n");
898*6777b538SAndroid Build Coastguard Worker   auto request = WaitForRequest();
899*6777b538SAndroid Build Coastguard Worker   server_->Send200(request.connection_id, "Response!", "text/plain",
900*6777b538SAndroid Build Coastguard Worker                    TRAFFIC_ANNOTATION_FOR_TESTS);
901*6777b538SAndroid Build Coastguard Worker 
902*6777b538SAndroid Build Coastguard Worker   std::string response;
903*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response));
904*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(response.starts_with("HTTP/1.1 200 OK"));
905*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(response.ends_with("Response!"));
906*6777b538SAndroid Build Coastguard Worker }
907*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpServerTest,SendRaw)908*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, SendRaw) {
909*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
910*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
911*6777b538SAndroid Build Coastguard Worker   client.Send("GET /test HTTP/1.1\r\n\r\n");
912*6777b538SAndroid Build Coastguard Worker   auto request = WaitForRequest();
913*6777b538SAndroid Build Coastguard Worker   server_->SendRaw(request.connection_id, "Raw Data ",
914*6777b538SAndroid Build Coastguard Worker                    TRAFFIC_ANNOTATION_FOR_TESTS);
915*6777b538SAndroid Build Coastguard Worker   server_->SendRaw(request.connection_id, "More Data",
916*6777b538SAndroid Build Coastguard Worker                    TRAFFIC_ANNOTATION_FOR_TESTS);
917*6777b538SAndroid Build Coastguard Worker   server_->SendRaw(request.connection_id, "Third Piece of Data",
918*6777b538SAndroid Build Coastguard Worker                    TRAFFIC_ANNOTATION_FOR_TESTS);
919*6777b538SAndroid Build Coastguard Worker 
920*6777b538SAndroid Build Coastguard Worker   const std::string expected_response("Raw Data More DataThird Piece of Data");
921*6777b538SAndroid Build Coastguard Worker   std::string response;
922*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.Read(&response, expected_response.length()));
923*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(expected_response, response);
924*6777b538SAndroid Build Coastguard Worker }
925*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpServerTest,WrongProtocolRequest)926*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, WrongProtocolRequest) {
927*6777b538SAndroid Build Coastguard Worker   const char* const kBadProtocolRequests[] = {
928*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.0\r\n\r\n",
929*6777b538SAndroid Build Coastguard Worker       "GET /test foo\r\n\r\n",
930*6777b538SAndroid Build Coastguard Worker       "GET /test \r\n\r\n",
931*6777b538SAndroid Build Coastguard Worker   };
932*6777b538SAndroid Build Coastguard Worker 
933*6777b538SAndroid Build Coastguard Worker   for (const char* bad_request : kBadProtocolRequests) {
934*6777b538SAndroid Build Coastguard Worker     TestHttpClient client;
935*6777b538SAndroid Build Coastguard Worker     CreateConnection(&client);
936*6777b538SAndroid Build Coastguard Worker 
937*6777b538SAndroid Build Coastguard Worker     client.Send(bad_request);
938*6777b538SAndroid Build Coastguard Worker     client.ExpectUsedThenDisconnectedWithNoData();
939*6777b538SAndroid Build Coastguard Worker 
940*6777b538SAndroid Build Coastguard Worker     // Assert that the delegate was updated properly.
941*6777b538SAndroid Build Coastguard Worker     ASSERT_EQ(1u, connection_map().size());
942*6777b538SAndroid Build Coastguard Worker     ASSERT_FALSE(connection_map().begin()->second);
943*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(HasRequest());
944*6777b538SAndroid Build Coastguard Worker 
945*6777b538SAndroid Build Coastguard Worker     // Reset the state of the connection map.
946*6777b538SAndroid Build Coastguard Worker     connection_map().clear();
947*6777b538SAndroid Build Coastguard Worker   }
948*6777b538SAndroid Build Coastguard Worker }
949*6777b538SAndroid Build Coastguard Worker 
950*6777b538SAndroid Build Coastguard Worker class MockStreamSocket : public StreamSocket {
951*6777b538SAndroid Build Coastguard Worker  public:
952*6777b538SAndroid Build Coastguard Worker   MockStreamSocket() = default;
953*6777b538SAndroid Build Coastguard Worker 
954*6777b538SAndroid Build Coastguard Worker   MockStreamSocket(const MockStreamSocket&) = delete;
955*6777b538SAndroid Build Coastguard Worker   MockStreamSocket& operator=(const MockStreamSocket&) = delete;
956*6777b538SAndroid Build Coastguard Worker 
957*6777b538SAndroid Build Coastguard Worker   ~MockStreamSocket() override = default;
958*6777b538SAndroid Build Coastguard Worker 
959*6777b538SAndroid Build Coastguard Worker   // StreamSocket
Connect(CompletionOnceCallback callback)960*6777b538SAndroid Build Coastguard Worker   int Connect(CompletionOnceCallback callback) override {
961*6777b538SAndroid Build Coastguard Worker     return ERR_NOT_IMPLEMENTED;
962*6777b538SAndroid Build Coastguard Worker   }
Disconnect()963*6777b538SAndroid Build Coastguard Worker   void Disconnect() override {
964*6777b538SAndroid Build Coastguard Worker     connected_ = false;
965*6777b538SAndroid Build Coastguard Worker     if (!read_callback_.is_null()) {
966*6777b538SAndroid Build Coastguard Worker       read_buf_ = nullptr;
967*6777b538SAndroid Build Coastguard Worker       read_buf_len_ = 0;
968*6777b538SAndroid Build Coastguard Worker       std::move(read_callback_).Run(ERR_CONNECTION_CLOSED);
969*6777b538SAndroid Build Coastguard Worker     }
970*6777b538SAndroid Build Coastguard Worker   }
IsConnected() const971*6777b538SAndroid Build Coastguard Worker   bool IsConnected() const override { return connected_; }
IsConnectedAndIdle() const972*6777b538SAndroid Build Coastguard Worker   bool IsConnectedAndIdle() const override { return IsConnected(); }
GetPeerAddress(IPEndPoint * address) const973*6777b538SAndroid Build Coastguard Worker   int GetPeerAddress(IPEndPoint* address) const override {
974*6777b538SAndroid Build Coastguard Worker     return ERR_NOT_IMPLEMENTED;
975*6777b538SAndroid Build Coastguard Worker   }
GetLocalAddress(IPEndPoint * address) const976*6777b538SAndroid Build Coastguard Worker   int GetLocalAddress(IPEndPoint* address) const override {
977*6777b538SAndroid Build Coastguard Worker     return ERR_NOT_IMPLEMENTED;
978*6777b538SAndroid Build Coastguard Worker   }
NetLog() const979*6777b538SAndroid Build Coastguard Worker   const NetLogWithSource& NetLog() const override { return net_log_; }
WasEverUsed() const980*6777b538SAndroid Build Coastguard Worker   bool WasEverUsed() const override { return true; }
GetNegotiatedProtocol() const981*6777b538SAndroid Build Coastguard Worker   NextProto GetNegotiatedProtocol() const override { return kProtoUnknown; }
GetSSLInfo(SSLInfo * ssl_info)982*6777b538SAndroid Build Coastguard Worker   bool GetSSLInfo(SSLInfo* ssl_info) override { return false; }
GetTotalReceivedBytes() const983*6777b538SAndroid Build Coastguard Worker   int64_t GetTotalReceivedBytes() const override {
984*6777b538SAndroid Build Coastguard Worker     NOTIMPLEMENTED();
985*6777b538SAndroid Build Coastguard Worker     return 0;
986*6777b538SAndroid Build Coastguard Worker   }
ApplySocketTag(const SocketTag & tag)987*6777b538SAndroid Build Coastguard Worker   void ApplySocketTag(const SocketTag& tag) override {}
988*6777b538SAndroid Build Coastguard Worker 
989*6777b538SAndroid Build Coastguard Worker   // Socket
Read(IOBuffer * buf,int buf_len,CompletionOnceCallback callback)990*6777b538SAndroid Build Coastguard Worker   int Read(IOBuffer* buf,
991*6777b538SAndroid Build Coastguard Worker            int buf_len,
992*6777b538SAndroid Build Coastguard Worker            CompletionOnceCallback callback) override {
993*6777b538SAndroid Build Coastguard Worker     if (!connected_) {
994*6777b538SAndroid Build Coastguard Worker       return ERR_SOCKET_NOT_CONNECTED;
995*6777b538SAndroid Build Coastguard Worker     }
996*6777b538SAndroid Build Coastguard Worker     if (pending_read_data_.empty()) {
997*6777b538SAndroid Build Coastguard Worker       read_buf_ = buf;
998*6777b538SAndroid Build Coastguard Worker       read_buf_len_ = buf_len;
999*6777b538SAndroid Build Coastguard Worker       read_callback_ = std::move(callback);
1000*6777b538SAndroid Build Coastguard Worker       return ERR_IO_PENDING;
1001*6777b538SAndroid Build Coastguard Worker     }
1002*6777b538SAndroid Build Coastguard Worker     DCHECK_GT(buf_len, 0);
1003*6777b538SAndroid Build Coastguard Worker     int read_len =
1004*6777b538SAndroid Build Coastguard Worker         std::min(static_cast<int>(pending_read_data_.size()), buf_len);
1005*6777b538SAndroid Build Coastguard Worker     memcpy(buf->data(), pending_read_data_.data(), read_len);
1006*6777b538SAndroid Build Coastguard Worker     pending_read_data_.erase(0, read_len);
1007*6777b538SAndroid Build Coastguard Worker     return read_len;
1008*6777b538SAndroid Build Coastguard Worker   }
1009*6777b538SAndroid Build Coastguard Worker 
Write(IOBuffer * buf,int buf_len,CompletionOnceCallback callback,const NetworkTrafficAnnotationTag & traffic_annotation)1010*6777b538SAndroid Build Coastguard Worker   int Write(IOBuffer* buf,
1011*6777b538SAndroid Build Coastguard Worker             int buf_len,
1012*6777b538SAndroid Build Coastguard Worker             CompletionOnceCallback callback,
1013*6777b538SAndroid Build Coastguard Worker             const NetworkTrafficAnnotationTag& traffic_annotation) override {
1014*6777b538SAndroid Build Coastguard Worker     return ERR_NOT_IMPLEMENTED;
1015*6777b538SAndroid Build Coastguard Worker   }
SetReceiveBufferSize(int32_t size)1016*6777b538SAndroid Build Coastguard Worker   int SetReceiveBufferSize(int32_t size) override {
1017*6777b538SAndroid Build Coastguard Worker     return ERR_NOT_IMPLEMENTED;
1018*6777b538SAndroid Build Coastguard Worker   }
SetSendBufferSize(int32_t size)1019*6777b538SAndroid Build Coastguard Worker   int SetSendBufferSize(int32_t size) override { return ERR_NOT_IMPLEMENTED; }
1020*6777b538SAndroid Build Coastguard Worker 
DidRead(const char * data,int data_len)1021*6777b538SAndroid Build Coastguard Worker   void DidRead(const char* data, int data_len) {
1022*6777b538SAndroid Build Coastguard Worker     if (!read_buf_.get()) {
1023*6777b538SAndroid Build Coastguard Worker       pending_read_data_.append(data, data_len);
1024*6777b538SAndroid Build Coastguard Worker       return;
1025*6777b538SAndroid Build Coastguard Worker     }
1026*6777b538SAndroid Build Coastguard Worker     int read_len = std::min(data_len, read_buf_len_);
1027*6777b538SAndroid Build Coastguard Worker     memcpy(read_buf_->data(), data, read_len);
1028*6777b538SAndroid Build Coastguard Worker     pending_read_data_.assign(data + read_len, data_len - read_len);
1029*6777b538SAndroid Build Coastguard Worker     read_buf_ = nullptr;
1030*6777b538SAndroid Build Coastguard Worker     read_buf_len_ = 0;
1031*6777b538SAndroid Build Coastguard Worker     std::move(read_callback_).Run(read_len);
1032*6777b538SAndroid Build Coastguard Worker   }
1033*6777b538SAndroid Build Coastguard Worker 
1034*6777b538SAndroid Build Coastguard Worker  private:
1035*6777b538SAndroid Build Coastguard Worker   bool connected_ = true;
1036*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBuffer> read_buf_;
1037*6777b538SAndroid Build Coastguard Worker   int read_buf_len_ = 0;
1038*6777b538SAndroid Build Coastguard Worker   CompletionOnceCallback read_callback_;
1039*6777b538SAndroid Build Coastguard Worker   std::string pending_read_data_;
1040*6777b538SAndroid Build Coastguard Worker   NetLogWithSource net_log_;
1041*6777b538SAndroid Build Coastguard Worker };
1042*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpServerTest,RequestWithBodySplitAcrossPackets)1043*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, RequestWithBodySplitAcrossPackets) {
1044*6777b538SAndroid Build Coastguard Worker   auto socket = std::make_unique<MockStreamSocket>();
1045*6777b538SAndroid Build Coastguard Worker   auto* socket_ptr = socket.get();
1046*6777b538SAndroid Build Coastguard Worker   HandleAcceptResult(std::move(socket));
1047*6777b538SAndroid Build Coastguard Worker   std::string body("body");
1048*6777b538SAndroid Build Coastguard Worker   std::string request_text = base::StringPrintf(
1049*6777b538SAndroid Build Coastguard Worker       "GET /test HTTP/1.1\r\n"
1050*6777b538SAndroid Build Coastguard Worker       "SomeHeader: 1\r\n"
1051*6777b538SAndroid Build Coastguard Worker       "Content-Length: %" PRIuS "\r\n\r\n%s",
1052*6777b538SAndroid Build Coastguard Worker       body.length(), body.c_str());
1053*6777b538SAndroid Build Coastguard Worker   socket_ptr->DidRead(request_text.c_str(), request_text.length() - 2);
1054*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(HasRequest());
1055*6777b538SAndroid Build Coastguard Worker   socket_ptr->DidRead(request_text.c_str() + request_text.length() - 2, 2);
1056*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(HasRequest());
1057*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(body, WaitForRequest().info.data);
1058*6777b538SAndroid Build Coastguard Worker }
1059*6777b538SAndroid Build Coastguard Worker 
TEST_F(HttpServerTest,MultipleRequestsOnSameConnection)1060*6777b538SAndroid Build Coastguard Worker TEST_F(HttpServerTest, MultipleRequestsOnSameConnection) {
1061*6777b538SAndroid Build Coastguard Worker   // The idea behind this test is that requests with or without bodies should
1062*6777b538SAndroid Build Coastguard Worker   // not break parsing of the next request.
1063*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
1064*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
1065*6777b538SAndroid Build Coastguard Worker   std::string body = "body";
1066*6777b538SAndroid Build Coastguard Worker   client.Send(
1067*6777b538SAndroid Build Coastguard Worker       base::StringPrintf("GET /test HTTP/1.1\r\n"
1068*6777b538SAndroid Build Coastguard Worker                          "Content-Length: %" PRIuS "\r\n\r\n%s",
1069*6777b538SAndroid Build Coastguard Worker                          body.length(), body.c_str()));
1070*6777b538SAndroid Build Coastguard Worker   auto first_request = WaitForRequest();
1071*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(body, first_request.info.data);
1072*6777b538SAndroid Build Coastguard Worker 
1073*6777b538SAndroid Build Coastguard Worker   int client_connection_id = first_request.connection_id;
1074*6777b538SAndroid Build Coastguard Worker   server_->Send200(client_connection_id, "Content for /test", "text/plain",
1075*6777b538SAndroid Build Coastguard Worker                    TRAFFIC_ANNOTATION_FOR_TESTS);
1076*6777b538SAndroid Build Coastguard Worker   std::string response1;
1077*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response1));
1078*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(response1.starts_with("HTTP/1.1 200 OK"));
1079*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(response1.ends_with("Content for /test"));
1080*6777b538SAndroid Build Coastguard Worker 
1081*6777b538SAndroid Build Coastguard Worker   client.Send("GET /test2 HTTP/1.1\r\n\r\n");
1082*6777b538SAndroid Build Coastguard Worker   auto second_request = WaitForRequest();
1083*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ("/test2", second_request.info.path);
1084*6777b538SAndroid Build Coastguard Worker 
1085*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(client_connection_id, second_request.connection_id);
1086*6777b538SAndroid Build Coastguard Worker   server_->Send404(client_connection_id, TRAFFIC_ANNOTATION_FOR_TESTS);
1087*6777b538SAndroid Build Coastguard Worker   std::string response2;
1088*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response2));
1089*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(response2.starts_with("HTTP/1.1 404 Not Found"));
1090*6777b538SAndroid Build Coastguard Worker 
1091*6777b538SAndroid Build Coastguard Worker   client.Send("GET /test3 HTTP/1.1\r\n\r\n");
1092*6777b538SAndroid Build Coastguard Worker   auto third_request = WaitForRequest();
1093*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ("/test3", third_request.info.path);
1094*6777b538SAndroid Build Coastguard Worker 
1095*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(client_connection_id, third_request.connection_id);
1096*6777b538SAndroid Build Coastguard Worker   server_->Send200(client_connection_id, "Content for /test3", "text/plain",
1097*6777b538SAndroid Build Coastguard Worker                    TRAFFIC_ANNOTATION_FOR_TESTS);
1098*6777b538SAndroid Build Coastguard Worker   std::string response3;
1099*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(client.ReadResponse(&response3));
1100*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(response3.starts_with("HTTP/1.1 200 OK"));
1101*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(response3.ends_with("Content for /test3"));
1102*6777b538SAndroid Build Coastguard Worker }
1103*6777b538SAndroid Build Coastguard Worker 
1104*6777b538SAndroid Build Coastguard Worker class CloseOnConnectHttpServerTest : public HttpServerTest {
1105*6777b538SAndroid Build Coastguard Worker  public:
OnConnect(int connection_id)1106*6777b538SAndroid Build Coastguard Worker   void OnConnect(int connection_id) override {
1107*6777b538SAndroid Build Coastguard Worker     HttpServerTest::OnConnect(connection_id);
1108*6777b538SAndroid Build Coastguard Worker     connection_ids_.push_back(connection_id);
1109*6777b538SAndroid Build Coastguard Worker     server_->Close(connection_id);
1110*6777b538SAndroid Build Coastguard Worker   }
1111*6777b538SAndroid Build Coastguard Worker 
1112*6777b538SAndroid Build Coastguard Worker  protected:
1113*6777b538SAndroid Build Coastguard Worker   std::vector<int> connection_ids_;
1114*6777b538SAndroid Build Coastguard Worker };
1115*6777b538SAndroid Build Coastguard Worker 
TEST_F(CloseOnConnectHttpServerTest,ServerImmediatelyClosesConnection)1116*6777b538SAndroid Build Coastguard Worker TEST_F(CloseOnConnectHttpServerTest, ServerImmediatelyClosesConnection) {
1117*6777b538SAndroid Build Coastguard Worker   TestHttpClient client;
1118*6777b538SAndroid Build Coastguard Worker   CreateConnection(&client);
1119*6777b538SAndroid Build Coastguard Worker   client.Send("GET / HTTP/1.1\r\n\r\n");
1120*6777b538SAndroid Build Coastguard Worker 
1121*6777b538SAndroid Build Coastguard Worker   // The server should close the socket without responding.
1122*6777b538SAndroid Build Coastguard Worker   client.ExpectUsedThenDisconnectedWithNoData();
1123*6777b538SAndroid Build Coastguard Worker 
1124*6777b538SAndroid Build Coastguard Worker   // Run any tasks the TestServer posted.
1125*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
1126*6777b538SAndroid Build Coastguard Worker 
1127*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(1ul, connection_ids_.size());
1128*6777b538SAndroid Build Coastguard Worker   // OnHttpRequest() should never have been called, since the connection was
1129*6777b538SAndroid Build Coastguard Worker   // closed without reading from it.
1130*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(HasRequest());
1131*6777b538SAndroid Build Coastguard Worker }
1132*6777b538SAndroid Build Coastguard Worker 
1133*6777b538SAndroid Build Coastguard Worker }  // namespace
1134*6777b538SAndroid Build Coastguard Worker 
1135*6777b538SAndroid Build Coastguard Worker }  // namespace net
1136