WebCore:
authorjianli@chromium.org <jianli@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Jul 2009 23:15:40 +0000 (23:15 +0000)
committerjianli@chromium.org <jianli@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Jul 2009 23:15:40 +0000 (23:15 +0000)
2009-07-15  Jian Li  <jianli@chromium.org>

        Reviewed by David Levin.

        Bug 25151 - workers that fail to load scripts not firing error event.
        https://bugs.webkit.org/show_bug.cgi?id=25151

        This fixes the problem that an error event is not fired when the worker
        script fails to load. Some reasons this may occur are an invalid URL for
        the worker script or a cross-origin redirect.

        We also moves the code to complete the URL and check its origin from
        Worker constructor to WorkerScriptLoader loading functions in order to
        move the exception throwing logic out of the scope of Worker constructor.
        Due to this change, we also remove the output ExceptionCode parameter
        in the worker constructor. Corresponding JS/V8 binding codes have been
        updated to reflect this change.

        * bindings/js/JSWorkerConstructor.cpp:
        (WebCore::constructWorker):
        * bindings/v8/custom/V8WorkerCustom.cpp:
        (WebCore::CALLBACK_FUNC_DECL):
        * workers/Worker.cpp:
        (WebCore::Worker::Worker):
        (WebCore::Worker::notifyFinished):
        * workers/Worker.h:
        (WebCore::Worker::create):
        * workers/WorkerContext.cpp:
        (WebCore::WorkerContext::importScripts):
        * workers/WorkerScriptLoader.cpp:
        (WebCore::toCrossOriginRedirectPolicy):
        (WebCore::WorkerScriptLoader::loadSynchronously):
        (WebCore::WorkerScriptLoader::loadAsynchronously):
        (WebCore::notifyLoadErrorTask):
        (WebCore::WorkerScriptLoader::createResourceRequest):
        (WebCore::WorkerScriptLoader::didFail):
        (WebCore::WorkerScriptLoader::didFailRedirectCheck):
        (WebCore::WorkerScriptLoader::didReceiveAuthenticationCancellation):
        (WebCore::WorkerScriptLoader::notifyError):
        * workers/WorkerScriptLoader.h:
        (WebCore::):
        (WebCore::WorkerScriptLoader::url):

LayoutTests:

2009-07-15  Jian Li  <jianli@chromium.org>

        Reviewed by David Levin.

        Bug 25151 - workers that fail to load scripts not firing error event.
        https://bugs.webkit.org/show_bug.cgi?id=25151

        Updates layout test cases for bug 25151.

        * fast/workers/worker-constructor-expected.txt:
        * fast/workers/worker-constructor.html:
        * http/tests/workers/worker-redirect-expected.txt:
        * http/tests/workers/worker-redirect.html:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@45958 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/workers/worker-constructor-expected.txt
LayoutTests/fast/workers/worker-constructor.html
LayoutTests/http/tests/workers/worker-redirect-expected.txt
LayoutTests/http/tests/workers/worker-redirect.html
WebCore/ChangeLog
WebCore/bindings/js/JSWorkerConstructor.cpp
WebCore/bindings/v8/custom/V8WorkerCustom.cpp
WebCore/workers/Worker.cpp
WebCore/workers/Worker.h
WebCore/workers/WorkerContext.cpp
WebCore/workers/WorkerScriptLoader.cpp
WebCore/workers/WorkerScriptLoader.h

index f08d6e8..d656d2b 100644 (file)
@@ -1,3 +1,17 @@
+2009-07-15  Jian Li  <jianli@chromium.org>
+
+        Reviewed by David Levin.
+
+        Bug 25151 - workers that fail to load scripts not firing error event.
+        https://bugs.webkit.org/show_bug.cgi?id=25151
+
+        Updates layout test cases for bug 25151.
+
+        * fast/workers/worker-constructor-expected.txt:
+        * fast/workers/worker-constructor.html:
+        * http/tests/workers/worker-redirect-expected.txt:
+        * http/tests/workers/worker-redirect.html:
+
 2009-07-15  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Dave Hyatt.
index 97678d1..a55b3c7 100644 (file)
@@ -3,6 +3,8 @@ Test Worker constructor functionality. Should print a series of PASS messages, f
 PASS: toString exception propagated correctly.
 PASS: trying to create workers recursively resulted in an exception (RangeError: Maximum call stack size exceeded.)
 PASS: invoking Worker constructor without arguments resulted in an exception (SyntaxError: Not enough arguments)
