summaryrefslogtreecommitdiffstats
path: root/netwerk/protocol/http/Http3Session.h
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /netwerk/protocol/http/Http3Session.h
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'netwerk/protocol/http/Http3Session.h')
-rw-r--r--netwerk/protocol/http/Http3Session.h218
1 files changed, 218 insertions, 0 deletions
diff --git a/netwerk/protocol/http/Http3Session.h b/netwerk/protocol/http/Http3Session.h
new file mode 100644
index 0000000000..6fe980cea0
--- /dev/null
+++ b/netwerk/protocol/http/Http3Session.h
@@ -0,0 +1,218 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=4 sw=2 et cindent: */
+/* 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 Http3Session_H__
+#define Http3Session_H__
+
+#include "nsISupportsImpl.h"
+#include "nsITimer.h"
+#include "mozilla/net/NeqoHttp3Conn.h"
+#include "nsAHttpConnection.h"
+#include "nsRefPtrHashtable.h"
+#include "nsWeakReference.h"
+#include "HttpTrafficAnalyzer.h"
+#include "mozilla/UniquePtr.h"
+#include "nsDeque.h"
+
+namespace mozilla {
+namespace net {
+
+class HttpConnectionUDP;
+class Http3Stream;
+class QuicSocketControl;
+
+// IID for the Http3Session interface
+#define NS_HTTP3SESSION_IID \
+ { \
+ 0x8fc82aaf, 0xc4ef, 0x46ed, { \
+ 0x89, 0x41, 0x93, 0x95, 0x8f, 0xac, 0x4f, 0x21 \
+ } \
+ }
+
+class Http3Session final : public nsAHttpTransaction,
+ public nsAHttpConnection,
+ public nsAHttpSegmentReader,
+ public nsAHttpSegmentWriter {
+ public:
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_HTTP3SESSION_IID)
+
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSAHTTPTRANSACTION
+ NS_DECL_NSAHTTPCONNECTION(mConnection)
+ NS_DECL_NSAHTTPSEGMENTREADER
+ NS_DECL_NSAHTTPSEGMENTWRITER
+
+ Http3Session();
+ nsresult Init(const nsHttpConnectionInfo* aConnInfo,
+ nsISocketTransport* aSocketTransport,
+ HttpConnectionUDP* readerWriter);
+
+ bool IsConnected() const { return mState == CONNECTED; }
+ bool CanSandData() const {
+ return (mState == CONNECTED) || (mState == ZERORTT);
+ }
+ bool IsClosing() const { return (mState == CLOSING || mState == CLOSED); }
+ bool IsClosed() const { return mState == CLOSED; }
+
+ bool AddStream(nsAHttpTransaction* aHttpTransaction, int32_t aPriority,
+ nsIInterfaceRequestor* aCallbacks);
+
+ bool CanReuse();
+
+ // overload of nsAHttpTransaction
+ [[nodiscard]] nsresult ReadSegmentsAgain(nsAHttpSegmentReader*, uint32_t,
+ uint32_t*, bool*) final;
+ [[nodiscard]] nsresult WriteSegmentsAgain(nsAHttpSegmentWriter*, uint32_t,
+ uint32_t*, bool*) final;
+
+ // The folowing functions are used by Http3Stream:
+ nsresult TryActivating(const nsACString& aMethod, const nsACString& aScheme,
+ const nsACString& aHost, const nsACString& aPath,
+ const nsACString& aHeaders, uint64_t* aStreamId,
+ Http3Stream* aStream);
+ void CloseSendingSide(uint64_t aStreamId);
+ nsresult SendRequestBody(uint64_t aStreamId, const char* buf, uint32_t count,
+ uint32_t* countRead);
+ nsresult ReadResponseHeaders(uint64_t aStreamId,
+ nsTArray<uint8_t>& aResponseHeaders, bool* aFin);
+ nsresult ReadResponseData(uint64_t aStreamId, char* aBuf, uint32_t aCount,
+ uint32_t* aCountWritten, bool* aFin);
+
+ void CloseStream(Http3Stream* aStream, nsresult aResult);
+
+ void SetCleanShutdown(bool aCleanShutdown) {
+ mCleanShutdown = aCleanShutdown;
+ }
+
+ bool TestJoinConnection(const nsACString& hostname, int32_t port);
+ bool JoinConnection(const nsACString& hostname, int32_t port);
+
+ void TransactionHasDataToWrite(nsAHttpTransaction* caller) override;
+ void TransactionHasDataToRecv(nsAHttpTransaction* caller) override;
+
+ nsISocketTransport* SocketTransport() { return mSocketTransport; }
+
+ // This function will be called by QuicSocketControl when the certificate
+ // verification is done.
+ void Authenticated(int32_t aError);
+
+ nsresult ProcessOutputAndEvents();
+
+ const nsCString& GetAlpnToken() { return mAlpnToken; }
+
+ void ReportHttp3Connection();
+
+ private:
+ ~Http3Session();
+
+ void CloseInternal(bool aCallNeqoClose);
+ void Shutdown();
+
+ bool RealJoinConnection(const nsACString& hostname, int32_t port,
+ bool justKidding);
+
+ nsresult ProcessOutput();
+ nsresult ProcessInput(uint32_t* aCountRead);
+ nsresult ProcessEvents(uint32_t count);
+
+ nsresult ProcessTransactionRead(uint64_t stream_id, uint32_t count,
+ uint32_t* countWritten);
+ nsresult ProcessTransactionRead(Http3Stream* stream, uint32_t count,
+ uint32_t* countWritten);
+ nsresult ProcessSlowConsumers();
+ void ConnectSlowConsumer(Http3Stream* stream);
+
+ void SetupTimer(uint64_t aTimeout);
+
+ void ResetRecvd(uint64_t aStreamId, uint64_t aError);
+
+ void QueueStream(Http3Stream* stream);
+ void RemoveStreamFromQueues(Http3Stream*);
+ void ProcessPending();
+
+ void CallCertVerification();
+ void SetSecInfo();
+
+ void StreamReadyToWrite(Http3Stream* aStream);
+ void MaybeResumeSend();
+
+ void CloseConnectionTelemetry(CloseError& aError, bool aClosing);
+ void Finish0Rtt(bool aRestart);
+
+ RefPtr<NeqoHttp3Conn> mHttp3Connection;
+ RefPtr<nsAHttpConnection> mConnection;
+ nsRefPtrHashtable<nsUint64HashKey, Http3Stream> mStreamIdHash;
+ nsRefPtrHashtable<nsPtrHashKey<nsAHttpTransaction>, Http3Stream>
+ mStreamTransactionHash;
+
+ nsDeque<Http3Stream> mReadyForWrite;
+ nsTArray<RefPtr<Http3Stream>> mSlowConsumersReadyForRead;
+ nsDeque<Http3Stream> mQueuedStreams;
+
+ enum State { INITIALIZING, ZERORTT, CONNECTED, CLOSING, CLOSED } mState;
+
+ bool mAuthenticationStarted;
+ bool mCleanShutdown;
+ bool mGoawayReceived;
+ bool mShouldClose;
+ bool mIsClosedByNeqo;
+ bool mHttp3ConnectionReported = false;
+ // mError is neqo error (a protocol error) and that may mean that we will
+ // send some packets after that.
+ nsresult mError;
+ // This is a socket error, there is no poioint in sending anything on that
+ // socket.
+ nsresult mSocketError;
+ bool mBeforeConnectedError;
+ uint64_t mCurrentForegroundTabOuterContentWindowId;
+
+ // True if the mTimer is inited and waiting for firing.
+ bool mTimerActive;
+
+ nsTArray<uint8_t> mPacketToSend;
+
+ RefPtr<HttpConnectionUDP> mSegmentReaderWriter;
+
+ // The underlying socket transport object is needed to propogate some events
+ RefPtr<nsISocketTransport> mSocketTransport;
+
+ nsCOMPtr<nsITimer> mTimer;
+
+ nsDataHashtable<nsCStringHashKey, bool> mJoinConnectionCache;
+
+ RefPtr<QuicSocketControl> mSocketControl;
+ nsCString mAlpnToken;
+
+ uint64_t mTransactionCount = 0;
+
+ // The stream(s) that we are getting 0RTT data from.
+ nsTArray<WeakPtr<Http3Stream>> m0RTTStreams;
+ // The stream(s) that are not able to send 0RTT data. We need to
+ // remember them put them into mReadyForWrite queue when 0RTT finishes.
+ nsTArray<WeakPtr<Http3Stream>> mCannotDo0RTTStreams;
+
+ // The following variables are needed for telemetry.
+ TimeStamp mConnectionIdleStart;
+ TimeStamp mConnectionIdleEnd;
+ Maybe<uint64_t> mFirstStreamIdReuseIdleConnection;
+ TimeStamp mTimerShouldTrigger;
+ uint64_t mBlockedByStreamLimitCount = 0;
+ uint64_t mTransactionsBlockedByStreamLimitCount = 0;
+ uint64_t mTransactionsSenderBlockedByFlowControlCount = 0;
+
+ // NS_NET_STATUS_CONNECTED_TO event will be created by the Http3Session.
+ // We want to propagate it to the first transaction.
+ RefPtr<nsHttpTransaction> mFirstHttpTransaction;
+
+ RefPtr<nsHttpConnectionInfo> mConnInfo;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(Http3Session, NS_HTTP3SESSION_IID);
+
+} // namespace net
+} // namespace mozilla
+
+#endif // Http3Session_H__