Android: Remove unneeded Compositor::SetNeedsRedraw()
[chromium-blink-merge.git] / ppapi / tests / test_url_loader.cc
blob8d13f4089f21d2dfc5bd53c2f565986651725ad1
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();
99 * The test order is important here, as running tests out of order may cause
100 * test timeout.
102 * Here is the environment:
104 * 1. TestServer.py only accepts one open connection at the time.
105 * 2. HTTP socket pool keeps sockets open for several seconds after last use
106 * (hoping that there will be another request that could reuse the connection).
107 * 3. HTTP socket pool is separated by host/port and privacy mode (which is
108 * based on cookies set/get permissions). So, connections to 127.0.0.1,
109 * localhost and localhost in privacy mode cannot reuse existing socket and will
110 * try to open another connection.
112 * Here is the problem:
114 * Original test order was repeatedly accessing 127.0.0.1, localhost and
115 * localhost in privacy mode, causing new sockets to open and try to connect to
116 * testserver, which they couldn't until previous connection is closed by socket
117 * pool idle socket timeout (10 seconds).
119 * Because of this the test run was taking around 45 seconds, and test was
120 * reported as 'timed out' by trybot.
122 * Re-ordering of tests provides more sequential access to 127.0.0.1, localhost
123 * and localhost in privacy mode. It decreases the number of times when socket
124 * pool doesn't have existing connection to host and has to wait, therefore
125 * reducing total test time and ensuring its completion under 30 seconds.
127 void TestURLLoader::RunTests(const std::string& filter) {
128 // These tests connect to 127.0.0.1:
129 RUN_CALLBACK_TEST(TestURLLoader, BasicGET, filter);
130 RUN_CALLBACK_TEST(TestURLLoader, BasicPOST, filter);
131 RUN_CALLBACK_TEST(TestURLLoader, BasicFilePOST, filter);
132 RUN_CALLBACK_TEST(TestURLLoader, BasicFileRangePOST, filter);
133 RUN_CALLBACK_TEST(TestURLLoader, CompoundBodyPOST, filter);
134 RUN_CALLBACK_TEST(TestURLLoader, EmptyDataPOST, filter);
135 RUN_CALLBACK_TEST(TestURLLoader, BinaryDataPOST, filter);
136 RUN_CALLBACK_TEST(TestURLLoader, CustomRequestHeader, filter);
137 RUN_CALLBACK_TEST(TestURLLoader, FailsBogusContentLength, filter);
138 RUN_CALLBACK_TEST(TestURLLoader, StreamToFile, filter);
139 RUN_CALLBACK_TEST(TestURLLoader, UntrustedJavascriptURLRestriction, filter);
140 RUN_CALLBACK_TEST(TestURLLoader, TrustedJavascriptURLRestriction, filter);
141 RUN_CALLBACK_TEST(TestURLLoader, UntrustedHttpRequests, filter);
142 RUN_CALLBACK_TEST(TestURLLoader, TrustedHttpRequests, filter);
143 RUN_CALLBACK_TEST(TestURLLoader, FollowURLRedirect, filter);
144 RUN_CALLBACK_TEST(TestURLLoader, AuditURLRedirect, filter);
145 RUN_CALLBACK_TEST(TestURLLoader, AbortCalls, filter);
146 RUN_CALLBACK_TEST(TestURLLoader, UntendedLoad, filter);
147 RUN_CALLBACK_TEST(TestURLLoader, PrefetchBufferThreshold, filter);
148 // These tests connect to localhost with privacy mode enabled:
149 RUN_CALLBACK_TEST(TestURLLoader, UntrustedSameOriginRestriction, filter);
150 RUN_CALLBACK_TEST(TestURLLoader, UntrustedCrossOriginRequest, filter);
151 // These tests connect to localhost with privacy mode disabled:
152 RUN_CALLBACK_TEST(TestURLLoader, TrustedSameOriginRestriction, filter);
153 RUN_CALLBACK_TEST(TestURLLoader, TrustedCrossOriginRequest, filter);
156 std::string TestURLLoader::ReadEntireFile(pp::FileIO* file_io,
157 std::string* data) {
158 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
159 char buf[256];
160 int64_t offset = 0;
162 for (;;) {
163 callback.WaitForResult(file_io->Read(offset, buf, sizeof(buf),
164 callback.GetCallback()));
165 if (callback.result() < 0)
166 return ReportError("FileIO::Read", callback.result());
167 if (callback.result() == 0)
168 break;
169 offset += callback.result();
170 data->append(buf, callback.result());
173 PASS();
176 std::string TestURLLoader::ReadEntireResponseBody(pp::URLLoader* loader,
177 std::string* body) {
178 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
179 char buf[2]; // Small so that multiple reads are needed.
181 for (;;) {
182 callback.WaitForResult(
183 loader->ReadResponseBody(buf, sizeof(buf), callback.GetCallback()));
184 if (callback.result() < 0)
185 return ReportError("URLLoader::ReadResponseBody", callback.result());
186 if (callback.result() == 0)
187 break;
188 body->append(buf, callback.result());
191 PASS();
194 std::string TestURLLoader::LoadAndCompareBody(
195 const pp::URLRequestInfo& request,
196 const std::string& expected_body) {
197 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
199 pp::URLLoader loader(instance_);
200 callback.WaitForResult(loader.Open(request, callback.GetCallback()));
201 CHECK_CALLBACK_BEHAVIOR(callback);
202 ASSERT_EQ(PP_OK, callback.result());
204 pp::URLResponseInfo response_info(loader.GetResponseInfo());
205 if (response_info.is_null())
206 return "URLLoader::GetResponseInfo returned null";
207 int32_t status_code = response_info.GetStatusCode();
208 if (status_code != 200)
209 return "Unexpected HTTP status code";
211 std::string body;
212 std::string error = ReadEntireResponseBody(&loader, &body);
213 if (!error.empty())
214 return error;
216 if (body.size() != expected_body.size())
217 return "URLLoader::ReadResponseBody returned unexpected content length";
218 if (body != expected_body)
219 return "URLLoader::ReadResponseBody returned unexpected content";
221 PASS();
224 int32_t TestURLLoader::OpenFileSystem(pp::FileSystem* file_system,
225 std::string* message) {
226 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
227 callback.WaitForResult(file_system->Open(1024, callback.GetCallback()));
228 if (callback.failed()) {
229 message->assign(callback.errors());
230 return callback.result();
232 if (callback.result() != PP_OK) {
233 message->assign("FileSystem::Open");
234 return callback.result();
236 return callback.result();
239 int32_t TestURLLoader::PrepareFileForPost(
240 const pp::FileRef& file_ref,
241 const std::string& data,
242 std::string* message) {
243 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
244 pp::FileIO file_io(instance_);
245 callback.WaitForResult(file_io.Open(file_ref,
246 PP_FILEOPENFLAG_CREATE |
247 PP_FILEOPENFLAG_TRUNCATE |
248 PP_FILEOPENFLAG_WRITE,
249 callback.GetCallback()));
250 if (callback.failed()) {
251 message->assign(callback.errors());
252 return callback.result();
254 if (callback.result() != PP_OK) {
255 message->assign("FileIO::Open failed.");
256 return callback.result();
259 int32_t rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 0, data,
260 callback_type());
261 if (rv != PP_OK) {
262 message->assign("FileIO::Write failed.");
263 return rv;
266 return rv;
269 std::string TestURLLoader::GetReachableAbsoluteURL(
270 const std::string& file_name) {
271 // Get the absolute page URL and replace the test case file name
272 // with the given one.
273 pp::Var document_url(
274 pp::PASS_REF,
275 testing_interface_->GetDocumentURL(instance_->pp_instance(),
276 NULL));
277 std::string url(document_url.AsString());
278 std::string old_name("test_case.html");
279 size_t index = url.find(old_name);
280 ASSERT_NE(index, std::string::npos);
281 url.replace(index, old_name.length(), file_name);
282 return url;
285 std::string TestURLLoader::GetReachableCrossOriginURL(
286 const std::string& file_name) {
287 // Get an absolute URL and use it to construct a URL that will be
288 // considered cross-origin by the CORS access control code, and yet be
289 // reachable by the test server.
290 std::string url = GetReachableAbsoluteURL(file_name);
291 // Replace '127.0.0.1' with 'localhost'.
292 std::string host("127.0.0.1");
293 size_t index = url.find(host);
294 ASSERT_NE(index, std::string::npos);
295 url.replace(index, host.length(), "localhost");
296 return url;
299 int32_t TestURLLoader::OpenUntrusted(const std::string& method,
300 const std::string& header) {
301 pp::URLRequestInfo request(instance_);
302 request.SetURL("/echo");
303 request.SetMethod(method);
304 request.SetHeaders(header);
306 return OpenUntrusted(request);
309 int32_t TestURLLoader::OpenTrusted(const std::string& method,
310 const std::string& header) {
311 pp::URLRequestInfo request(instance_);
312 request.SetURL("/echo");
313 request.SetMethod(method);
314 request.SetHeaders(header);
316 return OpenTrusted(request);
319 int32_t TestURLLoader::OpenUntrusted(const pp::URLRequestInfo& request) {
320 return Open(request, false);
323 int32_t TestURLLoader::OpenTrusted(const pp::URLRequestInfo& request) {
324 return Open(request, true);
327 int32_t TestURLLoader::Open(const pp::URLRequestInfo& request,
328 bool trusted) {
329 pp::URLLoader loader(instance_);
330 if (trusted)
331 url_loader_trusted_interface_->GrantUniversalAccess(loader.pp_resource());
332 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
333 callback.WaitForResult(loader.Open(request, callback.GetCallback()));
334 return callback.result();
337 std::string TestURLLoader::TestBasicGET() {
338 pp::URLRequestInfo request(instance_);
339 request.SetURL("test_url_loader_data/hello.txt");
340 return LoadAndCompareBody(request, "hello\n");
343 std::string TestURLLoader::TestBasicPOST() {
344 pp::URLRequestInfo request(instance_);
345 request.SetURL("/echo");
346 request.SetMethod("POST");
347 std::string postdata("postdata");
348 request.AppendDataToBody(postdata.data(), postdata.length());
349 return LoadAndCompareBody(request, postdata);
352 std::string TestURLLoader::TestBasicFilePOST() {
353 std::string message;
355 pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
356 int32_t rv = OpenFileSystem(&file_system, &message);
357 if (rv != PP_OK)
358 return ReportError(message.c_str(), rv);
360 pp::FileRef file_ref(file_system, "/file_post_test");
361 std::string postdata("postdata");
362 rv = PrepareFileForPost(file_ref, postdata, &message);
363 if (rv != PP_OK)
364 return ReportError(message.c_str(), rv);
366 pp::URLRequestInfo request(instance_);
367 request.SetURL("/echo");
368 request.SetMethod("POST");
369 request.AppendFileToBody(file_ref, 0);
370 return LoadAndCompareBody(request, postdata);
373 std::string TestURLLoader::TestBasicFileRangePOST() {
374 std::string message;
376 pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
377 int32_t rv = OpenFileSystem(&file_system, &message);
378 if (rv != PP_OK)
379 return ReportError(message.c_str(), rv);
381 pp::FileRef file_ref(file_system, "/file_range_post_test");
382 std::string postdata("postdatapostdata");
383 rv = PrepareFileForPost(file_ref, postdata, &message);
384 if (rv != PP_OK)
385 return ReportError(message.c_str(), rv);
387 pp::URLRequestInfo request(instance_);
388 request.SetURL("/echo");
389 request.SetMethod("POST");
390 request.AppendFileRangeToBody(file_ref, 4, 12, 0);
391 return LoadAndCompareBody(request, postdata.substr(4, 12));
394 std::string TestURLLoader::TestCompoundBodyPOST() {
395 pp::URLRequestInfo request(instance_);
396 request.SetURL("/echo");
397 request.SetMethod("POST");
398 std::string postdata1("post");
399 request.AppendDataToBody(postdata1.data(), postdata1.length());
400 std::string postdata2("data");
401 request.AppendDataToBody(postdata2.data(), postdata2.length());
402 return LoadAndCompareBody(request, postdata1 + postdata2);
405 std::string TestURLLoader::TestEmptyDataPOST() {
406 pp::URLRequestInfo request(instance_);
407 request.SetURL("/echo");
408 request.SetMethod("POST");
409 request.AppendDataToBody("", 0);
410 return LoadAndCompareBody(request, std::string());
413 std::string TestURLLoader::TestBinaryDataPOST() {
414 pp::URLRequestInfo request(instance_);
415 request.SetURL("/echo");
416 request.SetMethod("POST");
417 const char postdata_chars[] =
418 "\x00\x01\x02\x03\x04\x05postdata\xfa\xfb\xfc\xfd\xfe\xff";
419 std::string postdata(postdata_chars,
420 sizeof(postdata_chars) / sizeof(postdata_chars[0]));
421 request.AppendDataToBody(postdata.data(), postdata.length());
422 return LoadAndCompareBody(request, postdata);
425 std::string TestURLLoader::TestCustomRequestHeader() {
426 pp::URLRequestInfo request(instance_);
427 request.SetURL("/echoheader?Foo");
428 request.SetHeaders("Foo: 1");
429 return LoadAndCompareBody(request, "1");
432 std::string TestURLLoader::TestFailsBogusContentLength() {
433 pp::URLRequestInfo request(instance_);
434 request.SetURL("/echo");
435 request.SetMethod("POST");
436 request.SetHeaders("Content-Length: 400");
437 std::string postdata("postdata");
438 request.AppendDataToBody(postdata.data(), postdata.length());
440 int32_t rv;
441 rv = OpenUntrusted(request);
442 if (rv != PP_ERROR_NOACCESS)
443 return ReportError(
444 "Untrusted request with bogus Content-Length restriction", rv);
446 PASS();
449 std::string TestURLLoader::TestStreamToFile() {
450 pp::URLRequestInfo request(instance_);
451 request.SetURL("test_url_loader_data/hello.txt");
452 request.SetStreamToFile(true);
454 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
456 pp::URLLoader loader(instance_);
457 callback.WaitForResult(loader.Open(request, callback.GetCallback()));
458 CHECK_CALLBACK_BEHAVIOR(callback);
459 ASSERT_EQ(PP_OK, callback.result());
461 pp::URLResponseInfo response_info(loader.GetResponseInfo());
462 if (response_info.is_null())
463 return "URLLoader::GetResponseInfo returned null";
464 int32_t status_code = response_info.GetStatusCode();
465 if (status_code != 200)
466 return "Unexpected HTTP status code";
468 pp::FileRef body(response_info.GetBodyAsFileRef());
469 if (body.is_null())
470 return "URLResponseInfo::GetBody returned null";
472 callback.WaitForResult(loader.FinishStreamingToFile(callback.GetCallback()));
473 CHECK_CALLBACK_BEHAVIOR(callback);
474 ASSERT_EQ(PP_OK, callback.result());
476 pp::FileIO reader(instance_);
477 callback.WaitForResult(reader.Open(body, PP_FILEOPENFLAG_READ,
478 callback.GetCallback()));
479 CHECK_CALLBACK_BEHAVIOR(callback);
480 ASSERT_EQ(PP_OK, callback.result());
482 std::string data;
483 std::string error = ReadEntireFile(&reader, &data);
484 if (!error.empty())
485 return error;
487 std::string expected_body = "hello\n";
488 if (data.size() != expected_body.size())
489 return "ReadEntireFile returned unexpected content length";
490 if (data != expected_body)
491 return "ReadEntireFile returned unexpected content";
493 // FileIOTrusted is not supported by NaCl or ppapi/proxy.
494 if (!testing_interface_->IsOutOfProcess()) {
495 #if !(defined __native_client__)
496 int32_t file_descriptor = file_io_trusted_interface_->GetOSFileDescriptor(
497 reader.pp_resource());
498 if (file_descriptor < 0)
499 return "FileIO::GetOSFileDescriptor() returned a bad file descriptor.";
500 #endif
502 PASS();
505 // Untrusted, unintended cross-origin requests should fail.
506 std::string TestURLLoader::TestUntrustedSameOriginRestriction() {
507 pp::URLRequestInfo request(instance_);
508 std::string cross_origin_url = GetReachableCrossOriginURL("test_case.html");
509 request.SetURL(cross_origin_url);
511 int32_t rv = OpenUntrusted(request);
512 if (rv != PP_ERROR_NOACCESS)
513 return ReportError(
514 "Untrusted, unintended cross-origin request restriction", rv);
516 PASS();
519 // Trusted, unintended cross-origin requests should succeed.
520 std::string TestURLLoader::TestTrustedSameOriginRestriction() {
521 pp::URLRequestInfo request(instance_);
522 std::string cross_origin_url = GetReachableCrossOriginURL("test_case.html");
523 request.SetURL(cross_origin_url);
525 int32_t rv = OpenTrusted(request);
526 if (rv != PP_OK)
527 return ReportError("Trusted cross-origin request failed", rv);
529 PASS();
532 // Untrusted, intended cross-origin requests should use CORS and succeed.
533 std::string TestURLLoader::TestUntrustedCrossOriginRequest() {
534 pp::URLRequestInfo request(instance_);
535 std::string cross_origin_url = GetReachableCrossOriginURL("test_case.html");
536 request.SetURL(cross_origin_url);
537 request.SetAllowCrossOriginRequests(true);
539 int32_t rv = OpenUntrusted(request);
540 if (rv != PP_OK)
541 return ReportError(
542 "Untrusted, intended cross-origin request failed", rv);
544 PASS();
547 // Trusted, intended cross-origin requests should use CORS and succeed.
548 std::string TestURLLoader::TestTrustedCrossOriginRequest() {
549 pp::URLRequestInfo request(instance_);
550 std::string cross_origin_url = GetReachableCrossOriginURL("test_case.html");
551 request.SetURL(cross_origin_url);
552 request.SetAllowCrossOriginRequests(true);
554 int32_t rv = OpenTrusted(request);
555 if (rv != PP_OK)
556 return ReportError("Trusted cross-origin request failed", rv);
558 PASS();
561 // Untrusted Javascript URLs requests should fail.
562 std::string TestURLLoader::TestUntrustedJavascriptURLRestriction() {
563 pp::URLRequestInfo request(instance_);
564 request.SetURL("javascript:foo = bar");
566 int32_t rv = OpenUntrusted(request);
567 if (rv != PP_ERROR_NOACCESS)
568 return ReportError(
569 "Untrusted Javascript URL request restriction failed", rv);
571 PASS();
574 // Trusted Javascript URLs requests should succeed.
575 std::string TestURLLoader::TestTrustedJavascriptURLRestriction() {
576 pp::URLRequestInfo request(instance_);
577 request.SetURL("javascript:foo = bar");
579 int32_t rv = OpenTrusted(request);
580 if (rv == PP_ERROR_NOACCESS)
581 return ReportError(
582 "Trusted Javascript URL request", rv);
584 PASS();
587 std::string TestURLLoader::TestUntrustedHttpRequests() {
588 // HTTP methods are restricted only for untrusted loaders. Forbidden
589 // methods are CONNECT, TRACE, and TRACK, and any string that is not a
590 // valid token (containing special characters like CR, LF).
591 // http://www.w3.org/TR/XMLHttpRequest/
593 ASSERT_EQ(OpenUntrusted("cOnNeCt", std::string()), PP_ERROR_NOACCESS);
594 ASSERT_EQ(OpenUntrusted("tRaCk", std::string()), PP_ERROR_NOACCESS);
595 ASSERT_EQ(OpenUntrusted("tRaCe", std::string()), PP_ERROR_NOACCESS);
596 ASSERT_EQ(
597 OpenUntrusted("POST\x0d\x0ax-csrf-token:\x20test1234", std::string()),
598 PP_ERROR_NOACCESS);
600 // HTTP methods are restricted only for untrusted loaders. Try all headers
601 // that are forbidden by http://www.w3.org/TR/XMLHttpRequest/.
603 ASSERT_EQ(OpenUntrusted("GET", "Accept-Charset:\n"), PP_ERROR_NOACCESS);
604 ASSERT_EQ(OpenUntrusted("GET", "Accept-Encoding:\n"), PP_ERROR_NOACCESS);
605 ASSERT_EQ(OpenUntrusted("GET", "Connection:\n"), PP_ERROR_NOACCESS);
606 ASSERT_EQ(OpenUntrusted("GET", "Content-Length:\n"), PP_ERROR_NOACCESS);
607 ASSERT_EQ(OpenUntrusted("GET", "Cookie:\n"), PP_ERROR_NOACCESS);
608 ASSERT_EQ(OpenUntrusted("GET", "Cookie2:\n"), PP_ERROR_NOACCESS);
609 ASSERT_EQ(OpenUntrusted(
610 "GET", "Content-Transfer-Encoding:\n"), PP_ERROR_NOACCESS);
611 ASSERT_EQ(OpenUntrusted("GET", "Date:\n"), PP_ERROR_NOACCESS);
612 ASSERT_EQ(OpenUntrusted("GET", "Expect:\n"), PP_ERROR_NOACCESS);
613 ASSERT_EQ(OpenUntrusted("GET", "Host:\n"), PP_ERROR_NOACCESS);
614 ASSERT_EQ(OpenUntrusted("GET", "Keep-Alive:\n"), PP_ERROR_NOACCESS);
615 ASSERT_EQ(OpenUntrusted("GET", "Referer:\n"), PP_ERROR_NOACCESS);
616 ASSERT_EQ(OpenUntrusted("GET", "TE:\n"), PP_ERROR_NOACCESS);
617 ASSERT_EQ(OpenUntrusted("GET", "Trailer:\n"), PP_ERROR_NOACCESS);
618 ASSERT_EQ(OpenUntrusted(
619 "GET", "Transfer-Encoding:\n"), PP_ERROR_NOACCESS);
620 ASSERT_EQ(OpenUntrusted("GET", "Upgrade:\n"), PP_ERROR_NOACCESS);
621 ASSERT_EQ(OpenUntrusted("GET", "User-Agent:\n"), PP_ERROR_NOACCESS);
622 ASSERT_EQ(OpenUntrusted("GET", "Via:\n"), PP_ERROR_NOACCESS);
623 ASSERT_EQ(OpenUntrusted(
624 "GET", "Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA==:\n"),
625 PP_ERROR_NOACCESS);
626 ASSERT_EQ(OpenUntrusted("GET", "Sec-foo:\n"), PP_ERROR_NOACCESS);
628 // Untrusted requests with custom referrer should fail.
630 pp::URLRequestInfo request(instance_);
631 request.SetCustomReferrerURL("http://www.google.com/");
633 int32_t rv = OpenUntrusted(request);
634 if (rv != PP_ERROR_NOACCESS)
635 return ReportError(
636 "Untrusted request with custom referrer restriction", rv);
638 // Untrusted requests with custom transfer encodings should fail.
640 pp::URLRequestInfo request(instance_);
641 request.SetCustomContentTransferEncoding("foo");
643 int32_t rv = OpenUntrusted(request);
644 if (rv != PP_ERROR_NOACCESS)
645 return ReportError(
646 "Untrusted request with content-transfer-encoding restriction", rv);
649 PASS();
652 std::string TestURLLoader::TestTrustedHttpRequests() {
653 // Trusted requests can use restricted methods.
655 ASSERT_EQ(OpenTrusted("cOnNeCt", std::string()), PP_OK);
656 ASSERT_EQ(OpenTrusted("tRaCk", std::string()), PP_OK);
657 ASSERT_EQ(OpenTrusted("tRaCe", std::string()), PP_OK);
659 // Trusted requests can use restricted headers.
661 ASSERT_EQ(OpenTrusted("GET", "Accept-Charset:\n"), PP_OK);
662 ASSERT_EQ(OpenTrusted("GET", "Accept-Encoding:\n"), PP_OK);
663 ASSERT_EQ(OpenTrusted("GET", "Connection:\n"), PP_OK);
664 ASSERT_EQ(OpenTrusted("GET", "Content-Length:\n"), PP_OK);
665 ASSERT_EQ(OpenTrusted("GET", "Cookie:\n"), PP_OK);
666 ASSERT_EQ(OpenTrusted("GET", "Cookie2:\n"), PP_OK);
667 ASSERT_EQ(OpenTrusted(
668 "GET", "Content-Transfer-Encoding:\n"), PP_OK);
669 ASSERT_EQ(OpenTrusted("GET", "Date:\n"), PP_OK);
670 ASSERT_EQ(OpenTrusted("GET", "Expect:\n"), PP_OK);
671 ASSERT_EQ(OpenTrusted("GET", "Host:\n"), PP_OK);
672 ASSERT_EQ(OpenTrusted("GET", "Keep-Alive:\n"), PP_OK);
673 ASSERT_EQ(OpenTrusted("GET", "Referer:\n"), PP_OK);
674 ASSERT_EQ(OpenTrusted("GET", "TE:\n"), PP_OK);
675 ASSERT_EQ(OpenTrusted("GET", "Trailer:\n"), PP_OK);
676 ASSERT_EQ(OpenTrusted("GET", "Transfer-Encoding:\n"), PP_OK);
677 ASSERT_EQ(OpenTrusted("GET", "Upgrade:\n"), PP_OK);
678 ASSERT_EQ(OpenTrusted("GET", "User-Agent:\n"), PP_OK);
679 ASSERT_EQ(OpenTrusted("GET", "Via:\n"), PP_OK);
680 ASSERT_EQ(OpenTrusted(
681 "GET", "Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA==:\n"), PP_OK);
682 ASSERT_EQ(OpenTrusted("GET", "Sec-foo:\n"), PP_OK);
684 // Trusted requests with custom referrer should succeed.
686 pp::URLRequestInfo request(instance_);
687 request.SetCustomReferrerURL("http://www.google.com/");
689 int32_t rv = OpenTrusted(request);
690 if (rv != PP_OK)
691 return ReportError("Trusted request with custom referrer", rv);
693 // Trusted requests with custom transfer encodings should succeed.
695 pp::URLRequestInfo request(instance_);
696 request.SetCustomContentTransferEncoding("foo");
698 int32_t rv = OpenTrusted(request);
699 if (rv != PP_OK)
700 return ReportError(
701 "Trusted request with content-transfer-encoding failed", rv);
704 PASS();
707 // This test should cause a redirect and ensure that the loader follows it.
708 std::string TestURLLoader::TestFollowURLRedirect() {
709 pp::URLRequestInfo request(instance_);
710 // This prefix causes the test server to return a 301 redirect.
711 std::string redirect_prefix("/server-redirect?");
712 // We need an absolute path for the redirect to actually work.
713 std::string redirect_url =
714 GetReachableAbsoluteURL("test_url_loader_data/hello.txt");
715 request.SetURL(redirect_prefix.append(redirect_url));
716 return LoadAndCompareBody(request, "hello\n");
719 // This test should cause a redirect and ensure that the loader runs
720 // the callback, rather than following the redirect.
721 std::string TestURLLoader::TestAuditURLRedirect() {
722 pp::URLRequestInfo request(instance_);
723 // This path will cause the server to return a 301 redirect.
724 // This prefix causes the test server to return a 301 redirect.
725 std::string redirect_prefix("/server-redirect?");
726 // We need an absolute path for the redirect to actually work.
727 std::string redirect_url =
728 GetReachableAbsoluteURL("test_url_loader_data/hello.txt");
729 request.SetURL(redirect_prefix.append(redirect_url));
730 request.SetFollowRedirects(false);
732 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
734 pp::URLLoader loader(instance_);
735 callback.WaitForResult(loader.Open(request, callback.GetCallback()));
736 CHECK_CALLBACK_BEHAVIOR(callback);
737 ASSERT_EQ(PP_OK, callback.result());
739 // Checks that the response indicates a redirect, and that the URL
740 // is correct.
741 pp::URLResponseInfo response_info(loader.GetResponseInfo());
742 if (response_info.is_null())
743 return "URLLoader::GetResponseInfo returned null";
744 int32_t status_code = response_info.GetStatusCode();
745 if (status_code != 301)
746 return "Response status should be 301";
748 // Test that the paused loader can be resumed.
749 callback.WaitForResult(loader.FollowRedirect(callback.GetCallback()));
750 CHECK_CALLBACK_BEHAVIOR(callback);
751 ASSERT_EQ(PP_OK, callback.result());
752 std::string body;
753 std::string error = ReadEntireResponseBody(&loader, &body);
754 if (!error.empty())
755 return error;
757 if (body != "hello\n")
758 return "URLLoader::FollowRedirect failed";
760 PASS();
763 std::string TestURLLoader::TestAbortCalls() {
764 pp::URLRequestInfo request(instance_);
765 request.SetURL("test_url_loader_data/hello.txt");
767 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
768 int32_t rv;
770 // Abort |Open()|.
772 rv = pp::URLLoader(instance_).Open(request, callback.GetCallback());
774 callback.WaitForAbortResult(rv);
775 CHECK_CALLBACK_BEHAVIOR(callback);
777 // Abort |ReadResponseBody()|.
779 char buf[2] = { 0 };
781 pp::URLLoader loader(instance_);
782 callback.WaitForResult(loader.Open(request, callback.GetCallback()));
783 CHECK_CALLBACK_BEHAVIOR(callback);
784 ASSERT_EQ(PP_OK, callback.result());
786 rv = loader.ReadResponseBody(buf, sizeof(buf), callback.GetCallback());
787 } // Destroy |loader|.
788 callback.WaitForAbortResult(rv);
789 CHECK_CALLBACK_BEHAVIOR(callback);
790 if (rv == PP_OK_COMPLETIONPENDING) {
791 if (buf[0] || buf[1]) {
792 return "URLLoader::ReadResponseBody wrote data after resource "
793 "destruction.";
798 // TODO(viettrungluu): More abort tests (but add basic tests first).
799 // Also test that Close() aborts properly. crbug.com/69457
801 PASS();
804 std::string TestURLLoader::TestUntendedLoad() {
805 pp::URLRequestInfo request(instance_);
806 request.SetURL("test_url_loader_data/hello.txt");
807 request.SetRecordDownloadProgress(true);
808 TestCompletionCallback callback(instance_->pp_instance(), callback_type());
810 pp::URLLoader loader(instance_);
811 callback.WaitForResult(loader.Open(request, callback.GetCallback()));
812 CHECK_CALLBACK_BEHAVIOR(callback);
813 ASSERT_EQ(PP_OK, callback.result());
815 // We received the response callback. Yield until the network code has called
816 // the loader's didReceiveData and didFinishLoading methods before we give it
817 // another callback function, to make sure the loader works with no callback.
818 int64_t bytes_received = 0;
819 int64_t total_bytes_to_be_received = 0;
820 while (true) {
821 loader.GetDownloadProgress(&bytes_received, &total_bytes_to_be_received);
822 if (total_bytes_to_be_received <= 0)
823 return ReportError("URLLoader::GetDownloadProgress total size",
824 total_bytes_to_be_received);
825 if (bytes_received == total_bytes_to_be_received)
826 break;
827 // Yield if we're on the main thread, so that URLLoader can receive more
828 // data.
829 if (pp::Module::Get()->core()->IsMainThread()) {
830 NestedEvent event(instance_->pp_instance());
831 event.PostSignal(10);
832 event.Wait();
835 // The loader should now have the data and have finished successfully.
836 std::string body;
837 std::string error = ReadEntireResponseBody(&loader, &body);
838 if (!error.empty())
839 return error;
840 if (body != "hello\n")
841 return ReportError("Couldn't read data", callback.result());
843 PASS();
846 int32_t TestURLLoader::OpenWithPrefetchBufferThreshold(int32_t lower,
847 int32_t upper) {
848 pp::URLRequestInfo request(instance_);
849 request.SetURL("test_url_loader_data/hello.txt");
850 request.SetPrefetchBufferLowerThreshold(lower);
851 request.SetPrefetchBufferUpperThreshold(upper);
853 return OpenUntrusted(request);
856 std::string TestURLLoader::TestPrefetchBufferThreshold() {
857 int32_t rv = OpenWithPrefetchBufferThreshold(-1, 1);
858 if (rv != PP_ERROR_FAILED) {
859 return ReportError("The prefetch limits contained a negative value but "
860 "the URLLoader did not fail.", rv);
863 rv = OpenWithPrefetchBufferThreshold(0, 1);
864 if (rv != PP_OK) {
865 return ReportError("The prefetch buffer limits were legal values but "
866 "the URLLoader failed.", rv);
869 rv = OpenWithPrefetchBufferThreshold(1000, 1);
870 if (rv != PP_ERROR_FAILED) {
871 return ReportError("The lower buffer value was higher than the upper but "
872 "the URLLoader did not fail.", rv);
875 PASS();
878 // TODO(viettrungluu): Add tests for Get{Upload,Download}Progress, Close
879 // (including abort tests if applicable).