summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Barth <abarth@webkit.org>2011-05-20 20:58:34 (GMT)
committerPierre-Antoine LaFayette <plafayet@codeaurora.org>2012-02-02 18:54:30 (GMT)
commit0ddd7c1d91c08fbee6c99b79fa9971a7ac914384 (patch)
tree24747f3f9b7ba42d7d7505748e191d744c50173e
parent75a4602b16380981ba9c83540e24e37090d5b95d (diff)
Support the usage of CORS for WebGL and the 2D canvas
Factor CORS request preparation out of DocumentThreadableLoader https://bugs.webkit.org/show_bug.cgi?id=61209 2011-05-20 Adam Barth <abarth@webkit.org> Reviewed by Alexey Proskuryakov. Factor CORS request preparation out of DocumentThreadableLoader https://bugs.webkit.org/show_bug.cgi?id=61209 DocumentThreadableLoader has two jobs: 1) Proxy loads between threads. 2) Run the CORS state machine. This patch begins the work of separating those concerns, allowing CORS to be used elsewhere in the loading pipeline. In particular, this patch moves knowledge of how to prepare CORS requests out of DocumentThreadableLoder. * loader/CrossOriginAccessControl.cpp: (WebCore::isOnAccessControlSimpleRequestHeaderWhitelist): (WebCore::updateRequestForAccessControl): (WebCore::createAccessControlPreflightRequest): * loader/CrossOriginAccessControl.h: * loader/DocumentThreadableLoader.cpp: (WebCore::DocumentThreadableLoader::DocumentThreadableLoader): (WebCore::DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest): (WebCore::DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight): Change-Id: I5a4443a1655f906d833f608f15296dc7926d3326 git-svn-id: http://svn.webkit.org/repository/webkit/trunk@86980 268f45cc-cd09-0410-ab3c-d52691b4dbfc Add rel type prerender to distinguish prerender from prefetch https://bugs.webkit.org/show_bug.cgi?id=61079 2011-05-21 Gavin Peters <gavinp@chromium.org> Reviewed by Adam Barth. Add rel type prerender to distinguish prerender from prefetch https://bugs.webkit.org/show_bug.cgi?id=61079 Chrome right now uses <link rel=prefetch ...> for one of two things, to warm the cache in the same way as firefox, or to launch a speculative rendering of a web page, for faster "loading" when the user navigates to it. This new rel type will let us distinguish the two cases; the rel type prerender isn't used on the web today, but the Google Web Search example prerendering application is ready to experiment with it. * fast/dom/HTMLLinkElement/prerender-expected.txt: Added. * fast/dom/HTMLLinkElement/prerender.html: Added. * platform/gtk/Skipped: * platform/mac/Skipped: * platform/qt/Skipped: * platform/win/Skipped: 2011-05-21 Gavin Peters <gavinp@chromium.org> Reviewed by Adam Barth. Add rel type prerender to distinguish prerender from prefetch https://bugs.webkit.org/show_bug.cgi?id=61079 Chrome right now uses <link rel=prefetch ...> for one of two things, to warm the cache in the same way as firefox, or to launch a speculative rendering of a web page, for faster "loading" when the user navigates to it. This new rel type will let us distinguish the two cases; the rel type prerender isn't used on the web today, but the Google Web Search example prerendering application is ready to experiment with it. Test: fast/dom/HTMLLinkElement/prerender.html * html/HTMLLinkElement.cpp: (WebCore::HTMLLinkElement::tokenizeRelAttribute): (WebCore::HTMLLinkElement::process): * html/HTMLLinkElement.h: (WebCore::HTMLLinkElement::RelAttribute::RelAttribute): * loader/cache/CachedResource.cpp: (WebCore::defaultPriorityForResourceType): * loader/cache/CachedResource.h: (WebCore::CachedResource::isLinkResource): * loader/cache/CachedResourceLoader.cpp: (WebCore::createResource): (WebCore::CachedResourceLoader::requestLinkResource): (WebCore::CachedResourceLoader::canRequest): * loader/cache/CachedResourceLoader.h: * loader/cache/CachedResourceRequest.cpp: (WebCore::cachedResourceTypeToTargetType): (WebCore::CachedResourceRequest::load): * platform/network/ResourceRequestBase.h: Change-Id: I66a012e0bc3414cc48a7c497f08fb9b83cd8ab06 git-svn-id: http://svn.webkit.org/repository/webkit/trunk@87020 268f45cc-cd09-0410-ab3c-d52691b4dbfc Make CachedResource take a ResourceRequest instead of just a url string. 2011-05-24 Nate Chapin <japhet@chromium.org> Reviewed by Adam Barth. Change CachedResources to take a ResourceRequest instead of a url in their constructors and provide a very minimal set of cases for avoiding reusing a CachedResource. The ResourceRequest part of this change requires pushing responsibility for calling Document::completeURL() to the caller, instead of CachedResourceLoader, since ResourceRequest ASSERTs if it is constructed with an invalid url. https://bugs.webkit.org/show_bug.cgi?id=61318 Refactor, no new tests. * css/CSSFontSelector.cpp: (WebCore::CSSFontSelector::addFontFaceRule): * css/CSSImageValue.cpp: (WebCore::CSSImageValue::cachedImage): * css/CSSImportRule.cpp: (WebCore::CSSImportRule::insertedIntoParent): * dom/ProcessingInstruction.cpp: (WebCore::ProcessingInstruction::checkStyleSheet): * dom/ScriptElement.cpp: (WebCore::ScriptElement::requestScript): * html/HTMLLinkElement.cpp: (WebCore::HTMLLinkElement::process): * loader/ImageLoader.cpp: (WebCore::ImageLoader::updateFromElement): * loader/cache/CachedCSSStyleSheet.cpp: (WebCore::CachedCSSStyleSheet::CachedCSSStyleSheet): (WebCore::CachedCSSStyleSheet::didAddClient): (WebCore::CachedCSSStyleSheet::checkNotify): * loader/cache/CachedCSSStyleSheet.h: * loader/cache/CachedFont.cpp: (WebCore::CachedFont::CachedFont): * loader/cache/CachedFont.h: * loader/cache/CachedImage.cpp: (WebCore::CachedImage::CachedImage): (WebCore::CachedImage::checkShouldPaintBrokenImage): * loader/cache/CachedImage.h: * loader/cache/CachedResource.cpp: (WebCore::CachedResource::CachedResource): (WebCore::reuseRequest): (WebCore::CachedResource::allowReuseOfRequest): (WebCore::CachedResource::removeClient): (WebCore::CachedResource::canUseCacheValidator): * loader/cache/CachedResource.h: (WebCore::CachedResource::resourceRequest): (WebCore::CachedResource::url): * loader/cache/CachedResourceLoader.cpp: * loader/cache/CachedResourceLoader.h: * loader/cache/CachedResourceRequest.cpp: (WebCore::CachedResourceRequest::load): * loader/cache/CachedScript.cpp: (WebCore::CachedScript::CachedScript): * loader/cache/CachedScript.h: * loader/cache/CachedXSLStyleSheet.cpp: (WebCore::CachedXSLStyleSheet::CachedXSLStyleSheet): (WebCore::CachedXSLStyleSheet::didAddClient): (WebCore::CachedXSLStyleSheet::checkNotify): * loader/cache/CachedXSLStyleSheet.h: * svg/SVGFEImageElement.cpp: (WebCore::SVGFEImageElement::requestImageResource): * svg/SVGFontFaceUriElement.cpp: (WebCore::SVGFontFaceUriElement::loadFont): * xml/XSLImportRule.cpp: (WebCore::XSLImportRule::loadSheet): Change-Id: I4fb698cf09669661063eb42e310fbc1fd907bf76 git-svn-id: http://svn.webkit.org/repository/webkit/trunk@87239 268f45cc-cd09-0410-ab3c-d52691b4dbfc Support cross-origin property for images 2011-05-26 Adam Barth <abarth@webkit.org> Reviewed by Eric Seidel. Support cross-origin property for images https://bugs.webkit.org/show_bug.cgi?id=61015 Test various cases involving CORS requests and canvas tainting. * http/tests/security/canvas-remote-read-remote-image-allowed-expected.txt: Added. * http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials-expected.txt: Added. * http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials.html: Added. * http/tests/security/canvas-remote-read-remote-image-allowed.html: Added. * http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin-expected.txt: Added. * http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin.html: Added. * http/tests/security/resources/abe-allow-credentials.php: Added. * http/tests/security/resources/abe-allow-star.php: Added. 2011-05-26 Adam Barth <abarth@webkit.org> Reviewed by Eric Seidel. Support cross-origin property for images https://bugs.webkit.org/show_bug.cgi?id=61015 This patch add support for the crossorigin attribute of images and teaches 2D canvas to respect that flag and not taint a canvas if the image drawn on the canvas is allowed by CORS. While I was editing this code, I couldn't resist a couple touch-up changes. Tests: http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials.html http/tests/security/canvas-remote-read-remote-image-allowed.html http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin.html * html/HTMLAttributeNames.in: * html/HTMLCanvasElement.cpp: (WebCore::HTMLCanvasElement::securityOrigin): * html/HTMLCanvasElement.h: * html/HTMLImageElement.idl: * html/canvas/CanvasRenderingContext.cpp: (WebCore::CanvasRenderingContext::checkOrigin): * html/canvas/CanvasRenderingContext2D.cpp: (WebCore::CanvasRenderingContext2D::createPattern): * loader/ImageLoader.cpp: (WebCore::ImageLoader::updateFromElement): * loader/cache/CachedResource.cpp: (WebCore::CachedResource::passesAccessControlCheck): * loader/cache/CachedResource.h: Change-Id: I074a377f0045627e54806dacd5f3eb499a8dd5d0 git-svn-id: http://svn.webkit.org/repository/webkit/trunk@87473 268f45cc-cd09-0410-ab3c-d52691b4dbfc HTMLVideoElement::currentSrc() should return a KURL 2011-05-27 Adam Barth <abarth@webkit.org> Reviewed by Eric Seidel. HTMLVideoElement::currentSrc() should return a KURL https://bugs.webkit.org/show_bug.cgi?id=61578 I suspect we got into this mess because the author of this code didn't know about the URL attribute in WebKit IDL, which is super useful! Bad news: The line of code in question seems to have another bug, which I've documented in a FIXME. Let the yak shaving continue! * html/HTMLMediaElement.cpp: (WebCore::urlForLogging): (WebCore::HTMLMediaElement::loadResource): (WebCore::HTMLMediaElement::isSafeToLoadURL): (WebCore::HTMLMediaElement::selectNextSourceChild): (WebCore::HTMLMediaElement::getPluginProxyParams): * html/HTMLMediaElement.h: (WebCore::HTMLMediaElement::currentSrc): (WebCore::HTMLMediaElement::currentURL): * html/canvas/CanvasRenderingContext.cpp: (WebCore::CanvasRenderingContext::checkOrigin): * rendering/HitTestResult.cpp: (WebCore::HitTestResult::absoluteMediaURL): - This complete URL call was unnecessary because currentSrc is already absolute. Change-Id: I6fabb90aa5019a02a2434842824647d1484ed506 git-svn-id: http://svn.webkit.org/repository/webkit/trunk@87539 268f45cc-cd09-0410-ab3c-d52691b4dbfc Disallow use of cross-domain media (images, video) in WebGL 2011-06-09 Kenneth Russell <kbr@google.com> Reviewed by Adam Barth. Disallow use of cross-domain media (images, video) in WebGL https://bugs.webkit.org/show_bug.cgi?id=62257 Updated WebGL implementation to track recent spec updates in this area. Tests: http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html http/tests/security/webgl-remote-read-remote-image-allowed.html http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html * html/canvas/CanvasRenderingContext.cpp: (WebCore::CanvasRenderingContext::wouldTaintOrigin): (WebCore::CanvasRenderingContext::checkOrigin): * html/canvas/CanvasRenderingContext.h: (WebCore::CanvasRenderingContext::checkOrigin): * html/canvas/WebGLRenderingContext.cpp: (WebCore::WebGLRenderingContext::readPixels): (WebCore::WebGLRenderingContext::texImage2D): (WebCore::WebGLRenderingContext::videoFrameToImage): (WebCore::WebGLRenderingContext::texSubImage2D): * html/canvas/WebGLRenderingContext.h: 2011-06-09 Kenneth Russell <kbr@google.com> Reviewed by Adam Barth. Disallow use of cross-domain media (images, video) in WebGL https://bugs.webkit.org/show_bug.cgi?id=62257 Updated origin-clean-conformance.html to track upstream version in Khronos repository. Added new layout tests mirroring those added in bug 61015 which verify that new CORS support for images is working in the context of WebGL. Verified new tests in WebKit and Chromium. Skipped tests on platforms where WebGL is disabled. * http/tests/canvas/webgl/origin-clean-conformance-expected.txt: * http/tests/canvas/webgl/origin-clean-conformance.html: * http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt: Added. * http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt: Added. * http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html: Added. * http/tests/security/webgl-remote-read-remote-image-allowed.html: Added. * http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt: Added. * http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html: Added. * platform/gtk/Skipped: * platform/mac-leopard/Skipped: * platform/mac-wk2/Skipped: * platform/qt/Skipped: Change-Id: Id2e32ce41432838be6919002d606185ea60d97b3 git-svn-id: http://svn.webkit.org/repository/webkit/trunk@88489 268f45cc-cd09-0410-ab3c-d52691b4dbfc
-rw-r--r--LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt29
-rw-r--r--LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html218
-rw-r--r--LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-expected.txt15
-rw-r--r--LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials-expected.txt15
-rw-r--r--LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials.html108
-rw-r--r--LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed.html108
-rw-r--r--LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin-expected.txt15
-rw-r--r--LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin.html108
-rw-r--r--LayoutTests/http/tests/security/resources/abe-allow-credentials.php12
-rw-r--r--LayoutTests/http/tests/security/resources/abe-allow-star.php11
-rw-r--r--LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt13
-rw-r--r--LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt13
-rw-r--r--LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html101
-rw-r--r--LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html101
-rw-r--r--LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt13
-rw-r--r--LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html103
-rw-r--r--Source/WebCore/css/CSSFontSelector.cpp3
-rw-r--r--Source/WebCore/css/CSSImageValue.cpp4
-rw-r--r--Source/WebCore/css/CSSImportRule.cpp5
-rw-r--r--Source/WebCore/dom/ProcessingInstruction.cpp5
-rw-r--r--Source/WebCore/dom/ScriptElement.cpp3
-rw-r--r--Source/WebCore/html/HTMLAttributeNames.in1
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.h2
-rw-r--r--Source/WebCore/html/HTMLImageElement.idl3
-rw-r--r--Source/WebCore/html/HTMLLinkElement.cpp19
-rw-r--r--Source/WebCore/html/HTMLLinkElement.h2
-rw-r--r--Source/WebCore/html/HTMLMediaElement.cpp39
-rw-r--r--Source/WebCore/html/HTMLMediaElement.h6
-rw-r--r--Source/WebCore/html/HTMLMediaElement.idl2
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.cpp63
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.h21
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp10
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.cpp45
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.h2
-rw-r--r--Source/WebCore/html/parser/CSSPreloadScanner.cpp6
-rw-r--r--Source/WebCore/html/parser/HTMLPreloadScanner.cpp7
-rw-r--r--Source/WebCore/loader/CrossOriginAccessControl.cpp41
-rw-r--r--Source/WebCore/loader/CrossOriginAccessControl.h20
-rw-r--r--Source/WebCore/loader/DocumentThreadableLoader.cpp38
-rw-r--r--Source/WebCore/loader/ImageLoader.cpp13
-rw-r--r--Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp8
-rw-r--r--Source/WebCore/loader/cache/CachedCSSStyleSheet.h2
-rw-r--r--Source/WebCore/loader/cache/CachedFont.cpp4
-rw-r--r--Source/WebCore/loader/cache/CachedFont.h2
-rw-r--r--Source/WebCore/loader/cache/CachedImage.cpp10
-rw-r--r--Source/WebCore/loader/cache/CachedImage.h2
-rw-r--r--Source/WebCore/loader/cache/CachedResource.cpp19
-rw-r--r--Source/WebCore/loader/cache/CachedResource.h17
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.cpp117
-rw-r--r--Source/WebCore/loader/cache/CachedResourceLoader.h24
-rw-r--r--Source/WebCore/loader/cache/CachedResourceRequest.cpp25
-rw-r--r--Source/WebCore/loader/cache/CachedScript.cpp4
-rw-r--r--Source/WebCore/loader/cache/CachedScript.h2
-rw-r--r--Source/WebCore/loader/cache/CachedXSLStyleSheet.cpp8
-rw-r--r--Source/WebCore/loader/cache/CachedXSLStyleSheet.h2
-rw-r--r--Source/WebCore/loader/cache/MemoryCache.cpp4
-rw-r--r--Source/WebCore/platform/network/ResourceRequestBase.h1
-rw-r--r--Source/WebCore/platform/network/android/ResourceRequest.h1
-rw-r--r--Source/WebCore/rendering/HitTestResult.cpp2
-rw-r--r--Source/WebCore/svg/SVGFEImageElement.cpp3
-rw-r--r--Source/WebCore/svg/SVGFontFaceUriElement.cpp3
-rw-r--r--Source/WebCore/xml/XSLImportRule.cpp4
63 files changed, 1364 insertions, 247 deletions
diff --git a/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt b/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt
new file mode 100644
index 0000000..ca9217c
--- /dev/null
+++ b/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance-expected.txt
@@ -0,0 +1,29 @@
+This test ensures WebGL implementations follow proper same-origin restrictions.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS Playable video format found
+PASS img was loaded
+
+check that an attempt to upload an image from another origin throws an exception.
+PASS texImage2D with cross-origin image should throw exception.
+PASS texSubImage2D with cross-origin image should throw exception.
+check that readPixels and toDataURL continue to work against this canvas.
+PASS readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.
+PASS should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.
+check that an attempt to upload a tainted canvas throws an exception.
+PASS should throw exception by toDataURL for NON origin clean canvas.
+PASS texImage2D with NON origin clean canvas should throw exception.
+PASS texSubImage2D with NON origin clean canvas should throw exception.
+check that readPixels and toDataURL continue to work against this canvas.
+PASS readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.
+PASS should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.
+check that an attempt to upload a video from another origin throws an exception.
+PASS texImage2D with cross-origin video should throw exception.
+PASS texSubImage2D with cross-origin video should throw exception.
+check that readPixels and toDataURL continue to work against this canvas.
+PASS readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.
+PASS should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html b/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html
new file mode 100644
index 0000000..e983616
--- /dev/null
+++ b/LayoutTests/http/tests/canvas/webgl/origin-clean-conformance.html
@@ -0,0 +1,218 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Origin Restrictions Conformance Tests</title>
+<script>
+function create3DContext(canvas, attributes)
+{
+ if (!canvas)
+ canvas = document.createElement("canvas");
+ var context = null;
+ try {
+ context = canvas.getContext("experimental-webgl", attributes);
+ } catch(e) {}
+ if (!context) {
+ try {
+ context = canvas.getContext("webkit-3d", attributes);
+ } catch(e) {}
+ }
+ if (!context) {
+ try {
+ context = canvas.getContext("moz-webgl", attributes);
+ } catch(e) {}
+ }
+ if (!context) {
+ throw "Unable to fetch WebGL rendering context for Canvas";
+ }
+ return context;
+}
+
+function description(msg)
+{
+ // For MSIE 6 compatibility
+ var span = document.createElement("span");
+ span.innerHTML = '<p>' + msg + '</p><p>On success, you will see a series of "<span class="pass">PASS</span>" messages, followed by "<span class="pass">TEST COMPLETE</span>".</p>';
+ var description = document.getElementById("description");
+ if (description.firstChild)
+ description.replaceChild(span, description.firstChild);
+ else
+ description.appendChild(span);
+}
+
+function debug(msg)
+{
+ var span = document.createElement("span");
+ document.getElementById("console").appendChild(span); // insert it first so XHTML knows the namespace
+ span.innerHTML = msg + '<br />';
+}
+
+function escapeHTML(text)
+{
+ return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/\0/g, "\\0");
+}
+
+function testPassed(msg)
+{
+ debug('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>');
+}
+
+function testFailed(msg)
+{
+ debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>');
+}
+
+function assertMsg(assertion, msg) {
+ if (assertion) {
+ testPassed(msg);
+ } else {
+ testFailed(msg);
+ }
+}
+
+// Checks if function throws an exception.
+function causedException(func) {
+ var hadException = false;
+ try {
+ func();
+ } catch(e) {
+ hadException = true;
+ }
+ return hadException;
+}
+
+var testVideo = false;
+
+function init() {
+ var video = document.getElementById("video");
+
+ var base = "http://localhost:8000/resources/";
+ var videos = [
+ ["video/mp4", base + "test.mp4"],
+ ["video/ogg", base + "test.ogv"],
+ ];
+ var videoFile = null;
+ for (var i = 0; i < videos.length; ++i) {
+ if (video.canPlayType(videos[i][0])) {
+ videoFile = videos[i][1];
+ break;
+ }
+ }
+ assertMsg(videoFile, "Playable video format found");
+
+ if (videoFile) {
+ if (window.layoutTestController) {
+ layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+ }
+ video.src = videoFile;
+ video.addEventListener("playing", runTests);
+ video.play();
+ testVideo = true;
+ } else {
+ // Still run the other tests, even if the video failed.
+ runTests();
+ }
+}
+
+function runTests() {
+ description("This test ensures WebGL implementations follow proper same-origin restrictions.");
+ var img = document.getElementById("img");
+ assertMsg(img.width > 0 && img.height > 0, "img was loaded");
+
+ function makeTexImage2D(gl, src) {
+ return function() {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, src);
+ };
+ }
+
+ function makeTexSubImage2D(gl, src) {
+ return function() {
+ gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, src);
+ };
+ }
+
+ function makeReadPixels(gl) {
+ return function() {
+ var buf = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
+ };
+ }
+
+ function makeToDataURL(canvas) {
+ return function() {
+ var data = canvas.toDataURL();
+ }
+ }
+
+ var canvas1 = document.getElementById("canvas1");
+ var gl = create3DContext(canvas1);
+
+ debug("");
+ debug("check that an attempt to upload an image from another origin throws an exception.");
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 256, 256, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ assertMsg(causedException(makeTexImage2D(gl, img)),
+ "texImage2D with cross-origin image should throw exception.");
+ assertMsg(causedException(makeTexSubImage2D(gl, img)),
+ "texSubImage2D with cross-origin image should throw exception.");
+
+ debug("check that readPixels and toDataURL continue to work against this canvas.");
+ assertMsg(!causedException(makeReadPixels(gl)),
+ "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
+ assertMsg(!causedException(makeToDataURL(canvas1)),
+ "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.");
+
+ debug("check that an attempt to upload a tainted canvas throws an exception.");
+ var canvas2 = document.getElementById("canvas2");
+ var ctx2d = canvas2.getContext("2d");
+ ctx2d.drawImage(img, 0, 0);
+ assertMsg(causedException(makeToDataURL(canvas2)),
+ "should throw exception by toDataURL for NON origin clean canvas.");
+ assertMsg(causedException(makeTexImage2D(gl, canvas2)),
+ "texImage2D with NON origin clean canvas should throw exception.");
+ assertMsg(causedException(makeTexSubImage2D(gl, canvas2)),
+ "texSubImage2D with NON origin clean canvas should throw exception.");
+
+ debug("check that readPixels and toDataURL continue to work against this canvas.");
+ assertMsg(!causedException(makeReadPixels(gl)),
+ "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
+ assertMsg(!causedException(makeToDataURL(canvas1)),
+ "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.");
+
+ if (testVideo) {
+ debug("check that an attempt to upload a video from another origin throws an exception.");
+ var video = document.getElementById("video");
+ assertMsg(causedException(makeTexImage2D(gl, video)),
+ "texImage2D with cross-origin video should throw exception.");
+ assertMsg(causedException(makeTexSubImage2D(gl, video)),
+ "texSubImage2D with cross-origin video should throw exception.");
+
+ debug("check that readPixels and toDataURL continue to work against this canvas.");
+ assertMsg(!causedException(makeReadPixels(gl)),
+ "readPixels should never throw exception -- not possible to dirty origin of WebGL canvas.");
+ assertMsg(!causedException(makeToDataURL(canvas1)),
+ "should not throw exception by toDataURL for WebGL canvas, which should stay origin clean.");
+ }
+
+ debug('<br /><span class="pass">TEST COMPLETE</span>');
+ if (window.layoutTestController)
+ layoutTestController.waitUntilDone();
+ if (window.layoutTestController) {
+ layoutTestController.notifyDone();
+ }
+}
+</script>
+</head>
+<body onload="init()">
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas1"></canvas>
+<canvas id="canvas2"></canvas>
+<img id="img" src="http://localhost:8000/local/resources/abe.png" style="display:none;">
+<video id="video" style="display:none;"/>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-expected.txt b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-expected.txt
new file mode 100644
index 0000000..75cf15a
--- /dev/null
+++ b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-expected.txt
@@ -0,0 +1,15 @@
+Untainted canvas:
+PASS: Calling getImageData() from an untainted canvas was allowed.
+PASS: Calling toDataURL() on an untainted canvas was allowed.
+
+
+Tainted canvas:
+PASS: Calling getImageData() from a canvas tainted by a remote image was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image was allowed.
+PASS: Calling getImageData() from a canvas tainted by a CORS-untained canvas was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untained canvas was allowed.
+PASS: Calling getImageData() from a canvas tainted by a remote image tainted pattern was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image tainted pattern was allowed.
+PASS: Calling getImageData() from a canvas tainted by a CORS-untainted canvas pattern was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untainted canvas pattern was allowed.
+
diff --git a/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials-expected.txt b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials-expected.txt
new file mode 100644
index 0000000..75cf15a
--- /dev/null
+++ b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials-expected.txt
@@ -0,0 +1,15 @@
+Untainted canvas:
+PASS: Calling getImageData() from an untainted canvas was allowed.
+PASS: Calling toDataURL() on an untainted canvas was allowed.
+
+
+Tainted canvas:
+PASS: Calling getImageData() from a canvas tainted by a remote image was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image was allowed.
+PASS: Calling getImageData() from a canvas tainted by a CORS-untained canvas was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untained canvas was allowed.
+PASS: Calling getImageData() from a canvas tainted by a remote image tainted pattern was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image tainted pattern was allowed.
+PASS: Calling getImageData() from a canvas tainted by a CORS-untainted canvas pattern was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untainted canvas pattern was allowed.
+
diff --git a/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials.html b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials.html
new file mode 100644
index 0000000..a64ed5e
--- /dev/null
+++ b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed-with-credentials.html
@@ -0,0 +1,108 @@
+<pre id="console"></pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+log = function(msg)
+{
+ document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
+}
+
+testGetImageData = function(context, description)
+{
+ description = "Calling getImageData() from a canvas tainted by a " + description;
+ try {
+ var imageData = context.getImageData(0,0,100,100);
+ log("PASS: " + description + " was allowed.");
+ } catch (e) {
+ log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+testToDataURL = function(canvas, description)
+{
+ description = "Calling toDataURL() on a canvas CORS-untainted by a " + description;
+ try {
+ var dataURL = canvas.toDataURL();
+ log("PASS: " + description + " was allowed.");
+ } catch (e) {
+ log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+test = function(canvas, description)
+{
+ testGetImageData(canvas.getContext("2d"), description);
+ testToDataURL(canvas, description);
+}
+
+var image = new Image();
+image.onload = function() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+
+ // Control tests
+ log("Untainted canvas:");
+ try {
+ var imageData = context.getImageData(0, 0, 100, 100);
+ log("PASS: Calling getImageData() from an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling getImageData() from an untainted canvas was not allowed: Threw error: " + e + ".");
+ }
+ try {
+ var dataURL = canvas.toDataURL();
+ log("PASS: Calling toDataURL() on an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling toDataURL() on an untainted canvas was not allowed: Threw error: " + e + ".");
+ }
+
+ log("\n");
+ log("Tainted canvas:");
+ // Test reading from a canvas after drawing a remote image onto it
+ context.drawImage(image, 0, 0, 100, 100);
+
+ test(canvas, "remote image");
+
+ var dirtyCanvas = canvas;
+
+ // Now test reading from a canvas after drawing a tainted canvas onto it
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ context.drawImage(dirtyCanvas, 0, 0, 100, 100);
+
+ test(canvas, "CORS-untained canvas");
+
+ // Test reading after using a tainted pattern
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ var remoteImagePattern = context.createPattern(image, "repeat");
+ context.fillStyle = remoteImagePattern;
+ context.fillRect(0, 0, 100, 100);
+
+ test(canvas, "remote image tainted pattern");
+
+ // Test reading after using a tainted pattern
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ var taintedCanvasPattern = context.createPattern(dirtyCanvas, "repeat");
+ context.fillStyle = taintedCanvasPattern;
+ context.fillRect(0, 0, 100, 100);
+
+ test(canvas, "CORS-untainted canvas pattern");
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+image.crossOrigin = "use-credentials";
+image.src = "http://localhost:8000/security/resources/abe-allow-credentials.php";
+</script>
diff --git a/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed.html b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed.html
new file mode 100644
index 0000000..610605f
--- /dev/null
+++ b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-allowed.html
@@ -0,0 +1,108 @@
+<pre id="console"></pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+log = function(msg)
+{
+ document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
+}
+
+testGetImageData = function(context, description)
+{
+ description = "Calling getImageData() from a canvas tainted by a " + description;
+ try {
+ var imageData = context.getImageData(0,0,100,100);
+ log("PASS: " + description + " was allowed.");
+ } catch (e) {
+ log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+testToDataURL = function(canvas, description)
+{
+ description = "Calling toDataURL() on a canvas CORS-untainted by a " + description;
+ try {
+ var dataURL = canvas.toDataURL();
+ log("PASS: " + description + " was allowed.");
+ } catch (e) {
+ log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+test = function(canvas, description)
+{
+ testGetImageData(canvas.getContext("2d"), description);
+ testToDataURL(canvas, description);
+}
+
+var image = new Image();
+image.onload = function() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+
+ // Control tests
+ log("Untainted canvas:");
+ try {
+ var imageData = context.getImageData(0, 0, 100, 100);
+ log("PASS: Calling getImageData() from an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling getImageData() from an untainted canvas was not allowed: Threw error: " + e + ".");
+ }
+ try {
+ var dataURL = canvas.toDataURL();
+ log("PASS: Calling toDataURL() on an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling toDataURL() on an untainted canvas was not allowed: Threw error: " + e + ".");
+ }
+
+ log("\n");
+ log("Tainted canvas:");
+ // Test reading from a canvas after drawing a remote image onto it
+ context.drawImage(image, 0, 0, 100, 100);
+
+ test(canvas, "remote image");
+
+ var dirtyCanvas = canvas;
+
+ // Now test reading from a canvas after drawing a tainted canvas onto it
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ context.drawImage(dirtyCanvas, 0, 0, 100, 100);
+
+ test(canvas, "CORS-untained canvas");
+
+ // Test reading after using a tainted pattern
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ var remoteImagePattern = context.createPattern(image, "repeat");
+ context.fillStyle = remoteImagePattern;
+ context.fillRect(0, 0, 100, 100);
+
+ test(canvas, "remote image tainted pattern");
+
+ // Test reading after using a tainted pattern
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ var taintedCanvasPattern = context.createPattern(dirtyCanvas, "repeat");
+ context.fillStyle = taintedCanvasPattern;
+ context.fillRect(0, 0, 100, 100);
+
+ test(canvas, "CORS-untainted canvas pattern");
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+image.crossOrigin = "anonymous";
+image.src = "http://localhost:8000/security/resources/abe-allow-star.php";
+</script>
diff --git a/LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin-expected.txt b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin-expected.txt
new file mode 100644
index 0000000..aa3dde3
--- /dev/null
+++ b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin-expected.txt
@@ -0,0 +1,15 @@
+Untainted canvas:
+PASS: Calling getImageData() from an untainted canvas was allowed.
+PASS: Calling toDataURL() on an untainted canvas was allowed.
+
+
+Tainted canvas:
+PASS: Calling getImageData() from a canvas tainted by a remote image was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling toDataURL() on a canvas tainted by a remote image was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling getImageData() from a canvas tainted by a tained canvas was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling toDataURL() on a canvas tainted by a tained canvas was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling getImageData() from a canvas tainted by a remote image tainted pattern was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling toDataURL() on a canvas tainted by a remote image tainted pattern was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling getImageData() from a canvas tainted by a tainted canvas pattern was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling toDataURL() on a canvas tainted by a tainted canvas pattern was not allowed - Threw error: Error: SECURITY_ERR: DOM Exception 18.
+
diff --git a/LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin.html b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin.html
new file mode 100644
index 0000000..4815683
--- /dev/null
+++ b/LayoutTests/http/tests/security/canvas-remote-read-remote-image-blocked-no-crossorigin.html
@@ -0,0 +1,108 @@
+<pre id="console"></pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+log = function(msg)
+{
+ document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
+}
+
+testGetImageData = function(context, description)
+{
+ description = "Calling getImageData() from a canvas tainted by a " + description;
+ try {
+ var imageData = context.getImageData(0,0,100,100);
+ log("FAIL: " + description + " was allowed.");
+ } catch (e) {
+ log("PASS: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+testToDataURL = function(canvas, description)
+{
+ description = "Calling toDataURL() on a canvas tainted by a " + description;
+ try {
+ var dataURL = canvas.toDataURL();
+ log("FAIL: " + description + " was allowed.");
+ } catch (e) {
+ log("PASS: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+test = function(canvas, description)
+{
+ testGetImageData(canvas.getContext("2d"), description);
+ testToDataURL(canvas, description);
+}
+
+var image = new Image();
+image.onload = function() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+
+ // Control tests
+ log("Untainted canvas:");
+ try {
+ var imageData = context.getImageData(0, 0, 100, 100);
+ log("PASS: Calling getImageData() from an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling getImageData() from an untainted canvas was not allowed: Threw error: " + e + ".");
+ }
+ try {
+ var dataURL = canvas.toDataURL();
+ log("PASS: Calling toDataURL() on an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling toDataURL() on an untainted canvas was not allowed: Threw error: " + e + ".");
+ }
+
+ log("\n");
+ log("Tainted canvas:");
+ // Test reading from a canvas after drawing a remote image onto it
+ context.drawImage(image, 0, 0, 100, 100);
+
+ test(canvas, "remote image");
+
+ var dirtyCanvas = canvas;
+
+ // Now test reading from a canvas after drawing a tainted canvas onto it
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ context.drawImage(dirtyCanvas, 0, 0, 100, 100);
+
+ test(canvas, "tained canvas");
+
+ // Test reading after using a tainted pattern
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ var remoteImagePattern = context.createPattern(image, "repeat");
+ context.fillStyle = remoteImagePattern;
+ context.fillRect(0, 0, 100, 100);
+
+ test(canvas, "remote image tainted pattern");
+
+ // Test reading after using a tainted pattern
+ canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext("2d");
+ var taintedCanvasPattern = context.createPattern(dirtyCanvas, "repeat");
+ context.fillStyle = taintedCanvasPattern;
+ context.fillRect(0, 0, 100, 100);
+
+ test(canvas, "tainted canvas pattern");
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+// Notice that we forget to set the image.crossOrigin property!
+image.src = "http://localhost:8000/security/resources/abe-allow-star.php";
+</script>
diff --git a/LayoutTests/http/tests/security/resources/abe-allow-credentials.php b/LayoutTests/http/tests/security/resources/abe-allow-credentials.php
new file mode 100644
index 0000000..2ca7408
--- /dev/null
+++ b/LayoutTests/http/tests/security/resources/abe-allow-credentials.php
@@ -0,0 +1,12 @@
+<?php
+header("Access-Control-Allow-Origin: http://127.0.0.1:8000");
+header("Access-Control-Allow-Credentials: true");
+
+$name = 'abe.png';
+$fp = fopen($name, 'rb');
+header("Content-Type: image/png");
+header("Content-Length: " . filesize($name));
+
+fpassthru($fp);
+exit;
+?>
diff --git a/LayoutTests/http/tests/security/resources/abe-allow-star.php b/LayoutTests/http/tests/security/resources/abe-allow-star.php
new file mode 100644
index 0000000..d3d621d
--- /dev/null
+++ b/LayoutTests/http/tests/security/resources/abe-allow-star.php
@@ -0,0 +1,11 @@
+<?php
+header("Access-Control-Allow-Origin: *");
+
+$name = 'abe.png';
+$fp = fopen($name, 'rb');
+header("Content-Type: image/png");
+header("Content-Length: " . filesize($name));
+
+fpassthru($fp);
+exit;
+?>
diff --git a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt
new file mode 100644
index 0000000..c86861c
--- /dev/null
+++ b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-expected.txt
@@ -0,0 +1,13 @@
+Untainted canvas:
+PASS: Calling readPixels() from an untainted canvas was allowed.
+PASS: Calling toDataURL() on an untainted canvas was allowed.
+
+
+Tainted canvas:
+PASS: Calling texImage2D() with an untainted image was allowed
+PASS: Calling readPixels() from a canvas tainted by a remote image was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image was allowed.
+PASS: Calling texImage2D() with an untainted canvas was allowed
+PASS: Calling readPixels() from a canvas tainted by a CORS-untained canvas was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untained canvas was allowed.
+
diff --git a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt
new file mode 100644
index 0000000..c86861c
--- /dev/null
+++ b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials-expected.txt
@@ -0,0 +1,13 @@
+Untainted canvas:
+PASS: Calling readPixels() from an untainted canvas was allowed.
+PASS: Calling toDataURL() on an untainted canvas was allowed.
+
+
+Tainted canvas:
+PASS: Calling texImage2D() with an untainted image was allowed
+PASS: Calling readPixels() from a canvas tainted by a remote image was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a remote image was allowed.
+PASS: Calling texImage2D() with an untainted canvas was allowed
+PASS: Calling readPixels() from a canvas tainted by a CORS-untained canvas was allowed.
+PASS: Calling toDataURL() on a canvas CORS-untainted by a CORS-untained canvas was allowed.
+
diff --git a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html
new file mode 100644
index 0000000..c09e37b
--- /dev/null
+++ b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed-with-credentials.html
@@ -0,0 +1,101 @@
+<pre id="console"></pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+log = function(msg)
+{
+ document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
+}
+
+testTexImage2D = function(gl, source, description)
+{
+ description = "Calling texImage2D() with an untainted " + description;
+ try {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
+ log("PASS: " + description + " was allowed");
+ } catch (e) {
+ log("FAIL: " + description + " was not allowed: Threw error: " + e + ".");
+ }
+}
+
+testReadPixels = function(gl, description)
+{
+ description = "Calling readPixels() from a canvas tainted by a " + description;
+ try {
+ var pixels = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ log("PASS: " + description + " was allowed.");
+ } catch (e) {
+ log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+testToDataURL = function(canvas, description)
+{
+ description = "Calling toDataURL() on a canvas CORS-untainted by a " + description;
+ try {
+ var dataURL = canvas.toDataURL();
+ log("PASS: " + description + " was allowed.");
+ } catch (e) {
+ log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+test = function(canvas, description)
+{
+ testReadPixels(canvas.getContext("experimental-webgl"), description);
+ testToDataURL(canvas, description);
+}
+
+var image = new Image();
+image.onload = function() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var gl = canvas.getContext("experimental-webgl");
+
+ // Control tests
+ log("Untainted canvas:");
+ try {
+ var pixels = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ log("PASS: Calling readPixels() from an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling readPixels() from an untainted canvas was not allowed: Threw error: " + e + ".");
+ }
+ try {
+ var dataURL = canvas.toDataURL();
+ log("PASS: Calling toDataURL() on an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling toDataURL() on an untainted canvas was not allowed: Threw error: " + e + ".");
+ }
+
+ log("\n");
+ log("Tainted canvas:");
+ // Test reading from a canvas after uploading a remote image as a texture
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ testTexImage2D(gl, image, "image");
+
+ test(canvas, "remote image");
+
+ // Now test reading from a canvas after uploading a tainted canvas onto it
+ var dirtyCanvas = document.createElement("canvas");
+ dirtyCanvas.width = 100;
+ dirtyCanvas.height = 100;
+ var dirtyContext = dirtyCanvas.getContext("2d");
+ dirtyContext.drawImage(image, 0, 0, 100, 100);
+ testTexImage2D(gl, dirtyCanvas, "canvas");
+
+ test(canvas, "CORS-untained canvas");
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+image.crossOrigin = "use-credentials";
+image.src = "http://localhost:8000/security/resources/abe-allow-credentials.php";
+</script>
diff --git a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html
new file mode 100644
index 0000000..6448c2b
--- /dev/null
+++ b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-allowed.html
@@ -0,0 +1,101 @@
+<pre id="console"></pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+log = function(msg)
+{
+ document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
+}
+
+testTexImage2D = function(gl, source, description)
+{
+ description = "Calling texImage2D() with an untainted " + description;
+ try {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
+ log("PASS: " + description + " was allowed");
+ } catch (e) {
+ log("FAIL: " + description + " was not allowed: Threw error: " + e + ".");
+ }
+}
+
+testReadPixels = function(gl, description)
+{
+ description = "Calling readPixels() from a canvas tainted by a " + description;
+ try {
+ var pixels = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ log("PASS: " + description + " was allowed.");
+ } catch (e) {
+ log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+testToDataURL = function(canvas, description)
+{
+ description = "Calling toDataURL() on a canvas CORS-untainted by a " + description;
+ try {
+ var dataURL = canvas.toDataURL();
+ log("PASS: " + description + " was allowed.");
+ } catch (e) {
+ log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+test = function(canvas, description)
+{
+ testReadPixels(canvas.getContext("experimental-webgl"), description);
+ testToDataURL(canvas, description);
+}
+
+var image = new Image();
+image.onload = function() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var gl = canvas.getContext("experimental-webgl");
+
+ // Control tests
+ log("Untainted canvas:");
+ try {
+ var pixels = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ log("PASS: Calling readPixels() from an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling readPixels() from an untainted canvas was not allowed: Threw error: " + e + ".");
+ }
+ try {
+ var dataURL = canvas.toDataURL();
+ log("PASS: Calling toDataURL() on an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling toDataURL() on an untainted canvas was not allowed: Threw error: " + e + ".");
+ }
+
+ log("\n");
+ log("Tainted canvas:");
+ // Test reading from a canvas after uploading a remote image as a texture
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ testTexImage2D(gl, image, "image");
+
+ test(canvas, "remote image");
+
+ // Now test reading from a canvas after uploading a tainted canvas onto it
+ var dirtyCanvas = document.createElement("canvas");
+ dirtyCanvas.width = 100;
+ dirtyCanvas.height = 100;
+ var dirtyContext = dirtyCanvas.getContext("2d");
+ dirtyContext.drawImage(image, 0, 0, 100, 100);
+ testTexImage2D(gl, dirtyCanvas, "canvas");
+
+ test(canvas, "CORS-untained canvas");
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+image.crossOrigin = "anonymous";
+image.src = "http://localhost:8000/security/resources/abe-allow-star.php";
+</script>
diff --git a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt
new file mode 100644
index 0000000..ee74457
--- /dev/null
+++ b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin-expected.txt
@@ -0,0 +1,13 @@
+Untainted canvas:
+PASS: Calling readPixels() from an untainted canvas was allowed.
+PASS: Calling toDataURL() on an untainted canvas was allowed.
+
+
+Tainted canvas:
+PASS: Calling texImage2D() with a tainted image was not allowed: Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling readPixels() on a canvas where tainting was attempted by a remote image was allowed.
+PASS: Calling toDataURL() on a canvas where tainting was attempted by a remote image was allowed.
+PASS: Calling texImage2D() with a tainted canvas was not allowed: Threw error: Error: SECURITY_ERR: DOM Exception 18.
+PASS: Calling readPixels() on a canvas where tainting was attempted by a tainted canvas was allowed.
+PASS: Calling toDataURL() on a canvas where tainting was attempted by a tainted canvas was allowed.
+
diff --git a/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html
new file mode 100644
index 0000000..f870c3e
--- /dev/null
+++ b/LayoutTests/http/tests/security/webgl-remote-read-remote-image-blocked-no-crossorigin.html
@@ -0,0 +1,103 @@
+<pre id="console"></pre>
+<script>
+if (window.layoutTestController) {
+ layoutTestController.overridePreference("WebKitWebGLEnabled", "1");
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+}
+
+log = function(msg)
+{
+ document.getElementById('console').appendChild(document.createTextNode(msg + "\n"));
+}
+
+testTexImage2D = function(gl, source, description)
+{
+ description = "Calling texImage2D() with a tainted " + description;
+ try {
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source);
+ log("FAIL: " + description + " was allowed");
+ } catch (e) {
+ log("PASS: " + description + " was not allowed: Threw error: " + e + ".");
+ }
+}
+
+testReadPixels = function(gl, description)
+{
+ description = "Calling readPixels() on a canvas where tainting was attempted by a " + description;
+ try {
+ var pixels = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ log("PASS: " + description + " was allowed.");
+ } catch (e) {
+ log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+testToDataURL = function(canvas, description)
+{
+ description = "Calling toDataURL() on a canvas where tainting was attempted by a " + description;
+ try {
+ var dataURL = canvas.toDataURL();
+ log("PASS: " + description + " was allowed.");
+ } catch (e) {
+ log("FAIL: " + description + " was not allowed - Threw error: " + e + ".");
+ }
+}
+
+test = function(canvas, description)
+{
+ testReadPixels(canvas.getContext("experimental-webgl"), description);
+ testToDataURL(canvas, description);
+}
+
+var image = new Image();
+image.onload = function() {
+ var canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 100;
+ var gl = canvas.getContext("experimental-webgl");
+
+ // Control tests
+ log("Untainted canvas:");
+ try {
+ var pixels = new Uint8Array(4);
+ gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
+ log("PASS: Calling readPixels() from an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling readPixels() from an untainted canvas was not allowed: Threw error: " + e + ".");
+ }
+ try {
+ var dataURL = canvas.toDataURL();
+ log("PASS: Calling toDataURL() on an untainted canvas was allowed.");
+ } catch (e) {
+ log("FAIL: Calling toDataURL() on an untainted canvas was not allowed: Threw error: " + e + ".");
+ }
+
+ log("\n");
+ log("Tainted canvas:");
+ // Test reading from a canvas after uploading a remote image as a texture
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+ testTexImage2D(gl, image, "image");
+
+ test(canvas, "remote image");
+
+ var dirtyCanvas = canvas;
+
+ // Now test reading from a canvas after drawing a tainted canvas onto it
+ var dirtyCanvas = document.createElement("canvas");
+ dirtyCanvas.width = 100;
+ dirtyCanvas.height = 100;
+ var dirtyContext = dirtyCanvas.getContext("2d");
+ dirtyContext.drawImage(image, 0, 0, 100, 100);
+ testTexImage2D(gl, dirtyCanvas, "canvas");
+
+ test(canvas, "tainted canvas");
+
+ if (window.layoutTestController)
+ layoutTestController.notifyDone();
+}
+// Notice that we forget to set the image.crossOrigin property!
+image.src = "http://localhost:8000/security/resources/abe-allow-star.php";
+</script>
diff --git a/Source/WebCore/css/CSSFontSelector.cpp b/Source/WebCore/css/CSSFontSelector.cpp
index 122e433..ccdc722 100644
--- a/Source/WebCore/css/CSSFontSelector.cpp
+++ b/Source/WebCore/css/CSSFontSelector.cpp
@@ -245,7 +245,8 @@ void CSSFontSelector::addFontFaceRule(const CSSFontFaceRule* fontFaceRule)
Settings* settings = m_document ? m_document->frame() ? m_document->frame()->settings() : 0 : 0;
bool allowDownloading = foundSVGFont || (settings && settings->downloadableBinaryFontsEnabled());
if (allowDownloading && item->isSupportedFormat() && m_document) {
- CachedFont* cachedFont = m_document->cachedResourceLoader()->requestFont(item->resource());
+ ResourceRequest request(m_document->completeURL(item->resource()));
+ CachedFont* cachedFont = m_document->cachedResourceLoader()->requestFont(request);
if (cachedFont) {
source = new CSSFontFaceSource(item->resource(), cachedFont);
#if ENABLE(SVG_FONTS)
diff --git a/Source/WebCore/css/CSSImageValue.cpp b/Source/WebCore/css/CSSImageValue.cpp
index a9038b9..ffc6763 100644
--- a/Source/WebCore/css/CSSImageValue.cpp
+++ b/Source/WebCore/css/CSSImageValue.cpp
@@ -22,6 +22,7 @@
#include "CSSImageValue.h"
#include "CSSValueKeywords.h"
+#include "Document.h"
#include "MemoryCache.h"
#include "CachedImage.h"
#include "CachedResourceLoader.h"
@@ -71,7 +72,8 @@ StyleCachedImage* CSSImageValue::cachedImage(CachedResourceLoader* loader, const
if (!m_accessedImage) {
m_accessedImage = true;
- if (CachedImage* cachedImage = loader->requestImage(url)) {
+ ResourceRequest request(loader->document()->completeURL(url));
+ if (CachedImage* cachedImage = loader->requestImage(request)) {
cachedImage->addClient(this);
m_image = StyleCachedImage::create(cachedImage);
}
diff --git a/Source/WebCore/css/CSSImportRule.cpp b/Source/WebCore/css/CSSImportRule.cpp
index 09e313e..aa19e97 100644
--- a/Source/WebCore/css/CSSImportRule.cpp
+++ b/Source/WebCore/css/CSSImportRule.cpp
@@ -134,10 +134,11 @@ void CSSImportRule::insertedIntoParent()
root = curr;
}
+ ResourceRequest request(parentSheet->document()->completeURL(absHref));
if (parentSheet->isUserStyleSheet())
- m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(absHref, parentSheet->charset());
+ m_cachedSheet = cachedResourceLoader->requestUserCSSStyleSheet(request, parentSheet->charset());
else
- m_cachedSheet = cachedResourceLoader->requestCSSStyleSheet(absHref, parentSheet->charset());
+ m_cachedSheet = cachedResourceLoader->requestCSSStyleSheet(request, parentSheet->charset());
if (m_cachedSheet) {
// if the import rule is issued dynamically, the sheet may be
// removed from the pending sheet count, so let the doc know
diff --git a/Source/WebCore/dom/ProcessingInstruction.cpp b/Source/WebCore/dom/ProcessingInstruction.cpp
index 7135644..2f527f4 100644
--- a/Source/WebCore/dom/ProcessingInstruction.cpp
+++ b/Source/WebCore/dom/ProcessingInstruction.cpp
@@ -161,9 +161,10 @@ void ProcessingInstruction::checkStyleSheet()
m_loading = true;
document()->addPendingSheet();
+ ResourceRequest request(document()->completeURL(href));
#if ENABLE(XSLT)
if (m_isXSL)
- m_cachedSheet = document()->cachedResourceLoader()->requestXSLStyleSheet(url);
+ m_cachedSheet = document()->cachedResourceLoader()->requestXSLStyleSheet(request);
else
#endif
{
@@ -171,7 +172,7 @@ void ProcessingInstruction::checkStyleSheet()
if (charset.isEmpty())
charset = document()->charset();
- m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(url, charset);
+ m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(request, charset);
}
if (m_cachedSheet)
m_cachedSheet->addClient(this);
diff --git a/Source/WebCore/dom/ScriptElement.cpp b/Source/WebCore/dom/ScriptElement.cpp
index 55a7949..dc075ae 100644
--- a/Source/WebCore/dom/ScriptElement.cpp
+++ b/Source/WebCore/dom/ScriptElement.cpp
@@ -248,7 +248,8 @@ bool ScriptElement::requestScript(const String& sourceUrl)
ASSERT(!m_cachedScript);
// FIXME: If sourceUrl is empty, we should dispatchErrorEvent().
- m_cachedScript = m_element->document()->cachedResourceLoader()->requestScript(sourceUrl, scriptCharset());
+ ResourceRequest request(m_element->document()->completeURL(sourceUrl));
+ m_cachedScript = m_element->document()->cachedResourceLoader()->requestScript(request, scriptCharset());
m_isExternalScript = true;
if (m_cachedScript)
diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in
index 5e0fe7b..ee19ab8 100644
--- a/Source/WebCore/html/HTMLAttributeNames.in
+++ b/Source/WebCore/html/HTMLAttributeNames.in
@@ -82,6 +82,7 @@ content
contenteditable
controls
coords
+crossorigin
data
datetime
declare
diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp
index 02ed272..ece22c2 100644
--- a/Source/WebCore/html/HTMLCanvasElement.cpp
+++ b/Source/WebCore/html/HTMLCanvasElement.cpp
@@ -516,9 +516,9 @@ IntSize HTMLCanvasElement::convertToValidDeviceSize(float width, float height) c
return IntSize(width, height);
}
-const SecurityOrigin& HTMLCanvasElement::securityOrigin() const
+SecurityOrigin* HTMLCanvasElement::securityOrigin() const
{
- return *document()->securityOrigin();
+ return document()->securityOrigin();
}
CSSStyleSelector* HTMLCanvasElement::styleSelector()
diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h
index 37af718..2502585 100644
--- a/Source/WebCore/html/HTMLCanvasElement.h
+++ b/Source/WebCore/html/HTMLCanvasElement.h
@@ -125,7 +125,7 @@ public:
IntSize convertLogicalToDevice(const FloatSize&) const;
IntSize convertToValidDeviceSize(float width, float height) const;
- const SecurityOrigin& securityOrigin() const;
+ SecurityOrigin* securityOrigin() const;
void setOriginTainted() { m_originClean = false; }
bool originClean() const { return m_originClean; }
diff --git a/Source/WebCore/html/HTMLImageElement.idl b/Source/WebCore/html/HTMLImageElement.idl
index 935b721..c6a88ea 100644
--- a/Source/WebCore/html/HTMLImageElement.idl
+++ b/Source/WebCore/html/HTMLImageElement.idl
@@ -26,7 +26,8 @@ module html {
attribute [Reflect] DOMString name;
attribute [Reflect] DOMString align;
attribute [Reflect] DOMString alt;
- attribute [Reflect] DOMString border;
+ attribute [Reflect] DOMString border;
+ attribute [Reflect] DOMString crossOrigin;
attribute long height;
attribute [Reflect] long hspace;
attribute [Reflect] boolean isMap;
diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp
index 7cbf38b..fa78107 100644
--- a/Source/WebCore/html/HTMLLinkElement.cpp
+++ b/Source/WebCore/html/HTMLLinkElement.cpp
@@ -164,6 +164,7 @@ void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, RelAttribute
relAttribute.m_isDNSPrefetch = false;
#if ENABLE(LINK_PREFETCH)
relAttribute.m_isLinkPrefetch = false;
+ relAttribute.m_isLinkPrerender = false;
relAttribute.m_isLinkSubresource = false;
#endif
#ifdef ANDROID_APPLE_TOUCH_ICON
@@ -202,6 +203,8 @@ void HTMLLinkElement::tokenizeRelAttribute(const AtomicString& rel, RelAttribute
#if ENABLE(LINK_PREFETCH)
else if (equalIgnoringCase(*it, "prefetch"))
relAttribute.m_isLinkPrefetch = true;
+ else if (equalIgnoringCase(*it, "prerender"))
+ relAttribute.m_isLinkPrerender = true;
else if (equalIgnoringCase(*it, "subresource"))
relAttribute.m_isLinkSubresource = true;
#endif
@@ -254,14 +257,21 @@ void HTMLLinkElement::process()
}
#if ENABLE(LINK_PREFETCH)
- if ((m_relAttribute.m_isLinkPrefetch || m_relAttribute.m_isLinkSubresource) && m_url.isValid() && document()->frame()) {
+ if ((m_relAttribute.m_isLinkPrefetch || m_relAttribute.m_isLinkPrerender || m_relAttribute.m_isLinkSubresource) && m_url.isValid() && document()->frame()) {
if (!checkBeforeLoadEvent())
return;
ResourceLoadPriority priority = ResourceLoadPriorityUnresolved;
- if (m_relAttribute.m_isLinkSubresource)
+ CachedResource::Type type = CachedResource::LinkPrefetch;
+ // We only make one request to the cachedresourcelodaer if multiple rel types are
+ // specified,
+ if (m_relAttribute.m_isLinkSubresource) {
priority = ResourceLoadPriorityLow;
+ type = CachedResource::LinkSubresource;
+ } else if (m_relAttribute.m_isLinkPrerender)
+ type = CachedResource::LinkPrerender;
- m_cachedLinkResource = document()->cachedResourceLoader()->requestLinkResource(m_url, priority);
+ ResourceRequest linkRequest(document()->completeURL(m_url));
+ m_cachedLinkResource = document()->cachedResourceLoader()->requestLinkResource(type, linkRequest, priority);
if (m_cachedLinkResource)
m_cachedLinkResource->addClient(this);
}
@@ -302,7 +312,8 @@ void HTMLLinkElement::process()
// Load stylesheets that are not needed for the rendering immediately with low priority.
ResourceLoadPriority priority = blocking ? ResourceLoadPriorityUnresolved : ResourceLoadPriorityVeryLow;
- m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(m_url, charset, priority);
+ ResourceRequest request(document()->completeURL(m_url));
+ m_cachedSheet = document()->cachedResourceLoader()->requestCSSStyleSheet(request, charset, priority);
if (m_cachedSheet)
m_cachedSheet->addClient(this);
diff --git a/Source/WebCore/html/HTMLLinkElement.h b/Source/WebCore/html/HTMLLinkElement.h
index f602d38..3cad5c8 100644
--- a/Source/WebCore/html/HTMLLinkElement.h
+++ b/Source/WebCore/html/HTMLLinkElement.h
@@ -48,6 +48,7 @@ public:
#endif
#if ENABLE(LINK_PREFETCH)
bool m_isLinkPrefetch;
+ bool m_isLinkPrerender;
bool m_isLinkSubresource;
#endif
@@ -58,6 +59,7 @@ public:
, m_isDNSPrefetch(false)
#if ENABLE(LINK_PREFETCH)
, m_isLinkPrefetch(false)
+ , m_isLinkPrerender(false)
, m_isLinkSubresource(false)
#endif
{
diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp
index 023e8d2..b3e8cc2 100644
--- a/Source/WebCore/html/HTMLMediaElement.cpp
+++ b/Source/WebCore/html/HTMLMediaElement.cpp
@@ -89,16 +89,16 @@ using namespace std;
namespace WebCore {
#if !LOG_DISABLED
-static String urlForLogging(const String& url)
+static const char* urlForLogging(const KURL& url)
{
static const unsigned maximumURLLengthForLogging = 128;
- if (url.length() < maximumURLLengthForLogging)
- return url;
- return url.substring(0, maximumURLLengthForLogging) + "...";
+ if (url.string().length() < maximumURLLengthForLogging)
+ return url.string().utf8().data();
+ return String(url.string().substring(0, maximumURLLengthForLogging) + "...").utf8().data();
}
-static const char *boolString(bool val)
+static const char* boolString(bool val)
{
return val ? "true" : "false";
}
@@ -473,11 +473,6 @@ void HTMLMediaElement::setSrc(const String& url)
setAttribute(srcAttr, url);
}
-String HTMLMediaElement::currentSrc() const
-{
- return m_currentSrc;
-}
-
HTMLMediaElement::NetworkState HTMLMediaElement::networkState() const
{
return m_networkState;
@@ -694,7 +689,7 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content
{
ASSERT(isSafeToLoadURL(initialURL, Complain));
- LOG(Media, "HTMLMediaElement::loadResource(%s, %s)", urlForLogging(initialURL.string()).utf8().data(), contentType.raw().utf8().data());
+ LOG(Media, "HTMLMediaElement::loadResource(%s, %s)", urlForLogging(initialURL), contentType.raw().utf8().data());
Frame* frame = document()->frame();
if (!frame)
@@ -712,7 +707,7 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content
m_currentSrc = url;
- LOG(Media, "HTMLMediaElement::loadResource - m_currentSrc -> %s", urlForLogging(m_currentSrc).utf8().data());
+ LOG(Media, "HTMLMediaElement::loadResource - m_currentSrc -> %s", urlForLogging(m_currentSrc));
if (m_sendProgressEvents)
startProgressEventTimer();
@@ -732,7 +727,7 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content
else
m_player->setMediaElementType(MediaPlayer::Audio);
#endif
- m_player->load(m_currentSrc, contentType);
+ m_player->load(m_currentSrc.string(), contentType);
// If there is no poster to display, allow the media engine to render video frames as soon as
// they are available.
@@ -745,7 +740,7 @@ void HTMLMediaElement::loadResource(const KURL& initialURL, ContentType& content
bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidSourceAction actionIfInvalid)
{
if (!url.isValid()) {
- LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE because url is invalid", urlForLogging(url.string()).utf8().data());
+ LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE because url is invalid", urlForLogging(url));
return false;
}
@@ -753,7 +748,7 @@ bool HTMLMediaElement::isSafeToLoadURL(const KURL& url, InvalidSourceAction acti
if (!frame || !document()->securityOrigin()->canDisplay(url)) {
if (actionIfInvalid == Complain)
FrameLoader::reportLocalLoadFailed(frame, url.string());
- LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE rejected by SecurityOrigin", urlForLogging(url.string()).utf8().data());
+ LOG(Media, "HTMLMediaElement::isSafeToLoadURL(%s) -> FALSE rejected by SecurityOrigin", urlForLogging(url));
return false;
}
@@ -1741,7 +1736,7 @@ KURL HTMLMediaElement::selectNextSourceChild(ContentType *contentType, InvalidSo
mediaURL = source->getNonEmptyURLAttribute(srcAttr);
#if !LOG_DISABLED
if (shouldLog)
- LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'src' is %s", urlForLogging(mediaURL).utf8().data());
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild - 'src' is %s", urlForLogging(mediaURL));
#endif
if (mediaURL.isEmpty())
goto check_again;
@@ -1792,7 +1787,7 @@ check_again:
#if !LOG_DISABLED
if (shouldLog)
- LOG(Media, "HTMLMediaElement::selectNextSourceChild -> %p, %s", m_currentSourceNode, canUse ? urlForLogging(mediaURL.string()).utf8().data() : "");
+ LOG(Media, "HTMLMediaElement::selectNextSourceChild -> %p, %s", m_currentSourceNode, canUse ? urlForLogging(mediaURL) : "");
#endif
return canUse ? mediaURL : KURL();
}
@@ -1804,7 +1799,7 @@ void HTMLMediaElement::sourceWasAdded(HTMLSourceElement* source)
#if !LOG_DISABLED
if (source->hasTagName(sourceTag)) {
KURL url = source->getNonEmptyURLAttribute(srcAttr);
- LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLogging(url).utf8().data());
+ LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLogging(url));
}
#endif
@@ -1851,7 +1846,7 @@ void HTMLMediaElement::sourceWillBeRemoved(HTMLSourceElement* source)
#if !LOG_DISABLED
if (source->hasTagName(sourceTag)) {
KURL url = source->getNonEmptyURLAttribute(srcAttr);
- LOG(Media, "HTMLMediaElement::sourceWillBeRemoved - 'src' is %s", urlForLogging(url).utf8().data());
+ LOG(Media, "HTMLMediaElement::sourceWillBeRemoved - 'src' is %s", urlForLogging(url));
}
#endif
@@ -2462,10 +2457,10 @@ void HTMLMediaElement::getPluginProxyParams(KURL& url, Vector<String>& names, Ve
if (!isSafeToLoadURL(url, Complain))
url = selectNextSourceChild(0, DoNothing);
- m_currentSrc = url.string();
- if (url.isValid() && loader && loader->willLoadMediaElementURL(url)) {
+ m_currentSrc = url;
+ if (url.isValid() && frame && frame->loader()->willLoadMediaElementURL(url)) {
names.append("_media_element_src_");
- values.append(m_currentSrc);
+ values.append(m_currentSrc.string());
}
}
diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h
index 987cf87..b85c554 100644
--- a/Source/WebCore/html/HTMLMediaElement.h
+++ b/Source/WebCore/html/HTMLMediaElement.h
@@ -86,7 +86,7 @@ public:
// network state
void setSrc(const String&);
- String currentSrc() const;
+ const KURL& currentSrc() const { return m_currentSrc; }
enum NetworkState { NETWORK_EMPTY, NETWORK_IDLE, NETWORK_LOADING, NETWORK_NO_SOURCE };
NetworkState networkState() const;
@@ -342,8 +342,8 @@ private:
NetworkState m_networkState;
ReadyState m_readyState;
ReadyState m_readyStateMaximum;
- String m_currentSrc;
-
+ KURL m_currentSrc;
+
RefPtr<MediaError> m_error;
float m_volume;
diff --git a/Source/WebCore/html/HTMLMediaElement.idl b/Source/WebCore/html/HTMLMediaElement.idl
index c7e6b07..0bca569 100644
--- a/Source/WebCore/html/HTMLMediaElement.idl
+++ b/Source/WebCore/html/HTMLMediaElement.idl
@@ -31,7 +31,7 @@ interface [Conditional=VIDEO] HTMLMediaElement : HTMLElement {
// network state
attribute [Reflect, URL] DOMString src;
- readonly attribute DOMString currentSrc;
+ readonly attribute [URL] DOMString currentSrc;
const unsigned short NETWORK_EMPTY = 0;
const unsigned short NETWORK_IDLE = 1;
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
index c814c66..3622b06 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
@@ -51,48 +51,73 @@ void CanvasRenderingContext::deref()
m_canvas->deref();
}
-void CanvasRenderingContext::checkOrigin(const CanvasPattern* pattern)
+bool CanvasRenderingContext::wouldTaintOrigin(const CanvasPattern* pattern)
{
if (canvas()->originClean() && pattern && !pattern->originClean())
- canvas()->setOriginTainted();
+ return true;
+ return false;
}
-void CanvasRenderingContext::checkOrigin(const HTMLCanvasElement* sourceCanvas)
+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLCanvasElement* sourceCanvas)
{
if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean())
- canvas()->setOriginTainted();
+ return true;
+ return false;
}
-void CanvasRenderingContext::checkOrigin(const HTMLImageElement* image)
+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* image)
{
if (!image || !canvas()->originClean())
- return;
+ return false;
CachedImage* cachedImage = image->cachedImage();
- checkOrigin(cachedImage->response().url());
+ if (!cachedImage->passesAccessControlCheck(canvas()->securityOrigin())) {
+ if (wouldTaintOrigin(cachedImage->response().url()))
+ return true;
+ }
- if (canvas()->originClean() && !cachedImage->image()->hasSingleSecurityOrigin())
- canvas()->setOriginTainted();
+ if (!cachedImage->image()->hasSingleSecurityOrigin())
+ return true;
+
+ return false;
}
-void CanvasRenderingContext::checkOrigin(const HTMLVideoElement* video)
+bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
{
#if ENABLE(VIDEO)
- checkOrigin(KURL(KURL(), video->currentSrc()));
- if (canvas()->originClean() && video && !video->hasSingleSecurityOrigin())
- canvas()->setOriginTainted();
+ // FIXME: This check is likely wrong when a redirect is involved. We need
+ // to test the finalURL. Please be careful when fixing this issue not to
+ // make currentSrc be the final URL because then the
+ // HTMLMediaElement.currentSrc DOM API would leak redirect destinations!
+ if (!video || !canvas()->originClean())
+ return false;
+
+ if (wouldTaintOrigin(video->currentSrc()))
+ return true;
+
+ if (!video->hasSingleSecurityOrigin())
+ return true;
#endif
+
+ return false;
}
-void CanvasRenderingContext::checkOrigin(const KURL& url)
+bool CanvasRenderingContext::wouldTaintOrigin(const KURL& url)
{
- if (!canvas()->originClean() || m_cleanOrigins.contains(url.string()))
- return;
+ if (!canvas()->originClean() || m_cleanURLs.contains(url.string()))
+ return false;
- if (canvas()->securityOrigin().taintsCanvas(url))
+ if (canvas()->securityOrigin()->taintsCanvas(url))
+ return true;
+
+ m_cleanURLs.add(url.string());
+ return false;
+}
+
+void CanvasRenderingContext::checkOrigin(const KURL& url)
+{
+ if (wouldTaintOrigin(url))
canvas()->setOriginTainted();
- else
- m_cleanOrigins.add(url.string());
}
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.h b/Source/WebCore/html/canvas/CanvasRenderingContext.h
index a143596..8426752 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.h
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.h
@@ -27,6 +27,7 @@
#define CanvasRenderingContext_h
#include "GraphicsLayer.h"
+#include "HTMLCanvasElement.h"
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
@@ -35,7 +36,6 @@
namespace WebCore {
class CanvasPattern;
-class HTMLCanvasElement;
class HTMLImageElement;
class HTMLVideoElement;
class KURL;
@@ -44,7 +44,6 @@ class WebGLObject;
class CanvasRenderingContext {
WTF_MAKE_NONCOPYABLE(CanvasRenderingContext); WTF_MAKE_FAST_ALLOCATED;
public:
- CanvasRenderingContext(HTMLCanvasElement*);
virtual ~CanvasRenderingContext() { }
// Ref and deref the m_canvas
@@ -65,15 +64,23 @@ public:
#endif
protected:
- void checkOrigin(const CanvasPattern*);
- void checkOrigin(const HTMLCanvasElement*);
- void checkOrigin(const HTMLImageElement*);
- void checkOrigin(const HTMLVideoElement*);
+ CanvasRenderingContext(HTMLCanvasElement*);
+ bool wouldTaintOrigin(const CanvasPattern*);
+ bool wouldTaintOrigin(const HTMLCanvasElement*);
+ bool wouldTaintOrigin(const HTMLImageElement*);
+ bool wouldTaintOrigin(const HTMLVideoElement*);
+ bool wouldTaintOrigin(const KURL&);
+
+ template<class T> void checkOrigin(const T* arg)
+ {
+ if (wouldTaintOrigin(arg))
+ canvas()->setOriginTainted();
+ }
void checkOrigin(const KURL&);
private:
HTMLCanvasElement* m_canvas;
- HashSet<String> m_cleanOrigins;
+ HashSet<String> m_cleanURLs;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index b0a78c5..9d08ec4 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -84,6 +84,14 @@ using namespace HTMLNames;
static const char* const defaultFont = "10px sans-serif";
+static bool isOriginClean(CachedImage* cachedImage, SecurityOrigin* securityOrigin)
+{
+ if (!cachedImage->image()->hasSingleSecurityOrigin())
+ return false;
+ if (cachedImage->passesAccessControlCheck(securityOrigin))
+ return true;
+ return !securityOrigin->taintsCanvas(cachedImage->response().url());
+}
class CanvasStrokeStyleApplier : public StrokeStyleApplier {
public:
@@ -1540,7 +1548,7 @@ PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageEleme
if (!cachedImage || !image->cachedImage()->image())
return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
- bool originClean = !canvas()->securityOrigin().taintsCanvas(KURL(KURL(), cachedImage->response().url())) && cachedImage->image()->hasSingleSecurityOrigin();
+ bool originClean = isOriginClean(cachedImage, canvas()->securityOrigin());
return CanvasPattern::create(cachedImage->image(), repeatX, repeatY, originClean);
}
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
index 933d37f..b0b7e69a 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -2792,14 +2792,13 @@ void WebGLRenderingContext::polygonOffset(GC3Dfloat factor, GC3Dfloat units)
cleanupAfterGraphicsCall(false);
}
-void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
+void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode&)
{
if (isContextLost())
return;
- if (!canvas()->originClean()) {
- ec = SECURITY_ERR;
- return;
- }
+ // Due to WebGL's same-origin restrictions, it is not possible to
+ // taint the origin using the WebGL API.
+ ASSERT(canvas()->originClean());
// Validate input parameters.
if (!pixels) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
@@ -3142,7 +3141,11 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
return;
if (!validateHTMLImageElement(image))
return;
- checkOrigin(image);
+ if (wouldTaintOrigin(image)) {
+ ec = SECURITY_ERR;
+ return;
+ }
+
texImage2DImpl(target, level, internalformat, format, type, image->cachedImage()->image(),
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
@@ -3157,7 +3160,10 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
- checkOrigin(canvas);
+ if (wouldTaintOrigin(canvas)) {
+ ec = SECURITY_ERR;
+ return;
+ }
RefPtr<ImageData> imageData = canvas->getImageData();
if (imageData)
texImage2D(target, level, internalformat, format, type, imageData.get(), ec);
@@ -3167,7 +3173,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
}
#if ENABLE(VIDEO)
-PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video)
+PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, ExceptionCode& ec)
{
if (!video || !video->videoWidth() || !video->videoHeight()) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
@@ -3179,7 +3185,10 @@ PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* vid
m_context->synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY);
return 0;
}
- checkOrigin(video);
+ if (wouldTaintOrigin(video)) {
+ ec = SECURITY_ERR;
+ return 0;
+ }
IntRect destRect(0, 0, size.width(), size.height());
// FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
video->paintCurrentFrameInContext(buf->context(), destRect);
@@ -3192,8 +3201,8 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
ec = 0;
if (isContextLost())
return;
- RefPtr<Image> image = videoFrameToImage(video);
- if (!video)
+ RefPtr<Image> image = videoFrameToImage(video, ec);
+ if (!image)
return;
texImage2DImpl(target, level, internalformat, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
@@ -3334,7 +3343,10 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
return;
if (!validateHTMLImageElement(image))
return;
- checkOrigin(image);
+ if (wouldTaintOrigin(image)) {
+ ec = SECURITY_ERR;
+ return;
+ }
texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image->cachedImage()->image(),
m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
@@ -3349,7 +3361,10 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
- checkOrigin(canvas);
+ if (wouldTaintOrigin(canvas)) {
+ ec = SECURITY_ERR;
+ return;
+ }
RefPtr<ImageData> imageData = canvas->getImageData();
if (imageData)
texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), ec);
@@ -3365,8 +3380,8 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
ec = 0;
if (isContextLost())
return;
- RefPtr<Image> image = videoFrameToImage(video);
- if (!video)
+ RefPtr<Image> image = videoFrameToImage(video, ec);
+ if (!image)
return;
texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), m_unpackFlipY, m_unpackPremultiplyAlpha, ec);
}
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h
index 23c147d..9eb170b 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h
@@ -348,7 +348,7 @@ public:
bool validateWebGLObject(WebGLObject*);
#if ENABLE(VIDEO)
- PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*);
+ PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, ExceptionCode&);
#endif
RefPtr<GraphicsContext3D> m_context;
diff --git a/Source/WebCore/html/parser/CSSPreloadScanner.cpp b/Source/WebCore/html/parser/CSSPreloadScanner.cpp
index 3c23b9f..18c28c5 100644
--- a/Source/WebCore/html/parser/CSSPreloadScanner.cpp
+++ b/Source/WebCore/html/parser/CSSPreloadScanner.cpp
@@ -194,8 +194,10 @@ void CSSPreloadScanner::emitRule()
{
if (equalIgnoringCase("import", m_rule.data(), m_rule.size())) {
String value = parseCSSStringOrURL(m_ruleValue.data(), m_ruleValue.size());
- if (!value.isEmpty())
- m_document->cachedResourceLoader()->preload(CachedResource::CSSStyleSheet, value, String(), m_scanningBody);
+ if (!value.isEmpty()) {
+ ResourceRequest request(m_document->completeURL(value));
+ m_document->cachedResourceLoader()->preload(CachedResource::CSSStyleSheet, request, String(), m_scanningBody);
+ }
m_state = Initial;
} else if (equalIgnoringCase("charset", m_rule.data(), m_rule.size()))
m_state = Initial;
diff --git a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
index 5514597..5ddff90 100644
--- a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
+++ b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
@@ -126,12 +126,13 @@ public:
return;
CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
+ ResourceRequest request = document->completeURL(m_urlToLoad);
if (m_tagName == scriptTag)
- cachedResourceLoader->preload(CachedResource::Script, m_urlToLoad, m_charset, scanningBody);
+ cachedResourceLoader->preload(CachedResource::Script, request, m_charset, scanningBody);
else if (m_tagName == imgTag || (m_tagName == inputTag && m_inputIsImage))
- cachedResourceLoader->preload(CachedResource::ImageResource, m_urlToLoad, String(), scanningBody);
+ cachedResourceLoader->preload(CachedResource::ImageResource, request, String(), scanningBody);
else if (m_tagName == linkTag && m_linkIsStyleSheet && m_linkMediaAttributeIsScreen)
- cachedResourceLoader->preload(CachedResource::CSSStyleSheet, m_urlToLoad, m_charset, scanningBody);
+ cachedResourceLoader->preload(CachedResource::CSSStyleSheet, request, m_charset, scanningBody);
}
const AtomicString& tagName() const { return m_tagName; }
diff --git a/Source/WebCore/loader/CrossOriginAccessControl.cpp b/Source/WebCore/loader/CrossOriginAccessControl.cpp
index 8ca821e..671c185 100644
--- a/Source/WebCore/loader/CrossOriginAccessControl.cpp
+++ b/Source/WebCore/loader/CrossOriginAccessControl.cpp
@@ -43,7 +43,10 @@ bool isOnAccessControlSimpleRequestMethodWhitelist(const String& method)
bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name, const String& value)
{
- if (equalIgnoringCase(name, "accept") || equalIgnoringCase(name, "accept-language") || equalIgnoringCase(name, "content-language"))
+ if (equalIgnoringCase(name, "accept")
+ || equalIgnoringCase(name, "accept-language")
+ || equalIgnoringCase(name, "content-language")
+ || equalIgnoringCase(name, "origin"))
return true;
// Preflight is required for MIME types that can not be sent via form submission.
@@ -93,6 +96,42 @@ bool isOnAccessControlResponseHeaderWhitelist(const String& name)
return allowedCrossOriginResponseHeaders->contains(name);
}
+void updateRequestForAccessControl(ResourceRequest& request, SecurityOrigin* securityOrigin, bool allowCredentials)
+{
+ request.removeCredentials();
+ request.setAllowCookies(allowCredentials);
+ request.setHTTPOrigin(securityOrigin->toString());
+}
+
+ResourceRequest createAccessControlPreflightRequest(const ResourceRequest& request, SecurityOrigin* securityOrigin, bool allowCredentials)
+{
+ ResourceRequest preflightRequest(request.url());
+ updateRequestForAccessControl(preflightRequest, securityOrigin, allowCredentials);
+ preflightRequest.setHTTPMethod("OPTIONS");
+ preflightRequest.setHTTPHeaderField("Access-Control-Request-Method", request.httpMethod());
+ preflightRequest.setPriority(request.priority());
+
+ const HTTPHeaderMap& requestHeaderFields = request.httpHeaderFields();
+
+ if (requestHeaderFields.size() > 0) {
+ Vector<UChar> headerBuffer;
+ HTTPHeaderMap::const_iterator it = requestHeaderFields.begin();
+ append(headerBuffer, it->first);
+ ++it;
+
+ HTTPHeaderMap::const_iterator end = requestHeaderFields.end();
+ for (; it != end; ++it) {
+ headerBuffer.append(',');
+ headerBuffer.append(' ');
+ append(headerBuffer, it->first);
+ }
+
+ preflightRequest.setHTTPHeaderField("Access-Control-Request-Headers", String::adopt(headerBuffer));
+ }
+
+ return preflightRequest;
+}
+
bool passesAccessControlCheck(const ResourceResponse& response, bool includeCredentials, SecurityOrigin* securityOrigin, String& errorDescription)
{
// A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent,
diff --git a/Source/WebCore/loader/CrossOriginAccessControl.h b/Source/WebCore/loader/CrossOriginAccessControl.h
index 50c231e..74b4d58 100644
--- a/Source/WebCore/loader/CrossOriginAccessControl.h
+++ b/Source/WebCore/loader/CrossOriginAccessControl.h
@@ -27,20 +27,24 @@
#ifndef CrossOriginAccessControl_h
#define CrossOriginAccessControl_h
+#include "ResourceRequest.h"
#include <wtf/Forward.h>
namespace WebCore {
- class HTTPHeaderMap;
- class ResourceResponse;
- class SecurityOrigin;
+class HTTPHeaderMap;
+class ResourceResponse;
+class SecurityOrigin;
- bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap&);
- bool isOnAccessControlSimpleRequestMethodWhitelist(const String&);
- bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name, const String& value);
- bool isOnAccessControlResponseHeaderWhitelist(const String&);
+bool isSimpleCrossOriginAccessRequest(const String& method, const HTTPHeaderMap&);
+bool isOnAccessControlSimpleRequestMethodWhitelist(const String&);
+bool isOnAccessControlSimpleRequestHeaderWhitelist(const String& name, const String& value);
+bool isOnAccessControlResponseHeaderWhitelist(const String&);
- bool passesAccessControlCheck(const ResourceResponse&, bool includeCredentials, SecurityOrigin*, String& errorDescription);
+void updateRequestForAccessControl(ResourceRequest&, SecurityOrigin*, bool allowCredentials);
+ResourceRequest createAccessControlPreflightRequest(const ResourceRequest&, SecurityOrigin*, bool allowCredentials);
+
+bool passesAccessControlCheck(const ResourceResponse&, bool includeCredentials, SecurityOrigin*, String& errorDescription);
} // namespace WebCore
diff --git a/Source/WebCore/loader/DocumentThreadableLoader.cpp b/Source/WebCore/loader/DocumentThreadableLoader.cpp
index 2fbf324..7f545a1 100644
--- a/Source/WebCore/loader/DocumentThreadableLoader.cpp
+++ b/Source/WebCore/loader/DocumentThreadableLoader.cpp
@@ -89,8 +89,7 @@ DocumentThreadableLoader::DocumentThreadableLoader(Document* document, Threadabl
ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl);
OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceRequest(request));
- crossOriginRequest->removeCredentials();
- crossOriginRequest->setAllowCookies(m_options.allowCredentials);
+ updateRequestForAccessControl(*crossOriginRequest, m_document->securityOrigin(), m_options.allowCredentials);
if (!m_options.forcePreflight && isSimpleCrossOriginAccessRequest(crossOriginRequest->httpMethod(), crossOriginRequest->httpHeaderFields()))
makeSimpleCrossOriginAccessRequest(*crossOriginRequest);
@@ -109,47 +108,18 @@ void DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest(const Resource
ASSERT(isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields()));
// Cross-origin requests are only defined for HTTP. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied.
+ // FIXME: Consider allowing simple CORS requests to non-HTTP URLs.
if (!request.url().protocolInHTTPFamily()) {
m_client->didFail(ResourceError(errorDomainWebKitInternal, 0, request.url().string(), "Cross origin requests are only supported for HTTP."));
return;
}
- // Make a copy of the passed request so that we can modify some details.
- ResourceRequest crossOriginRequest(request);
- crossOriginRequest.setHTTPOrigin(m_document->securityOrigin()->toString());
-
- loadRequest(crossOriginRequest, DoSecurityCheck);
+ loadRequest(request, DoSecurityCheck);
}
void DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight(const ResourceRequest& request)
{
- ResourceRequest preflightRequest(request.url());
- preflightRequest.removeCredentials();
- preflightRequest.setHTTPOrigin(m_document->securityOrigin()->toString());
- preflightRequest.setAllowCookies(m_options.allowCredentials);
- preflightRequest.setHTTPMethod("OPTIONS");
- preflightRequest.setHTTPHeaderField("Access-Control-Request-Method", request.httpMethod());
-
- const HTTPHeaderMap& requestHeaderFields = request.httpHeaderFields();
-
- if (requestHeaderFields.size() > 0) {
- Vector<UChar> headerBuffer;
- HTTPHeaderMap::const_iterator it = requestHeaderFields.begin();
- append(headerBuffer, it->first);
- ++it;
-
- HTTPHeaderMap::const_iterator end = requestHeaderFields.end();
- for (; it != end; ++it) {
- headerBuffer.append(',');
- headerBuffer.append(' ');
- append(headerBuffer, it->first);
- }
-
- preflightRequest.setHTTPHeaderField("Access-Control-Request-Headers", String::adopt(headerBuffer));
- }
-
- preflightRequest.setPriority(request.priority());
-
+ ResourceRequest preflightRequest = createAccessControlPreflightRequest(request, m_document->securityOrigin(), m_options.allowCredentials);
loadRequest(preflightRequest, DoSecurityCheck);
}
diff --git a/Source/WebCore/loader/ImageLoader.cpp b/Source/WebCore/loader/ImageLoader.cpp
index 069b40e..0c1fe99 100644
--- a/Source/WebCore/loader/ImageLoader.cpp
+++ b/Source/WebCore/loader/ImageLoader.cpp
@@ -24,6 +24,7 @@
#include "CachedImage.h"
#include "CachedResourceLoader.h"
+#include "CrossOriginAccessControl.h"
#include "Document.h"
#include "Element.h"
#include "HTMLNames.h"
@@ -160,16 +161,24 @@ void ImageLoader::updateFromElement()
// need (<rdar://problem/5994621>).
CachedImage* newImage = 0;
if (!(attr.isNull() || (attr.isEmpty() && document->baseURI().isLocalFile()))) {
+ ResourceRequest request = ResourceRequest(document->completeURL(sourceURI(attr)));
+
+ String crossOriginMode = m_element->fastGetAttribute(HTMLNames::crossoriginAttr);
+ if (!crossOriginMode.isNull()) {
+ bool allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials");
+ updateRequestForAccessControl(request, document->securityOrigin(), allowCredentials);
+ }
+
if (m_loadManually) {
bool autoLoadOtherImages = document->cachedResourceLoader()->autoLoadImages();
document->cachedResourceLoader()->setAutoLoadImages(false);
- newImage = new CachedImage(sourceURI(attr));
+ newImage = new CachedImage(request);
newImage->setLoading(true);
newImage->setOwningCachedResourceLoader(document->cachedResourceLoader());
document->cachedResourceLoader()->m_documentResources.set(newImage->url(), newImage);
document->cachedResourceLoader()->setAutoLoadImages(autoLoadOtherImages);
} else
- newImage = document->cachedResourceLoader()->requestImage(sourceURI(attr));
+ newImage = document->cachedResourceLoader()->requestImage(request);
// If we do not have an image here, it means that a cross-site
// violation occurred.
diff --git a/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp b/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp
index ae7a03c..53a04fb 100644
--- a/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp
+++ b/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp
@@ -37,8 +37,8 @@
namespace WebCore {
-CachedCSSStyleSheet::CachedCSSStyleSheet(const String& url, const String& charset)
- : CachedResource(url, CSSStyleSheet)
+CachedCSSStyleSheet::CachedCSSStyleSheet(const ResourceRequest& resourceRequest, const String& charset)
+ : CachedResource(resourceRequest, CSSStyleSheet)
, m_decoder(TextResourceDecoder::create("text/css", charset))
{
// Prefer text/css but accept any type (dell.com serves a stylesheet
@@ -53,7 +53,7 @@ CachedCSSStyleSheet::~CachedCSSStyleSheet()
void CachedCSSStyleSheet::didAddClient(CachedResourceClient *c)
{
if (!isLoading())
- c->setCSSStyleSheet(m_url, m_response.url(), m_decoder->encoding().name(), this);
+ c->setCSSStyleSheet(m_resourceRequest.url(), m_response.url(), m_decoder->encoding().name(), this);
}
void CachedCSSStyleSheet::allClientsRemoved()
@@ -113,7 +113,7 @@ void CachedCSSStyleSheet::checkNotify()
CachedResourceClientWalker w(m_clients);
while (CachedResourceClient *c = w.next())
- c->setCSSStyleSheet(m_url, m_response.url(), m_decoder->encoding().name(), this);
+ c->setCSSStyleSheet(m_resourceRequest.url(), m_response.url(), m_decoder->encoding().name(), this);
}
void CachedCSSStyleSheet::error(CachedResource::Status status)
diff --git a/Source/WebCore/loader/cache/CachedCSSStyleSheet.h b/Source/WebCore/loader/cache/CachedCSSStyleSheet.h
index a982e03..6398717 100644
--- a/Source/WebCore/loader/cache/CachedCSSStyleSheet.h
+++ b/Source/WebCore/loader/cache/CachedCSSStyleSheet.h
@@ -37,7 +37,7 @@ namespace WebCore {
class CachedCSSStyleSheet : public CachedResource {
public:
- CachedCSSStyleSheet(const String& URL, const String& charset);
+ CachedCSSStyleSheet(const ResourceRequest&, const String& charset);
virtual ~CachedCSSStyleSheet();
const String sheetText(bool enforceMIMEType = true, bool* hasValidMIMEType = 0) const;
diff --git a/Source/WebCore/loader/cache/CachedFont.cpp b/Source/WebCore/loader/cache/CachedFont.cpp
index 30e0b80..e5cef59 100644
--- a/Source/WebCore/loader/cache/CachedFont.cpp
+++ b/Source/WebCore/loader/cache/CachedFont.cpp
@@ -55,8 +55,8 @@
namespace WebCore {
-CachedFont::CachedFont(const String &url)
- : CachedResource(url, FontResource)
+CachedFont::CachedFont(const ResourceRequest& resourceRequest)
+ : CachedResource(resourceRequest, FontResource)
, m_fontData(0)
, m_loadInitiated(false)
{
diff --git a/Source/WebCore/loader/cache/CachedFont.h b/Source/WebCore/loader/cache/CachedFont.h
index 930a29a..1121bc1 100644
--- a/Source/WebCore/loader/cache/CachedFont.h
+++ b/Source/WebCore/loader/cache/CachedFont.h
@@ -49,7 +49,7 @@ struct FontCustomPlatformData;
class CachedFont : public CachedResource {
public:
- CachedFont(const String& url);
+ CachedFont(const ResourceRequest&);
virtual ~CachedFont();
virtual void load(CachedResourceLoader* cachedResourceLoader);
diff --git a/Source/WebCore/loader/cache/CachedImage.cpp b/Source/WebCore/loader/cache/CachedImage.cpp
index 6867302..e96d784 100644
--- a/Source/WebCore/loader/cache/CachedImage.cpp
+++ b/Source/WebCore/loader/cache/CachedImage.cpp
@@ -52,8 +52,8 @@ using std::max;
namespace WebCore {
-CachedImage::CachedImage(const String& url)
- : CachedResource(url, ImageResource)
+CachedImage::CachedImage(const ResourceRequest& resourceRequest)
+ : CachedResource(resourceRequest, ImageResource)
, m_image(0)
, m_decodedDataDeletionTimer(this, &CachedImage::decodedDataDeletionTimerFired)
, m_shouldPaintBrokenImage(true)
@@ -63,7 +63,7 @@ CachedImage::CachedImage(const String& url)
}
CachedImage::CachedImage(Image* image)
- : CachedResource(String(), ImageResource)
+ : CachedResource(ResourceRequest(), ImageResource)
, m_image(image)
, m_decodedDataDeletionTimer(this, &CachedImage::decodedDataDeletionTimerFired)
, m_shouldPaintBrokenImage(true)
@@ -86,7 +86,7 @@ void CachedImage::decodedDataDeletionTimerFired(Timer<CachedImage>*)
void CachedImage::load(CachedResourceLoader* cachedResourceLoader)
{
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
- if (!cachedResourceLoader || (cachedResourceLoader->autoLoadImages() && !cachedResourceLoader->shouldBlockNetworkImage(m_url)))
+ if (!cachedResourceLoader || (cachedResourceLoader->autoLoadImages() && !cachedResourceLoader->shouldBlockNetworkImage(m_resourceRequest.url())))
#else
if (!cachedResourceLoader || cachedResourceLoader->autoLoadImages())
#endif
@@ -231,7 +231,7 @@ void CachedImage::checkShouldPaintBrokenImage()
if (!frame)
return;
- m_shouldPaintBrokenImage = frame->loader()->client()->shouldPaintBrokenImage(KURL(ParsedURLString, m_url));
+ m_shouldPaintBrokenImage = frame->loader()->client()->shouldPaintBrokenImage(m_resourceRequest.url());
}
void CachedImage::clear()
diff --git a/Source/WebCore/loader/cache/CachedImage.h b/Source/WebCore/loader/cache/CachedImage.h
index 79643d7..dc12ba2d 100644
--- a/Source/WebCore/loader/cache/CachedImage.h
+++ b/Source/WebCore/loader/cache/CachedImage.h
@@ -38,7 +38,7 @@ class CachedImage : public CachedResource, public ImageObserver {
friend class MemoryCache;
public:
- CachedImage(const String& url);
+ CachedImage(const ResourceRequest&);
CachedImage(Image*);
virtual ~CachedImage();
diff --git a/Source/WebCore/loader/cache/CachedResource.cpp b/Source/WebCore/loader/cache/CachedResource.cpp
index d94a737..86ed692 100644
--- a/Source/WebCore/loader/cache/CachedResource.cpp
+++ b/Source/WebCore/loader/cache/CachedResource.cpp
@@ -32,6 +32,7 @@
#include "CachedResourceHandle.h"
#include "CachedResourceLoader.h"
#include "CachedResourceRequest.h"
+#include "CrossOriginAccessControl.h"
#include "Frame.h"
#include "FrameLoaderClient.h"
#include "KURL.h"
@@ -68,7 +69,11 @@ static ResourceLoadPriority defaultPriorityForResourceType(CachedResource::Type
case CachedResource::ImageResource:
return ResourceLoadPriorityLow;
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
+ case CachedResource::LinkPrefetch:
+ return ResourceLoadPriorityVeryLow;
+ case CachedResource::LinkPrerender:
+ return ResourceLoadPriorityVeryLow;
+ case CachedResource::LinkSubresource:
return ResourceLoadPriorityVeryLow;
#endif
}
@@ -80,8 +85,8 @@ static ResourceLoadPriority defaultPriorityForResourceType(CachedResource::Type
static RefCountedLeakCounter cachedResourceLeakCounter("CachedResource");
#endif
-CachedResource::CachedResource(const String& url, Type type)
- : m_url(url)
+CachedResource::CachedResource(const ResourceRequest& request, Type type)
+ : m_resourceRequest(request)
, m_request(0)
, m_loadPriority(defaultPriorityForResourceType(type))
, m_responseTimestamp(currentTime())
@@ -115,7 +120,7 @@ CachedResource::CachedResource(const String& url, Type type)
cachedResourceLeakCounter.increment();
#endif
#if USE(CHROME_NETWORK_STACK)
- m_statHubHash = StatHubHash(url.latin1().data());
+ m_statHubHash = StatHubHash(request.url().string().latin1().data());
#endif // USE(CHROME_NETWORK_STACK)
}
@@ -191,6 +196,12 @@ void CachedResource::setInCache(bool inCache) {
#endif // USE(CHROME_NETWORK_STACK)
}
+bool CachedResource::passesAccessControlCheck(SecurityOrigin* securityOrigin)
+{
+ String errorDescription;
+ return WebCore::passesAccessControlCheck(m_response, resourceRequest().allowCookies(), securityOrigin, errorDescription);
+}
+
bool CachedResource::isExpired() const
{
if (m_response.isNull())
diff --git a/Source/WebCore/loader/cache/CachedResource.h b/Source/WebCore/loader/cache/CachedResource.h
index f0c3fe1..75c1692 100644
--- a/Source/WebCore/loader/cache/CachedResource.h
+++ b/Source/WebCore/loader/cache/CachedResource.h
@@ -29,6 +29,7 @@
#include "PlatformString.h"
#include "PurgePriority.h"
#include "ResourceLoadPriority.h"
+#include "ResourceRequest.h"
#include "ResourceResponse.h"
#include <wtf/HashCountedSet.h>
#include <wtf/HashSet.h>
@@ -47,6 +48,7 @@ class CachedResourceRequest;
class Frame;
class InspectorResource;
class PurgeableBuffer;
+class SecurityOrigin;
// A resource that is held in the cache. Classes who want to use this object should derive
// from CachedResourceClient, to get the function calls in case the requested data has arrived.
@@ -66,7 +68,9 @@ public:
, XSLStyleSheet
#endif
#if ENABLE(LINK_PREFETCH)
- , LinkResource
+ , LinkPrefetch
+ , LinkPrerender
+ , LinkSubresource
#endif
};
@@ -78,7 +82,7 @@ public:
DecodeError
};
- CachedResource(const String& url, Type);
+ CachedResource(const ResourceRequest&, Type);
virtual ~CachedResource();
virtual void load(CachedResourceLoader* cachedResourceLoader) { load(cachedResourceLoader, false, DoSecurityCheck, true); }
@@ -91,7 +95,8 @@ public:
virtual bool shouldIgnoreHTTPStatusCodeErrors() const { return false; }
- const String &url() const { return m_url; }
+ ResourceRequest& resourceRequest() { return m_resourceRequest; }
+ const KURL& url() const { return m_resourceRequest.url();}
Type type() const { return static_cast<Type>(m_type); }
ResourceLoadPriority loadPriority() const { return m_loadPriority; }
@@ -134,7 +139,7 @@ public:
bool isLinkResource() const
{
#if ENABLE(LINK_PREFETCH)
- return type() == LinkResource;
+ return type() == LinkPrefetch || type() == LinkPrerender || type() == LinkSubresource;
#else
return false;
#endif
@@ -147,6 +152,8 @@ public:
// Updates the expire date on the cache entry file
void finish();
+ bool passesAccessControlCheck(SecurityOrigin*);
+
// Called by the cache if the object has been removed from the cache
// while still being referenced. This means the object should delete itself
// if the number of clients observing it ever drops to 0.
@@ -229,7 +236,7 @@ protected:
HashCountedSet<CachedResourceClient*> m_clients;
- String m_url;
+ ResourceRequest m_resourceRequest;
String m_accept;
CachedResourceRequest* m_request;
ResourceLoadPriority m_loadPriority;
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.cpp b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
index 129ca52..4dab8e0 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.cpp
@@ -64,32 +64,36 @@ static void SaveSubURL(CachedResourceLoader* cachedResourceLoader, CachedResourc
#if USE(CHROME_NETWORK_STACK)
if (NULL != resource && NULL!=cachedResourceLoader) {
unsigned short main_url_len = cachedResourceLoader->document()->url().string().length();
- unsigned short sub_url_len = resource->url().length();
+ unsigned short sub_url_len = resource->url().string().length();
if (sub_url_len && main_url_len && cachedResourceLoader->document()->url().protocolInHTTPFamily() && KURL(ParsedURLString,resource->url()).protocolInHTTPFamily()) {
- StatHubUpdateSubUrl(cachedResourceLoader->document()->url().string().latin1().data(), resource->url().latin1().data());
+ StatHubUpdateSubUrl(cachedResourceLoader->document()->url().string().latin1().data(), resource->url().string().latin1().data());
}
}
#endif // USE(CHROME_NETWORK_STACK)
}
-static CachedResource* createResource(CachedResource::Type type, const KURL& url, const String& charset)
+static CachedResource* createResource(CachedResource::Type type, ResourceRequest& request, const String& charset)
{
switch (type) {
case CachedResource::ImageResource:
- return new CachedImage(url.string());
+ return new CachedImage(request);
case CachedResource::CSSStyleSheet:
- return new CachedCSSStyleSheet(url.string(), charset);
+ return new CachedCSSStyleSheet(request, charset);
case CachedResource::Script:
- return new CachedScript(url.string(), charset);
+ return new CachedScript(request, charset);
case CachedResource::FontResource:
- return new CachedFont(url.string());
+ return new CachedFont(request);
#if ENABLE(XSLT)
case CachedResource::XSLStyleSheet:
- return new CachedXSLStyleSheet(url.string());
+ return new CachedXSLStyleSheet(request);
#endif
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
- return new CachedResource(url.string(), CachedResource::LinkResource);
+ case CachedResource::LinkPrefetch:
+ return new CachedResource(request, CachedResource::LinkPrefetch);
+ case CachedResource::LinkPrerender:
+ return new CachedResource(request, CachedResource::LinkPrerender);
+ case CachedResource::LinkSubresource:
+ return new CachedResource(request, CachedResource::LinkSubresource);
#endif
}
ASSERT_NOT_REACHED();
@@ -140,7 +144,7 @@ Frame* CachedResourceLoader::frame() const
return m_document ? m_document->frame() : 0;
}
-CachedImage* CachedResourceLoader::requestImage(const String& url)
+CachedImage* CachedResourceLoader::requestImage(ResourceRequest& request)
{
if (Frame* f = frame()) {
Settings* settings = f->settings();
@@ -148,22 +152,22 @@ CachedImage* CachedResourceLoader::requestImage(const String& url)
return 0;
if (f->loader()->pageDismissalEventBeingDispatched()) {
- KURL completeURL = m_document->completeURL(url);
- if (completeURL.isValid() && canRequest(CachedResource::ImageResource, completeURL))
- PingLoader::loadImage(f, completeURL);
+ KURL requestURL = request.url();
+ if (requestURL.isValid() && canRequest(CachedResource::ImageResource, requestURL))
+ PingLoader::loadImage(f, requestURL);
return 0;
}
}
- CachedImage* resource = static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, url, String()));
+ CachedImage* resource = static_cast<CachedImage*>(requestResource(CachedResource::ImageResource, request, String()));
if (resource) {
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
- resource->setAutoLoadWasPreventedBySettings(!autoLoadImages() || shouldBlockNetworkImage(url));
+ resource->setAutoLoadWasPreventedBySettings(!autoLoadImages() || shouldBlockNetworkImage(request.url()));
#else
resource->setAutoLoadWasPreventedBySettings(!autoLoadImages());
#endif
if (autoLoadImages() && resource->stillNeedsLoad()) {
#ifdef ANDROID_BLOCK_NETWORK_IMAGE
- if (shouldBlockNetworkImage(url)) {
+ if (shouldBlockNetworkImage(request.url())) {
return resource;
}
#endif
@@ -174,26 +178,29 @@ CachedImage* CachedResourceLoader::requestImage(const String& url)
return resource;
}
-CachedFont* CachedResourceLoader::requestFont(const String& url)
+CachedFont* CachedResourceLoader::requestFont(ResourceRequest& request)
{
- return static_cast<CachedFont*>(requestResource(CachedResource::FontResource, url, String()));
+ return static_cast<CachedFont*>(requestResource(CachedResource::FontResource, request, String()));
}
-CachedCSSStyleSheet* CachedResourceLoader::requestCSSStyleSheet(const String& url, const String& charset, ResourceLoadPriority priority)
+CachedCSSStyleSheet* CachedResourceLoader::requestCSSStyleSheet(ResourceRequest& request, const String& charset, ResourceLoadPriority priority)
{
- return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, url, charset, priority));
+ return static_cast<CachedCSSStyleSheet*>(requestResource(CachedResource::CSSStyleSheet, request, charset, priority));
}
-CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(const String& requestURL, const String& charset)
+CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(ResourceRequest& request, const String& charset)
{
- KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(KURL(KURL(), requestURL));
+ KURL url = MemoryCache::removeFragmentIdentifierIfNeeded(request.url());
if (CachedResource* existing = memoryCache()->resourceForURL(url)) {
if (existing->type() == CachedResource::CSSStyleSheet)
return static_cast<CachedCSSStyleSheet*>(existing);
memoryCache()->remove(existing);
}
- CachedCSSStyleSheet* userSheet = new CachedCSSStyleSheet(url, charset);
+ if (url.string() != request.url())
+ request.setURL(url);
+
+ CachedCSSStyleSheet* userSheet = new CachedCSSStyleSheet(request, charset);
bool inCache = memoryCache()->add(userSheet);
if (!inCache)
@@ -207,23 +214,24 @@ CachedCSSStyleSheet* CachedResourceLoader::requestUserCSSStyleSheet(const String
return userSheet;
}
-CachedScript* CachedResourceLoader::requestScript(const String& url, const String& charset)
+CachedScript* CachedResourceLoader::requestScript(ResourceRequest& request, const String& charset)
{
- return static_cast<CachedScript*>(requestResource(CachedResource::Script, url, charset));
+ return static_cast<CachedScript*>(requestResource(CachedResource::Script, request, charset));
}
#if ENABLE(XSLT)
-CachedXSLStyleSheet* CachedResourceLoader::requestXSLStyleSheet(const String& url)
+CachedXSLStyleSheet* CachedResourceLoader::requestXSLStyleSheet(ResourceRequest& request)
{
- return static_cast<CachedXSLStyleSheet*>(requestResource(CachedResource::XSLStyleSheet, url, String()));
+ return static_cast<CachedXSLStyleSheet*>(requestResource(CachedResource::XSLStyleSheet, request, String()));
}
#endif
#if ENABLE(LINK_PREFETCH)
-CachedResource* CachedResourceLoader::requestLinkResource(const String& url, ResourceLoadPriority priority)
+CachedResource* CachedResourceLoader::requestLinkResource(CachedResource::Type type, ResourceRequest& request, ResourceLoadPriority priority)
{
ASSERT(frame());
- return requestResource(CachedResource::LinkResource, url, String(), priority);
+ ASSERT(type == CachedResource::LinkPrefetch || type == CachedResource::LinkPrerender || type == CachedResource::LinkSubresource);
+ return requestResource(type, request, String(), priority);
}
#endif
@@ -238,7 +246,9 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
case CachedResource::Script:
case CachedResource::FontResource:
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
+ case CachedResource::LinkPrefetch:
+ case CachedResource::LinkPrerender:
+ case CachedResource::LinkSubresource:
#endif
// These types of resources can be loaded from any origin.
// FIXME: Are we sure about CachedResource::FontResource?
@@ -280,7 +290,9 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
break;
}
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
+ case CachedResource::LinkPrefetch:
+ case CachedResource::LinkPrerender:
+ case CachedResource::LinkSubresource:
// Prefetch cannot affect the current document.
break;
#endif
@@ -309,7 +321,9 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
break;
}
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
+ case CachedResource::LinkPrefetch:
+ case CachedResource::LinkPrerender:
+ case CachedResource::LinkSubresource:
break;
#endif
}
@@ -317,9 +331,9 @@ bool CachedResourceLoader::canRequest(CachedResource::Type type, const KURL& url
return true;
}
-CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, const String& resourceURL, const String& charset, ResourceLoadPriority priority, bool forPreload)
+CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type, ResourceRequest& request, const String& charset, ResourceLoadPriority priority, bool forPreload)
{
- KURL url = m_document->completeURL(resourceURL);
+ KURL url = request.url();
LOG(ResourceLoading, "CachedResourceLoader::requestResource '%s', charset '%s', priority=%d, forPreload=%u", url.string().latin1().data(), charset.latin1().data(), priority, forPreload);
@@ -351,13 +365,16 @@ CachedResource* CachedResourceLoader::requestResource(CachedResource::Type type,
// See if we can use an existing resource from the cache.
CachedResource* resource = memoryCache()->resourceForURL(url);
+ if (request.url() != url)
+ request.setURL(url);
+
switch (determineRevalidationPolicy(type, forPreload, resource)) {
case Load:
- resource = loadResource(type, url, charset, priority);
+ resource = loadResource(type, request, charset, priority);
break;
case Reload:
memoryCache()->remove(resource);
- resource = loadResource(type, url, charset, priority);
+ resource = loadResource(type, request, charset, priority);
break;
case Revalidate:
resource = revalidateResource(resource, priority);
@@ -389,7 +406,7 @@ CachedResource* CachedResourceLoader::revalidateResource(CachedResource* resourc
// Copy the URL out of the resource to be revalidated in case it gets deleted by the remove() call below.
String url = resource->url();
- CachedResource* newResource = createResource(resource->type(), KURL(ParsedURLString, url), resource->encoding());
+ CachedResource* newResource = createResource(resource->type(), resource->resourceRequest(), resource->encoding());
LOG(ResourceLoading, "Resource %p created to revalidate %p", newResource, resource);
newResource->setResourceToRevalidate(resource);
@@ -404,13 +421,13 @@ CachedResource* CachedResourceLoader::revalidateResource(CachedResource* resourc
return newResource;
}
-CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, const KURL& url, const String& charset, ResourceLoadPriority priority)
+CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, ResourceRequest& request, const String& charset, ResourceLoadPriority priority)
{
- ASSERT(!memoryCache()->resourceForURL(url));
+ ASSERT(!memoryCache()->resourceForURL(request.url()));
- LOG(ResourceLoading, "Loading CachedResource for '%s'.", url.string().latin1().data());
+ LOG(ResourceLoading, "Loading CachedResource for '%s'.", request.url().string().latin1().data());
- CachedResource* resource = createResource(type, url, charset);
+ CachedResource* resource = createResource(type, request, charset);
bool inCache = memoryCache()->add(resource);
@@ -436,7 +453,7 @@ CachedResource* CachedResourceLoader::loadResource(CachedResource::Type type, co
return 0;
}
- m_validatedURLs.add(url.string());
+ m_validatedURLs.add(request.url());
return resource;
}
@@ -693,7 +710,7 @@ int CachedResourceLoader::requestCount()
return m_requestCount;
}
-void CachedResourceLoader::preload(CachedResource::Type type, const String& url, const String& charset, bool referencedFromBody)
+void CachedResourceLoader::preload(CachedResource::Type type, ResourceRequest& request, const String& charset, bool referencedFromBody)
{
// FIXME: Rip this out when we are sure it is no longer necessary (even for mobile).
UNUSED_PARAM(referencedFromBody);
@@ -703,11 +720,11 @@ void CachedResourceLoader::preload(CachedResource::Type type, const String& url,
if (!hasRendering && !canBlockParser) {
// Don't preload subresources that can't block the parser before we have something to draw.
// This helps prevent preloads from delaying first display when bandwidth is limited.
- PendingPreload pendingPreload = { type, url, charset };
+ PendingPreload pendingPreload = { type, request, charset };
m_pendingPreloads.append(pendingPreload);
return;
}
- requestPreload(type, url, charset);
+ requestPreload(type, request, charset);
}
void CachedResourceLoader::checkForPendingPreloads()
@@ -717,19 +734,19 @@ void CachedResourceLoader::checkForPendingPreloads()
while (!m_pendingPreloads.isEmpty()) {
PendingPreload preload = m_pendingPreloads.takeFirst();
// Don't request preload if the resource already loaded normally (this will result in double load if the page is being reloaded with cached results ignored).
- if (!cachedResource(m_document->completeURL(preload.m_url)))
- requestPreload(preload.m_type, preload.m_url, preload.m_charset);
+ if (!cachedResource(preload.m_request.url()))
+ requestPreload(preload.m_type, preload.m_request, preload.m_charset);
}
m_pendingPreloads.clear();
}
-void CachedResourceLoader::requestPreload(CachedResource::Type type, const String& url, const String& charset)
+void CachedResourceLoader::requestPreload(CachedResource::Type type, ResourceRequest& request, const String& charset)
{
String encoding;
if (type == CachedResource::Script || type == CachedResource::CSSStyleSheet)
encoding = charset.isEmpty() ? m_document->charset() : charset;
- CachedResource* resource = requestResource(type, url, encoding, ResourceLoadPriorityUnresolved, true);
+ CachedResource* resource = requestResource(type, request, encoding, ResourceLoadPriorityUnresolved, true);
if (!resource || (m_preloads && m_preloads->contains(resource)))
return;
resource->increasePreloadCount();
diff --git a/Source/WebCore/loader/cache/CachedResourceLoader.h b/Source/WebCore/loader/cache/CachedResourceLoader.h
index 79c63b9..a3933f3 100644
--- a/Source/WebCore/loader/cache/CachedResourceLoader.h
+++ b/Source/WebCore/loader/cache/CachedResourceLoader.h
@@ -59,17 +59,17 @@ public:
CachedResourceLoader(Document*);
~CachedResourceLoader();
- CachedImage* requestImage(const String& url);
- CachedCSSStyleSheet* requestCSSStyleSheet(const String& url, const String& charset, ResourceLoadPriority priority = ResourceLoadPriorityUnresolved);
- CachedCSSStyleSheet* requestUserCSSStyleSheet(const String& url, const String& charset);
- CachedScript* requestScript(const String& url, const String& charset);
- CachedFont* requestFont(const String& url);
+ CachedImage* requestImage(ResourceRequest&);
+ CachedCSSStyleSheet* requestCSSStyleSheet(ResourceRequest&, const String& charset, ResourceLoadPriority = ResourceLoadPriorityUnresolved);
+ CachedCSSStyleSheet* requestUserCSSStyleSheet(ResourceRequest&, const String& charset);
+ CachedScript* requestScript(ResourceRequest&, const String& charset);
+ CachedFont* requestFont(ResourceRequest&);
#if ENABLE(XSLT)
- CachedXSLStyleSheet* requestXSLStyleSheet(const String& url);
+ CachedXSLStyleSheet* requestXSLStyleSheet(ResourceRequest&);
#endif
#if ENABLE(LINK_PREFETCH)
- CachedResource* requestLinkResource(const String &url, ResourceLoadPriority priority = ResourceLoadPriorityUnresolved);
+ CachedResource* requestLinkResource(CachedResource::Type, ResourceRequest&, ResourceLoadPriority = ResourceLoadPriorityUnresolved);
#endif
// Logs an access denied message to the console for the specified URL.
@@ -110,15 +110,15 @@ public:
void clearPreloads();
void clearPendingPreloads();
- void preload(CachedResource::Type, const String& url, const String& charset, bool referencedFromBody);
+ void preload(CachedResource::Type, ResourceRequest&, const String& charset, bool referencedFromBody);
void checkForPendingPreloads();
void printPreloadStats();
private:
- CachedResource* requestResource(CachedResource::Type, const String& url, const String& charset, ResourceLoadPriority priority = ResourceLoadPriorityUnresolved, bool isPreload = false);
+ CachedResource* requestResource(CachedResource::Type, ResourceRequest&, const String& charset, ResourceLoadPriority = ResourceLoadPriorityUnresolved, bool isPreload = false);
CachedResource* revalidateResource(CachedResource*, ResourceLoadPriority priority);
- CachedResource* loadResource(CachedResource::Type, const KURL&, const String& charset, ResourceLoadPriority priority);
- void requestPreload(CachedResource::Type, const String& url, const String& charset);
+ CachedResource* loadResource(CachedResource::Type, ResourceRequest&, const String& charset, ResourceLoadPriority);
+ void requestPreload(CachedResource::Type, ResourceRequest& url, const String& charset);
enum RevalidationPolicy { Use, Revalidate, Reload, Load };
RevalidationPolicy determineRevalidationPolicy(CachedResource::Type, bool forPreload, CachedResource* existingResource) const;
@@ -142,7 +142,7 @@ private:
OwnPtr<ListHashSet<CachedResource*> > m_preloads;
struct PendingPreload {
CachedResource::Type m_type;
- String m_url;
+ ResourceRequest m_request;
String m_charset;
};
Deque<PendingPreload> m_pendingPreloads;
diff --git a/Source/WebCore/loader/cache/CachedResourceRequest.cpp b/Source/WebCore/loader/cache/CachedResourceRequest.cpp
index 9e7fe8f..e4e6b8b 100644
--- a/Source/WebCore/loader/cache/CachedResourceRequest.cpp
+++ b/Source/WebCore/loader/cache/CachedResourceRequest.cpp
@@ -42,11 +42,8 @@
namespace WebCore {
-static ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource::Type type, ResourceLoadPriority priority)
+static ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource::Type type)
{
-#if !ENABLE(LINK_PREFETCH)
- UNUSED_PARAM(priority);
-#endif
switch (type) {
case CachedResource::CSSStyleSheet:
#if ENABLE(XSLT)
@@ -60,9 +57,11 @@ static ResourceRequest::TargetType cachedResourceTypeToTargetType(CachedResource
case CachedResource::ImageResource:
return ResourceRequest::TargetIsImage;
#if ENABLE(LINK_PREFETCH)
- case CachedResource::LinkResource:
- if (priority == ResourceLoadPriorityLowest)
- return ResourceRequest::TargetIsPrefetch;
+ case CachedResource::LinkPrefetch:
+ return ResourceRequest::TargetIsPrefetch;
+ case CachedResource::LinkPrerender:
+ return ResourceRequest::TargetIsSubresource;
+ case CachedResource::LinkSubresource:
return ResourceRequest::TargetIsSubresource;
#endif
}
@@ -89,8 +88,8 @@ PassRefPtr<CachedResourceRequest> CachedResourceRequest::load(CachedResourceLoad
{
RefPtr<CachedResourceRequest> request = adoptRef(new CachedResourceRequest(cachedResourceLoader, resource, incremental));
- ResourceRequest resourceRequest(resource->url());
- resourceRequest.setTargetType(cachedResourceTypeToTargetType(resource->type(), resource->loadPriority()));
+ ResourceRequest resourceRequest = resource->resourceRequest();
+ resourceRequest.setTargetType(cachedResourceTypeToTargetType(resource->type()));
if (!resource->accept().isEmpty())
resourceRequest.setHTTPAccept(resource->accept());
@@ -113,7 +112,7 @@ PassRefPtr<CachedResourceRequest> CachedResourceRequest::load(CachedResourceLoad
}
#if ENABLE(LINK_PREFETCH)
- if (resource->type() == CachedResource::LinkResource)
+ if (resource->type() == CachedResource::LinkPrefetch || resource->type() == CachedResource::LinkPrerender || resource->type() == CachedResource::LinkSubresource)
resourceRequest.setHTTPHeaderField("Purpose", "prefetch");
#endif
@@ -124,7 +123,7 @@ PassRefPtr<CachedResourceRequest> CachedResourceRequest::load(CachedResourceLoad
request.get(), resourceRequest, priority, securityCheck, sendResourceLoadCallbacks);
if (!loader || loader->reachedTerminalState()) {
// FIXME: What if resources in other frames were waiting for this revalidation?
- LOG(ResourceLoading, "Cannot start loading '%s'", resource->url().latin1().data());
+ LOG(ResourceLoading, "Cannot start loading '%s'", resource->url().string().latin1().data());
cachedResourceLoader->decrementRequestCount(resource);
cachedResourceLoader->loadFinishing();
if (resource->resourceToRevalidate())
@@ -149,7 +148,7 @@ void CachedResourceRequest::didFinishLoading(SubresourceLoader* loader, double)
ASSERT(loader == m_loader.get());
ASSERT(!m_resource->resourceToRevalidate());
- LOG(ResourceLoading, "Received '%s'.", m_resource->url().latin1().data());
+ LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1().data());
// Prevent the document from being destroyed before we are done with
// the cachedResourceLoader that it will delete when the document gets deleted.
@@ -181,7 +180,7 @@ void CachedResourceRequest::didFail(bool cancelled)
if (m_finishing)
return;
- LOG(ResourceLoading, "Failed to load '%s' (cancelled=%d).\n", m_resource->url().latin1().data(), cancelled);
+ LOG(ResourceLoading, "Failed to load '%s' (cancelled=%d).\n", m_resource->url().string().latin1().data(), cancelled);
// Prevent the document from being destroyed before we are done with
// the cachedResourceLoader that it will delete when the document gets deleted.
diff --git a/Source/WebCore/loader/cache/CachedScript.cpp b/Source/WebCore/loader/cache/CachedScript.cpp
index e1a8a32..8c83bca 100644
--- a/Source/WebCore/loader/cache/CachedScript.cpp
+++ b/Source/WebCore/loader/cache/CachedScript.cpp
@@ -40,8 +40,8 @@
namespace WebCore {
-CachedScript::CachedScript(const String& url, const String& charset)
- : CachedResource(url, Script)
+CachedScript::CachedScript(const ResourceRequest& resourceRequest, const String& charset)
+ : CachedResource(resourceRequest, Script)
, m_decoder(TextResourceDecoder::create("application/javascript", charset))
, m_decodedDataDeletionTimer(this, &CachedScript::decodedDataDeletionTimerFired)
{
diff --git a/Source/WebCore/loader/cache/CachedScript.h b/Source/WebCore/loader/cache/CachedScript.h
index a4ea453..1a76c18 100644
--- a/Source/WebCore/loader/cache/CachedScript.h
+++ b/Source/WebCore/loader/cache/CachedScript.h
@@ -42,7 +42,7 @@ namespace WebCore {
class CachedScript : public CachedResource {
public:
- CachedScript(const String& url, const String& charset);
+ CachedScript(const ResourceRequest&, const String& charset);
virtual ~CachedScript();
const String& script();
diff --git a/Source/WebCore/loader/cache/CachedXSLStyleSheet.cpp b/Source/WebCore/loader/cache/CachedXSLStyleSheet.cpp
index ca7bf13..62e5048 100644
--- a/Source/WebCore/loader/cache/CachedXSLStyleSheet.cpp
+++ b/Source/WebCore/loader/cache/CachedXSLStyleSheet.cpp
@@ -37,8 +37,8 @@ namespace WebCore {
#if ENABLE(XSLT)
-CachedXSLStyleSheet::CachedXSLStyleSheet(const String &url)
- : CachedResource(url, XSLStyleSheet)
+CachedXSLStyleSheet::CachedXSLStyleSheet(const ResourceRequest& resourceRequest)
+ : CachedResource(resourceRequest, XSLStyleSheet)
, m_decoder(TextResourceDecoder::create("text/xsl"))
{
// It's XML we want.
@@ -49,7 +49,7 @@ CachedXSLStyleSheet::CachedXSLStyleSheet(const String &url)
void CachedXSLStyleSheet::didAddClient(CachedResourceClient* c)
{
if (!isLoading())
- c->setXSLStyleSheet(m_url, m_response.url(), m_sheet);
+ c->setXSLStyleSheet(m_resourceRequest.url(), m_response.url(), m_sheet);
}
void CachedXSLStyleSheet::setEncoding(const String& chs)
@@ -84,7 +84,7 @@ void CachedXSLStyleSheet::checkNotify()
CachedResourceClientWalker w(m_clients);
while (CachedResourceClient *c = w.next())
- c->setXSLStyleSheet(m_url, m_response.url(), m_sheet);
+ c->setXSLStyleSheet(m_resourceRequest.url(), m_response.url(), m_sheet);
}
void CachedXSLStyleSheet::error(CachedResource::Status status)
diff --git a/Source/WebCore/loader/cache/CachedXSLStyleSheet.h b/Source/WebCore/loader/cache/CachedXSLStyleSheet.h
index 8b29792..b8f7283 100644
--- a/Source/WebCore/loader/cache/CachedXSLStyleSheet.h
+++ b/Source/WebCore/loader/cache/CachedXSLStyleSheet.h
@@ -37,7 +37,7 @@ namespace WebCore {
#if ENABLE(XSLT)
class CachedXSLStyleSheet : public CachedResource {
public:
- CachedXSLStyleSheet(const String& url);
+ CachedXSLStyleSheet(const ResourceRequest&);
const String& sheet() const { return m_sheet; }
diff --git a/Source/WebCore/loader/cache/MemoryCache.cpp b/Source/WebCore/loader/cache/MemoryCache.cpp
index 7bf2cf4..c1fc778 100644
--- a/Source/WebCore/loader/cache/MemoryCache.cpp
+++ b/Source/WebCore/loader/cache/MemoryCache.cpp
@@ -98,7 +98,7 @@ bool MemoryCache::add(CachedResource* resource)
resourceAccessed(resource);
- LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource->url().latin1().data(), resource);
+ LOG(ResourceLoading, "MemoryCache::add Added '%s', resource %p\n", resource->url().string().latin1().data(), resource);
return true;
}
@@ -328,7 +328,7 @@ bool MemoryCache::makeResourcePurgeable(CachedResource* resource)
void MemoryCache::evict(CachedResource* resource)
{
- LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resource, resource->url().latin1().data());
+ LOG(ResourceLoading, "Evicting resource %p for '%s' from cache", resource, resource->url().string().latin1().data());
// The resource may have already been removed by someone other than our caller,
// who needed a fresh copy for a reload. See <http://bugs.webkit.org/show_bug.cgi?id=12479#c6>.
if (resource->inCache()) {
diff --git a/Source/WebCore/platform/network/ResourceRequestBase.h b/Source/WebCore/platform/network/ResourceRequestBase.h
index 53e1160..4c7abcb 100644
--- a/Source/WebCore/platform/network/ResourceRequestBase.h
+++ b/Source/WebCore/platform/network/ResourceRequestBase.h
@@ -65,6 +65,7 @@ namespace WebCore {
TargetIsWorker,
TargetIsSharedWorker,
TargetIsPrefetch,
+ TargetIsPrerender,
TargetIsFavicon,
};
diff --git a/Source/WebCore/platform/network/android/ResourceRequest.h b/Source/WebCore/platform/network/android/ResourceRequest.h
index 745c2ef..456f016 100644
--- a/Source/WebCore/platform/network/android/ResourceRequest.h
+++ b/Source/WebCore/platform/network/android/ResourceRequest.h
@@ -28,7 +28,6 @@
#ifndef ResourceRequest_h
#define ResourceRequest_h
-#include "CachedResource.h"
#include "ResourceRequestBase.h"
namespace WebCore {
diff --git a/Source/WebCore/rendering/HitTestResult.cpp b/Source/WebCore/rendering/HitTestResult.cpp
index 77ccc4b..cb2a607 100644
--- a/Source/WebCore/rendering/HitTestResult.cpp
+++ b/Source/WebCore/rendering/HitTestResult.cpp
@@ -327,7 +327,7 @@ KURL HitTestResult::absoluteMediaURL() const
{
#if ENABLE(VIDEO)
if (HTMLMediaElement* mediaElt = mediaElement())
- return m_innerNonSharedNode->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(mediaElt->currentSrc()));
+ return mediaElt->currentSrc();
return KURL();
#else
return KURL();
diff --git a/Source/WebCore/svg/SVGFEImageElement.cpp b/Source/WebCore/svg/SVGFEImageElement.cpp
index f33cd36..2b8b21c 100644
--- a/Source/WebCore/svg/SVGFEImageElement.cpp
+++ b/Source/WebCore/svg/SVGFEImageElement.cpp
@@ -70,7 +70,8 @@ void SVGFEImageElement::requestImageResource()
if (hrefElement && hrefElement->isSVGElement() && hrefElement->renderer())
return;
- m_cachedImage = ownerDocument()->cachedResourceLoader()->requestImage(href());
+ ResourceRequest request(ownerDocument()->completeURL(href()));
+ m_cachedImage = ownerDocument()->cachedResourceLoader()->requestImage(request);
if (m_cachedImage)
m_cachedImage->addClient(this);
diff --git a/Source/WebCore/svg/SVGFontFaceUriElement.cpp b/Source/WebCore/svg/SVGFontFaceUriElement.cpp
index b017143..57b2ab7 100644
--- a/Source/WebCore/svg/SVGFontFaceUriElement.cpp
+++ b/Source/WebCore/svg/SVGFontFaceUriElement.cpp
@@ -95,7 +95,8 @@ void SVGFontFaceUriElement::loadFont()
String href = getAttribute(XLinkNames::hrefAttr);
if (!href.isNull()) {
CachedResourceLoader* cachedResourceLoader = document()->cachedResourceLoader();
- m_cachedFont = cachedResourceLoader->requestFont(href);
+ ResourceRequest request(document()->completeURL(href));
+ m_cachedFont = cachedResourceLoader->requestFont(request);
if (m_cachedFont) {
m_cachedFont->addClient(this);
m_cachedFont->beginLoadIfNeeded(cachedResourceLoader);
diff --git a/Source/WebCore/xml/XSLImportRule.cpp b/Source/WebCore/xml/XSLImportRule.cpp
index c32da4e..d23f182 100644
--- a/Source/WebCore/xml/XSLImportRule.cpp
+++ b/Source/WebCore/xml/XSLImportRule.cpp
@@ -26,6 +26,7 @@
#include "CachedXSLStyleSheet.h"
#include "CachedResourceLoader.h"
+#include "Document.h"
#include "XSLStyleSheet.h"
namespace WebCore {
@@ -98,7 +99,8 @@ void XSLImportRule::loadSheet()
return;
}
- m_cachedSheet = cachedResourceLoader->requestXSLStyleSheet(absHref);
+ ResourceRequest request(cachedResourceLoader->document()->completeURL(absHref));
+ m_cachedSheet = cachedResourceLoader->requestXSLStyleSheet(request);
if (m_cachedSheet) {
m_cachedSheet->addClient(this);