Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(507)

Side by Side Diff: content/browser/loader/mime_sniffing_resource_handler_unittest.cc

Issue 2005273002: Move MimeTypeResourceHandler before ThrottlingResourceHandler (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/loader/mime_type_resource_handler.h" 5 #include "content/browser/loader/mime_sniffing_resource_handler.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
11 #include "base/files/file_path.h" 11 #include "base/files/file_path.h"
12 #include "base/location.h" 12 #include "base/location.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
16 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
17 #include "content/browser/loader/intercepting_resource_handler.h"
17 #include "content/browser/loader/resource_dispatcher_host_impl.h" 18 #include "content/browser/loader/resource_dispatcher_host_impl.h"
18 #include "content/public/browser/resource_controller.h" 19 #include "content/public/browser/resource_controller.h"
19 #include "content/public/browser/resource_dispatcher_host_delegate.h" 20 #include "content/public/browser/resource_dispatcher_host_delegate.h"
20 #include "content/public/browser/resource_request_info.h" 21 #include "content/public/browser/resource_request_info.h"
21 #include "content/public/common/resource_response.h" 22 #include "content/public/common/resource_response.h"
22 #include "content/public/common/webplugininfo.h" 23 #include "content/public/common/webplugininfo.h"
23 #include "content/public/test/test_browser_thread_bundle.h" 24 #include "content/public/test/test_browser_thread_bundle.h"
24 #include "content/public/test/test_utils.h" 25 #include "content/public/test/test_utils.h"
25 #include "content/test/fake_plugin_service.h" 26 #include "content/test/fake_plugin_service.h"
26 #include "net/url_request/url_request_context.h" 27 #include "net/url_request/url_request_context.h"
27 #include "testing/gtest/include/gtest/gtest.h" 28 #include "testing/gtest/include/gtest/gtest.h"
28 #include "url/gurl.h" 29 #include "url/gurl.h"
29 30
30 namespace content { 31 namespace content {
31 32
32 namespace { 33 namespace {
33 34
34 class TestResourceHandler : public ResourceHandler { 35 class TestResourceHandler : public ResourceHandler {
35 public: 36 public:
36 TestResourceHandler() : ResourceHandler(nullptr) {} 37 TestResourceHandler(bool response_started,
38 bool defer_response_started,
39 bool will_read,
40 bool read_completed,
41 bool defer_read_completed)
42 : ResourceHandler(nullptr),
43 buffer_(new net::IOBuffer(2048)),
44 response_started_(response_started),
45 defer_response_started_(defer_response_started),
46 will_read_(will_read),
47 read_completed_(read_completed),
48 defer_read_completed_(defer_read_completed) {}
37 49
38 void SetController(ResourceController* controller) override {} 50 void SetController(ResourceController* controller) override {}
39 51
40 bool OnRequestRedirected(const net::RedirectInfo& redirect_info, 52 bool OnRequestRedirected(const net::RedirectInfo& redirect_info,
41 ResourceResponse* response, 53 ResourceResponse* response,
42 bool* defer) override { 54 bool* defer) override {
43 NOTREACHED(); 55 NOTREACHED();
44 return false; 56 return false;
45 } 57 }
46 58
47 bool OnResponseStarted(ResourceResponse* response, bool* defer) override { 59 bool OnResponseStarted(ResourceResponse* response, bool* defer) override {
48 return false; 60 if (defer_response_started_)
61 *defer = true;
62 return response_started_;
49 } 63 }
50 64
51 bool OnWillStart(const GURL& url, bool* defer) override { 65 bool OnWillStart(const GURL& url, bool* defer) override { return false; }
52 return false;
53 }
54 66
55 bool OnBeforeNetworkStart(const GURL& url, bool* defer) override { 67 bool OnBeforeNetworkStart(const GURL& url, bool* defer) override {
56 NOTREACHED(); 68 NOTREACHED();
57 return false; 69 return false;
58 } 70 }
59 71
60 bool OnWillRead(scoped_refptr<net::IOBuffer>* buf, 72 bool OnWillRead(scoped_refptr<net::IOBuffer>* buf,
61 int* buf_size, 73 int* buf_size,
62 int min_size) override { 74 int min_size) override {
63 NOTREACHED(); 75 *buf = buffer_;
64 return false; 76 *buf_size = 2048;
77 return will_read_;
65 } 78 }
66 79
67 bool OnReadCompleted(int bytes_read, bool* defer) override { 80 bool OnReadCompleted(int bytes_read, bool* defer) override {
68 NOTREACHED(); 81 DCHECK_LT(bytes_read, 2048);
69 return false; 82 if (defer_read_completed_)
83 *defer = true;
84 return read_completed_;
70 } 85 }
71 86
72 void OnResponseCompleted(const net::URLRequestStatus& status, 87 void OnResponseCompleted(const net::URLRequestStatus& status,
73 const std::string& security_info, 88 const std::string& security_info,
74 bool* defer) override { 89 bool* defer) override {}
75 }
76 90
77 void OnDataDownloaded(int bytes_downloaded) override { 91 void OnDataDownloaded(int bytes_downloaded) override { NOTREACHED(); }
78 NOTREACHED(); 92
93 scoped_refptr<net::IOBuffer> buffer() { return buffer_; }
94
95 private:
96 scoped_refptr<net::IOBuffer> buffer_;
97 bool response_started_;
98 bool defer_response_started_;
99 bool will_read_;
100 bool read_completed_;
101 bool defer_read_completed_;
102 DISALLOW_COPY_AND_ASSIGN(TestResourceHandler);
103 };
104
105 class TestResourceDispatcherHostDelegate
106 : public ResourceDispatcherHostDelegate {
107 public:
108 TestResourceDispatcherHostDelegate(bool must_download)
109 : must_download_(must_download) {}
110
111 bool ShouldForceDownloadResource(const GURL& url,
112 const std::string& mime_type) override {
113 return must_download_;
79 } 114 }
80 115
81 private: 116 private:
82 DISALLOW_COPY_AND_ASSIGN(TestResourceHandler); 117 const bool must_download_;
83 }; 118 };
84 119
85 class TestResourceDispatcherHost : public ResourceDispatcherHostImpl { 120 class TestResourceDispatcherHost : public ResourceDispatcherHostImpl {
86 public: 121 public:
87 explicit TestResourceDispatcherHost(bool stream_has_handler) 122 TestResourceDispatcherHost(bool stream_has_handler)
88 : stream_has_handler_(stream_has_handler), 123 : stream_has_handler_(stream_has_handler),
89 intercepted_as_stream_(false), 124 intercepted_as_stream_(false),
90 intercepted_as_stream_count_(0) {} 125 intercepted_as_stream_count_(0),
126 last_resource_handler_(nullptr) {}
91 127
92 bool intercepted_as_stream() const { return intercepted_as_stream_; } 128 bool intercepted_as_stream() const { return intercepted_as_stream_; }
93 129
94 std::unique_ptr<ResourceHandler> CreateResourceHandlerForDownload( 130 std::unique_ptr<ResourceHandler> CreateResourceHandlerForDownload(
95 net::URLRequest* request, 131 net::URLRequest* request,
96 bool is_content_initiated, 132 bool is_content_initiated,
97 bool must_download) override { 133 bool must_download) override {
98 return std::unique_ptr<ResourceHandler>(new TestResourceHandler); 134 return CreateNewResourceHandler();
99 } 135 }
100 136
101 std::unique_ptr<ResourceHandler> MaybeInterceptAsStream( 137 std::unique_ptr<ResourceHandler> MaybeInterceptAsStream(
102 const base::FilePath& plugin_path, 138 const base::FilePath& plugin_path,
103 net::URLRequest* request, 139 net::URLRequest* request,
104 ResourceResponse* response, 140 ResourceResponse* response,
105 std::string* payload) override { 141 std::string* payload) override {
106 intercepted_as_stream_count_++; 142 intercepted_as_stream_count_++;
107 if (stream_has_handler_) { 143 if (stream_has_handler_) {
108 intercepted_as_stream_ = true; 144 intercepted_as_stream_ = true;
109 return std::unique_ptr<ResourceHandler>(new TestResourceHandler); 145 return CreateNewResourceHandler();
110 } else { 146 } else {
111 return std::unique_ptr<ResourceHandler>(); 147 return CreateNewResourceHandler();
112 } 148 }
113 } 149 }
114 150
115 int intercepted_as_stream_count() const { 151 int intercepted_as_stream_count() const {
116 return intercepted_as_stream_count_; 152 return intercepted_as_stream_count_;
117 } 153 }
118 154
155 TestResourceHandler* last_resource_handler() const {
156 return last_resource_handler_;
157 }
158
119 private: 159 private:
160 std::unique_ptr<ResourceHandler> CreateNewResourceHandler() {
161 std::unique_ptr<ResourceHandler> new_resource_handler;
162 new_resource_handler.reset(
163 new TestResourceHandler(false, false, true, true, false));
164 last_resource_handler_ =
165 static_cast<TestResourceHandler*>(new_resource_handler.get());
166 return new_resource_handler;
167 }
168
120 // Whether the URL request should be intercepted as a stream. 169 // Whether the URL request should be intercepted as a stream.
121 bool stream_has_handler_; 170 bool stream_has_handler_;
122 171
123 // Whether the URL request has been intercepted as a stream. 172 // Whether the URL request has been intercepted as a stream.
124 bool intercepted_as_stream_; 173 bool intercepted_as_stream_;
125 174
126 // Count of number of times MaybeInterceptAsStream function get called in a 175 // Count of number of times MaybeInterceptAsStream function get called in a
127 // test. 176 // test.
128 int intercepted_as_stream_count_; 177 int intercepted_as_stream_count_;
178
179 // The last TestResourceHandler created by this TestResourceDispatcherHost.
180 TestResourceHandler* last_resource_handler_;
129 }; 181 };
130 182
131 class TestResourceDispatcherHostDelegate
132 : public ResourceDispatcherHostDelegate {
133 public:
134 TestResourceDispatcherHostDelegate(bool must_download)
135 : must_download_(must_download) {
136 }
137
138 bool ShouldForceDownloadResource(const GURL& url,
139 const std::string& mime_type) override {
140 return must_download_;
141 }
142
143 private:
144 const bool must_download_;
145 };
146
147 class TestResourceController : public ResourceController {
148 public:
149 void Cancel() override {}
150
151 void CancelAndIgnore() override {
152 NOTREACHED();
153 }
154
155 void CancelWithError(int error_code) override {
156 NOTREACHED();
157 }
158
159 void Resume() override {
160 NOTREACHED();
161 }
162 };
163 183
164 class TestFakePluginService : public FakePluginService { 184 class TestFakePluginService : public FakePluginService {
165 public: 185 public:
166 // If |is_plugin_stale| is true, GetPluginInfo will indicate the plugins are 186 // If |is_plugin_stale| is true, GetPluginInfo will indicate the plugins are
167 // stale until GetPlugins is called. 187 // stale until GetPlugins is called.
168 TestFakePluginService(bool plugin_available, bool is_plugin_stale) 188 TestFakePluginService(bool plugin_available, bool is_plugin_stale)
169 : plugin_available_(plugin_available), 189 : plugin_available_(plugin_available),
170 is_plugin_stale_(is_plugin_stale) {} 190 is_plugin_stale_(is_plugin_stale) {}
171 191
172 bool GetPluginInfo(int render_process_id, 192 bool GetPluginInfo(int render_process_id,
(...skipping 22 matching lines...) Expand all
195 FROM_HERE, base::Bind(callback, plugins)); 215 FROM_HERE, base::Bind(callback, plugins));
196 } 216 }
197 217
198 private: 218 private:
199 const bool plugin_available_; 219 const bool plugin_available_;
200 bool is_plugin_stale_; 220 bool is_plugin_stale_;
201 221
202 DISALLOW_COPY_AND_ASSIGN(TestFakePluginService); 222 DISALLOW_COPY_AND_ASSIGN(TestFakePluginService);
203 }; 223 };
204 224
205 class MimeTypeResourceHandlerTest : public testing::Test { 225 class TestResourceController : public ResourceController {
206 public: 226 public:
207 MimeTypeResourceHandlerTest() 227 TestResourceController() : cancel_called_(0), resume_called_(0) {}
228 void Cancel() override { cancel_called_++; }
229
230 void CancelAndIgnore() override { NOTREACHED(); }
231
232 void CancelWithError(int error_code) override { NOTREACHED(); }
233
234 void Resume() override { resume_called_++; }
235
236 int cancel_called() const { return cancel_called_; }
237 int resume_called() const { return resume_called_; }
238
239
240 private:
241 int cancel_called_;
242 int resume_called_;
243 };
244
245 } // namespace
246
247 class MimeSniffingResourceHandlerTest : public testing::Test {
248 public:
249 MimeSniffingResourceHandlerTest()
208 : stream_has_handler_(false), 250 : stream_has_handler_(false),
209 plugin_available_(false), 251 plugin_available_(false),
210 plugin_stale_(false) {} 252 plugin_stale_(false) {}
211 253
254 std::string TestAcceptHeaderSetting(ResourceType request_resource_type);
255 std::string TestAcceptHeaderSettingWithURLRequest(
256 ResourceType request_resource_type,
257 net::URLRequest* request);
258
212 void set_stream_has_handler(bool stream_has_handler) { 259 void set_stream_has_handler(bool stream_has_handler) {
213 stream_has_handler_ = stream_has_handler; 260 stream_has_handler_ = stream_has_handler;
214 } 261 }
215 262
216 void set_plugin_available(bool plugin_available) { 263 void set_plugin_available(bool plugin_available) {
217 plugin_available_ = plugin_available; 264 plugin_available_ = plugin_available;
218 } 265 }
219 266
220 void set_plugin_stale(bool plugin_stale) { plugin_stale_ = plugin_stale; } 267 void set_plugin_stale(bool plugin_stale) { plugin_stale_ = plugin_stale; }
221 268
222 bool TestStreamIsIntercepted(bool allow_download, 269 bool TestStreamIsIntercepted(bool allow_download,
223 bool must_download, 270 bool must_download,
224 ResourceType request_resource_type); 271 ResourceType request_resource_type);
272 // Tests the operation of the MimeSniffingHandler when it needs to buffer
273 // data.
274 void TestHandlerSniffing(bool response_started,
275 bool defer_response_started,
276 bool will_read,
277 bool read_completed,
278 bool defer_read_completed);
225 279
226 std::string TestAcceptHeaderSetting(ResourceType request_resource_type); 280 // Tests the operation of the MimeSniffingHandler when it doesn't buffer
227 std::string TestAcceptHeaderSettingWithURLRequest( 281 // data.
228 ResourceType request_resource_type, 282 void TestHandlerNoSniffing(bool response_started,
229 net::URLRequest* request); 283 bool defer_response_started,
284 bool will_read,
285 bool read_completed,
286 bool defer_read_completed);
230 287
231 private: 288 private:
232 // Whether the URL request should be intercepted as a stream. 289 // Whether the URL request should be intercepted as a stream.
233 bool stream_has_handler_; 290 bool stream_has_handler_;
234 bool plugin_available_; 291 bool plugin_available_;
235 bool plugin_stale_; 292 bool plugin_stale_;
236 293
237 TestBrowserThreadBundle thread_bundle_; 294 TestBrowserThreadBundle thread_bundle_;
238 }; 295 };
239 296
240 bool MimeTypeResourceHandlerTest::TestStreamIsIntercepted( 297 std::string MimeSniffingResourceHandlerTest::TestAcceptHeaderSetting(
298 ResourceType request_resource_type) {
299 net::URLRequestContext context;
300 std::unique_ptr<net::URLRequest> request(context.CreateRequest(
301 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr));
302 return TestAcceptHeaderSettingWithURLRequest(request_resource_type,
303 request.get());
304 }
305
306 std::string
307 MimeSniffingResourceHandlerTest::TestAcceptHeaderSettingWithURLRequest(
308 ResourceType request_resource_type,
309 net::URLRequest* request) {
310 bool is_main_frame = request_resource_type == RESOURCE_TYPE_MAIN_FRAME;
311 ResourceRequestInfo::AllocateForTesting(request, request_resource_type,
312 nullptr, // context
313 0, // render_process_id
314 0, // render_view_id
315 0, // render_frame_id
316 is_main_frame, // is_main_frame
317 false, // parent_is_main_frame
318 false, // allow_download
319 true, // is_async
320 false); // is_using_lofi
321
322 std::unique_ptr<ResourceHandler> mime_sniffing_handler(
323 new MimeSniffingResourceHandler(
324 std::unique_ptr<ResourceHandler>(
325 new TestResourceHandler(false, false, false, false, false)),
326 nullptr, nullptr, nullptr, request));
327
328 bool defer = false;
329 mime_sniffing_handler->OnWillStart(request->url(), &defer);
330 content::RunAllPendingInMessageLoop();
331
332 std::string accept_header;
333 request->extra_request_headers().GetHeader("Accept", &accept_header);
334 return accept_header;
335 }
336
337 bool MimeSniffingResourceHandlerTest::TestStreamIsIntercepted(
241 bool allow_download, 338 bool allow_download,
242 bool must_download, 339 bool must_download,
243 ResourceType request_resource_type) { 340 ResourceType request_resource_type) {
244 net::URLRequestContext context; 341 net::URLRequestContext context;
245 std::unique_ptr<net::URLRequest> request(context.CreateRequest( 342 std::unique_ptr<net::URLRequest> request(context.CreateRequest(
246 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr)); 343 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr));
247 bool is_main_frame = request_resource_type == RESOURCE_TYPE_MAIN_FRAME; 344 bool is_main_frame = request_resource_type == RESOURCE_TYPE_MAIN_FRAME;
248 ResourceRequestInfo::AllocateForTesting( 345 ResourceRequestInfo::AllocateForTesting(request.get(), request_resource_type,
249 request.get(), 346 nullptr, // context
250 request_resource_type, 347 0, // render_process_id
251 nullptr, // context 348 0, // render_view_id
252 0, // render_process_id 349 0, // render_frame_id
253 0, // render_view_id 350 is_main_frame, // is_main_frame
254 0, // render_frame_id 351 false, // parent_is_main_frame
255 is_main_frame, // is_main_frame 352 allow_download, // allow_download
256 false, // parent_is_main_frame 353 true, // is_async
257 allow_download, // allow_download 354 false); // is_using_lofi
258 true, // is_async
259 false); // is_using_lofi
260 355
261 TestResourceDispatcherHost host(stream_has_handler_); 356 TestResourceDispatcherHost host(stream_has_handler_);
262 TestResourceDispatcherHostDelegate host_delegate(must_download); 357 TestResourceDispatcherHostDelegate host_delegate(must_download);
263 host.SetDelegate(&host_delegate); 358 host.SetDelegate(&host_delegate);
264 359
265 TestFakePluginService plugin_service(plugin_available_, plugin_stale_); 360 TestFakePluginService plugin_service(plugin_available_, plugin_stale_);
266 std::unique_ptr<ResourceHandler> mime_sniffing_handler( 361 std::unique_ptr<ResourceHandler> intercepting_handler(
267 new MimeTypeResourceHandler( 362 new InterceptingResourceHandler(std::unique_ptr<ResourceHandler>(),
268 std::unique_ptr<ResourceHandler>(new TestResourceHandler()), &host, 363 nullptr));
269 &plugin_service, request.get())); 364 std::unique_ptr<ResourceHandler> mime_handler(new MimeSniffingResourceHandler(
365 std::unique_ptr<ResourceHandler>(
366 new TestResourceHandler(false, false, false, false, false)),
367 &host, &plugin_service,
368 static_cast<InterceptingResourceHandler*>(intercepting_handler.get()),
369 request.get()));
370
270 TestResourceController resource_controller; 371 TestResourceController resource_controller;
271 mime_sniffing_handler->SetController(&resource_controller); 372 mime_handler->SetController(&resource_controller);
272 373
273 scoped_refptr<ResourceResponse> response(new ResourceResponse); 374 scoped_refptr<ResourceResponse> response(new ResourceResponse);
274 // The MIME type isn't important but it shouldn't be empty. 375 // The MIME type isn't important but it shouldn't be empty.
275 response->head.mime_type = "application/pdf"; 376 response->head.mime_type = "application/pdf";
276 377
277 bool defer = false; 378 bool defer = false;
278 mime_sniffing_handler->OnResponseStarted(response.get(), &defer); 379 mime_handler->OnResponseStarted(response.get(), &defer);
279 380
280 content::RunAllPendingInMessageLoop(); 381 content::RunAllPendingInMessageLoop();
281 EXPECT_LT(host.intercepted_as_stream_count(), 2); 382 EXPECT_LT(host.intercepted_as_stream_count(), 2);
282 return host.intercepted_as_stream(); 383 return host.intercepted_as_stream();
283 } 384 }
284 385
285 std::string MimeTypeResourceHandlerTest::TestAcceptHeaderSetting( 386 void MimeSniffingResourceHandlerTest::TestHandlerSniffing(
286 ResourceType request_resource_type) { 387 bool response_started,
388 bool defer_response_started,
389 bool will_read,
390 bool read_completed,
391 bool defer_read_completed) {
287 net::URLRequestContext context; 392 net::URLRequestContext context;
288 std::unique_ptr<net::URLRequest> request(context.CreateRequest( 393 std::unique_ptr<net::URLRequest> request(context.CreateRequest(
289 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr)); 394 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr));
290 return TestAcceptHeaderSettingWithURLRequest( 395 ResourceRequestInfo::AllocateForTesting(request.get(),
291 request_resource_type, request.get()); 396 RESOURCE_TYPE_MAIN_FRAME,
292 } 397 nullptr, // context
293 398 0, // render_process_id
294 std::string MimeTypeResourceHandlerTest::TestAcceptHeaderSettingWithURLRequest( 399 0, // render_view_id
295 ResourceType request_resource_type, 400 0, // render_frame_id
296 net::URLRequest* request) { 401 true, // is_main_frame
297 bool is_main_frame = request_resource_type == RESOURCE_TYPE_MAIN_FRAME; 402 false, // parent_is_main_frame
298 ResourceRequestInfo::AllocateForTesting( 403 false, // allow_download
299 request, 404 true, // is_async
300 request_resource_type, 405 false); // is_using_lofi
301 nullptr, // context 406
302 0, // render_process_id 407 TestResourceDispatcherHost host(false);
303 0, // render_view_id
304 0, // render_frame_id
305 is_main_frame, // is_main_frame
306 false, // parent_is_main_frame
307 false, // allow_download
308 true, // is_async
309 false); // is_using_lofi
310
311 TestResourceDispatcherHost host(stream_has_handler_);
312 TestResourceDispatcherHostDelegate host_delegate(false); 408 TestResourceDispatcherHostDelegate host_delegate(false);
313 host.SetDelegate(&host_delegate); 409 host.SetDelegate(&host_delegate);
314 410
315 std::unique_ptr<ResourceHandler> mime_sniffing_handler( 411 TestFakePluginService plugin_service(plugin_available_, plugin_stale_);
316 new MimeTypeResourceHandler( 412 std::unique_ptr<ResourceHandler> intercepting_handler(
317 std::unique_ptr<ResourceHandler>(new TestResourceHandler()), &host, 413 new InterceptingResourceHandler(std::unique_ptr<ResourceHandler>(),
318 nullptr, request)); 414 nullptr));
319 415 std::unique_ptr<ResourceHandler> handler(new MimeSniffingResourceHandler(
416 std::unique_ptr<ResourceHandler>(new TestResourceHandler(
417 response_started, defer_response_started, will_read, read_completed,
418 defer_read_completed)),
419 &host, &plugin_service,
420 static_cast<InterceptingResourceHandler*>(intercepting_handler.get()),
421 request.get()));
422 MimeSniffingResourceHandler* mime_sniffing_handler =
423 static_cast<MimeSniffingResourceHandler*>(handler.get());
424
425 TestResourceController resource_controller;
426 mime_sniffing_handler->SetController(&resource_controller);
427
428 // The response should be sniffed.
429 scoped_refptr<ResourceResponse> response(new ResourceResponse);
430 response->head.mime_type.assign("text/plain");
431
432 CHECK_EQ(MimeSniffingResourceHandler::STATE_STARTING,
433 mime_sniffing_handler->state_);
434
435 // Simulate the response starting. We should start buffering, so the return
436 // value should always be true.
320 bool defer = false; 437 bool defer = false;
321 mime_sniffing_handler->OnWillStart(request->url(), &defer); 438 CHECK_EQ(true,
439 mime_sniffing_handler->OnResponseStarted(response.get(), &defer));
440 CHECK_EQ(0, resource_controller.cancel_called());
441 CHECK_EQ(0, resource_controller.resume_called());
442 CHECK_EQ(false, defer);
443 CHECK_EQ(MimeSniffingResourceHandler::STATE_BUFFERING,
444 mime_sniffing_handler->state_);
445
446 // Read some data to sniff the mime type. This will ask the next
447 // ResourceHandler for a buffer.
448 scoped_refptr<net::IOBuffer> read_buffer;
449 int buf_size = 0;
450 CHECK_EQ(will_read,
451 mime_sniffing_handler->OnWillRead(&read_buffer, &buf_size, -1));
452 CHECK_EQ(0, resource_controller.cancel_called());
453 CHECK_EQ(MimeSniffingResourceHandler::STATE_BUFFERING,
454 mime_sniffing_handler->state_);
455
456 if (!will_read)
457 return;
458
459 // Simulate an HTML page. The mime sniffer will identify the MimeType and
460 // proceed with replay.
461 char data[] = "!DOCTYPE html\n<head>\n<title>Foo</title>\n</head>";
462 memcpy(read_buffer->data(), data, sizeof(data));
463
464 defer = false;
465 bool return_value =
466 mime_sniffing_handler->OnReadCompleted(sizeof(data), &defer);
467
468 // If the next handler cancels the response start, we hsould be notified
469 // immediately.
470 if (!response_started) {
471 CHECK_EQ(response_started, return_value);
472 CHECK_EQ(0, resource_controller.cancel_called());
473 return;
474 }
475
476 // The replay can be deferred both at response started and read replay
477 // stages.
478 CHECK_EQ(defer, defer_response_started || defer_read_completed);
479 if (defer_response_started) {
480 CHECK_EQ(true, defer);
481 CHECK_EQ(true, return_value);
482 CHECK_EQ(MimeSniffingResourceHandler::STATE_REPLAYING_RESPONSE_RECEIVED,
483 mime_sniffing_handler->state_);
484 mime_sniffing_handler->Resume();
485 }
486
487 // The body that was sniffed should be transmitted to the next handler. This
488 // may cancel the request.
489 if (!read_completed) {
490 if (defer_response_started) {
491 CHECK_EQ(1, resource_controller.cancel_called());
492 } else {
493 CHECK_EQ(0, resource_controller.cancel_called());
494 CHECK_EQ(false, return_value);
495 }
496 return;
497 }
498
499 CHECK_EQ(MimeSniffingResourceHandler::STATE_STREAMING,
500 mime_sniffing_handler->state_);
501
502 // The request may be deferred by the next handler once the read is done.
503 if (defer_read_completed) {
504 CHECK_EQ(true, defer);
505 mime_sniffing_handler->Resume();
506 }
507
508 CHECK_EQ(MimeSniffingResourceHandler::STATE_STREAMING,
509 mime_sniffing_handler->state_);
510 CHECK_EQ(0, resource_controller.cancel_called());
511
512 // Even if the next handler defers the request twice, the
513 // MimeSniffingResourceHandler should only call Resume on its controller
514 // once.
515 if (defer_response_started || defer_read_completed)
516 CHECK_EQ(1, resource_controller.resume_called());
517 else
518 CHECK_EQ(0, resource_controller.resume_called());
519
322 content::RunAllPendingInMessageLoop(); 520 content::RunAllPendingInMessageLoop();
323
324 std::string accept_header;
325 request->extra_request_headers().GetHeader("Accept", &accept_header);
326 return accept_header;
327 } 521 }
328 522
523 void MimeSniffingResourceHandlerTest::TestHandlerNoSniffing(
524 bool response_started,
525 bool defer_response_started,
526 bool will_read,
527 bool read_completed,
528 bool defer_read_completed) {
529 net::URLRequestContext context;
530 std::unique_ptr<net::URLRequest> request(context.CreateRequest(
531 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr));
532 ResourceRequestInfo::AllocateForTesting(request.get(),
533 RESOURCE_TYPE_MAIN_FRAME,
534 nullptr, // context
535 0, // render_process_id
536 0, // render_view_id
537 0, // render_frame_id
538 true, // is_main_frame
539 false, // parent_is_main_frame
540 false, // allow_download
541 true, // is_async
542 false); // is_using_lofi
543
544 TestResourceDispatcherHost host(false);
545 TestResourceDispatcherHostDelegate host_delegate(false);
546 host.SetDelegate(&host_delegate);
547
548 TestFakePluginService plugin_service(plugin_available_, plugin_stale_);
549 std::unique_ptr<ResourceHandler> intercepting_handler(
550 new InterceptingResourceHandler(std::unique_ptr<ResourceHandler>(),
551 nullptr));
552
553 std::unique_ptr<ResourceHandler> handler(new MimeSniffingResourceHandler(
554 std::unique_ptr<ResourceHandler>(new TestResourceHandler(
555 response_started, defer_response_started, will_read, read_completed,
556 defer_read_completed)),
557 &host, &plugin_service,
558 static_cast<InterceptingResourceHandler*>(intercepting_handler.get()),
559 request.get()));
560 MimeSniffingResourceHandler* mime_sniffing_handler =
561 static_cast<MimeSniffingResourceHandler*>(handler.get());
562
563 TestResourceController resource_controller;
564 mime_sniffing_handler->SetController(&resource_controller);
565 int expected_resume_calls = 0;
566
567 // The response should not be sniffed.
568 scoped_refptr<ResourceResponse> response(new ResourceResponse);
569 response->head.mime_type.assign("text/html");
570
571 CHECK_EQ(MimeSniffingResourceHandler::STATE_STARTING,
572 mime_sniffing_handler->state_);
573
574 // Simulate the response starting. There should be no need for buffering, so
575 // the return value should be that of the next handler.
576 bool defer = false;
577 CHECK_EQ(response_started,
578 mime_sniffing_handler->OnResponseStarted(response.get(), &defer));
579 CHECK_EQ(0, resource_controller.cancel_called());
580
581 if (!response_started)
582 return;
583
584 CHECK_EQ(defer_response_started, defer);
585 if (defer) {
586 CHECK_EQ(MimeSniffingResourceHandler::STATE_REPLAYING_RESPONSE_RECEIVED,
587 mime_sniffing_handler->state_);
588 expected_resume_calls++;
589 mime_sniffing_handler->Resume();
590 }
591
592 CHECK_EQ(expected_resume_calls, resource_controller.resume_called());
593 CHECK_EQ(MimeSniffingResourceHandler::STATE_STREAMING,
594 mime_sniffing_handler->state_);
595
596 // The MimeSniffingResourceHandler should be acting as a pass-through
597 // ResourceHandler.
598 scoped_refptr<net::IOBuffer> read_buffer;
599 int buf_size = 0;
600 CHECK_EQ(will_read,
601 mime_sniffing_handler->OnWillRead(&read_buffer, &buf_size, -1));
602 CHECK_EQ(0, resource_controller.cancel_called());
603 CHECK_EQ(MimeSniffingResourceHandler::STATE_STREAMING,
604 mime_sniffing_handler->state_);
605
606 if (!will_read)
607 return;
608
609 defer = false;
610 CHECK_EQ(read_completed,
611 mime_sniffing_handler->OnReadCompleted(2000, &defer));
612 CHECK_EQ(0, resource_controller.cancel_called());
613 CHECK_EQ(MimeSniffingResourceHandler::STATE_STREAMING,
614 mime_sniffing_handler->state_);
615
616 if (!read_completed)
617 return;
618
619 CHECK_EQ(defer_read_completed, defer);
620 if (defer) {
621 expected_resume_calls++;
622 mime_sniffing_handler->Resume();
623 }
624 CHECK_EQ(expected_resume_calls, resource_controller.resume_called());
625
626 content::RunAllPendingInMessageLoop();
627 }
628
329 // Test that the proper Accept: header is set based on the ResourceType 629 // Test that the proper Accept: header is set based on the ResourceType
330 TEST_F(MimeTypeResourceHandlerTest, AcceptHeaders) { 630 TEST_F(MimeSniffingResourceHandlerTest, AcceptHeaders) {
331 EXPECT_EQ( 631 EXPECT_EQ(
332 "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp," 632 "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,"
333 "*/*;q=0.8", 633 "*/*;q=0.8",
334 TestAcceptHeaderSetting(RESOURCE_TYPE_MAIN_FRAME)); 634 TestAcceptHeaderSetting(RESOURCE_TYPE_MAIN_FRAME));
335 EXPECT_EQ( 635 EXPECT_EQ(
336 "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp," 636 "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,"
337 "*/*;q=0.8", 637 "*/*;q=0.8",
338 TestAcceptHeaderSetting(RESOURCE_TYPE_SUB_FRAME)); 638 TestAcceptHeaderSetting(RESOURCE_TYPE_SUB_FRAME));
339 EXPECT_EQ("text/css,*/*;q=0.1", 639 EXPECT_EQ("text/css,*/*;q=0.1",
340 TestAcceptHeaderSetting(RESOURCE_TYPE_STYLESHEET)); 640 TestAcceptHeaderSetting(RESOURCE_TYPE_STYLESHEET));
341 EXPECT_EQ("*/*", 641 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_SCRIPT));
342 TestAcceptHeaderSetting(RESOURCE_TYPE_SCRIPT));
343 EXPECT_EQ("image/webp,image/*,*/*;q=0.8", 642 EXPECT_EQ("image/webp,image/*,*/*;q=0.8",
344 TestAcceptHeaderSetting(RESOURCE_TYPE_IMAGE)); 643 TestAcceptHeaderSetting(RESOURCE_TYPE_IMAGE));
345 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_FONT_RESOURCE)); 644 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_FONT_RESOURCE));
346 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_SUB_RESOURCE)); 645 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_SUB_RESOURCE));
347 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_OBJECT)); 646 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_OBJECT));
348 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_MEDIA)); 647 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_MEDIA));
349 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_WORKER)); 648 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_WORKER));
350 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_SHARED_WORKER)); 649 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_SHARED_WORKER));
351 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_PREFETCH)); 650 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_PREFETCH));
352 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_FAVICON)); 651 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_FAVICON));
353 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_XHR)); 652 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_XHR));
354 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_PING)); 653 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_PING));
355 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_SERVICE_WORKER)); 654 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_SERVICE_WORKER));
356 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_CSP_REPORT)); 655 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_CSP_REPORT));
357 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_PLUGIN_RESOURCE)); 656 EXPECT_EQ("*/*", TestAcceptHeaderSetting(RESOURCE_TYPE_PLUGIN_RESOURCE));
358 657
359 // Ensure that if an Accept header is already set, it is not overwritten. 658 // Ensure that if an Accept header is already set, it is not overwritten.
360 net::URLRequestContext context; 659 net::URLRequestContext context;
361 std::unique_ptr<net::URLRequest> request(context.CreateRequest( 660 std::unique_ptr<net::URLRequest> request(context.CreateRequest(
362 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr)); 661 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr));
363 request->SetExtraRequestHeaderByName("Accept", "*", true); 662 request->SetExtraRequestHeaderByName("Accept", "*", true);
364 EXPECT_EQ("*", 663 EXPECT_EQ("*", TestAcceptHeaderSettingWithURLRequest(RESOURCE_TYPE_XHR,
365 TestAcceptHeaderSettingWithURLRequest(RESOURCE_TYPE_XHR, request.get())); 664 request.get()));
366 } 665 }
367 666
368 // Test that stream requests are correctly intercepted under the right 667 // Test that stream requests are correctly intercepted under the right
369 // circumstances. Test is not relevent when plugins are disabled. 668 // circumstances. Test is not relevent when plugins are disabled.
370 #if defined(ENABLE_PLUGINS) 669 #if defined(ENABLE_PLUGINS)
371 TEST_F(MimeTypeResourceHandlerTest, StreamHandling) { 670 TEST_F(MimeSniffingResourceHandlerTest, StreamHandling) {
372 bool allow_download; 671 bool allow_download;
373 bool must_download; 672 bool must_download;
374 ResourceType resource_type; 673 ResourceType resource_type;
375 674
376 // Ensure the stream is handled by MaybeInterceptAsStream in the 675 // Ensure the stream is handled by MaybeInterceptAsStream in the
377 // ResourceDispatcherHost. 676 // ResourceDispatcherHost.
378 set_stream_has_handler(true); 677 set_stream_has_handler(true);
379 set_plugin_available(true); 678 set_plugin_available(true);
380 679
381 // Main frame request with no download allowed. Stream shouldn't be 680 // Main frame request with no download allowed. Stream shouldn't be
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 724
426 // Test the cases where the stream isn't handled by MaybeInterceptAsStream 725 // Test the cases where the stream isn't handled by MaybeInterceptAsStream
427 // in the ResourceDispatcherHost. 726 // in the ResourceDispatcherHost.
428 set_stream_has_handler(false); 727 set_stream_has_handler(false);
429 allow_download = false; 728 allow_download = false;
430 must_download = false; 729 must_download = false;
431 resource_type = RESOURCE_TYPE_OBJECT; 730 resource_type = RESOURCE_TYPE_OBJECT;
432 EXPECT_FALSE( 731 EXPECT_FALSE(
433 TestStreamIsIntercepted(allow_download, must_download, resource_type)); 732 TestStreamIsIntercepted(allow_download, must_download, resource_type));
434 733
435 allow_download = true;
436 must_download = false;
437 resource_type = RESOURCE_TYPE_MAIN_FRAME;
438 EXPECT_FALSE(
439 TestStreamIsIntercepted(allow_download, must_download, resource_type));
440
441 // Test the cases where the stream handled by MaybeInterceptAsStream 734 // Test the cases where the stream handled by MaybeInterceptAsStream
442 // with plugin not available. This is the case when intercepting streams for 735 // with plugin not available. This is the case when intercepting streams for
443 // the streamsPrivate extensions API. 736 // the streamsPrivate extensions API.
444 set_stream_has_handler(true); 737 set_stream_has_handler(true);
445 set_plugin_available(false); 738 set_plugin_available(false);
446 allow_download = false; 739 allow_download = false;
447 must_download = false; 740 must_download = false;
448 resource_type = RESOURCE_TYPE_OBJECT; 741 resource_type = RESOURCE_TYPE_OBJECT;
449 EXPECT_TRUE( 742 EXPECT_TRUE(
450 TestStreamIsIntercepted(allow_download, must_download, resource_type)); 743 TestStreamIsIntercepted(allow_download, must_download, resource_type));
451 744
452 // Test the cases where the stream handled by MaybeInterceptAsStream 745 // Test the cases where the stream handled by MaybeInterceptAsStream
453 // with plugin not available. This is the case when intercepting streams for 746 // with plugin not available. This is the case when intercepting streams for
454 // the streamsPrivate extensions API with stale plugin. 747 // the streamsPrivate extensions API with stale plugin.
455 set_plugin_stale(true); 748 set_plugin_stale(true);
456 allow_download = false; 749 allow_download = false;
457 must_download = false; 750 must_download = false;
458 resource_type = RESOURCE_TYPE_OBJECT; 751 resource_type = RESOURCE_TYPE_OBJECT;
459 EXPECT_TRUE( 752 EXPECT_TRUE(
460 TestStreamIsIntercepted(allow_download, must_download, resource_type)); 753 TestStreamIsIntercepted(allow_download, must_download, resource_type));
461 } 754 }
462 #endif 755 #endif
463 756
464 } // namespace 757 // Test that the MimeSniffingHandler operates properly when it doesn't sniff
758 // resources.
759 TEST_F(MimeSniffingResourceHandlerTest, NoSniffing) {
760 // Test simple case.
761 TestHandlerNoSniffing(true, false, true, true, false);
762
763 // Test deferral in OnResponseStarted and/or in OnReadCompleted.
764 TestHandlerNoSniffing(true, true, true, true, false);
765 TestHandlerNoSniffing(true, false, true, true, true);
766 TestHandlerNoSniffing(true, true, true, true, true);
767
768 // Test cancel in OnResponseStarted, OnWillRead, OnReadCompleted.
769 TestHandlerNoSniffing(false, false, false, false, false);
770 TestHandlerNoSniffing(true, false, false, false, false);
771 TestHandlerNoSniffing(true, false, true, false, false);
772
773 // Test cancel after OnResponseStarted deferral.
774 TestHandlerNoSniffing(true, true, false, false, false);
775 TestHandlerNoSniffing(true, true, true, false, false);
776 }
777
778 // Test that the MimeSniffingHandler operates properly when it sniffs
779 // resources.
780 TEST_F(MimeSniffingResourceHandlerTest, Sniffing) {
781 // Test simple case.
782 TestHandlerSniffing(true, false, true, true, false);
783
784 // Test deferral in OnResponseStarted and/or in OnReadCompleted.
785 TestHandlerSniffing(true, true, true, true, false);
786 TestHandlerSniffing(true, false, true, true, true);
787 TestHandlerSniffing(true, true, true, true, true);
788
789 // Test cancel in OnResponseStarted, OnWillRead, OnReadCompleted.
790 TestHandlerSniffing(false, false, false, false, false);
791 TestHandlerSniffing(true, false, false, false, false);
792 TestHandlerSniffing(true, false, true, false, false);
793
794 // Test cancel after OnResponseStarted deferral.
795 TestHandlerSniffing(true, true, false, false, false);
796 TestHandlerSniffing(true, true, true, false, false);
797 }
798
799 // Tests that 304s do not trigger a change in handlers.
800 TEST_F(MimeSniffingResourceHandlerTest, 304Handling) {
801 net::URLRequestContext context;
802 std::unique_ptr<net::URLRequest> request(context.CreateRequest(
803 GURL("http://www.google.com"), net::DEFAULT_PRIORITY, nullptr));
804 ResourceRequestInfo::AllocateForTesting(request.get(),
805 RESOURCE_TYPE_MAIN_FRAME,
806 nullptr, // context
807 0, // render_process_id
808 0, // render_view_id
809 0, // render_frame_id
810 true, // is_main_frame
811 false, // parent_is_main_frame
812 true, // allow_download
813 true, // is_async
814 false); // is_using_lofi
815
816 TestResourceDispatcherHost host(false);
817 TestResourceDispatcherHostDelegate host_delegate(false);
818 host.SetDelegate(&host_delegate);
819
820 TestFakePluginService plugin_service(false, false);
821 std::unique_ptr<ResourceHandler> intercepting_handler(
822 new InterceptingResourceHandler(std::unique_ptr<ResourceHandler>(),
823 nullptr));
824 std::unique_ptr<ResourceHandler> mime_handler(
825 new MimeSniffingResourceHandler(
826 std::unique_ptr<ResourceHandler>(
827 new TestResourceHandler(true, false, true, true, false)),
828 &host, &plugin_service,
829 static_cast<InterceptingResourceHandler*>(intercepting_handler.get()),
830 request.get()));
831
832 TestResourceController resource_controller;
833 mime_handler->SetController(&resource_controller);
834
835 // Simulate a 304 response.
836 scoped_refptr<ResourceResponse> response(new ResourceResponse);
837 // The MIME type isn't important but it shouldn't be empty.
838 response->head.mime_type = "application/pdf";
839 response->head.headers = new net::HttpResponseHeaders("HTTP/1.x 304 OK");
840
841 // The response is received. No new ResourceHandler should be created to
842 // handle the download.
843 bool defer = false;
844 mime_handler->OnResponseStarted(response.get(), &defer);
845 EXPECT_FALSE(defer);
846 TestResourceHandler* new_handler = host.last_resource_handler();
847 EXPECT_TRUE(!new_handler);
848 }
465 849
466 } // namespace content 850 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698