/* 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 HttpConnectionUDP_h_
#define HttpConnectionUDP_h_
#include "HttpConnectionBase.h"
#include "nsHttpConnectionInfo.h"
#include "nsHttpResponseHead.h"
#include "nsAHttpTransaction.h"
#include "nsCOMPtr.h"
#include "nsProxyRelease.h"
#include "prinrval.h"
#include "mozilla/Mutex.h"
#include "ARefBase.h"
#include "TimingStruct.h"
#include "HttpTrafficAnalyzer.h"
#include "nsIAsyncInputStream.h"
#include "nsIAsyncOutputStream.h"
#include "nsISupportsPriority.h"
#include "nsIInterfaceRequestor.h"
#include "nsITimer.h"
#include "Http3Session.h"
class nsIDNSRecord;
class nsISocketTransport;
class nsITLSSocketControl;
namespace mozilla {
namespace net {
class nsHttpHandler;
class ASpdySession;
// 1dcc863e-db90-4652-a1fe-13fea0b54e46
#define HTTPCONNECTIONUDP_IID \
{
0xb97d2036,
0xb441,
0x48be, {
0xb3,
0x1e,
0x25,
0x3e,
0xe8,
0x32,
0xdd,
0x67}}
//-----------------------------------------------------------------------------
// HttpConnectionUDP - represents a connection to a HTTP3 server
//
// NOTE: this objects lives on the socket thread only. it should not be
// accessed from any other thread.
//-----------------------------------------------------------------------------
class HttpConnectionUDP final : public HttpConnectionBase,
public nsIUDPSocketSyncListener,
public nsIInterfaceRequestor {
private:
virtual ~HttpConnectionUDP();
public:
NS_INLINE_DECL_STATIC_IID(HTTPCONNECTIONUDP_IID)
NS_DECL_HTTPCONNECTIONBASE
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIUDPSOCKETSYNCLISTENER
NS_DECL_NSIINTERFACEREQUESTOR
HttpConnectionUDP();
[[nodiscard]] nsresult Init(nsHttpConnectionInfo* info,
nsIDNSRecord* dnsRecord, nsresult status,
nsIInterfaceRequestor* callbacks, uint32_t caps);
[[nodiscard]] nsresult InitWithSocket(nsHttpConnectionInfo* info,
nsIUDPSocket* aSocket,
NetAddr aPeerAddr,
nsIInterfaceRequestor* callbacks,
uint32_t caps);
friend class HttpConnectionUDPForceIO;
[[nodiscard]]
static nsresult ReadFromStream(nsIInputStream*,
void*,
const char*, uint32_t, uint32_t,
uint32_t*);
bool UsingHttp3() override {
return true; }
void OnQuicTimeoutExpired();
int64_t BytesWritten() override;
nsresult GetSelfAddr(NetAddr* addr) override;
nsresult GetPeerAddr(NetAddr* addr) override;
bool ResolvedByTRR() override;
nsIRequest::TRRMode EffectiveTRRMode() override;
TRRSkippedReason TRRSkipReason() override;
bool GetEchConfigUsed() override {
return false; }
void NotifyDataRead();
void NotifyDataWrite();
Http3Stats GetStats();
void ResetTransaction(nsHttpTransaction* aHttpTransaction);
void HandleTunnelResponse(nsHttpTransaction* aHttpTransaction,
const nsHttpResponseHead& responseHead,
bool* reset);
nsresult CreateTunnelStream(nsAHttpTransaction* httpTransaction,
HttpConnectionBase** aHttpConnection,
bool aIsExtendedCONNECT =
false) override;
void OnConnected();
void SetDontExclude() override;
private:
nsresult InitCommon(nsIUDPSocket* aSocket,
const NetAddr& aPeerAddr,
nsIInterfaceRequestor* callbacks, uint32_t caps,
bool isInTunnel);
[[nodiscard]] nsresult OnTransactionDone(nsresult reason);
nsresult RecvData();
nsresult SendData();
already_AddRefed<nsIInputStream> CreateProxyConnectStream(
nsAHttpTransaction* trans);
private:
RefPtr<nsHttpHandler> mHttpHandler;
// keep gHttpHandler alive
RefPtr<nsIAsyncInputStream> mInputOverflow;
bool mConnectedTransport =
false;
bool mDontReuse =
false;
bool mIsReused =
false;
bool mLastTransactionExpectedNoContent =
false;
bool mConnected =
false;
int32_t mPriority = nsISupportsPriority::PRIORITY_NORMAL;
private:
// For ForceSend()
static void ForceSendIO(nsITimer* aTimer,
void* aClosure);
[[nodiscard]] nsresult MaybeForceSendIO();
bool mForceSendPending =
false;
nsCOMPtr<nsITimer> mForceSendTimer;
PRIntervalTime mLastRequestBytesSentTime =
0;
nsCOMPtr<nsIUDPSocket> mSocket;
nsCOMPtr<nsINetAddr> mSelfAddr;
nsCOMPtr<nsINetAddr> mPeerAddr;
bool mResolvedByTRR =
false;
nsIRequest::TRRMode mEffectiveTRRMode = nsIRequest::TRR_DEFAULT_MODE;
TRRSkippedReason mTRRSkipReason = nsITRRSkipReason::TRR_UNSET;
private:
// Http3
RefPtr<Http3Session> mHttp3Session;
nsCString mAlpnToken;
bool mIsInTunnel =
false;
bool mProxyConnectSucceeded =
false;
nsTArray<RefPtr<nsHttpTransaction>> mQueuedHttpConnectTransaction;
nsTArray<RefPtr<nsHttpTransaction>> mQueuedConnectUdpTransaction;
bool mAlreadyWildcard =
false;
// Transactions whose LNA check has been deferred until after the QUIC
// handshake completes; drained in OnConnected().
nsTArray<RefPtr<nsHttpTransaction>> mDeferredLnaTransactions;
};
}
// namespace net
}
// namespace mozilla
#endif // HttpConnectionUDP_h_