test_url_loader.cc 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082
  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.
  4. #include "ppapi/tests/test_url_loader.h"
  5. #include <stddef.h>
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include <string>
  9. #include "ppapi/c/pp_errors.h"
  10. #include "ppapi/c/ppb_file_io.h"
  11. #include "ppapi/c/ppb_url_loader.h"
  12. #include "ppapi/c/trusted/ppb_url_loader_trusted.h"
  13. #include "ppapi/cpp/dev/url_util_dev.h"
  14. #include "ppapi/cpp/file_io.h"
  15. #include "ppapi/cpp/file_ref.h"
  16. #include "ppapi/cpp/file_system.h"
  17. #include "ppapi/cpp/instance.h"
  18. #include "ppapi/cpp/module.h"
  19. #include "ppapi/cpp/private/file_io_private.h"
  20. #include "ppapi/cpp/url_loader.h"
  21. #include "ppapi/cpp/url_request_info.h"
  22. #include "ppapi/cpp/url_response_info.h"
  23. #include "ppapi/tests/test_utils.h"
  24. #include "ppapi/tests/testing_instance.h"
  25. REGISTER_TEST_CASE(URLLoader);
  26. namespace {
  27. int32_t WriteEntireBuffer(PP_Instance instance,
  28. pp::FileIO* file_io,
  29. int32_t offset,
  30. const std::string& data,
  31. CallbackType callback_type) {
  32. TestCompletionCallback callback(instance, callback_type);
  33. int32_t write_offset = offset;
  34. const char* buf = data.c_str();
  35. int32_t size = static_cast<int32_t>(data.size());
  36. while (write_offset < offset + size) {
  37. callback.WaitForResult(file_io->Write(write_offset,
  38. &buf[write_offset - offset],
  39. size - write_offset + offset,
  40. callback.GetCallback()));
  41. if (callback.result() < 0)
  42. return callback.result();
  43. if (callback.result() == 0)
  44. return PP_ERROR_FAILED;
  45. write_offset += callback.result();
  46. }
  47. return PP_OK;
  48. }
  49. } // namespace
  50. TestURLLoader::TestURLLoader(TestingInstance* instance)
  51. : TestCase(instance),
  52. file_io_private_interface_(NULL),
  53. url_loader_trusted_interface_(NULL) {
  54. }
  55. bool TestURLLoader::Init() {
  56. if (!CheckTestingInterface()) {
  57. instance_->AppendError("Testing interface not available");
  58. return false;
  59. }
  60. const PPB_FileIO* file_io_interface = static_cast<const PPB_FileIO*>(
  61. pp::Module::Get()->GetBrowserInterface(PPB_FILEIO_INTERFACE));
  62. if (!file_io_interface)
  63. instance_->AppendError("FileIO interface not available");
  64. file_io_private_interface_ = static_cast<const PPB_FileIO_Private*>(
  65. pp::Module::Get()->GetBrowserInterface(PPB_FILEIO_PRIVATE_INTERFACE));
  66. if (!file_io_private_interface_)
  67. instance_->AppendError("FileIO_Private interface not available");
  68. url_loader_trusted_interface_ = static_cast<const PPB_URLLoaderTrusted*>(
  69. pp::Module::Get()->GetBrowserInterface(PPB_URLLOADERTRUSTED_INTERFACE));
  70. if (!testing_interface_->IsOutOfProcess()) {
  71. // Trusted interfaces are not supported under NaCl.
  72. #if !(defined __native_client__)
  73. if (!url_loader_trusted_interface_)
  74. instance_->AppendError("URLLoaderTrusted interface not available");
  75. #else
  76. if (url_loader_trusted_interface_)
  77. instance_->AppendError("URLLoaderTrusted interface is supported by NaCl");
  78. #endif
  79. }
  80. return EnsureRunningOverHTTP();
  81. }
  82. /*
  83. * The test order is important here, as running tests out of order may cause
  84. * test timeout.
  85. *
  86. * Here is the environment:
  87. *
  88. * 1. net::EmbeddedTestServer only accepts one open connection at the time.
  89. * 2. HTTP socket pool keeps sockets open for several seconds after last use
  90. * (hoping that there will be another request that could reuse the connection).
  91. * 3. HTTP socket pool is separated by host/port and privacy mode (which is
  92. * based on cookies set/get permissions). So, connections to 127.0.0.1,
  93. * localhost and localhost in privacy mode cannot reuse existing socket and will
  94. * try to open another connection.
  95. *
  96. * Here is the problem:
  97. *
  98. * Original test order was repeatedly accessing 127.0.0.1, localhost and
  99. * localhost in privacy mode, causing new sockets to open and try to connect to
  100. * testserver, which they couldn't until previous connection is closed by socket
  101. * pool idle socket timeout (10 seconds).
  102. *
  103. * Because of this the test run was taking around 45 seconds, and test was
  104. * reported as 'timed out' by trybot.
  105. *
  106. * Re-ordering of tests provides more sequential access to 127.0.0.1, localhost
  107. * and localhost in privacy mode. It decreases the number of times when socket
  108. * pool doesn't have existing connection to host and has to wait, therefore
  109. * reducing total test time and ensuring its completion under 30 seconds.
  110. */
  111. void TestURLLoader::RunTests(const std::string& filter) {
  112. // These tests connect to 127.0.0.1:
  113. RUN_CALLBACK_TEST(TestURLLoader, BasicGET, filter);
  114. RUN_CALLBACK_TEST(TestURLLoader, BasicPOST, filter);
  115. RUN_CALLBACK_TEST(TestURLLoader, BasicFilePOST, filter);
  116. RUN_CALLBACK_TEST(TestURLLoader, BasicFileRangePOST, filter);
  117. RUN_CALLBACK_TEST(TestURLLoader, CompoundBodyPOST, filter);
  118. RUN_CALLBACK_TEST(TestURLLoader, EmptyDataPOST, filter);
  119. RUN_CALLBACK_TEST(TestURLLoader, BinaryDataPOST, filter);
  120. RUN_CALLBACK_TEST(TestURLLoader, CustomRequestHeader, filter);
  121. RUN_CALLBACK_TEST(TestURLLoader, FailsBogusContentLength, filter);
  122. RUN_CALLBACK_TEST(TestURLLoader, StreamToFile, filter);
  123. RUN_CALLBACK_TEST(TestURLLoader, UntrustedJavascriptURLRestriction, filter);
  124. RUN_CALLBACK_TEST(TestURLLoader, TrustedJavascriptURLRestriction, filter);
  125. RUN_CALLBACK_TEST(TestURLLoader, UntrustedHttpRequests, filter);
  126. RUN_CALLBACK_TEST(TestURLLoader, TrustedHttpRequests, filter);
  127. RUN_CALLBACK_TEST(TestURLLoader, FollowURLRedirect, filter);
  128. RUN_CALLBACK_TEST(TestURLLoader, AuditURLRedirect, filter);
  129. RUN_CALLBACK_TEST(TestURLLoader, RestrictURLRedirectCommon, filter);
  130. RUN_CALLBACK_TEST(TestURLLoader, RestrictURLRedirectEnabled, filter);
  131. RUN_CALLBACK_TEST(TestURLLoader, RestrictURLRedirectDisabled, filter);
  132. RUN_CALLBACK_TEST(TestURLLoader, AbortCalls, filter);
  133. RUN_CALLBACK_TEST(TestURLLoader, UntendedLoad, filter);
  134. RUN_CALLBACK_TEST(TestURLLoader, PrefetchBufferThreshold, filter);
  135. RUN_CALLBACK_TEST(TestURLLoader, XRequestedWithHeader, filter);
  136. // These tests connect to localhost with privacy mode enabled:
  137. RUN_CALLBACK_TEST(TestURLLoader, UntrustedSameOriginRestriction, filter);
  138. RUN_CALLBACK_TEST(TestURLLoader, UntrustedCrossOriginRequest, filter);
  139. RUN_CALLBACK_TEST(TestURLLoader, UntrustedCorbEligibleRequest, filter);
  140. // These tests connect to localhost with privacy mode disabled:
  141. RUN_CALLBACK_TEST(TestURLLoader, TrustedSameOriginRestriction, filter);
  142. RUN_CALLBACK_TEST(TestURLLoader, TrustedCrossOriginRequest, filter);
  143. RUN_CALLBACK_TEST(TestURLLoader, TrustedCorbEligibleRequest, filter);
  144. }
  145. std::string TestURLLoader::ReadEntireFile(pp::FileIO* file_io,
  146. std::string* data) {
  147. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  148. char buf[256];
  149. int64_t offset = 0;
  150. for (;;) {
  151. callback.WaitForResult(file_io->Read(offset, buf, sizeof(buf),
  152. callback.GetCallback()));
  153. if (callback.result() < 0)
  154. return ReportError("FileIO::Read", callback.result());
  155. if (callback.result() == 0)
  156. break;
  157. offset += callback.result();
  158. data->append(buf, callback.result());
  159. }
  160. PASS();
  161. }
  162. std::string TestURLLoader::ReadEntireResponseBody(pp::URLLoader* loader,
  163. std::string* body) {
  164. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  165. char buf[2]; // Small so that multiple reads are needed.
  166. for (;;) {
  167. callback.WaitForResult(
  168. loader->ReadResponseBody(buf, sizeof(buf), callback.GetCallback()));
  169. if (callback.result() < 0)
  170. return ReportError("URLLoader::ReadResponseBody", callback.result());
  171. if (callback.result() == 0)
  172. break;
  173. body->append(buf, callback.result());
  174. }
  175. PASS();
  176. }
  177. std::string TestURLLoader::LoadAndCompareBody(
  178. const pp::URLRequestInfo& request,
  179. const std::string& expected_body) {
  180. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  181. pp::URLLoader loader(instance_);
  182. callback.WaitForResult(loader.Open(request, callback.GetCallback()));
  183. CHECK_CALLBACK_BEHAVIOR(callback);
  184. ASSERT_EQ(PP_OK, callback.result());
  185. pp::URLResponseInfo response_info(loader.GetResponseInfo());
  186. if (response_info.is_null())
  187. return "URLLoader::GetResponseInfo returned null";
  188. int32_t status_code = response_info.GetStatusCode();
  189. if (status_code != 200)
  190. return "Unexpected HTTP status code";
  191. std::string body;
  192. std::string error = ReadEntireResponseBody(&loader, &body);
  193. if (!error.empty())
  194. return error;
  195. if (body.size() != expected_body.size())
  196. return "URLLoader::ReadResponseBody returned unexpected content length";
  197. if (body != expected_body)
  198. return "URLLoader::ReadResponseBody returned unexpected content";
  199. PASS();
  200. }
  201. std::string TestURLLoader::LoadAndFail(const pp::URLRequestInfo& request) {
  202. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  203. pp::URLLoader loader(instance_);
  204. callback.WaitForResult(loader.Open(request, callback.GetCallback()));
  205. CHECK_CALLBACK_BEHAVIOR(callback);
  206. ASSERT_EQ(PP_ERROR_FAILED, callback.result());
  207. PASS();
  208. }
  209. int32_t TestURLLoader::OpenFileSystem(pp::FileSystem* file_system,
  210. std::string* message) {
  211. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  212. callback.WaitForResult(file_system->Open(1024, callback.GetCallback()));
  213. if (callback.failed()) {
  214. message->assign(callback.errors());
  215. return callback.result();
  216. }
  217. if (callback.result() != PP_OK) {
  218. message->assign("FileSystem::Open");
  219. return callback.result();
  220. }
  221. return callback.result();
  222. }
  223. int32_t TestURLLoader::PrepareFileForPost(
  224. const pp::FileRef& file_ref,
  225. const std::string& data,
  226. std::string* message) {
  227. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  228. pp::FileIO file_io(instance_);
  229. callback.WaitForResult(file_io.Open(file_ref,
  230. PP_FILEOPENFLAG_CREATE |
  231. PP_FILEOPENFLAG_TRUNCATE |
  232. PP_FILEOPENFLAG_WRITE,
  233. callback.GetCallback()));
  234. if (callback.failed()) {
  235. message->assign(callback.errors());
  236. return callback.result();
  237. }
  238. if (callback.result() != PP_OK) {
  239. message->assign("FileIO::Open failed.");
  240. return callback.result();
  241. }
  242. int32_t rv = WriteEntireBuffer(instance_->pp_instance(), &file_io, 0, data,
  243. callback_type());
  244. if (rv != PP_OK) {
  245. message->assign("FileIO::Write failed.");
  246. return rv;
  247. }
  248. return rv;
  249. }
  250. std::string TestURLLoader::GetReachableAbsoluteURL(
  251. const std::string& file_name) {
  252. // Get the absolute page URL and replace the test case file name
  253. // with the given one.
  254. pp::Var document_url(
  255. pp::PASS_REF,
  256. testing_interface_->GetDocumentURL(instance_->pp_instance(),
  257. NULL));
  258. std::string url(document_url.AsString());
  259. std::string old_name("test_case.html");
  260. size_t index = url.find(old_name);
  261. ASSERT_NE(index, std::string::npos);
  262. url.replace(index, old_name.length(), file_name);
  263. return url;
  264. }
  265. std::string TestURLLoader::GetReachableCrossOriginURL(
  266. const std::string& file_name) {
  267. // Get an absolute URL and use it to construct a URL that will be
  268. // considered cross-origin by the CORS access control code, and yet be
  269. // reachable by the test server.
  270. std::string url = GetReachableAbsoluteURL(file_name);
  271. // Replace '127.0.0.1' with 'localhost'.
  272. std::string host("127.0.0.1");
  273. size_t index = url.find(host);
  274. ASSERT_NE(index, std::string::npos);
  275. url.replace(index, host.length(), "localhost");
  276. return url;
  277. }
  278. int32_t TestURLLoader::OpenUntrusted(const std::string& method,
  279. const std::string& header) {
  280. pp::URLRequestInfo request(instance_);
  281. request.SetURL("/echo");
  282. request.SetMethod(method);
  283. request.SetHeaders(header);
  284. return OpenUntrusted(request, NULL);
  285. }
  286. int32_t TestURLLoader::OpenTrusted(const std::string& method,
  287. const std::string& header) {
  288. pp::URLRequestInfo request(instance_);
  289. request.SetURL("/echo");
  290. request.SetMethod(method);
  291. request.SetHeaders(header);
  292. return OpenTrusted(request, NULL);
  293. }
  294. int32_t TestURLLoader::OpenUntrusted(const pp::URLRequestInfo& request,
  295. std::string* response_body) {
  296. return Open(request, false, response_body);
  297. }
  298. int32_t TestURLLoader::OpenTrusted(const pp::URLRequestInfo& request,
  299. std::string* response_body) {
  300. return Open(request, true, response_body);
  301. }
  302. int32_t TestURLLoader::Open(const pp::URLRequestInfo& request,
  303. bool trusted,
  304. std::string* response_body) {
  305. pp::URLLoader loader(instance_);
  306. if (trusted)
  307. url_loader_trusted_interface_->GrantUniversalAccess(loader.pp_resource());
  308. return OpenURLRequest(instance_->pp_instance(), &loader, request,
  309. callback_type(), response_body);
  310. }
  311. std::string TestURLLoader::TestBasicGET() {
  312. pp::URLRequestInfo request(instance_);
  313. request.SetURL("test_url_loader_data/hello.txt");
  314. return LoadAndCompareBody(request, "hello\n");
  315. }
  316. std::string TestURLLoader::TestBasicPOST() {
  317. pp::URLRequestInfo request(instance_);
  318. request.SetURL("/echo");
  319. request.SetMethod("POST");
  320. std::string postdata("postdata");
  321. request.AppendDataToBody(postdata.data(),
  322. static_cast<uint32_t>(postdata.length()));
  323. return LoadAndCompareBody(request, postdata);
  324. }
  325. std::string TestURLLoader::TestBasicFilePOST() {
  326. std::string message;
  327. pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  328. int32_t rv = OpenFileSystem(&file_system, &message);
  329. if (rv != PP_OK)
  330. return ReportError(message.c_str(), rv);
  331. pp::FileRef file_ref(file_system, "/file_post_test");
  332. std::string postdata("postdata");
  333. rv = PrepareFileForPost(file_ref, postdata, &message);
  334. if (rv != PP_OK)
  335. return ReportError(message.c_str(), rv);
  336. pp::URLRequestInfo request(instance_);
  337. request.SetURL("/echo");
  338. request.SetMethod("POST");
  339. request.AppendFileToBody(file_ref, 0);
  340. return LoadAndCompareBody(request, postdata);
  341. }
  342. std::string TestURLLoader::TestBasicFileRangePOST() {
  343. 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);
  348. pp::FileRef file_ref(file_system, "/file_range_post_test");
  349. std::string postdata("postdatapostdata");
  350. rv = PrepareFileForPost(file_ref, postdata, &message);
  351. if (rv != PP_OK)
  352. return ReportError(message.c_str(), rv);
  353. pp::URLRequestInfo request(instance_);
  354. request.SetURL("/echo");
  355. request.SetMethod("POST");
  356. request.AppendFileRangeToBody(file_ref, 4, 12, 0);
  357. return LoadAndCompareBody(request, postdata.substr(4, 12));
  358. }
  359. std::string TestURLLoader::TestCompoundBodyPOST() {
  360. pp::URLRequestInfo request(instance_);
  361. request.SetURL("/echo");
  362. request.SetMethod("POST");
  363. std::string postdata1("post");
  364. request.AppendDataToBody(postdata1.data(),
  365. static_cast<uint32_t>(postdata1.length()));
  366. std::string postdata2("data");
  367. request.AppendDataToBody(postdata2.data(),
  368. static_cast<uint32_t>(postdata2.length()));
  369. return LoadAndCompareBody(request, postdata1 + postdata2);
  370. }
  371. std::string TestURLLoader::TestEmptyDataPOST() {
  372. pp::URLRequestInfo request(instance_);
  373. request.SetURL("/echo");
  374. request.SetMethod("POST");
  375. request.AppendDataToBody("", 0);
  376. return LoadAndCompareBody(request, std::string());
  377. }
  378. std::string TestURLLoader::TestBinaryDataPOST() {
  379. pp::URLRequestInfo request(instance_);
  380. request.SetURL("/echo");
  381. request.SetMethod("POST");
  382. const char postdata_chars[] =
  383. "\x00\x01\x02\x03\x04\x05postdata\xfa\xfb\xfc\xfd\xfe\xff";
  384. std::string postdata(postdata_chars,
  385. sizeof(postdata_chars) / sizeof(postdata_chars[0]));
  386. request.AppendDataToBody(postdata.data(),
  387. static_cast<uint32_t>(postdata.length()));
  388. return LoadAndCompareBody(request, postdata);
  389. }
  390. std::string TestURLLoader::TestCustomRequestHeader() {
  391. pp::URLRequestInfo request(instance_);
  392. request.SetURL("/echoheader?Foo");
  393. request.SetHeaders("Foo: 1");
  394. return LoadAndCompareBody(request, "1");
  395. }
  396. std::string TestURLLoader::TestFailsBogusContentLength() {
  397. pp::URLRequestInfo request(instance_);
  398. request.SetURL("/echo");
  399. request.SetMethod("POST");
  400. request.SetHeaders("Content-Length: 400");
  401. std::string postdata("postdata");
  402. request.AppendDataToBody(postdata.data(),
  403. static_cast<uint32_t>(postdata.length()));
  404. int32_t rv;
  405. rv = OpenUntrusted(request, NULL);
  406. if (rv != PP_ERROR_NOACCESS)
  407. return ReportError(
  408. "Untrusted request with bogus Content-Length restriction", rv);
  409. PASS();
  410. }
  411. std::string TestURLLoader::TestStreamToFile() {
  412. pp::URLRequestInfo request(instance_);
  413. request.SetURL("test_url_loader_data/hello.txt");
  414. ASSERT_FALSE(request.SetStreamToFile(true));
  415. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  416. pp::URLLoader loader(instance_);
  417. callback.WaitForResult(loader.Open(request, callback.GetCallback()));
  418. CHECK_CALLBACK_BEHAVIOR(callback);
  419. ASSERT_EQ(PP_OK, callback.result());
  420. pp::URLResponseInfo response_info(loader.GetResponseInfo());
  421. if (response_info.is_null())
  422. return "URLLoader::GetResponseInfo returned null";
  423. int32_t status_code = response_info.GetStatusCode();
  424. if (status_code != 200)
  425. return "Unexpected HTTP status code";
  426. pp::FileRef body(response_info.GetBodyAsFileRef());
  427. ASSERT_TRUE(body.is_null());
  428. callback.WaitForResult(loader.FinishStreamingToFile(callback.GetCallback()));
  429. CHECK_CALLBACK_BEHAVIOR(callback);
  430. ASSERT_EQ(PP_ERROR_NOTSUPPORTED, callback.result());
  431. PASS();
  432. }
  433. // Untrusted, unintended cross-origin requests should fail.
  434. std::string TestURLLoader::TestUntrustedSameOriginRestriction() {
  435. pp::URLRequestInfo request(instance_);
  436. std::string cross_origin_url = GetReachableCrossOriginURL("test_case.html");
  437. request.SetURL(cross_origin_url);
  438. int32_t rv = OpenUntrusted(request, NULL);
  439. if (rv != PP_ERROR_NOACCESS)
  440. return ReportError(
  441. "Untrusted, unintended cross-origin request restriction", rv);
  442. PASS();
  443. }
  444. // Trusted, unintended cross-origin requests should succeed.
  445. std::string TestURLLoader::TestTrustedSameOriginRestriction() {
  446. pp::URLRequestInfo request(instance_);
  447. std::string cross_origin_url = GetReachableCrossOriginURL("test_case.html");
  448. request.SetURL(cross_origin_url);
  449. int32_t rv = OpenTrusted(request, NULL);
  450. if (rv != PP_OK)
  451. return ReportError("Trusted cross-origin request failed", rv);
  452. PASS();
  453. }
  454. // Untrusted, intended cross-origin requests should use CORS and succeed.
  455. std::string TestURLLoader::TestUntrustedCrossOriginRequest() {
  456. pp::URLRequestInfo request(instance_);
  457. std::string cross_origin_url = GetReachableCrossOriginURL("test_case.html");
  458. request.SetURL(cross_origin_url);
  459. request.SetAllowCrossOriginRequests(true);
  460. int32_t rv = OpenUntrusted(request, NULL);
  461. if (rv != PP_OK)
  462. return ReportError(
  463. "Untrusted, intended cross-origin request failed", rv);
  464. PASS();
  465. }
  466. // Trusted, intended cross-origin requests should use CORS and succeed.
  467. std::string TestURLLoader::TestTrustedCrossOriginRequest() {
  468. pp::URLRequestInfo request(instance_);
  469. std::string cross_origin_url = GetReachableCrossOriginURL("test_case.html");
  470. request.SetURL(cross_origin_url);
  471. request.SetAllowCrossOriginRequests(true);
  472. int32_t rv = OpenTrusted(request, NULL);
  473. if (rv != PP_OK)
  474. return ReportError("Trusted cross-origin request failed", rv);
  475. PASS();
  476. }
  477. // CORB (Cross-Origin Read Blocking) should apply to plugins without universal
  478. // access. This test is very similar to TestUntrustedSameOriginRestriction, but
  479. // explicitly uses a CORB-eligible response (test/json + nosniff).
  480. std::string TestURLLoader::TestUntrustedCorbEligibleRequest() {
  481. // It is important to use a CORB-eligible response here: text/json + nosniff.
  482. std::string cross_origin_url =
  483. GetReachableCrossOriginURL("corb_eligible_resource.json");
  484. pp::URLRequestInfo request(instance_);
  485. request.SetURL(cross_origin_url);
  486. request.SetAllowCrossOriginRequests(true);
  487. std::string response_body;
  488. int32_t rv = OpenUntrusted(request, &response_body);
  489. // Main verification - the response should be blocked. Ideally the blocking
  490. // should be done before the data leaves the browser and/or network-service
  491. // process (the test doesn't verify this though).
  492. if (rv != PP_ERROR_NOACCESS) {
  493. return ReportError("Untrusted Javascript URL request restriction failed",
  494. rv);
  495. }
  496. ASSERT_EQ("", response_body);
  497. PASS();
  498. }
  499. // CORB (Cross-Origin Read Blocking) should apply, even to plugins with
  500. // universal access like the PDF plugin.
  501. //
  502. // This test is quite similar to TestTrustedSameOriginRestriction, but it
  503. // explicitly uses a CORB-eligible response (test/json + nosniff) and also
  504. // explicitly verifies that the response body was not blocked.
  505. std::string TestURLLoader::TestTrustedCorbEligibleRequest() {
  506. // It is important to use a CORB-eligible response here: text/json + nosniff.
  507. std::string cross_origin_url =
  508. GetReachableCrossOriginURL("corb_eligible_resource.json");
  509. pp::URLRequestInfo request(instance_);
  510. request.SetURL(cross_origin_url);
  511. request.SetAllowCrossOriginRequests(true);
  512. // The test code below (similarly to the PDF plugin) sets the referrer - this
  513. // will propagate into network::ResourceRequest::request_initiator and should
  514. // match the NetworkService::AddAllowedRequestInitiatorForPlugin exemption.
  515. // This will pass `request_initiator_origin_lock` verification.
  516. std::string referrer = GetReachableAbsoluteURL("");
  517. request.SetCustomReferrerURL(referrer);
  518. request.SetHeaders(referrer);
  519. std::string response_body;
  520. int32_t rv = OpenTrusted(request, &response_body);
  521. if (rv != PP_OK)
  522. return ReportError("Trusted CORB-eligible request failed", rv);
  523. // Main verification - CORB should block the response where the
  524. // `request_initiator` is cross-origin wrt the target URL.
  525. //
  526. // Note that this case (and CORB blocking) does never apply to the PDF plugin,
  527. // because the PDF plugin only triggers requests where both
  528. // `request_initiator` and the target URL are based on the URL of the PDF
  529. // document (i.e. they are same-origin wrt each other).
  530. ASSERT_EQ("", response_body);
  531. PASS();
  532. }
  533. // Untrusted Javascript URLs requests should fail.
  534. std::string TestURLLoader::TestUntrustedJavascriptURLRestriction() {
  535. pp::URLRequestInfo request(instance_);
  536. request.SetURL("javascript:foo = bar");
  537. int32_t rv = OpenUntrusted(request, NULL);
  538. if (rv != PP_ERROR_NOACCESS)
  539. return ReportError(
  540. "Untrusted Javascript URL request restriction failed", rv);
  541. PASS();
  542. }
  543. // Trusted Javascript URLs requests should succeed.
  544. std::string TestURLLoader::TestTrustedJavascriptURLRestriction() {
  545. pp::URLRequestInfo request(instance_);
  546. request.SetURL("javascript:foo = bar");
  547. int32_t rv = OpenTrusted(request, NULL);
  548. if (rv == PP_ERROR_NOACCESS)
  549. return ReportError(
  550. "Trusted Javascript URL request", rv);
  551. PASS();
  552. }
  553. std::string TestURLLoader::TestUntrustedHttpRequests() {
  554. // HTTP methods are restricted only for untrusted loaders. Forbidden
  555. // methods are CONNECT, TRACE, and TRACK, and any string that is not a
  556. // valid token (containing special characters like CR, LF).
  557. // http://www.w3.org/TR/XMLHttpRequest/
  558. {
  559. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("cOnNeCt", std::string()));
  560. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("tRaCk", std::string()));
  561. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("tRaCe", std::string()));
  562. ASSERT_EQ(PP_ERROR_NOACCESS,
  563. OpenUntrusted("POST\x0d\x0ax-csrf-token:\x20test1234", std::string()));
  564. }
  565. // HTTP methods are restricted only for untrusted loaders. Try all headers
  566. // that are forbidden by http://www.w3.org/TR/XMLHttpRequest/.
  567. {
  568. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Accept-Charset:\n"));
  569. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Accept-Encoding:\n"));
  570. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Connection:\n"));
  571. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Content-Length:\n"));
  572. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Cookie:\n"));
  573. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Cookie2:\n"));
  574. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Date:\n"));
  575. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Dnt:\n"));
  576. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Expect:\n"));
  577. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Host:\n"));
  578. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Keep-Alive:\n"));
  579. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Referer:\n"));
  580. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "TE:\n"));
  581. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Trailer:\n"));
  582. ASSERT_EQ(PP_ERROR_NOACCESS,
  583. OpenUntrusted("GET", "Transfer-Encoding:\n"));
  584. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Upgrade:\n"));
  585. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "User-Agent:\n"));
  586. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Via:\n"));
  587. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted(
  588. "GET", "Proxy-Authorization: Basic dXNlcjpwYXNzd29yZA==:\n"));
  589. ASSERT_EQ(PP_ERROR_NOACCESS, OpenUntrusted("GET", "Sec-foo:\n"));
  590. }
  591. // Untrusted requests with custom referrer should fail.
  592. {
  593. pp::URLRequestInfo request(instance_);
  594. request.SetCustomReferrerURL("http://www.google.com/");
  595. int32_t rv = OpenUntrusted(request, NULL);
  596. if (rv != PP_ERROR_NOACCESS)
  597. return ReportError(
  598. "Untrusted request with custom referrer restriction", rv);
  599. }
  600. // Untrusted requests with custom transfer encodings should fail.
  601. {
  602. pp::URLRequestInfo request(instance_);
  603. request.SetCustomContentTransferEncoding("foo");
  604. int32_t rv = OpenUntrusted(request, NULL);
  605. if (rv != PP_ERROR_NOACCESS)
  606. return ReportError(
  607. "Untrusted request with content-transfer-encoding restriction", rv);
  608. }
  609. PASS();
  610. }
  611. std::string TestURLLoader::TestTrustedHttpRequests() {
  612. // Trusted requests can use restricted methods, other than CONNECT, which gets
  613. // sockets into a problematic state.
  614. {
  615. ASSERT_EQ(PP_OK, OpenTrusted("tRaCk", std::string()));
  616. ASSERT_EQ(PP_OK, OpenTrusted("tRaCe", std::string()));
  617. }
  618. // Trusted requests can use restricted headers.
  619. {
  620. ASSERT_EQ(PP_OK, OpenTrusted("GET", "Accept-Charset:\n"));
  621. ASSERT_EQ(PP_OK, OpenTrusted("GET", "Accept-Encoding:\n"));
  622. ASSERT_EQ(PP_OK, OpenTrusted("GET", "Connection:\n"));
  623. ASSERT_EQ(PP_OK, OpenTrusted("GET", "Cookie:\n"));
  624. ASSERT_EQ(PP_OK, OpenTrusted("GET", "Date:\n"));
  625. ASSERT_EQ(PP_OK, OpenTrusted("GET", "DNT:\n"));
  626. ASSERT_EQ(PP_OK, OpenTrusted("GET", "Expect:\n"));
  627. // Host header is still forbidden because it can conflict with specific URL.
  628. ASSERT_EQ(PP_OK, OpenTrusted("GET", "Referer:\n"));
  629. ASSERT_EQ(PP_OK, OpenTrusted("GET", "User-Agent:\n"));
  630. ASSERT_EQ(PP_OK, OpenTrusted("GET", "Via:\n"));
  631. ASSERT_EQ(PP_OK, OpenTrusted("GET", "Sec-foo:\n"));
  632. }
  633. // Trusted requests with custom referrer should succeed. Note that the
  634. // referrer has to be from the same origin as the plugin (this matches the
  635. // behavior of the PDF plugin, which after Flash removal is the only plugin
  636. // that depends on custom referrers).
  637. {
  638. pp::URLRequestInfo request(instance_);
  639. std::string referrer = GetReachableAbsoluteURL("");
  640. request.SetCustomReferrerURL(referrer);
  641. request.SetHeaders(referrer);
  642. int32_t rv = OpenTrusted(request, NULL);
  643. if (rv != PP_OK)
  644. return ReportError("Trusted request with custom referrer", rv);
  645. }
  646. // Trusted requests with custom transfer encodings should succeed.
  647. {
  648. pp::URLRequestInfo request(instance_);
  649. request.SetCustomContentTransferEncoding("foo");
  650. int32_t rv = OpenTrusted(request, NULL);
  651. if (rv != PP_OK)
  652. return ReportError(
  653. "Trusted request with content-transfer-encoding failed", rv);
  654. }
  655. PASS();
  656. }
  657. // This test should cause a redirect and ensure that the loader follows it.
  658. std::string TestURLLoader::TestFollowURLRedirect() {
  659. pp::URLRequestInfo request(instance_);
  660. // This prefix causes the test server to return a 301 redirect.
  661. std::string redirect_prefix("/server-redirect?");
  662. // We need an absolute path for the redirect to actually work.
  663. std::string redirect_url =
  664. GetReachableAbsoluteURL("test_url_loader_data/hello.txt");
  665. request.SetURL(redirect_prefix.append(redirect_url));
  666. return LoadAndCompareBody(request, "hello\n");
  667. }
  668. // This test should cause a redirect and ensure that the loader runs
  669. // the callback, rather than following the redirect.
  670. std::string TestURLLoader::TestAuditURLRedirect() {
  671. pp::URLRequestInfo request(instance_);
  672. // This path will cause the server to return a 301 redirect.
  673. // This prefix causes the test server to return a 301 redirect.
  674. std::string redirect_prefix("/server-redirect?");
  675. // We need an absolute path for the redirect to actually work.
  676. std::string redirect_url =
  677. GetReachableAbsoluteURL("test_url_loader_data/hello.txt");
  678. request.SetURL(redirect_prefix.append(redirect_url));
  679. request.SetFollowRedirects(false);
  680. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  681. pp::URLLoader loader(instance_);
  682. callback.WaitForResult(loader.Open(request, callback.GetCallback()));
  683. CHECK_CALLBACK_BEHAVIOR(callback);
  684. ASSERT_EQ(PP_OK, callback.result());
  685. // Checks that the response indicates a redirect, and that the URL
  686. // is correct.
  687. pp::URLResponseInfo response_info(loader.GetResponseInfo());
  688. if (response_info.is_null())
  689. return "URLLoader::GetResponseInfo returned null";
  690. int32_t status_code = response_info.GetStatusCode();
  691. if (status_code != 301)
  692. return "Response status should be 301";
  693. // Test that the paused loader can be resumed.
  694. callback.WaitForResult(loader.FollowRedirect(callback.GetCallback()));
  695. CHECK_CALLBACK_BEHAVIOR(callback);
  696. ASSERT_EQ(PP_OK, callback.result());
  697. std::string body;
  698. std::string error = ReadEntireResponseBody(&loader, &body);
  699. if (!error.empty())
  700. return error;
  701. if (body != "hello\n")
  702. return "URLLoader::FollowRedirect failed";
  703. PASS();
  704. }
  705. // This test checks if the redirect restriction does not block acceptable cases
  706. // of 307/308 GET and HEAD.
  707. std::string TestURLLoader::TestRestrictURLRedirectCommon() {
  708. std::string url = GetReachableAbsoluteURL("test_url_loader_data/hello.txt");
  709. std::string redirect_307_prefix("/server-redirect-307?");
  710. {
  711. // Default method is GET and will follow the redirect.
  712. pp::URLRequestInfo request_for_default_307(instance_);
  713. request_for_default_307.SetURL(redirect_307_prefix.append(url));
  714. std::string result_for_default_307 =
  715. LoadAndCompareBody(request_for_default_307, "hello\n");
  716. if (!result_for_default_307.empty())
  717. return result_for_default_307;
  718. }
  719. {
  720. // GET will follow the redirect.
  721. pp::URLRequestInfo request_for_get_307(instance_);
  722. request_for_get_307.SetURL(redirect_307_prefix.append(url));
  723. request_for_get_307.SetMethod("GET");
  724. std::string result_for_get_307 =
  725. LoadAndCompareBody(request_for_get_307, "hello\n");
  726. if (!result_for_get_307.empty())
  727. return result_for_get_307;
  728. }
  729. {
  730. // HEAD will follow the redirect.
  731. pp::URLRequestInfo request_for_head_307(instance_);
  732. request_for_head_307.SetURL(redirect_307_prefix.append(url));
  733. request_for_head_307.SetMethod("HEAD");
  734. std::string result_for_head_307 =
  735. LoadAndCompareBody(request_for_head_307, "");
  736. if (!result_for_head_307.empty())
  737. return result_for_head_307;
  738. }
  739. std::string redirect_308_prefix("/server-redirect-308?");
  740. {
  741. // Default method is GET and will follow the redirect.
  742. pp::URLRequestInfo request_for_default_308(instance_);
  743. request_for_default_308.SetURL(redirect_308_prefix.append(url));
  744. std::string result_for_default_308 =
  745. LoadAndCompareBody(request_for_default_308, "hello\n");
  746. if (!result_for_default_308.empty())
  747. return result_for_default_308;
  748. }
  749. {
  750. // GET will follow the redirect.
  751. pp::URLRequestInfo request_for_get_308(instance_);
  752. request_for_get_308.SetURL(redirect_308_prefix.append(url));
  753. request_for_get_308.SetMethod("GET");
  754. std::string result_for_get_308 =
  755. LoadAndCompareBody(request_for_get_308, "hello\n");
  756. if (!result_for_get_308.empty())
  757. return result_for_get_308;
  758. }
  759. {
  760. // HEAD will follow the redirect.
  761. pp::URLRequestInfo request_for_head_308(instance_);
  762. request_for_head_308.SetURL(redirect_308_prefix.append(url));
  763. request_for_head_308.SetMethod("HEAD");
  764. std::string result_for_head_308 =
  765. LoadAndCompareBody(request_for_head_308, "");
  766. if (!result_for_head_308.empty())
  767. return result_for_head_308;
  768. }
  769. PASS();
  770. }
  771. // This test checks if the redirect restriction blocks the restricted cases of
  772. // 307/308 POST.
  773. std::string TestURLLoader::TestRestrictURLRedirectEnabled() {
  774. std::string url = GetReachableAbsoluteURL("test_url_loader_data/hello.txt");
  775. {
  776. // POST will be blocked and fail.
  777. std::string redirect_307_prefix("/server-redirect-307?");
  778. pp::URLRequestInfo request_for_post_307(instance_);
  779. request_for_post_307.SetURL(redirect_307_prefix.append(url));
  780. request_for_post_307.SetMethod("POST");
  781. std::string result_for_post_307 = LoadAndFail(request_for_post_307);
  782. if (!result_for_post_307.empty())
  783. return result_for_post_307;
  784. }
  785. {
  786. // POST will be blocked and fail.
  787. pp::URLRequestInfo request_for_post_308(instance_);
  788. std::string redirect_308_prefix("/server-redirect-308?");
  789. request_for_post_308.SetURL(redirect_308_prefix.append(url));
  790. request_for_post_308.SetMethod("POST");
  791. std::string result_for_post_308 = LoadAndFail(request_for_post_308);
  792. if (!result_for_post_308.empty())
  793. return result_for_post_308;
  794. }
  795. PASS();
  796. }
  797. // This test checks if the redirect restriction does not block the restricted
  798. // cases if the restriction is disabled.
  799. std::string TestURLLoader::TestRestrictURLRedirectDisabled() {
  800. std::string url = GetReachableAbsoluteURL("test_url_loader_data/hello.txt");
  801. {
  802. // POST will not be blocked, but follow the redirect.
  803. std::string redirect_307_prefix("/server-redirect-307?");
  804. pp::URLRequestInfo request_for_post_307(instance_);
  805. request_for_post_307.SetURL(redirect_307_prefix.append(url));
  806. request_for_post_307.SetMethod("POST");
  807. std::string result_for_post_307 =
  808. LoadAndCompareBody(request_for_post_307, "hello\n");
  809. if (!result_for_post_307.empty())
  810. return result_for_post_307;
  811. }
  812. {
  813. // POST will not be blocked, but follow the redirect.
  814. pp::URLRequestInfo request_for_post_308(instance_);
  815. std::string redirect_308_prefix("/server-redirect-308?");
  816. request_for_post_308.SetURL(redirect_308_prefix.append(url));
  817. request_for_post_308.SetMethod("POST");
  818. std::string result_for_post_308 =
  819. LoadAndCompareBody(request_for_post_308, "hello\n");
  820. if (!result_for_post_308.empty())
  821. return result_for_post_308;
  822. }
  823. PASS();
  824. }
  825. std::string TestURLLoader::TestAbortCalls() {
  826. pp::URLRequestInfo request(instance_);
  827. request.SetURL("test_url_loader_data/hello.txt");
  828. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  829. int32_t rv;
  830. // Abort |Open()|.
  831. {
  832. rv = pp::URLLoader(instance_).Open(request, callback.GetCallback());
  833. }
  834. callback.WaitForAbortResult(rv);
  835. CHECK_CALLBACK_BEHAVIOR(callback);
  836. // Abort |ReadResponseBody()|.
  837. {
  838. char buf[2] = { 0 };
  839. {
  840. pp::URLLoader loader(instance_);
  841. callback.WaitForResult(loader.Open(request, callback.GetCallback()));
  842. CHECK_CALLBACK_BEHAVIOR(callback);
  843. ASSERT_EQ(PP_OK, callback.result());
  844. rv = loader.ReadResponseBody(buf, sizeof(buf), callback.GetCallback());
  845. } // Destroy |loader|.
  846. callback.WaitForAbortResult(rv);
  847. CHECK_CALLBACK_BEHAVIOR(callback);
  848. if (rv == PP_OK_COMPLETIONPENDING) {
  849. if (buf[0] || buf[1]) {
  850. return "URLLoader::ReadResponseBody wrote data after resource "
  851. "destruction.";
  852. }
  853. }
  854. }
  855. // TODO(viettrungluu): More abort tests (but add basic tests first).
  856. // Also test that Close() aborts properly. crbug.com/69457
  857. PASS();
  858. }
  859. std::string TestURLLoader::TestUntendedLoad() {
  860. pp::URLRequestInfo request(instance_);
  861. request.SetURL("test_url_loader_data/hello.txt");
  862. request.SetRecordDownloadProgress(true);
  863. TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  864. pp::URLLoader loader(instance_);
  865. callback.WaitForResult(loader.Open(request, callback.GetCallback()));
  866. CHECK_CALLBACK_BEHAVIOR(callback);
  867. ASSERT_EQ(PP_OK, callback.result());
  868. // We received the response callback. Yield until the network code has called
  869. // the loader's didReceiveData and didFinishLoading methods before we give it
  870. // another callback function, to make sure the loader works with no callback.
  871. int64_t bytes_received = 0;
  872. int64_t total_bytes_to_be_received = 0;
  873. while (true) {
  874. loader.GetDownloadProgress(&bytes_received, &total_bytes_to_be_received);
  875. if (total_bytes_to_be_received <= 0)
  876. return ReportError("URLLoader::GetDownloadProgress total size",
  877. static_cast<int32_t>(total_bytes_to_be_received));
  878. if (bytes_received == total_bytes_to_be_received)
  879. break;
  880. // Yield if we're on the main thread, so that URLLoader can receive more
  881. // data.
  882. if (pp::Module::Get()->core()->IsMainThread()) {
  883. NestedEvent event(instance_->pp_instance());
  884. event.PostSignal(10);
  885. event.Wait();
  886. }
  887. }
  888. // The loader should now have the data and have finished successfully.
  889. std::string body;
  890. std::string error = ReadEntireResponseBody(&loader, &body);
  891. if (!error.empty())
  892. return error;
  893. if (body != "hello\n")
  894. return ReportError("Couldn't read data", callback.result());
  895. PASS();
  896. }
  897. int32_t TestURLLoader::OpenWithPrefetchBufferThreshold(int32_t lower,
  898. int32_t upper) {
  899. pp::URLRequestInfo request(instance_);
  900. request.SetURL("test_url_loader_data/hello.txt");
  901. request.SetPrefetchBufferLowerThreshold(lower);
  902. request.SetPrefetchBufferUpperThreshold(upper);
  903. return OpenUntrusted(request, NULL);
  904. }
  905. std::string TestURLLoader::TestPrefetchBufferThreshold() {
  906. int32_t rv = OpenWithPrefetchBufferThreshold(-1, 1);
  907. if (rv != PP_ERROR_FAILED) {
  908. return ReportError("The prefetch limits contained a negative value but "
  909. "the URLLoader did not fail.", rv);
  910. }
  911. rv = OpenWithPrefetchBufferThreshold(0, 1);
  912. if (rv != PP_OK) {
  913. return ReportError("The prefetch buffer limits were legal values but "
  914. "the URLLoader failed.", rv);
  915. }
  916. rv = OpenWithPrefetchBufferThreshold(1000, 1);
  917. if (rv != PP_ERROR_FAILED) {
  918. return ReportError("The lower buffer value was higher than the upper but "
  919. "the URLLoader did not fail.", rv);
  920. }
  921. PASS();
  922. }
  923. // TODO(viettrungluu): This test properly belongs elsewhere. It tests that
  924. // Chrome properly tags URL requests made on behalf of Pepper plugins (with an
  925. // X-Requested-With header), but this isn't, strictly speaking, a PPAPI
  926. // behavior.
  927. std::string TestURLLoader::TestXRequestedWithHeader() {
  928. pp::URLRequestInfo request(instance_);
  929. request.SetURL("/echoheader?X-Requested-With");
  930. // The name and version of the plugin is set from the command-line (see
  931. // chrome/test/ppapi/ppapi_test.cc.
  932. return LoadAndCompareBody(request, "PPAPITests/1.2.3");
  933. }
  934. // TODO(viettrungluu): Add tests for Get{Upload,Download}Progress, Close
  935. // (including abort tests if applicable).