Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / web / tests / AssociatedURLLoaderTest.cpp
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 "config.h"
32
33 #include "FrameTestHelpers.h"
34 #include "URLTestHelpers.h"
35 #include "WebFrame.h"
36 #include "WebURLLoaderOptions.h"
37 #include "WebView.h"
38 #include "public/platform/Platform.h"
39 #include "public/platform/WebString.h"
40 #include "public/platform/WebThread.h"
41 #include "public/platform/WebURL.h"
42 #include "public/platform/WebURLLoader.h"
43 #include "public/platform/WebURLLoaderClient.h"
44 #include "public/platform/WebURLRequest.h"
45 #include "public/platform/WebURLResponse.h"
46 #include "public/platform/WebUnitTestSupport.h"
47 #include "wtf/text/CString.h"
48 #include "wtf/text/WTFString.h"
49
50 #include <gtest/gtest.h>
51
52 using namespace blink;
53 using blink::URLTestHelpers::toKURL;
54
55 namespace {
56
57 class AssociatedURLLoaderTest : public testing::Test,
58                                 public WebURLLoaderClient {
59 public:
60     AssociatedURLLoaderTest()
61         :  m_willSendRequest(false)
62         ,  m_didSendData(false)
63         ,  m_didReceiveResponse(false)
64         ,  m_didReceiveData(false)
65         ,  m_didReceiveCachedMetadata(false)
66         ,  m_didFinishLoading(false)
67         ,  m_didFail(false)
68         ,  m_runningMessageLoop(false)
69     {
70         // Reuse one of the test files from WebFrameTest.
71         m_baseFilePath = Platform::current()->unitTestSupport()->webKitRootDir();
72         m_baseFilePath.append("/Source/web/tests/data/");
73         m_frameFilePath = m_baseFilePath;
74         m_frameFilePath.append("iframes_test.html");
75     }
76
77     WebCore::KURL RegisterMockedUrl(const std::string& urlRoot, const WTF::String& filename)
78     {
79         WebURLResponse response;
80         response.initialize();
81         response.setMIMEType("text/html");
82         WTF::String localPath = m_baseFilePath;
83         localPath.append(filename);
84         WebCore::KURL url = toKURL(urlRoot + filename.utf8().data());
85         Platform::current()->unitTestSupport()->registerMockedURL(url, response, localPath);
86         return url;
87     }
88
89     void SetUp()
90     {
91         m_helper.initialize();
92
93         std::string urlRoot = "http://www.test.com/";
94         WebCore::KURL url = RegisterMockedUrl(urlRoot, "iframes_test.html");
95         const char* iframeSupportFiles[] = {
96             "invisible_iframe.html",
97             "visible_iframe.html",
98             "zero_sized_iframe.html",
99         };
100         for (size_t i = 0; i < arraysize(iframeSupportFiles); ++i) {
101             RegisterMockedUrl(urlRoot, iframeSupportFiles[i]);
102         }
103
104         WebURLRequest request;
105         request.initialize();
106         request.setURL(url);
107         mainFrame()->loadRequest(request);
108         serveRequests();
109
110         Platform::current()->unitTestSupport()->unregisterMockedURL(url);
111     }
112
113     void TearDown()
114     {
115         Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
116     }
117
118     void serveRequests()
119     {
120         Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
121     }
122
123     WebURLLoader* createAssociatedURLLoader(const WebURLLoaderOptions options = WebURLLoaderOptions())
124     {
125         return mainFrame()->createAssociatedURLLoader(options);
126     }
127
128     // WebURLLoaderClient implementation.
129     void willSendRequest(WebURLLoader* loader, WebURLRequest& newRequest, const WebURLResponse& redirectResponse)
130     {
131         m_willSendRequest = true;
132         EXPECT_EQ(m_expectedLoader, loader);
133         EXPECT_EQ(m_expectedNewRequest.url(), newRequest.url());
134         EXPECT_EQ(m_expectedRedirectResponse.url(), redirectResponse.url());
135         EXPECT_EQ(m_expectedRedirectResponse.httpStatusCode(), redirectResponse.httpStatusCode());
136         EXPECT_EQ(m_expectedRedirectResponse.mimeType(), redirectResponse.mimeType());
137     }
138
139     void didSendData(WebURLLoader* loader, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
140     {
141         m_didSendData = true;
142         EXPECT_EQ(m_expectedLoader, loader);
143     }
144
145     void didReceiveResponse(WebURLLoader* loader, const WebURLResponse& response)
146     {
147         m_didReceiveResponse = true;
148         m_actualResponse = WebURLResponse(response);
149         EXPECT_EQ(m_expectedLoader, loader);
150         EXPECT_EQ(m_expectedResponse.url(), response.url());
151         EXPECT_EQ(m_expectedResponse.httpStatusCode(), response.httpStatusCode());
152     }
153
154     void didDownloadData(WebURLLoader* loader, int dataLength, int encodedDataLength)
155     {
156         m_didDownloadData = true;
157         EXPECT_EQ(m_expectedLoader, loader);
158     }
159
160     void didReceiveData(WebURLLoader* loader, const char* data, int dataLength, int encodedDataLength)
161     {
162         m_didReceiveData = true;
163         EXPECT_EQ(m_expectedLoader, loader);
164         EXPECT_TRUE(data);
165         EXPECT_GT(dataLength, 0);
166     }
167
168     void didReceiveCachedMetadata(WebURLLoader* loader, const char* data, int dataLength)
169     {
170         m_didReceiveCachedMetadata = true;
171         EXPECT_EQ(m_expectedLoader, loader);
172     }
173
174     void didFinishLoading(WebURLLoader* loader, double finishTime, int64_t encodedDataLength)
175     {
176         m_didFinishLoading = true;
177         EXPECT_EQ(m_expectedLoader, loader);
178     }
179
180     void didFail(WebURLLoader* loader, const WebURLError& error)
181     {
182         m_didFail = true;
183         EXPECT_EQ(m_expectedLoader, loader);
184         if (m_runningMessageLoop) {
185             m_runningMessageLoop = false;
186             Platform::current()->currentThread()->exitRunLoop();
187         }
188     }
189
190     void CheckMethodFails(const char* unsafeMethod)
191     {
192         WebURLRequest request;
193         request.initialize();
194         request.setURL(toKURL("http://www.test.com/success.html"));
195         request.setHTTPMethod(WebString::fromUTF8(unsafeMethod));
196         WebURLLoaderOptions options;
197         options.untrustedHTTP = true;
198         CheckFails(request, options);
199     }
200
201     void CheckHeaderFails(const char* headerField)
202     {
203         CheckHeaderFails(headerField, "foo");
204     }
205
206     void CheckHeaderFails(const char* headerField, const char* headerValue)
207     {
208         WebURLRequest request;
209         request.initialize();
210         request.setURL(toKURL("http://www.test.com/success.html"));
211         if (equalIgnoringCase(WebString::fromUTF8(headerField), "referer"))
212             request.setHTTPReferrer(WebString::fromUTF8(headerValue), blink::WebReferrerPolicyDefault);
213         else
214             request.setHTTPHeaderField(WebString::fromUTF8(headerField), WebString::fromUTF8(headerValue));
215         WebURLLoaderOptions options;
216         options.untrustedHTTP = true;
217         CheckFails(request, options);
218     }
219
220     void CheckFails(const WebURLRequest& request, WebURLLoaderOptions options = WebURLLoaderOptions())
221     {
222         m_expectedLoader = createAssociatedURLLoader(options);
223         EXPECT_TRUE(m_expectedLoader);
224         m_didFail = false;
225         m_expectedLoader->loadAsynchronously(request, this);
226         // Failure should not be reported synchronously.
227         EXPECT_FALSE(m_didFail);
228         // Allow the loader to return the error.
229         m_runningMessageLoop = true;
230         Platform::current()->currentThread()->enterRunLoop();
231         EXPECT_TRUE(m_didFail);
232         EXPECT_FALSE(m_didReceiveResponse);
233     }
234
235     bool CheckAccessControlHeaders(const char* headerName, bool exposed)
236     {
237         std::string id("http://www.other.com/CheckAccessControlExposeHeaders_");
238         id.append(headerName);
239         if (exposed)
240             id.append("-Exposed");
241         id.append(".html");
242
243         WebCore::KURL url = toKURL(id);
244         WebURLRequest request;
245         request.initialize();
246         request.setURL(url);
247
248         WebString headerNameString(WebString::fromUTF8(headerName));
249         m_expectedResponse = WebURLResponse();
250         m_expectedResponse.initialize();
251         m_expectedResponse.setMIMEType("text/html");
252         m_expectedResponse.setHTTPStatusCode(200);
253         m_expectedResponse.addHTTPHeaderField("Access-Control-Allow-Origin", "*");
254         if (exposed)
255             m_expectedResponse.addHTTPHeaderField("access-control-expose-headers", headerNameString);
256         m_expectedResponse.addHTTPHeaderField(headerNameString, "foo");
257         Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
258
259         WebURLLoaderOptions options;
260         options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
261         m_expectedLoader = createAssociatedURLLoader(options);
262         EXPECT_TRUE(m_expectedLoader);
263         m_expectedLoader->loadAsynchronously(request, this);
264         serveRequests();
265         EXPECT_TRUE(m_didReceiveResponse);
266         EXPECT_TRUE(m_didReceiveData);
267         EXPECT_TRUE(m_didFinishLoading);
268
269         return !m_actualResponse.httpHeaderField(headerNameString).isEmpty();
270     }
271
272     WebFrame* mainFrame() const { return m_helper.webView()->mainFrame(); }
273
274 protected:
275     WTF::String m_baseFilePath;
276     WTF::String m_frameFilePath;
277     FrameTestHelpers::WebViewHelper m_helper;
278
279     WebURLLoader* m_expectedLoader;
280     WebURLResponse m_actualResponse;
281     WebURLResponse m_expectedResponse;
282     WebURLRequest m_expectedNewRequest;
283     WebURLResponse m_expectedRedirectResponse;
284     bool m_willSendRequest;
285     bool m_didSendData;
286     bool m_didReceiveResponse;
287     bool m_didDownloadData;
288     bool m_didReceiveData;
289     bool m_didReceiveCachedMetadata;
290     bool m_didFinishLoading;
291     bool m_didFail;
292     bool m_runningMessageLoop;
293 };
294
295 // Test a successful same-origin URL load.
296 TEST_F(AssociatedURLLoaderTest, SameOriginSuccess)
297 {
298     WebCore::KURL url = toKURL("http://www.test.com/SameOriginSuccess.html");
299     WebURLRequest request;
300     request.initialize();
301     request.setURL(url);
302
303     m_expectedResponse = WebURLResponse();
304     m_expectedResponse.initialize();
305     m_expectedResponse.setMIMEType("text/html");
306     m_expectedResponse.setHTTPStatusCode(200);
307     Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
308
309     m_expectedLoader = createAssociatedURLLoader();
310     EXPECT_TRUE(m_expectedLoader);
311     m_expectedLoader->loadAsynchronously(request, this);
312     serveRequests();
313     EXPECT_TRUE(m_didReceiveResponse);
314     EXPECT_TRUE(m_didReceiveData);
315     EXPECT_TRUE(m_didFinishLoading);
316 }
317
318 // Test that the same-origin restriction is the default.
319 TEST_F(AssociatedURLLoaderTest, SameOriginRestriction)
320 {
321     // This is cross-origin since the frame was loaded from www.test.com.
322     WebCore::KURL url = toKURL("http://www.other.com/SameOriginRestriction.html");
323     WebURLRequest request;
324     request.initialize();
325     request.setURL(url);
326     CheckFails(request);
327 }
328
329 // Test a successful cross-origin load.
330 TEST_F(AssociatedURLLoaderTest, CrossOriginSuccess)
331 {
332     // This is cross-origin since the frame was loaded from www.test.com.
333     WebCore::KURL url = toKURL("http://www.other.com/CrossOriginSuccess.html");
334     WebURLRequest request;
335     request.initialize();
336     request.setURL(url);
337
338     m_expectedResponse = WebURLResponse();
339     m_expectedResponse.initialize();
340     m_expectedResponse.setMIMEType("text/html");
341     m_expectedResponse.setHTTPStatusCode(200);
342     Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
343
344     WebURLLoaderOptions options;
345     options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyAllow;
346     m_expectedLoader = createAssociatedURLLoader(options);
347     EXPECT_TRUE(m_expectedLoader);
348     m_expectedLoader->loadAsynchronously(request, this);
349     serveRequests();
350     EXPECT_TRUE(m_didReceiveResponse);
351     EXPECT_TRUE(m_didReceiveData);
352     EXPECT_TRUE(m_didFinishLoading);
353 }
354
355 // Test a successful cross-origin load using CORS.
356 TEST_F(AssociatedURLLoaderTest, CrossOriginWithAccessControlSuccess)
357 {
358     // This is cross-origin since the frame was loaded from www.test.com.
359     WebCore::KURL url = toKURL("http://www.other.com/CrossOriginWithAccessControlSuccess.html");
360     WebURLRequest request;
361     request.initialize();
362     request.setURL(url);
363
364     m_expectedResponse = WebURLResponse();
365     m_expectedResponse.initialize();
366     m_expectedResponse.setMIMEType("text/html");
367     m_expectedResponse.setHTTPStatusCode(200);
368     m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
369     Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
370
371     WebURLLoaderOptions options;
372     options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
373     m_expectedLoader = createAssociatedURLLoader(options);
374     EXPECT_TRUE(m_expectedLoader);
375     m_expectedLoader->loadAsynchronously(request, this);
376     serveRequests();
377     EXPECT_TRUE(m_didReceiveResponse);
378     EXPECT_TRUE(m_didReceiveData);
379     EXPECT_TRUE(m_didFinishLoading);
380 }
381
382 // Test an unsuccessful cross-origin load using CORS.
383 TEST_F(AssociatedURLLoaderTest, CrossOriginWithAccessControlFailure)
384 {
385     // This is cross-origin since the frame was loaded from www.test.com.
386     WebCore::KURL url = toKURL("http://www.other.com/CrossOriginWithAccessControlFailure.html");
387     WebURLRequest request;
388     request.initialize();
389     request.setURL(url);
390
391     m_expectedResponse = WebURLResponse();
392     m_expectedResponse.initialize();
393     m_expectedResponse.setMIMEType("text/html");
394     m_expectedResponse.setHTTPStatusCode(200);
395     m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
396     Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
397
398     WebURLLoaderOptions options;
399     // Send credentials. This will cause the CORS checks to fail, because credentials can't be
400     // sent to a server which returns the header "access-control-allow-origin" with "*" as its value.
401     options.allowCredentials = true;
402     options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
403     m_expectedLoader = createAssociatedURLLoader(options);
404     EXPECT_TRUE(m_expectedLoader);
405     m_expectedLoader->loadAsynchronously(request, this);
406
407     // Failure should not be reported synchronously.
408     EXPECT_FALSE(m_didFail);
409     // The loader needs to receive the response, before doing the CORS check.
410     serveRequests();
411     EXPECT_TRUE(m_didFail);
412     EXPECT_FALSE(m_didReceiveResponse);
413 }
414
415 // Test an unsuccessful cross-origin load using CORS.
416 TEST_F(AssociatedURLLoaderTest, CrossOriginWithAccessControlFailureBadStatusCode)
417 {
418     // This is cross-origin since the frame was loaded from www.test.com.
419     WebCore::KURL url = toKURL("http://www.other.com/CrossOriginWithAccessControlFailure.html");
420     WebURLRequest request;
421     request.initialize();
422     request.setURL(url);
423
424     m_expectedResponse = WebURLResponse();
425     m_expectedResponse.initialize();
426     m_expectedResponse.setMIMEType("text/html");
427     m_expectedResponse.setHTTPStatusCode(0);
428     m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
429     Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
430
431     WebURLLoaderOptions options;
432     options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
433     m_expectedLoader = createAssociatedURLLoader(options);
434     EXPECT_TRUE(m_expectedLoader);
435     m_expectedLoader->loadAsynchronously(request, this);
436
437     // Failure should not be reported synchronously.
438     EXPECT_FALSE(m_didFail);
439     // The loader needs to receive the response, before doing the CORS check.
440     serveRequests();
441     EXPECT_TRUE(m_didFail);
442     EXPECT_FALSE(m_didReceiveResponse);
443 }
444
445 // Test a same-origin URL redirect and load.
446 TEST_F(AssociatedURLLoaderTest, RedirectSuccess)
447 {
448     WebCore::KURL url = toKURL("http://www.test.com/RedirectSuccess.html");
449     char redirect[] = "http://www.test.com/RedirectSuccess2.html";  // Same-origin
450     WebCore::KURL redirectURL = toKURL(redirect);
451
452     WebURLRequest request;
453     request.initialize();
454     request.setURL(url);
455
456     m_expectedRedirectResponse = WebURLResponse();
457     m_expectedRedirectResponse.initialize();
458     m_expectedRedirectResponse.setMIMEType("text/html");
459     m_expectedRedirectResponse.setHTTPStatusCode(301);
460     m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
461     Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedRedirectResponse, m_frameFilePath);
462
463     m_expectedNewRequest = WebURLRequest();
464     m_expectedNewRequest.initialize();
465     m_expectedNewRequest.setURL(redirectURL);
466
467     m_expectedResponse = WebURLResponse();
468     m_expectedResponse.initialize();
469     m_expectedResponse.setMIMEType("text/html");
470     m_expectedResponse.setHTTPStatusCode(200);
471     Platform::current()->unitTestSupport()->registerMockedURL(redirectURL, m_expectedResponse, m_frameFilePath);
472
473     m_expectedLoader = createAssociatedURLLoader();
474     EXPECT_TRUE(m_expectedLoader);
475     m_expectedLoader->loadAsynchronously(request, this);
476     serveRequests();
477     EXPECT_TRUE(m_willSendRequest);
478     EXPECT_TRUE(m_didReceiveResponse);
479     EXPECT_TRUE(m_didReceiveData);
480     EXPECT_TRUE(m_didFinishLoading);
481 }
482
483 // Test that a cross origin redirect response without CORS headers fails.
484 // Disabled, http://crbug.com/240912 .
485 TEST_F(AssociatedURLLoaderTest, DISABLED_RedirectCrossOriginWithAccessControlFailure)
486 {
487     WebCore::KURL url = toKURL("http://www.test.com/RedirectCrossOriginWithAccessControlFailure.html");
488     char redirect[] = "http://www.other.com/RedirectCrossOriginWithAccessControlFailure.html";  // Cross-origin
489     WebCore::KURL redirectURL = toKURL(redirect);
490
491     WebURLRequest request;
492     request.initialize();
493     request.setURL(url);
494
495     // Create a redirect response without CORS headers.
496     m_expectedRedirectResponse = WebURLResponse();
497     m_expectedRedirectResponse.initialize();
498     m_expectedRedirectResponse.setMIMEType("text/html");
499     m_expectedRedirectResponse.setHTTPStatusCode(301);
500     m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
501     Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedRedirectResponse, m_frameFilePath);
502
503     WebURLLoaderOptions options;
504     options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
505     m_expectedLoader = createAssociatedURLLoader(options);
506     EXPECT_TRUE(m_expectedLoader);
507     m_expectedLoader->loadAsynchronously(request, this);
508     serveRequests();
509     // We should not receive a notification for the redirect or any response.
510     EXPECT_FALSE(m_willSendRequest);
511     EXPECT_FALSE(m_didReceiveResponse);
512     EXPECT_FALSE(m_didReceiveData);
513     EXPECT_FALSE(m_didFail);
514 }
515
516 // Test that a cross origin redirect response with CORS headers that allow the requesting origin succeeds.
517 TEST_F(AssociatedURLLoaderTest, RedirectCrossOriginWithAccessControlSuccess)
518 {
519     WebCore::KURL url = toKURL("http://www.test.com/RedirectCrossOriginWithAccessControlSuccess.html");
520     char redirect[] = "http://www.other.com/RedirectCrossOriginWithAccessControlSuccess.html";  // Cross-origin
521     WebCore::KURL redirectURL = toKURL(redirect);
522
523     WebURLRequest request;
524     request.initialize();
525     request.setURL(url);
526
527     // Create a redirect response that allows the redirect to pass the access control checks.
528     m_expectedRedirectResponse = WebURLResponse();
529     m_expectedRedirectResponse.initialize();
530     m_expectedRedirectResponse.setMIMEType("text/html");
531     m_expectedRedirectResponse.setHTTPStatusCode(301);
532     m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
533     m_expectedRedirectResponse.addHTTPHeaderField("access-control-allow-origin", "*");
534     Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedRedirectResponse, m_frameFilePath);
535
536     m_expectedNewRequest = WebURLRequest();
537     m_expectedNewRequest.initialize();
538     m_expectedNewRequest.setURL(redirectURL);
539
540     m_expectedResponse = WebURLResponse();
541     m_expectedResponse.initialize();
542     m_expectedResponse.setMIMEType("text/html");
543     m_expectedResponse.setHTTPStatusCode(200);
544     m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
545     Platform::current()->unitTestSupport()->registerMockedURL(redirectURL, m_expectedResponse, m_frameFilePath);
546
547     WebURLLoaderOptions options;
548     options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
549     m_expectedLoader = createAssociatedURLLoader(options);
550     EXPECT_TRUE(m_expectedLoader);
551     m_expectedLoader->loadAsynchronously(request, this);
552     serveRequests();
553     // We should not receive a notification for the redirect.
554     EXPECT_FALSE(m_willSendRequest);
555     EXPECT_TRUE(m_didReceiveResponse);
556     EXPECT_TRUE(m_didReceiveData);
557     EXPECT_TRUE(m_didFinishLoading);
558 }
559
560 // Test that untrusted loads can't use a forbidden method.
561 TEST_F(AssociatedURLLoaderTest, UntrustedCheckMethods)
562 {
563     // Check non-token method fails.
564     CheckMethodFails("GET()");
565     CheckMethodFails("POST\x0d\x0ax-csrf-token:\x20test1234");
566
567     // Forbidden methods should fail regardless of casing.
568     CheckMethodFails("CoNneCt");
569     CheckMethodFails("TrAcK");
570     CheckMethodFails("TrAcE");
571 }
572
573 // Test that untrusted loads can't use a forbidden header field.
574 TEST_F(AssociatedURLLoaderTest, UntrustedCheckHeaders)
575 {
576     // Check non-token header fails.
577     CheckHeaderFails("foo()");
578
579     // Check forbidden headers fail.
580     CheckHeaderFails("accept-charset");
581     CheckHeaderFails("accept-encoding");
582     CheckHeaderFails("connection");
583     CheckHeaderFails("content-length");
584     CheckHeaderFails("cookie");
585     CheckHeaderFails("cookie2");
586     CheckHeaderFails("content-transfer-encoding");
587     CheckHeaderFails("date");
588     CheckHeaderFails("expect");
589     CheckHeaderFails("host");
590     CheckHeaderFails("keep-alive");
591     CheckHeaderFails("origin");
592     CheckHeaderFails("referer");
593     CheckHeaderFails("te");
594     CheckHeaderFails("trailer");
595     CheckHeaderFails("transfer-encoding");
596     CheckHeaderFails("upgrade");
597     CheckHeaderFails("user-agent");
598     CheckHeaderFails("via");
599
600     CheckHeaderFails("proxy-");
601     CheckHeaderFails("proxy-foo");
602     CheckHeaderFails("sec-");
603     CheckHeaderFails("sec-foo");
604
605     // Check that validation is case-insensitive.
606     CheckHeaderFails("AcCePt-ChArSeT");
607     CheckHeaderFails("ProXy-FoO");
608
609     // Check invalid header values.
610     CheckHeaderFails("foo", "bar\x0d\x0ax-csrf-token:\x20test1234");
611 }
612
613 // Test that the loader filters response headers according to the CORS standard.
614 TEST_F(AssociatedURLLoaderTest, CrossOriginHeaderWhitelisting)
615 {
616     // Test that whitelisted headers are returned without exposing them.
617     EXPECT_TRUE(CheckAccessControlHeaders("cache-control", false));
618     EXPECT_TRUE(CheckAccessControlHeaders("content-language", false));
619     EXPECT_TRUE(CheckAccessControlHeaders("content-type", false));
620     EXPECT_TRUE(CheckAccessControlHeaders("expires", false));
621     EXPECT_TRUE(CheckAccessControlHeaders("last-modified", false));
622     EXPECT_TRUE(CheckAccessControlHeaders("pragma", false));
623
624     // Test that non-whitelisted headers aren't returned.
625     EXPECT_FALSE(CheckAccessControlHeaders("non-whitelisted", false));
626
627     // Test that Set-Cookie headers aren't returned.
628     EXPECT_FALSE(CheckAccessControlHeaders("Set-Cookie", false));
629     EXPECT_FALSE(CheckAccessControlHeaders("Set-Cookie2", false));
630
631     // Test that exposed headers that aren't whitelisted are returned.
632     EXPECT_TRUE(CheckAccessControlHeaders("non-whitelisted", true));
633
634     // Test that Set-Cookie headers aren't returned, even if exposed.
635     EXPECT_FALSE(CheckAccessControlHeaders("Set-Cookie", true));
636 }
637
638 // Test that the loader can allow non-whitelisted response headers for trusted CORS loads.
639 TEST_F(AssociatedURLLoaderTest, CrossOriginHeaderAllowResponseHeaders)
640 {
641     WebURLRequest request;
642     request.initialize();
643     WebCore::KURL url = toKURL("http://www.other.com/CrossOriginHeaderAllowResponseHeaders.html");
644     request.setURL(url);
645
646     WebString headerNameString(WebString::fromUTF8("non-whitelisted"));
647     m_expectedResponse = WebURLResponse();
648     m_expectedResponse.initialize();
649     m_expectedResponse.setMIMEType("text/html");
650     m_expectedResponse.setHTTPStatusCode(200);
651     m_expectedResponse.addHTTPHeaderField("Access-Control-Allow-Origin", "*");
652     m_expectedResponse.addHTTPHeaderField(headerNameString, "foo");
653     Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
654
655     WebURLLoaderOptions options;
656     options.exposeAllResponseHeaders = true; // This turns off response whitelisting.
657     options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
658     m_expectedLoader = createAssociatedURLLoader(options);
659     EXPECT_TRUE(m_expectedLoader);
660     m_expectedLoader->loadAsynchronously(request, this);
661     serveRequests();
662     EXPECT_TRUE(m_didReceiveResponse);
663     EXPECT_TRUE(m_didReceiveData);
664     EXPECT_TRUE(m_didFinishLoading);
665
666     EXPECT_FALSE(m_actualResponse.httpHeaderField(headerNameString).isEmpty());
667 }
668
669 }