Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: third_party/WebKit/Source/web/AssociatedURLLoaderTest.cpp

Issue 2399463007: AssociatedURLLoader shouldn't derive from WebURLLoader (Closed)
Patch Set: Rebase Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2011 Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "platform/testing/URLTestHelpers.h"
32 #include "platform/testing/UnitTestHelpers.h"
33 #include "public/platform/Platform.h"
34 #include "public/platform/WebString.h"
35 #include "public/platform/WebThread.h"
36 #include "public/platform/WebURL.h"
37 #include "public/platform/WebURLLoader.h"
38 #include "public/platform/WebURLLoaderClient.h"
39 #include "public/platform/WebURLLoaderMockFactory.h"
40 #include "public/platform/WebURLRequest.h"
41 #include "public/platform/WebURLResponse.h"
42 #include "public/web/WebCache.h"
43 #include "public/web/WebFrame.h"
44 #include "public/web/WebURLLoaderOptions.h"
45 #include "public/web/WebView.h"
46 #include "testing/gtest/include/gtest/gtest.h"
47 #include "web/tests/FrameTestHelpers.h"
48 #include "wtf/PtrUtil.h"
49 #include "wtf/text/CString.h"
50 #include "wtf/text/WTFString.h"
51 #include <memory>
52
53 using blink::URLTestHelpers::toKURL;
54 using blink::testing::runPendingTasks;
55
56 namespace blink {
57
58 class AssociatedURLLoaderTest : public ::testing::Test,
59 public WebURLLoaderClient {
60 public:
61 AssociatedURLLoaderTest()
62 : m_willFollowRedirect(false),
63 m_didSendData(false),
64 m_didReceiveResponse(false),
65 m_didReceiveData(false),
66 m_didReceiveCachedMetadata(false),
67 m_didFinishLoading(false),
68 m_didFail(false) {
69 // Reuse one of the test files from WebFrameTest.
70 m_baseFilePath = testing::blinkRootDir();
71 m_baseFilePath.append("/Source/web/tests/data/");
72 m_frameFilePath = m_baseFilePath;
73 m_frameFilePath.append("iframes_test.html");
74 }
75
76 KURL RegisterMockedUrl(const std::string& urlRoot,
77 const WTF::String& filename) {
78 WebURLResponse response;
79 response.setMIMEType("text/html");
80 WTF::String localPath = m_baseFilePath;
81 localPath.append(filename);
82 KURL url = toKURL(urlRoot + filename.utf8().data());
83 Platform::current()->getURLLoaderMockFactory()->registerURL(url, response,
84 localPath);
85 return url;
86 }
87
88 void SetUp() override {
89 m_helper.initialize();
90
91 std::string urlRoot = "http://www.test.com/";
92 KURL url = RegisterMockedUrl(urlRoot, "iframes_test.html");
93 const char* iframeSupportFiles[] = {
94 "invisible_iframe.html", "visible_iframe.html",
95 "zero_sized_iframe.html",
96 };
97 for (size_t i = 0; i < WTF_ARRAY_LENGTH(iframeSupportFiles); ++i) {
98 RegisterMockedUrl(urlRoot, iframeSupportFiles[i]);
99 }
100
101 FrameTestHelpers::loadFrame(mainFrame(), url.getString().utf8().data());
102
103 Platform::current()->getURLLoaderMockFactory()->unregisterURL(url);
104 }
105
106 void TearDown() override {
107 Platform::current()->getURLLoaderMockFactory()->unregisterAllURLs();
108 WebCache::clear();
109 }
110
111 void serveRequests() {
112 Platform::current()->getURLLoaderMockFactory()->serveAsynchronousRequests();
113 }
114
115 std::unique_ptr<WebURLLoader> createAssociatedURLLoader(
116 const WebURLLoaderOptions options = WebURLLoaderOptions()) {
117 return wrapUnique(mainFrame()->createAssociatedURLLoader(options));
118 }
119
120 // WebURLLoaderClient implementation.
121 bool willFollowRedirect(WebURLLoader* loader,
122 WebURLRequest& newRequest,
123 const WebURLResponse& redirectResponse) override {
124 m_willFollowRedirect = true;
125 EXPECT_EQ(m_expectedLoader.get(), loader);
126 EXPECT_EQ(m_expectedNewRequest.url(), newRequest.url());
127 // Check that CORS simple headers are transferred to the new request.
128 EXPECT_EQ(m_expectedNewRequest.httpHeaderField("accept"),
129 newRequest.httpHeaderField("accept"));
130 EXPECT_EQ(m_expectedRedirectResponse.url(), redirectResponse.url());
131 EXPECT_EQ(m_expectedRedirectResponse.httpStatusCode(),
132 redirectResponse.httpStatusCode());
133 EXPECT_EQ(m_expectedRedirectResponse.mimeType(),
134 redirectResponse.mimeType());
135 return true;
136 }
137
138 void didSendData(WebURLLoader* loader,
139 unsigned long long bytesSent,
140 unsigned long long totalBytesToBeSent) override {
141 m_didSendData = true;
142 EXPECT_EQ(m_expectedLoader.get(), loader);
143 }
144
145 void didReceiveResponse(WebURLLoader* loader,
146 const WebURLResponse& response) override {
147 m_didReceiveResponse = true;
148 m_actualResponse = WebURLResponse(response);
149 EXPECT_EQ(m_expectedLoader.get(), loader);
150 EXPECT_EQ(m_expectedResponse.url(), response.url());
151 EXPECT_EQ(m_expectedResponse.httpStatusCode(), response.httpStatusCode());
152 }
153
154 void didDownloadData(WebURLLoader* loader,
155 int dataLength,
156 int encodedDataLength) override {
157 m_didDownloadData = true;
158 EXPECT_EQ(m_expectedLoader.get(), loader);
159 }
160
161 void didReceiveData(WebURLLoader* loader,
162 const char* data,
163 int dataLength,
164 int encodedDataLength,
165 int encodedBodyLength) override {
166 m_didReceiveData = true;
167 EXPECT_EQ(m_expectedLoader.get(), loader);
168 EXPECT_TRUE(data);
169 EXPECT_GT(dataLength, 0);
170 }
171
172 void didReceiveCachedMetadata(WebURLLoader* loader,
173 const char* data,
174 int dataLength) override {
175 m_didReceiveCachedMetadata = true;
176 EXPECT_EQ(m_expectedLoader.get(), loader);
177 }
178
179 void didFinishLoading(WebURLLoader* loader,
180 double finishTime,
181 int64_t encodedDataLength) override {
182 m_didFinishLoading = true;
183 EXPECT_EQ(m_expectedLoader.get(), loader);
184 }
185
186 void didFail(WebURLLoader* loader, const WebURLError& error) override {
187 m_didFail = true;
188 EXPECT_EQ(m_expectedLoader.get(), loader);
189 }
190
191 void CheckMethodFails(const char* unsafeMethod) {
192 WebURLRequest request;
193 request.setURL(toKURL("http://www.test.com/success.html"));
194 request.setHTTPMethod(WebString::fromUTF8(unsafeMethod));
195 WebURLLoaderOptions options;
196 options.untrustedHTTP = true;
197 CheckFails(request, options);
198 }
199
200 void CheckHeaderFails(const char* headerField) {
201 CheckHeaderFails(headerField, "foo");
202 }
203
204 void CheckHeaderFails(const char* headerField, const char* headerValue) {
205 WebURLRequest request;
206 request.setURL(toKURL("http://www.test.com/success.html"));
207 if (equalIgnoringASCIICase(WebString::fromUTF8(headerField), "referer"))
208 request.setHTTPReferrer(WebString::fromUTF8(headerValue),
209 WebReferrerPolicyDefault);
210 else
211 request.setHTTPHeaderField(WebString::fromUTF8(headerField),
212 WebString::fromUTF8(headerValue));
213 WebURLLoaderOptions options;
214 options.untrustedHTTP = true;
215 CheckFails(request, options);
216 }
217
218 void CheckFails(const WebURLRequest& request,
219 WebURLLoaderOptions options = WebURLLoaderOptions()) {
220 m_expectedLoader = createAssociatedURLLoader(options);
221 EXPECT_TRUE(m_expectedLoader);
222 m_didFail = false;
223 m_expectedLoader->loadAsynchronously(request, this);
224 // Failure should not be reported synchronously.
225 EXPECT_FALSE(m_didFail);
226 // Allow the loader to return the error.
227 runPendingTasks();
228 EXPECT_TRUE(m_didFail);
229 EXPECT_FALSE(m_didReceiveResponse);
230 }
231
232 bool CheckAccessControlHeaders(const char* headerName, bool exposed) {
233 std::string id("http://www.other.com/CheckAccessControlExposeHeaders_");
234 id.append(headerName);
235 if (exposed)
236 id.append("-Exposed");
237 id.append(".html");
238
239 KURL url = toKURL(id);
240 WebURLRequest request;
241 request.setURL(url);
242
243 WebString headerNameString(WebString::fromUTF8(headerName));
244 m_expectedResponse = WebURLResponse();
245 m_expectedResponse.setMIMEType("text/html");
246 m_expectedResponse.setHTTPStatusCode(200);
247 m_expectedResponse.addHTTPHeaderField("Access-Control-Allow-Origin", "*");
248 if (exposed)
249 m_expectedResponse.addHTTPHeaderField("access-control-expose-headers",
250 headerNameString);
251 m_expectedResponse.addHTTPHeaderField(headerNameString, "foo");
252 Platform::current()->getURLLoaderMockFactory()->registerURL(
253 url, m_expectedResponse, m_frameFilePath);
254
255 WebURLLoaderOptions options;
256 options.crossOriginRequestPolicy =
257 WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
258 m_expectedLoader = createAssociatedURLLoader(options);
259 EXPECT_TRUE(m_expectedLoader);
260 m_expectedLoader->loadAsynchronously(request, this);
261 serveRequests();
262 EXPECT_TRUE(m_didReceiveResponse);
263 EXPECT_TRUE(m_didReceiveData);
264 EXPECT_TRUE(m_didFinishLoading);
265
266 return !m_actualResponse.httpHeaderField(headerNameString).isEmpty();
267 }
268
269 WebFrame* mainFrame() const { return m_helper.webView()->mainFrame(); }
270
271 protected:
272 String m_baseFilePath;
273 String m_frameFilePath;
274 FrameTestHelpers::WebViewHelper m_helper;
275
276 std::unique_ptr<WebURLLoader> m_expectedLoader;
277 WebURLResponse m_actualResponse;
278 WebURLResponse m_expectedResponse;
279 WebURLRequest m_expectedNewRequest;
280 WebURLResponse m_expectedRedirectResponse;
281 bool m_willFollowRedirect;
282 bool m_didSendData;
283 bool m_didReceiveResponse;
284 bool m_didDownloadData;
285 bool m_didReceiveData;
286 bool m_didReceiveCachedMetadata;
287 bool m_didFinishLoading;
288 bool m_didFail;
289 };
290
291 // Test a successful same-origin URL load.
292 TEST_F(AssociatedURLLoaderTest, SameOriginSuccess) {
293 KURL url = toKURL("http://www.test.com/SameOriginSuccess.html");
294 WebURLRequest request;
295 request.setURL(url);
296
297 m_expectedResponse = WebURLResponse();
298 m_expectedResponse.setMIMEType("text/html");
299 m_expectedResponse.setHTTPStatusCode(200);
300 Platform::current()->getURLLoaderMockFactory()->registerURL(
301 url, m_expectedResponse, m_frameFilePath);
302
303 m_expectedLoader = createAssociatedURLLoader();
304 EXPECT_TRUE(m_expectedLoader);
305 m_expectedLoader->loadAsynchronously(request, this);
306 serveRequests();
307 EXPECT_TRUE(m_didReceiveResponse);
308 EXPECT_TRUE(m_didReceiveData);
309 EXPECT_TRUE(m_didFinishLoading);
310 }
311
312 // Test that the same-origin restriction is the default.
313 TEST_F(AssociatedURLLoaderTest, SameOriginRestriction) {
314 // This is cross-origin since the frame was loaded from www.test.com.
315 KURL url = toKURL("http://www.other.com/SameOriginRestriction.html");
316 WebURLRequest request;
317 request.setURL(url);
318 CheckFails(request);
319 }
320
321 // Test a successful cross-origin load.
322 TEST_F(AssociatedURLLoaderTest, CrossOriginSuccess) {
323 // This is cross-origin since the frame was loaded from www.test.com.
324 KURL url = toKURL("http://www.other.com/CrossOriginSuccess");
325 WebURLRequest request;
326 request.setURL(url);
327 // No-CORS requests (CrossOriginRequestPolicyAllow) aren't allowed for the
328 // default context. So we set the context as Script here.
329 request.setRequestContext(WebURLRequest::RequestContextScript);
330
331 m_expectedResponse = WebURLResponse();
332 m_expectedResponse.setMIMEType("text/html");
333 m_expectedResponse.setHTTPStatusCode(200);
334 Platform::current()->getURLLoaderMockFactory()->registerURL(
335 url, m_expectedResponse, m_frameFilePath);
336
337 WebURLLoaderOptions options;
338 options.crossOriginRequestPolicy =
339 WebURLLoaderOptions::CrossOriginRequestPolicyAllow;
340 m_expectedLoader = createAssociatedURLLoader(options);
341 EXPECT_TRUE(m_expectedLoader);
342 m_expectedLoader->loadAsynchronously(request, this);
343 serveRequests();
344 EXPECT_TRUE(m_didReceiveResponse);
345 EXPECT_TRUE(m_didReceiveData);
346 EXPECT_TRUE(m_didFinishLoading);
347 }
348
349 // Test a successful cross-origin load using CORS.
350 TEST_F(AssociatedURLLoaderTest, CrossOriginWithAccessControlSuccess) {
351 // This is cross-origin since the frame was loaded from www.test.com.
352 KURL url =
353 toKURL("http://www.other.com/CrossOriginWithAccessControlSuccess.html");
354 WebURLRequest request;
355 request.setURL(url);
356
357 m_expectedResponse = WebURLResponse();
358 m_expectedResponse.setMIMEType("text/html");
359 m_expectedResponse.setHTTPStatusCode(200);
360 m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
361 Platform::current()->getURLLoaderMockFactory()->registerURL(
362 url, m_expectedResponse, m_frameFilePath);
363
364 WebURLLoaderOptions options;
365 options.crossOriginRequestPolicy =
366 WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
367 m_expectedLoader = createAssociatedURLLoader(options);
368 EXPECT_TRUE(m_expectedLoader);
369 m_expectedLoader->loadAsynchronously(request, this);
370 serveRequests();
371 EXPECT_TRUE(m_didReceiveResponse);
372 EXPECT_TRUE(m_didReceiveData);
373 EXPECT_TRUE(m_didFinishLoading);
374 }
375
376 // Test an unsuccessful cross-origin load using CORS.
377 TEST_F(AssociatedURLLoaderTest, CrossOriginWithAccessControlFailure) {
378 // This is cross-origin since the frame was loaded from www.test.com.
379 KURL url =
380 toKURL("http://www.other.com/CrossOriginWithAccessControlFailure.html");
381 WebURLRequest request;
382 request.setURL(url);
383
384 m_expectedResponse = WebURLResponse();
385 m_expectedResponse.setMIMEType("text/html");
386 m_expectedResponse.setHTTPStatusCode(200);
387 m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
388 Platform::current()->getURLLoaderMockFactory()->registerURL(
389 url, m_expectedResponse, m_frameFilePath);
390
391 WebURLLoaderOptions options;
392 // Send credentials. This will cause the CORS checks to fail, because
393 // credentials can't be sent to a server which returns the header
394 // "access-control-allow-origin" with "*" as its value.
395 options.allowCredentials = true;
396 options.crossOriginRequestPolicy =
397 WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
398 m_expectedLoader = createAssociatedURLLoader(options);
399 EXPECT_TRUE(m_expectedLoader);
400 m_expectedLoader->loadAsynchronously(request, this);
401
402 // Failure should not be reported synchronously.
403 EXPECT_FALSE(m_didFail);
404 // The loader needs to receive the response, before doing the CORS check.
405 serveRequests();
406 EXPECT_TRUE(m_didFail);
407 EXPECT_FALSE(m_didReceiveResponse);
408 }
409
410 // Test an unsuccessful cross-origin load using CORS.
411 TEST_F(AssociatedURLLoaderTest,
412 CrossOriginWithAccessControlFailureBadStatusCode) {
413 // This is cross-origin since the frame was loaded from www.test.com.
414 KURL url =
415 toKURL("http://www.other.com/CrossOriginWithAccessControlFailure.html");
416 WebURLRequest request;
417 request.setURL(url);
418
419 m_expectedResponse = WebURLResponse();
420 m_expectedResponse.setMIMEType("text/html");
421 m_expectedResponse.setHTTPStatusCode(0);
422 m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
423 Platform::current()->getURLLoaderMockFactory()->registerURL(
424 url, m_expectedResponse, m_frameFilePath);
425
426 WebURLLoaderOptions options;
427 options.crossOriginRequestPolicy =
428 WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
429 m_expectedLoader = createAssociatedURLLoader(options);
430 EXPECT_TRUE(m_expectedLoader);
431 m_expectedLoader->loadAsynchronously(request, this);
432
433 // Failure should not be reported synchronously.
434 EXPECT_FALSE(m_didFail);
435 // The loader needs to receive the response, before doing the CORS check.
436 serveRequests();
437 EXPECT_TRUE(m_didFail);
438 EXPECT_FALSE(m_didReceiveResponse);
439 }
440
441 // Test a same-origin URL redirect and load.
442 TEST_F(AssociatedURLLoaderTest, RedirectSuccess) {
443 KURL url = toKURL("http://www.test.com/RedirectSuccess.html");
444 char redirect[] = "http://www.test.com/RedirectSuccess2.html"; // Same-origin
445 KURL redirectURL = toKURL(redirect);
446
447 WebURLRequest request;
448 request.setURL(url);
449
450 m_expectedRedirectResponse = WebURLResponse();
451 m_expectedRedirectResponse.setMIMEType("text/html");
452 m_expectedRedirectResponse.setHTTPStatusCode(301);
453 m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
454 Platform::current()->getURLLoaderMockFactory()->registerURL(
455 url, m_expectedRedirectResponse, m_frameFilePath);
456
457 m_expectedNewRequest = WebURLRequest();
458 m_expectedNewRequest.setURL(redirectURL);
459
460 m_expectedResponse = WebURLResponse();
461 m_expectedResponse.setMIMEType("text/html");
462 m_expectedResponse.setHTTPStatusCode(200);
463 Platform::current()->getURLLoaderMockFactory()->registerURL(
464 redirectURL, m_expectedResponse, m_frameFilePath);
465
466 m_expectedLoader = createAssociatedURLLoader();
467 EXPECT_TRUE(m_expectedLoader);
468 m_expectedLoader->loadAsynchronously(request, this);
469 serveRequests();
470 EXPECT_TRUE(m_willFollowRedirect);
471 EXPECT_TRUE(m_didReceiveResponse);
472 EXPECT_TRUE(m_didReceiveData);
473 EXPECT_TRUE(m_didFinishLoading);
474 }
475
476 // Test a cross-origin URL redirect without Access Control set.
477 TEST_F(AssociatedURLLoaderTest, RedirectCrossOriginFailure) {
478 KURL url = toKURL("http://www.test.com/RedirectCrossOriginFailure.html");
479 char redirect[] =
480 "http://www.other.com/RedirectCrossOriginFailure.html"; // Cross-origin
481 KURL redirectURL = toKURL(redirect);
482
483 WebURLRequest request;
484 request.setURL(url);
485
486 m_expectedRedirectResponse = WebURLResponse();
487 m_expectedRedirectResponse.setMIMEType("text/html");
488 m_expectedRedirectResponse.setHTTPStatusCode(301);
489 m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
490 Platform::current()->getURLLoaderMockFactory()->registerURL(
491 url, m_expectedRedirectResponse, m_frameFilePath);
492
493 m_expectedNewRequest = WebURLRequest();
494 m_expectedNewRequest.setURL(redirectURL);
495
496 m_expectedResponse = WebURLResponse();
497 m_expectedResponse.setMIMEType("text/html");
498 m_expectedResponse.setHTTPStatusCode(200);
499 Platform::current()->getURLLoaderMockFactory()->registerURL(
500 redirectURL, m_expectedResponse, m_frameFilePath);
501
502 m_expectedLoader = createAssociatedURLLoader();
503 EXPECT_TRUE(m_expectedLoader);
504 m_expectedLoader->loadAsynchronously(request, this);
505
506 serveRequests();
507 EXPECT_FALSE(m_willFollowRedirect);
508 EXPECT_FALSE(m_didReceiveResponse);
509 EXPECT_FALSE(m_didReceiveData);
510 EXPECT_FALSE(m_didFinishLoading);
511 }
512
513 // Test that a cross origin redirect response without CORS headers fails.
514 TEST_F(AssociatedURLLoaderTest, RedirectCrossOriginWithAccessControlFailure) {
515 KURL url = toKURL(
516 "http://www.test.com/RedirectCrossOriginWithAccessControlFailure.html");
517 char redirect[] =
518 "http://www.other.com/"
519 "RedirectCrossOriginWithAccessControlFailure.html"; // Cross-origin
520 KURL redirectURL = toKURL(redirect);
521
522 WebURLRequest request;
523 request.setURL(url);
524
525 m_expectedRedirectResponse = WebURLResponse();
526 m_expectedRedirectResponse.setMIMEType("text/html");
527 m_expectedRedirectResponse.setHTTPStatusCode(301);
528 m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
529 Platform::current()->getURLLoaderMockFactory()->registerURL(
530 url, m_expectedRedirectResponse, m_frameFilePath);
531
532 m_expectedNewRequest = WebURLRequest();
533 m_expectedNewRequest.setURL(redirectURL);
534
535 m_expectedResponse = WebURLResponse();
536 m_expectedResponse.setMIMEType("text/html");
537 m_expectedResponse.setHTTPStatusCode(200);
538 Platform::current()->getURLLoaderMockFactory()->registerURL(
539 redirectURL, m_expectedResponse, m_frameFilePath);
540
541 WebURLLoaderOptions options;
542 options.crossOriginRequestPolicy =
543 WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
544 m_expectedLoader = createAssociatedURLLoader(options);
545 EXPECT_TRUE(m_expectedLoader);
546 m_expectedLoader->loadAsynchronously(request, this);
547
548 serveRequests();
549 // We should get a notification about access control check failure.
550 EXPECT_FALSE(m_willFollowRedirect);
551 EXPECT_FALSE(m_didReceiveResponse);
552 EXPECT_FALSE(m_didReceiveData);
553 EXPECT_TRUE(m_didFail);
554 }
555
556 // Test that a cross origin redirect response with CORS headers that allow the
557 // requesting origin succeeds.
558 TEST_F(AssociatedURLLoaderTest, RedirectCrossOriginWithAccessControlSuccess) {
559 KURL url = toKURL(
560 "http://www.test.com/RedirectCrossOriginWithAccessControlSuccess.html");
561 char redirect[] =
562 "http://www.other.com/"
563 "RedirectCrossOriginWithAccessControlSuccess.html"; // Cross-origin
564 KURL redirectURL = toKURL(redirect);
565
566 WebURLRequest request;
567 request.setURL(url);
568 // Add a CORS simple header.
569 request.setHTTPHeaderField("accept", "application/json");
570
571 // Create a redirect response that allows the redirect to pass the access
572 // control checks.
573 m_expectedRedirectResponse = WebURLResponse();
574 m_expectedRedirectResponse.setMIMEType("text/html");
575 m_expectedRedirectResponse.setHTTPStatusCode(301);
576 m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
577 m_expectedRedirectResponse.addHTTPHeaderField("access-control-allow-origin",
578 "*");
579 Platform::current()->getURLLoaderMockFactory()->registerURL(
580 url, m_expectedRedirectResponse, m_frameFilePath);
581
582 m_expectedNewRequest = WebURLRequest();
583 m_expectedNewRequest.setURL(redirectURL);
584 m_expectedNewRequest.setHTTPHeaderField("accept", "application/json");
585
586 m_expectedResponse = WebURLResponse();
587 m_expectedResponse.setMIMEType("text/html");
588 m_expectedResponse.setHTTPStatusCode(200);
589 m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
590 Platform::current()->getURLLoaderMockFactory()->registerURL(
591 redirectURL, m_expectedResponse, m_frameFilePath);
592
593 WebURLLoaderOptions options;
594 options.crossOriginRequestPolicy =
595 WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
596 m_expectedLoader = createAssociatedURLLoader(options);
597 EXPECT_TRUE(m_expectedLoader);
598 m_expectedLoader->loadAsynchronously(request, this);
599 serveRequests();
600 // We should not receive a notification for the redirect.
601 EXPECT_FALSE(m_willFollowRedirect);
602 EXPECT_TRUE(m_didReceiveResponse);
603 EXPECT_TRUE(m_didReceiveData);
604 EXPECT_TRUE(m_didFinishLoading);
605 }
606
607 // Test that untrusted loads can't use a forbidden method.
608 TEST_F(AssociatedURLLoaderTest, UntrustedCheckMethods) {
609 // Check non-token method fails.
610 CheckMethodFails("GET()");
611 CheckMethodFails("POST\x0d\x0ax-csrf-token:\x20test1234");
612
613 // Forbidden methods should fail regardless of casing.
614 CheckMethodFails("CoNneCt");
615 CheckMethodFails("TrAcK");
616 CheckMethodFails("TrAcE");
617 }
618
619 // This test is flaky on Windows and Android. See <http://crbug.com/471645>.
620 #if OS(WIN) || OS(ANDROID)
621 #define MAYBE_UntrustedCheckHeaders DISABLED_UntrustedCheckHeaders
622 #else
623 #define MAYBE_UntrustedCheckHeaders UntrustedCheckHeaders
624 #endif
625
626 // Test that untrusted loads can't use a forbidden header field.
627 TEST_F(AssociatedURLLoaderTest, MAYBE_UntrustedCheckHeaders) {
628 // Check non-token header fails.
629 CheckHeaderFails("foo()");
630
631 // Check forbidden headers fail.
632 CheckHeaderFails("accept-charset");
633 CheckHeaderFails("accept-encoding");
634 CheckHeaderFails("connection");
635 CheckHeaderFails("content-length");
636 CheckHeaderFails("cookie");
637 CheckHeaderFails("cookie2");
638 CheckHeaderFails("date");
639 CheckHeaderFails("dnt");
640 CheckHeaderFails("expect");
641 CheckHeaderFails("host");
642 CheckHeaderFails("keep-alive");
643 CheckHeaderFails("origin");
644 CheckHeaderFails("referer", "http://example.com/");
645 CheckHeaderFails("te");
646 CheckHeaderFails("trailer");
647 CheckHeaderFails("transfer-encoding");
648 CheckHeaderFails("upgrade");
649 CheckHeaderFails("user-agent");
650 CheckHeaderFails("via");
651
652 CheckHeaderFails("proxy-");
653 CheckHeaderFails("proxy-foo");
654 CheckHeaderFails("sec-");
655 CheckHeaderFails("sec-foo");
656
657 // Check that validation is case-insensitive.
658 CheckHeaderFails("AcCePt-ChArSeT");
659 CheckHeaderFails("ProXy-FoO");
660
661 // Check invalid header values.
662 CheckHeaderFails("foo", "bar\x0d\x0ax-csrf-token:\x20test1234");
663 }
664
665 // Test that the loader filters response headers according to the CORS standard.
666 TEST_F(AssociatedURLLoaderTest, CrossOriginHeaderWhitelisting) {
667 // Test that whitelisted headers are returned without exposing them.
668 EXPECT_TRUE(CheckAccessControlHeaders("cache-control", false));
669 EXPECT_TRUE(CheckAccessControlHeaders("content-language", false));
670 EXPECT_TRUE(CheckAccessControlHeaders("content-type", false));
671 EXPECT_TRUE(CheckAccessControlHeaders("expires", false));
672 EXPECT_TRUE(CheckAccessControlHeaders("last-modified", false));
673 EXPECT_TRUE(CheckAccessControlHeaders("pragma", false));
674
675 // Test that non-whitelisted headers aren't returned.
676 EXPECT_FALSE(CheckAccessControlHeaders("non-whitelisted", false));
677
678 // Test that Set-Cookie headers aren't returned.
679 EXPECT_FALSE(CheckAccessControlHeaders("Set-Cookie", false));
680 EXPECT_FALSE(CheckAccessControlHeaders("Set-Cookie2", false));
681
682 // Test that exposed headers that aren't whitelisted are returned.
683 EXPECT_TRUE(CheckAccessControlHeaders("non-whitelisted", true));
684
685 // Test that Set-Cookie headers aren't returned, even if exposed.
686 EXPECT_FALSE(CheckAccessControlHeaders("Set-Cookie", true));
687 }
688
689 // Test that the loader can allow non-whitelisted response headers for trusted
690 // CORS loads.
691 TEST_F(AssociatedURLLoaderTest, CrossOriginHeaderAllowResponseHeaders) {
692 WebURLRequest request;
693 KURL url =
694 toKURL("http://www.other.com/CrossOriginHeaderAllowResponseHeaders.html");
695 request.setURL(url);
696
697 WebString headerNameString(WebString::fromUTF8("non-whitelisted"));
698 m_expectedResponse = WebURLResponse();
699 m_expectedResponse.setMIMEType("text/html");
700 m_expectedResponse.setHTTPStatusCode(200);
701 m_expectedResponse.addHTTPHeaderField("Access-Control-Allow-Origin", "*");
702 m_expectedResponse.addHTTPHeaderField(headerNameString, "foo");
703 Platform::current()->getURLLoaderMockFactory()->registerURL(
704 url, m_expectedResponse, m_frameFilePath);
705
706 WebURLLoaderOptions options;
707 options.exposeAllResponseHeaders =
708 true; // This turns off response whitelisting.
709 options.crossOriginRequestPolicy =
710 WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
711 m_expectedLoader = createAssociatedURLLoader(options);
712 EXPECT_TRUE(m_expectedLoader);
713 m_expectedLoader->loadAsynchronously(request, this);
714 serveRequests();
715 EXPECT_TRUE(m_didReceiveResponse);
716 EXPECT_TRUE(m_didReceiveData);
717 EXPECT_TRUE(m_didFinishLoading);
718
719 EXPECT_FALSE(m_actualResponse.httpHeaderField(headerNameString).isEmpty());
720 }
721
722 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/web/AssociatedURLLoader.cpp ('k') | third_party/WebKit/Source/web/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698