| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 #include "core/inspector/InspectorInstrumentation.h" | 37 #include "core/inspector/InspectorInstrumentation.h" |
| 38 #include "core/workers/SharedWorker.h" | 38 #include "core/workers/SharedWorker.h" |
| 39 #include "platform/network/ResourceResponse.h" | 39 #include "platform/network/ResourceResponse.h" |
| 40 #include "public/platform/WebMessagePortChannel.h" | 40 #include "public/platform/WebMessagePortChannel.h" |
| 41 #include "public/platform/WebString.h" | 41 #include "public/platform/WebString.h" |
| 42 #include "public/platform/WebURL.h" | 42 #include "public/platform/WebURL.h" |
| 43 #include "public/web/WebContentSecurityPolicy.h" | 43 #include "public/web/WebContentSecurityPolicy.h" |
| 44 #include "public/web/WebFrameClient.h" | 44 #include "public/web/WebFrameClient.h" |
| 45 #include "public/web/WebKit.h" | 45 #include "public/web/WebKit.h" |
| 46 #include "public/web/WebSharedWorker.h" | 46 #include "public/web/WebSharedWorker.h" |
| 47 #include "public/web/WebSharedWorkerConnectListener.h" |
| 47 #include "public/web/WebSharedWorkerCreationErrors.h" | 48 #include "public/web/WebSharedWorkerCreationErrors.h" |
| 48 #include "public/web/WebSharedWorkerRepositoryClient.h" | 49 #include "public/web/WebSharedWorkerRepositoryClient.h" |
| 49 #include "web/WebLocalFrameImpl.h" | 50 #include "web/WebLocalFrameImpl.h" |
| 50 #include "wtf/PtrUtil.h" | 51 #include "wtf/PtrUtil.h" |
| 51 #include <memory> | 52 #include <memory> |
| 52 #include <utility> | 53 #include <utility> |
| 53 | 54 |
| 54 namespace blink { | 55 namespace blink { |
| 55 | 56 |
| 56 // Callback class that keeps the SharedWorker and WebSharedWorker objects alive | 57 // Implementation of the callback interface passed to the embedder. This will be |
| 57 // while connecting. | 58 // destructed when a connection to a shared worker is established. |
| 58 class SharedWorkerConnector | 59 class SharedWorkerConnectListener final |
| 59 : private WebSharedWorkerConnector::ConnectListener { | 60 : public WebSharedWorkerConnectListener { |
| 60 public: | 61 public: |
| 61 SharedWorkerConnector( | 62 explicit SharedWorkerConnectListener(SharedWorker* worker) |
| 62 SharedWorker* worker, | 63 : m_worker(worker) {} |
| 63 WebMessagePortChannelUniquePtr channel, | |
| 64 std::unique_ptr<WebSharedWorkerConnector> webWorkerConnector) | |
| 65 : m_worker(worker), | |
| 66 m_webWorkerConnector(std::move(webWorkerConnector)), | |
| 67 m_channel(std::move(channel)) {} | |
| 68 | 64 |
| 69 virtual ~SharedWorkerConnector(); | 65 ~SharedWorkerConnectListener() override { |
| 70 void connect(); | 66 DCHECK(!m_worker->isBeingConnected()); |
| 67 } |
| 71 | 68 |
| 72 private: | 69 // WebSharedWorkerConnectListener overrides. |
| 73 // WebSharedWorkerConnector::ConnectListener overrides. | 70 |
| 74 void connected() override; | 71 void workerCreated(WebWorkerCreationError creationError) override { |
| 75 void scriptLoadFailed() override; | 72 m_worker->setIsBeingConnected(true); |
| 73 |
| 74 // No nested workers (for now) - connect() should only be called from |
| 75 // document context. |
| 76 DCHECK(m_worker->getExecutionContext()->isDocument()); |
| 77 Document* document = toDocument(m_worker->getExecutionContext()); |
| 78 bool isSecureContext = m_worker->getExecutionContext()->isSecureContext(); |
| 79 switch (creationError) { |
| 80 case WebWorkerCreationErrorNone: |
| 81 return; |
| 82 case WebWorkerCreationErrorSecureContextMismatch: |
| 83 UseCounter::Feature feature = |
| 84 isSecureContext |
| 85 ? UseCounter::NonSecureSharedWorkerAccessedFromSecureContext |
| 86 : UseCounter::SecureSharedWorkerAccessedFromNonSecureContext; |
| 87 UseCounter::count(document, feature); |
| 88 return; |
| 89 } |
| 90 } |
| 91 |
| 92 void scriptLoadFailed() override { |
| 93 m_worker->dispatchEvent(Event::createCancelable(EventTypeNames::error)); |
| 94 m_worker->setIsBeingConnected(false); |
| 95 } |
| 96 |
| 97 void connected() override { m_worker->setIsBeingConnected(false); } |
| 76 | 98 |
| 77 Persistent<SharedWorker> m_worker; | 99 Persistent<SharedWorker> m_worker; |
| 78 std::unique_ptr<WebSharedWorkerConnector> m_webWorkerConnector; | |
| 79 WebMessagePortChannelUniquePtr m_channel; | |
| 80 }; | 100 }; |
| 81 | 101 |
| 82 SharedWorkerConnector::~SharedWorkerConnector() { | |
| 83 m_worker->setIsBeingConnected(false); | |
| 84 } | |
| 85 | |
| 86 void SharedWorkerConnector::connect() { | |
| 87 m_worker->setIsBeingConnected(true); | |
| 88 m_webWorkerConnector->connect(m_channel.release(), this); | |
| 89 } | |
| 90 | |
| 91 void SharedWorkerConnector::connected() { | |
| 92 // Free ourselves (this releases the SharedWorker so it can be freed as well | |
| 93 // if unreferenced). | |
| 94 delete this; | |
| 95 } | |
| 96 | |
| 97 void SharedWorkerConnector::scriptLoadFailed() { | |
| 98 m_worker->dispatchEvent(Event::createCancelable(EventTypeNames::error)); | |
| 99 // Free ourselves (this releases the SharedWorker so it can be freed as well | |
| 100 // if unreferenced). | |
| 101 delete this; | |
| 102 } | |
| 103 | |
| 104 static WebSharedWorkerRepositoryClient::DocumentID getId(void* document) { | 102 static WebSharedWorkerRepositoryClient::DocumentID getId(void* document) { |
| 105 DCHECK(document); | 103 DCHECK(document); |
| 106 return reinterpret_cast<WebSharedWorkerRepositoryClient::DocumentID>( | 104 return reinterpret_cast<WebSharedWorkerRepositoryClient::DocumentID>( |
| 107 document); | 105 document); |
| 108 } | 106 } |
| 109 | 107 |
| 110 void SharedWorkerRepositoryClientImpl::connect( | 108 void SharedWorkerRepositoryClientImpl::connect( |
| 111 SharedWorker* worker, | 109 SharedWorker* worker, |
| 112 WebMessagePortChannelUniquePtr port, | 110 WebMessagePortChannelUniquePtr port, |
| 113 const KURL& url, | 111 const KURL& url, |
| 114 const String& name) { | 112 const String& name) { |
| 115 DCHECK(m_client); | 113 DCHECK(m_client); |
| 116 | 114 |
| 117 // No nested workers (for now) - connect() should only be called from document | 115 // No nested workers (for now) - connect() should only be called from document |
| 118 // context. | 116 // context. |
| 119 DCHECK(worker->getExecutionContext()->isDocument()); | 117 DCHECK(worker->getExecutionContext()->isDocument()); |
| 120 Document* document = toDocument(worker->getExecutionContext()); | 118 Document* document = toDocument(worker->getExecutionContext()); |
| 121 | 119 |
| 122 // TODO(estark): this is broken, as it only uses the first header | 120 // TODO(estark): this is broken, as it only uses the first header |
| 123 // when multiple might have been sent. Fix by making the | 121 // when multiple might have been sent. Fix by making the |
| 124 // SharedWorkerConnector interface take a map that can contain | 122 // SharedWorkerConnectListener interface take a map that can contain |
| 125 // multiple headers. | 123 // multiple headers. |
| 126 std::unique_ptr<Vector<CSPHeaderAndType>> headers = | 124 std::unique_ptr<Vector<CSPHeaderAndType>> headers = |
| 127 worker->getExecutionContext()->contentSecurityPolicy()->headers(); | 125 worker->getExecutionContext()->contentSecurityPolicy()->headers(); |
| 128 WebString header; | 126 WebString header; |
| 129 WebContentSecurityPolicyType headerType = WebContentSecurityPolicyTypeReport; | 127 WebContentSecurityPolicyType headerType = WebContentSecurityPolicyTypeReport; |
| 130 | 128 |
| 131 if (headers->size() > 0) { | 129 if (headers->size() > 0) { |
| 132 header = (*headers)[0].first; | 130 header = (*headers)[0].first; |
| 133 headerType = | 131 headerType = |
| 134 static_cast<WebContentSecurityPolicyType>((*headers)[0].second); | 132 static_cast<WebContentSecurityPolicyType>((*headers)[0].second); |
| 135 } | 133 } |
| 136 | 134 |
| 137 WebWorkerCreationError creationError; | |
| 138 bool isSecureContext = worker->getExecutionContext()->isSecureContext(); | 135 bool isSecureContext = worker->getExecutionContext()->isSecureContext(); |
| 139 std::unique_ptr<WebSharedWorkerConnector> webWorkerConnector = | 136 std::unique_ptr<WebSharedWorkerConnectListener> listener = |
| 140 m_client->createSharedWorkerConnector( | 137 WTF::makeUnique<SharedWorkerConnectListener>(worker); |
| 141 url, name, getId(document), header, headerType, | 138 m_client->connect( |
| 142 worker->getExecutionContext()->securityContext().addressSpace(), | 139 url, name, getId(document), header, headerType, |
| 143 isSecureContext ? WebSharedWorkerCreationContextTypeSecure | 140 worker->getExecutionContext()->securityContext().addressSpace(), |
| 144 : WebSharedWorkerCreationContextTypeNonsecure, | 141 isSecureContext ? WebSharedWorkerCreationContextTypeSecure |
| 145 &creationError); | 142 : WebSharedWorkerCreationContextTypeNonsecure, |
| 146 | 143 port.release(), std::move(listener)); |
| 147 switch (creationError) { | |
| 148 case WebWorkerCreationErrorNone: | |
| 149 break; | |
| 150 case WebWorkerCreationErrorSecureContextMismatch: | |
| 151 UseCounter::Feature feature = | |
| 152 isSecureContext | |
| 153 ? UseCounter::NonSecureSharedWorkerAccessedFromSecureContext | |
| 154 : UseCounter::SecureSharedWorkerAccessedFromNonSecureContext; | |
| 155 UseCounter::count(document, feature); | |
| 156 break; | |
| 157 } | |
| 158 | |
| 159 // The connector object manages its own lifecycle (and the lifecycles of the | |
| 160 // two worker objects). It will free itself once connecting is completed. | |
| 161 SharedWorkerConnector* connector = new SharedWorkerConnector( | |
| 162 worker, std::move(port), std::move(webWorkerConnector)); | |
| 163 connector->connect(); | |
| 164 } | 144 } |
| 165 | 145 |
| 166 void SharedWorkerRepositoryClientImpl::documentDetached(Document* document) { | 146 void SharedWorkerRepositoryClientImpl::documentDetached(Document* document) { |
| 167 DCHECK(m_client); | 147 DCHECK(m_client); |
| 168 m_client->documentDetached(getId(document)); | 148 m_client->documentDetached(getId(document)); |
| 169 } | 149 } |
| 170 | 150 |
| 171 SharedWorkerRepositoryClientImpl::SharedWorkerRepositoryClientImpl( | 151 SharedWorkerRepositoryClientImpl::SharedWorkerRepositoryClientImpl( |
| 172 WebSharedWorkerRepositoryClient* client) | 152 WebSharedWorkerRepositoryClient* client) |
| 173 : m_client(client) {} | 153 : m_client(client) {} |
| 174 | 154 |
| 175 } // namespace blink | 155 } // namespace blink |
| OLD | NEW |