/* -*- Mode: C++; tab-width: 8; 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_net_Http3StreamTunnel_h #define mozilla_net_Http3StreamTunnel_h #include "Http3Stream.h" #include "nsHttpConnection.h" namespace mozilla::net { class Http3StreamTunnel; class Http3TransportLayer final : public nsISocketTransport, public nsIInputStreamCallback, public nsIOutputStreamCallback { public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSITRANSPORT NS_DECL_NSISOCKETTRANSPORT NS_DECL_NSIINPUTSTREAMCALLBACK NS_DECL_NSIOUTPUTSTREAMCALLBACK explicit Http3TransportLayer(Http3StreamTunnel* aStream); already_AddRefed GetStream(); nsresult Condition() const { return mCondition; } nsIAsyncInputStream* GetInput(); nsIAsyncOutputStream* GetOutput(); nsresult CallToReadData(); nsresult CallToWriteData(); void OnStreamClosed(nsresult aReason); private: class InputStreamTunnel : public nsIAsyncInputStream { public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIINPUTSTREAM NS_DECL_NSIASYNCINPUTSTREAM explicit InputStreamTunnel(Http3TransportLayer* aTransport); nsresult OnSocketReady(nsresult condition); bool HasCallback() { return !!mCallback; } private: friend class Http3TransportLayer; virtual ~InputStreamTunnel() = default; // The lifetime of InputStreamTunnel and OutputStreamTunnel are bound to // Http3TransportLayer, so using |mTransport| as a raw pointer should be // safe. Http3TransportLayer* MOZ_OWNING_REF mTransport; nsCOMPtr mCallback; nsresult mCondition{NS_OK}; }; class OutputStreamTunnel : public nsIAsyncOutputStream { public: NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIOUTPUTSTREAM NS_DECL_NSIASYNCOUTPUTSTREAM explicit OutputStreamTunnel(Http3TransportLayer* aTransport); nsresult OnSocketReady(nsresult condition); void MaybeSetRequestDone(nsIOutputStreamCallback* aCallback); private: friend class Http3TransportLayer; virtual ~OutputStreamTunnel() = default; Http3TransportLayer* MOZ_OWNING_REF mTransport; nsCOMPtr mCallback; nsresult mCondition{NS_OK}; }; virtual ~Http3TransportLayer(); RefPtr mStream; InputStreamTunnel mInput; OutputStreamTunnel mOutput; nsresult mCondition{NS_OK}; }; class Http3StreamTunnel final : public Http3Stream { public: explicit Http3StreamTunnel(nsAHttpTransaction* aTrans, Http3Session* aSession, uint64_t aCurrentBrowserId); Http3WebTransportSession* GetHttp3WebTransportSession() override { return nullptr; } Http3WebTransportStream* GetHttp3WebTransportStream() override { return nullptr; } Http3Stream* GetHttp3Stream() override { return this; } Http3ConnectUDPStream* GetHttp3ConnectUDPStream() override { return nullptr; } Http3StreamTunnel* GetHttp3StreamTunnel() override { return this; } nsresult TryActivating() override; void Close(nsresult aResult) override; already_AddRefed CreateHttpConnection( nsIInterfaceRequestor* aCallbacks, PRIntervalTime aRtt, bool aIsExtendedCONNECT); void CleanupStream(nsresult aReason); void SetRequestDone(); void HasDataToWrite(); void HasDataToRead(); [[nodiscard]] nsresult ReadSegments() override; [[nodiscard]] nsresult WriteSegments() override; private: virtual ~Http3StreamTunnel(); RefPtr mTransport; bool mClosed = false; }; } // namespace mozilla::net #endif // mozilla_net_Http3StreamTunnel_h