+PASS: onerror invoked for an empty script URL.
+PASS: onerror invoked for an invalid script URL.
 PASS: onerror invoked for a script that could not be loaded.
 DONE
 
index 8f8e723..264892f 100644 (file)
@@ -7,48 +7,105 @@ function log(message)
     document.getElementById("result").innerHTML += message + "<br>";
 }
 
-if (window.layoutTestController) {
-    layoutTestController.dumpAsText();
-    layoutTestController.waitUntilDone();
+function runNextTest()
+{
+    testIndex++;
+    if (testIndex > totalTests) {
+        log("DONE");
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    } else {
+        eval("test" + testIndex + "();");
+    }
 }
 
-try {
-    new Worker({toString:function(){throw "exception"}})
-    log("FAIL: toString exception not propagated.");
-} catch (ex) {
-    if (ex == "exception")
-        log("PASS: toString exception propagated correctly.");
-    else
-        log("FAIL: unexpected exception (" + ex + ") received instead of one propagated from toString.");
+function test1()
+{
+    try {
+        new Worker({toString:function(){throw "exception"}})
+        log("FAIL: toString exception not propagated.");
+    } catch (ex) {
+        if (ex == "exception")
+            log("PASS: toString exception propagated correctly.");
+        else
+            log("FAIL: unexpected exception (" + ex + ") received instead of one propagated from toString.");
+    }
+    runNextTest();
 }
 
-try {
-    var foo = {toString:function(){new Worker(foo)}}
-    new Worker(foo);
-    log("FAIL: no exception when trying to create workers recursively");
-} catch (ex) {
-    log("PASS: trying to create workers recursively resulted in an exception (" + ex + ")");
+function test2()
+{
+    try {
+        var foo = {toString:function(){new Worker(foo)}}
+        new Worker(foo);
+        log("FAIL: no exception when trying to create workers recursively");
+    } catch (ex) {
+        log("PASS: trying to create workers recursively resulted in an exception (" + ex + ")");
+    }
+    runNextTest();
 }
 
-try {
-    new Worker();
-    log("FAIL: invoking Worker constructor without arguments did not result in an exception");
-} catch (ex) {
-    log("PASS: invoking Worker constructor without arguments resulted in an exception (" + ex + ")");
+function test3()
+{
+    try {
+        new Worker();
+        log("FAIL: invoking Worker constructor without arguments did not result in an exception");
+    } catch (ex) {
+        log("PASS: invoking Worker constructor without arguments resulted in an exception (" + ex + ")");
+    }
+    runNextTest();
 }
 
-try {
-    var worker = new Worker("does-not-exist.js");
-    worker.onerror = function() {
-        log("PASS: onerror invoked for a script that could not be loaded.");
-        log("DONE");
-        if (window.layoutTestController)
-            layoutTestController.notifyDone();
+function test4()
+{
+    try {
+        var worker = new Worker("");
+        worker.onerror = function() {
+            log("PASS: onerror invoked for an empty script URL.");
+            runNextTest();
+        }
+    } catch (ex) {
+        log("FAIL: unexpected exception " + ex);
+        runNextTest();
+    }
+}
+
+function test5()
+{
+    try {
+        var worker = new Worker("invalidurl://");
+        worker.onerror = function() {
+            log("PASS: onerror invoked for an invalid script URL.");
+            runNextTest();
+        }
+    } catch (ex) {
+        log("FAIL: unexpected exception " + ex);
+        runNextTest();
+    }
+}
+
+function test6()
+{
+    try {
+        var worker = new Worker("does-not-exist.js");
+        worker.onerror = function() {
+            log("PASS: onerror invoked for a script that could not be loaded.");
+            runNextTest();
+        }
+    } catch (ex) {
+        log("FAIL: unexpected exception " + ex);
+        runNextTest();
     }
-} catch (ex) {
-    log("FAIL: unexpected exception " + ex);
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
 }
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+var totalTests = 6;
+var testIndex = 0;
+runNextTest();
+
 </script>
 </body>
index dbf132e..0b15b3b 100644 (file)
@@ -1,4 +1,6 @@
 Test that loading the worker's script does not allow a cross origin redirect (bug 26146)
 
+SUCCESS: threw error when attempting to cross origin while loading the worker script.
 SUCCESS: threw error when attempting to redirected cross origin while loading the worker script.
+DONE
 
index 86037f2..8f7239d 100644 (file)
@@ -7,22 +7,53 @@ function log(message)
     document.getElementById("result").innerHTML += message + "<br>";
 }
 
+function runNextTest()
+{
+    testIndex++;
+    if (testIndex > totalTests) {
+        log("DONE");
+        if (window.layoutTestController)
+            layoutTestController.notifyDone();
+    } else {
+        eval("test" + testIndex + "();");
+    }
+}
+
+function test1()
+{
+    var worker = new Worker('http://localhost:8000/workers/resources/worker-redirect-target.js');
+    worker.onerror = function(evt) {
+        log("SUCCESS: threw error when attempting to cross origin while loading the worker script.");
+        runNextTest();
+    }
+    worker.onmessage = function(evt) {
+        log("FAIL: executed script when redirect cross origin.");
+        runNextTest();
+    }
+}
+
+function test2()
+{
+    var worker = new Worker('/resources/redirect.php?url=http://localhost:8000/workers/resources/worker-redirect-target.js');
+    worker.onerror = function(evt) {
+        log("SUCCESS: threw error when attempting to redirected cross origin while loading the worker script.");
+        runNextTest();
+    }
+    worker.onmessage = function(evt) {
+        log("FAIL: executed script when redirect cross origin.");
+        runNextTest();
+    }
+}
+
 if (window.layoutTestController) {
     layoutTestController.dumpAsText();
     layoutTestController.waitUntilDone();
 }
 
-var worker = new Worker('/resources/redirect.php?url=http://localhost:8000/workers/resources/worker-redirect-target.js');
-worker.onerror = function(evt) {
-    log("SUCCESS: threw error when attempting to redirected cross origin while loading the worker script.");
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-worker.onmessage = function(evt) {
-    log("FAIL: executed script when redirect cross origin.");
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
-}
+var totalTests = 2;
+var testIndex = 0;
+runNextTest();
+
 </script>
 </body>
 </html>
index e96ba9d..22bbf91 100644 (file)
@@ -1,3 +1,46 @@
+2009-07-15  Jian Li  <jianli@chromium.org>
+
+        Reviewed by David Levin.
+
+        Bug 25151 - workers that fail to load scripts not firing error event.
+        https://bugs.webkit.org/show_bug.cgi?id=25151
+
+        This fixes the problem that an error event is not fired when the worker
+        script fails to load. Some reasons this may occur are an invalid URL for
+        the worker script or a cross-origin redirect.
+
+        We also moves the code to complete the URL and check its origin from
+        Worker constructor to WorkerScriptLoader loading functions in order to
+        move the exception throwing logic out of the scope of Worker constructor.
+        Due to this change, we also remove the output ExceptionCode parameter
+        in the worker constructor. Corresponding JS/V8 binding codes have been
+        updated to reflect this change.
+
+        * bindings/js/JSWorkerConstructor.cpp:
+        (WebCore::constructWorker):
+        * bindings/v8/custom/V8WorkerCustom.cpp:
+        (WebCore::CALLBACK_FUNC_DECL):
+        * workers/Worker.cpp:
+        (WebCore::Worker::Worker):
+        (WebCore::Worker::notifyFinished):
+        * workers/Worker.h:
+        (WebCore::Worker::create):
+        * workers/WorkerContext.cpp:
+        (WebCore::WorkerContext::importScripts):
+        * workers/WorkerScriptLoader.cpp:
+        (WebCore::toCrossOriginRedirectPolicy):
+        (WebCore::WorkerScriptLoader::loadSynchronously):
+        (WebCore::WorkerScriptLoader::loadAsynchronously):
+        (WebCore::notifyLoadErrorTask):
+        (WebCore::WorkerScriptLoader::createResourceRequest):
+        (WebCore::WorkerScriptLoader::didFail):
+        (WebCore::WorkerScriptLoader::didFailRedirectCheck):
+        (WebCore::WorkerScriptLoader::didReceiveAuthenticationCancellation):
+        (WebCore::WorkerScriptLoader::notifyError):
+        * workers/WorkerScriptLoader.h:
+        (WebCore::):
+        (WebCore::WorkerScriptLoader::url):
+
 2009-07-15  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Dave Hyatt.
index 07ea2eb..cf3dfd1 100644 (file)
@@ -59,9 +59,7 @@ static JSObject* constructWorker(ExecState* exec, JSObject*, const ArgList& args
 
     DOMWindow* window = asJSDOMWindow(exec->lexicalGlobalObject())->impl();
     
-    ExceptionCode ec = 0;
-    RefPtr<Worker> worker = Worker::create(scriptURL, window->document(), ec);
-    setDOMException(exec, ec);
+    RefPtr<Worker> worker = Worker::create(scriptURL, window->document());
 
     return asObject(toJS(exec, worker.release()));
 }
index 29b2d43..7eb4f60 100644 (file)
@@ -80,11 +80,7 @@ CALLBACK_FUNC_DECL(WorkerConstructor)
 
     // Create the worker object.
     // Note: it's OK to let this RefPtr go out of scope because we also call setDOMWrapper(), which effectively holds a reference to obj.
-    ExceptionCode ec = 0;
-    RefPtr<Worker> obj = Worker::create(toWebCoreString(scriptUrl), context, ec);
-
-    if (ec)
-        return throwError(ec);
+    RefPtr<Worker> obj = Worker::create(toWebCoreString(scriptUrl), context);
 
     // Setup the standard wrapper object internal fields.
     v8::Handle<v8::Object> wrapperObject = args.Holder();
index 2e03e3d..f28ca40 100644 (file)
 
 namespace WebCore {
 
-Worker::Worker(const String& url, ScriptExecutionContext* context, ExceptionCode& ec)
+Worker::Worker(const String& url, ScriptExecutionContext* context)
     : ActiveDOMObject(context, this)
     , m_contextProxy(WorkerContextProxy::create(this))
 {
-    m_scriptURL = context->completeURL(url);
-    if (url.isEmpty() || !m_scriptURL.isValid()) {
-        ec = SYNTAX_ERR;
-        return;
-    }
-
-    if (!context->securityOrigin()->canAccess(SecurityOrigin::create(m_scriptURL).get())) {
-        ec = SECURITY_ERR;
-        return;
-    }
-
     m_scriptLoader = new WorkerScriptLoader();
-    m_scriptLoader->loadAsynchronously(scriptExecutionContext(), m_scriptURL, DenyCrossOriginRedirect, this);
+    m_scriptLoader->loadAsynchronously(scriptExecutionContext(), url, CompleteURL, DenyCrossOriginLoad, this);
     setPendingActivity(this);  // The worker context does not exist while loading, so we must ensure that the worker object is not collected, as well as its event listeners.
 }
 
@@ -117,7 +106,7 @@ void Worker::notifyFinished()
     if (m_scriptLoader->failed())
         dispatchErrorEvent();
     else
-        m_contextProxy->startWorkerContext(m_scriptURL, scriptExecutionContext()->userAgent(m_scriptURL), m_scriptLoader->script());
+        m_contextProxy->startWorkerContext(m_scriptLoader->url(), scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script());
 
     m_scriptLoader = 0;
 
index 1fcc8be..bde27e8 100644 (file)
@@ -33,7 +33,6 @@
 #include "ActiveDOMObject.h"
 #include "EventListener.h"
 #include "EventTarget.h"
-#include "KURL.h"
 #include "WorkerScriptLoaderClient.h"
 #include <wtf/OwnPtr.h>
 #include <wtf/PassRefPtr.h>
@@ -51,7 +50,7 @@ namespace WebCore {
 
     class Worker : public RefCounted<Worker>, public ActiveDOMObject, private WorkerScriptLoaderClient, public EventTarget {
     public:
-        static PassRefPtr<Worker> create(const String& url, ScriptExecutionContext* context, ExceptionCode& ec) { return adoptRef(new Worker(url, context, ec)); }
+        static PassRefPtr<Worker> create(const String& url, ScriptExecutionContext* context) { return adoptRef(new Worker(url, context)); }
         ~Worker();
 
         virtual ScriptExecutionContext* scriptExecutionContext() const { return ActiveDOMObject::scriptExecutionContext(); }
@@ -88,14 +87,13 @@ namespace WebCore {
         EventListener* onerror() const { return m_onErrorListener.get(); }
 
     private:
-        Worker(const String&, ScriptExecutionContext*, ExceptionCode&);
+        Worker(const String&, ScriptExecutionContext*);
 
         virtual void notifyFinished();
 
         virtual void refEventTarget() { ref(); }
         virtual void derefEventTarget() { deref(); }
 
-        KURL m_scriptURL;
         OwnPtr<WorkerScriptLoader> m_scriptLoader;
 
         WorkerContextProxy* m_contextProxy; // The proxy outlives the worker to perform thread shutdown.
index 8e9fb97..5fcc080 100644 (file)
@@ -290,7 +290,7 @@ void WorkerContext::importScripts(const Vector<String>& urls, const String& call
 
     for (Vector<KURL>::const_iterator it = completedURLs.begin(); it != end; ++it) {
         WorkerScriptLoader scriptLoader;
-        scriptLoader.loadSynchronously(scriptExecutionContext(), *it, AllowCrossOriginRedirect);
+        scriptLoader.loadSynchronously(scriptExecutionContext(), *it, DoNotCompleteURL, AllowCrossOriginLoad);
 
         // If the fetching attempt failed, throw a NETWORK_ERR exception and abort all these steps.
         if (scriptLoader.failed()) {
index 8737b88..093bf07 100644 (file)
 
 #include "WorkerScriptLoader.h"
 
+#include "GenericWorkerTask.h"
 #include "ResourceRequest.h"
 #include "ScriptExecutionContext.h"
 #include "SecurityOrigin.h"
 #include "WorkerContext.h"
 #include "WorkerScriptLoaderClient.h"
 #include "WorkerThreadableLoader.h"
+#include <wtf/OwnPtr.h>
+#include <wtf/UnusedParam.h>
 
 namespace WebCore {
 
@@ -47,24 +50,59 @@ WorkerScriptLoader::WorkerScriptLoader()
 {
 }
 
-void WorkerScriptLoader::loadSynchronously(ScriptExecutionContext* scriptExecutionContext, const String& url, CrossOriginRedirectPolicy crossOriginRedirectPolicy)
+static CrossOriginRedirectPolicy toCrossOriginRedirectPolicy(CrossOriginLoadPolicy crossOriginLoadPolicy)
 {
-    ResourceRequest request(url);
-    request.setHTTPMethod("GET");
+    return (crossOriginLoadPolicy == DenyCrossOriginLoad) ? DenyCrossOriginRedirect : AllowCrossOriginRedirect;
+}
+
+void WorkerScriptLoader::loadSynchronously(ScriptExecutionContext* scriptExecutionContext, const String& url, URLCompletionPolicy urlCompletionPolicy, CrossOriginLoadPolicy crossOriginLoadPolicy)
+{
+    OwnPtr<ResourceRequest> request(createResourceRequest(scriptExecutionContext, url, urlCompletionPolicy, crossOriginLoadPolicy));
+    if (!request)
+        return;
 
     ASSERT(scriptExecutionContext->isWorkerContext());
-    WorkerThreadableLoader::loadResourceSynchronously(static_cast<WorkerContext*>(scriptExecutionContext), request, *this, AllowStoredCredentials, crossOriginRedirectPolicy);
+    WorkerThreadableLoader::loadResourceSynchronously(static_cast<WorkerContext*>(scriptExecutionContext), *request, *this, AllowStoredCredentials, toCrossOriginRedirectPolicy(crossOriginLoadPolicy));
 }
     
-void WorkerScriptLoader::loadAsynchronously(ScriptExecutionContext* scriptExecutionContext, const String& url, CrossOriginRedirectPolicy crossOriginRedirectPolicy, WorkerScriptLoaderClient* client)
+void WorkerScriptLoader::loadAsynchronously(ScriptExecutionContext* scriptExecutionContext, const String& url, URLCompletionPolicy urlCompletionPolicy, CrossOriginLoadPolicy crossOriginLoadPolicy, WorkerScriptLoaderClient* client)
 {
     ASSERT(client);
     m_client = client;
 
-    ResourceRequest request(url);
-    request.setHTTPMethod("GET");
+    OwnPtr<ResourceRequest> request(createResourceRequest(scriptExecutionContext, url, urlCompletionPolicy, crossOriginLoadPolicy));
+    if (!request)
+        return;
 
-    m_threadableLoader = ThreadableLoader::create(scriptExecutionContext, this, request, DoNotSendLoadCallbacks, DoNotSniffContent, AllowStoredCredentials, crossOriginRedirectPolicy);
+    m_threadableLoader = ThreadableLoader::create(scriptExecutionContext, this, *request, DoNotSendLoadCallbacks, DoNotSniffContent, AllowStoredCredentials, toCrossOriginRedirectPolicy(crossOriginLoadPolicy));
+}
+
+static void notifyLoadErrorTask(ScriptExecutionContext* context, WorkerScriptLoader* loader)
+{
+    UNUSED_PARAM(context);
+    loader->notifyError();
+}
+
+PassOwnPtr<ResourceRequest> WorkerScriptLoader::createResourceRequest(ScriptExecutionContext* scriptExecutionContext, const String& url, URLCompletionPolicy urlCompletionPolicy, CrossOriginLoadPolicy crossOriginLoadPolicy)
+{
+    if (urlCompletionPolicy == CompleteURL) {
+        m_url = scriptExecutionContext->completeURL(url);
+        if (url.isEmpty() || !m_url.isValid()) {
+            scriptExecutionContext->postTask(createCallbackTask(&notifyLoadErrorTask, this));
+            return 0;
+        }
+    } else
+        m_url = KURL(url);
+
+    if (crossOriginLoadPolicy == DenyCrossOriginLoad && !scriptExecutionContext->securityOrigin()->canAccess(SecurityOrigin::create(m_url).get())) {
+        scriptExecutionContext->postTask(createCallbackTask(&notifyLoadErrorTask, this));
+        return 0;
+    }
+
+    OwnPtr<ResourceRequest> request(new ResourceRequest(m_url));
+    request->setHTTPMethod("GET");
+
+    return request.release();
 }
     
 void WorkerScriptLoader::didReceiveResponse(const ResourceResponse& response)
@@ -111,18 +149,21 @@ void WorkerScriptLoader::didFinishLoading(unsigned long identifier)
 
 void WorkerScriptLoader::didFail(const ResourceError&)
 {
-    m_failed = true;
-    notifyFinished();
+    notifyError();
 }
 
 void WorkerScriptLoader::didFailRedirectCheck()
 {
-    m_failed = true;
-    notifyFinished();
+    notifyError();
 }
 
 void WorkerScriptLoader::didReceiveAuthenticationCancellation(const ResourceResponse&)
 {
+    notifyError();
+}
+
+void WorkerScriptLoader::notifyError()
+{
     m_failed = true;
     notifyFinished();
 }
index e3a9663..f465d7f 100644 (file)
@@ -30,6 +30,7 @@
 
 #if ENABLE(WORKERS)
 
+#include "KURL.h"
 #include "ResourceResponse.h"
 #include "ScriptString.h"
 #include "TextResourceDecoder.h"
@@ -41,14 +42,27 @@ namespace WebCore {
     class ScriptExecutionContext;
     class WorkerScriptLoaderClient;
 
+    enum URLCompletionPolicy {
+        CompleteURL,
+        DoNotCompleteURL
+    };
+
+    enum CrossOriginLoadPolicy {
+        DenyCrossOriginLoad,
+        AllowCrossOriginLoad
+    };
+
     class WorkerScriptLoader : public ThreadableLoaderClient {
     public:
         WorkerScriptLoader();
 
-        void loadSynchronously(ScriptExecutionContext*, const String& url, CrossOriginRedirectPolicy);
-        void loadAsynchronously(ScriptExecutionContext*, const String& url, CrossOriginRedirectPolicy, WorkerScriptLoaderClient*);
+        void loadSynchronously(ScriptExecutionContext*, const String& url, URLCompletionPolicy, CrossOriginLoadPolicy);
+        void loadAsynchronously(ScriptExecutionContext*, const String& url, URLCompletionPolicy, CrossOriginLoadPolicy, WorkerScriptLoaderClient*);
+
+        void notifyError();
 
         const String& script() const { return m_script; }
+        const KURL& url() const { return m_url; }
         bool failed() const { return m_failed; }
         unsigned long identifier() const { return m_identifier; }
 
@@ -60,6 +74,7 @@ namespace WebCore {
         virtual void didReceiveAuthenticationCancellation(const ResourceResponse&);
 
     private:
+        PassOwnPtr<ResourceRequest> createResourceRequest(ScriptExecutionContext*, const String& url, URLCompletionPolicy, CrossOriginLoadPolicy);
         void notifyFinished();
 
         WorkerScriptLoaderClient* m_client;
@@ -67,6 +82,7 @@ namespace WebCore {
         String m_responseEncoding;        
         RefPtr<TextResourceDecoder> m_decoder;
         String m_script;
+        KURL m_url;
         bool m_failed;
         unsigned long m_identifier;
     };