Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / http / http_network_layer_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/http/http_network_layer.h"
6
7 #include "base/basictypes.h"
8 #include "base/strings/stringprintf.h"
9 #include "net/base/net_log.h"
10 #include "net/cert/mock_cert_verifier.h"
11 #include "net/dns/mock_host_resolver.h"
12 #include "net/http/http_network_session.h"
13 #include "net/http/http_server_properties_impl.h"
14 #include "net/http/http_transaction_test_util.h"
15 #include "net/http/transport_security_state.h"
16 #include "net/proxy/proxy_service.h"
17 #include "net/socket/socket_test_util.h"
18 #include "net/spdy/spdy_session_pool.h"
19 #include "net/ssl/ssl_config_service_defaults.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "testing/platform_test.h"
22
23 namespace net {
24
25 namespace {
26
27 class HttpNetworkLayerTest : public PlatformTest {
28  protected:
29   HttpNetworkLayerTest() : ssl_config_service_(new SSLConfigServiceDefaults) {}
30
31   void SetUp() override {
32     ConfigureTestDependencies(ProxyService::CreateDirect());
33   }
34
35   void ConfigureTestDependencies(ProxyService* proxy_service) {
36     cert_verifier_.reset(new MockCertVerifier);
37     transport_security_state_.reset(new TransportSecurityState);
38     proxy_service_.reset(proxy_service);
39     HttpNetworkSession::Params session_params;
40     session_params.client_socket_factory = &mock_socket_factory_;
41     session_params.host_resolver = &host_resolver_;
42     session_params.cert_verifier = cert_verifier_.get();
43     session_params.transport_security_state = transport_security_state_.get();
44     session_params.proxy_service = proxy_service_.get();
45     session_params.ssl_config_service = ssl_config_service_.get();
46     session_params.http_server_properties =
47         http_server_properties_.GetWeakPtr();
48     network_session_ = new HttpNetworkSession(session_params);
49     factory_.reset(new HttpNetworkLayer(network_session_.get()));
50   }
51
52   void ExecuteRequestExpectingContentAndHeader(const std::string& method,
53                                                const std::string& content,
54                                                const std::string& header,
55                                                const std::string& value) {
56     TestCompletionCallback callback;
57
58     HttpRequestInfo request_info;
59     request_info.url = GURL("http://www.google.com/");
60     request_info.method = method;
61     request_info.load_flags = LOAD_NORMAL;
62
63     scoped_ptr<HttpTransaction> trans;
64     int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
65     EXPECT_EQ(OK, rv);
66
67     rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
68     if (rv == ERR_IO_PENDING)
69       rv = callback.WaitForResult();
70     ASSERT_EQ(OK, rv);
71
72     std::string contents;
73     rv = ReadTransaction(trans.get(), &contents);
74     EXPECT_EQ(OK, rv);
75     EXPECT_EQ(content, contents);
76
77     if (!header.empty()) {
78       // We also have a server header here that isn't set by the proxy.
79       EXPECT_TRUE(trans->GetResponseInfo()->headers->HasHeaderValue(
80           header, value));
81     }
82   }
83
84   // Check that |proxy_count| proxies are in the retry list.
85   // These will be, in order, |bad_proxy| and |bad_proxy2|".
86   void TestBadProxies(unsigned int proxy_count, const std::string& bad_proxy,
87                       const std::string& bad_proxy2) {
88     const ProxyRetryInfoMap& retry_info = proxy_service_->proxy_retry_info();
89     ASSERT_EQ(proxy_count, retry_info.size());
90     if (proxy_count > 0)
91       ASSERT_TRUE(retry_info.find(bad_proxy) != retry_info.end());
92     if (proxy_count > 1)
93       ASSERT_TRUE(retry_info.find(bad_proxy2) != retry_info.end());
94   }
95
96   // Simulates a request through a proxy which returns a bypass, which is then
97   // retried through a second proxy that doesn't bypass.
98   // Checks that the expected requests were issued, the expected content was
99   // received, and the first proxy |bad_proxy| was marked as bad.
100   void TestProxyFallback(const std::string& bad_proxy) {
101     MockRead data_reads[] = {
102       MockRead("HTTP/1.1 200 OK\r\n"
103                "Chrome-Proxy: bypass=0\r\n\r\n"),
104       MockRead("Bypass message"),
105       MockRead(SYNCHRONOUS, OK),
106     };
107     TestProxyFallbackWithMockReads(bad_proxy, "", data_reads,
108                                    arraysize(data_reads), 1u);
109   }
110
111   void TestProxyFallbackWithMockReads(const std::string& bad_proxy,
112                                       const std::string& bad_proxy2,
113                                       MockRead data_reads[],
114                                       int data_reads_size,
115                                       unsigned int expected_retry_info_size) {
116     TestProxyFallbackByMethodWithMockReads(bad_proxy, bad_proxy2, data_reads,
117                                            data_reads_size, "GET", "content",
118                                            true, expected_retry_info_size);
119   }
120
121   void TestProxyFallbackByMethodWithMockReads(
122       const std::string& bad_proxy,
123       const std::string& bad_proxy2,
124       MockRead data_reads[],
125       int data_reads_size,
126       std::string method,
127       std::string content,
128       bool retry_expected,
129       unsigned int expected_retry_info_size) {
130     std::string trailer =
131         (method == "HEAD" || method == "PUT" || method == "POST") ?
132         "Content-Length: 0\r\n\r\n" : "\r\n";
133     std::string request =
134         base::StringPrintf("%s http://www.google.com/ HTTP/1.1\r\n"
135                            "Host: www.google.com\r\n"
136                            "Proxy-Connection: keep-alive\r\n"
137                            "%s", method.c_str(), trailer.c_str());
138
139     MockWrite data_writes[] = {
140       MockWrite(request.c_str()),
141     };
142
143     StaticSocketDataProvider data1(data_reads, data_reads_size,
144                                   data_writes, arraysize(data_writes));
145     mock_socket_factory_.AddSocketDataProvider(&data1);
146
147     // Second data provider returns the expected content.
148     MockRead data_reads2[3];
149     size_t data_reads2_index = 0;
150     data_reads2[data_reads2_index++] = MockRead("HTTP/1.0 200 OK\r\n"
151                                                 "Server: not-proxy\r\n\r\n");
152     if (!content.empty())
153       data_reads2[data_reads2_index++] = MockRead(content.c_str());
154     data_reads2[data_reads2_index++] = MockRead(SYNCHRONOUS, OK);
155
156     MockWrite data_writes2[] = {
157       MockWrite(request.c_str()),
158     };
159     StaticSocketDataProvider data2(data_reads2, data_reads2_index,
160                                   data_writes2, arraysize(data_writes2));
161     mock_socket_factory_.AddSocketDataProvider(&data2);
162
163     // Expect that we get "content" and not "Bypass message", and that there's
164     // a "not-proxy" "Server:" header in the final response.
165     if (retry_expected) {
166       ExecuteRequestExpectingContentAndHeader(method, content,
167                                               "server", "not-proxy");
168     } else {
169       ExecuteRequestExpectingContentAndHeader(method, content, "", "");
170     }
171
172     // We should also observe the bad proxy in the retry list.
173     TestBadProxies(expected_retry_info_size, bad_proxy, bad_proxy2);
174   }
175
176   // Simulates a request through a proxy which returns a bypass, which is then
177   // retried through a direct connection to the origin site.
178   // Checks that the expected requests were issued, the expected content was
179   // received, and the proxy |bad_proxy| was marked as bad.
180   void TestProxyFallbackToDirect(const std::string& bad_proxy) {
181     MockRead data_reads[] = {
182       MockRead("HTTP/1.1 200 OK\r\n"
183                "Chrome-Proxy: bypass=0\r\n\r\n"),
184       MockRead("Bypass message"),
185       MockRead(SYNCHRONOUS, OK),
186     };
187     MockWrite data_writes[] = {
188       MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
189                 "Host: www.google.com\r\n"
190                 "Proxy-Connection: keep-alive\r\n\r\n"),
191     };
192     StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
193                                   data_writes, arraysize(data_writes));
194     mock_socket_factory_.AddSocketDataProvider(&data1);
195
196     // Second data provider returns the expected content.
197     MockRead data_reads2[] = {
198       MockRead("HTTP/1.0 200 OK\r\n"
199                "Server: not-proxy\r\n\r\n"),
200       MockRead("content"),
201       MockRead(SYNCHRONOUS, OK),
202     };
203     MockWrite data_writes2[] = {
204       MockWrite("GET / HTTP/1.1\r\n"
205                 "Host: www.google.com\r\n"
206                 "Connection: keep-alive\r\n\r\n"),
207     };
208     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
209                                    data_writes2, arraysize(data_writes2));
210     mock_socket_factory_.AddSocketDataProvider(&data2);
211
212     // Expect that we get "content" and not "Bypass message", and that there's
213     // a "not-proxy" "Server:" header in the final response.
214     ExecuteRequestExpectingContentAndHeader("GET", "content",
215                                             "server", "not-proxy");
216
217     // We should also observe the bad proxy in the retry list.
218     TestBadProxies(1u, bad_proxy, "");
219   }
220
221   // Simulates a request through a proxy which returns a bypass, under a
222   // configuration where there is no valid bypass. |proxy_count| proxies
223   // are expected to be configured.
224   // Checks that the expected requests were issued, the bypass message was the
225   // final received content,  and all proxies were marked as bad.
226   void TestProxyFallbackFail(unsigned int proxy_count,
227                              const std::string& bad_proxy,
228                              const std::string& bad_proxy2) {
229     MockRead data_reads[] = {
230       MockRead("HTTP/1.1 200 OK\r\n"
231                "Chrome-Proxy: bypass=0\r\n\r\n"),
232       MockRead("Bypass message"),
233       MockRead(SYNCHRONOUS, OK),
234     };
235     MockWrite data_writes[] = {
236       MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
237                 "Host: www.google.com\r\n"
238                 "Proxy-Connection: keep-alive\r\n\r\n"),
239     };
240     StaticSocketDataProvider data1(data_reads, arraysize(data_reads),
241                                    data_writes, arraysize(data_writes));
242     StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
243                                    data_writes, arraysize(data_writes));
244
245     mock_socket_factory_.AddSocketDataProvider(&data1);
246     if (proxy_count > 1)
247       mock_socket_factory_.AddSocketDataProvider(&data2);
248
249     // Expect that we get "Bypass message", and not "content"..
250     ExecuteRequestExpectingContentAndHeader("GET", "Bypass message", "", "");
251
252     // We should also observe the bad proxy or proxies in the retry list.
253     TestBadProxies(proxy_count, bad_proxy, bad_proxy2);
254   }
255
256   MockClientSocketFactory mock_socket_factory_;
257   MockHostResolver host_resolver_;
258   scoped_ptr<CertVerifier> cert_verifier_;
259   scoped_ptr<TransportSecurityState> transport_security_state_;
260   scoped_ptr<ProxyService> proxy_service_;
261   const scoped_refptr<SSLConfigService> ssl_config_service_;
262   scoped_refptr<HttpNetworkSession> network_session_;
263   scoped_ptr<HttpNetworkLayer> factory_;
264   HttpServerPropertiesImpl http_server_properties_;
265 };
266
267 TEST_F(HttpNetworkLayerTest, CreateAndDestroy) {
268   scoped_ptr<HttpTransaction> trans;
269   int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
270   EXPECT_EQ(OK, rv);
271   EXPECT_TRUE(trans.get() != NULL);
272 }
273
274 TEST_F(HttpNetworkLayerTest, Suspend) {
275   scoped_ptr<HttpTransaction> trans;
276   int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
277   EXPECT_EQ(OK, rv);
278
279   trans.reset();
280
281   factory_->OnSuspend();
282
283   rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
284   EXPECT_EQ(ERR_NETWORK_IO_SUSPENDED, rv);
285
286   ASSERT_TRUE(trans == NULL);
287
288   factory_->OnResume();
289
290   rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
291   EXPECT_EQ(OK, rv);
292 }
293
294 TEST_F(HttpNetworkLayerTest, GET) {
295   MockRead data_reads[] = {
296     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
297     MockRead("hello world"),
298     MockRead(SYNCHRONOUS, OK),
299   };
300   MockWrite data_writes[] = {
301     MockWrite("GET / HTTP/1.1\r\n"
302               "Host: www.google.com\r\n"
303               "Connection: keep-alive\r\n"
304               "User-Agent: Foo/1.0\r\n\r\n"),
305   };
306   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
307                                 data_writes, arraysize(data_writes));
308   mock_socket_factory_.AddSocketDataProvider(&data);
309
310   TestCompletionCallback callback;
311
312   HttpRequestInfo request_info;
313   request_info.url = GURL("http://www.google.com/");
314   request_info.method = "GET";
315   request_info.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
316                                        "Foo/1.0");
317   request_info.load_flags = LOAD_NORMAL;
318
319   scoped_ptr<HttpTransaction> trans;
320   int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
321   EXPECT_EQ(OK, rv);
322
323   rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
324   rv = callback.GetResult(rv);
325   ASSERT_EQ(OK, rv);
326
327   std::string contents;
328   rv = ReadTransaction(trans.get(), &contents);
329   EXPECT_EQ(OK, rv);
330   EXPECT_EQ("hello world", contents);
331 }
332
333 TEST_F(HttpNetworkLayerTest, NetworkVerified) {
334   MockRead data_reads[] = {
335     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
336     MockRead("hello world"),
337     MockRead(SYNCHRONOUS, OK),
338   };
339   MockWrite data_writes[] = {
340     MockWrite("GET / HTTP/1.1\r\n"
341               "Host: www.google.com\r\n"
342               "Connection: keep-alive\r\n"
343               "User-Agent: Foo/1.0\r\n\r\n"),
344   };
345   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
346                                 data_writes, arraysize(data_writes));
347   mock_socket_factory_.AddSocketDataProvider(&data);
348
349   TestCompletionCallback callback;
350
351   HttpRequestInfo request_info;
352   request_info.url = GURL("http://www.google.com/");
353   request_info.method = "GET";
354   request_info.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
355                                        "Foo/1.0");
356   request_info.load_flags = LOAD_NORMAL;
357
358   scoped_ptr<HttpTransaction> trans;
359   int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
360   EXPECT_EQ(OK, rv);
361
362   rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
363   ASSERT_EQ(OK, callback.GetResult(rv));
364
365   EXPECT_TRUE(trans->GetResponseInfo()->network_accessed);
366 }
367
368 TEST_F(HttpNetworkLayerTest, NetworkUnVerified) {
369   MockRead data_reads[] = {
370     MockRead(ASYNC, ERR_CONNECTION_RESET),
371   };
372   MockWrite data_writes[] = {
373     MockWrite("GET / HTTP/1.1\r\n"
374               "Host: www.google.com\r\n"
375               "Connection: keep-alive\r\n"
376               "User-Agent: Foo/1.0\r\n\r\n"),
377   };
378   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
379                                 data_writes, arraysize(data_writes));
380   mock_socket_factory_.AddSocketDataProvider(&data);
381
382   TestCompletionCallback callback;
383
384   HttpRequestInfo request_info;
385   request_info.url = GURL("http://www.google.com/");
386   request_info.method = "GET";
387   request_info.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
388                                        "Foo/1.0");
389   request_info.load_flags = LOAD_NORMAL;
390
391   scoped_ptr<HttpTransaction> trans;
392   int rv = factory_->CreateTransaction(DEFAULT_PRIORITY, &trans);
393   EXPECT_EQ(OK, rv);
394
395   rv = trans->Start(&request_info, callback.callback(), BoundNetLog());
396   ASSERT_EQ(ERR_CONNECTION_RESET, callback.GetResult(rv));
397
398   // If the response info is null, that means that any consumer won't
399   // see the network accessed bit set.
400   EXPECT_EQ(NULL, trans->GetResponseInfo());
401 }
402
403 }  // namespace
404
405 }  // namespace net