123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
- /* 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 mozilla_dom_TCPSocket_h
- #define mozilla_dom_TCPSocket_h
- #include "mozilla/dom/TCPSocketBinding.h"
- #include "mozilla/DOMEventTargetHelper.h"
- #include "nsITransport.h"
- #include "nsIStreamListener.h"
- #include "nsIAsyncInputStream.h"
- #include "nsISupportsImpl.h"
- #include "nsIObserver.h"
- #include "nsWeakReference.h"
- #include "nsITCPSocketCallback.h"
- #include "js/RootingAPI.h"
- class nsISocketTransport;
- class nsIInputStreamPump;
- class nsIScriptableInputStream;
- class nsIBinaryInputStream;
- class nsIMultiplexInputStream;
- class nsIAsyncStreamCopier;
- class nsIInputStream;
- class nsINetworkInfo;
- namespace mozilla {
- class ErrorResult;
- namespace dom {
- class DOMError;
- struct ServerSocketOptions;
- class TCPServerSocket;
- class TCPSocketChild;
- class TCPSocketParent;
- // This interface is only used for legacy navigator.mozTCPSocket API compatibility.
- class LegacyMozTCPSocket : public nsISupports
- {
- public:
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_CLASS(LegacyMozTCPSocket)
- explicit LegacyMozTCPSocket(nsPIDOMWindowInner* aWindow);
- already_AddRefed<TCPServerSocket>
- Listen(uint16_t aPort,
- const ServerSocketOptions& aOptions,
- uint16_t aBacklog,
- ErrorResult& aRv);
- already_AddRefed<TCPSocket>
- Open(const nsAString& aHost,
- uint16_t aPort,
- const SocketOptions& aOptions,
- ErrorResult& aRv);
- bool WrapObject(JSContext* aCx,
- JS::Handle<JSObject*> aGivenProto,
- JS::MutableHandle<JSObject*> aReflector);
- private:
- virtual ~LegacyMozTCPSocket();
- nsCOMPtr<nsIGlobalObject> mGlobal;
- };
- class TCPSocket final : public DOMEventTargetHelper
- , public nsIStreamListener
- , public nsITransportEventSink
- , public nsIInputStreamCallback
- , public nsIObserver
- , public nsSupportsWeakReference
- , public nsITCPSocketCallback
- {
- public:
- TCPSocket(nsIGlobalObject* aGlobal, const nsAString& aHost, uint16_t aPort,
- bool aSsl, bool aUseArrayBuffers);
- NS_DECL_ISUPPORTS_INHERITED
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TCPSocket, DOMEventTargetHelper)
- NS_DECL_NSIREQUESTOBSERVER
- NS_DECL_NSISTREAMLISTENER
- NS_DECL_NSITRANSPORTEVENTSINK
- NS_DECL_NSIINPUTSTREAMCALLBACK
- NS_DECL_NSIOBSERVER
- NS_DECL_NSITCPSOCKETCALLBACK
- virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
- static bool ShouldTCPSocketExist(JSContext* aCx, JSObject* aGlobal);
- void GetHost(nsAString& aHost);
- uint32_t Port();
- bool Ssl();
- uint64_t BufferedAmount();
- void Suspend();
- void Resume(ErrorResult& aRv);
- void Close();
- void CloseImmediately();
- bool Send(JSContext* aCx, const nsACString& aData, ErrorResult& aRv);
- bool Send(JSContext* aCx,
- const ArrayBuffer& aData,
- uint32_t aByteOffset,
- const Optional<uint32_t>& aByteLength,
- ErrorResult& aRv);
- TCPReadyState ReadyState();
- TCPSocketBinaryType BinaryType();
- void UpgradeToSecure(ErrorResult& aRv);
- static already_AddRefed<TCPSocket>
- Constructor(const GlobalObject& aGlobal,
- const nsAString& aHost,
- uint16_t aPort,
- const SocketOptions& aOptions,
- ErrorResult& aRv);
- // Perform a send operation that's asssociated with a sequence number. Used in
- // IPC scenarios to track the number of bytes buffered at any given time.
- void SendWithTrackingNumber(const nsACString& aData,
- const uint32_t& aTrackingNumber,
- ErrorResult& aRv);
- void SendWithTrackingNumber(JSContext* aCx,
- const ArrayBuffer& aData,
- uint32_t aByteOffset,
- const Optional<uint32_t>& aByteLength,
- const uint32_t& aTrackingNumber,
- ErrorResult& aRv);
- // Create a TCPSocket object from an existing low-level socket connection.
- // Used by the TCPServerSocket implementation when a new connection is accepted.
- static already_AddRefed<TCPSocket>
- CreateAcceptedSocket(nsIGlobalObject* aGlobal, nsISocketTransport* aTransport, bool aUseArrayBuffers);
- // Create a TCPSocket object from an existing child-side IPC actor.
- // Used by the TCPServerSocketChild implementation when a new connection is accepted.
- static already_AddRefed<TCPSocket>
- CreateAcceptedSocket(nsIGlobalObject* aGlobal, TCPSocketChild* aSocketBridge, bool aUseArrayBuffers);
- // Initialize this socket's associated app and browser information.
- void SetAppIdAndBrowser(uint32_t aAppId, bool aInBrowser);
- // Initialize this socket's associated IPC actor in the parent process.
- void SetSocketBridgeParent(TCPSocketParent* aBridgeParent);
- static bool SocketEnabled();
- IMPL_EVENT_HANDLER(open);
- IMPL_EVENT_HANDLER(drain);
- IMPL_EVENT_HANDLER(data);
- IMPL_EVENT_HANDLER(error);
- IMPL_EVENT_HANDLER(close);
- nsresult Init();
- // Inform this socket that a buffered send() has completed sending.
- void NotifyCopyComplete(nsresult aStatus);
- // Initialize this socket from a low-level connection that hasn't connected yet
- // (called from RecvOpenBind() in TCPSocketParent).
- nsresult InitWithUnconnectedTransport(nsISocketTransport* aTransport);
- private:
- ~TCPSocket();
- // Initialize this socket with an existing IPC actor.
- void InitWithSocketChild(TCPSocketChild* aBridge);
- // Initialize this socket from an existing low-level connection.
- nsresult InitWithTransport(nsISocketTransport* aTransport);
- // Initialize the input/output streams for this socket object.
- nsresult CreateStream();
- // Initialize the asynchronous read operation from this socket's input stream.
- nsresult CreateInputStreamPump();
- // Send the contents of the provided input stream, which is assumed to be the given length
- // for reporting and buffering purposes.
- bool Send(nsIInputStream* aStream, uint32_t aByteLength);
- // Begin an asynchronous copy operation if one is not already in progress.
- nsresult EnsureCopying();
- // Enable TLS on this socket.
- void ActivateTLS();
- // Dispatch an error event if necessary, then dispatch a "close" event.
- nsresult MaybeReportErrorAndCloseIfOpen(nsresult status);
- // Helper for FireDataStringEvent/FireDataArrayEvent.
- nsresult FireDataEvent(JSContext* aCx, const nsAString& aType,
- JS::Handle<JS::Value> aData);
- // Helper for Close/CloseImmediately
- void CloseHelper(bool waitForUnsentData);
- TCPReadyState mReadyState;
- // Whether to use strings or array buffers for the "data" event.
- bool mUseArrayBuffers;
- nsString mHost;
- uint16_t mPort;
- // Whether this socket is using a secure transport.
- bool mSsl;
- // The associated IPC actor in a child process.
- RefPtr<TCPSocketChild> mSocketBridgeChild;
- // The associated IPC actor in a parent process.
- RefPtr<TCPSocketParent> mSocketBridgeParent;
- // Raw socket streams
- nsCOMPtr<nsISocketTransport> mTransport;
- nsCOMPtr<nsIInputStream> mSocketInputStream;
- nsCOMPtr<nsIOutputStream> mSocketOutputStream;
- // Input stream machinery
- nsCOMPtr<nsIInputStreamPump> mInputStreamPump;
- nsCOMPtr<nsIScriptableInputStream> mInputStreamScriptable;
- nsCOMPtr<nsIBinaryInputStream> mInputStreamBinary;
- // Output stream machinery
- nsCOMPtr<nsIMultiplexInputStream> mMultiplexStream;
- nsCOMPtr<nsIAsyncStreamCopier> mMultiplexStreamCopier;
- // Is there an async copy operation in progress?
- bool mAsyncCopierActive;
- // True if the buffer is full and a "drain" event is expected by the client.
- bool mWaitingForDrain;
- // The id of the window that created this socket.
- uint64_t mInnerWindowID;
- // The current number of buffered bytes. Only used in content processes when IPC is enabled.
- uint64_t mBufferedAmount;
- // The number of times this socket has had `Suspend` called without a corresponding `Resume`.
- uint32_t mSuspendCount;
- // The current sequence number (ie. number of send operations) that have been processed.
- // This is used in the IPC scenario by the child process to filter out outdated notifications
- // about the amount of buffered data present in the parent process.
- uint32_t mTrackingNumber;
- // True if this socket has been upgraded to secure after the initial connection,
- // but the actual upgrade is waiting for an in-progress copy operation to complete.
- bool mWaitingForStartTLS;
- // The buffered data awaiting the TLS upgrade to finish.
- nsTArray<nsCOMPtr<nsIInputStream>> mPendingDataAfterStartTLS;
- // The data to be sent while AsyncCopier is still active.
- nsTArray<nsCOMPtr<nsIInputStream>> mPendingDataWhileCopierActive;
- bool mObserversActive;
- };
- } // namespace dom
- } // namespace mozilla
- #endif // mozilla_dom_TCPSocket_h
|