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/url_request/url_request_job.h"
6
7#include "base/memory/scoped_ptr.h"
8#include "base/run_loop.h"
9#include "net/base/request_priority.h"
10#include "net/http/http_transaction_test_util.h"
11#include "net/url_request/url_request.h"
12#include "net/url_request/url_request_test_util.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace net {
16
17namespace {
18
19// This is a header that signals the end of the data.
20const char kGzipData[] = "\x1f\x08b\x08\0\0\0\0\0\0\3\3\0\0\0\0\0\0\0\0";
21const char kGzipDataWithName[] =
22    "\x1f\x08b\x08\x08\0\0\0\0\0\0name\0\3\0\0\0\0\0\0\0\0";
23
24void GZipServer(const HttpRequestInfo* request,
25                std::string* response_status,
26                std::string* response_headers,
27                std::string* response_data) {
28  response_data->assign(kGzipData, sizeof(kGzipData));
29}
30
31void BigGZipServer(const HttpRequestInfo* request,
32                   std::string* response_status,
33                   std::string* response_headers,
34                   std::string* response_data) {
35  response_data->assign(kGzipDataWithName, sizeof(kGzipDataWithName));
36  response_data->insert(10, 64 * 1024, 'a');
37}
38
39const MockTransaction kGZip_Transaction = {
40    "http://www.google.com/gzyp",
41    "GET",
42    base::Time(),
43    "",
44    LOAD_NORMAL,
45    "HTTP/1.1 200 OK",
46    "Cache-Control: max-age=10000\n"
47    "Content-Encoding: gzip\n"
48    "Content-Length: 30\n",  // Intentionally wrong.
49    base::Time(),
50    "",
51    TEST_MODE_NORMAL,
52    &GZipServer,
53    0,
54    OK
55};
56
57const MockTransaction kRedirect_Transaction = {
58    "http://www.google.com/redirect",
59    "GET",
60    base::Time(),
61    "",
62    LOAD_NORMAL,
63    "HTTP/1.1 302 Found",
64    "Cache-Control: max-age=10000\n"
65    "Location: http://www.google.com/destination\n"
66    "Content-Length: 5\n",
67    base::Time(),
68    "hello",
69    TEST_MODE_NORMAL,
70    NULL,
71    0,
72    OK
73};
74
75}  // namespace
76
77TEST(URLRequestJob, TransactionNotifiedWhenDone) {
78  MockNetworkLayer network_layer;
79  TestURLRequestContext context;
80  context.set_http_transaction_factory(&network_layer);
81
82  TestDelegate d;
83  scoped_ptr<URLRequest> req(context.CreateRequest(
84      GURL(kGZip_Transaction.url), DEFAULT_PRIORITY, &d, NULL));
85  AddMockTransaction(&kGZip_Transaction);
86
87  req->set_method("GET");
88  req->Start();
89
90  base::MessageLoop::current()->Run();
91
92  EXPECT_TRUE(network_layer.done_reading_called());
93
94  RemoveMockTransaction(&kGZip_Transaction);
95}
96
97TEST(URLRequestJob, SyncTransactionNotifiedWhenDone) {
98  MockNetworkLayer network_layer;
99  TestURLRequestContext context;
100  context.set_http_transaction_factory(&network_layer);
101
102  TestDelegate d;
103  scoped_ptr<URLRequest> req(context.CreateRequest(
104      GURL(kGZip_Transaction.url), DEFAULT_PRIORITY, &d, NULL));
105  MockTransaction transaction(kGZip_Transaction);
106  transaction.test_mode = TEST_MODE_SYNC_ALL;
107  AddMockTransaction(&transaction);
108
109  req->set_method("GET");
110  req->Start();
111
112  base::RunLoop().Run();
113
114  EXPECT_TRUE(network_layer.done_reading_called());
115
116  RemoveMockTransaction(&transaction);
117}
118
119// Tests processing a large gzip header one byte at a time.
120TEST(URLRequestJob, SyncSlowTransaction) {
121  MockNetworkLayer network_layer;
122  TestURLRequestContext context;
123  context.set_http_transaction_factory(&network_layer);
124
125  TestDelegate d;
126  scoped_ptr<URLRequest> req(context.CreateRequest(
127      GURL(kGZip_Transaction.url), DEFAULT_PRIORITY, &d, NULL));
128  MockTransaction transaction(kGZip_Transaction);
129  transaction.test_mode = TEST_MODE_SYNC_ALL | TEST_MODE_SLOW_READ;
130  transaction.handler = &BigGZipServer;
131  AddMockTransaction(&transaction);
132
133  req->set_method("GET");
134  req->Start();
135
136  base::RunLoop().Run();
137
138  EXPECT_TRUE(network_layer.done_reading_called());
139
140  RemoveMockTransaction(&transaction);
141}
142
143TEST(URLRequestJob, RedirectTransactionNotifiedWhenDone) {
144  MockNetworkLayer network_layer;
145  TestURLRequestContext context;
146  context.set_http_transaction_factory(&network_layer);
147
148  TestDelegate d;
149  scoped_ptr<URLRequest> req(context.CreateRequest(
150      GURL(kRedirect_Transaction.url), DEFAULT_PRIORITY, &d, NULL));
151  AddMockTransaction(&kRedirect_Transaction);
152
153  req->set_method("GET");
154  req->Start();
155
156  base::RunLoop().Run();
157
158  EXPECT_TRUE(network_layer.done_reading_called());
159
160  RemoveMockTransaction(&kRedirect_Transaction);
161}
162
163TEST(URLRequestJob, TransactionNotCachedWhenNetworkDelegateRedirects) {
164  MockNetworkLayer network_layer;
165  TestNetworkDelegate network_delegate;
166  network_delegate.set_redirect_on_headers_received_url(GURL("http://foo"));
167  TestURLRequestContext context;
168  context.set_http_transaction_factory(&network_layer);
169  context.set_network_delegate(&network_delegate);
170
171  TestDelegate d;
172  scoped_ptr<URLRequest> req(context.CreateRequest(
173      GURL(kGZip_Transaction.url), DEFAULT_PRIORITY, &d, NULL));
174  AddMockTransaction(&kGZip_Transaction);
175
176  req->set_method("GET");
177  req->Start();
178
179  base::RunLoop().Run();
180
181  EXPECT_TRUE(network_layer.stop_caching_called());
182
183  RemoveMockTransaction(&kGZip_Transaction);
184}
185
186}  // namespace net
187