HttpTransactionChild.cpp (22597B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* vim:set ts=4 sw=4 sts=4 et cin: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 // HttpLog.h should generally be included first 8 #include "HttpLog.h" 9 10 #include "HttpTransactionChild.h" 11 12 #include "mozilla/ipc/IPCStreamUtils.h" 13 #include "mozilla/net/BackgroundDataBridgeParent.h" 14 #include "mozilla/net/ChannelEventQueue.h" 15 #include "mozilla/net/InputChannelThrottleQueueChild.h" 16 #include "mozilla/net/SocketProcessChild.h" 17 #include "mozilla/ScopeExit.h" 18 #include "mozilla/StaticPrefs_network.h" 19 #include "nsInputStreamPump.h" 20 #include "nsITransportSecurityInfo.h" 21 #include "nsHttpHandler.h" 22 #include "nsNetUtil.h" 23 #include "nsProxyInfo.h" 24 #include "nsProxyRelease.h" 25 #include "nsQueryObject.h" 26 #include "nsSerializationHelper.h" 27 #include "OpaqueResponseUtils.h" 28 #include "nsIRequestContext.h" 29 30 namespace mozilla::net { 31 32 NS_IMPL_ISUPPORTS(HttpTransactionChild, nsIRequestObserver, nsIStreamListener, 33 nsITransportEventSink, nsIThrottledInputChannel, 34 nsIThreadRetargetableStreamListener, nsIEarlyHintObserver); 35 36 //----------------------------------------------------------------------------- 37 // HttpTransactionChild <public> 38 //----------------------------------------------------------------------------- 39 40 HttpTransactionChild::HttpTransactionChild() { 41 LOG(("Creating HttpTransactionChild @%p\n", this)); 42 } 43 44 HttpTransactionChild::~HttpTransactionChild() { 45 LOG(("Destroying HttpTransactionChild @%p\n", this)); 46 } 47 48 static already_AddRefed<nsIRequestContext> CreateRequestContext( 49 uint64_t aRequestContextID) { 50 if (!aRequestContextID) { 51 return nullptr; 52 } 53 54 nsIRequestContextService* rcsvc = gHttpHandler->GetRequestContextService(); 55 if (!rcsvc) { 56 return nullptr; 57 } 58 59 nsCOMPtr<nsIRequestContext> requestContext; 60 rcsvc->GetRequestContext(aRequestContextID, getter_AddRefs(requestContext)); 61 62 return requestContext.forget(); 63 } 64 65 nsresult HttpTransactionChild::InitInternal( 66 uint32_t caps, const HttpConnectionInfoCloneArgs& infoArgs, 67 nsHttpRequestHead* requestHead, nsIInputStream* requestBody, 68 uint64_t requestContentLength, bool requestBodyHasHeaders, 69 uint64_t browserId, uint8_t httpTrafficCategory, uint64_t requestContextID, 70 ClassOfService classOfService, uint32_t initialRwin, 71 bool responseTimeoutEnabled, uint64_t channelId, 72 bool aHasTransactionObserver, 73 const nsILoadInfo::IPAddressSpace& aParentIPAddressSpace, 74 const LNAPerms& aLnaPermissionStatus) { 75 LOG(("HttpTransactionChild::InitInternal [this=%p caps=%x]\n", this, caps)); 76 77 RefPtr<nsHttpConnectionInfo> cinfo = 78 nsHttpConnectionInfo::DeserializeHttpConnectionInfoCloneArgs(infoArgs); 79 nsCOMPtr<nsIRequestContext> rc = CreateRequestContext(requestContextID); 80 81 std::function<void(TransactionObserverResult&&)> observer; 82 if (aHasTransactionObserver) { 83 nsMainThreadPtrHandle<HttpTransactionChild> handle( 84 new nsMainThreadPtrHolder<HttpTransactionChild>( 85 "HttpTransactionChildProxy", this, false)); 86 observer = [handle](TransactionObserverResult&& aResult) { 87 handle->mTransactionObserverResult.emplace(std::move(aResult)); 88 }; 89 } 90 91 nsresult rv = mTransaction->Init( 92 caps, cinfo, requestHead, requestBody, requestContentLength, 93 requestBodyHasHeaders, GetCurrentSerialEventTarget(), 94 nullptr, // TODO: security callback, fix in bug 1512479. 95 this, browserId, static_cast<HttpTrafficCategory>(httpTrafficCategory), 96 rc, classOfService, initialRwin, responseTimeoutEnabled, channelId, 97 std::move(observer), aParentIPAddressSpace, aLnaPermissionStatus); 98 if (NS_WARN_IF(NS_FAILED(rv))) { 99 mTransaction = nullptr; 100 return rv; 101 } 102 103 (void)mTransaction->AsyncRead(this, getter_AddRefs(mTransactionPump)); 104 return rv; 105 } 106 107 mozilla::ipc::IPCResult HttpTransactionChild::RecvCancelPump( 108 const nsresult& aStatus) { 109 LOG(("HttpTransactionChild::RecvCancelPump start [this=%p]\n", this)); 110 CancelInternal(aStatus); 111 return IPC_OK(); 112 } 113 114 void HttpTransactionChild::CancelInternal(nsresult aStatus) { 115 MOZ_ASSERT(NS_FAILED(aStatus)); 116 117 mCanceled = true; 118 mStatus = aStatus; 119 if (mTransactionPump) { 120 mTransactionPump->Cancel(mStatus); 121 } 122 } 123 124 mozilla::ipc::IPCResult HttpTransactionChild::RecvSuspendPump() { 125 LOG(("HttpTransactionChild::RecvSuspendPump start [this=%p]\n", this)); 126 127 if (mTransactionPump) { 128 mTransactionPump->Suspend(); 129 } 130 return IPC_OK(); 131 } 132 133 mozilla::ipc::IPCResult HttpTransactionChild::RecvResumePump() { 134 LOG(("HttpTransactionChild::RecvResumePump start [this=%p]\n", this)); 135 136 if (mTransactionPump) { 137 mTransactionPump->Resume(); 138 } 139 return IPC_OK(); 140 } 141 142 mozilla::ipc::IPCResult HttpTransactionChild::RecvInit( 143 const uint32_t& aCaps, const HttpConnectionInfoCloneArgs& aArgs, 144 const nsHttpRequestHead& aReqHeaders, const Maybe<IPCStream>& aRequestBody, 145 const uint64_t& aReqContentLength, const bool& aReqBodyIncludesHeaders, 146 const uint64_t& aTopLevelOuterContentWindowId, 147 const uint8_t& aHttpTrafficCategory, const uint64_t& aRequestContextID, 148 const ClassOfService& aClassOfService, const uint32_t& aInitialRwin, 149 const bool& aResponseTimeoutEnabled, const uint64_t& aChannelId, 150 const bool& aHasTransactionObserver, 151 const mozilla::Maybe<PInputChannelThrottleQueueChild*>& aThrottleQueue, 152 const bool& aIsDocumentLoad, 153 const nsILoadInfo::IPAddressSpace& aParentIPAddressSpace, 154 const LNAPerms& aLnaPermissionStatus, const TimeStamp& aRedirectStart, 155 const TimeStamp& aRedirectEnd) { 156 mRequestHead = aReqHeaders; 157 if (aRequestBody) { 158 mUploadStream = mozilla::ipc::DeserializeIPCStream(aRequestBody); 159 } 160 161 mTransaction = new nsHttpTransaction(); 162 mChannelId = aChannelId; 163 mIsDocumentLoad = aIsDocumentLoad; 164 mRedirectStart = aRedirectStart; 165 mRedirectEnd = aRedirectEnd; 166 167 if (aThrottleQueue.isSome()) { 168 mThrottleQueue = 169 static_cast<InputChannelThrottleQueueChild*>(aThrottleQueue.ref()); 170 } 171 172 nsresult rv = InitInternal( 173 aCaps, aArgs, &mRequestHead, mUploadStream, aReqContentLength, 174 aReqBodyIncludesHeaders, aTopLevelOuterContentWindowId, 175 aHttpTrafficCategory, aRequestContextID, aClassOfService, aInitialRwin, 176 aResponseTimeoutEnabled, aChannelId, aHasTransactionObserver, 177 aParentIPAddressSpace, aLnaPermissionStatus); 178 if (NS_FAILED(rv)) { 179 LOG(("HttpTransactionChild::RecvInit: [this=%p] InitInternal failed!\n", 180 this)); 181 mTransaction = nullptr; 182 SendOnInitFailed(rv); 183 } 184 return IPC_OK(); 185 } 186 187 mozilla::ipc::IPCResult HttpTransactionChild::RecvSetDNSWasRefreshed() { 188 LOG(("HttpTransactionChild::SetDNSWasRefreshed [this=%p]\n", this)); 189 if (mTransaction) { 190 mTransaction->SetDNSWasRefreshed(); 191 } 192 return IPC_OK(); 193 } 194 195 mozilla::ipc::IPCResult HttpTransactionChild::RecvDontReuseConnection() { 196 LOG(("HttpTransactionChild::RecvDontReuseConnection [this=%p]\n", this)); 197 if (mTransaction) { 198 mTransaction->DontReuseConnection(); 199 } 200 return IPC_OK(); 201 } 202 203 mozilla::ipc::IPCResult HttpTransactionChild::RecvSetH2WSConnRefTaken() { 204 LOG(("HttpTransactionChild::RecvSetH2WSConnRefTaken [this=%p]\n", this)); 205 if (mTransaction) { 206 mTransaction->SetH2WSConnRefTaken(); 207 } 208 return IPC_OK(); 209 } 210 211 void HttpTransactionChild::ActorDestroy(ActorDestroyReason aWhy) { 212 LOG(("HttpTransactionChild::ActorDestroy [this=%p]\n", this)); 213 mTransaction = nullptr; 214 mTransactionPump = nullptr; 215 } 216 217 nsHttpTransaction* HttpTransactionChild::GetHttpTransaction() { 218 return mTransaction.get(); 219 } 220 221 //----------------------------------------------------------------------------- 222 // HttpTransactionChild <nsIStreamListener> 223 //----------------------------------------------------------------------------- 224 225 NS_IMETHODIMP 226 HttpTransactionChild::OnDataAvailable(nsIRequest* aRequest, 227 nsIInputStream* aInputStream, 228 uint64_t aOffset, uint32_t aCount) { 229 LOG(("HttpTransactionChild::OnDataAvailable [this=%p, aOffset= %" PRIu64 230 " aCount=%" PRIu32 "]\n", 231 this, aOffset, aCount)); 232 233 // Don't bother sending IPC if already canceled. 234 if (mCanceled) { 235 return mStatus; 236 } 237 238 // TODO: send string data in chunks and handle errors. Bug 1600129. 239 nsCString data; 240 nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount); 241 if (NS_FAILED(rv)) { 242 return rv; 243 } 244 245 mLogicalOffset += aCount; 246 247 if (NS_IsMainThread()) { 248 if (!CanSend()) { 249 return NS_ERROR_FAILURE; 250 } 251 252 nsHttp::SendFunc<nsCString> sendFunc = 253 [self = UnsafePtr<HttpTransactionChild>(this)]( 254 const nsCString& aData, uint64_t aOffset, uint32_t aCount) { 255 return self->SendOnDataAvailable(aData, aOffset, aCount, 256 TimeStamp::Now()); 257 }; 258 259 LOG((" ODA to parent process")); 260 if (!nsHttp::SendDataInChunks(data, aOffset, aCount, sendFunc)) { 261 return NS_ERROR_FAILURE; 262 } 263 return NS_OK; 264 } 265 266 MOZ_ASSERT(mDataBridgeParent); 267 268 if (!mDataBridgeParent->CanSend()) { 269 return NS_ERROR_FAILURE; 270 } 271 272 nsHttp::SendFunc<nsDependentCSubstring> sendFunc = 273 [self = UnsafePtr<HttpTransactionChild>(this)]( 274 const nsDependentCSubstring& aData, uint64_t aOffset, 275 uint32_t aCount) { 276 return self->mDataBridgeParent->SendOnTransportAndData( 277 aOffset, aCount, aData, TimeStamp::Now()); 278 }; 279 280 LOG((" ODA to content process")); 281 if (!nsHttp::SendDataInChunks(data, aOffset, aCount, sendFunc)) { 282 MOZ_ASSERT(false, "Send ODA to content process failed"); 283 return NS_ERROR_FAILURE; 284 } 285 286 // We still need to send ODA to parent process, because the data needs to be 287 // saved in cache. Note that we set dataSentToChildProcess to true, so this 288 // ODA will not be sent to child process. 289 RefPtr<HttpTransactionChild> self = this; 290 rv = NS_DispatchToMainThread( 291 NS_NewRunnableFunction( 292 "HttpTransactionChild::OnDataAvailable", 293 [self, offset(aOffset), count(aCount), data(data)]() { 294 nsHttp::SendFunc<nsCString> sendFunc = 295 [self](const nsCString& aData, uint64_t aOffset, 296 uint32_t aCount) { 297 return self->SendOnDataAvailable(aData, aOffset, aCount, 298 TimeStamp::Now()); 299 }; 300 301 if (!nsHttp::SendDataInChunks(data, offset, count, sendFunc)) { 302 self->CancelInternal(NS_ERROR_FAILURE); 303 } 304 }), 305 NS_DISPATCH_NORMAL); 306 MOZ_ASSERT(NS_SUCCEEDED(rv)); 307 308 return NS_OK; 309 } 310 311 static TimingStructArgs ToTimingStructArgs(TimingStruct aTiming) { 312 TimingStructArgs args; 313 args.domainLookupStart() = aTiming.domainLookupStart; 314 args.domainLookupEnd() = aTiming.domainLookupEnd; 315 args.connectStart() = aTiming.connectStart; 316 args.tcpConnectEnd() = aTiming.tcpConnectEnd; 317 args.secureConnectionStart() = aTiming.secureConnectionStart; 318 args.connectEnd() = aTiming.connectEnd; 319 args.requestStart() = aTiming.requestStart; 320 args.responseStart() = aTiming.responseStart; 321 args.responseEnd() = aTiming.responseEnd; 322 args.transactionPending() = aTiming.transactionPending; 323 return args; 324 } 325 326 // The maximum number of bytes to consider when attempting to sniff. 327 // See https://mimesniff.spec.whatwg.org/#reading-the-resource-header. 328 static const uint32_t MAX_BYTES_SNIFFED = 1445; 329 330 static void GetDataForSniffer(void* aClosure, const uint8_t* aData, 331 uint32_t aCount) { 332 nsTArray<uint8_t>* outData = static_cast<nsTArray<uint8_t>*>(aClosure); 333 outData->AppendElements(aData, std::min(aCount, MAX_BYTES_SNIFFED)); 334 } 335 336 bool HttpTransactionChild::CanSendODAToContentProcessDirectly( 337 const Maybe<nsHttpResponseHead>& aHead) { 338 if (!StaticPrefs::network_send_ODA_to_content_directly()) { 339 return false; 340 } 341 342 // If this is a document load, the content process that receives ODA is not 343 // decided yet, so don't bother to do the rest check. 344 if (mIsDocumentLoad) { 345 return false; 346 } 347 348 if (!aHead) { 349 return false; 350 } 351 352 // We only need to deliver ODA when the response is succeed. 353 if (aHead->Status() != 200) { 354 return false; 355 } 356 357 // UnknownDecoder could be used in parent process, so we can't send ODA to 358 // content process. 359 if (!aHead->HasContentType()) { 360 return false; 361 } 362 363 return true; 364 } 365 366 NS_IMETHODIMP 367 HttpTransactionChild::OnStartRequest(nsIRequest* aRequest) { 368 LOG(("HttpTransactionChild::OnStartRequest start [this=%p] mTransaction=%p\n", 369 this, mTransaction.get())); 370 371 // Don't bother sending IPC to parent process if already canceled. 372 if (mCanceled) { 373 return mStatus; 374 } 375 376 if (!CanSend()) { 377 return NS_ERROR_FAILURE; 378 } 379 380 MOZ_ASSERT(mTransaction); 381 382 nsresult status; 383 aRequest->GetStatus(&status); 384 385 mProtocolVersion.Truncate(); 386 387 nsCOMPtr<nsITransportSecurityInfo> securityInfo(mTransaction->SecurityInfo()); 388 if (securityInfo) { 389 nsAutoCString protocol; 390 if (NS_SUCCEEDED(securityInfo->GetNegotiatedNPN(protocol)) && 391 !protocol.IsEmpty()) { 392 mProtocolVersion.Assign(protocol); 393 } 394 } 395 396 RefPtr<nsHttpConnectionInfo> connInfo; 397 UniquePtr<nsHttpResponseHead> head( 398 mTransaction->TakeResponseHeadAndConnInfo(getter_AddRefs(connInfo))); 399 Maybe<nsHttpResponseHead> optionalHead; 400 nsTArray<uint8_t> dataForSniffer; 401 if (head) { 402 if (mProtocolVersion.IsEmpty()) { 403 HttpVersion version = head->Version(); 404 mProtocolVersion.Assign(nsHttp::GetProtocolVersion(version)); 405 } 406 optionalHead = Some(*head); 407 408 if (GetOpaqueResponseBlockedReason(*head) == 409 OpaqueResponseBlockedReason::BLOCKED_SHOULD_SNIFF) { 410 RefPtr<nsInputStreamPump> pump = do_QueryObject(mTransactionPump); 411 pump->PeekStream(GetDataForSniffer, &dataForSniffer); 412 } 413 } 414 415 Maybe<nsCString> optionalAltSvcUsed; 416 nsCString altSvcUsed; 417 if (NS_SUCCEEDED(mTransaction->RequestHead()->GetHeader( 418 nsHttp::Alternate_Service_Used, altSvcUsed)) && 419 !altSvcUsed.IsEmpty()) { 420 optionalAltSvcUsed.emplace(altSvcUsed); 421 } 422 423 if (CanSendODAToContentProcessDirectly(optionalHead)) { 424 Maybe<RefPtr<BackgroundDataBridgeParent>> dataBridgeParent = 425 SocketProcessChild::GetSingleton()->GetAndRemoveDataBridge(mChannelId); 426 // Check if there is a registered BackgroundDataBridgeParent. 427 if (dataBridgeParent) { 428 mDataBridgeParent = std::move(dataBridgeParent.ref()); 429 430 nsCOMPtr<nsISerialEventTarget> backgroundThread = 431 mDataBridgeParent->GetBackgroundThread(); 432 nsCOMPtr<nsIThreadRetargetableRequest> retargetableTransactionPump; 433 retargetableTransactionPump = do_QueryObject(mTransactionPump); 434 // nsInputStreamPump should implement this interface. 435 MOZ_ASSERT(retargetableTransactionPump); 436 437 nsresult rv = 438 retargetableTransactionPump->RetargetDeliveryTo(backgroundThread); 439 LOG((" Retarget to background thread [this=%p rv=%08x]\n", this, 440 static_cast<uint32_t>(rv))); 441 if (NS_FAILED(rv)) { 442 mDataBridgeParent->Destroy(); 443 mDataBridgeParent = nullptr; 444 } 445 } 446 } 447 448 int32_t proxyConnectResponseCode = 449 mTransaction->GetProxyConnectResponseCode(); 450 451 nsIRequest::TRRMode mode = nsIRequest::TRR_DEFAULT_MODE; 452 TRRSkippedReason reason = nsITRRSkipReason::TRR_UNSET; 453 { 454 NetAddr selfAddr; 455 NetAddr peerAddr; 456 bool isTrr = false; 457 bool echConfigUsed = false; 458 if (mTransaction) { 459 mTransaction->GetNetworkAddresses(selfAddr, peerAddr, isTrr, mode, reason, 460 echConfigUsed); 461 } 462 } 463 464 HttpConnectionInfoCloneArgs infoArgs; 465 nsHttpConnectionInfo::SerializeHttpConnectionInfo(connInfo, infoArgs); 466 467 (void)SendOnStartRequest( 468 status, std::move(optionalHead), securityInfo, 469 mTransaction->ProxyConnectFailed(), 470 ToTimingStructArgs(mTransaction->Timings()), proxyConnectResponseCode, 471 dataForSniffer, optionalAltSvcUsed, !!mDataBridgeParent, 472 mTransaction->TakeRestartedState(), mTransaction->HTTPSSVCReceivedStage(), 473 mTransaction->GetSupportsHTTP3(), mode, reason, mTransaction->Caps(), 474 TimeStamp::Now(), infoArgs, mTransaction->GetTargetIPAddressSpace()); 475 return NS_OK; 476 } 477 478 ResourceTimingStructArgs HttpTransactionChild::GetTimingAttributes() { 479 // Note that not all fields in ResourceTimingStructArgs are filled, since 480 // we only need some in HttpChannelChild::OnStopRequest. 481 ResourceTimingStructArgs args; 482 args.domainLookupStart() = mTransaction->GetDomainLookupStart(); 483 args.domainLookupEnd() = mTransaction->GetDomainLookupEnd(); 484 args.connectStart() = mTransaction->GetConnectStart(); 485 args.tcpConnectEnd() = mTransaction->GetTcpConnectEnd(); 486 args.secureConnectionStart() = mTransaction->GetSecureConnectionStart(); 487 args.connectEnd() = mTransaction->GetConnectEnd(); 488 args.requestStart() = mTransaction->GetRequestStart(); 489 args.responseStart() = mTransaction->GetResponseStart(); 490 args.responseEnd() = mTransaction->GetResponseEnd(); 491 args.transferSize() = mTransaction->GetTransferSize(); 492 args.encodedBodySize() = mLogicalOffset; 493 args.decodedBodySize() = 0; 494 args.redirectStart() = mRedirectStart; 495 args.redirectEnd() = mRedirectEnd; 496 args.transferSize() = mTransaction->GetTransferSize(); 497 args.transactionPending() = mTransaction->GetPendingTime(); 498 return args; 499 } 500 501 NS_IMETHODIMP 502 HttpTransactionChild::OnStopRequest(nsIRequest* aRequest, nsresult aStatus) { 503 LOG(("HttpTransactionChild::OnStopRequest [this=%p]\n", this)); 504 505 mTransactionPump = nullptr; 506 507 auto onStopGuard = MakeScopeExit([&] { 508 LOG((" calling mDataBridgeParent->OnStopRequest by ScopeExit [this=%p]\n", 509 this)); 510 MOZ_ASSERT(NS_FAILED(mStatus), "This shoule be only called when failure"); 511 if (mDataBridgeParent) { 512 mDataBridgeParent->OnStopRequest(mStatus, ResourceTimingStructArgs(), 513 TimeStamp(), nsHttpHeaderArray(), 514 TimeStamp::Now()); 515 mDataBridgeParent = nullptr; 516 } 517 }); 518 519 // Don't bother sending IPC to parent process if already canceled. 520 if (mCanceled) { 521 return mStatus; 522 } 523 524 if (!CanSend()) { 525 mStatus = NS_ERROR_UNEXPECTED; 526 return mStatus; 527 } 528 529 MOZ_ASSERT(mTransaction); 530 531 UniquePtr<nsHttpHeaderArray> headerArray( 532 mTransaction->TakeResponseTrailers()); 533 Maybe<nsHttpHeaderArray> responseTrailers; 534 if (headerArray) { 535 responseTrailers.emplace(*headerArray); 536 } 537 538 onStopGuard.release(); 539 540 TimeStamp lastActTabOpt = nsHttp::GetLastActiveTabLoadOptimizationHit(); 541 542 if (mDataBridgeParent) { 543 mDataBridgeParent->OnStopRequest( 544 aStatus, GetTimingAttributes(), lastActTabOpt, 545 responseTrailers ? *responseTrailers : nsHttpHeaderArray(), 546 TimeStamp::Now()); 547 mDataBridgeParent = nullptr; 548 } 549 550 (void)SendOnStopRequest(aStatus, mTransaction->ResponseIsComplete(), 551 mTransaction->GetTransferSize(), 552 ToTimingStructArgs(mTransaction->Timings()), 553 responseTrailers, mTransactionObserverResult, 554 lastActTabOpt, TimeStamp::Now()); 555 556 return NS_OK; 557 } 558 559 //----------------------------------------------------------------------------- 560 // HttpTransactionChild <nsITransportEventSink> 561 //----------------------------------------------------------------------------- 562 563 NS_IMETHODIMP 564 HttpTransactionChild::OnTransportStatus(nsITransport* aTransport, 565 nsresult aStatus, int64_t aProgress, 566 int64_t aProgressMax) { 567 LOG(("HttpTransactionChild::OnTransportStatus [this=%p status=%" PRIx32 568 " progress=%" PRId64 "]\n", 569 this, static_cast<uint32_t>(aStatus), aProgress)); 570 571 if (!CanSend()) { 572 return NS_OK; 573 } 574 575 Maybe<NetworkAddressArg> arg; 576 if (aStatus == NS_NET_STATUS_CONNECTED_TO || 577 aStatus == NS_NET_STATUS_WAITING_FOR) { 578 NetAddr selfAddr; 579 NetAddr peerAddr; 580 bool isTrr = false; 581 bool echConfigUsed = false; 582 nsIRequest::TRRMode mode = nsIRequest::TRR_DEFAULT_MODE; 583 TRRSkippedReason reason = nsITRRSkipReason::TRR_UNSET; 584 if (mTransaction) { 585 mTransaction->GetNetworkAddresses(selfAddr, peerAddr, isTrr, mode, reason, 586 echConfigUsed); 587 } else { 588 nsCOMPtr<nsISocketTransport> socketTransport = 589 do_QueryInterface(aTransport); 590 if (socketTransport) { 591 socketTransport->GetSelfAddr(&selfAddr); 592 socketTransport->GetPeerAddr(&peerAddr); 593 socketTransport->ResolvedByTRR(&isTrr); 594 socketTransport->GetEffectiveTRRMode(&mode); 595 socketTransport->GetTrrSkipReason(&reason); 596 socketTransport->GetEchConfigUsed(&echConfigUsed); 597 } 598 } 599 arg.emplace(selfAddr, peerAddr, isTrr, mode, reason, echConfigUsed); 600 } 601 602 (void)SendOnTransportStatus(aStatus, aProgress, aProgressMax, arg); 603 return NS_OK; 604 } 605 606 //----------------------------------------------------------------------------- 607 // HttpBaseChannel::nsIThrottledInputChannel 608 //----------------------------------------------------------------------------- 609 610 NS_IMETHODIMP 611 HttpTransactionChild::SetThrottleQueue(nsIInputChannelThrottleQueue* aQueue) { 612 return NS_ERROR_NOT_IMPLEMENTED; 613 } 614 615 NS_IMETHODIMP 616 HttpTransactionChild::GetThrottleQueue(nsIInputChannelThrottleQueue** aQueue) { 617 nsCOMPtr<nsIInputChannelThrottleQueue> queue = 618 static_cast<nsIInputChannelThrottleQueue*>(mThrottleQueue.get()); 619 queue.forget(aQueue); 620 return NS_OK; 621 } 622 623 //----------------------------------------------------------------------------- 624 // EventSourceImpl::nsIThreadRetargetableStreamListener 625 //----------------------------------------------------------------------------- 626 NS_IMETHODIMP 627 HttpTransactionChild::CheckListenerChain() { 628 MOZ_ASSERT(NS_IsMainThread(), "Should be on the main thread!"); 629 return NS_OK; 630 } 631 632 NS_IMETHODIMP 633 HttpTransactionChild::OnDataFinished(nsresult aStatus) { return NS_OK; } 634 635 NS_IMETHODIMP 636 HttpTransactionChild::EarlyHint(const nsACString& aValue, 637 const nsACString& aReferrerPolicy, 638 const nsACString& aCSPHeader) { 639 LOG(("HttpTransactionChild::EarlyHint")); 640 if (CanSend()) { 641 (void)SendEarlyHint(aValue, aReferrerPolicy, aCSPHeader); 642 } 643 return NS_OK; 644 } 645 646 } // namespace mozilla::net