| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 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 12 matching lines...) Expand all Loading... |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 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. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "modules/websockets/DocumentWebSocketChannel.h" | 31 #include "modules/websockets/DocumentWebSocketChannel.h" |
| 32 | 32 |
| 33 #include <memory> |
| 33 #include "core/dom/DOMArrayBuffer.h" | 34 #include "core/dom/DOMArrayBuffer.h" |
| 34 #include "core/dom/Document.h" | 35 #include "core/dom/Document.h" |
| 35 #include "core/dom/ExecutionContext.h" | 36 #include "core/dom/ExecutionContext.h" |
| 36 #include "core/fileapi/FileReaderLoader.h" | 37 #include "core/fileapi/FileReaderLoader.h" |
| 37 #include "core/fileapi/FileReaderLoaderClient.h" | 38 #include "core/fileapi/FileReaderLoaderClient.h" |
| 38 #include "core/frame/LocalFrame.h" | 39 #include "core/frame/LocalFrame.h" |
| 39 #include "core/inspector/ConsoleMessage.h" | 40 #include "core/inspector/ConsoleMessage.h" |
| 40 #include "core/inspector/InspectorInstrumentation.h" | 41 #include "core/inspector/InspectorInstrumentation.h" |
| 41 #include "core/loader/FrameLoader.h" | 42 #include "core/loader/FrameLoader.h" |
| 42 #include "core/loader/FrameLoaderClient.h" | 43 #include "core/loader/FrameLoaderClient.h" |
| 43 #include "core/loader/MixedContentChecker.h" | 44 #include "core/loader/MixedContentChecker.h" |
| 44 #include "modules/websockets/InspectorWebSocketEvents.h" | 45 #include "modules/websockets/InspectorWebSocketEvents.h" |
| 45 #include "modules/websockets/WebSocketChannelClient.h" | 46 #include "modules/websockets/WebSocketChannelClient.h" |
| 46 #include "modules/websockets/WebSocketFrame.h" | 47 #include "modules/websockets/WebSocketFrame.h" |
| 47 #include "modules/websockets/WebSocketHandleImpl.h" | 48 #include "modules/websockets/WebSocketHandleImpl.h" |
| 49 #include "platform/WebFrameScheduler.h" |
| 48 #include "platform/loader/fetch/UniqueIdentifier.h" | 50 #include "platform/loader/fetch/UniqueIdentifier.h" |
| 49 #include "platform/network/NetworkLog.h" | 51 #include "platform/network/NetworkLog.h" |
| 50 #include "platform/network/WebSocketHandshakeRequest.h" | 52 #include "platform/network/WebSocketHandshakeRequest.h" |
| 51 #include "platform/weborigin/SecurityOrigin.h" | 53 #include "platform/weborigin/SecurityOrigin.h" |
| 52 #include "public/platform/InterfaceProvider.h" | 54 #include "public/platform/InterfaceProvider.h" |
| 53 #include "public/platform/Platform.h" | 55 #include "public/platform/Platform.h" |
| 54 #include "wtf/PtrUtil.h" | 56 #include "wtf/PtrUtil.h" |
| 55 #include <memory> | |
| 56 | 57 |
| 57 namespace blink { | 58 namespace blink { |
| 58 | 59 |
| 59 class DocumentWebSocketChannel::BlobLoader final | 60 class DocumentWebSocketChannel::BlobLoader final |
| 60 : public GarbageCollectedFinalized<DocumentWebSocketChannel::BlobLoader>, | 61 : public GarbageCollectedFinalized<DocumentWebSocketChannel::BlobLoader>, |
| 61 public FileReaderLoaderClient { | 62 public FileReaderLoaderClient { |
| 62 public: | 63 public: |
| 63 BlobLoader(PassRefPtr<BlobDataHandle>, DocumentWebSocketChannel*); | 64 BlobLoader(PassRefPtr<BlobDataHandle>, DocumentWebSocketChannel*); |
| 64 ~BlobLoader() override {} | 65 ~BlobLoader() override {} |
| 65 | 66 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 } | 159 } |
| 159 if (MixedContentChecker::isMixedContent(document()->getSecurityOrigin(), | 160 if (MixedContentChecker::isMixedContent(document()->getSecurityOrigin(), |
| 160 url)) { | 161 url)) { |
| 161 String message = | 162 String message = |
| 162 "Connecting to a non-secure WebSocket server from a secure origin is " | 163 "Connecting to a non-secure WebSocket server from a secure origin is " |
| 163 "deprecated."; | 164 "deprecated."; |
| 164 document()->addConsoleMessage( | 165 document()->addConsoleMessage( |
| 165 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); | 166 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, message)); |
| 166 } | 167 } |
| 167 | 168 |
| 169 if (document()->frame()) { |
| 170 connection_handle_for_scheduler_ = |
| 171 document()->frame()->frameScheduler()->onActiveConnectionCreated(); |
| 172 } |
| 173 |
| 168 m_url = url; | 174 m_url = url; |
| 169 Vector<String> protocols; | 175 Vector<String> protocols; |
| 170 // Avoid placing an empty token in the Vector when the protocol string is | 176 // Avoid placing an empty token in the Vector when the protocol string is |
| 171 // empty. | 177 // empty. |
| 172 if (!protocol.isEmpty()) { | 178 if (!protocol.isEmpty()) { |
| 173 // Since protocol is already verified and escaped, we can simply split | 179 // Since protocol is already verified and escaped, we can simply split |
| 174 // it. | 180 // it. |
| 175 protocol.split(", ", true, protocols); | 181 protocol.split(", ", true, protocols); |
| 176 } | 182 } |
| 177 | 183 |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 281 m_messages.append(new Message(codeToSend, reason)); | 287 m_messages.append(new Message(codeToSend, reason)); |
| 282 processSendQueue(); | 288 processSendQueue(); |
| 283 } | 289 } |
| 284 | 290 |
| 285 void DocumentWebSocketChannel::fail(const String& reason, | 291 void DocumentWebSocketChannel::fail(const String& reason, |
| 286 MessageLevel level, | 292 MessageLevel level, |
| 287 std::unique_ptr<SourceLocation> location) { | 293 std::unique_ptr<SourceLocation> location) { |
| 288 NETWORK_DVLOG(1) << this << " fail(" << reason << ")"; | 294 NETWORK_DVLOG(1) << this << " fail(" << reason << ")"; |
| 289 // m_handle and m_client can be null here. | 295 // m_handle and m_client can be null here. |
| 290 | 296 |
| 297 connection_handle_for_scheduler_.reset(); |
| 298 |
| 291 InspectorInstrumentation::didReceiveWebSocketFrameError(document(), | 299 InspectorInstrumentation::didReceiveWebSocketFrameError(document(), |
| 292 m_identifier, reason); | 300 m_identifier, reason); |
| 293 const String message = "WebSocket connection to '" + m_url.elidedString() + | 301 const String message = "WebSocket connection to '" + m_url.elidedString() + |
| 294 "' failed: " + reason; | 302 "' failed: " + reason; |
| 295 document()->addConsoleMessage(ConsoleMessage::create( | 303 document()->addConsoleMessage(ConsoleMessage::create( |
| 296 JSMessageSource, level, message, std::move(location))); | 304 JSMessageSource, level, message, std::move(location))); |
| 297 | 305 |
| 298 if (m_client) | 306 if (m_client) |
| 299 m_client->didError(); | 307 m_client->didError(); |
| 300 // |reason| is only for logging and should not be provided for scripts, | 308 // |reason| is only for logging and should not be provided for scripts, |
| 301 // hence close reason must be empty. | 309 // hence close reason must be empty. |
| 302 handleDidClose(false, CloseEventCodeAbnormalClosure, String()); | 310 handleDidClose(false, CloseEventCodeAbnormalClosure, String()); |
| 303 // handleDidClose may delete this object. | 311 // handleDidClose may delete this object. |
| 304 } | 312 } |
| 305 | 313 |
| 306 void DocumentWebSocketChannel::disconnect() { | 314 void DocumentWebSocketChannel::disconnect() { |
| 307 NETWORK_DVLOG(1) << this << " disconnect()"; | 315 NETWORK_DVLOG(1) << this << " disconnect()"; |
| 308 if (m_identifier) { | 316 if (m_identifier) { |
| 309 TRACE_EVENT_INSTANT1( | 317 TRACE_EVENT_INSTANT1( |
| 310 "devtools.timeline", "WebSocketDestroy", TRACE_EVENT_SCOPE_THREAD, | 318 "devtools.timeline", "WebSocketDestroy", TRACE_EVENT_SCOPE_THREAD, |
| 311 "data", InspectorWebSocketEvent::data(document(), m_identifier)); | 319 "data", InspectorWebSocketEvent::data(document(), m_identifier)); |
| 312 InspectorInstrumentation::didCloseWebSocket(document(), m_identifier); | 320 InspectorInstrumentation::didCloseWebSocket(document(), m_identifier); |
| 313 } | 321 } |
| 322 connection_handle_for_scheduler_.reset(); |
| 314 abortAsyncOperations(); | 323 abortAsyncOperations(); |
| 315 m_handle.reset(); | 324 m_handle.reset(); |
| 316 m_client = nullptr; | 325 m_client = nullptr; |
| 317 m_identifier = 0; | 326 m_identifier = 0; |
| 318 } | 327 } |
| 319 | 328 |
| 320 DocumentWebSocketChannel::Message::Message(const CString& text) | 329 DocumentWebSocketChannel::Message::Message(const CString& text) |
| 321 : type(MessageTypeText), text(text) {} | 330 : type(MessageTypeText), text(text) {} |
| 322 | 331 |
| 323 DocumentWebSocketChannel::Message::Message( | 332 DocumentWebSocketChannel::Message::Message( |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 496 InspectorInstrumentation::didReceiveWebSocketHandshakeResponse( | 505 InspectorInstrumentation::didReceiveWebSocketHandshakeResponse( |
| 497 document(), m_identifier, m_handshakeRequest.get(), response); | 506 document(), m_identifier, m_handshakeRequest.get(), response); |
| 498 m_handshakeRequest.clear(); | 507 m_handshakeRequest.clear(); |
| 499 } | 508 } |
| 500 | 509 |
| 501 void DocumentWebSocketChannel::didFail(WebSocketHandle* handle, | 510 void DocumentWebSocketChannel::didFail(WebSocketHandle* handle, |
| 502 const String& message) { | 511 const String& message) { |
| 503 NETWORK_DVLOG(1) << this << " didFail(" << handle << ", " << String(message) | 512 NETWORK_DVLOG(1) << this << " didFail(" << handle << ", " << String(message) |
| 504 << ")"; | 513 << ")"; |
| 505 | 514 |
| 515 connection_handle_for_scheduler_.reset(); |
| 516 |
| 506 DCHECK(m_handle); | 517 DCHECK(m_handle); |
| 507 DCHECK_EQ(handle, m_handle.get()); | 518 DCHECK_EQ(handle, m_handle.get()); |
| 508 | 519 |
| 509 // This function is called when the browser is required to fail the | 520 // This function is called when the browser is required to fail the |
| 510 // WebSocketConnection. Hence we fail this channel by calling | 521 // WebSocketConnection. Hence we fail this channel by calling |
| 511 // |this->failAsError| function. | 522 // |this->failAsError| function. |
| 512 failAsError(message); | 523 failAsError(message); |
| 513 // |this| may be deleted. | 524 // |this| may be deleted. |
| 514 } | 525 } |
| 515 | 526 |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 578 } | 589 } |
| 579 } | 590 } |
| 580 | 591 |
| 581 void DocumentWebSocketChannel::didClose(WebSocketHandle* handle, | 592 void DocumentWebSocketChannel::didClose(WebSocketHandle* handle, |
| 582 bool wasClean, | 593 bool wasClean, |
| 583 unsigned short code, | 594 unsigned short code, |
| 584 const String& reason) { | 595 const String& reason) { |
| 585 NETWORK_DVLOG(1) << this << " didClose(" << handle << ", " << wasClean << ", " | 596 NETWORK_DVLOG(1) << this << " didClose(" << handle << ", " << wasClean << ", " |
| 586 << code << ", " << String(reason) << ")"; | 597 << code << ", " << String(reason) << ")"; |
| 587 | 598 |
| 599 connection_handle_for_scheduler_.reset(); |
| 600 |
| 588 DCHECK(m_handle); | 601 DCHECK(m_handle); |
| 589 DCHECK_EQ(handle, m_handle.get()); | 602 DCHECK_EQ(handle, m_handle.get()); |
| 590 | 603 |
| 591 m_handle.reset(); | 604 m_handle.reset(); |
| 592 | 605 |
| 593 if (m_identifier) { | 606 if (m_identifier) { |
| 594 TRACE_EVENT_INSTANT1( | 607 TRACE_EVENT_INSTANT1( |
| 595 "devtools.timeline", "WebSocketDestroy", TRACE_EVENT_SCOPE_THREAD, | 608 "devtools.timeline", "WebSocketDestroy", TRACE_EVENT_SCOPE_THREAD, |
| 596 "data", InspectorWebSocketEvent::data(document(), m_identifier)); | 609 "data", InspectorWebSocketEvent::data(document(), m_identifier)); |
| 597 InspectorInstrumentation::didCloseWebSocket(document(), m_identifier); | 610 InspectorInstrumentation::didCloseWebSocket(document(), m_identifier); |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 WebSocketChannel::trace(visitor); | 670 WebSocketChannel::trace(visitor); |
| 658 } | 671 } |
| 659 | 672 |
| 660 std::ostream& operator<<(std::ostream& ostream, | 673 std::ostream& operator<<(std::ostream& ostream, |
| 661 const DocumentWebSocketChannel* channel) { | 674 const DocumentWebSocketChannel* channel) { |
| 662 return ostream << "DocumentWebSocketChannel " | 675 return ostream << "DocumentWebSocketChannel " |
| 663 << static_cast<const void*>(channel); | 676 << static_cast<const void*>(channel); |
| 664 } | 677 } |
| 665 | 678 |
| 666 } // namespace blink | 679 } // namespace blink |
| OLD | NEW |