Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef WebSocket_h__
8 : #define WebSocket_h__
9 :
10 : #include "mozilla/Attributes.h"
11 : #include "mozilla/CheckedInt.h"
12 : #include "mozilla/dom/TypedArray.h"
13 : #include "mozilla/dom/WebSocketBinding.h" // for BinaryType
14 : #include "mozilla/DOMEventTargetHelper.h"
15 : #include "mozilla/ErrorResult.h"
16 : #include "mozilla/Mutex.h"
17 : #include "nsCOMPtr.h"
18 : #include "nsCycleCollectionParticipant.h"
19 : #include "nsISupports.h"
20 : #include "nsISupportsUtils.h"
21 : #include "nsString.h"
22 : #include "nsWrapperCache.h"
23 :
24 : #define DEFAULT_WS_SCHEME_PORT 80
25 : #define DEFAULT_WSS_SCHEME_PORT 443
26 :
27 : class nsIInputStream;
28 : class nsITransportProvider;
29 :
30 : namespace mozilla {
31 : namespace dom {
32 :
33 : class Blob;
34 :
35 : class WebSocketImpl;
36 :
37 : class WebSocket final : public DOMEventTargetHelper
38 : {
39 : friend class WebSocketImpl;
40 :
41 : public:
42 : enum {
43 : CONNECTING = 0,
44 : OPEN = 1,
45 : CLOSING = 2,
46 : CLOSED = 3
47 : };
48 :
49 : public:
50 : NS_DECL_ISUPPORTS_INHERITED
51 0 : NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(WebSocket, DOMEventTargetHelper)
52 : virtual bool IsCertainlyAliveForCC() const override;
53 :
54 : // EventTarget
55 : using EventTarget::EventListenerAdded;
56 : virtual void EventListenerAdded(nsIAtom* aType) override;
57 :
58 : using EventTarget::EventListenerRemoved;
59 : virtual void EventListenerRemoved(nsIAtom* aType) override;
60 :
61 : virtual void DisconnectFromOwner() override;
62 :
63 : // nsWrapperCache
64 0 : nsPIDOMWindowInner* GetParentObject() { return GetOwner(); }
65 :
66 : virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override;
67 :
68 : public: // static helpers:
69 :
70 : // Determine if preferences allow WebSocket
71 : static bool PrefEnabled(JSContext* aCx = nullptr, JSObject* aGlobal = nullptr);
72 :
73 : public: // WebIDL interface:
74 :
75 : // Constructor:
76 : static already_AddRefed<WebSocket> Constructor(const GlobalObject& aGlobal,
77 : const nsAString& aUrl,
78 : ErrorResult& rv);
79 :
80 : static already_AddRefed<WebSocket> Constructor(const GlobalObject& aGlobal,
81 : const nsAString& aUrl,
82 : const nsAString& aProtocol,
83 : ErrorResult& rv);
84 :
85 : static already_AddRefed<WebSocket> Constructor(const GlobalObject& aGlobal,
86 : const nsAString& aUrl,
87 : const Sequence<nsString>& aProtocols,
88 : ErrorResult& rv);
89 :
90 : static already_AddRefed<WebSocket> CreateServerWebSocket(const GlobalObject& aGlobal,
91 : const nsAString& aUrl,
92 : const Sequence<nsString>& aProtocols,
93 : nsITransportProvider* aTransportProvider,
94 : const nsAString& aNegotiatedExtensions,
95 : ErrorResult& rv);
96 :
97 : static already_AddRefed<WebSocket> ConstructorCommon(const GlobalObject& aGlobal,
98 : const nsAString& aUrl,
99 : const Sequence<nsString>& aProtocols,
100 : nsITransportProvider* aTransportProvider,
101 : const nsACString& aNegotiatedExtensions,
102 : ErrorResult& rv);
103 :
104 : // webIDL: readonly attribute DOMString url
105 : void GetUrl(nsAString& aResult);
106 :
107 : // webIDL: readonly attribute unsigned short readyState;
108 : uint16_t ReadyState();
109 :
110 : // webIDL: readonly attribute unsigned long bufferedAmount;
111 : uint32_t BufferedAmount() const;
112 :
113 : // webIDL: attribute Function? onopen;
114 0 : IMPL_EVENT_HANDLER(open)
115 :
116 : // webIDL: attribute Function? onerror;
117 0 : IMPL_EVENT_HANDLER(error)
118 :
119 : // webIDL: attribute Function? onclose;
120 0 : IMPL_EVENT_HANDLER(close)
121 :
122 : // webIDL: readonly attribute DOMString extensions;
123 : void GetExtensions(nsAString& aResult);
124 :
125 : // webIDL: readonly attribute DOMString protocol;
126 : void GetProtocol(nsAString& aResult);
127 :
128 : // webIDL: void close(optional unsigned short code, optional DOMString reason):
129 : void Close(const Optional<uint16_t>& aCode,
130 : const Optional<nsAString>& aReason,
131 : ErrorResult& aRv);
132 :
133 : // webIDL: attribute Function? onmessage;
134 0 : IMPL_EVENT_HANDLER(message)
135 :
136 : // webIDL: attribute DOMString binaryType;
137 : dom::BinaryType BinaryType() const;
138 : void SetBinaryType(dom::BinaryType aData);
139 :
140 : // webIDL: void send(DOMString|Blob|ArrayBufferView data);
141 : void Send(const nsAString& aData,
142 : ErrorResult& aRv);
143 : void Send(Blob& aData,
144 : ErrorResult& aRv);
145 : void Send(const ArrayBuffer& aData,
146 : ErrorResult& aRv);
147 : void Send(const ArrayBufferView& aData,
148 : ErrorResult& aRv);
149 :
150 : private: // constructor && destructor
151 : explicit WebSocket(nsPIDOMWindowInner* aOwnerWindow);
152 : virtual ~WebSocket();
153 :
154 : void SetReadyState(uint16_t aReadyState);
155 :
156 : // These methods actually do the dispatch for various events.
157 : nsresult CreateAndDispatchSimpleEvent(const nsAString& aName);
158 : nsresult CreateAndDispatchMessageEvent(const nsACString& aData,
159 : bool aIsBinary);
160 : nsresult CreateAndDispatchCloseEvent(bool aWasClean,
161 : uint16_t aCode,
162 : const nsAString& aReason);
163 :
164 : // if there are "strong event listeners" (see comment in WebSocket.cpp) or
165 : // outgoing not sent messages then this method keeps the object alive
166 : // when js doesn't have strong references to it.
167 : void UpdateMustKeepAlive();
168 : // ATTENTION, when calling this method the object can be released
169 : // (and possibly collected).
170 : void DontKeepAliveAnyMore();
171 :
172 : private:
173 : WebSocket(const WebSocket& x) = delete; // prevent bad usage
174 : WebSocket& operator=(const WebSocket& x) = delete;
175 :
176 : void Send(nsIInputStream* aMsgStream,
177 : const nsACString& aMsgString,
178 : uint32_t aMsgLength,
179 : bool aIsBinary,
180 : ErrorResult& aRv);
181 :
182 : void AssertIsOnTargetThread() const;
183 :
184 : // Raw pointer because this WebSocketImpl is created, managed and destroyed by
185 : // WebSocket.
186 : WebSocketImpl* mImpl;
187 :
188 : bool mIsMainThread;
189 :
190 : bool mKeepingAlive;
191 : bool mCheckMustKeepAlive;
192 :
193 : CheckedUint32 mOutgoingBufferedAmount;
194 :
195 : // related to the WebSocket constructor steps
196 : nsString mURI;
197 : nsString mEffectiveURL; // after redirects
198 : nsCString mEstablishedExtensions;
199 : nsCString mEstablishedProtocol;
200 :
201 : dom::BinaryType mBinaryType;
202 :
203 : // This mutex protects mReadyState that is the only variable that is used in
204 : // different threads.
205 : mozilla::Mutex mMutex;
206 :
207 : // This value should not be used directly but use ReadyState() instead.
208 : uint16_t mReadyState;
209 : };
210 :
211 : } //namespace dom
212 : } //namespace mozilla
213 :
214 : #endif
|