1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=8 et tw=80 : */
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
8 #include "TRRServiceChannel.h"
11 #include "AltServiceChild.h"
12 #include "mozilla/ScopeExit.h"
13 #include "mozilla/StaticPrefs_network.h"
14 #include "mozilla/Unused.h"
15 #include "nsDNSPrefetch.h"
17 #include "nsHttpTransaction.h"
18 #include "nsICancelable.h"
19 #include "nsICachingChannel.h"
20 #include "nsIHttpPushListener.h"
21 #include "nsIProtocolProxyService2.h"
22 #include "nsIOService.h"
23 #include "nsISeekableStream.h"
24 #include "nsURLHelper.h"
25 #include "ProxyConfigLookup.h"
26 #include "TRRLoadInfo.h"
27 #include "ReferrerInfo.h"
29 #include "TRRService.h"
31 namespace mozilla::net
{
33 NS_IMPL_ADDREF(TRRServiceChannel
)
35 // Because nsSupportsWeakReference isn't thread-safe we must ensure that
36 // TRRServiceChannel is destroyed on the target thread. Any Release() called
37 // on a different thread is dispatched to the target thread.
38 bool TRRServiceChannel::DispatchRelease() {
39 if (mCurrentEventTarget
->IsOnCurrentThread()) {
43 mCurrentEventTarget
->Dispatch(
44 NewNonOwningRunnableMethod("net::TRRServiceChannel::Release", this,
45 &TRRServiceChannel::Release
),
51 NS_IMETHODIMP_(MozExternalRefCountType
)
52 TRRServiceChannel::Release() {
53 nsrefcnt count
= mRefCnt
- 1;
54 if (DispatchRelease()) {
55 // Redispatched to the target thread.
59 MOZ_ASSERT(0 != mRefCnt
, "dup release");
61 NS_LOG_RELEASE(this, count
, "TRRServiceChannel");
72 NS_INTERFACE_MAP_BEGIN(TRRServiceChannel
)
73 NS_INTERFACE_MAP_ENTRY(nsIRequest
)
74 NS_INTERFACE_MAP_ENTRY(nsIChannel
)
75 NS_INTERFACE_MAP_ENTRY(nsIHttpChannel
)
76 NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal
)
77 NS_INTERFACE_MAP_ENTRY(nsISupportsPriority
)
78 NS_INTERFACE_MAP_ENTRY(nsIClassOfService
)
79 NS_INTERFACE_MAP_ENTRY(nsIProxiedChannel
)
80 NS_INTERFACE_MAP_ENTRY(nsIProtocolProxyCallback
)
81 NS_INTERFACE_MAP_ENTRY(nsIStreamListener
)
82 NS_INTERFACE_MAP_ENTRY(nsIRequestObserver
)
83 NS_INTERFACE_MAP_ENTRY(nsITransportEventSink
)
84 NS_INTERFACE_MAP_ENTRY(nsIDNSListener
)
85 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference
)
86 NS_INTERFACE_MAP_ENTRY(nsIUploadChannel2
)
87 NS_INTERFACE_MAP_ENTRY_CONCRETE(TRRServiceChannel
)
88 NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel
)
90 TRRServiceChannel::TRRServiceChannel()
91 : HttpAsyncAborter
<TRRServiceChannel
>(this),
92 mProxyRequest(nullptr, "TRRServiceChannel::mProxyRequest"),
93 mCurrentEventTarget(GetCurrentSerialEventTarget()) {
94 LOG(("TRRServiceChannel ctor [this=%p]\n", this));
97 TRRServiceChannel::~TRRServiceChannel() {
98 LOG(("TRRServiceChannel dtor [this=%p]\n", this));
101 NS_IMETHODIMP
TRRServiceChannel::SetCanceledReason(const nsACString
& aReason
) {
102 return SetCanceledReasonImpl(aReason
);
105 NS_IMETHODIMP
TRRServiceChannel::GetCanceledReason(nsACString
& aReason
) {
106 return GetCanceledReasonImpl(aReason
);
110 TRRServiceChannel::CancelWithReason(nsresult aStatus
,
111 const nsACString
& aReason
) {
112 return CancelWithReasonImpl(aStatus
, aReason
);
116 TRRServiceChannel::Cancel(nsresult status
) {
117 LOG(("TRRServiceChannel::Cancel [this=%p status=%" PRIx32
"]\n", this,
118 static_cast<uint32_t>(status
)));
120 LOG((" ignoring; already canceled\n"));
127 nsCOMPtr
<nsICancelable
> proxyRequest
;
129 auto req
= mProxyRequest
.Lock();
130 proxyRequest
.swap(*req
);
134 NS_DispatchToMainThread(
135 NS_NewRunnableFunction(
136 "CancelProxyRequest",
137 [proxyRequest
, status
]() { proxyRequest
->Cancel(status
); }),
141 CancelNetworkRequest(status
);
145 void TRRServiceChannel::CancelNetworkRequest(nsresult aStatus
) {
147 nsresult rv
= gHttpHandler
->CancelTransaction(mTransaction
, aStatus
);
149 LOG(("failed to cancel the transaction\n"));
152 if (mTransactionPump
) mTransactionPump
->Cancel(aStatus
);
156 TRRServiceChannel::Suspend() {
157 LOG(("TRRServiceChannel::SuspendInternal [this=%p]\n", this));
159 if (mTransactionPump
) {
160 return mTransactionPump
->Suspend();
167 TRRServiceChannel::Resume() {
168 LOG(("TRRServiceChannel::Resume [this=%p]\n", this));
170 if (mTransactionPump
) {
171 return mTransactionPump
->Resume();
178 TRRServiceChannel::GetSecurityInfo(nsITransportSecurityInfo
** securityInfo
) {
179 NS_ENSURE_ARG_POINTER(securityInfo
);
180 *securityInfo
= do_AddRef(mSecurityInfo
).take();
185 TRRServiceChannel::AsyncOpen(nsIStreamListener
* aListener
) {
186 NS_ENSURE_ARG_POINTER(aListener
);
187 NS_ENSURE_TRUE(!LoadIsPending(), NS_ERROR_IN_PROGRESS
);
188 NS_ENSURE_TRUE(!LoadWasOpened(), NS_ERROR_ALREADY_OPENED
);
195 // HttpBaseChannel::MaybeWaitForUploadStreamNormalization can only be used on
196 // main thread, so we can only return an error here.
198 MOZ_ASSERT(!LoadPendingUploadStreamNormalization());
200 if (LoadPendingUploadStreamNormalization()) {
201 return NS_ERROR_FAILURE
;
204 if (!gHttpHandler
->Active()) {
205 LOG((" after HTTP shutdown..."));
207 return NS_ERROR_NOT_AVAILABLE
;
210 nsresult rv
= NS_CheckPortSafety(mURI
);
216 StoreIsPending(true);
217 StoreWasOpened(true);
219 mListener
= aListener
;
221 mAsyncOpenTime
= TimeStamp::Now();
223 rv
= MaybeResolveProxyAndBeginConnect();
225 Unused
<< AsyncAbort(rv
);
231 nsresult
TRRServiceChannel::MaybeResolveProxyAndBeginConnect() {
234 // The common case for HTTP channels is to begin proxy resolution and return
235 // at this point. The only time we know mProxyInfo already is if we're
236 // proxying a non-http protocol like ftp. We don't need to discover proxy
237 // settings if we are never going to make a network connection.
238 // If mConnectionInfo is already supplied, we don't need to do proxy
240 if (!mProxyInfo
&& !mConnectionInfo
&&
241 !(mLoadFlags
& (nsICachingChannel::LOAD_ONLY_FROM_CACHE
|
242 nsICachingChannel::LOAD_NO_NETWORK_IO
)) &&
243 NS_SUCCEEDED(ResolveProxy())) {
249 Unused
<< AsyncAbort(rv
);
255 nsresult
TRRServiceChannel::ResolveProxy() {
256 LOG(("TRRServiceChannel::ResolveProxy [this=%p]\n", this));
257 if (!NS_IsMainThread()) {
258 return NS_DispatchToMainThread(
259 NewRunnableMethod("TRRServiceChannel::ResolveProxy", this,
260 &TRRServiceChannel::ResolveProxy
),
264 MOZ_ASSERT(NS_IsMainThread());
266 // TODO: bug 1625171. Consider moving proxy resolution to socket process.
267 RefPtr
<TRRServiceChannel
> self
= this;
268 nsCOMPtr
<nsICancelable
> proxyRequest
;
269 nsresult rv
= ProxyConfigLookup::Create(
270 [self
](nsIProxyInfo
* aProxyInfo
, nsresult aStatus
) {
271 self
->OnProxyAvailable(nullptr, nullptr, aProxyInfo
, aStatus
);
273 mURI
, mProxyResolveFlags
, getter_AddRefs(proxyRequest
));
276 if (!mCurrentEventTarget
->IsOnCurrentThread()) {
277 return mCurrentEventTarget
->Dispatch(
278 NewRunnableMethod
<nsresult
>("TRRServiceChannel::AsyncAbort", this,
279 &TRRServiceChannel::AsyncAbort
, rv
),
285 auto req
= mProxyRequest
.Lock();
286 // We only set mProxyRequest if the channel hasn't already been cancelled
287 // on another thread.
289 *req
= proxyRequest
.forget();
293 // If the channel has been cancelled, we go ahead and cancel the proxy
294 // request right here.
296 proxyRequest
->Cancel(mStatus
);
303 TRRServiceChannel::OnProxyAvailable(nsICancelable
* request
, nsIChannel
* channel
,
304 nsIProxyInfo
* pi
, nsresult status
) {
305 LOG(("TRRServiceChannel::OnProxyAvailable [this=%p pi=%p status=%" PRIx32
306 " mStatus=%" PRIx32
"]\n",
307 this, pi
, static_cast<uint32_t>(status
),
308 static_cast<uint32_t>(static_cast<nsresult
>(mStatus
))));
310 if (!mCurrentEventTarget
->IsOnCurrentThread()) {
311 RefPtr
<TRRServiceChannel
> self
= this;
312 nsCOMPtr
<nsIProxyInfo
> info
= pi
;
313 return mCurrentEventTarget
->Dispatch(
314 NS_NewRunnableFunction("TRRServiceChannel::OnProxyAvailable",
315 [self
, info
, status
]() {
316 self
->OnProxyAvailable(nullptr, nullptr, info
,
322 MOZ_ASSERT(mCurrentEventTarget
->IsOnCurrentThread());
325 auto proxyRequest
= mProxyRequest
.Lock();
326 *proxyRequest
= nullptr;
331 // If status is a failure code, then it means that we failed to resolve
332 // proxy info. That is a non-fatal error assuming it wasn't because the
333 // request was canceled. We just failover to DIRECT when proxy resolution
334 // fails (failure can mean that the PAC URL could not be loaded).
336 if (NS_SUCCEEDED(status
)) mProxyInfo
= pi
;
338 if (!gHttpHandler
->Active()) {
340 ("nsHttpChannel::OnProxyAvailable [this=%p] "
341 "Handler no longer active.\n",
343 rv
= NS_ERROR_NOT_AVAILABLE
;
349 Unused
<< AsyncAbort(rv
);
354 nsresult
TRRServiceChannel::BeginConnect() {
355 LOG(("TRRServiceChannel::BeginConnect [this=%p]\n", this));
358 // Construct connection info object
360 nsAutoCString scheme
;
362 bool isHttps
= mURI
->SchemeIs("https");
364 rv
= mURI
->GetScheme(scheme
);
365 if (NS_SUCCEEDED(rv
)) rv
= mURI
->GetAsciiHost(host
);
366 if (NS_SUCCEEDED(rv
)) rv
= mURI
->GetPort(&port
);
367 if (NS_SUCCEEDED(rv
)) rv
= mURI
->GetAsciiSpec(mSpec
);
372 // Just a warning here because some nsIURIs do not implement this method.
373 Unused
<< NS_WARN_IF(NS_FAILED(mURI
->GetUsername(mUsername
)));
375 // Reject the URL if it doesn't specify a host
376 if (host
.IsEmpty()) {
377 rv
= NS_ERROR_MALFORMED_URI
;
380 LOG(("host=%s port=%d\n", host
.get(), port
));
381 LOG(("uri=%s\n", mSpec
.get()));
383 nsCOMPtr
<nsProxyInfo
> proxyInfo
;
384 if (mProxyInfo
) proxyInfo
= do_QueryInterface(mProxyInfo
);
386 mRequestHead
.SetHTTPS(isHttps
);
387 mRequestHead
.SetOrigin(scheme
, host
, port
);
389 RefPtr
<nsHttpConnectionInfo
> connInfo
= new nsHttpConnectionInfo(
390 host
, port
, ""_ns
, mUsername
, proxyInfo
, OriginAttributes(), isHttps
);
391 // TODO: Bug 1622778 for using AltService in socket process.
392 StoreAllowAltSvc(XRE_IsParentProcess() && LoadAllowAltSvc());
393 bool http2Allowed
= !gHttpHandler
->IsHttp2Excluded(connInfo
);
394 bool http3Allowed
= Http3Allowed();
396 mCaps
|= NS_HTTP_DISALLOW_HTTP3
;
399 RefPtr
<AltSvcMapping
> mapping
;
400 if (!mConnectionInfo
&& LoadAllowAltSvc() && // per channel
401 (http2Allowed
|| http3Allowed
) && !(mLoadFlags
& LOAD_FRESH_CONNECTION
) &&
402 AltSvcMapping::AcceptableProxy(proxyInfo
) &&
403 (scheme
.EqualsLiteral("http") || scheme
.EqualsLiteral("https")) &&
404 (mapping
= gHttpHandler
->GetAltServiceMapping(
405 scheme
, host
, port
, mPrivateBrowsing
, OriginAttributes(),
406 http2Allowed
, http3Allowed
))) {
407 LOG(("TRRServiceChannel %p Alt Service Mapping Found %s://%s:%d [%s]\n",
408 this, scheme
.get(), mapping
->AlternateHost().get(),
409 mapping
->AlternatePort(), mapping
->HashKey().get()));
411 if (!(mLoadFlags
& LOAD_ANONYMOUS
) && !mPrivateBrowsing
) {
412 nsAutoCString
altUsedLine(mapping
->AlternateHost());
414 mapping
->AlternatePort() ==
415 (isHttps
? NS_HTTPS_DEFAULT_PORT
: NS_HTTP_DEFAULT_PORT
);
417 altUsedLine
.AppendLiteral(":");
418 altUsedLine
.AppendInt(mapping
->AlternatePort());
420 rv
= mRequestHead
.SetHeader(nsHttp::Alternate_Service_Used
, altUsedLine
);
421 MOZ_ASSERT(NS_SUCCEEDED(rv
));
424 LOG(("TRRServiceChannel %p Using connection info from altsvc mapping",
426 mapping
->GetConnectionInfo(getter_AddRefs(mConnectionInfo
), proxyInfo
,
428 Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC
, true);
429 Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC_OE
, !isHttps
);
430 } else if (mConnectionInfo
) {
431 LOG(("TRRServiceChannel %p Using channel supplied connection info", this));
433 LOG(("TRRServiceChannel %p Using default connection info", this));
435 mConnectionInfo
= connInfo
;
436 Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC
, false);
439 // Need to re-ask the handler, since mConnectionInfo may not be the connInfo
441 if (gHttpHandler
->IsHttp2Excluded(mConnectionInfo
)) {
443 mCaps
|= NS_HTTP_DISALLOW_SPDY
;
444 mConnectionInfo
->SetNoSpdy(true);
447 // If TimingEnabled flag is not set after OnModifyRequest() then
448 // clear the already recorded AsyncOpen value for consistency.
449 if (!LoadTimingEnabled()) mAsyncOpenTime
= TimeStamp();
451 // if this somehow fails we can go on without it
452 Unused
<< gHttpHandler
->AddConnectionHeader(&mRequestHead
, mCaps
);
454 // Adjust mCaps according to our request headers:
455 // - If "Connection: close" is set as a request header, then do not bother
456 // trying to establish a keep-alive connection.
457 if (mRequestHead
.HasHeaderValue(nsHttp::Connection
, "close")) {
458 mCaps
&= ~(NS_HTTP_ALLOW_KEEPALIVE
);
461 if (gHttpHandler
->CriticalRequestPrioritization()) {
462 if (mClassOfService
.Flags() & nsIClassOfService::Leader
) {
463 mCaps
|= NS_HTTP_LOAD_AS_BLOCKING
;
465 if (mClassOfService
.Flags() & nsIClassOfService::Unblocked
) {
466 mCaps
|= NS_HTTP_LOAD_UNBLOCKED
;
468 if (mClassOfService
.Flags() & nsIClassOfService::UrgentStart
&&
469 gHttpHandler
->IsUrgentStartEnabled()) {
470 mCaps
|= NS_HTTP_URGENT_START
;
471 SetPriority(nsISupportsPriority::PRIORITY_HIGHEST
);
479 MaybeStartDNSPrefetch();
481 rv
= ContinueOnBeforeConnect();
489 nsresult
TRRServiceChannel::ContinueOnBeforeConnect() {
490 LOG(("TRRServiceChannel::ContinueOnBeforeConnect [this=%p]\n", this));
492 // ensure that we are using a valid hostname
493 if (!net_IsValidHostName(nsDependentCString(mConnectionInfo
->Origin()))) {
494 return NS_ERROR_UNKNOWN_HOST
;
497 if (LoadIsTRRServiceChannel()) {
498 mCaps
|= NS_HTTP_LARGE_KEEPALIVE
;
499 mCaps
|= NS_HTTP_DISALLOW_HTTPS_RR
;
502 mCaps
|= NS_HTTP_TRR_FLAGS_FROM_MODE(nsIRequest::GetTRRMode());
504 // Finalize ConnectionInfo flags before SpeculativeConnect
505 mConnectionInfo
->SetAnonymous((mLoadFlags
& LOAD_ANONYMOUS
) != 0);
506 mConnectionInfo
->SetPrivate(mPrivateBrowsing
);
507 mConnectionInfo
->SetNoSpdy(mCaps
& NS_HTTP_DISALLOW_SPDY
);
508 mConnectionInfo
->SetBeConservative((mCaps
& NS_HTTP_BE_CONSERVATIVE
) ||
509 LoadBeConservative());
510 mConnectionInfo
->SetTlsFlags(mTlsFlags
);
511 mConnectionInfo
->SetIsTrrServiceChannel(LoadIsTRRServiceChannel());
512 mConnectionInfo
->SetTRRMode(nsIRequest::GetTRRMode());
513 mConnectionInfo
->SetIPv4Disabled(mCaps
& NS_HTTP_DISABLE_IPV4
);
514 mConnectionInfo
->SetIPv6Disabled(mCaps
& NS_HTTP_DISABLE_IPV6
);
516 if (mLoadFlags
& LOAD_FRESH_CONNECTION
) {
517 Telemetry::ScalarAdd(
518 Telemetry::ScalarID::NETWORKING_TRR_CONNECTION_CYCLE_COUNT
,
519 NS_ConvertUTF8toUTF16(TRRService::ProviderKey()), 1);
521 gHttpHandler
->ConnMgr()->DoSingleConnectionCleanup(mConnectionInfo
);
523 ("TRRServiceChannel::BeginConnect "
524 "DoSingleConnectionCleanup succeeded=%d %08x [this=%p]",
525 NS_SUCCEEDED(rv
), static_cast<uint32_t>(rv
), this));
531 nsresult
TRRServiceChannel::Connect() {
532 LOG(("TRRServiceChannel::Connect [this=%p]\n", this));
534 nsresult rv
= SetupTransaction();
539 rv
= gHttpHandler
->InitiateTransaction(mTransaction
, mPriority
);
544 return mTransaction
->AsyncRead(this, getter_AddRefs(mTransactionPump
));
547 nsresult
TRRServiceChannel::SetupTransaction() {
549 "TRRServiceChannel::SetupTransaction "
550 "[this=%p, cos=%lu, inc=%d, prio=%d]\n",
551 this, mClassOfService
.Flags(), mClassOfService
.Incremental(), mPriority
));
553 NS_ENSURE_TRUE(!mTransaction
, NS_ERROR_ALREADY_INITIALIZED
);
557 if (!LoadAllowSpdy()) {
558 mCaps
|= NS_HTTP_DISALLOW_SPDY
;
560 // Check a proxy info from mConnectionInfo. TRR channel may use a proxy that
561 // is set in mConnectionInfo but acutally the channel do not have mProxyInfo
562 // set. This can happend when network.trr.async_connInfo is true.
563 bool useNonDirectProxy
= mConnectionInfo
->ProxyInfo()
564 ? !mConnectionInfo
->ProxyInfo()->IsDirect()
566 if (!Http3Allowed() || useNonDirectProxy
) {
567 mCaps
|= NS_HTTP_DISALLOW_HTTP3
;
569 if (LoadBeConservative()) {
570 mCaps
|= NS_HTTP_BE_CONSERVATIVE
;
573 // Use the URI path if not proxying (transparent proxying such as proxy
574 // CONNECT does not count here). Also figure out what HTTP version to use.
575 nsAutoCString buf
, path
;
576 nsCString
* requestURI
;
578 // This is the normal e2e H1 path syntax "/index.html"
579 rv
= mURI
->GetPathQueryRef(path
);
584 // path may contain UTF-8 characters, so ensure that they're escaped.
585 if (NS_EscapeURL(path
.get(), path
.Length(), esc_OnlyNonASCII
| esc_Spaces
,
592 // trim off the #ref portion if any...
593 int32_t ref1
= requestURI
->FindChar('#');
594 if (ref1
!= kNotFound
) {
595 requestURI
->SetLength(ref1
);
598 if (mConnectionInfo
->UsingConnect() || !mConnectionInfo
->UsingHttpProxy()) {
599 mRequestHead
.SetVersion(gHttpHandler
->HttpVersion());
601 mRequestHead
.SetPath(*requestURI
);
603 // RequestURI should be the absolute uri H1 proxy syntax
604 // "http://foo/index.html" so we will overwrite the relative version in
606 rv
= mURI
->GetUserPass(buf
);
607 if (NS_FAILED(rv
)) return rv
;
608 if (!buf
.IsEmpty() && ((strncmp(mSpec
.get(), "http:", 5) == 0) ||
609 strncmp(mSpec
.get(), "https:", 6) == 0)) {
610 nsCOMPtr
<nsIURI
> tempURI
= nsIOService::CreateExposableURI(mURI
);
611 rv
= tempURI
->GetAsciiSpec(path
);
612 if (NS_FAILED(rv
)) return rv
;
618 // trim off the #ref portion if any...
619 int32_t ref2
= requestURI
->FindChar('#');
620 if (ref2
!= kNotFound
) {
621 requestURI
->SetLength(ref2
);
624 mRequestHead
.SetVersion(gHttpHandler
->ProxyHttpVersion());
627 mRequestHead
.SetRequestURI(*requestURI
);
629 // Force setting no-cache header for TRRServiceChannel.
630 // We need to send 'Pragma:no-cache' to inhibit proxy caching even if
631 // no proxy is configured since we might be talking with a transparent
632 // proxy, i.e. one that operates at the network level. See bug #14772.
633 rv
= mRequestHead
.SetHeaderOnce(nsHttp::Pragma
, "no-cache", true);
634 MOZ_ASSERT(NS_SUCCEEDED(rv
));
635 // If we're configured to speak HTTP/1.1 then also send 'Cache-control:
637 if (mRequestHead
.Version() >= HttpVersion::v1_1
) {
638 rv
= mRequestHead
.SetHeaderOnce(nsHttp::Cache_Control
, "no-cache", true);
639 MOZ_ASSERT(NS_SUCCEEDED(rv
));
642 // create wrapper for this channel's notification callbacks
643 nsCOMPtr
<nsIInterfaceRequestor
> callbacks
;
644 NS_NewNotificationCallbacksAggregation(mCallbacks
, mLoadGroup
,
645 getter_AddRefs(callbacks
));
647 // create the transaction object
648 mTransaction
= new nsHttpTransaction();
649 LOG1(("TRRServiceChannel %p created nsHttpTransaction %p\n", this,
650 mTransaction
.get()));
652 // See bug #466080. Transfer LOAD_ANONYMOUS flag to socket-layer.
653 if (mLoadFlags
& LOAD_ANONYMOUS
) mCaps
|= NS_HTTP_LOAD_ANONYMOUS
;
655 if (LoadTimingEnabled()) mCaps
|= NS_HTTP_TIMING_ENABLED
;
657 nsCOMPtr
<nsIHttpPushListener
> pushListener
;
658 NS_QueryNotificationCallbacks(mCallbacks
, mLoadGroup
,
659 NS_GET_IID(nsIHttpPushListener
),
660 getter_AddRefs(pushListener
));
661 HttpTransactionShell::OnPushCallback pushCallback
= nullptr;
663 mCaps
|= NS_HTTP_ONPUSH_LISTENER
;
664 nsWeakPtr
weakPtrThis(
665 do_GetWeakReference(static_cast<nsIHttpChannel
*>(this)));
666 pushCallback
= [weakPtrThis
](uint32_t aPushedStreamId
,
667 const nsACString
& aUrl
,
668 const nsACString
& aRequestString
,
669 HttpTransactionShell
* aTransaction
) {
670 if (nsCOMPtr
<nsIHttpChannel
> channel
= do_QueryReferent(weakPtrThis
)) {
671 return static_cast<TRRServiceChannel
*>(channel
.get())
672 ->OnPush(aPushedStreamId
, aUrl
, aRequestString
, aTransaction
);
674 return NS_ERROR_NOT_AVAILABLE
;
678 EnsureRequestContext();
680 rv
= mTransaction
->Init(
681 mCaps
, mConnectionInfo
, &mRequestHead
, mUploadStream
, mReqContentLength
,
682 LoadUploadStreamHasHeaders(), mCurrentEventTarget
, callbacks
, this,
683 mBrowserId
, HttpTrafficCategory::eInvalid
, mRequestContext
,
684 mClassOfService
, mInitialRwin
, LoadResponseTimeoutEnabled(), mChannelId
,
685 nullptr, std::move(pushCallback
), mTransWithPushedStream
,
688 mTransWithPushedStream
= nullptr;
691 mTransaction
= nullptr;
698 void TRRServiceChannel::SetPushedStreamTransactionAndId(
699 HttpTransactionShell
* aTransWithPushedStream
, uint32_t aPushedStreamId
) {
700 MOZ_ASSERT(!mTransWithPushedStream
);
701 LOG(("TRRServiceChannel::SetPushedStreamTransaction [this=%p] trans=%p", this,
702 aTransWithPushedStream
));
704 mTransWithPushedStream
= aTransWithPushedStream
;
705 mPushedStreamId
= aPushedStreamId
;
708 nsresult
TRRServiceChannel::OnPush(uint32_t aPushedStreamId
,
709 const nsACString
& aUrl
,
710 const nsACString
& aRequestString
,
711 HttpTransactionShell
* aTransaction
) {
712 MOZ_ASSERT(aTransaction
);
713 LOG(("TRRServiceChannel::OnPush [this=%p, trans=%p]\n", this, aTransaction
));
715 MOZ_ASSERT(mCaps
& NS_HTTP_ONPUSH_LISTENER
);
716 nsCOMPtr
<nsIHttpPushListener
> pushListener
;
717 NS_QueryNotificationCallbacks(mCallbacks
, mLoadGroup
,
718 NS_GET_IID(nsIHttpPushListener
),
719 getter_AddRefs(pushListener
));
723 ("TRRServiceChannel::OnPush [this=%p] notification callbacks do not "
724 "implement nsIHttpPushListener\n",
726 return NS_ERROR_NOT_AVAILABLE
;
729 nsCOMPtr
<nsIURI
> pushResource
;
732 // Create a Channel for the Push Resource
733 rv
= NS_NewURI(getter_AddRefs(pushResource
), aUrl
);
735 return NS_ERROR_FAILURE
;
738 nsCOMPtr
<nsILoadInfo
> loadInfo
=
739 static_cast<TRRLoadInfo
*>(mLoadInfo
.get())->Clone();
740 nsCOMPtr
<nsIChannel
> pushHttpChannel
;
741 rv
= gHttpHandler
->CreateTRRServiceChannel(pushResource
, nullptr, 0, nullptr,
743 getter_AddRefs(pushHttpChannel
));
744 NS_ENSURE_SUCCESS(rv
, rv
);
746 rv
= pushHttpChannel
->SetLoadFlags(mLoadFlags
);
747 NS_ENSURE_SUCCESS(rv
, rv
);
749 RefPtr
<TRRServiceChannel
> channel
;
750 CallQueryInterface(pushHttpChannel
, channel
.StartAssignment());
753 return NS_ERROR_UNEXPECTED
;
756 // new channel needs mrqeuesthead and headers from pushedStream
757 channel
->mRequestHead
.ParseHeaderSet(aRequestString
.BeginReading());
758 channel
->mLoadGroup
= mLoadGroup
;
759 channel
->mCallbacks
= mCallbacks
;
761 // Link the pushed stream with the new channel and call listener
762 channel
->SetPushedStreamTransactionAndId(aTransaction
, aPushedStreamId
);
763 rv
= pushListener
->OnPush(this, channel
);
767 void TRRServiceChannel::MaybeStartDNSPrefetch() {
768 if (mConnectionInfo
->UsingHttpProxy() ||
769 (mLoadFlags
& (nsICachingChannel::LOAD_NO_NETWORK_IO
|
770 nsICachingChannel::LOAD_ONLY_FROM_CACHE
))) {
775 ("TRRServiceChannel::MaybeStartDNSPrefetch [this=%p] "
777 this, mCaps
& NS_HTTP_REFRESH_DNS
? ", refresh requested" : ""));
779 OriginAttributes originAttributes
;
781 new nsDNSPrefetch(mURI
, originAttributes
, nsIRequest::GetTRRMode(), this,
782 LoadTimingEnabled());
783 nsIDNSService::DNSFlags dnsFlags
= nsIDNSService::RESOLVE_DEFAULT_FLAGS
;
784 if (mCaps
& NS_HTTP_REFRESH_DNS
) {
785 dnsFlags
|= nsIDNSService::RESOLVE_BYPASS_CACHE
;
787 nsresult rv
= mDNSPrefetch
->PrefetchHigh(dnsFlags
);
788 NS_ENSURE_SUCCESS_VOID(rv
);
792 TRRServiceChannel::OnTransportStatus(nsITransport
* trans
, nsresult status
,
793 int64_t progress
, int64_t progressMax
) {
797 nsresult
TRRServiceChannel::CallOnStartRequest() {
798 LOG(("TRRServiceChannel::CallOnStartRequest [this=%p]", this));
800 if (LoadOnStartRequestCalled()) {
801 LOG(("CallOnStartRequest already invoked before"));
806 StoreTracingEnabled(false);
808 // Ensure mListener->OnStartRequest will be invoked before exiting
810 auto onStartGuard
= MakeScopeExit([&] {
812 (" calling mListener->OnStartRequest by ScopeExit [this=%p, "
814 this, mListener
.get()));
815 MOZ_ASSERT(!LoadOnStartRequestCalled());
818 nsCOMPtr
<nsIStreamListener
> deleteProtector(mListener
);
819 StoreOnStartRequestCalled(true);
820 deleteProtector
->OnStartRequest(this);
822 StoreOnStartRequestCalled(true);
825 if (mResponseHead
&& !mResponseHead
->HasContentCharset()) {
826 mResponseHead
->SetContentCharset(mContentCharsetHint
);
829 LOG((" calling mListener->OnStartRequest [this=%p, listener=%p]\n", this,
832 // About to call OnStartRequest, dismiss the guard object.
833 onStartGuard
.release();
836 MOZ_ASSERT(!LoadOnStartRequestCalled(),
837 "We should not call OsStartRequest twice");
838 nsCOMPtr
<nsIStreamListener
> deleteProtector(mListener
);
839 StoreOnStartRequestCalled(true);
840 rv
= deleteProtector
->OnStartRequest(this);
841 if (NS_FAILED(rv
)) return rv
;
843 NS_WARNING("OnStartRequest skipped because of null listener");
844 StoreOnStartRequestCalled(true);
847 if (!mResponseHead
) {
851 nsAutoCString contentEncoding
;
852 rv
= mResponseHead
->GetHeader(nsHttp::Content_Encoding
, contentEncoding
);
853 if (NS_FAILED(rv
) || contentEncoding
.IsEmpty()) {
857 // DoApplyContentConversions can only be called on the main thread.
858 if (NS_IsMainThread()) {
859 nsCOMPtr
<nsIStreamListener
> listener
;
861 DoApplyContentConversions(mListener
, getter_AddRefs(listener
), nullptr);
866 AfterApplyContentConversions(rv
, listener
);
872 RefPtr
<TRRServiceChannel
> self
= this;
873 rv
= NS_DispatchToMainThread(
874 NS_NewRunnableFunction("TRRServiceChannel::DoApplyContentConversions",
876 nsCOMPtr
<nsIStreamListener
> listener
;
877 nsresult rv
= self
->DoApplyContentConversions(
878 self
->mListener
, getter_AddRefs(listener
),
880 self
->AfterApplyContentConversions(rv
, listener
);
891 void TRRServiceChannel::AfterApplyContentConversions(
892 nsresult aResult
, nsIStreamListener
* aListener
) {
893 LOG(("TRRServiceChannel::AfterApplyContentConversions [this=%p]", this));
894 if (!mCurrentEventTarget
->IsOnCurrentThread()) {
895 RefPtr
<TRRServiceChannel
> self
= this;
896 nsCOMPtr
<nsIStreamListener
> listener
= aListener
;
897 self
->mCurrentEventTarget
->Dispatch(
898 NS_NewRunnableFunction(
899 "TRRServiceChannel::AfterApplyContentConversions",
900 [self
, aResult
, listener
]() {
902 self
->AfterApplyContentConversions(aResult
, listener
);
912 if (NS_FAILED(aResult
)) {
913 Unused
<< AsyncAbort(aResult
);
918 mListener
= aListener
;
919 mCompressListener
= aListener
;
920 StoreHasAppliedConversion(true);
924 void TRRServiceChannel::ProcessAltService() {
925 // e.g. Alt-Svc: h2=":443"; ma=60
926 // e.g. Alt-Svc: h2="otherhost:443"
927 // Alt-Svc = 1#( alternative *( OWS ";" OWS parameter ) )
928 // alternative = protocol-id "=" alt-authority
929 // protocol-id = token ; percent-encoded ALPN protocol identifier
930 // alt-authority = quoted-string ; containing [ uri-host ] ":" port
932 if (!LoadAllowAltSvc()) { // per channel opt out
936 if (!gHttpHandler
->AllowAltSvc() || (mCaps
& NS_HTTP_DISALLOW_SPDY
)) {
941 mURI
->GetScheme(scheme
);
942 bool isHttp
= scheme
.EqualsLiteral("http");
943 if (!isHttp
&& !scheme
.EqualsLiteral("https")) {
948 Unused
<< mResponseHead
->GetHeader(nsHttp::Alternate_Service
, altSvc
);
949 if (altSvc
.IsEmpty()) {
953 if (!nsHttp::IsReasonableHeaderValue(altSvc
)) {
954 LOG(("Alt-Svc Response Header seems unreasonable - skipping\n"));
958 nsCString originHost
;
959 int32_t originPort
= 80;
960 mURI
->GetPort(&originPort
);
961 if (NS_FAILED(mURI
->GetAsciiHost(originHost
))) {
965 nsCOMPtr
<nsIInterfaceRequestor
> callbacks
;
966 nsCOMPtr
<nsProxyInfo
> proxyInfo
;
967 NS_NewNotificationCallbacksAggregation(mCallbacks
, mLoadGroup
,
968 getter_AddRefs(callbacks
));
970 proxyInfo
= do_QueryInterface(mProxyInfo
);
973 auto processHeaderTask
= [altSvc
, scheme
, originHost
, originPort
,
975 privateBrowsing(mPrivateBrowsing
), callbacks
,
976 proxyInfo
, caps(mCaps
)]() {
977 if (XRE_IsSocketProcess()) {
978 AltServiceChild::ProcessHeader(altSvc
, scheme
, originHost
, originPort
,
979 userName
, privateBrowsing
, callbacks
,
980 proxyInfo
, caps
& NS_HTTP_DISALLOW_SPDY
,
985 AltSvcMapping::ProcessHeader(
986 altSvc
, scheme
, originHost
, originPort
, userName
, privateBrowsing
,
987 callbacks
, proxyInfo
, caps
& NS_HTTP_DISALLOW_SPDY
, OriginAttributes());
990 if (NS_IsMainThread()) {
995 NS_DispatchToMainThread(NS_NewRunnableFunction(
996 "TRRServiceChannel::ProcessAltService", std::move(processHeaderTask
)));
1000 TRRServiceChannel::OnStartRequest(nsIRequest
* request
) {
1001 LOG(("TRRServiceChannel::OnStartRequest [this=%p request=%p status=%" PRIx32
1003 this, request
, static_cast<uint32_t>(static_cast<nsresult
>(mStatus
))));
1005 if (!(mCanceled
|| NS_FAILED(mStatus
))) {
1006 // capture the request's status, so our consumers will know ASAP of any
1007 // connection failures, etc - bug 93581
1009 request
->GetStatus(&status
);
1013 MOZ_ASSERT(request
== mTransactionPump
, "Unexpected request");
1015 StoreAfterOnStartRequestBegun(true);
1017 if (!mSecurityInfo
) {
1018 // grab the security info from the connection object; the transaction
1019 // is guaranteed to own a reference to the connection.
1020 mSecurityInfo
= mTransaction
->SecurityInfo();
1024 if (NS_SUCCEEDED(mStatus
) && mTransaction
) {
1025 // mTransactionPump doesn't hit OnInputStreamReady and call this until
1026 // all of the response headers have been acquired, so we can take
1027 // ownership of them from the transaction.
1028 mResponseHead
= mTransaction
->TakeResponseHead();
1029 if (mResponseHead
) {
1030 uint32_t httpStatus
= mResponseHead
->Status();
1031 if (mTransaction
->ProxyConnectFailed()) {
1032 LOG(("TRRServiceChannel proxy connect failed httpStatus: %d",
1034 MOZ_ASSERT(mConnectionInfo
->UsingConnect(),
1035 "proxy connect failed but not using CONNECT?");
1036 nsresult rv
= HttpProxyResponseToErrorCode(httpStatus
);
1037 mTransaction
->DontReuseConnection();
1039 return CallOnStartRequest();
1042 if ((httpStatus
< 500) && (httpStatus
!= 421) && (httpStatus
!= 407)) {
1043 ProcessAltService();
1046 if (httpStatus
== 300 || httpStatus
== 301 || httpStatus
== 302 ||
1047 httpStatus
== 303 || httpStatus
== 307 || httpStatus
== 308) {
1048 nsresult rv
= SyncProcessRedirection(httpStatus
);
1049 if (NS_SUCCEEDED(rv
)) {
1058 NS_WARNING("No response head in OnStartRequest");
1062 // avoid crashing if mListener happens to be null...
1064 MOZ_ASSERT_UNREACHABLE("mListener is null");
1068 return CallOnStartRequest();
1071 nsresult
TRRServiceChannel::SyncProcessRedirection(uint32_t aHttpStatus
) {
1072 nsAutoCString location
;
1074 // if a location header was not given, then we can't perform the redirect,
1075 // so just carry on as though this were a normal response.
1076 if (NS_FAILED(mResponseHead
->GetHeader(nsHttp::Location
, location
))) {
1077 return NS_ERROR_FAILURE
;
1080 // make sure non-ASCII characters in the location header are escaped.
1081 nsAutoCString locationBuf
;
1082 if (NS_EscapeURL(location
.get(), -1, esc_OnlyNonASCII
| esc_Spaces
,
1084 location
= locationBuf
;
1087 LOG(("redirecting to: %s [redirection-limit=%u]\n", location
.get(),
1088 uint32_t(mRedirectionLimit
)));
1090 nsCOMPtr
<nsIURI
> redirectURI
;
1091 nsresult rv
= NS_NewURI(getter_AddRefs(redirectURI
), location
);
1093 if (NS_FAILED(rv
)) {
1094 LOG(("Invalid URI for redirect: Location: %s\n", location
.get()));
1095 return NS_ERROR_CORRUPTED_CONTENT
;
1098 // move the reference of the old location to the new one if the new
1100 PropagateReferenceIfNeeded(mURI
, redirectURI
);
1103 ShouldRewriteRedirectToGET(aHttpStatus
, mRequestHead
.ParsedMethod());
1105 // Let's not rewrite the method to GET for TRR requests.
1107 return NS_ERROR_FAILURE
;
1110 // If the method is not safe (such as POST, PUT, DELETE, ...)
1111 if (!mRequestHead
.IsSafeMethod()) {
1112 LOG(("TRRServiceChannel: unsafe redirect to:%s\n", location
.get()));
1115 uint32_t redirectFlags
;
1116 if (nsHttp::IsPermanentRedirect(aHttpStatus
)) {
1117 redirectFlags
= nsIChannelEventSink::REDIRECT_PERMANENT
;
1119 redirectFlags
= nsIChannelEventSink::REDIRECT_TEMPORARY
;
1122 nsCOMPtr
<nsIChannel
> newChannel
;
1123 nsCOMPtr
<nsILoadInfo
> redirectLoadInfo
=
1124 static_cast<TRRLoadInfo
*>(mLoadInfo
.get())->Clone();
1125 rv
= gHttpHandler
->CreateTRRServiceChannel(redirectURI
, nullptr, 0, nullptr,
1127 getter_AddRefs(newChannel
));
1128 if (NS_FAILED(rv
)) {
1132 rv
= SetupReplacementChannel(redirectURI
, newChannel
, !rewriteToGET
,
1134 if (NS_FAILED(rv
)) {
1138 // Make sure to do this after we received redirect veto answer,
1139 // i.e. after all sinks had been notified
1140 newChannel
->SetOriginalURI(mOriginalURI
);
1142 rv
= newChannel
->AsyncOpen(mListener
);
1143 LOG((" new channel AsyncOpen returned %" PRIX32
, static_cast<uint32_t>(rv
)));
1145 // close down this channel
1146 Cancel(NS_BINDING_REDIRECTED
);
1153 nsresult
TRRServiceChannel::SetupReplacementChannel(nsIURI
* aNewURI
,
1154 nsIChannel
* aNewChannel
,
1155 bool aPreserveMethod
,
1156 uint32_t aRedirectFlags
) {
1158 ("TRRServiceChannel::SetupReplacementChannel "
1159 "[this=%p newChannel=%p preserveMethod=%d]",
1160 this, aNewChannel
, aPreserveMethod
));
1162 nsresult rv
= HttpBaseChannel::SetupReplacementChannel(
1163 aNewURI
, aNewChannel
, aPreserveMethod
, aRedirectFlags
);
1164 if (NS_FAILED(rv
)) {
1168 rv
= CheckRedirectLimit(aRedirectFlags
);
1169 NS_ENSURE_SUCCESS(rv
, rv
);
1171 nsCOMPtr
<nsIHttpChannel
> httpChannel
= do_QueryInterface(aNewChannel
);
1174 return NS_ERROR_FAILURE
;
1177 // convey the ApplyConversion flag (bug 91862)
1178 nsCOMPtr
<nsIEncodedChannel
> encodedChannel
= do_QueryInterface(httpChannel
);
1179 if (encodedChannel
) {
1180 encodedChannel
->SetApplyConversion(LoadApplyConversion());
1183 // mContentTypeHint is empty when this channel is used to download
1185 if (mContentTypeHint
.IsEmpty()) {
1189 // Make sure we set content-type on the old channel properly.
1190 MOZ_ASSERT(mContentTypeHint
.Equals("application/dns-message") ||
1191 mContentTypeHint
.Equals("application/oblivious-dns-message"));
1193 // Apply TRR specific settings. Note that we already know mContentTypeHint is
1194 // "application/dns-message" or "application/oblivious-dns-message" here.
1195 return TRR::SetupTRRServiceChannelInternal(
1197 mRequestHead
.ParsedMethod() == nsHttpRequestHead::kMethod_Get
,
1202 TRRServiceChannel::OnDataAvailable(nsIRequest
* request
, nsIInputStream
* input
,
1203 uint64_t offset
, uint32_t count
) {
1204 LOG(("TRRServiceChannel::OnDataAvailable [this=%p request=%p offset=%" PRIu64
1205 " count=%" PRIu32
"]\n",
1206 this, request
, offset
, count
));
1208 // don't send out OnDataAvailable notifications if we've been canceled.
1209 if (mCanceled
) return mStatus
;
1211 MOZ_ASSERT(mResponseHead
, "No response head in ODA!!");
1214 return mListener
->OnDataAvailable(this, input
, offset
, count
);
1217 return NS_ERROR_ABORT
;
1221 TRRServiceChannel::OnStopRequest(nsIRequest
* request
, nsresult status
) {
1222 LOG(("TRRServiceChannel::OnStopRequest [this=%p request=%p status=%" PRIx32
1224 this, request
, static_cast<uint32_t>(status
)));
1226 if (mCanceled
|| NS_FAILED(mStatus
)) status
= mStatus
;
1228 mTransactionTimings
= mTransaction
->Timings();
1229 mTransaction
= nullptr;
1230 mTransactionPump
= nullptr;
1233 LOG(("TRRServiceChannel %p calling OnStopRequest\n", this));
1234 MOZ_ASSERT(LoadOnStartRequestCalled(),
1235 "OnStartRequest should be called before OnStopRequest");
1236 MOZ_ASSERT(!LoadOnStopRequestCalled(),
1237 "We should not call OnStopRequest twice");
1238 StoreOnStopRequestCalled(true);
1239 mListener
->OnStopRequest(this, status
);
1241 StoreOnStopRequestCalled(true);
1243 mDNSPrefetch
= nullptr;
1246 mLoadGroup
->RemoveRequest(this, nullptr, status
);
1254 TRRServiceChannel::OnLookupComplete(nsICancelable
* request
, nsIDNSRecord
* rec
,
1257 ("TRRServiceChannel::OnLookupComplete [this=%p] prefetch complete%s: "
1258 "%s status[0x%" PRIx32
"]\n",
1259 this, mCaps
& NS_HTTP_REFRESH_DNS
? ", refresh requested" : "",
1260 NS_SUCCEEDED(status
) ? "success" : "failure",
1261 static_cast<uint32_t>(status
)));
1263 // We no longer need the dns prefetch object. Note: mDNSPrefetch could be
1264 // validly null if OnStopRequest has already been called.
1265 // We only need the domainLookup timestamps when not loading from cache
1266 if (mDNSPrefetch
&& mDNSPrefetch
->TimingsValid() && mTransaction
) {
1267 TimeStamp connectStart
= mTransaction
->GetConnectStart();
1268 TimeStamp requestStart
= mTransaction
->GetRequestStart();
1269 // We only set the domainLookup timestamps if we're not using a
1270 // persistent connection.
1271 if (requestStart
.IsNull() && connectStart
.IsNull()) {
1272 mTransaction
->SetDomainLookupStart(mDNSPrefetch
->StartTimestamp());
1273 mTransaction
->SetDomainLookupEnd(mDNSPrefetch
->EndTimestamp());
1276 mDNSPrefetch
= nullptr;
1278 // Unset DNS cache refresh if it was requested,
1279 if (mCaps
& NS_HTTP_REFRESH_DNS
) {
1280 mCaps
&= ~NS_HTTP_REFRESH_DNS
;
1282 mTransaction
->SetDNSWasRefreshed();
1290 TRRServiceChannel::LogBlockedCORSRequest(const nsAString
& aMessage
,
1291 const nsACString
& aCategory
,
1293 return NS_ERROR_NOT_IMPLEMENTED
;
1297 TRRServiceChannel::LogMimeTypeMismatch(const nsACString
& aMessageName
,
1298 bool aWarning
, const nsAString
& aURL
,
1299 const nsAString
& aContentType
) {
1300 return NS_ERROR_NOT_IMPLEMENTED
;
1304 TRRServiceChannel::GetIsAuthChannel(bool* aIsAuthChannel
) {
1305 return NS_ERROR_NOT_IMPLEMENTED
;
1309 TRRServiceChannel::SetNotificationCallbacks(nsIInterfaceRequestor
* aCallbacks
) {
1310 mCallbacks
= aCallbacks
;
1315 TRRServiceChannel::SetPriority(int32_t value
) {
1316 return NS_ERROR_NOT_IMPLEMENTED
;
1319 void TRRServiceChannel::OnClassOfServiceUpdated() {
1320 LOG(("TRRServiceChannel::OnClassOfServiceUpdated this=%p, cos=%lu inc=%d",
1321 this, mClassOfService
.Flags(), mClassOfService
.Incremental()));
1324 gHttpHandler
->UpdateClassOfServiceOnTransaction(mTransaction
,
1330 TRRServiceChannel::SetClassFlags(uint32_t inFlags
) {
1331 uint32_t previous
= mClassOfService
.Flags();
1332 mClassOfService
.SetFlags(inFlags
);
1333 if (previous
!= mClassOfService
.Flags()) {
1334 OnClassOfServiceUpdated();
1340 TRRServiceChannel::SetIncremental(bool inFlag
) {
1341 bool previous
= mClassOfService
.Incremental();
1342 mClassOfService
.SetIncremental(inFlag
);
1343 if (previous
!= mClassOfService
.Incremental()) {
1344 OnClassOfServiceUpdated();
1350 TRRServiceChannel::SetClassOfService(ClassOfService cos
) {
1351 ClassOfService previous
= mClassOfService
;
1352 mClassOfService
= cos
;
1353 if (previous
!= mClassOfService
) {
1354 OnClassOfServiceUpdated();
1360 TRRServiceChannel::AddClassFlags(uint32_t inFlags
) {
1361 uint32_t previous
= mClassOfService
.Flags();
1362 mClassOfService
.SetFlags(inFlags
| mClassOfService
.Flags());
1363 if (previous
!= mClassOfService
.Flags()) {
1364 OnClassOfServiceUpdated();
1370 TRRServiceChannel::ClearClassFlags(uint32_t inFlags
) {
1371 uint32_t previous
= mClassOfService
.Flags();
1372 mClassOfService
.SetFlags(~inFlags
& mClassOfService
.Flags());
1373 if (previous
!= mClassOfService
.Flags()) {
1374 OnClassOfServiceUpdated();
1380 TRRServiceChannel::ResumeAt(uint64_t aStartPos
, const nsACString
& aEntityID
) {
1381 return NS_ERROR_NOT_IMPLEMENTED
;
1384 void TRRServiceChannel::DoAsyncAbort(nsresult aStatus
) {
1385 Unused
<< AsyncAbort(aStatus
);
1389 TRRServiceChannel::GetProxyInfo(nsIProxyInfo
** result
) {
1390 if (!mConnectionInfo
) {
1391 *result
= do_AddRef(mProxyInfo
).take();
1393 *result
= do_AddRef(mConnectionInfo
->ProxyInfo()).take();
1398 NS_IMETHODIMP
TRRServiceChannel::GetHttpProxyConnectResponseCode(
1399 int32_t* aResponseCode
) {
1400 NS_ENSURE_ARG_POINTER(aResponseCode
);
1402 *aResponseCode
= -1;
1407 TRRServiceChannel::GetLoadFlags(nsLoadFlags
* aLoadFlags
) {
1408 return HttpBaseChannel::GetLoadFlags(aLoadFlags
);
1412 TRRServiceChannel::SetLoadFlags(nsLoadFlags aLoadFlags
) {
1413 if (aLoadFlags
& (nsICachingChannel::LOAD_ONLY_FROM_CACHE
| LOAD_FROM_CACHE
|
1414 nsICachingChannel::LOAD_NO_NETWORK_IO
)) {
1415 MOZ_ASSERT(false, "Wrong load flags!");
1416 return NS_ERROR_FAILURE
;
1419 return HttpBaseChannel::SetLoadFlags(aLoadFlags
);
1423 TRRServiceChannel::GetURI(nsIURI
** aURI
) {
1424 return HttpBaseChannel::GetURI(aURI
);
1428 TRRServiceChannel::GetNotificationCallbacks(
1429 nsIInterfaceRequestor
** aCallbacks
) {
1430 return HttpBaseChannel::GetNotificationCallbacks(aCallbacks
);
1434 TRRServiceChannel::GetLoadGroup(nsILoadGroup
** aLoadGroup
) {
1435 return HttpBaseChannel::GetLoadGroup(aLoadGroup
);
1439 TRRServiceChannel::GetRequestMethod(nsACString
& aMethod
) {
1440 return HttpBaseChannel::GetRequestMethod(aMethod
);
1443 void TRRServiceChannel::DoNotifyListener() {
1444 LOG(("TRRServiceChannel::DoNotifyListener this=%p", this));
1446 // In case nsHttpChannel::OnStartRequest wasn't called (e.g. due to flag
1447 // LOAD_ONLY_IF_MODIFIED) we want to set AfterOnStartRequestBegun to true
1448 // before notifying listener.
1449 if (!LoadAfterOnStartRequestBegun()) {
1450 StoreAfterOnStartRequestBegun(true);
1453 if (mListener
&& !LoadOnStartRequestCalled()) {
1454 nsCOMPtr
<nsIStreamListener
> listener
= mListener
;
1455 StoreOnStartRequestCalled(true);
1456 listener
->OnStartRequest(this);
1458 StoreOnStartRequestCalled(true);
1460 // Make sure IsPending is set to false. At this moment we are done from
1461 // the point of view of our consumer and we have to report our self
1463 StoreIsPending(false);
1465 if (mListener
&& !LoadOnStopRequestCalled()) {
1466 nsCOMPtr
<nsIStreamListener
> listener
= mListener
;
1467 StoreOnStopRequestCalled(true);
1468 listener
->OnStopRequest(this, mStatus
);
1470 StoreOnStopRequestCalled(true);
1472 // We have to make sure to drop the references to listeners and callbacks
1473 // no longer needed.
1476 DoNotifyListenerCleanup();
1479 void TRRServiceChannel::DoNotifyListenerCleanup() {}
1482 TRRServiceChannel::GetDomainLookupStart(TimeStamp
* _retval
) {
1484 *_retval
= mTransaction
->GetDomainLookupStart();
1486 *_retval
= mTransactionTimings
.domainLookupStart
;
1492 TRRServiceChannel::GetDomainLookupEnd(TimeStamp
* _retval
) {
1494 *_retval
= mTransaction
->GetDomainLookupEnd();
1496 *_retval
= mTransactionTimings
.domainLookupEnd
;
1502 TRRServiceChannel::GetConnectStart(TimeStamp
* _retval
) {
1504 *_retval
= mTransaction
->GetConnectStart();
1506 *_retval
= mTransactionTimings
.connectStart
;
1512 TRRServiceChannel::GetTcpConnectEnd(TimeStamp
* _retval
) {
1514 *_retval
= mTransaction
->GetTcpConnectEnd();
1516 *_retval
= mTransactionTimings
.tcpConnectEnd
;
1522 TRRServiceChannel::GetSecureConnectionStart(TimeStamp
* _retval
) {
1524 *_retval
= mTransaction
->GetSecureConnectionStart();
1526 *_retval
= mTransactionTimings
.secureConnectionStart
;
1532 TRRServiceChannel::GetConnectEnd(TimeStamp
* _retval
) {
1534 *_retval
= mTransaction
->GetConnectEnd();
1536 *_retval
= mTransactionTimings
.connectEnd
;
1542 TRRServiceChannel::GetRequestStart(TimeStamp
* _retval
) {
1544 *_retval
= mTransaction
->GetRequestStart();
1546 *_retval
= mTransactionTimings
.requestStart
;
1552 TRRServiceChannel::GetResponseStart(TimeStamp
* _retval
) {
1554 *_retval
= mTransaction
->GetResponseStart();
1556 *_retval
= mTransactionTimings
.responseStart
;
1562 TRRServiceChannel::GetResponseEnd(TimeStamp
* _retval
) {
1564 *_retval
= mTransaction
->GetResponseEnd();
1566 *_retval
= mTransactionTimings
.responseEnd
;
1571 NS_IMETHODIMP
TRRServiceChannel::SetLoadGroup(nsILoadGroup
* aLoadGroup
) {
1576 TRRServiceChannel::TimingAllowCheck(nsIPrincipal
* aOrigin
, bool* aResult
) {
1577 NS_ENSURE_ARG_POINTER(aResult
);
1582 bool TRRServiceChannel::SameOriginWithOriginalUri(nsIURI
* aURI
) { return true; }
1584 } // namespace mozilla::net