Make certificate viewer a tab-modal dialog.
[chromium-blink-merge.git] / ppapi / tests / test_url_loader.cc
blob0978f0e25ec5e8b3cf69fa770115199d8ae6d6f5
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"
7 #include <stdio.h>
8 #include <string.h>
9 #include <string>
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);
31 namespace {
33 int32_t WriteEntireBuffer(PP_Instance instance,
34 pp::FileIO* file_io,
35 int32_t offset,
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();
55 return PP_OK;
58 } // namespace
60 TestURLLoader::TestURLLoader(TestingInstance* instance)
61 : TestCase(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");
69 return false;
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");
88 #else
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");
93 #endif
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,
125 std::string* data) {
126 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
127 char buf[256];
128 int64_t offset = 0;
130 for (;;) {
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)
136 break;
137 offset += callback.result();
138 data->append(buf, callback.result());
141 PASS();
144 std::string TestURLLoader::ReadEntireResponseBody(pp::URLLoader* loader,
145 std::string* body) {
146 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
147 char buf[2]; // Small so that multiple reads are needed.
149 for (;;) {
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)
155 break;
156 body->append(buf, callback.result());
159 PASS();
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";
179 std::string body;
180 std::string error = ReadEntireResponseBody(&loader, &body);
181 if (!error.empty())
182 return error;
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";
189 PASS();
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,
228 callback_type());
229 if (rv != PP_OK) {
230 message->assign("FileIO::Write failed.");
231 return rv;
234 return rv;
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(
242 pp::PASS_REF,
243 testing_interface_->GetDocumentURL(instance_->pp_instance(),
244 NULL));
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);
250 return url;
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");
264 return url;
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,
296 bool trusted) {
297 pp::URLLoader loader(instance_);
298 if (trusted)
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() {
321 std::string message;
323 pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
324 int32_t rv = OpenFileSystem(&file_system, &message);
325 if (rv != PP_OK)
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);
331 if (rv != PP_OK)
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() {
342 std::string message;
344 pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
345 int32_t rv = OpenFileSystem(&file_system, &message);
346 if (rv != PP_OK)
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);
352 if (rv != PP_OK)
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());
408 int32_t rv;
409 rv = OpenUntrusted(request);
410 if (rv != PP_ERROR_NOACCESS)
411 return ReportError(
412 "Untrusted request with bogus Content-Length restriction", rv);
414 PASS();
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());
437 if (body.is_null())
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());
450 std::string data;
451 std::string error = ReadEntireFile(&reader, &data);
452 if (!error.empty())
453 return error;
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.";
468 #endif
470 PASS();
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)
481 return ReportError(
482 "Untrusted, unintended cross-origin request restriction", rv);
484 PASS();
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);
494 if (rv != PP_OK)
495 return ReportError("Trusted cross-origin request failed", rv);
497 PASS();
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);
508 if (rv != PP_OK)
509 return ReportError(
510 "Untrusted, intended cross-origin request failed", rv);
512 PASS();
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);
523 if (rv != PP_OK)
524 return ReportError("Trusted cross-origin request failed", rv);
526 PASS();
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)
536 return ReportError(
537 "Untrusted Javascript URL request restriction failed", rv);
539 PASS();
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)
549 return ReportError(
550 "Trusted Javascript URL request", rv);
552 PASS();
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);
564 ASSERT_EQ(
565 OpenUntrusted("POST\x0d\x0ax-csrf-token:\x20test1234", std::string()),
566 PP_ERROR_NOACCESS);
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"),
593 PP_ERROR_NOACCESS);
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)
603 return ReportError(
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)
613 return ReportError(
614 "Untrusted request with content-transfer-encoding restriction", rv);
617 PASS();
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);
658 if (rv != PP_OK)
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);
667 if (rv != PP_OK)
668 return ReportError(
669 "Trusted request with content-transfer-encoding failed", rv);
672 PASS();
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
708 // is correct.
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());
720 std::string body;
721 std::string error = ReadEntireResponseBody(&loader, &body);
722 if (!error.empty())
723 return error;
725 if (body != "hello\n")
726 return "URLLoader::FollowRedirect failed";
728 PASS();
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());
736 int32_t rv;
738 // Abort |Open()|.
740 rv = pp::URLLoader(instance_).Open(request, callback.GetCallback());
742 callback.WaitForAbortResult(rv);
743 CHECK_CALLBACK_BEHAVIOR(callback);
745 // Abort |ReadResponseBody()|.
747 char buf[2] = { 0 };
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 "
761 "destruction.";
766 // TODO(viettrungluu): More abort tests (but add basic tests first).
767 // Also test that Close() aborts properly. crbug.com/69457
769 PASS();
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;
788 while (true) {
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)
794 break;
795 // Yield if we're on the main thread, so that URLLoader can receive more
796 // data.
797 if (pp::Module::Get()->core()->IsMainThread()) {
798 NestedEvent event(instance_->pp_instance());
799 event.PostSignal(10);
800 event.Wait();
804 // The loader should now have the data and have finished successfully.
805 std::string body;
806 std::string error = ReadEntireResponseBody(&loader, &body);
807 if (!error.empty())
808 return error;
809 if (body != "hello\n")
810 return ReportError("Couldn't read data", callback.result());
812 PASS();
815 int32_t TestURLLoader::OpenWithPrefetchBufferThreshold(int32_t lower,
816 int32_t upper) {
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);
833 if (rv != PP_OK) {
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);
844 PASS();
847 // TODO(viettrungluu): Add tests for Get{Upload,Download}Progress, Close
848 // (including abort tests if applicable).