1 /* 2 * Copyright (C) 2009 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "web/SharedWorkerRepositoryClientImpl.h" 33 34 #include "bindings/v8/ExceptionMessages.h" 35 #include "bindings/v8/ExceptionState.h" 36 #include "core/dom/ExceptionCode.h" 37 #include "core/dom/ExecutionContext.h" 38 #include "core/events/Event.h" 39 #include "core/frame/csp/ContentSecurityPolicy.h" 40 #include "core/inspector/InspectorInstrumentation.h" 41 #include "core/workers/SharedWorker.h" 42 #include "core/workers/WorkerScriptLoader.h" 43 #include "core/workers/WorkerScriptLoaderClient.h" 44 #include "platform/network/ResourceResponse.h" 45 #include "public/platform/WebMessagePortChannel.h" 46 #include "public/platform/WebString.h" 47 #include "public/platform/WebURL.h" 48 #include "public/web/WebContentSecurityPolicy.h" 49 #include "public/web/WebFrameClient.h" 50 #include "public/web/WebKit.h" 51 #include "public/web/WebSharedWorker.h" 52 #include "public/web/WebSharedWorkerRepositoryClient.h" 53 #include "web/WebLocalFrameImpl.h" 54 55 using namespace WebCore; 56 57 namespace blink { 58 59 // Callback class that keeps the SharedWorker and WebSharedWorker objects alive while connecting. 60 class SharedWorkerConnector : private WebSharedWorkerConnector::ConnectListener { 61 public: 62 SharedWorkerConnector(PassRefPtrWillBeRawPtr<SharedWorker> worker, const KURL& url, const String& name, PassOwnPtr<WebMessagePortChannel> channel, PassOwnPtr<WebSharedWorkerConnector> webWorkerConnector) 63 : m_worker(worker) 64 , m_url(url) 65 , m_name(name) 66 , m_webWorkerConnector(webWorkerConnector) 67 , m_channel(channel) { } 68 69 virtual ~SharedWorkerConnector(); 70 void connect(); 71 72 private: 73 // WebSharedWorkerConnector::ConnectListener overrides. 74 virtual void connected() OVERRIDE; 75 virtual void scriptLoadFailed() OVERRIDE; 76 77 RefPtrWillBePersistent<SharedWorker> m_worker; 78 KURL m_url; 79 String m_name; 80 OwnPtr<WebSharedWorkerConnector> m_webWorkerConnector; 81 OwnPtr<WebMessagePortChannel> m_channel; 82 }; 83 84 SharedWorkerConnector::~SharedWorkerConnector() 85 { 86 m_worker->unsetPreventGC(); 87 } 88 void SharedWorkerConnector::connect() 89 { 90 m_worker->setPreventGC(); 91 m_webWorkerConnector->connect(m_channel.leakPtr(), this); 92 } 93 94 void SharedWorkerConnector::connected() 95 { 96 // Free ourselves (this releases the SharedWorker so it can be freed as well if unreferenced). 97 delete this; 98 } 99 100 void SharedWorkerConnector::scriptLoadFailed() 101 { 102 m_worker->dispatchEvent(Event::createCancelable(EventTypeNames::error)); 103 // Free ourselves (this releases the SharedWorker so it can be freed as well if unreferenced). 104 delete this; 105 } 106 107 static WebSharedWorkerRepositoryClient::DocumentID getId(void* document) 108 { 109 ASSERT(document); 110 return reinterpret_cast<WebSharedWorkerRepositoryClient::DocumentID>(document); 111 } 112 113 void SharedWorkerRepositoryClientImpl::connect(PassRefPtrWillBeRawPtr<SharedWorker> worker, PassOwnPtr<WebMessagePortChannel> port, const KURL& url, const String& name, ExceptionState& exceptionState) 114 { 115 ASSERT(m_client); 116 117 // No nested workers (for now) - connect() should only be called from document context. 118 ASSERT(worker->executionContext()->isDocument()); 119 Document* document = toDocument(worker->executionContext()); 120 OwnPtr<WebSharedWorkerConnector> webWorkerConnector = adoptPtr(m_client->createSharedWorkerConnector(url, name, getId(document), worker->executionContext()->contentSecurityPolicy()->deprecatedHeader(), static_cast<blink::WebContentSecurityPolicyType>(worker->executionContext()->contentSecurityPolicy()->deprecatedHeaderType()))); 121 if (!webWorkerConnector) { 122 // Existing worker does not match this url, so return an error back to the caller. 123 exceptionState.throwDOMException(URLMismatchError, "The location of the SharedWorker named '" + name + "' does not exactly match the provided URL ('" + url.elidedString() + "')."); 124 return; 125 } 126 127 // The connector object manages its own lifecycle (and the lifecycles of the two worker objects). 128 // It will free itself once connecting is completed. 129 SharedWorkerConnector* connector = new SharedWorkerConnector(worker, url, name, port, webWorkerConnector.release()); 130 connector->connect(); 131 } 132 133 void SharedWorkerRepositoryClientImpl::documentDetached(Document* document) 134 { 135 ASSERT(m_client); 136 m_client->documentDetached(getId(document)); 137 } 138 139 SharedWorkerRepositoryClientImpl::SharedWorkerRepositoryClientImpl(WebSharedWorkerRepositoryClient* client) 140 : m_client(client) 141 { 142 } 143 144 } // namespace blink 145