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 nsHttpTransaction_h__ 7 #define nsHttpTransaction_h__ 8 9 #include "nsHttp.h" 10 #include "nsAHttpTransaction.h" 11 #include "HttpTransactionShell.h" 12 #include "nsAHttpConnection.h" 13 #include "EventTokenBucket.h" 14 #include "nsCOMPtr.h" 15 #include "nsIAsyncOutputStream.h" 16 #include "nsThreadUtils.h" 17 #include "nsIInterfaceRequestor.h" 18 #include "nsIAsyncOutputStream.h" 19 #include "nsITimer.h" 20 #include "nsIEarlyHintObserver.h" 21 #include "nsTHashMap.h" 22 #include "TimingStruct.h" 23 #include "Http2Push.h" 24 #include "mozilla/net/DNS.h" 25 #include "mozilla/net/NeckoChannelParams.h" 26 #include "ARefBase.h" 27 28 //----------------------------------------------------------------------------- 29 30 class nsIDNSHTTPSSVCRecord; 31 class nsIEventTarget; 32 class nsIInputStream; 33 class nsIOutputStream; 34 class nsIRequestContext; 35 class nsISVCBRecord; 36 37 namespace mozilla { 38 namespace net { 39 40 class HTTPSRecordResolver; 41 class nsHttpChunkedDecoder; 42 class nsHttpHeaderArray; 43 class nsHttpRequestHead; 44 class nsHttpResponseHead; 45 class NullHttpTransaction; 46 class SpdyConnectTransaction; 47 48 //----------------------------------------------------------------------------- 49 // nsHttpTransaction represents a single HTTP transaction. It is thread-safe, 50 // intended to run on the socket thread. 51 //----------------------------------------------------------------------------- 52 53 class nsHttpTransaction final : public nsAHttpTransaction, 54 public HttpTransactionShell, 55 public ATokenBucketEvent, 56 public nsIInputStreamCallback, 57 public nsIOutputStreamCallback, 58 public ARefBase, 59 public nsITimerCallback, 60 public nsINamed { 61 public: 62 NS_DECL_THREADSAFE_ISUPPORTS 63 NS_DECL_NSAHTTPTRANSACTION 64 NS_DECL_HTTPTRANSACTIONSHELL 65 NS_DECL_NSIINPUTSTREAMCALLBACK 66 NS_DECL_NSIOUTPUTSTREAMCALLBACK 67 NS_DECL_NSITIMERCALLBACK 68 NS_DECL_NSINAMED 69 70 nsHttpTransaction(); 71 72 void OnActivated() override; 73 74 // attributes ResponseHead()75 nsHttpResponseHead* ResponseHead() { 76 return mHaveAllHeaders ? mResponseHead : nullptr; 77 } 78 ConsumerTarget()79 nsIEventTarget* ConsumerTarget() { return mConsumerTarget; } 80 81 // Called to set/find out if the transaction generated a complete response. SetResponseIsComplete()82 void SetResponseIsComplete() { mResponseIsComplete = true; } 83 EnableKeepAlive()84 void EnableKeepAlive() { mCaps |= NS_HTTP_ALLOW_KEEPALIVE; } MakeSticky()85 void MakeSticky() { mCaps |= NS_HTTP_STICKY_CONNECTION; } MakeNonSticky()86 void MakeNonSticky() override { mCaps &= ~NS_HTTP_STICKY_CONNECTION; } 87 WaitingForHTTPSRR()88 bool WaitingForHTTPSRR() const { return mCaps & NS_HTTP_FORCE_WAIT_HTTP_RR; } MakeDontWaitHTTPSRR()89 void MakeDontWaitHTTPSRR() { mCaps &= ~NS_HTTP_FORCE_WAIT_HTTP_RR; } 90 91 // SetPriority() may only be used by the connection manager. SetPriority(int32_t priority)92 void SetPriority(int32_t priority) { mPriority = priority; } Priority()93 int32_t Priority() { return mPriority; } 94 95 void PrintDiagnostics(nsCString& log); 96 97 // Sets mPendingTime to the current time stamp or to a null time stamp (if now 98 // is false) 99 void SetPendingTime(bool now = true) { 100 if (!now && !mPendingTime.IsNull()) { 101 // Remember how long it took. We will use this vaule to record 102 // TRANSACTION_WAIT_TIME_HTTP2_SUP_HTTP3 telemetry, but we need to wait 103 // for the response headers. 104 mPendingDurationTime = TimeStamp::Now() - mPendingTime; 105 } 106 // Note that the transaction could be added in to a pending queue multiple 107 // times (when the transaction is restarted or moved to a new conn entry due 108 // to HTTPS RR), so we should only set the pending time once. 109 if (mPendingTime.IsNull()) { 110 mPendingTime = now ? TimeStamp::Now() : TimeStamp(); 111 } 112 } GetPendingTime()113 TimeStamp GetPendingTime() { return mPendingTime; } 114 115 // overload of nsAHttpTransaction::RequestContext() RequestContext()116 nsIRequestContext* RequestContext() override { return mRequestContext.get(); } 117 void DispatchedAsBlocking(); 118 void RemoveDispatchedAsBlocking(); 119 120 void DisableSpdy() override; DoNotRemoveAltSvc()121 void DoNotRemoveAltSvc() override { mDoNotRemoveAltSvc = true; } 122 void DisableHttp3(bool aAllowRetryHTTPSRR) override; 123 QueryHttpTransaction()124 nsHttpTransaction* QueryHttpTransaction() override { return this; } 125 GetPushedStream()126 already_AddRefed<Http2PushedStreamWrapper> GetPushedStream() { 127 return do_AddRef(mPushedStream); 128 } TakePushedStream()129 already_AddRefed<Http2PushedStreamWrapper> TakePushedStream() { 130 return mPushedStream.forget(); 131 } 132 InitialRwin()133 uint32_t InitialRwin() const { return mInitialRwin; }; ChannelPipeFull()134 bool ChannelPipeFull() { return mWaitingOnPipeOut; } 135 136 // Locked methods to get and set timing info 137 void BootstrapTimings(TimingStruct times); 138 void SetConnectStart(mozilla::TimeStamp timeStamp, bool onlyIfNull = false); 139 void SetConnectEnd(mozilla::TimeStamp timeStamp, bool onlyIfNull = false); 140 void SetRequestStart(mozilla::TimeStamp timeStamp, bool onlyIfNull = false); 141 void SetResponseStart(mozilla::TimeStamp timeStamp, bool onlyIfNull = false); 142 void SetResponseEnd(mozilla::TimeStamp timeStamp, bool onlyIfNull = false); 143 144 [[nodiscard]] bool Do0RTT() override; 145 [[nodiscard]] nsresult Finish0RTT(bool aRestart, 146 bool aAlpnChanged /* ignored */) override; 147 148 // After Finish0RTT early data may have failed but the caller did not request 149 // restart - this indicates that state for dev tools 150 void Refused0RTT(); 151 TopBrowsingContextId()152 uint64_t TopBrowsingContextId() override { return mTopBrowsingContextId; } 153 154 void SetHttpTrailers(nsCString& aTrailers); 155 156 bool IsWebsocketUpgrade(); 157 void SetH2WSTransaction(SpdyConnectTransaction*); 158 159 void OnProxyConnectComplete(int32_t aResponseCode) override; 160 void SetFlat407Headers(const nsACString& aHeaders); 161 162 // This is only called by Http2PushedStream::TryOnPush when a new pushed 163 // stream is available. The newly added stream will be taken by another 164 // transaction. 165 void OnPush(Http2PushedStreamWrapper* aStream); 166 167 void UpdateConnectionInfo(nsHttpConnectionInfo* aConnInfo); 168 169 void SetClassOfService(uint32_t cos); 170 171 virtual nsresult OnHTTPSRRAvailable( 172 nsIDNSHTTPSSVCRecord* aHTTPSSVCRecord, 173 nsISVCBRecord* aHighestPriorityRecord) override; 174 175 void GetHashKeyOfConnectionEntry(nsACString& aResult); 176 177 private: 178 friend class DeleteHttpTransaction; 179 virtual ~nsHttpTransaction(); 180 181 [[nodiscard]] nsresult Restart(); 182 char* LocateHttpStart(char* buf, uint32_t len, bool aAllowPartialMatch); 183 [[nodiscard]] nsresult ParseLine(nsACString& line); 184 [[nodiscard]] nsresult ParseLineSegment(char* seg, uint32_t len); 185 [[nodiscard]] nsresult ParseHead(char*, uint32_t count, uint32_t* countRead); 186 [[nodiscard]] nsresult HandleContentStart(); 187 [[nodiscard]] nsresult HandleContent(char*, uint32_t count, 188 uint32_t* contentRead, 189 uint32_t* contentRemaining); 190 [[nodiscard]] nsresult ProcessData(char*, uint32_t, uint32_t*); 191 void DeleteSelfOnConsumerThread(); 192 void ReleaseBlockingTransaction(); 193 194 [[nodiscard]] static nsresult ReadRequestSegment(nsIInputStream*, void*, 195 const char*, uint32_t, 196 uint32_t, uint32_t*); 197 [[nodiscard]] static nsresult WritePipeSegment(nsIOutputStream*, void*, char*, 198 uint32_t, uint32_t, uint32_t*); 199 TimingEnabled()200 bool TimingEnabled() const { return mCaps & NS_HTTP_TIMING_ENABLED; } 201 202 bool ResponseTimeoutEnabled() const final; 203 ReuseConnectionOnRestartOK(bool reuseOk)204 void ReuseConnectionOnRestartOK(bool reuseOk) override { 205 mReuseOnRestart = reuseOk; 206 } 207 208 // Called right after we parsed the response head. Checks for connection 209 // based authentication schemes in reponse headers for WWW and Proxy 210 // authentication. If such is found in any of them, NS_HTTP_STICKY_CONNECTION 211 // is set in mCaps. We need the sticky flag be set early to keep the 212 // connection from very start of the authentication process. 213 void CheckForStickyAuthScheme(); 214 void CheckForStickyAuthSchemeAt(nsHttpAtom const& header); 215 bool IsStickyAuthSchemeAt(nsACString const& auth); 216 217 // Called from WriteSegments. Checks for conditions whether to throttle 218 // reading the content. When this returns true, WriteSegments returns 219 // WOULD_BLOCK. 220 bool ShouldThrottle(); 221 222 void NotifyTransactionObserver(nsresult reason); 223 224 // When echConfig is enabled, this function put other available records 225 // in mRecordsForRetry. Returns true when mRecordsForRetry is not empty, 226 // otherwise returns false. 227 bool PrepareSVCBRecordsForRetry(const nsACString& aFailedDomainName, 228 bool& aAllRecordsHaveEchConfig); 229 // This function setups a new connection info for restarting this transaction. 230 void PrepareConnInfoForRetry(nsresult aReason); 231 // This function is used to select the next non http3 record and is only 232 // executed when the fast fallback timer is triggered. 233 already_AddRefed<nsHttpConnectionInfo> PrepareFastFallbackConnInfo( 234 bool aEchConfigUsed); 235 236 void MaybeReportFailedSVCDomain(nsresult aReason, 237 nsHttpConnectionInfo* aFailedConnInfo); 238 239 already_AddRefed<Http2PushedStreamWrapper> TakePushedStreamById( 240 uint32_t aStreamId); 241 242 // IMPORTANT: when adding new values, always add them to the end, otherwise 243 // it will mess up telemetry. 244 enum HTTPSSVC_CONNECTION_FAILED_REASON : uint32_t { 245 HTTPSSVC_CONNECTION_OK = 0, 246 HTTPSSVC_CONNECTION_UNKNOWN_HOST = 1, 247 HTTPSSVC_CONNECTION_UNREACHABLE = 2, 248 HTTPSSVC_CONNECTION_421_RECEIVED = 3, 249 HTTPSSVC_CONNECTION_SECURITY_ERROR = 4, 250 HTTPSSVC_CONNECTION_NO_USABLE_RECORD = 5, 251 HTTPSSVC_CONNECTION_ALL_RECORDS_EXCLUDED = 6, 252 HTTPSSVC_CONNECTION_OTHERS = 7, 253 }; 254 HTTPSSVC_CONNECTION_FAILED_REASON ErrorCodeToFailedReason( 255 nsresult aErrorCode); 256 257 void OnHttp3BackupTimer(); 258 void OnBackupConnectionReady(bool aTriggeredByHTTPSRR); 259 void OnFastFallbackTimer(); 260 void HandleFallback(nsHttpConnectionInfo* aFallbackConnInfo); 261 void MaybeCancelFallbackTimer(); 262 263 // IMPORTANT: when adding new values, always add them to the end, otherwise 264 // it will mess up telemetry. 265 enum TRANSACTION_RESTART_REASON : uint32_t { 266 TRANSACTION_RESTART_NONE = 0, // The transacion was not restarted. 267 TRANSACTION_RESTART_FORCED, // The transaction was forced to restart. 268 TRANSACTION_RESTART_NO_DATA_SENT, 269 TRANSACTION_RESTART_DOWNGRADE_WITH_EARLY_DATA, 270 TRANSACTION_RESTART_HTTPS_RR_NET_RESET, 271 TRANSACTION_RESTART_HTTPS_RR_CONNECTION_REFUSED, 272 TRANSACTION_RESTART_HTTPS_RR_UNKNOWN_HOST, 273 TRANSACTION_RESTART_HTTPS_RR_NET_TIMEOUT, 274 TRANSACTION_RESTART_HTTPS_RR_SEC_ERROR, 275 TRANSACTION_RESTART_HTTPS_RR_FAST_FALLBACK, 276 TRANSACTION_RESTART_HTTP3_FAST_FALLBACK, 277 TRANSACTION_RESTART_OTHERS, 278 TRANSACTION_RESTART_PROTOCOL_VERSION_ALERT, 279 }; 280 void SetRestartReason(TRANSACTION_RESTART_REASON aReason); 281 282 private: 283 class UpdateSecurityCallbacks : public Runnable { 284 public: UpdateSecurityCallbacks(nsHttpTransaction * aTrans,nsIInterfaceRequestor * aCallbacks)285 UpdateSecurityCallbacks(nsHttpTransaction* aTrans, 286 nsIInterfaceRequestor* aCallbacks) 287 : Runnable("net::nsHttpTransaction::UpdateSecurityCallbacks"), 288 mTrans(aTrans), 289 mCallbacks(aCallbacks) {} 290 Run()291 NS_IMETHOD Run() override { 292 if (mTrans->mConnection) { 293 mTrans->mConnection->SetSecurityCallbacks(mCallbacks); 294 } 295 return NS_OK; 296 } 297 298 private: 299 RefPtr<nsHttpTransaction> mTrans; 300 nsCOMPtr<nsIInterfaceRequestor> mCallbacks; 301 }; 302 303 Mutex mLock{"transaction lock"}; 304 305 nsCOMPtr<nsIInterfaceRequestor> mCallbacks; 306 nsCOMPtr<nsITransportEventSink> mTransportSink; 307 nsCOMPtr<nsIEventTarget> mConsumerTarget; 308 nsCOMPtr<nsISupports> mSecurityInfo; 309 nsCOMPtr<nsIAsyncInputStream> mPipeIn; 310 nsCOMPtr<nsIAsyncOutputStream> mPipeOut; 311 nsCOMPtr<nsIRequestContext> mRequestContext; 312 313 uint64_t mChannelId{0}; 314 315 nsCString mReqHeaderBuf; // flattened request headers 316 nsCOMPtr<nsIInputStream> mRequestStream; 317 int64_t mRequestSize{0}; 318 319 RefPtr<nsAHttpConnection> mConnection; 320 RefPtr<nsHttpConnectionInfo> mConnInfo; 321 // This is only set in UpdateConnectionInfo() when we have received a SVCB RR. 322 // When echConfig is not used and the connection is failed, this transaction 323 // will be restarted with this origin connection info directly. 324 // When echConfig is enabled, there are two cases below. 325 // 1. If all records have echConfig, we will retry other records except the 326 // failed one. In the case all other records with echConfig are failed and the 327 // pref network.dns.echconfig.fallback_to_origin_when_all_failed is true, this 328 // origin connection info will be used. 329 // 2. If only some records have echConfig and some not, we always fallback to 330 // this origin conn info. 331 RefPtr<nsHttpConnectionInfo> mOrigConnInfo; 332 nsHttpRequestHead* mRequestHead{nullptr}; // weak ref 333 nsHttpResponseHead* mResponseHead{nullptr}; // owning pointer 334 335 nsAHttpSegmentReader* mReader{nullptr}; 336 nsAHttpSegmentWriter* mWriter{nullptr}; 337 338 nsCString mLineBuf; // may contain a partial line 339 340 int64_t mContentLength{-1}; // equals -1 if unknown 341 int64_t mContentRead{0}; // count of consumed content bytes 342 Atomic<int64_t, ReleaseAcquire> mTransferSize{0}; // count of received bytes 343 344 // After a 304/204 or other "no-content" style response we will skip over 345 // up to MAX_INVALID_RESPONSE_BODY_SZ bytes when looking for the next 346 // response header to deal with servers that actually sent a response 347 // body where they should not have. This member tracks how many bytes have 348 // so far been skipped. 349 uint32_t mInvalidResponseBytesRead{0}; 350 351 RefPtr<Http2PushedStreamWrapper> mPushedStream; 352 uint32_t mInitialRwin{0}; 353 354 nsHttpChunkedDecoder* mChunkedDecoder{nullptr}; 355 356 TimingStruct mTimings; 357 358 nsresult mStatus{NS_OK}; 359 360 int16_t mPriority{0}; 361 362 // the number of times this transaction has been restarted 363 uint16_t mRestartCount{0}; 364 uint32_t mCaps{0}; 365 366 HttpVersion mHttpVersion{HttpVersion::UNKNOWN}; 367 uint16_t mHttpResponseCode{0}; 368 nsCString mFlat407Headers; 369 370 uint32_t mCurrentHttpResponseHeaderSize{0}; 371 372 int32_t const THROTTLE_NO_LIMIT = -1; 373 // This can have 3 possible values: 374 // * THROTTLE_NO_LIMIT - this means the transaction is not in any way limited 375 // to read the response, this is the default 376 // * a positive number - a limit is set because the transaction is obligated 377 // to throttle the response read, this is decresed with 378 // every piece of data the transaction receives 379 // * zero - when the transaction depletes the limit for reading, this makes it 380 // stop reading and return WOULD_BLOCK from WriteSegments; 381 // transaction then waits for a call of ResumeReading that resets 382 // this member back to THROTTLE_NO_LIMIT 383 int32_t mThrottlingReadAllowance{THROTTLE_NO_LIMIT}; 384 385 // mCapsToClear holds flags that should be cleared in mCaps, e.g. unset 386 // NS_HTTP_REFRESH_DNS when DNS refresh request has completed to avoid 387 // redundant requests on the network. The member itself is atomic, but 388 // access to it from the networking thread may happen either before or 389 // after the main thread modifies it. To deal with raciness, only unsetting 390 // bitfields should be allowed: 'lost races' will thus err on the 391 // conservative side, e.g. by going ahead with a 2nd DNS refresh. 392 Atomic<uint32_t> mCapsToClear{0}; 393 Atomic<bool, ReleaseAcquire> mResponseIsComplete{false}; 394 Atomic<bool, ReleaseAcquire> mClosed{false}; 395 Atomic<bool, Relaxed> mIsHttp3Used{false}; 396 397 // True iff WriteSegments was called while this transaction should be 398 // throttled (stop reading) Used to resume read on unblock of reading. Conn 399 // manager is responsible for calling back to resume reading. 400 bool mReadingStopped{false}; 401 402 // state flags, all logically boolean, but not packed together into a 403 // bitfield so as to avoid bitfield-induced races. See bug 560579. 404 bool mConnected{false}; 405 bool mActivated{false}; 406 bool mHaveStatusLine{false}; 407 bool mHaveAllHeaders{false}; 408 bool mTransactionDone{false}; 409 bool mDidContentStart{false}; 410 bool mNoContent{false}; // expecting an empty entity body 411 bool mSentData{false}; 412 bool mReceivedData{false}; 413 bool mStatusEventPending{false}; 414 bool mHasRequestBody{false}; 415 bool mProxyConnectFailed{false}; 416 bool mHttpResponseMatched{false}; 417 bool mPreserveStream{false}; 418 bool mDispatchedAsBlocking{false}; 419 bool mResponseTimeoutEnabled{true}; 420 bool mForceRestart{false}; 421 bool mReuseOnRestart{false}; 422 bool mContentDecoding{false}; 423 bool mContentDecodingCheck{false}; 424 bool mDeferredSendProgress{false}; 425 bool mWaitingOnPipeOut{false}; 426 bool mDoNotRemoveAltSvc{false}; 427 428 // mClosed := transaction has been explicitly closed 429 // mTransactionDone := transaction ran to completion or was interrupted 430 // mResponseComplete := transaction ran to completion 431 432 // For Restart-In-Progress Functionality 433 bool mReportedStart{false}; 434 bool mReportedResponseHeader{false}; 435 436 // protected by nsHttp::GetLock() 437 bool mResponseHeadTaken{false}; 438 UniquePtr<nsHttpHeaderArray> mForTakeResponseTrailers; 439 bool mResponseTrailersTaken{false}; 440 441 // Set when this transaction was restarted by call to Restart(). Used to tell 442 // the http channel to reset proxy authentication. 443 Atomic<bool> mRestarted{false}; 444 445 // The time when the transaction was submitted to the Connection Manager 446 TimeStamp mPendingTime; 447 TimeDuration mPendingDurationTime; 448 449 uint64_t mTopBrowsingContextId{0}; 450 451 // For Rate Pacing via an EventTokenBucket 452 public: 453 // called by the connection manager to run this transaction through the 454 // token bucket. If the token bucket admits the transaction immediately it 455 // returns true. The function is called repeatedly until it returns true. 456 bool TryToRunPacedRequest(); 457 458 // ATokenBucketEvent pure virtual implementation. Called by the token bucket 459 // when the transaction is ready to run. If this happens asynchrounously to 460 // token bucket submission the transaction just posts an event that causes 461 // the pending transaction queue to be rerun (and TryToRunPacedRequest() to 462 // be run again. 463 void OnTokenBucketAdmitted() override; // ATokenBucketEvent 464 465 // CancelPacing() can be used to tell the token bucket to remove this 466 // transaction from the list of pending transactions. This is used when a 467 // transaction is believed to be HTTP/1 (and thus subject to rate pacing) 468 // but later can be dispatched via spdy (not subject to rate pacing). 469 void CancelPacing(nsresult reason); 470 471 // Called by the connetion manager on the socket thread when reading for this 472 // previously throttled transaction has to be resumed. 473 void ResumeReading(); 474 475 // This examins classification of this transaction whether the Throttleable 476 // class has been set while Leader, Unblocked, DontThrottle has not. 477 bool EligibleForThrottling() const; 478 479 private: 480 bool mSubmittedRatePacing{false}; 481 bool mPassedRatePacing{false}; 482 bool mSynchronousRatePaceRequest{false}; 483 nsCOMPtr<nsICancelable> mTokenBucketCancel; 484 485 void CollectTelemetryForUploads(); 486 487 public: ClassOfService()488 uint32_t ClassOfService() { return mClassOfService; } 489 490 private: 491 Atomic<uint32_t, Relaxed> mClassOfService{0}; 492 493 public: 494 // setting TunnelProvider to non-null means the transaction should only 495 // be dispatched on a specific ConnectionInfo Hash Key (as opposed to a 496 // generic wild card one). That means in the specific case of carrying this 497 // transaction on an HTTP/2 tunnel it will only be dispatched onto an 498 // existing tunnel instead of triggering creation of a new one. 499 // The tunnel provider is used for ASpdySession::MaybeReTunnel() checks. 500 SetTunnelProvider(ASpdySession * provider)501 void SetTunnelProvider(ASpdySession* provider) { mTunnelProvider = provider; } TunnelProvider()502 ASpdySession* TunnelProvider() { return mTunnelProvider; } SecurityCallbacks()503 nsIInterfaceRequestor* SecurityCallbacks() { return mCallbacks; } 504 // Called when this transaction is inserted in the pending queue. 505 void OnPendingQueueInserted(const nsACString& aConnectionHashKey); 506 507 private: 508 RefPtr<ASpdySession> mTunnelProvider; 509 TransactionObserverFunc mTransactionObserver; 510 NetAddr mSelfAddr; 511 NetAddr mPeerAddr; 512 bool mResolvedByTRR{false}; 513 bool mEchConfigUsed = false; 514 515 bool m0RTTInProgress{false}; 516 bool mDoNotTryEarlyData{false}; 517 enum { 518 EARLY_NONE, 519 EARLY_SENT, 520 EARLY_ACCEPTED, 521 EARLY_425 522 } mEarlyDataDisposition{EARLY_NONE}; 523 524 // H2 websocket support 525 RefPtr<SpdyConnectTransaction> mH2WSTransaction; 526 527 HttpTrafficCategory mTrafficCategory{HttpTrafficCategory::eInvalid}; 528 bool mThroughCaptivePortal; 529 Atomic<int32_t> mProxyConnectResponseCode{0}; 530 531 OnPushCallback mOnPushCallback; 532 nsTHashMap<uint32_t, RefPtr<Http2PushedStreamWrapper>> mIDToStreamMap; 533 534 nsCOMPtr<nsICancelable> mDNSRequest; 535 Atomic<uint32_t, Relaxed> mHTTPSSVCReceivedStage{HTTPSSVC_NOT_USED}; 536 bool m421Received = false; 537 nsCOMPtr<nsIDNSHTTPSSVCRecord> mHTTPSSVCRecord; 538 nsTArray<RefPtr<nsISVCBRecord>> mRecordsForRetry; 539 bool mDontRetryWithDirectRoute = false; 540 bool mFastFallbackTriggered = false; 541 bool mAllRecordsInH3ExcludedListBefore = false; 542 bool mHttp3BackupTimerCreated = false; 543 nsCOMPtr<nsITimer> mFastFallbackTimer; 544 nsCOMPtr<nsITimer> mHttp3BackupTimer; 545 RefPtr<nsHttpConnectionInfo> mBackupConnInfo; 546 RefPtr<HTTPSRecordResolver> mResolver; 547 TRANSACTION_RESTART_REASON mRestartReason = TRANSACTION_RESTART_NONE; 548 549 nsTHashMap<nsUint32HashKey, uint32_t> mEchRetryCounterMap; 550 551 bool mSupportsHTTP3 = false; 552 553 bool mEarlyDataWasAvailable = false; 554 bool ShouldRestartOn0RttError(nsresult reason); 555 556 nsCOMPtr<nsIEarlyHintObserver> mEarlyHintObserver; 557 // This hash key is set when a transaction is inserted into the connection 558 // entry's pending queue. 559 // See nsHttpConnectionMgr::GetOrCreateConnectionEntry(). A transaction could 560 // be associated with the connection entry whose hash key is not the same as 561 // this transaction's. 562 nsCString mHashKeyOfConnectionEntry; 563 }; 564 565 } // namespace net 566 } // namespace mozilla 567 568 #endif // nsHttpTransaction_h__ 569