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
3 // found in the LICENSE file.
5 #include "content/child/web_url_loader_impl.h"
10 #include "base/command_line.h"
11 #include "base/macros.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/single_thread_task_runner.h"
15 #include "base/time/time.h"
16 #include "content/child/request_extra_data.h"
17 #include "content/child/request_info.h"
18 #include "content/child/resource_dispatcher.h"
19 #include "content/public/child/fixed_received_data.h"
20 #include "content/public/child/request_peer.h"
21 #include "content/public/common/content_switches.h"
22 #include "content/public/common/resource_response_info.h"
23 #include "net/base/net_errors.h"
24 #include "net/http/http_response_headers.h"
25 #include "net/http/http_util.h"
26 #include "net/url_request/redirect_info.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "third_party/WebKit/public/platform/WebString.h"
29 #include "third_party/WebKit/public/platform/WebURLError.h"
30 #include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
31 #include "third_party/WebKit/public/platform/WebURLRequest.h"
32 #include "third_party/WebKit/public/platform/WebURLResponse.h"
38 const char kTestURL
[] = "http://foo";
39 const char kTestData
[] = "blah!";
41 const char kFtpDirMimeType
[] = "text/vnd.chromium.ftp-dir";
42 // Simple FTP directory listing. Tests are not concerned with correct parsing,
43 // but rather correct cleanup when deleted while parsing. Important details of
44 // this list are that it contains more than one entry that are not "." or "..".
45 const char kFtpDirListing
[] =
46 "drwxr-xr-x 3 ftp ftp 4096 May 15 18:11 goat\n"
47 "drwxr-xr-x 3 ftp ftp 4096 May 15 18:11 hat";
49 const char kMultipartResponseMimeType
[] = "multipart/x-mixed-replace";
50 const char kMultipartResponseHeaders
[] =
51 "HTTP/1.0 200 Peachy\r\n"
52 "Content-Type: multipart/x-mixed-replace; boundary=boundary\r\n\r\n";
53 // Simple multipart response. Imporant details for the tests are that it
54 // contains multiple chunks, and that it doesn't end with a boundary, so will
55 // send data in OnResponseComplete. Also, it will resolve to kTestData.
56 const char kMultipartResponse
[] =
58 "Content-type: text/html\n\n"
61 "Content-type: text/html\n\n"
64 class TestResourceDispatcher
: public ResourceDispatcher
{
66 TestResourceDispatcher() :
67 ResourceDispatcher(nullptr, nullptr),
72 ~TestResourceDispatcher() override
{}
74 // TestDispatcher implementation:
76 int StartAsync(const RequestInfo
& request_info
,
77 ResourceRequestBody
* request_body
,
78 RequestPeer
* peer
) override
{
81 url_
= request_info
.url
;
85 void Cancel(int request_id
) override
{
86 EXPECT_FALSE(canceled_
);
90 RequestPeer
* peer() { return peer_
; }
92 bool canceled() { return canceled_
; }
94 const GURL
& url() { return url_
; }
101 DISALLOW_COPY_AND_ASSIGN(TestResourceDispatcher
);
104 class TestWebURLLoaderClient
: public blink::WebURLLoaderClient
{
106 TestWebURLLoaderClient(
107 ResourceDispatcher
* dispatcher
,
108 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
)
109 : loader_(new WebURLLoaderImpl(dispatcher
, task_runner
)),
110 expect_multipart_response_(false),
111 delete_on_receive_redirect_(false),
112 delete_on_receive_response_(false),
113 delete_on_receive_data_(false),
114 delete_on_finish_(false),
115 delete_on_fail_(false),
116 did_receive_redirect_(false),
117 did_receive_response_(false),
118 did_finish_(false) {}
120 ~TestWebURLLoaderClient() override
{}
122 // blink::WebURLLoaderClient implementation:
123 void willSendRequest(
124 blink::WebURLLoader
* loader
,
125 blink::WebURLRequest
& newRequest
,
126 const blink::WebURLResponse
& redirectResponse
) override
{
127 EXPECT_TRUE(loader_
);
128 EXPECT_EQ(loader_
.get(), loader
);
129 // No test currently simulates mutiple redirects.
130 EXPECT_FALSE(did_receive_redirect_
);
131 did_receive_redirect_
= true;
133 if (delete_on_receive_redirect_
)
137 void didSendData(blink::WebURLLoader
* loader
,
138 unsigned long long bytesSent
,
139 unsigned long long totalBytesToBeSent
) override
{
140 EXPECT_TRUE(loader_
);
141 EXPECT_EQ(loader_
.get(), loader
);
144 void didReceiveResponse(
145 blink::WebURLLoader
* loader
,
146 const blink::WebURLResponse
& response
) override
{
147 EXPECT_TRUE(loader_
);
148 EXPECT_EQ(loader_
.get(), loader
);
150 // Only multipart requests may receive multiple response headers.
151 EXPECT_TRUE(expect_multipart_response_
|| !did_receive_response_
);
153 did_receive_response_
= true;
154 response_
= response
;
155 if (delete_on_receive_response_
)
159 void didDownloadData(blink::WebURLLoader
* loader
,
161 int encodedDataLength
) override
{
162 EXPECT_TRUE(loader_
);
163 EXPECT_EQ(loader_
.get(), loader
);
166 void didReceiveData(blink::WebURLLoader
* loader
,
169 int encodedDataLength
) override
{
170 EXPECT_TRUE(loader_
);
171 EXPECT_EQ(loader_
.get(), loader
);
172 // The response should have started, but must not have finished, or failed.
173 EXPECT_TRUE(did_receive_response_
);
174 EXPECT_FALSE(did_finish_
);
175 EXPECT_EQ(net::OK
, error_
.reason
);
176 EXPECT_EQ("", error_
.domain
.utf8());
178 received_data_
.append(data
, dataLength
);
180 if (delete_on_receive_data_
)
184 void didReceiveCachedMetadata(blink::WebURLLoader
* loader
,
186 int dataLength
) override
{
187 EXPECT_EQ(loader_
.get(), loader
);
190 void didFinishLoading(blink::WebURLLoader
* loader
,
192 int64_t totalEncodedDataLength
) override
{
193 EXPECT_TRUE(loader_
);
194 EXPECT_EQ(loader_
.get(), loader
);
195 EXPECT_TRUE(did_receive_response_
);
196 EXPECT_FALSE(did_finish_
);
199 if (delete_on_finish_
)
203 void didFail(blink::WebURLLoader
* loader
,
204 const blink::WebURLError
& error
) override
{
205 EXPECT_TRUE(loader_
);
206 EXPECT_EQ(loader_
.get(), loader
);
207 EXPECT_FALSE(did_finish_
);
214 WebURLLoaderImpl
* loader() { return loader_
.get(); }
215 void DeleteLoader() {
219 void set_expect_multipart_response() { expect_multipart_response_
= true; }
221 void set_delete_on_receive_redirect() { delete_on_receive_redirect_
= true; }
222 void set_delete_on_receive_response() { delete_on_receive_response_
= true; }
223 void set_delete_on_receive_data() { delete_on_receive_data_
= true; }
224 void set_delete_on_finish() { delete_on_finish_
= true; }
225 void set_delete_on_fail() { delete_on_fail_
= true; }
227 bool did_receive_redirect() const { return did_receive_redirect_
; }
228 bool did_receive_response() const { return did_receive_response_
; }
229 const std::string
& received_data() const { return received_data_
; }
230 bool did_finish() const { return did_finish_
; }
231 const blink::WebURLError
& error() const { return error_
; }
232 const blink::WebURLResponse
& response() const { return response_
; }
235 scoped_ptr
<WebURLLoaderImpl
> loader_
;
237 bool expect_multipart_response_
;
239 bool delete_on_receive_redirect_
;
240 bool delete_on_receive_response_
;
241 bool delete_on_receive_data_
;
242 bool delete_on_finish_
;
243 bool delete_on_fail_
;
245 bool did_receive_redirect_
;
246 bool did_receive_response_
;
247 std::string received_data_
;
249 blink::WebURLError error_
;
250 blink::WebURLResponse response_
;
252 DISALLOW_COPY_AND_ASSIGN(TestWebURLLoaderClient
);
255 class WebURLLoaderImplTest
: public testing::Test
{
257 explicit WebURLLoaderImplTest()
258 : client_(&dispatcher_
, message_loop_
.task_runner()) {}
259 ~WebURLLoaderImplTest() override
{}
261 void DoStartAsyncRequest() {
262 blink::WebURLRequest request
;
263 request
.initialize();
264 request
.setURL(GURL(kTestURL
));
265 client()->loader()->loadAsynchronously(request
, client());
269 void DoReceiveRedirect() {
270 EXPECT_FALSE(client()->did_receive_redirect());
271 net::RedirectInfo redirect_info
;
272 redirect_info
.status_code
= 302;
273 redirect_info
.new_method
= "GET";
274 redirect_info
.new_url
= GURL(kTestURL
);
275 redirect_info
.new_first_party_for_cookies
= GURL(kTestURL
);
276 peer()->OnReceivedRedirect(redirect_info
,
277 content::ResourceResponseInfo());
278 EXPECT_TRUE(client()->did_receive_redirect());
281 void DoReceiveResponse() {
282 EXPECT_FALSE(client()->did_receive_response());
283 peer()->OnReceivedResponse(content::ResourceResponseInfo());
284 EXPECT_TRUE(client()->did_receive_response());
287 // Assumes it is called only once for a request.
288 void DoReceiveData() {
289 EXPECT_EQ("", client()->received_data());
290 peer()->OnReceivedData(make_scoped_ptr(new FixedReceivedData(
291 kTestData
, strlen(kTestData
), strlen(kTestData
))));
292 EXPECT_EQ(kTestData
, client()->received_data());
295 void DoCompleteRequest() {
296 EXPECT_FALSE(client()->did_finish());
297 peer()->OnCompletedRequest(net::OK
, false, false, "", base::TimeTicks(),
299 EXPECT_TRUE(client()->did_finish());
300 // There should be no error.
301 EXPECT_EQ(net::OK
, client()->error().reason
);
302 EXPECT_EQ("", client()->error().domain
.utf8());
305 void DoReceiveCompletedResponse() {
306 EXPECT_FALSE(client()->did_receive_response());
307 EXPECT_EQ("", client()->received_data());
308 EXPECT_FALSE(client()->did_finish());
310 peer()->OnReceivedCompletedResponse(
311 content::ResourceResponseInfo(),
312 make_scoped_ptr(new FixedReceivedData(kTestData
, strlen(kTestData
),
314 net::OK
, false, false, "", base::TimeTicks(), strlen(kTestData
));
316 EXPECT_TRUE(client()->did_receive_response());
317 EXPECT_EQ(kTestData
, client()->received_data());
318 EXPECT_EQ(net::OK
, client()->error().reason
);
319 EXPECT_EQ("", client()->error().domain
.utf8());
322 void DoFailRequest() {
323 EXPECT_FALSE(client()->did_finish());
324 peer()->OnCompletedRequest(net::ERR_FAILED
, false, false, "",
325 base::TimeTicks(), strlen(kTestData
));
326 EXPECT_FALSE(client()->did_finish());
327 EXPECT_EQ(net::ERR_FAILED
, client()->error().reason
);
328 EXPECT_EQ(net::kErrorDomain
, client()->error().domain
.utf8());
331 void DoReceiveResponseFtp() {
332 EXPECT_FALSE(client()->did_receive_response());
333 content::ResourceResponseInfo response_info
;
334 response_info
.mime_type
= kFtpDirMimeType
;
335 peer()->OnReceivedResponse(response_info
);
336 EXPECT_TRUE(client()->did_receive_response());
339 void DoReceiveDataFtp() {
340 peer()->OnReceivedData(make_scoped_ptr(new FixedReceivedData(
341 kFtpDirListing
, strlen(kFtpDirListing
), strlen(kFtpDirListing
))));
342 // The FTP delegate should modify the data the client sees.
343 EXPECT_NE(kFtpDirListing
, client()->received_data());
346 void DoReceiveResponseMultipart() {
347 EXPECT_FALSE(client()->did_receive_response());
348 content::ResourceResponseInfo response_info
;
349 response_info
.headers
= new net::HttpResponseHeaders(
350 net::HttpUtil::AssembleRawHeaders(kMultipartResponseHeaders
,
351 strlen(kMultipartResponseHeaders
)));
352 response_info
.mime_type
= kMultipartResponseMimeType
;
353 peer()->OnReceivedResponse(response_info
);
354 EXPECT_TRUE(client()->did_receive_response());
357 void DoReceiveDataMultipart() {
358 peer()->OnReceivedData(make_scoped_ptr(
359 new FixedReceivedData(kMultipartResponse
, strlen(kMultipartResponse
),
360 strlen(kMultipartResponse
))));
361 // Multipart delegate should modify the data the client sees.
362 EXPECT_NE(kMultipartResponse
, client()->received_data());
365 TestWebURLLoaderClient
* client() { return &client_
; }
366 TestResourceDispatcher
* dispatcher() { return &dispatcher_
; }
367 RequestPeer
* peer() { return dispatcher()->peer(); }
368 base::MessageLoop
* message_loop() { return &message_loop_
; }
371 base::MessageLoop message_loop_
;
372 TestResourceDispatcher dispatcher_
;
373 TestWebURLLoaderClient client_
;
376 TEST_F(WebURLLoaderImplTest
, Success
) {
377 DoStartAsyncRequest();
381 EXPECT_FALSE(dispatcher()->canceled());
382 EXPECT_EQ(kTestData
, client()->received_data());
385 TEST_F(WebURLLoaderImplTest
, Redirect
) {
386 DoStartAsyncRequest();
391 EXPECT_FALSE(dispatcher()->canceled());
392 EXPECT_EQ(kTestData
, client()->received_data());
395 TEST_F(WebURLLoaderImplTest
, Failure
) {
396 DoStartAsyncRequest();
400 EXPECT_FALSE(dispatcher()->canceled());
403 TEST_F(WebURLLoaderImplTest
, ReceiveCompletedResponse
) {
404 DoStartAsyncRequest();
405 DoReceiveCompletedResponse();
406 EXPECT_FALSE(dispatcher()->canceled());
407 EXPECT_EQ(kTestData
, client()->received_data());
410 // The client may delete the WebURLLoader during any callback from the loader.
411 // These tests make sure that doesn't result in a crash.
412 TEST_F(WebURLLoaderImplTest
, DeleteOnReceiveRedirect
) {
413 client()->set_delete_on_receive_redirect();
414 DoStartAsyncRequest();
418 TEST_F(WebURLLoaderImplTest
, DeleteOnReceiveResponse
) {
419 client()->set_delete_on_receive_response();
420 DoStartAsyncRequest();
424 TEST_F(WebURLLoaderImplTest
, DeleteOnReceiveData
) {
425 client()->set_delete_on_receive_data();
426 DoStartAsyncRequest();
431 TEST_F(WebURLLoaderImplTest
, DeleteOnFinish
) {
432 client()->set_delete_on_finish();
433 DoStartAsyncRequest();
439 TEST_F(WebURLLoaderImplTest
, DeleteOnFail
) {
440 client()->set_delete_on_fail();
441 DoStartAsyncRequest();
447 TEST_F(WebURLLoaderImplTest
, DeleteBeforeResponseDataURL
) {
448 blink::WebURLRequest request
;
449 request
.initialize();
450 request
.setURL(GURL("data:text/html;charset=utf-8,blah!"));
451 client()->loader()->loadAsynchronously(request
, client());
452 client()->DeleteLoader();
453 message_loop()->RunUntilIdle();
454 EXPECT_FALSE(client()->did_receive_response());
459 TEST_F(WebURLLoaderImplTest
, DataURL
) {
460 blink::WebURLRequest request
;
461 request
.initialize();
462 request
.setURL(GURL("data:text/html;charset=utf-8,blah!"));
463 client()->loader()->loadAsynchronously(request
, client());
464 message_loop()->RunUntilIdle();
465 EXPECT_EQ("blah!", client()->received_data());
466 EXPECT_TRUE(client()->did_finish());
467 EXPECT_EQ(net::OK
, client()->error().reason
);
468 EXPECT_EQ("", client()->error().domain
.utf8());
471 TEST_F(WebURLLoaderImplTest
, DataURLDeleteOnReceiveResponse
) {
472 blink::WebURLRequest request
;
473 request
.initialize();
474 request
.setURL(GURL("data:text/html;charset=utf-8,blah!"));
475 client()->set_delete_on_receive_response();
476 client()->loader()->loadAsynchronously(request
, client());
477 message_loop()->RunUntilIdle();
478 EXPECT_TRUE(client()->did_receive_response());
479 EXPECT_EQ("", client()->received_data());
480 EXPECT_FALSE(client()->did_finish());
483 TEST_F(WebURLLoaderImplTest
, DataURLDeleteOnReceiveData
) {
484 blink::WebURLRequest request
;
485 request
.initialize();
486 request
.setURL(GURL("data:text/html;charset=utf-8,blah!"));
487 client()->set_delete_on_receive_data();
488 client()->loader()->loadAsynchronously(request
, client());
489 message_loop()->RunUntilIdle();
490 EXPECT_TRUE(client()->did_receive_response());
491 EXPECT_EQ("blah!", client()->received_data());
492 EXPECT_FALSE(client()->did_finish());
495 TEST_F(WebURLLoaderImplTest
, DataURLDeleteOnFinish
) {
496 blink::WebURLRequest request
;
497 request
.initialize();
498 request
.setURL(GURL("data:text/html;charset=utf-8,blah!"));
499 client()->set_delete_on_finish();
500 client()->loader()->loadAsynchronously(request
, client());
501 message_loop()->RunUntilIdle();
502 EXPECT_TRUE(client()->did_receive_response());
503 EXPECT_EQ("blah!", client()->received_data());
504 EXPECT_TRUE(client()->did_finish());
507 TEST_F(WebURLLoaderImplTest
, DataURLDefersLoading
) {
508 blink::WebURLRequest request
;
509 request
.initialize();
510 request
.setURL(GURL("data:text/html;charset=utf-8,blah!"));
511 client()->loader()->loadAsynchronously(request
, client());
513 // setDefersLoading() might be called with either false or true in no
514 // specific order. The user of the API will not have sufficient information
515 // about the WebURLLoader's internal state, so the latter gracefully needs to
516 // handle calling setDefersLoading any number of times with any values from
517 // any point in time.
519 client()->loader()->setDefersLoading(false);
520 client()->loader()->setDefersLoading(true);
521 client()->loader()->setDefersLoading(true);
522 message_loop()->RunUntilIdle();
523 EXPECT_FALSE(client()->did_finish());
525 client()->loader()->setDefersLoading(false);
526 client()->loader()->setDefersLoading(true);
527 message_loop()->RunUntilIdle();
528 EXPECT_FALSE(client()->did_finish());
530 client()->loader()->setDefersLoading(false);
531 message_loop()->RunUntilIdle();
532 EXPECT_TRUE(client()->did_finish());
534 client()->loader()->setDefersLoading(true);
535 client()->loader()->setDefersLoading(false);
536 client()->loader()->setDefersLoading(false);
537 message_loop()->RunUntilIdle();
538 EXPECT_TRUE(client()->did_finish());
540 EXPECT_EQ("blah!", client()->received_data());
541 EXPECT_EQ(net::OK
, client()->error().reason
);
542 EXPECT_EQ("", client()->error().domain
.utf8());
545 // FTP integration tests. These are focused more on safe deletion than correct
546 // parsing of FTP responses.
548 TEST_F(WebURLLoaderImplTest
, Ftp
) {
549 DoStartAsyncRequest();
550 DoReceiveResponseFtp();
553 EXPECT_FALSE(dispatcher()->canceled());
556 TEST_F(WebURLLoaderImplTest
, FtpDeleteOnReceiveResponse
) {
557 client()->set_delete_on_receive_response();
558 DoStartAsyncRequest();
559 DoReceiveResponseFtp();
561 // No data should have been received.
562 EXPECT_EQ("", client()->received_data());
565 TEST_F(WebURLLoaderImplTest
, FtpDeleteOnReceiveFirstData
) {
566 client()->set_delete_on_receive_data();
567 DoStartAsyncRequest();
568 DoReceiveResponseFtp();
570 EXPECT_NE("", client()->received_data());
573 TEST_F(WebURLLoaderImplTest
, FtpDeleteOnReceiveMoreData
) {
574 DoStartAsyncRequest();
575 DoReceiveResponseFtp();
578 // Directory listings are only parsed once the request completes, so this will
579 // cancel in DoReceiveDataFtp, before the request finishes.
580 client()->set_delete_on_receive_data();
581 peer()->OnCompletedRequest(net::OK
, false, false, "", base::TimeTicks(),
583 EXPECT_FALSE(client()->did_finish());
586 TEST_F(WebURLLoaderImplTest
, FtpDeleteOnFinish
) {
587 client()->set_delete_on_finish();
588 DoStartAsyncRequest();
589 DoReceiveResponseFtp();
594 TEST_F(WebURLLoaderImplTest
, FtpDeleteOnFail
) {
595 client()->set_delete_on_fail();
596 DoStartAsyncRequest();
597 DoReceiveResponseFtp();
602 // Multipart integration tests. These are focused more on safe deletion than
603 // correct parsing of Multipart responses.
605 TEST_F(WebURLLoaderImplTest
, Multipart
) {
606 client()->set_expect_multipart_response();
607 DoStartAsyncRequest();
608 DoReceiveResponseMultipart();
609 DoReceiveDataMultipart();
611 EXPECT_EQ(kTestData
, client()->received_data());
612 EXPECT_FALSE(dispatcher()->canceled());
615 TEST_F(WebURLLoaderImplTest
, MultipartDeleteOnReceiveFirstResponse
) {
616 client()->set_expect_multipart_response();
617 client()->set_delete_on_receive_response();
618 DoStartAsyncRequest();
619 DoReceiveResponseMultipart();
620 EXPECT_EQ("", client()->received_data());
623 TEST_F(WebURLLoaderImplTest
, MultipartDeleteOnReceiveSecondResponse
) {
624 client()->set_expect_multipart_response();
625 DoStartAsyncRequest();
626 DoReceiveResponseMultipart();
627 client()->set_delete_on_receive_response();
628 DoReceiveDataMultipart();
629 EXPECT_EQ("", client()->received_data());
632 TEST_F(WebURLLoaderImplTest
, MultipartDeleteOnReceiveFirstData
) {
633 client()->set_expect_multipart_response();
634 client()->set_delete_on_receive_data();
635 DoStartAsyncRequest();
636 DoReceiveResponseMultipart();
637 DoReceiveDataMultipart();
638 EXPECT_EQ("bl", client()->received_data());
641 TEST_F(WebURLLoaderImplTest
, MultipartDeleteOnReceiveMoreData
) {
642 client()->set_expect_multipart_response();
643 DoStartAsyncRequest();
644 DoReceiveResponseMultipart();
645 DoReceiveDataMultipart();
646 // For multipart responses, the delegate may send some data when notified
647 // of a request completing.
648 client()->set_delete_on_receive_data();
649 peer()->OnCompletedRequest(net::OK
, false, false, "", base::TimeTicks(),
651 EXPECT_FALSE(client()->did_finish());
652 EXPECT_EQ(kTestData
, client()->received_data());
655 TEST_F(WebURLLoaderImplTest
, MultipartDeleteFinish
) {
656 client()->set_expect_multipart_response();
657 client()->set_delete_on_finish();
658 DoStartAsyncRequest();
659 DoReceiveResponseMultipart();
660 DoReceiveDataMultipart();
662 EXPECT_EQ(kTestData
, client()->received_data());
665 TEST_F(WebURLLoaderImplTest
, MultipartDeleteFail
) {
666 client()->set_expect_multipart_response();
667 client()->set_delete_on_fail();
668 DoStartAsyncRequest();
669 DoReceiveResponseMultipart();
670 DoReceiveDataMultipart();
674 // PlzNavigate: checks that the stream override parameters provided on
675 // navigation commit are properly applied.
676 TEST_F(WebURLLoaderImplTest
, BrowserSideNavigationCommit
) {
677 // Initialize the request and the stream override.
678 const GURL kStreamURL
= GURL("http://bar");
679 const std::string kMimeType
= "text/html";
680 blink::WebURLRequest request
;
681 request
.initialize();
682 request
.setURL(GURL(kTestURL
));
683 request
.setFrameType(blink::WebURLRequest::FrameTypeTopLevel
);
684 request
.setRequestContext(blink::WebURLRequest::RequestContextFrame
);
685 scoped_ptr
<StreamOverrideParameters
> stream_override(
686 new StreamOverrideParameters());
687 stream_override
->stream_url
= kStreamURL
;
688 stream_override
->response
.mime_type
= kMimeType
;
689 RequestExtraData
* extra_data
= new RequestExtraData();
690 extra_data
->set_stream_override(stream_override
.Pass());
691 request
.setExtraData(extra_data
);
692 base::CommandLine::ForCurrentProcess()->AppendSwitch(
693 switches::kEnableBrowserSideNavigation
);
695 client()->loader()->loadAsynchronously(request
, client());
697 // The stream url should have been requestead instead of the request url.
699 EXPECT_EQ(kStreamURL
, dispatcher()->url());
701 EXPECT_FALSE(client()->did_receive_response());
702 peer()->OnReceivedResponse(content::ResourceResponseInfo());
703 EXPECT_TRUE(client()->did_receive_response());
705 // The response info should have been overriden.
706 ASSERT_FALSE(client()->response().isNull());
707 EXPECT_EQ(kMimeType
, client()->response().mimeType().latin1());
711 EXPECT_FALSE(dispatcher()->canceled());
712 EXPECT_EQ(kTestData
, client()->received_data());
716 } // namespace content