1 /* 2 * Copyright (C) 2013 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 #ifndef NewWebSocketChannelImpl_h 32 #define NewWebSocketChannelImpl_h 33 34 #include "core/dom/ContextLifecycleObserver.h" 35 #include "core/fileapi/Blob.h" 36 #include "core/fileapi/FileError.h" 37 #include "core/frame/ConsoleTypes.h" 38 #include "modules/websockets/WebSocketChannel.h" 39 #include "platform/weborigin/KURL.h" 40 #include "public/platform/WebSocketHandle.h" 41 #include "public/platform/WebSocketHandleClient.h" 42 #include "wtf/ArrayBuffer.h" 43 #include "wtf/Deque.h" 44 #include "wtf/FastAllocBase.h" 45 #include "wtf/OwnPtr.h" 46 #include "wtf/PassOwnPtr.h" 47 #include "wtf/PassRefPtr.h" 48 #include "wtf/RefPtr.h" 49 #include "wtf/Vector.h" 50 #include "wtf/text/CString.h" 51 #include "wtf/text/WTFString.h" 52 53 namespace blink { 54 55 class WebSocketHandshakeRequestInfo; 56 class WebSocketHandshakeResponseInfo; 57 58 } // namespace blink 59 60 namespace WebCore { 61 62 class Document; 63 class WebSocketHandshakeRequest; 64 65 // This class may replace MainThreadWebSocketChannel. 66 class NewWebSocketChannelImpl FINAL : public WebSocketChannel, public blink::WebSocketHandleClient, public ContextLifecycleObserver { 67 WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED; 68 public: 69 // You can specify the source file and the line number information 70 // explicitly by passing the last parameter. 71 // In the usual case, they are set automatically and you don't have to 72 // pass it. 73 static PassRefPtrWillBeRawPtr<NewWebSocketChannelImpl> create(ExecutionContext* context, WebSocketChannelClient* client, const String& sourceURL = String(), unsigned lineNumber = 0) 74 { 75 return adoptRefWillBeRefCountedGarbageCollected(new NewWebSocketChannelImpl(context, client, sourceURL, lineNumber)); 76 } 77 virtual ~NewWebSocketChannelImpl(); 78 79 // WebSocketChannel functions. 80 virtual bool connect(const KURL&, const String& protocol) OVERRIDE; 81 virtual WebSocketChannel::SendResult send(const String& message) OVERRIDE; 82 virtual WebSocketChannel::SendResult send(const ArrayBuffer&, unsigned byteOffset, unsigned byteLength) OVERRIDE; 83 virtual WebSocketChannel::SendResult send(PassRefPtr<BlobDataHandle>) OVERRIDE; 84 virtual WebSocketChannel::SendResult send(PassOwnPtr<Vector<char> > data) OVERRIDE; 85 // Start closing handshake. Use the CloseEventCodeNotSpecified for the code 86 // argument to omit payload. 87 virtual void close(int code, const String& reason) OVERRIDE; 88 virtual void fail(const String& reason, MessageLevel, const String&, unsigned lineNumber) OVERRIDE; 89 virtual void disconnect() OVERRIDE; 90 91 virtual void suspend() OVERRIDE; 92 virtual void resume() OVERRIDE; 93 94 virtual void trace(Visitor*) OVERRIDE; 95 96 private: 97 enum MessageType { 98 MessageTypeText, 99 MessageTypeBlob, 100 MessageTypeArrayBuffer, 101 MessageTypeVector, 102 }; 103 104 struct Message { 105 explicit Message(const String&); 106 explicit Message(PassRefPtr<BlobDataHandle>); 107 explicit Message(PassRefPtr<ArrayBuffer>); 108 explicit Message(PassOwnPtr<Vector<char> >); 109 110 MessageType type; 111 112 CString text; 113 RefPtr<BlobDataHandle> blobDataHandle; 114 RefPtr<ArrayBuffer> arrayBuffer; 115 OwnPtr<Vector<char> > vectorData; 116 }; 117 118 struct ReceivedMessage { 119 bool isMessageText; 120 Vector<char> data; 121 }; 122 123 class BlobLoader; 124 125 NewWebSocketChannelImpl(ExecutionContext*, WebSocketChannelClient*, const String&, unsigned); 126 void sendInternal(); 127 void flowControlIfNecessary(); failAsError(const String & reason)128 void failAsError(const String& reason) { fail(reason, ErrorMessageLevel, m_sourceURLAtConstruction, m_lineNumberAtConstruction); } 129 void abortAsyncOperations(); 130 void handleDidClose(bool wasClean, unsigned short code, const String& reason); 131 Document* document(); // can be called only when m_identifier > 0. 132 133 // WebSocketHandleClient functions. 134 virtual void didConnect(blink::WebSocketHandle*, bool fail, const blink::WebString& selectedProtocol, const blink::WebString& extensions) OVERRIDE; 135 virtual void didStartOpeningHandshake(blink::WebSocketHandle*, const blink::WebSocketHandshakeRequestInfo&) OVERRIDE; 136 virtual void didFinishOpeningHandshake(blink::WebSocketHandle*, const blink::WebSocketHandshakeResponseInfo&) OVERRIDE; 137 virtual void didFail(blink::WebSocketHandle*, const blink::WebString& message) OVERRIDE; 138 virtual void didReceiveData(blink::WebSocketHandle*, bool fin, blink::WebSocketHandle::MessageType, const char* data, size_t /* size */) OVERRIDE; 139 virtual void didClose(blink::WebSocketHandle*, bool wasClean, unsigned short code, const blink::WebString& reason) OVERRIDE; 140 virtual void didReceiveFlowControl(blink::WebSocketHandle*, int64_t quota) OVERRIDE; 141 virtual void didStartClosingHandshake(blink::WebSocketHandle*) OVERRIDE; 142 143 // Methods for BlobLoader. 144 void didFinishLoadingBlob(PassRefPtr<ArrayBuffer>); 145 void didFailLoadingBlob(FileError::ErrorCode); 146 147 // LifecycleObserver functions. 148 // This object must be destroyed before the context. contextDestroyed()149 virtual void contextDestroyed() OVERRIDE { ASSERT_NOT_REACHED(); } 150 151 // m_handle is a handle of the connection. 152 // m_handle == 0 means this channel is closed. 153 OwnPtr<blink::WebSocketHandle> m_handle; 154 155 // m_client can be deleted while this channel is alive, but this class 156 // expects that disconnect() is called before the deletion. 157 WebSocketChannelClient* m_client; 158 KURL m_url; 159 // m_identifier > 0 means calling scriptContextExecution() returns a Document. 160 unsigned long m_identifier; 161 OwnPtrWillBeMember<BlobLoader> m_blobLoader; 162 Deque<OwnPtr<Message> > m_messages; 163 Vector<char> m_receivingMessageData; 164 165 bool m_receivingMessageTypeIsText; 166 int64_t m_sendingQuota; 167 int64_t m_receivedDataSizeForFlowControl; 168 size_t m_sentSizeOfTopMessage; 169 170 String m_sourceURLAtConstruction; 171 unsigned m_lineNumberAtConstruction; 172 RefPtr<WebSocketHandshakeRequest> m_handshakeRequest; 173 174 static const int64_t receivedDataSizeForFlowControlHighWaterMark = 1 << 15; 175 }; 176 177 } // namespace WebCore 178 179 #endif // NewWebSocketChannelImpl_h 180