1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/content/base/src/WebSocket.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,261 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim: set sw=2 ts=8 et tw=80 : */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef WebSocket_h__ 1.11 +#define WebSocket_h__ 1.12 + 1.13 +#include "mozilla/Attributes.h" 1.14 +#include "mozilla/dom/TypedArray.h" 1.15 +#include "mozilla/dom/WebSocketBinding.h" // for BinaryType 1.16 +#include "mozilla/DOMEventTargetHelper.h" 1.17 +#include "mozilla/ErrorResult.h" 1.18 +#include "nsAutoPtr.h" 1.19 +#include "nsCOMPtr.h" 1.20 +#include "nsCycleCollectionParticipant.h" 1.21 +#include "nsIInterfaceRequestor.h" 1.22 +#include "nsIObserver.h" 1.23 +#include "nsIRequest.h" 1.24 +#include "nsISupports.h" 1.25 +#include "nsISupportsUtils.h" 1.26 +#include "nsIWebSocketChannel.h" 1.27 +#include "nsIWebSocketListener.h" 1.28 +#include "nsString.h" 1.29 +#include "nsWeakReference.h" 1.30 +#include "nsWrapperCache.h" 1.31 + 1.32 +#define DEFAULT_WS_SCHEME_PORT 80 1.33 +#define DEFAULT_WSS_SCHEME_PORT 443 1.34 + 1.35 +namespace mozilla { 1.36 +namespace dom { 1.37 + 1.38 +class WebSocket : public DOMEventTargetHelper, 1.39 + public nsIInterfaceRequestor, 1.40 + public nsIWebSocketListener, 1.41 + public nsIObserver, 1.42 + public nsSupportsWeakReference, 1.43 + public nsIRequest 1.44 +{ 1.45 +friend class CallDispatchConnectionCloseEvents; 1.46 +friend class nsAutoCloseWS; 1.47 + 1.48 +public: 1.49 + enum { 1.50 + CONNECTING = 0, 1.51 + OPEN = 1, 1.52 + CLOSING = 2, 1.53 + CLOSED = 3 1.54 + }; 1.55 + 1.56 +public: 1.57 + NS_DECL_ISUPPORTS_INHERITED 1.58 + NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_INHERITED( 1.59 + WebSocket, DOMEventTargetHelper) 1.60 + NS_DECL_NSIINTERFACEREQUESTOR 1.61 + NS_DECL_NSIWEBSOCKETLISTENER 1.62 + NS_DECL_NSIOBSERVER 1.63 + NS_DECL_NSIREQUEST 1.64 + 1.65 + // EventTarget 1.66 + virtual void EventListenerAdded(nsIAtom* aType) MOZ_OVERRIDE; 1.67 + virtual void EventListenerRemoved(nsIAtom* aType) MOZ_OVERRIDE; 1.68 + 1.69 + virtual void DisconnectFromOwner() MOZ_OVERRIDE; 1.70 + 1.71 + // nsWrapperCache 1.72 + nsPIDOMWindow* GetParentObject() { return GetOwner(); } 1.73 + 1.74 + virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE; 1.75 + 1.76 +public: // static helpers: 1.77 + 1.78 + // Determine if preferences allow WebSocket 1.79 + static bool PrefEnabled(JSContext* aCx = nullptr, JSObject* aGlobal = nullptr); 1.80 + 1.81 +public: // WebIDL interface: 1.82 + 1.83 + // Constructor: 1.84 + static already_AddRefed<WebSocket> Constructor(const GlobalObject& aGlobal, 1.85 + const nsAString& aUrl, 1.86 + ErrorResult& rv); 1.87 + 1.88 + static already_AddRefed<WebSocket> Constructor(const GlobalObject& aGlobal, 1.89 + const nsAString& aUrl, 1.90 + const nsAString& aProtocol, 1.91 + ErrorResult& rv); 1.92 + 1.93 + static already_AddRefed<WebSocket> Constructor(const GlobalObject& aGlobal, 1.94 + const nsAString& aUrl, 1.95 + const Sequence<nsString>& aProtocols, 1.96 + ErrorResult& rv); 1.97 + 1.98 + // webIDL: readonly attribute DOMString url 1.99 + void GetUrl(nsAString& aResult); 1.100 + 1.101 + // webIDL: readonly attribute unsigned short readyState; 1.102 + uint16_t ReadyState() const { return mReadyState; } 1.103 + 1.104 + // webIDL: readonly attribute unsigned long bufferedAmount; 1.105 + uint32_t BufferedAmount() const { return mOutgoingBufferedAmount; } 1.106 + 1.107 + // webIDL: attribute Function? onopen; 1.108 + IMPL_EVENT_HANDLER(open) 1.109 + 1.110 + // webIDL: attribute Function? onerror; 1.111 + IMPL_EVENT_HANDLER(error) 1.112 + 1.113 + // webIDL: attribute Function? onclose; 1.114 + IMPL_EVENT_HANDLER(close) 1.115 + 1.116 + // webIDL: readonly attribute DOMString extensions; 1.117 + void GetExtensions(nsAString& aResult); 1.118 + 1.119 + // webIDL: readonly attribute DOMString protocol; 1.120 + void GetProtocol(nsAString& aResult); 1.121 + 1.122 + // webIDL: void close(optional unsigned short code, optional DOMString reason): 1.123 + void Close(const Optional<uint16_t>& aCode, 1.124 + const Optional<nsAString>& aReason, 1.125 + ErrorResult& aRv); 1.126 + 1.127 + // webIDL: attribute Function? onmessage; 1.128 + IMPL_EVENT_HANDLER(message) 1.129 + 1.130 + // webIDL: attribute DOMString binaryType; 1.131 + dom::BinaryType BinaryType() const { return mBinaryType; } 1.132 + void SetBinaryType(dom::BinaryType aData) { mBinaryType = aData; } 1.133 + 1.134 + // webIDL: void send(DOMString|Blob|ArrayBufferView data); 1.135 + void Send(const nsAString& aData, 1.136 + ErrorResult& aRv); 1.137 + void Send(nsIDOMBlob* aData, 1.138 + ErrorResult& aRv); 1.139 + void Send(const ArrayBuffer& aData, 1.140 + ErrorResult& aRv); 1.141 + void Send(const ArrayBufferView& aData, 1.142 + ErrorResult& aRv); 1.143 + 1.144 +private: // constructor && distructor 1.145 + WebSocket(nsPIDOMWindow* aOwnerWindow); 1.146 + virtual ~WebSocket(); 1.147 + 1.148 +protected: 1.149 + nsresult Init(JSContext* aCx, 1.150 + nsIPrincipal* aPrincipal, 1.151 + const nsAString& aURL, 1.152 + nsTArray<nsString>& aProtocolArray); 1.153 + 1.154 + void Send(nsIInputStream* aMsgStream, 1.155 + const nsACString& aMsgString, 1.156 + uint32_t aMsgLength, 1.157 + bool aIsBinary, 1.158 + ErrorResult& aRv); 1.159 + 1.160 + nsresult ParseURL(const nsString& aURL); 1.161 + nsresult EstablishConnection(); 1.162 + 1.163 + // These methods when called can release the WebSocket object 1.164 + void FailConnection(uint16_t reasonCode, 1.165 + const nsACString& aReasonString = EmptyCString()); 1.166 + nsresult CloseConnection(uint16_t reasonCode, 1.167 + const nsACString& aReasonString = EmptyCString()); 1.168 + nsresult Disconnect(); 1.169 + 1.170 + nsresult ConsoleError(); 1.171 + nsresult PrintErrorOnConsole(const char* aBundleURI, 1.172 + const char16_t* aError, 1.173 + const char16_t** aFormatStrings, 1.174 + uint32_t aFormatStringsLen); 1.175 + 1.176 + nsresult DoOnMessageAvailable(const nsACString& aMsg, 1.177 + bool isBinary); 1.178 + 1.179 + // ConnectionCloseEvents: 'error' event if needed, then 'close' event. 1.180 + // - These must not be dispatched while we are still within an incoming call 1.181 + // from JS (ex: close()). Set 'sync' to false in that case to dispatch in a 1.182 + // separate new event. 1.183 + nsresult ScheduleConnectionCloseEvents(nsISupports* aContext, 1.184 + nsresult aStatusCode, 1.185 + bool sync); 1.186 + // 2nd half of ScheduleConnectionCloseEvents, sometimes run in its own event. 1.187 + void DispatchConnectionCloseEvents(); 1.188 + 1.189 + // These methods actually do the dispatch for various events. 1.190 + nsresult CreateAndDispatchSimpleEvent(const nsString& aName); 1.191 + nsresult CreateAndDispatchMessageEvent(const nsACString& aData, 1.192 + bool isBinary); 1.193 + nsresult CreateAndDispatchCloseEvent(bool aWasClean, 1.194 + uint16_t aCode, 1.195 + const nsString& aReason); 1.196 + 1.197 + // if there are "strong event listeners" (see comment in WebSocket.cpp) or 1.198 + // outgoing not sent messages then this method keeps the object alive 1.199 + // when js doesn't have strong references to it. 1.200 + void UpdateMustKeepAlive(); 1.201 + // ATTENTION, when calling this method the object can be released 1.202 + // (and possibly collected). 1.203 + void DontKeepAliveAnyMore(); 1.204 + 1.205 + nsresult UpdateURI(); 1.206 + 1.207 +protected: //data 1.208 + 1.209 + nsCOMPtr<nsIWebSocketChannel> mChannel; 1.210 + 1.211 + // related to the WebSocket constructor steps 1.212 + nsString mOriginalURL; 1.213 + nsString mEffectiveURL; // after redirects 1.214 + bool mSecure; // if true it is using SSL and the wss scheme, 1.215 + // otherwise it is using the ws scheme with no SSL 1.216 + 1.217 + bool mKeepingAlive; 1.218 + bool mCheckMustKeepAlive; 1.219 + bool mOnCloseScheduled; 1.220 + bool mFailed; 1.221 + bool mDisconnected; 1.222 + 1.223 + // Set attributes of DOM 'onclose' message 1.224 + bool mCloseEventWasClean; 1.225 + nsString mCloseEventReason; 1.226 + uint16_t mCloseEventCode; 1.227 + 1.228 + nsCString mAsciiHost; // hostname 1.229 + uint32_t mPort; 1.230 + nsCString mResource; // [filepath[?query]] 1.231 + nsString mUTF16Origin; 1.232 + 1.233 + nsCOMPtr<nsIURI> mURI; 1.234 + nsCString mRequestedProtocolList; 1.235 + nsCString mEstablishedProtocol; 1.236 + nsCString mEstablishedExtensions; 1.237 + 1.238 + uint16_t mReadyState; 1.239 + 1.240 + nsCOMPtr<nsIPrincipal> mPrincipal; 1.241 + 1.242 + uint32_t mOutgoingBufferedAmount; 1.243 + 1.244 + dom::BinaryType mBinaryType; 1.245 + 1.246 + // Web Socket owner information: 1.247 + // - the script file name, UTF8 encoded. 1.248 + // - source code line number where the Web Socket object was constructed. 1.249 + // - the ID of the inner window where the script lives. Note that this may not 1.250 + // be the same as the Web Socket owner window. 1.251 + // These attributes are used for error reporting. 1.252 + nsCString mScriptFile; 1.253 + uint32_t mScriptLine; 1.254 + uint64_t mInnerWindowID; 1.255 + 1.256 +private: 1.257 + WebSocket(const WebSocket& x) MOZ_DELETE; // prevent bad usage 1.258 + WebSocket& operator=(const WebSocket& x) MOZ_DELETE; 1.259 +}; 1.260 + 1.261 +} //namespace dom 1.262 +} //namespace mozilla 1.263 + 1.264 +#endif