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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_TCPSocket_h
8 #define mozilla_dom_TCPSocket_h
10 #include "mozilla/dom/TCPSocketBinding.h"
11 #include "mozilla/dom/TypedArray.h"
12 #include "mozilla/DOMEventTargetHelper.h"
13 #include "nsIProxyInfo.h"
14 #include "nsITransport.h"
15 #include "nsIStreamListener.h"
16 #include "nsIAsyncInputStream.h"
17 #include "nsISupportsImpl.h"
18 #include "nsIObserver.h"
19 #include "nsWeakReference.h"
20 #include "nsITCPSocketCallback.h"
21 #include "nsIProtocolProxyCallback.h"
22 #include "js/RootingAPI.h"
24 class nsISocketTransport
;
25 class nsIInputStreamPump
;
26 class nsIScriptableInputStream
;
27 class nsIBinaryInputStream
;
28 class nsIMultiplexInputStream
;
29 class nsIAsyncStreamCopier
;
37 struct ServerSocketOptions
;
38 class TCPServerSocket
;
40 class TCPSocketParent
;
42 // This interface is only used for legacy navigator.mozTCPSocket API
44 class LegacyMozTCPSocket
: public nsISupports
{
46 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
47 NS_DECL_CYCLE_COLLECTION_CLASS(LegacyMozTCPSocket
)
49 explicit LegacyMozTCPSocket(nsPIDOMWindowInner
* aWindow
);
51 already_AddRefed
<TCPServerSocket
> Listen(uint16_t aPort
,
52 const ServerSocketOptions
& aOptions
,
53 uint16_t aBacklog
, ErrorResult
& aRv
);
55 already_AddRefed
<TCPSocket
> Open(const nsAString
& aHost
, uint16_t aPort
,
56 const SocketOptions
& aOptions
,
59 bool WrapObject(JSContext
* aCx
, JS::Handle
<JSObject
*> aGivenProto
,
60 JS::MutableHandle
<JSObject
*> aReflector
);
63 virtual ~LegacyMozTCPSocket();
65 nsCOMPtr
<nsIGlobalObject
> mGlobal
;
68 class TCPSocket final
: public DOMEventTargetHelper
,
69 public nsIStreamListener
,
70 public nsITransportEventSink
,
71 public nsIInputStreamCallback
,
73 public nsSupportsWeakReference
,
74 public nsITCPSocketCallback
,
75 public nsIProtocolProxyCallback
{
77 TCPSocket(nsIGlobalObject
* aGlobal
, const nsAString
& aHost
, uint16_t aPort
,
78 bool aSsl
, bool aUseArrayBuffers
);
80 NS_DECL_ISUPPORTS_INHERITED
81 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TCPSocket
,
83 NS_DECL_NSIREQUESTOBSERVER
84 NS_DECL_NSISTREAMLISTENER
85 NS_DECL_NSITRANSPORTEVENTSINK
86 NS_DECL_NSIINPUTSTREAMCALLBACK
88 NS_DECL_NSITCPSOCKETCALLBACK
89 NS_DECL_NSIPROTOCOLPROXYCALLBACK
91 virtual JSObject
* WrapObject(JSContext
* aCx
,
92 JS::Handle
<JSObject
*> aGivenProto
) override
;
94 static bool ShouldTCPSocketExist(JSContext
* aCx
, JSObject
* aGlobal
);
96 nsISocketTransport
* GetTransport() const { return mTransport
.get(); }
98 void GetHost(nsAString
& aHost
);
99 uint32_t Port() const;
101 uint64_t BufferedAmount() const { return mBufferedAmount
; }
103 void Resume(ErrorResult
& aRv
);
105 void CloseImmediately();
106 bool Send(const nsACString
& aData
, ErrorResult
& aRv
);
107 bool Send(const ArrayBuffer
& aData
, uint32_t aByteOffset
,
108 const Optional
<uint32_t>& aByteLength
, ErrorResult
& aRv
);
109 TCPReadyState
ReadyState();
110 TCPSocketBinaryType
BinaryType() const;
111 void UpgradeToSecure(ErrorResult
& aRv
);
113 static already_AddRefed
<TCPSocket
> Constructor(const GlobalObject
& aGlobal
,
114 const nsAString
& aHost
,
116 const SocketOptions
& aOptions
,
119 // Create a TCPSocket object from an existing low-level socket connection.
120 // Used by the TCPServerSocket implementation when a new connection is
122 static already_AddRefed
<TCPSocket
> CreateAcceptedSocket(
123 nsIGlobalObject
* aGlobal
, nsISocketTransport
* aTransport
,
124 bool aUseArrayBuffers
);
125 // Create a TCPSocket object from an existing child-side IPC actor.
126 // Used by the TCPServerSocketChild implementation when a new connection is
128 static already_AddRefed
<TCPSocket
> CreateAcceptedSocket(
129 nsIGlobalObject
* aGlobal
, TCPSocketChild
* aBridge
, bool aUseArrayBuffers
);
131 // Initialize this socket's associated IPC actor in the parent process.
132 void SetSocketBridgeParent(TCPSocketParent
* aBridgeParent
);
134 static bool SocketEnabled();
136 IMPL_EVENT_HANDLER(open
);
137 IMPL_EVENT_HANDLER(drain
);
138 IMPL_EVENT_HANDLER(data
);
139 IMPL_EVENT_HANDLER(error
);
140 IMPL_EVENT_HANDLER(close
);
142 nsresult
Init(nsIProxyInfo
* aProxyInfo
);
144 // Inform this socket that a buffered send() has completed sending.
145 void NotifyCopyComplete(nsresult aStatus
);
147 // Initialize this socket from a low-level connection that hasn't connected
148 // yet (called from RecvOpenBind() in TCPSocketParent).
149 nsresult
InitWithUnconnectedTransport(nsISocketTransport
* aTransport
);
154 // Initialize this socket with an existing IPC actor.
155 void InitWithSocketChild(TCPSocketChild
* aSocketBridge
);
156 // Initialize this socket from an existing low-level connection.
157 nsresult
InitWithTransport(nsISocketTransport
* aTransport
);
158 // Initialize the input/output streams for this socket object.
159 nsresult
CreateStream();
160 // Initialize the asynchronous read operation from this socket's input stream.
161 nsresult
CreateInputStreamPump();
162 // Send the contents of the provided input stream, which is assumed to be the
163 // given length for reporting and buffering purposes.
164 bool Send(nsIInputStream
* aStream
, uint32_t aByteLength
);
165 // Begin an asynchronous copy operation if one is not already in progress.
166 nsresult
EnsureCopying();
167 // Re-calculate buffered amount.
168 void CalculateBufferedAmount();
169 // Helper function, should be called by ActivateTLS(), only.
170 void ActivateTLSHelper();
171 // Enable TLS on this socket, dispatch to STSThread if necessary.
173 // Dispatch an error event if necessary, then dispatch a "close" event.
174 nsresult
MaybeReportErrorAndCloseIfOpen(nsresult status
);
176 // Helper for FireDataStringEvent/FireDataArrayEvent.
177 nsresult
FireDataEvent(JSContext
* aCx
, const nsAString
& aType
,
178 JS::Handle
<JS::Value
> aData
);
179 // Helper for Close/CloseImmediately
180 void CloseHelper(bool waitForUnsentData
);
182 nsresult
ResolveProxy();
184 TCPReadyState mReadyState
;
185 // Whether to use strings or array buffers for the "data" event.
186 bool mUseArrayBuffers
;
189 // Whether this socket is using a secure transport.
192 // The associated IPC actor in a child process.
193 RefPtr
<TCPSocketChild
> mSocketBridgeChild
;
194 // The associated IPC actor in a parent process.
195 RefPtr
<TCPSocketParent
> mSocketBridgeParent
;
197 // Raw socket streams
198 nsCOMPtr
<nsISocketTransport
> mTransport
;
199 nsCOMPtr
<nsIInputStream
> mSocketInputStream
;
200 nsCOMPtr
<nsIOutputStream
> mSocketOutputStream
;
202 nsCOMPtr
<nsICancelable
> mProxyRequest
;
204 // Input stream machinery
205 nsCOMPtr
<nsIInputStreamPump
> mInputStreamPump
;
206 nsCOMPtr
<nsIScriptableInputStream
> mInputStreamScriptable
;
207 nsCOMPtr
<nsIBinaryInputStream
> mInputStreamBinary
;
209 // Is there an async copy operation in progress?
210 bool mAsyncCopierActive
;
211 // True if the buffer is full and a "drain" event is expected by the client.
212 bool mWaitingForDrain
;
214 // The id of the window that created this socket.
215 uint64_t mInnerWindowID
;
217 // The current number of buffered bytes. Only used in content processes when
219 uint64_t mBufferedAmount
;
221 // The number of times this socket has had `Suspend` called without a
222 // corresponding `Resume`.
223 uint32_t mSuspendCount
;
225 // The current sequence number (ie. number of send operations) that have been
226 // processed. This is used in the IPC scenario by the child process to filter
227 // out outdated notifications about the amount of buffered data present in the
229 uint32_t mTrackingNumber
;
231 // True if this socket has been upgraded to secure after the initial
232 // connection, but the actual upgrade is waiting for an in-progress copy
233 // operation to complete.
234 bool mWaitingForStartTLS
;
235 // The buffered data awaiting the TLS upgrade to finish.
236 nsTArray
<nsCOMPtr
<nsIInputStream
>> mPendingDataAfterStartTLS
;
238 // The data to be sent.
239 nsTArray
<nsCOMPtr
<nsIInputStream
>> mPendingData
;
241 bool mObserversActive
;
245 } // namespace mozilla
247 #endif // mozilla_dom_TCPSocket_h