HttpConnectionBase.h (10816B)
1 /* -*- Mode: C++; tab-width: 4; 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 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef HttpConnectionBase_h__ 7 #define HttpConnectionBase_h__ 8 9 #include "nsHttpConnectionInfo.h" 10 #include "nsHttpResponseHead.h" 11 #include "nsAHttpTransaction.h" 12 #include "nsCOMPtr.h" 13 #include "nsProxyRelease.h" 14 #include "prinrval.h" 15 #include "mozilla/Mutex.h" 16 #include "ARefBase.h" 17 #include "TimingStruct.h" 18 #include "HttpTrafficAnalyzer.h" 19 20 #include "mozilla/net/DNS.h" 21 #include "mozilla/WeakPtr.h" 22 #include "nsIAsyncInputStream.h" 23 #include "nsIAsyncOutputStream.h" 24 #include "nsIInterfaceRequestor.h" 25 #include "nsITimer.h" 26 27 class nsISocketTransport; 28 class nsITLSSocketControl; 29 30 namespace mozilla { 31 namespace net { 32 33 class ConnectionEntry; 34 class nsHttpHandler; 35 class ASpdySession; 36 class WebTransportSessionBase; 37 38 enum class ConnectionState : uint32_t { 39 HALF_OPEN = 0, 40 INITED, 41 TLS_HANDSHAKING, 42 ZERORTT, 43 TRANSFERING, 44 CLOSED 45 }; 46 47 enum class ConnectionExperienceState : uint32_t { 48 Not_Experienced = 0, 49 First_Request_Sent = (1 << 0), 50 First_Response_Received = (1 << 1), 51 Experienced = (1 << 2), 52 }; 53 54 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(ConnectionExperienceState); 55 56 // 1dcc863e-db90-4652-a1fe-13fea0b54e46 57 #define HTTPCONNECTIONBASE_IID \ 58 {0x437e7d26, 0xa2fd, 0x49f2, {0xb3, 0x7c, 0x84, 0x23, 0xf0, 0x94, 0x72, 0x36}} 59 60 //----------------------------------------------------------------------------- 61 // nsHttpConnection - represents a connection to a HTTP server (or proxy) 62 // 63 // NOTE: this objects lives on the socket thread only. it should not be 64 // accessed from any other thread. 65 //----------------------------------------------------------------------------- 66 67 class HttpConnectionBase : public nsSupportsWeakReference { 68 public: 69 NS_INLINE_DECL_STATIC_IID(HTTPCONNECTIONBASE_IID) 70 71 HttpConnectionBase(); 72 73 // Activate causes the given transaction to be processed on this 74 // connection. It fails if there is already an existing transaction unless 75 // a multiplexing protocol such as SPDY is being used 76 [[nodiscard]] virtual nsresult Activate(nsAHttpTransaction*, uint32_t caps, 77 int32_t pri) = 0; 78 79 // Close the underlying socket transport. 80 virtual void Close(nsresult reason, bool aIsShutdown = false) = 0; 81 82 virtual bool CanReuse() = 0; // can this connection be reused? 83 virtual bool CanDirectlyActivate() = 0; 84 85 virtual void DontReuse() = 0; 86 87 virtual nsAHttpTransaction* Transaction() = 0; 88 nsHttpConnectionInfo* ConnectionInfo() { return mConnInfo; } 89 90 virtual void CloseTransaction(nsAHttpTransaction*, nsresult, 91 bool aIsShutdown = false) = 0; 92 93 [[nodiscard]] virtual nsresult OnHeadersAvailable(nsAHttpTransaction*, 94 nsHttpRequestHead*, 95 nsHttpResponseHead*, 96 bool* reset) = 0; 97 98 [[nodiscard]] virtual nsresult TakeTransport(nsISocketTransport**, 99 nsIAsyncInputStream**, 100 nsIAsyncOutputStream**) = 0; 101 102 virtual WebTransportSessionBase* GetWebTransportSession( 103 nsAHttpTransaction* aTransaction) { 104 return nullptr; 105 } 106 107 virtual bool UsingSpdy() { return false; } 108 virtual bool UsingHttp3() { return false; } 109 110 virtual void SetTransactionCaps(uint32_t aCaps) { mTransactionCaps = aCaps; } 111 112 virtual void PrintDiagnostics(nsCString& log) = 0; 113 114 // IsExperienced() returns true when the connection has started at least one 115 // non null HTTP transaction of any version. 116 bool IsExperienced() { return mExperienced; } 117 118 virtual bool TestJoinConnection(const nsACString& hostname, int32_t port) = 0; 119 virtual bool JoinConnection(const nsACString& hostname, int32_t port) = 0; 120 121 // Return true when the socket this connection is using has not been 122 // authenticated using a client certificate. Before SSL negotiation 123 // has finished this returns false. 124 virtual bool NoClientCertAuth() const { return true; } 125 126 // HTTP/2 websocket support 127 virtual ExtendedCONNECTSupport GetExtendedCONNECTSupport() { 128 return ExtendedCONNECTSupport::NO_SUPPORT; 129 } 130 131 void GetConnectionInfo(nsHttpConnectionInfo** ci) { 132 *ci = do_AddRef(mConnInfo).take(); 133 } 134 virtual void GetTLSSocketControl(nsITLSSocketControl** result) = 0; 135 136 [[nodiscard]] virtual nsresult ResumeSend() = 0; 137 [[nodiscard]] virtual nsresult ResumeRecv() = 0; 138 [[nodiscard]] virtual nsresult ForceSend() = 0; 139 [[nodiscard]] virtual nsresult ForceRecv() = 0; 140 virtual HttpVersion Version() = 0; 141 virtual bool LastTransactionExpectedNoContent() = 0; 142 virtual void SetLastTransactionExpectedNoContent(bool) = 0; 143 virtual int64_t BytesWritten() = 0; // includes TLS 144 void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks); 145 void SetTrafficCategory(HttpTrafficCategory); 146 147 void BootstrapTimings(TimingStruct times); 148 149 virtual bool IsPersistent() = 0; 150 virtual bool IsReused() = 0; 151 [[nodiscard]] virtual nsresult PushBack(const char* data, 152 uint32_t length) = 0; 153 PRIntervalTime Rtt() { return mRtt; } 154 virtual void SetEvent(nsresult aStatus) = 0; 155 156 virtual nsISocketTransport* Transport() { return nullptr; } 157 158 virtual nsresult GetSelfAddr(NetAddr* addr) = 0; 159 virtual nsresult GetPeerAddr(NetAddr* addr) = 0; 160 virtual bool ResolvedByTRR() = 0; 161 virtual nsIRequest::TRRMode EffectiveTRRMode() = 0; 162 virtual TRRSkippedReason TRRSkipReason() = 0; 163 virtual bool GetEchConfigUsed() = 0; 164 virtual PRIntervalTime LastWriteTime() = 0; 165 166 void ChangeConnectionState(ConnectionState aState); 167 ConnectionCloseReason CloseReason() const { return mCloseReason; } 168 void SetCloseReason(ConnectionCloseReason aReason) { 169 if (mCloseReason == ConnectionCloseReason::UNSET) { 170 mCloseReason = aReason; 171 } 172 } 173 174 void RecordConnectionCloseTelemetry(nsresult aReason); 175 void RecordConnectionAddressType(); 176 177 bool IsProxyConnectInProgress() { return mState == SETTING_UP_TUNNEL; } 178 179 virtual nsresult CreateTunnelStream(nsAHttpTransaction* httpTransaction, 180 HttpConnectionBase** aHttpConnection, 181 bool aIsExtendedCONNECT = false) = 0; 182 virtual void SetInTunnel() {}; 183 184 void SetOwner(ConnectionEntry* aEntry); 185 ConnectionEntry* OwnerEntry() const; 186 187 protected: 188 // The capabailities associated with the most recent transaction 189 uint32_t mTransactionCaps{0}; 190 191 RefPtr<nsHttpConnectionInfo> mConnInfo; 192 // Set when this connection is added to the active connections list, 193 // cleared when it is removed. 194 WeakPtr<ConnectionEntry> mOwnerEntry; 195 196 bool mExperienced{false}; 197 // Used to track whether this connection is serving the first request. 198 bool mHasFirstHttpTransaction{false}; 199 200 bool mBootstrappedTimingsSet{false}; 201 TimingStruct mBootstrappedTimings; 202 203 Mutex mCallbacksLock MOZ_UNANNOTATED{"nsHttpConnection::mCallbacksLock"}; 204 nsMainThreadPtrHandle<nsIInterfaceRequestor> mCallbacks; 205 206 nsTArray<HttpTrafficCategory> mTrafficCategory; 207 PRIntervalTime mRtt{0}; 208 nsresult mErrorBeforeConnect = NS_OK; 209 210 ConnectionState mConnectionState = ConnectionState::HALF_OPEN; 211 212 // Represent if the connection has served more than one request. 213 ConnectionExperienceState mExperienceState = 214 ConnectionExperienceState::Not_Experienced; 215 216 ConnectionCloseReason mCloseReason = ConnectionCloseReason::UNSET; 217 218 bool mAddressTypeReported{false}; 219 220 // Tunnel retated functions: 221 enum HttpConnectionState { 222 UNINITIALIZED, 223 SETTING_UP_TUNNEL, 224 REQUEST, 225 } mState{HttpConnectionState::UNINITIALIZED}; 226 void ChangeState(HttpConnectionState newState); 227 bool TunnelSetupInProgress() { return mState == SETTING_UP_TUNNEL; } 228 virtual void SetTunnelSetupDone() {} 229 virtual nsresult SetupProxyConnectStream() { return NS_OK; } 230 nsresult CheckTunnelIsNeeded(nsAHttpTransaction* aTransaction); 231 }; 232 233 #define NS_DECL_HTTPCONNECTIONBASE \ 234 [[nodiscard]] nsresult Activate(nsAHttpTransaction*, uint32_t, int32_t) \ 235 override; \ 236 [[nodiscard]] nsresult OnHeadersAvailable( \ 237 nsAHttpTransaction*, nsHttpRequestHead*, nsHttpResponseHead*, \ 238 bool* reset) override; \ 239 [[nodiscard]] nsresult TakeTransport( \ 240 nsISocketTransport**, nsIAsyncInputStream**, nsIAsyncOutputStream**) \ 241 override; \ 242 void Close(nsresult, bool aIsShutdown = false) override; \ 243 bool CanReuse() override; \ 244 bool CanDirectlyActivate() override; \ 245 void DontReuse() override; \ 246 void CloseTransaction(nsAHttpTransaction*, nsresult, \ 247 bool aIsShutdown = false) override; \ 248 void PrintDiagnostics(nsCString&) override; \ 249 bool TestJoinConnection(const nsACString&, int32_t) override; \ 250 bool JoinConnection(const nsACString&, int32_t) override; \ 251 void GetTLSSocketControl(nsITLSSocketControl** result) override; \ 252 [[nodiscard]] nsresult ResumeSend() override; \ 253 [[nodiscard]] nsresult ResumeRecv() override; \ 254 [[nodiscard]] nsresult ForceSend() override; \ 255 [[nodiscard]] nsresult ForceRecv() override; \ 256 HttpVersion Version() override; \ 257 bool LastTransactionExpectedNoContent() override; \ 258 void SetLastTransactionExpectedNoContent(bool val) override; \ 259 bool IsPersistent() override; \ 260 bool IsReused() override; \ 261 [[nodiscard]] nsresult PushBack(const char* data, uint32_t length) override; \ 262 void SetEvent(nsresult aStatus) override; \ 263 virtual nsAHttpTransaction* Transaction() override; \ 264 PRIntervalTime LastWriteTime() override; 265 266 } // namespace net 267 } // namespace mozilla 268 269 #endif // HttpConnectionBase_h__