This source file includes following definitions.
- m_runningMessageLoop
- RegisterMockedUrl
- SetUp
- TearDown
- serveRequests
- createAssociatedURLLoader
- willSendRequest
- didSendData
- didReceiveResponse
- didDownloadData
- didReceiveData
- didReceiveCachedMetadata
- didFinishLoading
- didFail
- CheckMethodFails
- CheckHeaderFails
- CheckHeaderFails
- CheckFails
- CheckAccessControlHeaders
- mainFrame
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "config.h"
#include "FrameTestHelpers.h"
#include "URLTestHelpers.h"
#include "WebFrame.h"
#include "WebURLLoaderOptions.h"
#include "WebView.h"
#include "public/platform/Platform.h"
#include "public/platform/WebString.h"
#include "public/platform/WebThread.h"
#include "public/platform/WebURL.h"
#include "public/platform/WebURLLoader.h"
#include "public/platform/WebURLLoaderClient.h"
#include "public/platform/WebURLRequest.h"
#include "public/platform/WebURLResponse.h"
#include "public/platform/WebUnitTestSupport.h"
#include "wtf/text/CString.h"
#include "wtf/text/WTFString.h"
#include <gtest/gtest.h>
using namespace blink;
using blink::URLTestHelpers::toKURL;
namespace {
class AssociatedURLLoaderTest : public testing::Test,
public WebURLLoaderClient {
public:
AssociatedURLLoaderTest()
: m_willSendRequest(false)
, m_didSendData(false)
, m_didReceiveResponse(false)
, m_didReceiveData(false)
, m_didReceiveCachedMetadata(false)
, m_didFinishLoading(false)
, m_didFail(false)
, m_runningMessageLoop(false)
{
m_baseFilePath = Platform::current()->unitTestSupport()->webKitRootDir();
m_baseFilePath.append("/Source/web/tests/data/");
m_frameFilePath = m_baseFilePath;
m_frameFilePath.append("iframes_test.html");
}
WebCore::KURL RegisterMockedUrl(const std::string& urlRoot, const WTF::String& filename)
{
WebURLResponse response;
response.initialize();
response.setMIMEType("text/html");
WTF::String localPath = m_baseFilePath;
localPath.append(filename);
WebCore::KURL url = toKURL(urlRoot + filename.utf8().data());
Platform::current()->unitTestSupport()->registerMockedURL(url, response, localPath);
return url;
}
void SetUp()
{
m_helper.initialize();
std::string urlRoot = "http://www.test.com/";
WebCore::KURL url = RegisterMockedUrl(urlRoot, "iframes_test.html");
const char* iframeSupportFiles[] = {
"invisible_iframe.html",
"visible_iframe.html",
"zero_sized_iframe.html",
};
for (size_t i = 0; i < arraysize(iframeSupportFiles); ++i) {
RegisterMockedUrl(urlRoot, iframeSupportFiles[i]);
}
WebURLRequest request;
request.initialize();
request.setURL(url);
mainFrame()->loadRequest(request);
serveRequests();
Platform::current()->unitTestSupport()->unregisterMockedURL(url);
}
void TearDown()
{
Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
}
void serveRequests()
{
Platform::current()->unitTestSupport()->serveAsynchronousMockedRequests();
}
PassOwnPtr<WebURLLoader> createAssociatedURLLoader(const WebURLLoaderOptions options = WebURLLoaderOptions())
{
return adoptPtr(mainFrame()->createAssociatedURLLoader(options));
}
void willSendRequest(WebURLLoader* loader, WebURLRequest& newRequest, const WebURLResponse& redirectResponse)
{
m_willSendRequest = true;
EXPECT_EQ(m_expectedLoader, loader);
EXPECT_EQ(m_expectedNewRequest.url(), newRequest.url());
EXPECT_EQ(m_expectedRedirectResponse.url(), redirectResponse.url());
EXPECT_EQ(m_expectedRedirectResponse.httpStatusCode(), redirectResponse.httpStatusCode());
EXPECT_EQ(m_expectedRedirectResponse.mimeType(), redirectResponse.mimeType());
}
void didSendData(WebURLLoader* loader, unsigned long long bytesSent, unsigned long long totalBytesToBeSent)
{
m_didSendData = true;
EXPECT_EQ(m_expectedLoader, loader);
}
void didReceiveResponse(WebURLLoader* loader, const WebURLResponse& response)
{
m_didReceiveResponse = true;
m_actualResponse = WebURLResponse(response);
EXPECT_EQ(m_expectedLoader, loader);
EXPECT_EQ(m_expectedResponse.url(), response.url());
EXPECT_EQ(m_expectedResponse.httpStatusCode(), response.httpStatusCode());
}
void didDownloadData(WebURLLoader* loader, int dataLength, int encodedDataLength)
{
m_didDownloadData = true;
EXPECT_EQ(m_expectedLoader, loader);
}
void didReceiveData(WebURLLoader* loader, const char* data, int dataLength, int encodedDataLength)
{
m_didReceiveData = true;
EXPECT_EQ(m_expectedLoader, loader);
EXPECT_TRUE(data);
EXPECT_GT(dataLength, 0);
}
void didReceiveCachedMetadata(WebURLLoader* loader, const char* data, int dataLength)
{
m_didReceiveCachedMetadata = true;
EXPECT_EQ(m_expectedLoader, loader);
}
void didFinishLoading(WebURLLoader* loader, double finishTime, int64_t encodedDataLength)
{
m_didFinishLoading = true;
EXPECT_EQ(m_expectedLoader, loader);
}
void didFail(WebURLLoader* loader, const WebURLError& error)
{
m_didFail = true;
EXPECT_EQ(m_expectedLoader, loader);
if (m_runningMessageLoop) {
m_runningMessageLoop = false;
Platform::current()->currentThread()->exitRunLoop();
}
}
void CheckMethodFails(const char* unsafeMethod)
{
WebURLRequest request;
request.initialize();
request.setURL(toKURL("http://www.test.com/success.html"));
request.setHTTPMethod(WebString::fromUTF8(unsafeMethod));
WebURLLoaderOptions options;
options.untrustedHTTP = true;
CheckFails(request, options);
}
void CheckHeaderFails(const char* headerField)
{
CheckHeaderFails(headerField, "foo");
}
void CheckHeaderFails(const char* headerField, const char* headerValue)
{
WebURLRequest request;
request.initialize();
request.setURL(toKURL("http://www.test.com/success.html"));
if (equalIgnoringCase(WebString::fromUTF8(headerField), "referer"))
request.setHTTPReferrer(WebString::fromUTF8(headerValue), blink::WebReferrerPolicyDefault);
else
request.setHTTPHeaderField(WebString::fromUTF8(headerField), WebString::fromUTF8(headerValue));
WebURLLoaderOptions options;
options.untrustedHTTP = true;
CheckFails(request, options);
}
void CheckFails(const WebURLRequest& request, WebURLLoaderOptions options = WebURLLoaderOptions())
{
m_expectedLoader = createAssociatedURLLoader(options);
EXPECT_TRUE(m_expectedLoader);
m_didFail = false;
m_expectedLoader->loadAsynchronously(request, this);
EXPECT_FALSE(m_didFail);
m_runningMessageLoop = true;
Platform::current()->currentThread()->enterRunLoop();
EXPECT_TRUE(m_didFail);
EXPECT_FALSE(m_didReceiveResponse);
}
bool CheckAccessControlHeaders(const char* headerName, bool exposed)
{
std::string id("http://www.other.com/CheckAccessControlExposeHeaders_");
id.append(headerName);
if (exposed)
id.append("-Exposed");
id.append(".html");
WebCore::KURL url = toKURL(id);
WebURLRequest request;
request.initialize();
request.setURL(url);
WebString headerNameString(WebString::fromUTF8(headerName));
m_expectedResponse = WebURLResponse();
m_expectedResponse.initialize();
m_expectedResponse.setMIMEType("text/html");
m_expectedResponse.setHTTPStatusCode(200);
m_expectedResponse.addHTTPHeaderField("Access-Control-Allow-Origin", "*");
if (exposed)
m_expectedResponse.addHTTPHeaderField("access-control-expose-headers", headerNameString);
m_expectedResponse.addHTTPHeaderField(headerNameString, "foo");
Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
WebURLLoaderOptions options;
options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
m_expectedLoader = createAssociatedURLLoader(options);
EXPECT_TRUE(m_expectedLoader);
m_expectedLoader->loadAsynchronously(request, this);
serveRequests();
EXPECT_TRUE(m_didReceiveResponse);
EXPECT_TRUE(m_didReceiveData);
EXPECT_TRUE(m_didFinishLoading);
return !m_actualResponse.httpHeaderField(headerNameString).isEmpty();
}
WebFrame* mainFrame() const { return m_helper.webView()->mainFrame(); }
protected:
WTF::String m_baseFilePath;
WTF::String m_frameFilePath;
FrameTestHelpers::WebViewHelper m_helper;
OwnPtr<WebURLLoader> m_expectedLoader;
WebURLResponse m_actualResponse;
WebURLResponse m_expectedResponse;
WebURLRequest m_expectedNewRequest;
WebURLResponse m_expectedRedirectResponse;
bool m_willSendRequest;
bool m_didSendData;
bool m_didReceiveResponse;
bool m_didDownloadData;
bool m_didReceiveData;
bool m_didReceiveCachedMetadata;
bool m_didFinishLoading;
bool m_didFail;
bool m_runningMessageLoop;
};
TEST_F(AssociatedURLLoaderTest, SameOriginSuccess)
{
WebCore::KURL url = toKURL("http://www.test.com/SameOriginSuccess.html");
WebURLRequest request;
request.initialize();
request.setURL(url);
m_expectedResponse = WebURLResponse();
m_expectedResponse.initialize();
m_expectedResponse.setMIMEType("text/html");
m_expectedResponse.setHTTPStatusCode(200);
Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
m_expectedLoader = createAssociatedURLLoader();
EXPECT_TRUE(m_expectedLoader);
m_expectedLoader->loadAsynchronously(request, this);
serveRequests();
EXPECT_TRUE(m_didReceiveResponse);
EXPECT_TRUE(m_didReceiveData);
EXPECT_TRUE(m_didFinishLoading);
}
TEST_F(AssociatedURLLoaderTest, SameOriginRestriction)
{
WebCore::KURL url = toKURL("http://www.other.com/SameOriginRestriction.html");
WebURLRequest request;
request.initialize();
request.setURL(url);
CheckFails(request);
}
TEST_F(AssociatedURLLoaderTest, CrossOriginSuccess)
{
WebCore::KURL url = toKURL("http://www.other.com/CrossOriginSuccess.html");
WebURLRequest request;
request.initialize();
request.setURL(url);
m_expectedResponse = WebURLResponse();
m_expectedResponse.initialize();
m_expectedResponse.setMIMEType("text/html");
m_expectedResponse.setHTTPStatusCode(200);
Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
WebURLLoaderOptions options;
options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyAllow;
m_expectedLoader = createAssociatedURLLoader(options);
EXPECT_TRUE(m_expectedLoader);
m_expectedLoader->loadAsynchronously(request, this);
serveRequests();
EXPECT_TRUE(m_didReceiveResponse);
EXPECT_TRUE(m_didReceiveData);
EXPECT_TRUE(m_didFinishLoading);
}
TEST_F(AssociatedURLLoaderTest, CrossOriginWithAccessControlSuccess)
{
WebCore::KURL url = toKURL("http://www.other.com/CrossOriginWithAccessControlSuccess.html");
WebURLRequest request;
request.initialize();
request.setURL(url);
m_expectedResponse = WebURLResponse();
m_expectedResponse.initialize();
m_expectedResponse.setMIMEType("text/html");
m_expectedResponse.setHTTPStatusCode(200);
m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
WebURLLoaderOptions options;
options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
m_expectedLoader = createAssociatedURLLoader(options);
EXPECT_TRUE(m_expectedLoader);
m_expectedLoader->loadAsynchronously(request, this);
serveRequests();
EXPECT_TRUE(m_didReceiveResponse);
EXPECT_TRUE(m_didReceiveData);
EXPECT_TRUE(m_didFinishLoading);
}
TEST_F(AssociatedURLLoaderTest, CrossOriginWithAccessControlFailure)
{
WebCore::KURL url = toKURL("http://www.other.com/CrossOriginWithAccessControlFailure.html");
WebURLRequest request;
request.initialize();
request.setURL(url);
m_expectedResponse = WebURLResponse();
m_expectedResponse.initialize();
m_expectedResponse.setMIMEType("text/html");
m_expectedResponse.setHTTPStatusCode(200);
m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
WebURLLoaderOptions options;
options.allowCredentials = true;
options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
m_expectedLoader = createAssociatedURLLoader(options);
EXPECT_TRUE(m_expectedLoader);
m_expectedLoader->loadAsynchronously(request, this);
EXPECT_FALSE(m_didFail);
serveRequests();
EXPECT_TRUE(m_didFail);
EXPECT_FALSE(m_didReceiveResponse);
}
TEST_F(AssociatedURLLoaderTest, CrossOriginWithAccessControlFailureBadStatusCode)
{
WebCore::KURL url = toKURL("http://www.other.com/CrossOriginWithAccessControlFailure.html");
WebURLRequest request;
request.initialize();
request.setURL(url);
m_expectedResponse = WebURLResponse();
m_expectedResponse.initialize();
m_expectedResponse.setMIMEType("text/html");
m_expectedResponse.setHTTPStatusCode(0);
m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
WebURLLoaderOptions options;
options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
m_expectedLoader = createAssociatedURLLoader(options);
EXPECT_TRUE(m_expectedLoader);
m_expectedLoader->loadAsynchronously(request, this);
EXPECT_FALSE(m_didFail);
serveRequests();
EXPECT_TRUE(m_didFail);
EXPECT_FALSE(m_didReceiveResponse);
}
TEST_F(AssociatedURLLoaderTest, RedirectSuccess)
{
WebCore::KURL url = toKURL("http://www.test.com/RedirectSuccess.html");
char redirect[] = "http://www.test.com/RedirectSuccess2.html";
WebCore::KURL redirectURL = toKURL(redirect);
WebURLRequest request;
request.initialize();
request.setURL(url);
m_expectedRedirectResponse = WebURLResponse();
m_expectedRedirectResponse.initialize();
m_expectedRedirectResponse.setMIMEType("text/html");
m_expectedRedirectResponse.setHTTPStatusCode(301);
m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedRedirectResponse, m_frameFilePath);
m_expectedNewRequest = WebURLRequest();
m_expectedNewRequest.initialize();
m_expectedNewRequest.setURL(redirectURL);
m_expectedResponse = WebURLResponse();
m_expectedResponse.initialize();
m_expectedResponse.setMIMEType("text/html");
m_expectedResponse.setHTTPStatusCode(200);
Platform::current()->unitTestSupport()->registerMockedURL(redirectURL, m_expectedResponse, m_frameFilePath);
m_expectedLoader = createAssociatedURLLoader();
EXPECT_TRUE(m_expectedLoader);
m_expectedLoader->loadAsynchronously(request, this);
serveRequests();
EXPECT_TRUE(m_willSendRequest);
EXPECT_TRUE(m_didReceiveResponse);
EXPECT_TRUE(m_didReceiveData);
EXPECT_TRUE(m_didFinishLoading);
}
TEST_F(AssociatedURLLoaderTest, DISABLED_RedirectCrossOriginWithAccessControlFailure)
{
WebCore::KURL url = toKURL("http://www.test.com/RedirectCrossOriginWithAccessControlFailure.html");
char redirect[] = "http://www.other.com/RedirectCrossOriginWithAccessControlFailure.html";
WebCore::KURL redirectURL = toKURL(redirect);
WebURLRequest request;
request.initialize();
request.setURL(url);
m_expectedRedirectResponse = WebURLResponse();
m_expectedRedirectResponse.initialize();
m_expectedRedirectResponse.setMIMEType("text/html");
m_expectedRedirectResponse.setHTTPStatusCode(301);
m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedRedirectResponse, m_frameFilePath);
WebURLLoaderOptions options;
options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
m_expectedLoader = createAssociatedURLLoader(options);
EXPECT_TRUE(m_expectedLoader);
m_expectedLoader->loadAsynchronously(request, this);
serveRequests();
EXPECT_FALSE(m_willSendRequest);
EXPECT_FALSE(m_didReceiveResponse);
EXPECT_FALSE(m_didReceiveData);
EXPECT_FALSE(m_didFail);
}
TEST_F(AssociatedURLLoaderTest, RedirectCrossOriginWithAccessControlSuccess)
{
WebCore::KURL url = toKURL("http://www.test.com/RedirectCrossOriginWithAccessControlSuccess.html");
char redirect[] = "http://www.other.com/RedirectCrossOriginWithAccessControlSuccess.html";
WebCore::KURL redirectURL = toKURL(redirect);
WebURLRequest request;
request.initialize();
request.setURL(url);
m_expectedRedirectResponse = WebURLResponse();
m_expectedRedirectResponse.initialize();
m_expectedRedirectResponse.setMIMEType("text/html");
m_expectedRedirectResponse.setHTTPStatusCode(301);
m_expectedRedirectResponse.setHTTPHeaderField("Location", redirect);
m_expectedRedirectResponse.addHTTPHeaderField("access-control-allow-origin", "*");
Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedRedirectResponse, m_frameFilePath);
m_expectedNewRequest = WebURLRequest();
m_expectedNewRequest.initialize();
m_expectedNewRequest.setURL(redirectURL);
m_expectedResponse = WebURLResponse();
m_expectedResponse.initialize();
m_expectedResponse.setMIMEType("text/html");
m_expectedResponse.setHTTPStatusCode(200);
m_expectedResponse.addHTTPHeaderField("access-control-allow-origin", "*");
Platform::current()->unitTestSupport()->registerMockedURL(redirectURL, m_expectedResponse, m_frameFilePath);
WebURLLoaderOptions options;
options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
m_expectedLoader = createAssociatedURLLoader(options);
EXPECT_TRUE(m_expectedLoader);
m_expectedLoader->loadAsynchronously(request, this);
serveRequests();
EXPECT_FALSE(m_willSendRequest);
EXPECT_TRUE(m_didReceiveResponse);
EXPECT_TRUE(m_didReceiveData);
EXPECT_TRUE(m_didFinishLoading);
}
TEST_F(AssociatedURLLoaderTest, UntrustedCheckMethods)
{
CheckMethodFails("GET()");
CheckMethodFails("POST\x0d\x0ax-csrf-token:\x20test1234");
CheckMethodFails("CoNneCt");
CheckMethodFails("TrAcK");
CheckMethodFails("TrAcE");
}
TEST_F(AssociatedURLLoaderTest, UntrustedCheckHeaders)
{
CheckHeaderFails("foo()");
CheckHeaderFails("accept-charset");
CheckHeaderFails("accept-encoding");
CheckHeaderFails("connection");
CheckHeaderFails("content-length");
CheckHeaderFails("cookie");
CheckHeaderFails("cookie2");
CheckHeaderFails("content-transfer-encoding");
CheckHeaderFails("date");
CheckHeaderFails("expect");
CheckHeaderFails("host");
CheckHeaderFails("keep-alive");
CheckHeaderFails("origin");
CheckHeaderFails("referer");
CheckHeaderFails("te");
CheckHeaderFails("trailer");
CheckHeaderFails("transfer-encoding");
CheckHeaderFails("upgrade");
CheckHeaderFails("user-agent");
CheckHeaderFails("via");
CheckHeaderFails("proxy-");
CheckHeaderFails("proxy-foo");
CheckHeaderFails("sec-");
CheckHeaderFails("sec-foo");
CheckHeaderFails("AcCePt-ChArSeT");
CheckHeaderFails("ProXy-FoO");
CheckHeaderFails("foo", "bar\x0d\x0ax-csrf-token:\x20test1234");
}
TEST_F(AssociatedURLLoaderTest, CrossOriginHeaderWhitelisting)
{
EXPECT_TRUE(CheckAccessControlHeaders("cache-control", false));
EXPECT_TRUE(CheckAccessControlHeaders("content-language", false));
EXPECT_TRUE(CheckAccessControlHeaders("content-type", false));
EXPECT_TRUE(CheckAccessControlHeaders("expires", false));
EXPECT_TRUE(CheckAccessControlHeaders("last-modified", false));
EXPECT_TRUE(CheckAccessControlHeaders("pragma", false));
EXPECT_FALSE(CheckAccessControlHeaders("non-whitelisted", false));
EXPECT_FALSE(CheckAccessControlHeaders("Set-Cookie", false));
EXPECT_FALSE(CheckAccessControlHeaders("Set-Cookie2", false));
EXPECT_TRUE(CheckAccessControlHeaders("non-whitelisted", true));
EXPECT_FALSE(CheckAccessControlHeaders("Set-Cookie", true));
}
TEST_F(AssociatedURLLoaderTest, CrossOriginHeaderAllowResponseHeaders)
{
WebURLRequest request;
request.initialize();
WebCore::KURL url = toKURL("http://www.other.com/CrossOriginHeaderAllowResponseHeaders.html");
request.setURL(url);
WebString headerNameString(WebString::fromUTF8("non-whitelisted"));
m_expectedResponse = WebURLResponse();
m_expectedResponse.initialize();
m_expectedResponse.setMIMEType("text/html");
m_expectedResponse.setHTTPStatusCode(200);
m_expectedResponse.addHTTPHeaderField("Access-Control-Allow-Origin", "*");
m_expectedResponse.addHTTPHeaderField(headerNameString, "foo");
Platform::current()->unitTestSupport()->registerMockedURL(url, m_expectedResponse, m_frameFilePath);
WebURLLoaderOptions options;
options.exposeAllResponseHeaders = true;
options.crossOriginRequestPolicy = WebURLLoaderOptions::CrossOriginRequestPolicyUseAccessControl;
m_expectedLoader = createAssociatedURLLoader(options);
EXPECT_TRUE(m_expectedLoader);
m_expectedLoader->loadAsynchronously(request, this);
serveRequests();
EXPECT_TRUE(m_didReceiveResponse);
EXPECT_TRUE(m_didReceiveData);
EXPECT_TRUE(m_didFinishLoading);
EXPECT_FALSE(m_actualResponse.httpHeaderField(headerNameString).isEmpty());
}
}