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.
5 #include "ppapi/tests/test_url_loader.h"
11 #include "ppapi/c/dev/ppb_testing_dev.h"
12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/c/ppb_file_io.h"
14 #include "ppapi/c/ppb_url_loader.h"
15 #include "ppapi/c/trusted/ppb_file_io_trusted.h"
16 #include "ppapi/c/trusted/ppb_url_loader_trusted.h"
17 #include "ppapi/cpp/dev/url_util_dev.h"
18 #include "ppapi/cpp/file_io.h"
19 #include "ppapi/cpp/file_ref.h"
20 #include "ppapi/cpp/file_system.h"
21 #include "ppapi/cpp/instance.h"
22 #include "ppapi/cpp/module.h"
23 #include "ppapi/cpp/url_loader.h"
24 #include "ppapi/cpp/url_request_info.h"
25 #include "ppapi/cpp/url_response_info.h"
26 #include "ppapi/tests/test_utils.h"
27 #include "ppapi/tests/testing_instance.h"
29 REGISTER_TEST_CASE(URLLoader
);
33 int32_t WriteEntireBuffer(PP_Instance instance
,
36 const std::string
& data
,
37 CallbackType callback_type
) {
38 TestCompletionCallback
callback(instance
, callback_type
);
39 int32_t write_offset
= offset
;
40 const char* buf
= data
.c_str();
41 int32_t size
= data
.size();
43 while (write_offset
< offset
+ size
) {
44 callback
.WaitForResult(file_io
->Write(write_offset
,
45 &buf
[write_offset
- offset
],
46 size
- write_offset
+ offset
,
47 callback
.GetCallback()));
48 if (callback
.result() < 0)
49 return callback
.result();
50 if (callback
.result() == 0)
51 return PP_ERROR_FAILED
;
52 write_offset
+= callback
.result();
60 TestURLLoader::TestURLLoader(TestingInstance
* instance
)
62 file_io_trusted_interface_(NULL
),
63 url_loader_trusted_interface_(NULL
) {
66 bool TestURLLoader::Init() {
67 if (!CheckTestingInterface()) {
68 instance_
->AppendError("Testing interface not available");
72 const PPB_FileIO
* file_io_interface
= static_cast<const PPB_FileIO
*>(
73 pp::Module::Get()->GetBrowserInterface(PPB_FILEIO_INTERFACE
));
74 if (!file_io_interface
)
75 instance_
->AppendError("FileIO interface not available");
77 file_io_trusted_interface_
= static_cast<const PPB_FileIOTrusted
*>(
78 pp::Module::Get()->GetBrowserInterface(PPB_FILEIOTRUSTED_INTERFACE
));
79 url_loader_trusted_interface_
= static_cast<const PPB_URLLoaderTrusted
*>(
80 pp::Module::Get()->GetBrowserInterface(PPB_URLLOADERTRUSTED_INTERFACE
));
81 if (!testing_interface_
->IsOutOfProcess()) {
82 // Trusted interfaces are not supported under NaCl.
83 #if !(defined __native_client__)
84 if (!file_io_trusted_interface_
)
85 instance_
->AppendError("FileIOTrusted interface not available");
86 if (!url_loader_trusted_interface_
)
87 instance_
->AppendError("URLLoaderTrusted interface not available");
89 if (file_io_trusted_interface_
)
90 instance_
->AppendError("FileIOTrusted interface is supported by NaCl");
91 if (url_loader_trusted_interface_
)
92 instance_
->AppendError("URLLoaderTrusted interface is supported by NaCl");
95 return EnsureRunningOverHTTP();
98 void TestURLLoader::RunTests(const std::string
& filter
) {
99 RUN_CALLBACK_TEST(TestURLLoader
, BasicGET
, filter
);
100 RUN_CALLBACK_TEST(TestURLLoader
, BasicPOST
, filter
);
101 RUN_CALLBACK_TEST(TestURLLoader
, BasicFilePOST
, filter
);
102 RUN_CALLBACK_TEST(TestURLLoader
, BasicFileRangePOST
, filter
);
103 RUN_CALLBACK_TEST(TestURLLoader
, CompoundBodyPOST
, filter
);
104 RUN_CALLBACK_TEST(TestURLLoader
, EmptyDataPOST
, filter
);
105 RUN_CALLBACK_TEST(TestURLLoader
, BinaryDataPOST
, filter
);
106 RUN_CALLBACK_TEST(TestURLLoader
, CustomRequestHeader
, filter
);
107 RUN_CALLBACK_TEST(TestURLLoader
, FailsBogusContentLength
, filter
);
108 RUN_CALLBACK_TEST(TestURLLoader
, StreamToFile
, filter
);
109 RUN_CALLBACK_TEST(TestURLLoader
, UntrustedSameOriginRestriction
, filter
);
110 RUN_CALLBACK_TEST(TestURLLoader
, TrustedSameOriginRestriction
, filter
);
111 RUN_CALLBACK_TEST(TestURLLoader
, UntrustedCrossOriginRequest
, filter
);
112 RUN_CALLBACK_TEST(TestURLLoader
, TrustedCrossOriginRequest
, filter
);
113 RUN_CALLBACK_TEST(TestURLLoader
, UntrustedJavascriptURLRestriction
, filter
);
114 RUN_CALLBACK_TEST(TestURLLoader
, TrustedJavascriptURLRestriction
, filter
);
115 RUN_CALLBACK_TEST(TestURLLoader
, UntrustedHttpRequests
, filter
);
116 RUN_CALLBACK_TEST(TestURLLoader
, TrustedHttpRequests
, filter
);
117 RUN_CALLBACK_TEST(TestURLLoader
, FollowURLRedirect
, filter
);
118 RUN_CALLBACK_TEST(TestURLLoader
, AuditURLRedirect
, filter
);
119 RUN_CALLBACK_TEST(TestURLLoader
, AbortCalls
, filter
);
120 RUN_CALLBACK_TEST(TestURLLoader
, UntendedLoad
, filter
);
121 RUN_CALLBACK_TEST(TestURLLoader
, PrefetchBufferThreshold
, filter
);
124 std::string
TestURLLoader::ReadEntireFile(pp::FileIO
* file_io
,
126 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
131 callback
.WaitForResult(file_io
->Read(offset
, buf
, sizeof(buf
),
132 callback
.GetCallback()));
133 if (callback
.result() < 0)
134 return ReportError("FileIO::Read", callback
.result());
135 if (callback
.result() == 0)
137 offset
+= callback
.result();
138 data
->append(buf
, callback
.result());
144 std::string
TestURLLoader::ReadEntireResponseBody(pp::URLLoader
* loader
,
146 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
147 char buf
[2]; // Small so that multiple reads are needed.
150 callback
.WaitForResult(
151 loader
->ReadResponseBody(buf
, sizeof(buf
), callback
.GetCallback()));
152 if (callback
.result() < 0)
153 return ReportError("URLLoader::ReadResponseBody", callback
.result());
154 if (callback
.result() == 0)
156 body
->append(buf
, callback
.result());
162 std::string
TestURLLoader::LoadAndCompareBody(
163 const pp::URLRequestInfo
& request
,
164 const std::string
& expected_body
) {
165 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
167 pp::URLLoader
loader(instance_
);
168 callback
.WaitForResult(loader
.Open(request
, callback
.GetCallback()));
169 CHECK_CALLBACK_BEHAVIOR(callback
);
170 ASSERT_EQ(PP_OK
, callback
.result());
172 pp::URLResponseInfo
response_info(loader
.GetResponseInfo());
173 if (response_info
.is_null())
174 return "URLLoader::GetResponseInfo returned null";
175 int32_t status_code
= response_info
.GetStatusCode();
176 if (status_code
!= 200)
177 return "Unexpected HTTP status code";
180 std::string error
= ReadEntireResponseBody(&loader
, &body
);
184 if (body
.size() != expected_body
.size())
185 return "URLLoader::ReadResponseBody returned unexpected content length";
186 if (body
!= expected_body
)
187 return "URLLoader::ReadResponseBody returned unexpected content";
192 int32_t TestURLLoader::OpenFileSystem(pp::FileSystem
* file_system
,
193 std::string
* message
) {
194 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
195 callback
.WaitForResult(file_system
->Open(1024, callback
.GetCallback()));
196 if (callback
.failed()) {
197 message
->assign(callback
.errors());
198 return callback
.result();
200 if (callback
.result() != PP_OK
) {
201 message
->assign("FileSystem::Open");
202 return callback
.result();
204 return callback
.result();
207 int32_t TestURLLoader::PrepareFileForPost(
208 const pp::FileRef
& file_ref
,
209 const std::string
& data
,
210 std::string
* message
) {
211 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
212 pp::FileIO
file_io(instance_
);
213 callback
.WaitForResult(file_io
.Open(file_ref
,
214 PP_FILEOPENFLAG_CREATE
|
215 PP_FILEOPENFLAG_TRUNCATE
|
216 PP_FILEOPENFLAG_WRITE
,
217 callback
.GetCallback()));
218 if (callback
.failed()) {
219 message
->assign(callback
.errors());
220 return callback
.result();
222 if (callback
.result() != PP_OK
) {
223 message
->assign("FileIO::Open failed.");
224 return callback
.result();
227 int32_t rv
= WriteEntireBuffer(instance_
->pp_instance(), &file_io
, 0, data
,
230 message
->assign("FileIO::Write failed.");
237 std::string
TestURLLoader::GetReachableAbsoluteURL(
238 const std::string
& file_name
) {
239 // Get the absolute page URL and replace the test case file name
240 // with the given one.
241 pp::Var
document_url(
243 testing_interface_
->GetDocumentURL(instance_
->pp_instance(),
245 std::string
url(document_url
.AsString());
246 std::string
old_name("test_case.html");
247 size_t index
= url
.find(old_name
);
248 ASSERT_NE(index
, std::string::npos
);
249 url
.replace(index
, old_name
.length(), file_name
);
253 std::string
TestURLLoader::GetReachableCrossOriginURL(
254 const std::string
& file_name
) {
255 // Get an absolute URL and use it to construct a URL that will be
256 // considered cross-origin by the CORS access control code, and yet be
257 // reachable by the test server.
258 std::string url
= GetReachableAbsoluteURL(file_name
);
259 // Replace '127.0.0.1' with 'localhost'.
260 std::string
host("127.0.0.1");
261 size_t index
= url
.find(host
);
262 ASSERT_NE(index
, std::string::npos
);
263 url
.replace(index
, host
.length(), "localhost");
267 int32_t TestURLLoader::OpenUntrusted(const std::string
& method
,
268 const std::string
& header
) {
269 pp::URLRequestInfo
request(instance_
);
270 request
.SetURL("/echo");
271 request
.SetMethod(method
);
272 request
.SetHeaders(header
);
274 return OpenUntrusted(request
);
277 int32_t TestURLLoader::OpenTrusted(const std::string
& method
,
278 const std::string
& header
) {
279 pp::URLRequestInfo
request(instance_
);
280 request
.SetURL("/echo");
281 request
.SetMethod(method
);
282 request
.SetHeaders(header
);
284 return OpenTrusted(request
);
287 int32_t TestURLLoader::OpenUntrusted(const pp::URLRequestInfo
& request
) {
288 return Open(request
, false);
291 int32_t TestURLLoader::OpenTrusted(const pp::URLRequestInfo
& request
) {
292 return Open(request
, true);
295 int32_t TestURLLoader::Open(const pp::URLRequestInfo
& request
,
297 pp::URLLoader
loader(instance_
);
299 url_loader_trusted_interface_
->GrantUniversalAccess(loader
.pp_resource());
300 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
301 callback
.WaitForResult(loader
.Open(request
, callback
.GetCallback()));
302 return callback
.result();
305 std::string
TestURLLoader::TestBasicGET() {
306 pp::URLRequestInfo
request(instance_
);
307 request
.SetURL("test_url_loader_data/hello.txt");
308 return LoadAndCompareBody(request
, "hello\n");
311 std::string
TestURLLoader::TestBasicPOST() {
312 pp::URLRequestInfo
request(instance_
);
313 request
.SetURL("/echo");
314 request
.SetMethod("POST");
315 std::string
postdata("postdata");
316 request
.AppendDataToBody(postdata
.data(), postdata
.length());
317 return LoadAndCompareBody(request
, postdata
);
320 std::string
TestURLLoader::TestBasicFilePOST() {
323 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
324 int32_t rv
= OpenFileSystem(&file_system
, &message
);
326 return ReportError(message
.c_str(), rv
);
328 pp::FileRef
file_ref(file_system
, "/file_post_test");
329 std::string
postdata("postdata");
330 rv
= PrepareFileForPost(file_ref
, postdata
, &message
);
332 return ReportError(message
.c_str(), rv
);
334 pp::URLRequestInfo
request(instance_
);
335 request
.SetURL("/echo");
336 request
.SetMethod("POST");
337 request
.AppendFileToBody(file_ref
, 0);
338 return LoadAndCompareBody(request
, postdata
);
341 std::string
TestURLLoader::TestBasicFileRangePOST() {
344 pp::FileSystem
file_system(instance_
, PP_FILESYSTEMTYPE_LOCALTEMPORARY
);
345 int32_t rv
= OpenFileSystem(&file_system
, &message
);
347 return ReportError(message
.c_str(), rv
);
349 pp::FileRef
file_ref(file_system
, "/file_range_post_test");
350 std::string
postdata("postdatapostdata");
351 rv
= PrepareFileForPost(file_ref
, postdata
, &message
);
353 return ReportError(message
.c_str(), rv
);
355 pp::URLRequestInfo
request(instance_
);
356 request
.SetURL("/echo");
357 request
.SetMethod("POST");
358 request
.AppendFileRangeToBody(file_ref
, 4, 12, 0);
359 return LoadAndCompareBody(request
, postdata
.substr(4, 12));
362 std::string
TestURLLoader::TestCompoundBodyPOST() {
363 pp::URLRequestInfo
request(instance_
);
364 request
.SetURL("/echo");
365 request
.SetMethod("POST");
366 std::string
postdata1("post");
367 request
.AppendDataToBody(postdata1
.data(), postdata1
.length());
368 std::string
postdata2("data");
369 request
.AppendDataToBody(postdata2
.data(), postdata2
.length());
370 return LoadAndCompareBody(request
, postdata1
+ postdata2
);
373 std::string
TestURLLoader::TestEmptyDataPOST() {
374 pp::URLRequestInfo
request(instance_
);
375 request
.SetURL("/echo");
376 request
.SetMethod("POST");
377 request
.AppendDataToBody("", 0);
378 return LoadAndCompareBody(request
, std::string());
381 std::string
TestURLLoader::TestBinaryDataPOST() {
382 pp::URLRequestInfo
request(instance_
);
383 request
.SetURL("/echo");
384 request
.SetMethod("POST");
385 const char postdata_chars
[] =
386 "\x00\x01\x02\x03\x04\x05postdata\xfa\xfb\xfc\xfd\xfe\xff";
387 std::string
postdata(postdata_chars
,
388 sizeof(postdata_chars
) / sizeof(postdata_chars
[0]));
389 request
.AppendDataToBody(postdata
.data(), postdata
.length());
390 return LoadAndCompareBody(request
, postdata
);
393 std::string
TestURLLoader::TestCustomRequestHeader() {
394 pp::URLRequestInfo
request(instance_
);
395 request
.SetURL("/echoheader?Foo");
396 request
.SetHeaders("Foo: 1");
397 return LoadAndCompareBody(request
, "1");
400 std::string
TestURLLoader::TestFailsBogusContentLength() {
401 pp::URLRequestInfo
request(instance_
);
402 request
.SetURL("/echo");
403 request
.SetMethod("POST");
404 request
.SetHeaders("Content-Length: 400");
405 std::string
postdata("postdata");
406 request
.AppendDataToBody(postdata
.data(), postdata
.length());
409 rv
= OpenUntrusted(request
);
410 if (rv
!= PP_ERROR_NOACCESS
)
412 "Untrusted request with bogus Content-Length restriction", rv
);
417 std::string
TestURLLoader::TestStreamToFile() {
418 pp::URLRequestInfo
request(instance_
);
419 request
.SetURL("test_url_loader_data/hello.txt");
420 request
.SetStreamToFile(true);
422 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
424 pp::URLLoader
loader(instance_
);
425 callback
.WaitForResult(loader
.Open(request
, callback
.GetCallback()));
426 CHECK_CALLBACK_BEHAVIOR(callback
);
427 ASSERT_EQ(PP_OK
, callback
.result());
429 pp::URLResponseInfo
response_info(loader
.GetResponseInfo());
430 if (response_info
.is_null())
431 return "URLLoader::GetResponseInfo returned null";
432 int32_t status_code
= response_info
.GetStatusCode();
433 if (status_code
!= 200)
434 return "Unexpected HTTP status code";
436 pp::FileRef
body(response_info
.GetBodyAsFileRef());
438 return "URLResponseInfo::GetBody returned null";
440 callback
.WaitForResult(loader
.FinishStreamingToFile(callback
.GetCallback()));
441 CHECK_CALLBACK_BEHAVIOR(callback
);
442 ASSERT_EQ(PP_OK
, callback
.result());
444 pp::FileIO
reader(instance_
);
445 callback
.WaitForResult(reader
.Open(body
, PP_FILEOPENFLAG_READ
,
446 callback
.GetCallback()));
447 CHECK_CALLBACK_BEHAVIOR(callback
);
448 ASSERT_EQ(PP_OK
, callback
.result());
451 std::string error
= ReadEntireFile(&reader
, &data
);
455 std::string expected_body
= "hello\n";
456 if (data
.size() != expected_body
.size())
457 return "ReadEntireFile returned unexpected content length";
458 if (data
!= expected_body
)
459 return "ReadEntireFile returned unexpected content";
461 // FileIOTrusted is not supported by NaCl or ppapi/proxy.
462 if (!testing_interface_
->IsOutOfProcess()) {
463 #if !(defined __native_client__)
464 int32_t file_descriptor
= file_io_trusted_interface_
->GetOSFileDescriptor(
465 reader
.pp_resource());
466 if (file_descriptor
< 0)
467 return "FileIO::GetOSFileDescriptor() returned a bad file descriptor.";
473 // Untrusted, unintended cross-origin requests should fail.
474 std::string
TestURLLoader::TestUntrustedSameOriginRestriction() {
475 pp::URLRequestInfo
request(instance_
);
476 std::string cross_origin_url
= GetReachableCrossOriginURL("test_case.html");
477 request
.SetURL(cross_origin_url
);
479 int32_t rv
= OpenUntrusted(request
);
480 if (rv
!= PP_ERROR_NOACCESS
)
482 "Untrusted, unintended cross-origin request restriction", rv
);
487 // Trusted, unintended cross-origin requests should succeed.
488 std::string
TestURLLoader::TestTrustedSameOriginRestriction() {
489 pp::URLRequestInfo
request(instance_
);
490 std::string cross_origin_url
= GetReachableCrossOriginURL("test_case.html");
491 request
.SetURL(cross_origin_url
);
493 int32_t rv
= OpenTrusted(request
);
495 return ReportError("Trusted cross-origin request failed", rv
);
500 // Untrusted, intended cross-origin requests should use CORS and succeed.
501 std::string
TestURLLoader::TestUntrustedCrossOriginRequest() {
502 pp::URLRequestInfo
request(instance_
);
503 std::string cross_origin_url
= GetReachableCrossOriginURL("test_case.html");
504 request
.SetURL(cross_origin_url
);
505 request
.SetAllowCrossOriginRequests(true);
507 int32_t rv
= OpenUntrusted(request
);
510 "Untrusted, intended cross-origin request failed", rv
);
515 // Trusted, intended cross-origin requests should use CORS and succeed.
516 std::string
TestURLLoader::TestTrustedCrossOriginRequest() {
517 pp::URLRequestInfo
request(instance_
);
518 std::string cross_origin_url
= GetReachableCrossOriginURL("test_case.html");
519 request
.SetURL(cross_origin_url
);
520 request
.SetAllowCrossOriginRequests(true);
522 int32_t rv
= OpenTrusted(request
);
524 return ReportError("Trusted cross-origin request failed", rv
);
529 // Untrusted Javascript URLs requests should fail.
530 std::string
TestURLLoader::TestUntrustedJavascriptURLRestriction() {
531 pp::URLRequestInfo
request(instance_
);
532 request
.SetURL("javascript:foo = bar");
534 int32_t rv
= OpenUntrusted(request
);
535 if (rv
!= PP_ERROR_NOACCESS
)
537 "Untrusted Javascript URL request restriction failed", rv
);
542 // Trusted Javascript URLs requests should succeed.
543 std::string
TestURLLoader::TestTrustedJavascriptURLRestriction() {
544 pp::URLRequestInfo
request(instance_
);
545 request
.SetURL("javascript:foo = bar");
547 int32_t rv
= OpenTrusted(request
);
548 if (rv
== PP_ERROR_NOACCESS
)
550 "Trusted Javascript URL request", rv
);
555 std::string
TestURLLoader::TestUntrustedHttpRequests() {
556 // HTTP methods are restricted only for untrusted loaders. Forbidden
557 // methods are CONNECT, TRACE, and TRACK, and any string that is not a
558 // valid token (containing special characters like CR, LF).
559 // http://www.w3.org/TR/XMLHttpRequest/
561 ASSERT_EQ(OpenUntrusted("cOnNeCt", std::string()), PP_ERROR_NOACCESS
);
562 ASSERT_EQ(OpenUntrusted("tRaCk", std::string()), PP_ERROR_NOACCESS
);
563 ASSERT_EQ(OpenUntrusted("tRaCe", std::string()), PP_ERROR_NOACCESS
);
565 OpenUntrusted("POST\x0d\x0ax-csrf-token:\x20test1234", std::string()),
568 // HTTP methods are restricted only for untrusted loaders. Try all headers
569 // that are forbidden by http://www.w3.org/TR/XMLHttpRequest/.
571 ASSERT_EQ(OpenUntrusted("GET", "Accept-Charset:\n"), PP_ERROR_NOACCESS
);
572 ASSERT_EQ(OpenUntrusted("GET", "Accept-Encoding:\n"), PP_ERROR_NOACCESS
);
573 ASSERT_EQ(OpenUntrusted("GET", "Connection:\n"), PP_ERROR_NOACCESS
);
574 ASSERT_EQ(OpenUntrusted("GET", "Content-Length:\n"), PP_ERROR_NOACCESS
);
575 ASSERT_EQ(OpenUntrusted("GET", "Cookie:\n"), PP_ERROR_NOACCESS
);
576 ASSERT_EQ(OpenUntrusted("GET", "Cookie2:\n"), PP_ERROR_NOACCESS
);
577 ASSERT_EQ(OpenUntrusted(
578 "GET", "Content-Transfer-Encoding:\n"), PP_ERROR_NOACCESS
);
579 ASSERT_EQ(OpenUntrusted("GET", "Date:\n"), PP_ERROR_NOACCESS
);
580 ASSERT_EQ(OpenUntrusted("GET", "Expect:\n"), PP_ERROR_NOACCESS
);
581 ASSERT_EQ(OpenUntrusted("GET", "Host:\n"), PP_ERROR_NOACCESS
);
582 ASSERT_EQ(OpenUntrusted("GET", "Keep-Alive:\n"), PP_ERROR_NOACCESS
);
583 ASSERT_EQ(OpenUntrusted("GET", "Referer:\n"), PP_ERROR_NOACCESS
);
584 ASSERT_EQ(OpenUntrusted("GET", "TE:\n"), PP_ERROR_NOACCESS
);
585 ASSERT_EQ(OpenUntrusted("GET", "Trailer:\n"), PP_ERROR_NOACCESS
);
586 ASSERT_EQ(OpenUntrusted(
587 "GET", "Transfer-Encoding:\n"), PP_ERROR_NOACCESS
);
588 ASSERT_EQ(OpenUntrusted("GET", "Upgrade:\n"), PP_ERROR_NOACCESS
);
589 ASSERT_EQ(OpenUntrusted("GET", "User-Agent:\n"), PP_ERROR_NOACCESS
);
590 ASSERT_EQ(OpenUntrusted("GET", "Via:\n"), PP_ERROR_NOACCESS
);
591 ASSERT_EQ(OpenUntrusted(
592 "GET", "Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA==:\n"),
594 ASSERT_EQ(OpenUntrusted("GET", "Sec-foo:\n"), PP_ERROR_NOACCESS
);
596 // Untrusted requests with custom referrer should fail.
598 pp::URLRequestInfo
request(instance_
);
599 request
.SetCustomReferrerURL("http://www.google.com/");
601 int32_t rv
= OpenUntrusted(request
);
602 if (rv
!= PP_ERROR_NOACCESS
)
604 "Untrusted request with custom referrer restriction", rv
);
606 // Untrusted requests with custom transfer encodings should fail.
608 pp::URLRequestInfo
request(instance_
);
609 request
.SetCustomContentTransferEncoding("foo");
611 int32_t rv
= OpenUntrusted(request
);
612 if (rv
!= PP_ERROR_NOACCESS
)
614 "Untrusted request with content-transfer-encoding restriction", rv
);
620 std::string
TestURLLoader::TestTrustedHttpRequests() {
621 // Trusted requests can use restricted methods.
623 ASSERT_EQ(OpenTrusted("cOnNeCt", std::string()), PP_OK
);
624 ASSERT_EQ(OpenTrusted("tRaCk", std::string()), PP_OK
);
625 ASSERT_EQ(OpenTrusted("tRaCe", std::string()), PP_OK
);
627 // Trusted requests can use restricted headers.
629 ASSERT_EQ(OpenTrusted("GET", "Accept-Charset:\n"), PP_OK
);
630 ASSERT_EQ(OpenTrusted("GET", "Accept-Encoding:\n"), PP_OK
);
631 ASSERT_EQ(OpenTrusted("GET", "Connection:\n"), PP_OK
);
632 ASSERT_EQ(OpenTrusted("GET", "Content-Length:\n"), PP_OK
);
633 ASSERT_EQ(OpenTrusted("GET", "Cookie:\n"), PP_OK
);
634 ASSERT_EQ(OpenTrusted("GET", "Cookie2:\n"), PP_OK
);
635 ASSERT_EQ(OpenTrusted(
636 "GET", "Content-Transfer-Encoding:\n"), PP_OK
);
637 ASSERT_EQ(OpenTrusted("GET", "Date:\n"), PP_OK
);
638 ASSERT_EQ(OpenTrusted("GET", "Expect:\n"), PP_OK
);
639 ASSERT_EQ(OpenTrusted("GET", "Host:\n"), PP_OK
);
640 ASSERT_EQ(OpenTrusted("GET", "Keep-Alive:\n"), PP_OK
);
641 ASSERT_EQ(OpenTrusted("GET", "Referer:\n"), PP_OK
);
642 ASSERT_EQ(OpenTrusted("GET", "TE:\n"), PP_OK
);
643 ASSERT_EQ(OpenTrusted("GET", "Trailer:\n"), PP_OK
);
644 ASSERT_EQ(OpenTrusted("GET", "Transfer-Encoding:\n"), PP_OK
);
645 ASSERT_EQ(OpenTrusted("GET", "Upgrade:\n"), PP_OK
);
646 ASSERT_EQ(OpenTrusted("GET", "User-Agent:\n"), PP_OK
);
647 ASSERT_EQ(OpenTrusted("GET", "Via:\n"), PP_OK
);
648 ASSERT_EQ(OpenTrusted(
649 "GET", "Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA==:\n"), PP_OK
);
650 ASSERT_EQ(OpenTrusted("GET", "Sec-foo:\n"), PP_OK
);
652 // Trusted requests with custom referrer should succeed.
654 pp::URLRequestInfo
request(instance_
);
655 request
.SetCustomReferrerURL("http://www.google.com/");
657 int32_t rv
= OpenTrusted(request
);
659 return ReportError("Trusted request with custom referrer", rv
);
661 // Trusted requests with custom transfer encodings should succeed.
663 pp::URLRequestInfo
request(instance_
);
664 request
.SetCustomContentTransferEncoding("foo");
666 int32_t rv
= OpenTrusted(request
);
669 "Trusted request with content-transfer-encoding failed", rv
);
675 // This test should cause a redirect and ensure that the loader follows it.
676 std::string
TestURLLoader::TestFollowURLRedirect() {
677 pp::URLRequestInfo
request(instance_
);
678 // This prefix causes the test server to return a 301 redirect.
679 std::string
redirect_prefix("/server-redirect?");
680 // We need an absolute path for the redirect to actually work.
681 std::string redirect_url
=
682 GetReachableAbsoluteURL("test_url_loader_data/hello.txt");
683 request
.SetURL(redirect_prefix
.append(redirect_url
));
684 return LoadAndCompareBody(request
, "hello\n");
687 // This test should cause a redirect and ensure that the loader runs
688 // the callback, rather than following the redirect.
689 std::string
TestURLLoader::TestAuditURLRedirect() {
690 pp::URLRequestInfo
request(instance_
);
691 // This path will cause the server to return a 301 redirect.
692 // This prefix causes the test server to return a 301 redirect.
693 std::string
redirect_prefix("/server-redirect?");
694 // We need an absolute path for the redirect to actually work.
695 std::string redirect_url
=
696 GetReachableAbsoluteURL("test_url_loader_data/hello.txt");
697 request
.SetURL(redirect_prefix
.append(redirect_url
));
698 request
.SetFollowRedirects(false);
700 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
702 pp::URLLoader
loader(instance_
);
703 callback
.WaitForResult(loader
.Open(request
, callback
.GetCallback()));
704 CHECK_CALLBACK_BEHAVIOR(callback
);
705 ASSERT_EQ(PP_OK
, callback
.result());
707 // Checks that the response indicates a redirect, and that the URL
709 pp::URLResponseInfo
response_info(loader
.GetResponseInfo());
710 if (response_info
.is_null())
711 return "URLLoader::GetResponseInfo returned null";
712 int32_t status_code
= response_info
.GetStatusCode();
713 if (status_code
!= 301)
714 return "Response status should be 301";
716 // Test that the paused loader can be resumed.
717 callback
.WaitForResult(loader
.FollowRedirect(callback
.GetCallback()));
718 CHECK_CALLBACK_BEHAVIOR(callback
);
719 ASSERT_EQ(PP_OK
, callback
.result());
721 std::string error
= ReadEntireResponseBody(&loader
, &body
);
725 if (body
!= "hello\n")
726 return "URLLoader::FollowRedirect failed";
731 std::string
TestURLLoader::TestAbortCalls() {
732 pp::URLRequestInfo
request(instance_
);
733 request
.SetURL("test_url_loader_data/hello.txt");
735 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
740 rv
= pp::URLLoader(instance_
).Open(request
, callback
.GetCallback());
742 callback
.WaitForAbortResult(rv
);
743 CHECK_CALLBACK_BEHAVIOR(callback
);
745 // Abort |ReadResponseBody()|.
749 pp::URLLoader
loader(instance_
);
750 callback
.WaitForResult(loader
.Open(request
, callback
.GetCallback()));
751 CHECK_CALLBACK_BEHAVIOR(callback
);
752 ASSERT_EQ(PP_OK
, callback
.result());
754 rv
= loader
.ReadResponseBody(buf
, sizeof(buf
), callback
.GetCallback());
755 } // Destroy |loader|.
756 callback
.WaitForAbortResult(rv
);
757 CHECK_CALLBACK_BEHAVIOR(callback
);
758 if (rv
== PP_OK_COMPLETIONPENDING
) {
759 if (buf
[0] || buf
[1]) {
760 return "URLLoader::ReadResponseBody wrote data after resource "
766 // TODO(viettrungluu): More abort tests (but add basic tests first).
767 // Also test that Close() aborts properly. crbug.com/69457
772 std::string
TestURLLoader::TestUntendedLoad() {
773 pp::URLRequestInfo
request(instance_
);
774 request
.SetURL("test_url_loader_data/hello.txt");
775 request
.SetRecordDownloadProgress(true);
776 TestCompletionCallback
callback(instance_
->pp_instance(), callback_type());
778 pp::URLLoader
loader(instance_
);
779 callback
.WaitForResult(loader
.Open(request
, callback
.GetCallback()));
780 CHECK_CALLBACK_BEHAVIOR(callback
);
781 ASSERT_EQ(PP_OK
, callback
.result());
783 // We received the response callback. Yield until the network code has called
784 // the loader's didReceiveData and didFinishLoading methods before we give it
785 // another callback function, to make sure the loader works with no callback.
786 int64_t bytes_received
= 0;
787 int64_t total_bytes_to_be_received
= 0;
789 loader
.GetDownloadProgress(&bytes_received
, &total_bytes_to_be_received
);
790 if (total_bytes_to_be_received
<= 0)
791 return ReportError("URLLoader::GetDownloadProgress total size",
792 total_bytes_to_be_received
);
793 if (bytes_received
== total_bytes_to_be_received
)
795 // Yield if we're on the main thread, so that URLLoader can receive more
797 if (pp::Module::Get()->core()->IsMainThread()) {
798 NestedEvent
event(instance_
->pp_instance());
799 event
.PostSignal(10);
804 // The loader should now have the data and have finished successfully.
806 std::string error
= ReadEntireResponseBody(&loader
, &body
);
809 if (body
!= "hello\n")
810 return ReportError("Couldn't read data", callback
.result());
815 int32_t TestURLLoader::OpenWithPrefetchBufferThreshold(int32_t lower
,
817 pp::URLRequestInfo
request(instance_
);
818 request
.SetURL("test_url_loader_data/hello.txt");
819 request
.SetPrefetchBufferLowerThreshold(lower
);
820 request
.SetPrefetchBufferUpperThreshold(upper
);
822 return OpenUntrusted(request
);
825 std::string
TestURLLoader::TestPrefetchBufferThreshold() {
826 int32_t rv
= OpenWithPrefetchBufferThreshold(-1, 1);
827 if (rv
!= PP_ERROR_FAILED
) {
828 return ReportError("The prefetch limits contained a negative value but "
829 "the URLLoader did not fail.", rv
);
832 rv
= OpenWithPrefetchBufferThreshold(0, 1);
834 return ReportError("The prefetch buffer limits were legal values but "
835 "the URLLoader failed.", rv
);
838 rv
= OpenWithPrefetchBufferThreshold(1000, 1);
839 if (rv
!= PP_ERROR_FAILED
) {
840 return ReportError("The lower buffer value was higher than the upper but "
841 "the URLLoader did not fail.", rv
);
847 // TODO(viettrungluu): Add tests for Get{Upload,Download}Progress, Close
848 // (including abort tests if applicable).