TCPSocket.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #ifndef mozilla_dom_TCPSocket_h
  6. #define mozilla_dom_TCPSocket_h
  7. #include "mozilla/dom/TCPSocketBinding.h"
  8. #include "mozilla/DOMEventTargetHelper.h"
  9. #include "nsITransport.h"
  10. #include "nsIStreamListener.h"
  11. #include "nsIAsyncInputStream.h"
  12. #include "nsISupportsImpl.h"
  13. #include "nsIObserver.h"
  14. #include "nsWeakReference.h"
  15. #include "nsITCPSocketCallback.h"
  16. #include "js/RootingAPI.h"
  17. class nsISocketTransport;
  18. class nsIInputStreamPump;
  19. class nsIScriptableInputStream;
  20. class nsIBinaryInputStream;
  21. class nsIMultiplexInputStream;
  22. class nsIAsyncStreamCopier;
  23. class nsIInputStream;
  24. class nsINetworkInfo;
  25. namespace mozilla {
  26. class ErrorResult;
  27. namespace dom {
  28. class DOMError;
  29. struct ServerSocketOptions;
  30. class TCPServerSocket;
  31. class TCPSocketChild;
  32. class TCPSocketParent;
  33. // This interface is only used for legacy navigator.mozTCPSocket API compatibility.
  34. class LegacyMozTCPSocket : public nsISupports
  35. {
  36. public:
  37. NS_DECL_CYCLE_COLLECTING_ISUPPORTS
  38. NS_DECL_CYCLE_COLLECTION_CLASS(LegacyMozTCPSocket)
  39. explicit LegacyMozTCPSocket(nsPIDOMWindowInner* aWindow);
  40. already_AddRefed<TCPServerSocket>
  41. Listen(uint16_t aPort,
  42. const ServerSocketOptions& aOptions,
  43. uint16_t aBacklog,
  44. ErrorResult& aRv);
  45. already_AddRefed<TCPSocket>
  46. Open(const nsAString& aHost,
  47. uint16_t aPort,
  48. const SocketOptions& aOptions,
  49. ErrorResult& aRv);
  50. bool WrapObject(JSContext* aCx,
  51. JS::Handle<JSObject*> aGivenProto,
  52. JS::MutableHandle<JSObject*> aReflector);
  53. private:
  54. virtual ~LegacyMozTCPSocket();
  55. nsCOMPtr<nsIGlobalObject> mGlobal;
  56. };
  57. class TCPSocket final : public DOMEventTargetHelper
  58. , public nsIStreamListener
  59. , public nsITransportEventSink
  60. , public nsIInputStreamCallback
  61. , public nsIObserver
  62. , public nsSupportsWeakReference
  63. , public nsITCPSocketCallback
  64. {
  65. public:
  66. TCPSocket(nsIGlobalObject* aGlobal, const nsAString& aHost, uint16_t aPort,
  67. bool aSsl, bool aUseArrayBuffers);
  68. NS_DECL_ISUPPORTS_INHERITED
  69. NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TCPSocket, DOMEventTargetHelper)
  70. NS_DECL_NSIREQUESTOBSERVER
  71. NS_DECL_NSISTREAMLISTENER
  72. NS_DECL_NSITRANSPORTEVENTSINK
  73. NS_DECL_NSIINPUTSTREAMCALLBACK
  74. NS_DECL_NSIOBSERVER
  75. NS_DECL_NSITCPSOCKETCALLBACK
  76. virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
  77. static bool ShouldTCPSocketExist(JSContext* aCx, JSObject* aGlobal);
  78. void GetHost(nsAString& aHost);
  79. uint32_t Port();
  80. bool Ssl();
  81. uint64_t BufferedAmount();
  82. void Suspend();
  83. void Resume(ErrorResult& aRv);
  84. void Close();
  85. void CloseImmediately();
  86. bool Send(JSContext* aCx, const nsACString& aData, ErrorResult& aRv);
  87. bool Send(JSContext* aCx,
  88. const ArrayBuffer& aData,
  89. uint32_t aByteOffset,
  90. const Optional<uint32_t>& aByteLength,
  91. ErrorResult& aRv);
  92. TCPReadyState ReadyState();
  93. TCPSocketBinaryType BinaryType();
  94. void UpgradeToSecure(ErrorResult& aRv);
  95. static already_AddRefed<TCPSocket>
  96. Constructor(const GlobalObject& aGlobal,
  97. const nsAString& aHost,
  98. uint16_t aPort,
  99. const SocketOptions& aOptions,
  100. ErrorResult& aRv);
  101. // Perform a send operation that's asssociated with a sequence number. Used in
  102. // IPC scenarios to track the number of bytes buffered at any given time.
  103. void SendWithTrackingNumber(const nsACString& aData,
  104. const uint32_t& aTrackingNumber,
  105. ErrorResult& aRv);
  106. void SendWithTrackingNumber(JSContext* aCx,
  107. const ArrayBuffer& aData,
  108. uint32_t aByteOffset,
  109. const Optional<uint32_t>& aByteLength,
  110. const uint32_t& aTrackingNumber,
  111. ErrorResult& aRv);
  112. // Create a TCPSocket object from an existing low-level socket connection.
  113. // Used by the TCPServerSocket implementation when a new connection is accepted.
  114. static already_AddRefed<TCPSocket>
  115. CreateAcceptedSocket(nsIGlobalObject* aGlobal, nsISocketTransport* aTransport, bool aUseArrayBuffers);
  116. // Create a TCPSocket object from an existing child-side IPC actor.
  117. // Used by the TCPServerSocketChild implementation when a new connection is accepted.
  118. static already_AddRefed<TCPSocket>
  119. CreateAcceptedSocket(nsIGlobalObject* aGlobal, TCPSocketChild* aSocketBridge, bool aUseArrayBuffers);
  120. // Initialize this socket's associated app and browser information.
  121. void SetAppIdAndBrowser(uint32_t aAppId, bool aInBrowser);
  122. // Initialize this socket's associated IPC actor in the parent process.
  123. void SetSocketBridgeParent(TCPSocketParent* aBridgeParent);
  124. static bool SocketEnabled();
  125. IMPL_EVENT_HANDLER(open);
  126. IMPL_EVENT_HANDLER(drain);
  127. IMPL_EVENT_HANDLER(data);
  128. IMPL_EVENT_HANDLER(error);
  129. IMPL_EVENT_HANDLER(close);
  130. nsresult Init();
  131. // Inform this socket that a buffered send() has completed sending.
  132. void NotifyCopyComplete(nsresult aStatus);
  133. // Initialize this socket from a low-level connection that hasn't connected yet
  134. // (called from RecvOpenBind() in TCPSocketParent).
  135. nsresult InitWithUnconnectedTransport(nsISocketTransport* aTransport);
  136. private:
  137. ~TCPSocket();
  138. // Initialize this socket with an existing IPC actor.
  139. void InitWithSocketChild(TCPSocketChild* aBridge);
  140. // Initialize this socket from an existing low-level connection.
  141. nsresult InitWithTransport(nsISocketTransport* aTransport);
  142. // Initialize the input/output streams for this socket object.
  143. nsresult CreateStream();
  144. // Initialize the asynchronous read operation from this socket's input stream.
  145. nsresult CreateInputStreamPump();
  146. // Send the contents of the provided input stream, which is assumed to be the given length
  147. // for reporting and buffering purposes.
  148. bool Send(nsIInputStream* aStream, uint32_t aByteLength);
  149. // Begin an asynchronous copy operation if one is not already in progress.
  150. nsresult EnsureCopying();
  151. // Enable TLS on this socket.
  152. void ActivateTLS();
  153. // Dispatch an error event if necessary, then dispatch a "close" event.
  154. nsresult MaybeReportErrorAndCloseIfOpen(nsresult status);
  155. // Helper for FireDataStringEvent/FireDataArrayEvent.
  156. nsresult FireDataEvent(JSContext* aCx, const nsAString& aType,
  157. JS::Handle<JS::Value> aData);
  158. // Helper for Close/CloseImmediately
  159. void CloseHelper(bool waitForUnsentData);
  160. TCPReadyState mReadyState;
  161. // Whether to use strings or array buffers for the "data" event.
  162. bool mUseArrayBuffers;
  163. nsString mHost;
  164. uint16_t mPort;
  165. // Whether this socket is using a secure transport.
  166. bool mSsl;
  167. // The associated IPC actor in a child process.
  168. RefPtr<TCPSocketChild> mSocketBridgeChild;
  169. // The associated IPC actor in a parent process.
  170. RefPtr<TCPSocketParent> mSocketBridgeParent;
  171. // Raw socket streams
  172. nsCOMPtr<nsISocketTransport> mTransport;
  173. nsCOMPtr<nsIInputStream> mSocketInputStream;
  174. nsCOMPtr<nsIOutputStream> mSocketOutputStream;
  175. // Input stream machinery
  176. nsCOMPtr<nsIInputStreamPump> mInputStreamPump;
  177. nsCOMPtr<nsIScriptableInputStream> mInputStreamScriptable;
  178. nsCOMPtr<nsIBinaryInputStream> mInputStreamBinary;
  179. // Output stream machinery
  180. nsCOMPtr<nsIMultiplexInputStream> mMultiplexStream;
  181. nsCOMPtr<nsIAsyncStreamCopier> mMultiplexStreamCopier;
  182. // Is there an async copy operation in progress?
  183. bool mAsyncCopierActive;
  184. // True if the buffer is full and a "drain" event is expected by the client.
  185. bool mWaitingForDrain;
  186. // The id of the window that created this socket.
  187. uint64_t mInnerWindowID;
  188. // The current number of buffered bytes. Only used in content processes when IPC is enabled.
  189. uint64_t mBufferedAmount;
  190. // The number of times this socket has had `Suspend` called without a corresponding `Resume`.
  191. uint32_t mSuspendCount;
  192. // The current sequence number (ie. number of send operations) that have been processed.
  193. // This is used in the IPC scenario by the child process to filter out outdated notifications
  194. // about the amount of buffered data present in the parent process.
  195. uint32_t mTrackingNumber;
  196. // True if this socket has been upgraded to secure after the initial connection,
  197. // but the actual upgrade is waiting for an in-progress copy operation to complete.
  198. bool mWaitingForStartTLS;
  199. // The buffered data awaiting the TLS upgrade to finish.
  200. nsTArray<nsCOMPtr<nsIInputStream>> mPendingDataAfterStartTLS;
  201. // The data to be sent while AsyncCopier is still active.
  202. nsTArray<nsCOMPtr<nsIInputStream>> mPendingDataWhileCopierActive;
  203. bool mObserversActive;
  204. };
  205. } // namespace dom
  206. } // namespace mozilla
  207. #endif // mozilla_dom_TCPSocket_h