diff options
Diffstat (limited to 'dom/websocket/WebSocket.h')
-rw-r--r-- | dom/websocket/WebSocket.h | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/dom/websocket/WebSocket.h b/dom/websocket/WebSocket.h new file mode 100644 index 0000000000..a290750cf0 --- /dev/null +++ b/dom/websocket/WebSocket.h @@ -0,0 +1,192 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef WebSocket_h__ +#define WebSocket_h__ + +#include "mozilla/Attributes.h" +#include "mozilla/CheckedInt.h" +#include "mozilla/dom/TypedArray.h" +#include "mozilla/dom/WebSocketBinding.h" // for BinaryType +#include "mozilla/DOMEventTargetHelper.h" +#include "mozilla/Mutex.h" +#include "nsCOMPtr.h" +#include "nsCycleCollectionParticipant.h" +#include "nsISupports.h" +#include "nsISupportsUtils.h" +#include "nsString.h" +#include "nsWrapperCache.h" + +#define DEFAULT_WS_SCHEME_PORT 80 +#define DEFAULT_WSS_SCHEME_PORT 443 + +class nsIInputStream; +class nsITransportProvider; + +namespace mozilla { +class ErrorResult; + +namespace dom { + +class Blob; +class StringOrStringSequence; +class WebSocketImpl; + +class WebSocket final : public DOMEventTargetHelper { + friend class WebSocketImpl; + + public: + enum { CONNECTING = 0, OPEN = 1, CLOSING = 2, CLOSED = 3 }; + + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WebSocket, DOMEventTargetHelper) + virtual bool IsCertainlyAliveForCC() const override; + + // EventTarget + using EventTarget::EventListenerAdded; + virtual void EventListenerAdded(nsAtom* aType) override; + + using EventTarget::EventListenerRemoved; + virtual void EventListenerRemoved(nsAtom* aType) override; + + virtual void DisconnectFromOwner() override; + + mozilla::Maybe<EventCallbackDebuggerNotificationType> + GetDebuggerNotificationType() const override; + + // nsWrapperCache + virtual JSObject* WrapObject(JSContext* cx, + JS::Handle<JSObject*> aGivenProto) override; + + public: // static helpers: + // Determine if preferences allow WebSocket + static bool PrefEnabled(JSContext* aCx = nullptr, + JSObject* aGlobal = nullptr); + + public: // WebIDL interface: + // Constructor: + static already_AddRefed<WebSocket> Constructor( + const GlobalObject& aGlobal, const nsAString& aUrl, + const StringOrStringSequence& aProtocols, ErrorResult& rv); + + static already_AddRefed<WebSocket> CreateServerWebSocket( + const GlobalObject& aGlobal, const nsAString& aUrl, + const Sequence<nsString>& aProtocols, + nsITransportProvider* aTransportProvider, + const nsAString& aNegotiatedExtensions, ErrorResult& rv); + + static already_AddRefed<WebSocket> ConstructorCommon( + const GlobalObject& aGlobal, const nsAString& aUrl, + const Sequence<nsString>& aProtocols, + nsITransportProvider* aTransportProvider, + const nsACString& aNegotiatedExtensions, ErrorResult& rv); + + // webIDL: readonly attribute DOMString url + void GetUrl(nsAString& aResult); + + // webIDL: readonly attribute unsigned short readyState; + uint16_t ReadyState(); + + // webIDL: readonly attribute unsigned long long bufferedAmount; + uint64_t BufferedAmount() const; + + // webIDL: attribute Function? onopen; + IMPL_EVENT_HANDLER(open) + + // webIDL: attribute Function? onerror; + IMPL_EVENT_HANDLER(error) + + // webIDL: attribute Function? onclose; + IMPL_EVENT_HANDLER(close) + + // webIDL: readonly attribute DOMString extensions; + void GetExtensions(nsAString& aResult); + + // webIDL: readonly attribute DOMString protocol; + void GetProtocol(nsAString& aResult); + + // webIDL: void close(optional unsigned short code, + // optional DOMString reason): + void Close(const Optional<uint16_t>& aCode, + const Optional<nsAString>& aReason, ErrorResult& aRv); + + // webIDL: attribute Function? onmessage; + IMPL_EVENT_HANDLER(message) + + // webIDL: attribute DOMString binaryType; + dom::BinaryType BinaryType() const; + void SetBinaryType(dom::BinaryType aData); + + // webIDL: void send(DOMString|Blob|ArrayBufferView data); + void Send(const nsAString& aData, ErrorResult& aRv); + void Send(Blob& aData, ErrorResult& aRv); + void Send(const ArrayBuffer& aData, ErrorResult& aRv); + void Send(const ArrayBufferView& aData, ErrorResult& aRv); + + private: // constructor && destructor + explicit WebSocket(nsIGlobalObject* aGlobal); + virtual ~WebSocket(); + + void SetReadyState(uint16_t aReadyState); + + // These methods actually do the dispatch for various events. + nsresult CreateAndDispatchSimpleEvent(const nsAString& aName); + nsresult CreateAndDispatchMessageEvent(const nsACString& aData, + bool aIsBinary); + nsresult CreateAndDispatchCloseEvent(bool aWasClean, uint16_t aCode, + const nsAString& aReason); + + static bool IsValidProtocolString(const nsString& aValue); + + // if there are "strong event listeners" (see comment in WebSocket.cpp) or + // outgoing not sent messages then this method keeps the object alive + // when js doesn't have strong references to it. + void UpdateMustKeepAlive(); + // ATTENTION, when calling this method the object can be released + // (and possibly collected). + void DontKeepAliveAnyMore(); + + private: + WebSocket(const WebSocket& x) = delete; // prevent bad usage + WebSocket& operator=(const WebSocket& x) = delete; + + void Send(nsIInputStream* aMsgStream, const nsACString& aMsgString, + uint32_t aMsgLength, bool aIsBinary, ErrorResult& aRv); + + void AssertIsOnTargetThread() const; + + // Raw pointer because this WebSocketImpl is created, managed and destroyed by + // WebSocket. + WebSocketImpl* mImpl; + + bool mIsMainThread; + + bool mKeepingAlive; + bool mCheckMustKeepAlive; + + CheckedUint64 mOutgoingBufferedAmount; + + // related to the WebSocket constructor steps + nsString mURI; + nsString mEffectiveURL; // after redirects + nsCString mEstablishedExtensions; + nsCString mEstablishedProtocol; + + dom::BinaryType mBinaryType; + + // This mutex protects mReadyState that is the only variable that is used in + // different threads. + mozilla::Mutex mMutex; + + // This value should not be used directly but use ReadyState() instead. + uint16_t mReadyState MOZ_GUARDED_BY(mMutex); +}; + +} // namespace dom +} // namespace mozilla + +#endif |