Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp
Warning:line 4867, column 3
Value stored to 'rv' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_protocol_http4.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/netwerk/protocol/http -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/netwerk/protocol/http -resource-dir /usr/lib/llvm-18/lib/clang/18 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D MOZ_APP_UA_NAME="" -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/netwerk/protocol/http -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /var/lib/jenkins/workspace/firefox-scan-build/ipc/chromium/src -I /var/lib/jenkins/workspace/firefox-scan-build/dom/base -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/base -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/cookie -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/dns -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/ipc -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/socket/neqo_glue -I /var/lib/jenkins/workspace/firefox-scan-build/netwerk/url-classifier -I /var/lib/jenkins/workspace/firefox-scan-build/extensions/auth -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-07-27-022226-2793976-1 -x c++ Unified_cpp_protocol_http4.cpp
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim:set expandtab ts=4 sw=2 sts=2 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 <inttypes.h>
11
12#include "mozilla/ScopeExit.h"
13#include "mozilla/Sprintf.h"
14#include "mozilla/dom/nsCSPContext.h"
15#include "mozilla/glean/GleanMetrics.h"
16#include "mozilla/StoragePrincipalHelper.h"
17
18#include "nsCOMPtr.h"
19#include "nsContentSecurityUtils.h"
20#include "nsHttp.h"
21#include "nsHttpChannel.h"
22#include "nsHttpChannelAuthProvider.h"
23#include "nsHttpHandler.h"
24#include "nsIStreamConverter.h"
25#include "nsString.h"
26#include "nsICacheStorageService.h"
27#include "nsICacheStorage.h"
28#include "nsICacheEntry.h"
29#include "nsICryptoHash.h"
30#include "nsIEffectiveTLDService.h"
31#include "nsIHttpHeaderVisitor.h"
32#include "nsINetworkInterceptController.h"
33#include "nsIStringBundle.h"
34#include "nsIStreamListenerTee.h"
35#include "nsISeekableStream.h"
36#include "nsIProtocolProxyService2.h"
37#include "nsIURLQueryStringStripper.h"
38#include "nsIWebTransport.h"
39#include "nsCRT.h"
40#include "nsMimeTypes.h"
41#include "nsNetCID.h"
42#include "nsNetUtil.h"
43#include "nsIStreamTransportService.h"
44#include "prnetdb.h"
45#include "nsEscape.h"
46#include "nsComponentManagerUtils.h"
47#include "nsStreamUtils.h"
48#include "nsIOService.h"
49#include "nsDNSPrefetch.h"
50#include "nsChannelClassifier.h"
51#include "nsIRedirectResultListener.h"
52#include "mozilla/TimeStamp.h"
53#include "nsError.h"
54#include "nsPrintfCString.h"
55#include "nsAlgorithm.h"
56#include "nsQueryObject.h"
57#include "nsThreadUtils.h"
58#include "nsIConsoleService.h"
59#include "mozilla/AntiTrackingRedirectHeuristic.h"
60#include "mozilla/AntiTrackingUtils.h"
61#include "mozilla/Attributes.h"
62#include "mozilla/BasePrincipal.h"
63#include "mozilla/DebugOnly.h"
64#include "mozilla/PerfStats.h"
65#include "mozilla/ProfilerLabels.h"
66#include "mozilla/Components.h"
67#include "mozilla/StaticPrefs_network.h"
68#include "mozilla/StaticPrefs_privacy.h"
69#include "mozilla/StaticPrefs_security.h"
70#include "sslt.h"
71#include "nsCharSeparatedTokenizer.h"
72#include "nsContentUtils.h"
73#include "nsContentSecurityManager.h"
74#include "nsIClassOfService.h"
75#include "nsIPrincipal.h"
76#include "nsIScriptError.h"
77#include "nsIScriptSecurityManager.h"
78#include "nsITransportSecurityInfo.h"
79#include "nsIWebProgressListener.h"
80#include "LoadContextInfo.h"
81#include "netCore.h"
82#include "nsHttpTransaction.h"
83#include "nsICancelable.h"
84#include "nsIHttpChannelInternal.h"
85#include "nsIPrompt.h"
86#include "nsInputStreamPump.h"
87#include "nsURLHelper.h"
88#include "nsISocketTransport.h"
89#include "nsIStreamConverterService.h"
90#include "nsISiteSecurityService.h"
91#include "nsString.h"
92#include "nsStringStream.h"
93#include "mozilla/dom/PerformanceStorage.h"
94#include "mozilla/dom/ReferrerInfo.h"
95#include "mozilla/Telemetry.h"
96#include "AlternateServices.h"
97#include "NetworkMarker.h"
98#include "nsIHttpPushListener.h"
99#include "nsIDNSRecord.h"
100#include "mozilla/dom/Document.h"
101#include "nsICompressConvStats.h"
102#include "nsCORSListenerProxy.h"
103#include "nsISocketProvider.h"
104#include "mozilla/extensions/StreamFilterParent.h"
105#include "mozilla/net/Predictor.h"
106#include "mozilla/MathAlgorithms.h"
107#include "mozilla/NullPrincipal.h"
108#include "CacheControlParser.h"
109#include "nsMixedContentBlocker.h"
110#include "CacheStorageService.h"
111#include "HttpChannelParent.h"
112#include "HttpTransactionParent.h"
113#include "ThirdPartyUtil.h"
114#include "InterceptedHttpChannel.h"
115#include "../../cache2/CacheFileUtils.h"
116#include "nsINetworkLinkService.h"
117#include "mozilla/ContentBlockingAllowList.h"
118#include "mozilla/dom/ServiceWorkerUtils.h"
119#include "mozilla/dom/nsHTTPSOnlyStreamListener.h"
120#include "mozilla/dom/nsHTTPSOnlyUtils.h"
121#include "mozilla/net/AsyncUrlChannelClassifier.h"
122#include "mozilla/net/CookieJarSettings.h"
123#include "mozilla/net/NeckoChannelParams.h"
124#include "mozilla/net/OpaqueResponseUtils.h"
125#include "mozilla/net/UrlClassifierFeatureFactory.h"
126#include "HttpTrafficAnalyzer.h"
127#include "mozilla/net/SocketProcessParent.h"
128#include "mozilla/dom/SecFetch.h"
129#include "mozilla/net/TRRService.h"
130#include "nsUnknownDecoder.h"
131#ifdef XP_WIN
132# include "HttpWinUtils.h"
133#endif
134#ifdef FUZZING
135# include "mozilla/StaticPrefs_fuzzing.h"
136#endif
137
138namespace mozilla {
139
140using namespace dom;
141
142namespace net {
143
144namespace {
145
146// True if the local cache should be bypassed when processing a request.
147#define BYPASS_LOCAL_CACHE(loadFlags, isPreferCacheLoadOverBypass)((loadFlags) & (nsIRequest::LOAD_BYPASS_CACHE | nsICachingChannel
::LOAD_BYPASS_LOCAL_CACHE) && !(((loadFlags) & nsIRequest
::LOAD_FROM_CACHE) && (isPreferCacheLoadOverBypass)))
\
148 ((loadFlags) & (nsIRequest::LOAD_BYPASS_CACHE | \
149 nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE) && \
150 !(((loadFlags) & nsIRequest::LOAD_FROM_CACHE) && \
151 (isPreferCacheLoadOverBypass)))
152
153#define RECOVER_FROM_CACHE_FILE_ERROR(result)((result) == NS_ERROR_FILE_NOT_FOUND || (result) == NS_ERROR_FILE_CORRUPTED
|| (result) == NS_ERROR_OUT_OF_MEMORY)
\
154 ((result) == NS_ERROR_FILE_NOT_FOUND || \
155 (result) == NS_ERROR_FILE_CORRUPTED || (result) == NS_ERROR_OUT_OF_MEMORY)
156
157#define WRONG_RACING_RESPONSE_SOURCE(req)(mRaceCacheWithNetwork && (((mFirstResponseSource == RESPONSE_FROM_CACHE
) && ((req) != mCachePump)) || ((mFirstResponseSource
== RESPONSE_FROM_NETWORK) && ((req) != mTransactionPump
))))
\
158 (mRaceCacheWithNetwork && \
159 (((mFirstResponseSource == RESPONSE_FROM_CACHE) && \
160 ((req) != mCachePump)) || \
161 ((mFirstResponseSource == RESPONSE_FROM_NETWORK) && \
162 ((req) != mTransactionPump))))
163
164static NS_DEFINE_CID(kStreamListenerTeeCID, NS_STREAMLISTENERTEE_CID)const nsCID kStreamListenerTeeCID = { 0x831f8f13, 0x7aa8, 0x485f
, { 0xb0, 0x2e, 0x77, 0xc8, 0x81, 0xcc, 0x57, 0x73 } }
;
165
166enum ChannelDisposition {
167 kHttpCanceled = 0,
168 kHttpDisk = 1,
169 kHttpNetOK = 2,
170 kHttpNetEarlyFail = 3,
171 kHttpNetLateFail = 4,
172 kHttpsCanceled = 8,
173 kHttpsDisk = 9,
174 kHttpsNetOK = 10,
175 kHttpsNetEarlyFail = 11,
176 kHttpsNetLateFail = 12
177};
178
179void AccumulateCacheHitTelemetry(CacheDisposition hitOrMiss,
180 nsIChannel* aChannel) {
181 nsCString key("UNKNOWN");
182
183 nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
184
185 nsAutoCString contentType;
186 if (NS_SUCCEEDED(aChannel->GetContentType(contentType))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aChannel->GetContentType
(contentType))), 1)))
) {
187 if (nsContentUtils::IsJavascriptMIMEType(
188 NS_ConvertUTF8toUTF16(contentType))) {
189 key.AssignLiteral("JAVASCRIPT");
190 } else if (StringBeginsWith(contentType, "text/css"_ns) ||
191 (loadInfo && loadInfo->GetExternalContentPolicyType() ==
192 ExtContentPolicy::TYPE_STYLESHEET)) {
193 key.AssignLiteral("STYLESHEET");
194 } else if (StringBeginsWith(contentType, "application/wasm"_ns)) {
195 key.AssignLiteral("WASM");
196 } else if (StringBeginsWith(contentType, "image/"_ns)) {
197 key.AssignLiteral("IMAGE");
198 } else if (StringBeginsWith(contentType, "video/"_ns)) {
199 key.AssignLiteral("MEDIA");
200 } else if (StringBeginsWith(contentType, "audio/"_ns)) {
201 key.AssignLiteral("MEDIA");
202 } else if (!StringBeginsWith(contentType,
203 nsLiteralCString(UNKNOWN_CONTENT_TYPE"application/x-unknown-content-type"))) {
204 key.AssignLiteral("OTHER");
205 }
206 }
207
208 Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3 label =
209 Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::Unresolved;
210 switch (hitOrMiss) {
211 case kCacheUnresolved:
212 label = Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::Unresolved;
213 break;
214 case kCacheHit:
215 label = Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::Hit;
216 break;
217 case kCacheHitViaReval:
218 label = Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::HitViaReval;
219 break;
220 case kCacheMissedViaReval:
221 label = Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::MissedViaReval;
222 break;
223 case kCacheMissed:
224 label = Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::Missed;
225 break;
226 case kCacheUnknown:
227 label = Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::Unknown;
228 break;
229 }
230
231 Telemetry::AccumulateCategoricalKeyed(key, label);
232 Telemetry::AccumulateCategoricalKeyed("ALL"_ns, label);
233}
234
235// Computes and returns a SHA1 hash of the input buffer. The input buffer
236// must be a null-terminated string.
237nsresult Hash(const char* buf, nsACString& hash) {
238 nsresult rv;
239
240 nsCOMPtr<nsICryptoHash> hasher =
241 do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID"@mozilla.org/security/hash;1", &rv);
242 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 242); return rv; } } while (false)
;
243
244 rv = hasher->Init(nsICryptoHash::SHA1);
245 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 245); return rv; } } while (false)
;
246
247 rv = hasher->Update(reinterpret_cast<unsigned const char*>(buf), strlen(buf));
248 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 248); return rv; } } while (false)
;
249
250 rv = hasher->Finish(true, hash);
251 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 251); return rv; } } while (false)
;
252
253 return NS_OK;
254}
255
256} // unnamed namespace
257
258// We only treat 3xx responses as redirects if they have a Location header and
259// the status code is in a whitelist.
260bool nsHttpChannel::WillRedirect(const nsHttpResponseHead& response) {
261 return IsRedirectStatus(response.Status()) &&
262 response.HasHeader(nsHttp::Location);
263}
264
265nsresult StoreAuthorizationMetaData(nsICacheEntry* entry,
266 nsHttpRequestHead* requestHead);
267
268class MOZ_STACK_CLASS AutoRedirectVetoNotifier {
269 public:
270 explicit AutoRedirectVetoNotifier(nsHttpChannel* channel, nsresult& aRv)
271 : mChannel(channel), mRv(aRv) {
272 if (mChannel->LoadHasAutoRedirectVetoNotifier()) {
273 MOZ_CRASH("Nested AutoRedirectVetoNotifier on the stack")do { do { } while (false); MOZ_ReportCrash("" "Nested AutoRedirectVetoNotifier on the stack"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 273); AnnotateMozCrashReason("MOZ_CRASH(" "Nested AutoRedirectVetoNotifier on the stack"
")"); do { *((volatile int*)__null) = 273; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
274 mChannel = nullptr;
275 return;
276 }
277
278 mChannel->StoreHasAutoRedirectVetoNotifier(true);
279 }
280 ~AutoRedirectVetoNotifier() { ReportRedirectResult(mRv); }
281 void RedirectSucceeded() { ReportRedirectResult(NS_OK); }
282
283 private:
284 nsHttpChannel* mChannel;
285 bool mCalledReport = false;
286 nsresult& mRv;
287 void ReportRedirectResult(nsresult aRv);
288};
289
290void AutoRedirectVetoNotifier::ReportRedirectResult(nsresult aRv) {
291 if (!mChannel) return;
292
293 if (mCalledReport) {
294 return;
295 }
296 mCalledReport = true;
297
298 mChannel->mRedirectChannel = nullptr;
299
300 if (NS_SUCCEEDED(aRv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aRv)), 1)))) {
301 mChannel->RemoveAsNonTailRequest();
302 }
303
304 nsCOMPtr<nsIRedirectResultListener> vetoHook;
305 NS_QueryNotificationCallbacks(mChannel, NS_GET_IID(nsIRedirectResultListener)(nsIRedirectResultListener::COMTypeInfo<nsIRedirectResultListener
, void>::kIID)
,
306 getter_AddRefs(vetoHook));
307
308 nsHttpChannel* channel = mChannel;
309 mChannel = nullptr;
310
311 if (vetoHook) vetoHook->OnRedirectResult(aRv);
312
313 // Drop after the notification
314 channel->StoreHasAutoRedirectVetoNotifier(false);
315}
316
317//-----------------------------------------------------------------------------
318// nsHttpChannel <public>
319//-----------------------------------------------------------------------------
320
321nsHttpChannel::nsHttpChannel() : HttpAsyncAborter<nsHttpChannel>(this) {
322 LOG(("Creating nsHttpChannel [this=%p, nsIChannel=%p]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Creating nsHttpChannel [this=%p, nsIChannel=%p]\n", this, static_cast
<nsIChannel*>(this)); } } while (0)
323 static_cast<nsIChannel*>(this)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Creating nsHttpChannel [this=%p, nsIChannel=%p]\n", this, static_cast
<nsIChannel*>(this)); } } while (0)
;
324 mChannelCreationTime = PR_Now();
325 mChannelCreationTimestamp = TimeStamp::Now();
326}
327
328nsHttpChannel::~nsHttpChannel() {
329 LOG(("Destroying nsHttpChannel [this=%p, nsIChannel=%p]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Destroying nsHttpChannel [this=%p, nsIChannel=%p]\n", this
, static_cast<nsIChannel*>(this)); } } while (0)
330 static_cast<nsIChannel*>(this)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Destroying nsHttpChannel [this=%p, nsIChannel=%p]\n", this
, static_cast<nsIChannel*>(this)); } } while (0)
;
331
332 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(mozilla::net::
gHttpLog, mozilla::LogLevel::Verbose)), 0))
) {
333 nsCString webExtension;
334 this->GetPropertyAsACString(u"cancelledByExtension"_ns, webExtension);
335 if (!webExtension.IsEmpty()) {
336 LOG(("channel [%p] cancelled by extension [id=%s]", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "channel [%p] cancelled by extension [id=%s]", this, webExtension
.get()); } } while (0)
337 webExtension.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "channel [%p] cancelled by extension [id=%s]", this, webExtension
.get()); } } while (0)
;
338 }
339 }
340
341 if (mAuthProvider) {
342 DebugOnly<nsresult> rv = mAuthProvider->Disconnect(NS_ERROR_ABORT);
343 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 343); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 343; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
344 }
345
346 ReleaseMainThreadOnlyReferences();
347 if (gHttpHandler) {
348 gHttpHandler->RemoveHttpChannel(mChannelId);
349 }
350}
351
352void nsHttpChannel::ReleaseMainThreadOnlyReferences() {
353 if (NS_IsMainThread()) {
354 // Already on main thread, let dtor to
355 // take care of releasing references
356 return;
357 }
358
359 nsTArray<nsCOMPtr<nsISupports>> arrayToRelease;
360 arrayToRelease.AppendElement(mAuthProvider.forget());
361 arrayToRelease.AppendElement(mRedirectChannel.forget());
362 arrayToRelease.AppendElement(mPreflightChannel.forget());
363 arrayToRelease.AppendElement(mDNSPrefetch.forget());
364
365 MOZ_DIAGNOSTIC_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mEarlyHintObserver)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mEarlyHintObserver))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("!mEarlyHintObserver"
" (" "Early hint observer should have been released in ReleaseListeners()"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 367); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mEarlyHintObserver"
") (" "Early hint observer should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 367; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
366 !mEarlyHintObserver,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mEarlyHintObserver)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mEarlyHintObserver))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("!mEarlyHintObserver"
" (" "Early hint observer should have been released in ReleaseListeners()"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 367); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mEarlyHintObserver"
") (" "Early hint observer should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 367; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
367 "Early hint observer should have been released in ReleaseListeners()")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mEarlyHintObserver)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mEarlyHintObserver))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("!mEarlyHintObserver"
" (" "Early hint observer should have been released in ReleaseListeners()"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 367); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mEarlyHintObserver"
") (" "Early hint observer should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 367; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
368 arrayToRelease.AppendElement(mEarlyHintObserver.forget());
369 MOZ_DIAGNOSTIC_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mChannelClassifier)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mChannelClassifier))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("!mChannelClassifier"
" (" "Channel classifier should have been released in ReleaseListeners()"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 371); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mChannelClassifier"
") (" "Channel classifier should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 371; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
370 !mChannelClassifier,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mChannelClassifier)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mChannelClassifier))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("!mChannelClassifier"
" (" "Channel classifier should have been released in ReleaseListeners()"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 371); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mChannelClassifier"
") (" "Channel classifier should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 371; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
371 "Channel classifier should have been released in ReleaseListeners()")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mChannelClassifier)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mChannelClassifier))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("!mChannelClassifier"
" (" "Channel classifier should have been released in ReleaseListeners()"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 371); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mChannelClassifier"
") (" "Channel classifier should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 371; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
372 arrayToRelease.AppendElement(
373 mChannelClassifier.forget().downcast<nsIURIClassifierCallback>());
374 MOZ_DIAGNOSTIC_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mWarningReporter)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mWarningReporter))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mWarningReporter"
" (" "Warning reporter should have been released in ReleaseListeners()"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 376); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mWarningReporter"
") (" "Warning reporter should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 376; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
375 !mWarningReporter,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mWarningReporter)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mWarningReporter))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mWarningReporter"
" (" "Warning reporter should have been released in ReleaseListeners()"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 376); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mWarningReporter"
") (" "Warning reporter should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 376; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
376 "Warning reporter should have been released in ReleaseListeners()")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mWarningReporter)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mWarningReporter))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mWarningReporter"
" (" "Warning reporter should have been released in ReleaseListeners()"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 376); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mWarningReporter"
") (" "Warning reporter should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 376; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
377 arrayToRelease.AppendElement(mWarningReporter.forget());
378
379 NS_DispatchToMainThread(new ProxyReleaseRunnable(std::move(arrayToRelease)));
380}
381
382nsresult nsHttpChannel::Init(nsIURI* uri, uint32_t caps, nsProxyInfo* proxyInfo,
383 uint32_t proxyResolveFlags, nsIURI* proxyURI,
384 uint64_t channelId,
385 ExtContentPolicyType aContentPolicyType,
386 nsILoadInfo* aLoadInfo) {
387 nsresult rv =
388 HttpBaseChannel::Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI,
389 channelId, aContentPolicyType, aLoadInfo);
390 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
391
392 LOG1(("nsHttpChannel::Init [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla::
detail::log_print(moz_real_module, mozilla::LogLevel::Error, "nsHttpChannel::Init [this=%p]\n"
, this); } } while (0)
;
393
394 return rv;
395}
396
397nsresult nsHttpChannel::AddSecurityMessage(const nsAString& aMessageTag,
398 const nsAString& aMessageCategory) {
399 if (mWarningReporter) {
400 return mWarningReporter->ReportSecurityMessage(aMessageTag,
401 aMessageCategory);
402 }
403 return HttpBaseChannel::AddSecurityMessage(aMessageTag, aMessageCategory);
404}
405
406NS_IMETHODIMPnsresult
407nsHttpChannel::LogBlockedCORSRequest(const nsAString& aMessage,
408 const nsACString& aCategory,
409 bool aIsWarning) {
410 if (mWarningReporter) {
411 return mWarningReporter->LogBlockedCORSRequest(aMessage, aCategory,
412 aIsWarning);
413 }
414 return NS_ERROR_UNEXPECTED;
415}
416
417NS_IMETHODIMPnsresult
418nsHttpChannel::LogMimeTypeMismatch(const nsACString& aMessageName,
419 bool aWarning, const nsAString& aURL,
420 const nsAString& aContentType) {
421 if (mWarningReporter) {
422 return mWarningReporter->LogMimeTypeMismatch(aMessageName, aWarning, aURL,
423 aContentType);
424 }
425 return NS_ERROR_UNEXPECTED;
426}
427
428//-----------------------------------------------------------------------------
429// nsHttpChannel <private>
430//-----------------------------------------------------------------------------
431
432nsresult nsHttpChannel::PrepareToConnect() {
433 LOG(("nsHttpChannel::PrepareToConnect [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::PrepareToConnect [this=%p]\n", this); } } while
(0)
;
434
435 // notify "http-on-modify-request-before-cookies" observers
436 gHttpHandler->OnModifyRequestBeforeCookies(this);
437
438 AddCookiesToRequest();
439
440#ifdef XP_WIN
441
442 auto prefEnabledForCurrentContainer = [&]() {
443 uint32_t containerId = mLoadInfo->GetOriginAttributes().mUserContextId;
444 // Make sure that the default container ID is 0
445 static_assert(nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID == 0);
446 nsPrintfCString prefName("network.http.windows-sso.container-enabled.%u",
447 containerId);
448
449 bool enabled = false;
450 Preferences::GetBool(prefName.get(), &enabled);
451
452 LOG(("Pref for %s is %d\n", prefName.get(), enabled))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Pref for %s is %d\n", prefName.get(), enabled); } } while (
0)
;
453
454 return enabled;
455 };
456
457 // If Windows 10 SSO is enabled, we potentially add auth information to
458 // secure top level loads (DOCUMENTs) and iframes (SUBDOCUMENTs) that
459 // aren't anonymous or private browsing.
460 if (StaticPrefs::network_http_windows_sso_enabled() &&
461 mURI->SchemeIs("https") && !(mLoadFlags & LOAD_ANONYMOUS) &&
462 !mPrivateBrowsing) {
463 ExtContentPolicyType type = mLoadInfo->GetExternalContentPolicyType();
464 if ((type == ExtContentPolicy::TYPE_DOCUMENT ||
465 type == ExtContentPolicy::TYPE_SUBDOCUMENT) &&
466 prefEnabledForCurrentContainer()) {
467 AddWindowsSSO(this);
468 }
469 }
470#endif
471
472 // notify "http-on-modify-request" observers
473 CallOnModifyRequestObservers();
474
475 return CallOrWaitForResume(
476 [](auto* self) { return self->OnBeforeConnect(); });
477}
478
479void nsHttpChannel::HandleContinueCancellingByURLClassifier(
480 nsresult aErrorCode) {
481 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 482); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 482; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
482 UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 482); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 482; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
483 MOZ_ASSERT(!mCallOnResume, "How did that happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCallOnResume)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mCallOnResume))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mCallOnResume"
" (" "How did that happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 483); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 483; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
484
485 if (mSuspendCount) {
486 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume HandleContinueCancellingByURLClassifier "
"[this=%p]\n", this); } } while (0)
487 ("Waiting until resume HandleContinueCancellingByURLClassifier "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume HandleContinueCancellingByURLClassifier "
"[this=%p]\n", this); } } while (0)
488 "[this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume HandleContinueCancellingByURLClassifier "
"[this=%p]\n", this); } } while (0)
489 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume HandleContinueCancellingByURLClassifier "
"[this=%p]\n", this); } } while (0)
;
490 mCallOnResume = [aErrorCode](nsHttpChannel* self) {
491 self->HandleContinueCancellingByURLClassifier(aErrorCode);
492 return NS_OK;
493 };
494 return;
495 }
496
497 LOG(("nsHttpChannel::HandleContinueCancellingByURLClassifier [this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::HandleContinueCancellingByURLClassifier [this=%p]\n"
, this); } } while (0)
498 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::HandleContinueCancellingByURLClassifier [this=%p]\n"
, this); } } while (0)
;
499 ContinueCancellingByURLClassifier(aErrorCode);
500}
501
502void nsHttpChannel::SetPriorityHeader() {
503 nsAutoCString userSetPriority;
504 Unused << GetRequestHeader("Priority"_ns, userSetPriority);
505 if (!userSetPriority.IsEmpty()) {
506 // If the Priority header is set by the user, do not override it.
507 return;
508 }
509
510 uint8_t urgency =
511 nsHttpHandler::UrgencyFromCoSFlags(mClassOfService.Flags(), mPriority);
512 bool incremental = mClassOfService.Incremental();
513
514 nsPrintfCString value(
515 "%s", urgency != 3 ? nsPrintfCString("u=%d", urgency).get() : "");
516
517 if (incremental) {
518 if (!value.IsEmpty()) {
519 value.Append(", ");
520 }
521 value.Append("i");
522 }
523
524 if (!value.IsEmpty()) {
525 SetRequestHeader("Priority"_ns, value, false);
526 }
527}
528
529nsresult nsHttpChannel::OnBeforeConnect() {
530 nsresult rv = NS_OK;
531
532 // Check if request was cancelled during suspend AFTER on-modify-request
533 if (mCanceled) {
534 return mStatus;
535 }
536
537 // Check to see if we should redirect this channel elsewhere by
538 // nsIHttpChannel.redirectTo API request
539 if (mAPIRedirectToURI) {
540 return AsyncCall(&nsHttpChannel::HandleAsyncAPIRedirect);
541 }
542
543 // Note that we are only setting the "Upgrade-Insecure-Requests" request
544 // header for *all* navigational requests instead of all requests as
545 // defined in the spec, see:
546 // https://www.w3.org/TR/upgrade-insecure-requests/#preference
547 ExtContentPolicyType type = mLoadInfo->GetExternalContentPolicyType();
548
549 if (type == ExtContentPolicy::TYPE_DOCUMENT ||
550 type == ExtContentPolicy::TYPE_SUBDOCUMENT) {
551 rv = SetRequestHeader("Upgrade-Insecure-Requests"_ns, "1"_ns, false);
552 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 552); return rv; } } while (false)
;
553 }
554
555 if (LoadAuthRedirectedChannel()) {
556 // This channel is a result of a redirect due to auth retry
557 // We have already checked for HSTS upgarde in the redirecting channel.
558 // We can safely skip those checks
559 return ContinueOnBeforeConnect(false, rv);
560 }
561
562 SecFetch::AddSecFetchHeader(this);
563
564 // Check to see if we should redirect this channel to the unstripped URI. To
565 // revert the query stripping if the loading channel is in the content
566 // blocking allow list.
567 if (ContentBlockingAllowList::Check(this)) {
568 nsCOMPtr<nsIURI> unstrippedURI;
569 mLoadInfo->GetUnstrippedURI(getter_AddRefs(unstrippedURI));
570
571 if (unstrippedURI) {
572 return AsyncCall(&nsHttpChannel::HandleAsyncRedirectToUnstrippedURI);
573 }
574 }
575
576 nsCOMPtr<nsIPrincipal> resultPrincipal;
577 if (!mURI->SchemeIs("https")) {
578 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
579 this, getter_AddRefs(resultPrincipal));
580 }
581
582 // Check if we already know about the HSTS status of the host
583 nsISiteSecurityService* sss = gHttpHandler->GetSSService();
584 NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY)do { if ((__builtin_expect(!!(!(sss)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "sss" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 584); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
585 bool isSecureURI;
586 OriginAttributes originAttributes;
587 if (!StoragePrincipalHelper::GetOriginAttributesForHSTS(this,
588 originAttributes)) {
589 return NS_ERROR_FAILURE;
590 }
591 rv = sss->IsSecureURI(mURI, originAttributes, &isSecureURI);
592 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 592); return rv; } } while (false)
;
593 // Save that on the loadInfo so it can later be consumed by
594 // SecurityInfo.sys.mjs
595 mLoadInfo->SetHstsStatus(isSecureURI);
596
597 RefPtr<mozilla::dom::BrowsingContext> bc;
598 mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
599 if (bc && bc->Top()->GetForceOffline()) {
600 return NS_ERROR_OFFLINE;
601 }
602
603 // At this point it is no longer possible to call
604 // HttpBaseChannel::UpgradeToSecure.
605 StoreUpgradableToSecure(false);
606 bool shouldUpgrade = LoadUpgradeToSecure();
607 if (mURI->SchemeIs("http")) {
608 OriginAttributes originAttributes;
609 if (!StoragePrincipalHelper::GetOriginAttributesForHSTS(this,
610 originAttributes)) {
611 return NS_ERROR_FAILURE;
612 }
613
614 if (!shouldUpgrade) {
615 // Make sure http channel is released on main thread.
616 // See bug 1539148 for details.
617 nsMainThreadPtrHandle<nsHttpChannel> self(
618 new nsMainThreadPtrHolder<nsHttpChannel>(
619 "nsHttpChannel::OnBeforeConnect::self", this));
620 auto resultCallback = [self(self)](bool aResult, nsresult aStatus) {
621 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 621); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 621; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
622
623 nsresult rv = self->MaybeUseHTTPSRRForUpgrade(aResult, aStatus);
624 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
625 self->CloseCacheEntry(false);
626 Unused << self->AsyncAbort(rv);
627 }
628 };
629
630 bool willCallback = false;
631 rv = NS_ShouldSecureUpgrade(
632 mURI, mLoadInfo, resultPrincipal, LoadAllowSTS(), originAttributes,
633 shouldUpgrade, std::move(resultCallback), willCallback);
634 // If the request gets upgraded because of the HTTPS-Only mode, but no
635 // event listener has been registered so far, we want to do that here.
636 uint32_t httpOnlyStatus = mLoadInfo->GetHttpsOnlyStatus();
637 if (httpOnlyStatus &
638 nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_NOT_REGISTERED) {
639 RefPtr<nsHTTPSOnlyStreamListener> httpsOnlyListener =
640 new nsHTTPSOnlyStreamListener(mListener, mLoadInfo);
641 mListener = httpsOnlyListener;
642
643 httpOnlyStatus ^=
644 nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_NOT_REGISTERED;
645 httpOnlyStatus |= nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_REGISTERED;
646 mLoadInfo->SetHttpsOnlyStatus(httpOnlyStatus);
647 }
648 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnBeforeConnect " "[this=%p willCallback=%d rv=%"
"x" "]\n", this, willCallback, static_cast<uint32_t>(rv
)); } } while (0)
649 ("nsHttpChannel::OnBeforeConnect "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnBeforeConnect " "[this=%p willCallback=%d rv=%"
"x" "]\n", this, willCallback, static_cast<uint32_t>(rv
)); } } while (0)
650 "[this=%p willCallback=%d rv=%" PRIx32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnBeforeConnect " "[this=%p willCallback=%d rv=%"
"x" "]\n", this, willCallback, static_cast<uint32_t>(rv
)); } } while (0)
651 this, willCallback, static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnBeforeConnect " "[this=%p willCallback=%d rv=%"
"x" "]\n", this, willCallback, static_cast<uint32_t>(rv
)); } } while (0)
;
652
653 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || MOZ_UNLIKELY(willCallback)(__builtin_expect(!!(willCallback), 0))) {
654 return rv;
655 }
656 }
657 }
658
659 return MaybeUseHTTPSRRForUpgrade(shouldUpgrade, NS_OK);
660}
661
662// Returns true if the network connectivity checker indicated
663// that HTTPS records can be resolved on this network - false otherwise.
664// When TRR is enabled, we always return true, as resolving HTTPS
665// records don't depend on the network.
666static bool canUseHTTPSRRonNetwork(bool* aTRREnabled = nullptr) {
667 // Respect the pref.
668 if (StaticPrefs::network_dns_force_use_https_rr()) {
669 if (aTRREnabled) {
670 *aTRREnabled = true;
671 }
672 return true;
673 }
674
675 if (nsCOMPtr<nsIDNSService> dns = mozilla::components::DNS::Service()) {
676 nsIDNSService::ResolverMode mode;
677 // If the browser is currently using TRR/DoH, then it can
678 // definitely resolve HTTPS records.
679 if (NS_SUCCEEDED(dns->GetCurrentTrrMode(&mode))((bool)(__builtin_expect(!!(!NS_FAILED_impl(dns->GetCurrentTrrMode
(&mode))), 1)))
&&
680 (mode == nsIDNSService::MODE_TRRFIRST ||
681 mode == nsIDNSService::MODE_TRRONLY)) {
682 if (aTRREnabled) {
683 *aTRREnabled = true;
684 }
685 return true;
686 }
687 }
688 if (RefPtr<NetworkConnectivityService> ncs =
689 NetworkConnectivityService::GetSingleton()) {
690 nsINetworkConnectivityService::ConnectivityState state;
691 if (NS_SUCCEEDED(ncs->GetDNS_HTTPS(&state))((bool)(__builtin_expect(!!(!NS_FAILED_impl(ncs->GetDNS_HTTPS
(&state))), 1)))
&&
692 state == nsINetworkConnectivityService::NOT_AVAILABLE) {
693 return false;
694 }
695 }
696 return true;
697}
698
699nsresult nsHttpChannel::MaybeUseHTTPSRRForUpgrade(bool aShouldUpgrade,
700 nsresult aStatus) {
701 if (NS_FAILED(aStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus)), 0)))) {
702 return aStatus;
703 }
704
705 if (mURI->SchemeIs("https") || aShouldUpgrade || !LoadUseHTTPSSVC()) {
706 return ContinueOnBeforeConnect(aShouldUpgrade, aStatus);
707 }
708
709 auto shouldSkipUpgradeWithHTTPSRR = [&]() -> bool {
710 // Skip using HTTPS RR to upgrade when this is not a top-level load and the
711 // loading principal is http.
712 if ((mLoadInfo->GetExternalContentPolicyType() !=
713 ExtContentPolicy::TYPE_DOCUMENT) &&
714 (mLoadInfo->GetLoadingPrincipal() &&
715 mLoadInfo->GetLoadingPrincipal()->SchemeIs("http"))) {
716 return true;
717 }
718
719 // If the network connectivity checker indicates the network is
720 // blocking HTTPS requests, then we should skip them so we don't
721 // needlessly wait for a timeout.
722 bool trrEnabled = false;
723 if (!canUseHTTPSRRonNetwork(&trrEnabled)) {
724 return true;
725 }
726
727 // Don't block the channel when TRR is not used.
728 if (!trrEnabled) {
729 return true;
730 }
731
732 nsAutoCString uriHost;
733 mURI->GetAsciiHost(uriHost);
734
735 return gHttpHandler->IsHostExcludedForHTTPSRR(uriHost);
736 };
737
738 if (shouldSkipUpgradeWithHTTPSRR()) {
739 StoreUseHTTPSSVC(false);
740 // If the website does not want to use HTTPS RR, we should set
741 // NS_HTTP_DISALLOW_HTTPS_RR. This is for avoiding HTTPS RR being used by
742 // the transaction.
743 DisallowHTTPSRR(mCaps);
744 return ContinueOnBeforeConnect(aShouldUpgrade, aStatus);
745 }
746
747 if (mHTTPSSVCRecord.isSome()) {
748 LOG((do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeUseHTTPSRRForUpgrade [%p] mHTTPSSVCRecord is some"
, this); } } while (0)
749 "nsHttpChannel::MaybeUseHTTPSRRForUpgrade [%p] mHTTPSSVCRecord is some",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeUseHTTPSRRForUpgrade [%p] mHTTPSSVCRecord is some"
, this); } } while (0)
750 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeUseHTTPSRRForUpgrade [%p] mHTTPSSVCRecord is some"
, this); } } while (0)
;
751 StoreWaitHTTPSSVCRecord(false);
752 bool hasHTTPSRR = (mHTTPSSVCRecord.ref() != nullptr);
753 return ContinueOnBeforeConnect(hasHTTPSRR, aStatus, hasHTTPSRR);
754 }
755
756 auto dnsStrategy = GetProxyDNSStrategy();
757 if (!(dnsStrategy & DNS_PREFETCH_ORIGIN)) {
758 return ContinueOnBeforeConnect(aShouldUpgrade, aStatus);
759 }
760
761 LOG(("nsHttpChannel::MaybeUseHTTPSRRForUpgrade [%p] wait for HTTPS RR",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeUseHTTPSRRForUpgrade [%p] wait for HTTPS RR"
, this); } } while (0)
762 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeUseHTTPSRRForUpgrade [%p] wait for HTTPS RR"
, this); } } while (0)
;
763
764 OriginAttributes originAttributes;
765 StoragePrincipalHelper::GetOriginAttributesForHTTPSRR(this, originAttributes);
766
767 RefPtr<nsDNSPrefetch> resolver =
768 new nsDNSPrefetch(mURI, originAttributes, nsIRequest::GetTRRMode());
769 nsWeakPtr weakPtrThis(
770 do_GetWeakReference(static_cast<nsIHttpChannel*>(this)));
771 nsresult rv = resolver->FetchHTTPSSVC(
772 mCaps & NS_HTTP_REFRESH_DNS(1 << 3), !LoadUseHTTPSSVC(),
773 [weakPtrThis](nsIDNSHTTPSSVCRecord* aRecord) {
774 nsCOMPtr<nsIHttpChannel> channel = do_QueryReferent(weakPtrThis);
775 RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(channel);
776 if (httpChannelImpl) {
777 httpChannelImpl->OnHTTPSRRAvailable(aRecord);
778 }
779 });
780 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
781 LOG((" FetchHTTPSSVC failed with 0x%08" PRIx32,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " FetchHTTPSSVC failed with 0x%08" "x", static_cast<uint32_t
>(rv)); } } while (0)
782 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " FetchHTTPSSVC failed with 0x%08" "x", static_cast<uint32_t
>(rv)); } } while (0)
;
783 return ContinueOnBeforeConnect(aShouldUpgrade, aStatus);
784 }
785
786 StoreWaitHTTPSSVCRecord(true);
787 return NS_OK;
788}
789
790nsresult nsHttpChannel::ContinueOnBeforeConnect(bool aShouldUpgrade,
791 nsresult aStatus,
792 bool aUpgradeWithHTTPSRR) {
793 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnBeforeConnect " "[this=%p aShouldUpgrade=%d rv=%"
"x" "]\n", this, aShouldUpgrade, static_cast<uint32_t>
(aStatus)); } } while (0)
794 ("nsHttpChannel::ContinueOnBeforeConnect "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnBeforeConnect " "[this=%p aShouldUpgrade=%d rv=%"
"x" "]\n", this, aShouldUpgrade, static_cast<uint32_t>
(aStatus)); } } while (0)
795 "[this=%p aShouldUpgrade=%d rv=%" PRIx32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnBeforeConnect " "[this=%p aShouldUpgrade=%d rv=%"
"x" "]\n", this, aShouldUpgrade, static_cast<uint32_t>
(aStatus)); } } while (0)
796 this, aShouldUpgrade, static_cast<uint32_t>(aStatus)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnBeforeConnect " "[this=%p aShouldUpgrade=%d rv=%"
"x" "]\n", this, aShouldUpgrade, static_cast<uint32_t>
(aStatus)); } } while (0)
;
797
798 MOZ_ASSERT(!LoadWaitHTTPSSVCRecord())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadWaitHTTPSSVCRecord())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadWaitHTTPSSVCRecord())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadWaitHTTPSSVCRecord()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 798); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadWaitHTTPSSVCRecord()"
")"); do { *((volatile int*)__null) = 798; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
799
800 if (NS_FAILED(aStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus)), 0)))) {
801 return aStatus;
802 }
803
804 if (aShouldUpgrade && !mURI->SchemeIs("https")) {
805 // only set HTTPS_RR to be responsbile for the upgrade in the loadinfo
806 // if it actually was responsible, otherwise the correct flag is
807 // already present in the loadinfo.
808 if (aUpgradeWithHTTPSRR) {
809 mLoadInfo->SetHttpsUpgradeTelemetry(nsILoadInfo::HTTPS_RR);
810 }
811 return AsyncCall(&nsHttpChannel::HandleAsyncRedirectChannelToHttps);
812 }
813
814 // ensure that we are using a valid hostname
815 if (!net_IsValidHostName(nsDependentCString(mConnectionInfo->Origin()))) {
816 return NS_ERROR_UNKNOWN_HOST;
817 }
818
819 if (mUpgradeProtocolCallback) {
820 // Websockets can run over HTTP/2, but other upgrades can't.
821 if (mUpgradeProtocol.EqualsLiteral("websocket") &&
822 StaticPrefs::network_http_http2_websockets()) {
823 // Need to tell the conn manager that we're ok with http/2 even with
824 // the allow keepalive bit not set. That bit needs to stay off,
825 // though, in case we end up having to fallback to http/1.1 (where
826 // we absolutely do want to disable keepalive).
827 mCaps |= NS_HTTP_ALLOW_SPDY_WITHOUT_KEEPALIVE(1 << 15);
828 } else {
829 mCaps |= NS_HTTP_DISALLOW_SPDY(1 << 7);
830 }
831 // Upgrades cannot use HTTP/3.
832 mCaps |= NS_HTTP_DISALLOW_HTTP3(1 << 21);
833 // Because NS_HTTP_STICKY_CONNECTION breaks HTTPS RR fallabck mecnahism, we
834 // can not use HTTPS RR for upgrade requests.
835 DisallowHTTPSRR(mCaps);
836 }
837
838 if (LoadIsTRRServiceChannel()) {
839 mCaps |= NS_HTTP_LARGE_KEEPALIVE(1 << 1);
840 DisallowHTTPSRR(mCaps);
841 }
842
843 if (mTransactionSticky) {
844 MOZ_ASSERT(LoadAuthRedirectedChannel())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadAuthRedirectedChannel())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadAuthRedirectedChannel())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("LoadAuthRedirectedChannel()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 844); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadAuthRedirectedChannel()"
")"); do { *((volatile int*)__null) = 844; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
845 // this means this is a redirected channel channel due to auth retry and a
846 // connection based auth scheme was used
847 // we have a reference to the old-transaction with sticky connection which
848 // we need to use
849 mCaps |= NS_HTTP_STICKY_CONNECTION(1 << 2);
850 }
851
852 mCaps |= NS_HTTP_TRR_FLAGS_FROM_MODE(nsIRequest::GetTRRMode())((static_cast<uint32_t>(nsIRequest::GetTRRMode()) &
3) << 19)
;
853
854 // Finalize ConnectionInfo flags before SpeculativeConnect
855 mConnectionInfo->SetAnonymous((mLoadFlags & LOAD_ANONYMOUS) != 0);
856 mConnectionInfo->SetPrivate(mPrivateBrowsing);
857 mConnectionInfo->SetNoSpdy(mCaps & NS_HTTP_DISALLOW_SPDY(1 << 7));
858 mConnectionInfo->SetBeConservative((mCaps & NS_HTTP_BE_CONSERVATIVE(1 << 11)) ||
859 LoadBeConservative());
860 mConnectionInfo->SetTlsFlags(mTlsFlags);
861 mConnectionInfo->SetIsTrrServiceChannel(LoadIsTRRServiceChannel());
862 mConnectionInfo->SetTRRMode(nsIRequest::GetTRRMode());
863 mConnectionInfo->SetIPv4Disabled(mCaps & NS_HTTP_DISABLE_IPV4(1 << 17));
864 mConnectionInfo->SetIPv6Disabled(mCaps & NS_HTTP_DISABLE_IPV6(1 << 18));
865 mConnectionInfo->SetAnonymousAllowClientCert(
866 (mLoadFlags & LOAD_ANONYMOUS_ALLOW_CLIENT_CERT) != 0);
867
868 if (mWebTransportSessionEventListener) {
869 nsTArray<RefPtr<nsIWebTransportHash>> aServerCertHashes;
870 nsresult rv;
871 nsCOMPtr<WebTransportConnectionSettings> wtconSettings =
872 do_QueryInterface(mWebTransportSessionEventListener, &rv);
873 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 873); return rv; } } while (false)
;
874
875 wtconSettings->GetServerCertificateHashes(aServerCertHashes);
876 gHttpHandler->ConnMgr()->StoreServerCertHashes(
877 mConnectionInfo, gHttpHandler->IsHttp2Excluded(mConnectionInfo),
878 !Http3Allowed(), std::move(aServerCertHashes));
879 }
880
881 if (ShouldIntercept()) {
882 return RedirectToInterceptedChannel();
883 }
884
885 // notify "http-on-before-connect" observers
886 gHttpHandler->OnBeforeConnect(this);
887
888 return CallOrWaitForResume([](auto* self) { return self->Connect(); });
889}
890
891class MOZ_STACK_CLASS AddResponseHeadersToResponseHead final
892 : public nsIHttpHeaderVisitor {
893 public:
894 explicit AddResponseHeadersToResponseHead(nsHttpResponseHead* aResponseHead)
895 : mResponseHead(aResponseHead) {}
896
897 NS_IMETHODvirtual nsresult VisitHeader(const nsACString& aHeader,
898 const nsACString& aValue) override {
899 nsAutoCString headerLine = aHeader + ": "_ns + aValue;
900 DebugOnly<nsresult> rv = mResponseHead->ParseHeaderLine(headerLine);
901 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 901); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 901; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
902
903 return NS_OK;
904 }
905
906 NS_IMETHODvirtual nsresult QueryInterface(REFNSIIDconst nsIID& aIID, void** aInstancePtr) override;
907
908 // Stub AddRef/Release since this is a stack class.
909 NS_IMETHOD_(MozExternalRefCountType)virtual MozExternalRefCountType AddRef(void) override {
910 return ++mRefCnt;
911 }
912
913 NS_IMETHOD_(MozExternalRefCountType)virtual MozExternalRefCountType Release(void) override {
914 return --mRefCnt;
915 }
916
917 virtual ~AddResponseHeadersToResponseHead() {
918 MOZ_DIAGNOSTIC_ASSERT(mRefCnt == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRefCnt == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mRefCnt == 0))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mRefCnt == 0", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 918); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mRefCnt == 0"
")"); do { *((volatile int*)__null) = 918; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
919 }
920
921 private:
922 nsHttpResponseHead* mResponseHead;
923
924 nsrefcnt mRefCnt = 0;
925};
926
927NS_IMPL_QUERY_INTERFACE(AddResponseHeadersToResponseHead, nsIHttpHeaderVisitor)nsresult AddResponseHeadersToResponseHead::QueryInterface(const
nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 927); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<AddResponseHeadersToResponseHead, nsIHttpHeaderVisitor
>, int32_t( reinterpret_cast<char*>(static_cast<nsIHttpHeaderVisitor
*>((AddResponseHeadersToResponseHead*)0x1000)) - reinterpret_cast
<char*>((AddResponseHeadersToResponseHead*)0x1000))}, {
&mozilla::detail::kImplementedIID<AddResponseHeadersToResponseHead
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIHttpHeaderVisitor*>
((AddResponseHeadersToResponseHead*)0x1000))) - reinterpret_cast
<char*>((AddResponseHeadersToResponseHead*)0x1000))}, {
nullptr, 0 } } ; static_assert((sizeof(table) / sizeof(table
[0])) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
928
929nsresult nsHttpChannel::HandleOverrideResponse() {
930 // Start building a response with the data from mOverrideResponse.
931 mResponseHead = MakeUnique<nsHttpResponseHead>();
932
933 // Apply override response status code and status text.
934 uint32_t statusCode;
935 nsresult rv = mOverrideResponse->GetResponseStatus(&statusCode);
936 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 936); return rv; } } while (false)
;
937
938 nsAutoCString statusText;
939 rv = mOverrideResponse->GetResponseStatusText(statusText);
940 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 940); return rv; } } while (false)
;
941
942 // Hardcoding protocol HTTP/1.1
943 nsPrintfCString line("HTTP/1.1 %u %s", statusCode, statusText.get());
944 rv = mResponseHead->ParseStatusLine(line);
945 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 945); return rv; } } while (false)
;
946
947 // Apply override response headers.
948 AddResponseHeadersToResponseHead visitor(mResponseHead.get());
949 rv = mOverrideResponse->VisitResponseHeaders(&visitor);
950 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 950); return rv; } } while (false)
;
951
952 if (WillRedirect(*mResponseHead)) {
953 // TODO: Bug 759040 - We should call HandleAsyncRedirect directly here,
954 // to avoid event dispatching latency.
955 LOG(("Skipping read of overridden response redirect entity\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Skipping read of overridden response redirect entity\n"); }
} while (0)
;
956 return AsyncCall(&nsHttpChannel::HandleAsyncRedirect);
957 }
958
959 // Handle Set-Cookie headers as if the response was from networking.
960 if (nsAutoCString cookie;
961 NS_SUCCEEDED(mResponseHead->GetHeader(nsHttp::Set_Cookie, cookie))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mResponseHead->
GetHeader(nsHttp::Set_Cookie, cookie))), 1)))
) {
962 SetCookie(cookie);
963 nsCOMPtr<nsIParentChannel> parentChannel;
964 NS_QueryNotificationCallbacks(this, parentChannel);
965 if (RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel)) {
966 httpParent->SetCookie(std::move(cookie));
967 }
968 }
969
970 rv = ProcessSecurityHeaders();
971 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
972 NS_WARNING("ProcessSecurityHeaders failed, continuing load.")NS_DebugBreak(NS_DEBUG_WARNING, "ProcessSecurityHeaders failed, continuing load."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 972)
;
973 }
974
975 if ((statusCode < 500) && (statusCode != 421)) {
976 ProcessAltService();
977 }
978
979 nsAutoCString body;
980 rv = mOverrideResponse->GetResponseBody(body);
981 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 981); return rv; } } while (false)
;
982
983 nsCOMPtr<nsIInputStream> stringStream;
984 rv = NS_NewCStringInputStream(getter_AddRefs(stringStream), body);
985 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 985); return rv; } } while (false)
;
986 rv = nsInputStreamPump::Create(getter_AddRefs(mCachePump), stringStream, 0, 0,
987 true);
988 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
989 stringStream->Close();
990 return rv;
991 }
992
993 rv = mCachePump->AsyncRead(this);
994 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
995
996 return NS_OK;
997}
998
999nsresult nsHttpChannel::Connect() {
1000 LOG(("nsHttpChannel::Connect [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::Connect [this=%p]\n", this); } } while (0)
;
1001
1002 // If mOverrideResponse is set, bypass the rest of the connection and reply
1003 // immediately with a response built using the data from mOverrideResponse.
1004 if (mOverrideResponse) {
1005 return HandleOverrideResponse();
1006 }
1007
1008 // Don't allow resuming when cache must be used
1009 if (LoadResuming() && (mLoadFlags & LOAD_ONLY_FROM_CACHE)) {
1010 LOG(("Resuming from cache is not supported yet"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Resuming from cache is not supported yet"); } } while (0)
;
1011 return NS_ERROR_DOCUMENT_NOT_CACHED;
1012 }
1013
1014 // Step 8.18 of HTTP-network-or-cache fetch
1015 // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
1016 nsAutoCString rangeVal;
1017 if (NS_SUCCEEDED(GetRequestHeader("Range"_ns, rangeVal))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetRequestHeader(
"Range"_ns, rangeVal))), 1)))
) {
1018 SetRequestHeader("Accept-Encoding"_ns, "identity"_ns, true);
1019 }
1020
1021#ifdef MOZ_WIDGET_ANDROID
1022 bool val = false;
1023 if (nsIOService::ShouldAddAdditionalSearchHeaders(mURI, &val)) {
1024 SetRequestHeader("X-Search-Subdivision"_ns, val ? "1"_ns : "0"_ns, false);
1025 }
1026#endif
1027
1028 bool isTrackingResource = IsThirdPartyTrackingResource();
1029 LOG(("nsHttpChannel %p tracking resource=%d, cos=%lu, inc=%d", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p tracking resource=%d, cos=%lu, inc=%d", this
, isTrackingResource, mClassOfService.Flags(), mClassOfService
.Incremental()); } } while (0)
1030 isTrackingResource, mClassOfService.Flags(),do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p tracking resource=%d, cos=%lu, inc=%d", this
, isTrackingResource, mClassOfService.Flags(), mClassOfService
.Incremental()); } } while (0)
1031 mClassOfService.Incremental()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p tracking resource=%d, cos=%lu, inc=%d", this
, isTrackingResource, mClassOfService.Flags(), mClassOfService
.Incremental()); } } while (0)
;
1032
1033 if (isTrackingResource) {
1034 AddClassFlags(nsIClassOfService::Tail);
1035 }
1036
1037 if (WaitingForTailUnblock()) {
1038 MOZ_DIAGNOSTIC_ASSERT(!mOnTailUnblock)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mOnTailUnblock)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mOnTailUnblock))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mOnTailUnblock"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1038); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mOnTailUnblock"
")"); do { *((volatile int*)__null) = 1038; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1039 mOnTailUnblock = &nsHttpChannel::ConnectOnTailUnblock;
1040 return NS_OK;
1041 }
1042
1043 return ConnectOnTailUnblock();
1044}
1045
1046nsresult nsHttpChannel::ConnectOnTailUnblock() {
1047 nsresult rv;
1048
1049 LOG(("nsHttpChannel::ConnectOnTailUnblock [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ConnectOnTailUnblock [this=%p]\n", this); }
} while (0)
;
1050
1051 // Consider opening a TCP connection right away.
1052 SpeculativeConnect();
1053
1054 // open a cache entry for this channel...
1055 rv = OpenCacheEntry(mURI->SchemeIs("https"));
1056
1057 // do not continue if asyncOpenCacheEntry is in progress
1058 if (AwaitingCacheCallbacks()) {
1059 LOG(("nsHttpChannel::Connect %p AwaitingCacheCallbacks forces async\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::Connect %p AwaitingCacheCallbacks forces async\n"
, this); } } while (0)
1060 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::Connect %p AwaitingCacheCallbacks forces async\n"
, this); } } while (0)
;
1061 MOZ_ASSERT(NS_SUCCEEDED(rv), "Unexpected state")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))" " ("
"Unexpected state" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1061); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
") (" "Unexpected state" ")"); do { *((volatile int*)__null)
= 1061; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
1062
1063 if (mNetworkTriggered && mWaitingForProxy) {
1064 // Someone has called TriggerNetwork(), meaning we are racing the
1065 // network with the cache.
1066 mWaitingForProxy = false;
1067 return ContinueConnect();
1068 }
1069
1070 return NS_OK;
1071 }
1072
1073 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1074 LOG(("OpenCacheEntry failed [rv=%" PRIx32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "OpenCacheEntry failed [rv=%" "x" "]\n", static_cast<uint32_t
>(rv)); } } while (0)
1075 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "OpenCacheEntry failed [rv=%" "x" "]\n", static_cast<uint32_t
>(rv)); } } while (0)
;
1076 // if this channel is only allowed to pull from the cache, then
1077 // we must fail if we were unable to open a cache entry.
1078 if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
1079 return NS_ERROR_DOCUMENT_NOT_CACHED;
1080 }
1081 // otherwise, let's just proceed without using the cache.
1082 }
1083
1084 if (mRaceCacheWithNetwork && ((mCacheEntry && !mCachedContentIsValid &&
1085 (mDidReval || LoadCachedContentIsPartial())) ||
1086 mIgnoreCacheEntry)) {
1087 // We won't send the conditional request because the unconditional
1088 // request was already sent (see bug 1377223).
1089 AccumulateCategorical(
1090 Telemetry::LABELS_NETWORK_RACE_CACHE_VALIDATION::NotSent);
1091 }
1092
1093 // When racing, if OnCacheEntryAvailable is called before AsyncOpenURI
1094 // returns, then we may not have started reading from the cache.
1095 // If the content is valid, we should attempt to do so, as technically the
1096 // cache has won the race.
1097 if (mRaceCacheWithNetwork && mCachedContentIsValid) {
1098 Unused << ReadFromCache();
1099 }
1100
1101 return TriggerNetwork();
1102}
1103
1104nsresult nsHttpChannel::ContinueConnect() {
1105 // If we need to start a CORS preflight, do it now!
1106 // Note that it is important to do this before the early returns below.
1107 if (!LoadIsCorsPreflightDone() && LoadRequireCORSPreflight()) {
1108 MOZ_ASSERT(!mPreflightChannel)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mPreflightChannel)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mPreflightChannel))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mPreflightChannel"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1108); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPreflightChannel"
")"); do { *((volatile int*)__null) = 1108; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1109 nsresult rv = nsCORSListenerProxy::StartCORSPreflight(
1110 this, this, mUnsafeHeaders, getter_AddRefs(mPreflightChannel));
1111 return rv;
1112 }
1113
1114 MOZ_RELEASE_ASSERT(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()" " ("
"CORS preflight must have been finished by the time we " "do the rest of ContinueConnect"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1116); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()"
") (" "CORS preflight must have been finished by the time we "
"do the rest of ContinueConnect" ")"); do { *((volatile int*
)__null) = 1116; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
1115 "CORS preflight must have been finished by the time we "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()" " ("
"CORS preflight must have been finished by the time we " "do the rest of ContinueConnect"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1116); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()"
") (" "CORS preflight must have been finished by the time we "
"do the rest of ContinueConnect" ")"); do { *((volatile int*
)__null) = 1116; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
1116 "do the rest of ContinueConnect")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()" " ("
"CORS preflight must have been finished by the time we " "do the rest of ContinueConnect"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1116); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()"
") (" "CORS preflight must have been finished by the time we "
"do the rest of ContinueConnect" ")"); do { *((volatile int*
)__null) = 1116; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1117
1118 // we may or may not have a cache entry at this point
1119 if (mCacheEntry) {
1120 // read straight from the cache if possible...
1121 if (mCachedContentIsValid) {
1122 nsRunnableMethod<nsHttpChannel>* event = nullptr;
1123 nsresult rv;
1124 if (!LoadCachedContentIsPartial()) {
1125 rv = AsyncCall(&nsHttpChannel::AsyncOnExamineCachedResponse, &event);
1126 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1127 LOG((" AsyncCall failed (%08x)", static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " AsyncCall failed (%08x)", static_cast<uint32_t>(rv
)); } } while (0)
;
1128 }
1129 }
1130 rv = ReadFromCache();
1131 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && event) {
1132 event->Revoke();
1133 }
1134
1135 AccumulateCacheHitTelemetry(kCacheHit, this);
1136 mCacheDisposition = kCacheHit;
1137
1138 return rv;
1139 }
1140 if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
1141 // the cache contains the requested resource, but it must be
1142 // validated before we can reuse it. since we are not allowed
1143 // to hit the net, there's nothing more to do. the document
1144 // is effectively not in the cache.
1145 LOG((" !mCachedContentIsValid && mLoadFlags & LOAD_ONLY_FROM_CACHE"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " !mCachedContentIsValid && mLoadFlags & LOAD_ONLY_FROM_CACHE"
); } } while (0)
;
1146 return NS_ERROR_DOCUMENT_NOT_CACHED;
1147 }
1148 } else if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
1149 LOG((" !mCacheEntry && mLoadFlags & LOAD_ONLY_FROM_CACHE"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " !mCacheEntry && mLoadFlags & LOAD_ONLY_FROM_CACHE"
); } } while (0)
;
1150 return NS_ERROR_DOCUMENT_NOT_CACHED;
1151 }
1152
1153 if (mLoadFlags & LOAD_NO_NETWORK_IO) {
1154 LOG((" mLoadFlags & LOAD_NO_NETWORK_IO"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " mLoadFlags & LOAD_NO_NETWORK_IO"); } } while (0)
;
1155 return NS_ERROR_DOCUMENT_NOT_CACHED;
1156 }
1157
1158 // hit the net...
1159 nsresult rv = DoConnect(mTransactionSticky);
1160 mTransactionSticky = nullptr;
1161 return rv;
1162}
1163
1164nsresult nsHttpChannel::DoConnect(HttpTransactionShell* aTransWithStickyConn) {
1165 LOG(("nsHttpChannel::DoConnect [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::DoConnect [this=%p]\n", this); } } while (0
)
;
1166
1167 if (!mDNSBlockingPromise.IsEmpty()) {
1168 LOG((" waiting for DNS prefetch"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " waiting for DNS prefetch"); } } while (0)
;
1169
1170 // Transaction is passed only from auth retry for which we will definitely
1171 // not block on DNS to alter the origin server name for IP; it has already
1172 // been done.
1173 MOZ_ASSERT(!aTransWithStickyConn)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aTransWithStickyConn)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aTransWithStickyConn))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!aTransWithStickyConn"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1173); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aTransWithStickyConn"
")"); do { *((volatile int*)__null) = 1173; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1174 MOZ_ASSERT(mDNSBlockingThenable)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mDNSBlockingThenable)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mDNSBlockingThenable))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mDNSBlockingThenable"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1174); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDNSBlockingThenable"
")"); do { *((volatile int*)__null) = 1174; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1175
1176 nsCOMPtr<nsISerialEventTarget> target(do_GetMainThread());
1177 RefPtr<nsHttpChannel> self(this);
1178 mDNSBlockingThenable->Then(
1179 target, __func__,
1180 [self](const nsCOMPtr<nsIDNSRecord>& aRec) {
1181 nsresult rv = self->DoConnectActual(nullptr);
1182 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1183 self->CloseCacheEntry(false);
1184 Unused << self->AsyncAbort(rv);
1185 }
1186 },
1187 [self](nsresult err) {
1188 self->CloseCacheEntry(false);
1189 Unused << self->AsyncAbort(err);
1190 });
1191
1192 // The connection will continue when the promise is resolved in
1193 // OnLookupComplete.
1194 return NS_OK;
1195 }
1196
1197 return DoConnectActual(aTransWithStickyConn);
1198}
1199
1200nsresult nsHttpChannel::DoConnectActual(
1201 HttpTransactionShell* aTransWithStickyConn) {
1202 LOG(("nsHttpChannel::DoConnectActual [this=%p, aTransWithStickyConn=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::DoConnectActual [this=%p, aTransWithStickyConn=%p]\n"
, this, aTransWithStickyConn); } } while (0)
1203 this, aTransWithStickyConn))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::DoConnectActual [this=%p, aTransWithStickyConn=%p]\n"
, this, aTransWithStickyConn); } } while (0)
;
1204
1205 nsresult rv = SetupChannelForTransaction();
1206 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1207 return rv;
1208 }
1209
1210 return DispatchTransaction(aTransWithStickyConn);
1211}
1212
1213nsresult nsHttpChannel::DispatchTransaction(
1214 HttpTransactionShell* aTransWithStickyConn) {
1215 LOG(("nsHttpChannel::DispatchTransaction [this=%p, aTransWithStickyConn=%p]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::DispatchTransaction [this=%p, aTransWithStickyConn=%p]"
, this, aTransWithStickyConn); } } while (0)
1216 this, aTransWithStickyConn))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::DispatchTransaction [this=%p, aTransWithStickyConn=%p]"
, this, aTransWithStickyConn); } } while (0)
;
1217 nsresult rv = InitTransaction();
1218 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1219 return rv;
1220 }
1221 if (aTransWithStickyConn) {
1222 rv = gHttpHandler->InitiateTransactionWithStickyConn(
1223 mTransaction, mPriority, aTransWithStickyConn);
1224 } else {
1225 rv = gHttpHandler->InitiateTransaction(mTransaction, mPriority);
1226 }
1227
1228 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1229 return rv;
1230 }
1231
1232 rv = mTransaction->AsyncRead(this, getter_AddRefs(mTransactionPump));
1233 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1234 return rv;
1235 }
1236
1237 uint32_t suspendCount = mSuspendCount;
1238 if (LoadAsyncResumePending()) {
1239 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Suspend()'ing transaction pump once because of async resume pending"
", sc=%u, pump=%p, this=%p", suspendCount, mTransactionPump.
get(), this); } } while (0)
1240 (" Suspend()'ing transaction pump once because of async resume pending"do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Suspend()'ing transaction pump once because of async resume pending"
", sc=%u, pump=%p, this=%p", suspendCount, mTransactionPump.
get(), this); } } while (0)
1241 ", sc=%u, pump=%p, this=%p",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Suspend()'ing transaction pump once because of async resume pending"
", sc=%u, pump=%p, this=%p", suspendCount, mTransactionPump.
get(), this); } } while (0)
1242 suspendCount, mTransactionPump.get(), this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Suspend()'ing transaction pump once because of async resume pending"
", sc=%u, pump=%p, this=%p", suspendCount, mTransactionPump.
get(), this); } } while (0)
;
1243 ++suspendCount;
1244 }
1245 while (suspendCount--) {
1246 mTransactionPump->Suspend();
1247 }
1248
1249 return NS_OK;
1250}
1251
1252void nsHttpChannel::SpeculativeConnect() {
1253 // Before we take the latency hit of dealing with the cache, try and
1254 // get the TCP (and SSL) handshakes going so they can overlap.
1255
1256 // don't speculate if we are offline, when doing http upgrade (i.e.
1257 // websockets bootstrap), or if we can't do keep-alive (because then we
1258 // couldn't reuse the speculative connection anyhow).
1259 RefPtr<mozilla::dom::BrowsingContext> bc;
1260 mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
1261
1262 if (gIOService->IsOffline() || mUpgradeProtocolCallback ||
1263 !(mCaps & NS_HTTP_ALLOW_KEEPALIVE(1 << 0)) ||
1264 (bc && bc->Top()->GetForceOffline())) {
1265 return;
1266 }
1267
1268 // LOAD_ONLY_FROM_CACHE and LOAD_NO_NETWORK_IO must not hit network.
1269 // LOAD_FROM_CACHE is unlikely to hit network, so skip preconnects for it.
1270 if (mLoadFlags &
1271 (LOAD_ONLY_FROM_CACHE | LOAD_FROM_CACHE | LOAD_NO_NETWORK_IO)) {
1272 return;
1273 }
1274
1275 if (LoadAllowStaleCacheContent()) {
1276 return;
1277 }
1278
1279 nsCOMPtr<nsIInterfaceRequestor> callbacks;
1280 NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
1281 getter_AddRefs(callbacks));
1282 if (!callbacks) return;
1283
1284 Unused << gHttpHandler->SpeculativeConnect(
1285 mConnectionInfo, callbacks,
1286 mCaps & (NS_HTTP_DISALLOW_SPDY(1 << 7) | NS_HTTP_TRR_MODE_MASK((1 << 19) | (1 << 20)) |
1287 NS_HTTP_DISABLE_IPV4(1 << 17) | NS_HTTP_DISABLE_IPV6(1 << 18) |
1288 NS_HTTP_DISALLOW_HTTP3(1 << 21) | NS_HTTP_REFRESH_DNS(1 << 3)),
1289 gHttpHandler->EchConfigEnabled());
1290}
1291
1292void nsHttpChannel::DoNotifyListenerCleanup() {
1293 // We don't need this info anymore
1294 CleanRedirectCacheChainIfNecessary();
1295}
1296
1297void nsHttpChannel::ReleaseListeners() {
1298 HttpBaseChannel::ReleaseListeners();
1299 mChannelClassifier = nullptr;
1300 mWarningReporter = nullptr;
1301 mEarlyHintObserver = nullptr;
1302 mWebTransportSessionEventListener = nullptr;
1303
1304 for (StreamFilterRequest& request : mStreamFilterRequests) {
1305 request.mPromise->Reject(false, __func__);
1306 }
1307 mStreamFilterRequests.Clear();
1308}
1309
1310void nsHttpChannel::DoAsyncAbort(nsresult aStatus) {
1311 Unused << AsyncAbort(aStatus);
1312}
1313
1314void nsHttpChannel::HandleAsyncRedirect() {
1315 MOZ_ASSERT(!mCallOnResume, "How did that happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCallOnResume)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mCallOnResume))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mCallOnResume"
" (" "How did that happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1315); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 1315; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
1316
1317 if (mSuspendCount) {
1318 LOG(("Waiting until resume to do async redirect [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to do async redirect [this=%p]\n", this
); } } while (0)
;
1319 mCallOnResume = [](nsHttpChannel* self) {
1320 self->HandleAsyncRedirect();
1321 return NS_OK;
1322 };
1323 return;
1324 }
1325
1326 nsresult rv = NS_OK;
1327
1328 LOG(("nsHttpChannel::HandleAsyncRedirect [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::HandleAsyncRedirect [this=%p]\n", this); } }
while (0)
;
1329
1330 // since this event is handled asynchronously, it is possible that this
1331 // channel could have been canceled, in which case there would be no point
1332 // in processing the redirect.
1333 if (NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1)))) {
1334 PushRedirectAsyncFunc(&nsHttpChannel::ContinueHandleAsyncRedirect);
1335 rv = AsyncProcessRedirection(mResponseHead->Status());
1336 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1337 PopRedirectAsyncFunc(&nsHttpChannel::ContinueHandleAsyncRedirect);
1338 // TODO: if !DoNotRender3xxBody(), render redirect body instead.
1339 // But first we need to cache 3xx bodies (bug 748510)
1340 rv = ContinueHandleAsyncRedirect(rv);
1341 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1341); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1341; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1342 }
1343 } else {
1344 rv = ContinueHandleAsyncRedirect(mStatus);
1345 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1345); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1345; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1346 }
1347}
1348
1349nsresult nsHttpChannel::ContinueHandleAsyncRedirect(nsresult rv) {
1350 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1351 // If AsyncProcessRedirection fails, then we have to send out the
1352 // OnStart/OnStop notifications.
1353 LOG(("ContinueHandleAsyncRedirect got failure result [rv=%" PRIx32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueHandleAsyncRedirect got failure result [rv=%" "x" "]\n"
, static_cast<uint32_t>(rv)); } } while (0)
1354 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueHandleAsyncRedirect got failure result [rv=%" "x" "]\n"
, static_cast<uint32_t>(rv)); } } while (0)
;
1355
1356 bool redirectsEnabled = !mLoadInfo->GetDontFollowRedirects();
1357
1358 if (redirectsEnabled) {
1359 // TODO: stop failing original channel if redirect vetoed?
1360 mStatus = rv;
1361
1362 DoNotifyListener();
1363
1364 // Blow away cache entry if we couldn't process the redirect
1365 // for some reason (the cache entry might be corrupt).
1366 if (mCacheEntry) {
1367 mCacheEntry->AsyncDoom(nullptr);
1368 }
1369 } else {
1370 DoNotifyListener();
1371 }
1372 }
1373
1374 CloseCacheEntry(true);
1375
1376 StoreIsPending(false);
1377
1378 if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, mStatus);
1379
1380 return NS_OK;
1381}
1382
1383void nsHttpChannel::HandleAsyncNotModified() {
1384 MOZ_ASSERT(!mCallOnResume, "How did that happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCallOnResume)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mCallOnResume))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mCallOnResume"
" (" "How did that happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1384); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 1384; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
1385
1386 if (mSuspendCount) {
1387 LOG(("Waiting until resume to do async not-modified [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to do async not-modified [this=%p]\n"
, this); } } while (0)
;
1388 mCallOnResume = [](nsHttpChannel* self) {
1389 self->HandleAsyncNotModified();
1390 return NS_OK;
1391 };
1392 return;
1393 }
1394
1395 LOG(("nsHttpChannel::HandleAsyncNotModified [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::HandleAsyncNotModified [this=%p]\n", this);
} } while (0)
;
1396
1397 DoNotifyListener();
1398
1399 CloseCacheEntry(false);
1400
1401 StoreIsPending(false);
1402
1403 if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, mStatus);
1404}
1405
1406nsresult nsHttpChannel::SetupChannelForTransaction() {
1407 LOG((do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetupChannelForTransaction [this=%p, cos=%lu, inc=%d "
"prio=%d]\n", this, mClassOfService.Flags(), mClassOfService
.Incremental(), mPriority); } } while (0)
1408 "nsHttpChannel::SetupChannelForTransaction [this=%p, cos=%lu, inc=%d "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetupChannelForTransaction [this=%p, cos=%lu, inc=%d "
"prio=%d]\n", this, mClassOfService.Flags(), mClassOfService
.Incremental(), mPriority); } } while (0)
1409 "prio=%d]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetupChannelForTransaction [this=%p, cos=%lu, inc=%d "
"prio=%d]\n", this, mClassOfService.Flags(), mClassOfService
.Incremental(), mPriority); } } while (0)
1410 this, mClassOfService.Flags(), mClassOfService.Incremental(), mPriority))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetupChannelForTransaction [this=%p, cos=%lu, inc=%d "
"prio=%d]\n", this, mClassOfService.Flags(), mClassOfService
.Incremental(), mPriority); } } while (0)
;
1411
1412 NS_ENSURE_TRUE(!mTransaction, NS_ERROR_ALREADY_INITIALIZED)do { if ((__builtin_expect(!!(!(!mTransaction)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!mTransaction" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1412); return NS_ERROR_ALREADY_INITIALIZED; } } while (false
)
;
1413
1414 nsresult rv;
1415
1416 mozilla::MutexAutoLock lock(mRCWNLock);
1417
1418 if (StaticPrefs::network_http_priority_header_enabled()) {
1419 SetPriorityHeader();
1420 }
1421
1422 // If we're racing cache with network, conditional or byte range header
1423 // could be added in OnCacheEntryCheck. We cannot send conditional request
1424 // without having the entry, so we need to remove the headers here and
1425 // ignore the cache entry in OnCacheEntryAvailable.
1426 if (mRaceCacheWithNetwork && AwaitingCacheCallbacks()) {
1427 if (mDidReval) {
1428 LOG((" Removing conditional request headers"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Removing conditional request headers"); } } while (0)
;
1429 UntieValidationRequest();
1430 mDidReval = false;
1431 mIgnoreCacheEntry = true;
1432 }
1433
1434 if (LoadCachedContentIsPartial()) {
1435 LOG((" Removing byte range request headers"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Removing byte range request headers"); } } while (0)
;
1436 UntieByteRangeRequest();
1437 StoreCachedContentIsPartial(false);
1438 mIgnoreCacheEntry = true;
1439 }
1440
1441 if (mIgnoreCacheEntry) {
1442 mAvailableCachedAltDataType.Truncate();
1443 StoreDeliveringAltData(false);
1444 mAltDataLength = -1;
1445 mCacheInputStream.CloseAndRelease();
1446 }
1447 }
1448
1449 StoreUsedNetwork(1);
1450
1451 if (!LoadAllowSpdy()) {
1452 mCaps |= NS_HTTP_DISALLOW_SPDY(1 << 7);
1453 }
1454 if (!LoadAllowHttp3()) {
1455 mCaps |= NS_HTTP_DISALLOW_HTTP3(1 << 21);
1456 }
1457 if (LoadBeConservative()) {
1458 mCaps |= NS_HTTP_BE_CONSERVATIVE(1 << 11);
1459 }
1460
1461 if (mLoadFlags & LOAD_ANONYMOUS_ALLOW_CLIENT_CERT) {
1462 mCaps |= NS_HTTP_LOAD_ANONYMOUS_CONNECT_ALLOW_CLIENT_CERT(1 << 23);
1463 }
1464
1465 if (nsContentUtils::ShouldResistFingerprinting(this,
1466 RFPTarget::HttpUserAgent)) {
1467 mCaps |= NS_HTTP_USE_RFP(1 << 26);
1468 }
1469
1470 // Use the URI path if not proxying (transparent proxying such as proxy
1471 // CONNECT does not count here). Also figure out what HTTP version to use.
1472 nsAutoCString buf, path;
1473 nsCString* requestURI;
1474
1475 // This is the normal e2e H1 path syntax "/index.html"
1476 rv = mURI->GetPathQueryRef(path);
1477 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1478 return rv;
1479 }
1480
1481 // path may contain UTF-8 characters, so ensure that they're escaped.
1482 if (NS_EscapeURL(path.get(), path.Length(), esc_OnlyNonASCII | esc_Spaces,
1483 buf)) {
1484 requestURI = &buf;
1485 } else {
1486 requestURI = &path;
1487 }
1488
1489 // trim off the #ref portion if any...
1490 int32_t ref1 = requestURI->FindChar('#');
1491 if (ref1 != kNotFound) {
1492 requestURI->SetLength(ref1);
1493 }
1494
1495 if (mConnectionInfo->UsingConnect() || !mConnectionInfo->UsingHttpProxy()) {
1496 mRequestHead.SetVersion(gHttpHandler->HttpVersion());
1497 } else {
1498 mRequestHead.SetPath(*requestURI);
1499
1500 // RequestURI should be the absolute uri H1 proxy syntax
1501 // "http://foo/index.html" so we will overwrite the relative version in
1502 // requestURI
1503 rv = mURI->GetUserPass(buf);
1504 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
1505 if (!buf.IsEmpty() && ((strncmp(mSpec.get(), "http:", 5) == 0) ||
1506 strncmp(mSpec.get(), "https:", 6) == 0)) {
1507 nsCOMPtr<nsIURI> tempURI = nsIOService::CreateExposableURI(mURI);
1508 rv = tempURI->GetAsciiSpec(path);
1509 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
1510 requestURI = &path;
1511 } else {
1512 requestURI = &mSpec;
1513 }
1514
1515 // trim off the #ref portion if any...
1516 int32_t ref2 = requestURI->FindChar('#');
1517 if (ref2 != kNotFound) {
1518 requestURI->SetLength(ref2);
1519 }
1520
1521 mRequestHead.SetVersion(gHttpHandler->ProxyHttpVersion());
1522 }
1523
1524 mRequestHead.SetRequestURI(*requestURI);
1525
1526 // set the request time for cache expiration calculations
1527 mRequestTime = NowInSeconds()PRTimeToSeconds(PR_Now());
1528 StoreRequestTimeInitialized(true);
1529
1530 // if doing a reload, force end-to-end
1531 if (mLoadFlags & LOAD_BYPASS_CACHE) {
1532 // We need to send 'Pragma:no-cache' to inhibit proxy caching even if
1533 // no proxy is configured since we might be talking with a transparent
1534 // proxy, i.e. one that operates at the network level. See bug #14772.
1535 // But we should not touch Pragma if Cache-Control is already set
1536 // (https://fetch.spec.whatwg.org/#ref-for-concept-request-cache-mode%E2%91%A3)
1537 if (!mRequestHead.HasHeader(nsHttp::Pragma)) {
1538 rv = mRequestHead.SetHeaderOnce(nsHttp::Pragma, "no-cache", true);
1539 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1539); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1539; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1540 }
1541 // If we're configured to speak HTTP/1.1 then also send 'Cache-control:
1542 // no-cache'. But likewise don't touch Cache-Control if it's already set.
1543 if (mRequestHead.Version() >= HttpVersion::v1_1 &&
1544 !mRequestHead.HasHeader(nsHttp::Cache_Control)) {
1545 rv = mRequestHead.SetHeaderOnce(nsHttp::Cache_Control, "no-cache", true);
1546 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1546); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1546; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1547 }
1548 } else if (mLoadFlags & VALIDATE_ALWAYS) {
1549 // We need to send 'Cache-Control: max-age=0' to force each cache along
1550 // the path to the origin server to revalidate its own entry, if any,
1551 // with the next cache or server. See bug #84847.
1552 //
1553 // If we're configured to speak HTTP/1.0 then just send 'Pragma: no-cache'
1554 //
1555 // But don't send the headers if they're already set:
1556 // https://fetch.spec.whatwg.org/#ref-for-concept-request-cache-mode%E2%91%A2
1557 if (mRequestHead.Version() >= HttpVersion::v1_1) {
1558 if (!mRequestHead.HasHeader(nsHttp::Cache_Control)) {
1559 rv = mRequestHead.SetHeaderOnce(nsHttp::Cache_Control, "max-age=0",
1560 true);
1561 }
1562 } else {
1563 if (!mRequestHead.HasHeader(nsHttp::Pragma)) {
1564 rv = mRequestHead.SetHeaderOnce(nsHttp::Pragma, "no-cache", true);
1565 }
1566 }
1567 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1567); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1567; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1568 }
1569
1570 if (LoadResuming()) {
1571 char byteRange[32];
1572 SprintfLiteral(byteRange, "bytes=%" PRIu64"l" "u" "-", mStartPos);
1573 rv = mRequestHead.SetHeader(nsHttp::Range, nsDependentCString(byteRange));
1574 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1574); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1574; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1575
1576 if (!mEntityID.IsEmpty()) {
1577 // Also, we want an error if this resource changed in the meantime
1578 // Format of the entity id is: escaped_etag/size/lastmod
1579 nsCString::const_iterator start, end, slash;
1580 mEntityID.BeginReading(start);
1581 mEntityID.EndReading(end);
1582 mEntityID.BeginReading(slash);
1583
1584 if (FindCharInReadable('/', slash, end)) {
1585 nsAutoCString ifMatch;
1586 rv = mRequestHead.SetHeader(
1587 nsHttp::If_Match,
1588 NS_UnescapeURL(Substring(start, slash), 0, ifMatch));
1589 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1589); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1589; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1590
1591 ++slash; // Incrementing, so that searching for '/' won't find
1592 // the same slash again
1593 }
1594
1595 if (FindCharInReadable('/', slash, end)) {
1596 rv = mRequestHead.SetHeader(nsHttp::If_Unmodified_Since,
1597 Substring(++slash, end));
1598 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1598); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1598; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1599 }
1600 }
1601 }
1602
1603 // See bug #466080. Transfer LOAD_ANONYMOUS flag to socket-layer.
1604 if (mLoadFlags & LOAD_ANONYMOUS) mCaps |= NS_HTTP_LOAD_ANONYMOUS(1 << 4);
1605
1606 if (LoadTimingEnabled()) mCaps |= NS_HTTP_TIMING_ENABLED(1 << 5);
1607
1608 if (mUpgradeProtocolCallback) {
1609 rv = mRequestHead.SetHeader(nsHttp::Upgrade, mUpgradeProtocol, false);
1610 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1610; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1611 rv = mRequestHead.SetHeaderOnce(nsHttp::Connection, nsHttp::Upgrade.get(),
1612 true);
1613 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1613); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1613; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1614 mCaps |= NS_HTTP_STICKY_CONNECTION(1 << 2);
1615 mCaps &= ~NS_HTTP_ALLOW_KEEPALIVE(1 << 0);
1616 }
1617
1618 if (mWebTransportSessionEventListener) {
1619 mCaps |= NS_HTTP_STICKY_CONNECTION(1 << 2);
1620 }
1621
1622 return NS_OK;
1623}
1624
1625nsresult nsHttpChannel::InitTransaction() {
1626 nsresult rv;
1627 // create wrapper for this channel's notification callbacks
1628 nsCOMPtr<nsIInterfaceRequestor> callbacks;
1629 NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
1630 getter_AddRefs(callbacks));
1631
1632 // create the transaction object
1633 if (nsIOService::UseSocketProcess()) {
1634 if (NS_WARN_IF(!gIOService->SocketProcessReady())NS_warn_if_impl(!gIOService->SocketProcessReady(), "!gIOService->SocketProcessReady()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1634)
) {
1635 return NS_ERROR_NOT_AVAILABLE;
1636 }
1637 SocketProcessParent* socketProcess = SocketProcessParent::GetSingleton();
1638 if (!socketProcess->CanSend()) {
1639 return NS_ERROR_NOT_AVAILABLE;
1640 }
1641
1642 nsCOMPtr<nsIParentChannel> parentChannel;
1643 NS_QueryNotificationCallbacks(this, parentChannel);
1644 RefPtr<DocumentLoadListener> documentChannelParent =
1645 do_QueryObject(parentChannel);
1646 // See HttpTransactionChild::CanSendODAToContentProcessDirectly() and
1647 // nsHttpChannel::CallOnStartRequest() for the reason why we need to know if
1648 // this is a document load. We only send ODA directly to child process for
1649 // non document loads.
1650 RefPtr<HttpTransactionParent> transParent =
1651 new HttpTransactionParent(!!documentChannelParent);
1652 LOG1(("nsHttpChannel %p created HttpTransactionParent %p\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla::
detail::log_print(moz_real_module, mozilla::LogLevel::Error, "nsHttpChannel %p created HttpTransactionParent %p\n"
, this, transParent.get()); } } while (0)
1653 transParent.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla::
detail::log_print(moz_real_module, mozilla::LogLevel::Error, "nsHttpChannel %p created HttpTransactionParent %p\n"
, this, transParent.get()); } } while (0)
;
1654
1655 // Since OnStopRequest could be sent to child process from socket process
1656 // directly, we need to store these two values in HttpTransactionChild and
1657 // forward to child process until HttpTransactionChild::OnStopRequest is
1658 // called.
1659 transParent->SetRedirectTimestamp(mRedirectStartTimeStamp,
1660 mRedirectEndTimeStamp);
1661
1662 if (socketProcess) {
1663 MOZ_ALWAYS_TRUE(do { if ((__builtin_expect(!!(socketProcess->SendPHttpTransactionConstructor
(transParent)), 1))) { } else { do { static_assert( mozilla::
detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "socketProcess->SendPHttpTransactionConstructor(transParent)"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1664); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "socketProcess->SendPHttpTransactionConstructor(transParent)"
")"); do { *((volatile int*)__null) = 1664; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1664 socketProcess->SendPHttpTransactionConstructor(transParent))do { if ((__builtin_expect(!!(socketProcess->SendPHttpTransactionConstructor
(transParent)), 1))) { } else { do { static_assert( mozilla::
detail::AssertionConditionType<decltype(false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "socketProcess->SendPHttpTransactionConstructor(transParent)"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1664); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "socketProcess->SendPHttpTransactionConstructor(transParent)"
")"); do { *((volatile int*)__null) = 1664; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1665 }
1666 mTransaction = transParent;
1667 } else {
1668 mTransaction = new nsHttpTransaction();
1669 LOG1(("nsHttpChannel %p created nsHttpTransaction %p\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla::
detail::log_print(moz_real_module, mozilla::LogLevel::Error, "nsHttpChannel %p created nsHttpTransaction %p\n"
, this, mTransaction.get()); } } while (0)
1670 mTransaction.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Error)), 0))) { mozilla::
detail::log_print(moz_real_module, mozilla::LogLevel::Error, "nsHttpChannel %p created nsHttpTransaction %p\n"
, this, mTransaction.get()); } } while (0)
;
1671 }
1672
1673 // Save the mapping of channel id and the channel. We need this mapping for
1674 // nsIHttpActivityObserver.
1675 gHttpHandler->AddHttpChannel(mChannelId, ToSupports(this));
1676
1677 nsCOMPtr<nsIHttpPushListener> pushListener;
1678 NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
1679 NS_GET_IID(nsIHttpPushListener)(nsIHttpPushListener::COMTypeInfo<nsIHttpPushListener, void
>::kIID)
,
1680 getter_AddRefs(pushListener));
1681 HttpTransactionShell::OnPushCallback pushCallback = nullptr;
1682 if (pushListener) {
1683 mCaps |= NS_HTTP_ONPUSH_LISTENER(1 << 9);
1684 nsWeakPtr weakPtrThis(
1685 do_GetWeakReference(static_cast<nsIHttpChannel*>(this)));
1686 pushCallback = [weakPtrThis](uint32_t aPushedStreamId,
1687 const nsACString& aUrl,
1688 const nsACString& aRequestString,
1689 HttpTransactionShell* aTransaction) {
1690 if (nsCOMPtr<nsIHttpChannel> channel = do_QueryReferent(weakPtrThis)) {
1691 return static_cast<nsHttpChannel*>(channel.get())
1692 ->OnPush(aPushedStreamId, aUrl, aRequestString, aTransaction);
1693 }
1694 return NS_ERROR_NOT_AVAILABLE;
1695 };
1696 }
1697
1698 EnsureBrowserId();
1699 EnsureRequestContext();
1700
1701 HttpTrafficCategory category = CreateTrafficCategory();
1702 std::function<void(TransactionObserverResult&&)> observer;
1703 if (mTransactionObserver) {
1704 observer = [transactionObserver{std::move(mTransactionObserver)}](
1705 TransactionObserverResult&& aResult) {
1706 transactionObserver->Complete(aResult.versionOk(), aResult.authOk(),
1707 aResult.closeReason());
1708 };
1709 }
1710 mTransaction->SetIsForWebTransport(!!mWebTransportSessionEventListener);
1711 rv = mTransaction->Init(
1712 mCaps, mConnectionInfo, &mRequestHead, mUploadStream, mReqContentLength,
1713 LoadUploadStreamHasHeaders(), GetCurrentSerialEventTarget(), callbacks,
1714 this, mBrowserId, category, mRequestContext, mClassOfService,
1715 mInitialRwin, LoadResponseTimeoutEnabled(), mChannelId,
1716 std::move(observer), std::move(pushCallback), mTransWithPushedStream,
1717 mPushedStreamId);
1718 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1719 mTransaction = nullptr;
1720 return rv;
1721 }
1722
1723 return rv;
1724}
1725
1726HttpTrafficCategory nsHttpChannel::CreateTrafficCategory() {
1727 MOZ_ASSERT(!mFirstPartyClassificationFlags ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1728); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
")"); do { *((volatile int*)__null) = 1728; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1728 !mThirdPartyClassificationFlags)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1728); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
")"); do { *((volatile int*)__null) = 1728; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1729
1730 if (!StaticPrefs::network_traffic_analyzer_enabled()) {
1731 return HttpTrafficCategory::eInvalid;
1732 }
1733
1734 HttpTrafficAnalyzer::ClassOfService cos;
1735 {
1736 if ((mClassOfService.Flags() & nsIClassOfService::Leader) &&
1737 mLoadInfo->GetExternalContentPolicyType() ==
1738 ExtContentPolicy::TYPE_SCRIPT) {
1739 cos = HttpTrafficAnalyzer::ClassOfService::eLeader;
1740 } else if (mLoadFlags & nsIRequest::LOAD_BACKGROUND) {
1741 cos = HttpTrafficAnalyzer::ClassOfService::eBackground;
1742 } else {
1743 cos = HttpTrafficAnalyzer::ClassOfService::eOther;
1744 }
1745 }
1746
1747 bool isThirdParty = AntiTrackingUtils::IsThirdPartyChannel(this);
1748
1749 HttpTrafficAnalyzer::TrackingClassification tc;
1750 {
1751 uint32_t flags = isThirdParty ? mThirdPartyClassificationFlags
1752 : mFirstPartyClassificationFlags;
1753
1754 using CF = nsIClassifiedChannel::ClassificationFlags;
1755 using TC = HttpTrafficAnalyzer::TrackingClassification;
1756
1757 if (flags & CF::CLASSIFIED_TRACKING_CONTENT) {
1758 tc = TC::eContent;
1759 } else if (flags & CF::CLASSIFIED_FINGERPRINTING_CONTENT) {
1760 tc = TC::eFingerprinting;
1761 } else if (flags & CF::CLASSIFIED_ANY_BASIC_TRACKING) {
1762 tc = TC::eBasic;
1763 } else {
1764 tc = TC::eNone;
1765 }
1766 }
1767
1768 bool isSystemPrincipal =
1769 mLoadInfo->GetLoadingPrincipal() &&
1770 mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal();
1771 return HttpTrafficAnalyzer::CreateTrafficCategory(
1772 NS_UsePrivateBrowsing(this), isSystemPrincipal, isThirdParty, cos, tc);
1773}
1774
1775void nsHttpChannel::SetCachedContentType() {
1776 if (!mResponseHead) {
1777 return;
1778 }
1779
1780 nsAutoCString contentTypeStr;
1781 mResponseHead->ContentType(contentTypeStr);
1782
1783 uint8_t contentType = nsICacheEntry::CONTENT_TYPE_OTHER;
1784 if (nsContentUtils::IsJavascriptMIMEType(
1785 NS_ConvertUTF8toUTF16(contentTypeStr))) {
1786 contentType = nsICacheEntry::CONTENT_TYPE_JAVASCRIPT;
1787 } else if (StringBeginsWith(contentTypeStr, "text/css"_ns) ||
1788 (mLoadInfo->GetExternalContentPolicyType() ==
1789 ExtContentPolicy::TYPE_STYLESHEET)) {
1790 contentType = nsICacheEntry::CONTENT_TYPE_STYLESHEET;
1791 } else if (StringBeginsWith(contentTypeStr, "application/wasm"_ns)) {
1792 contentType = nsICacheEntry::CONTENT_TYPE_WASM;
1793 } else if (StringBeginsWith(contentTypeStr, "image/"_ns)) {
1794 contentType = nsICacheEntry::CONTENT_TYPE_IMAGE;
1795 } else if (StringBeginsWith(contentTypeStr, "video/"_ns)) {
1796 contentType = nsICacheEntry::CONTENT_TYPE_MEDIA;
1797 } else if (StringBeginsWith(contentTypeStr, "audio/"_ns)) {
1798 contentType = nsICacheEntry::CONTENT_TYPE_MEDIA;
1799 }
1800
1801 mCacheEntry->SetContentType(contentType);
1802}
1803
1804nsresult nsHttpChannel::CallOnStartRequest() {
1805 LOG(("nsHttpChannel::CallOnStartRequest [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnStartRequest [this=%p]", this); } } while
(0)
;
1806
1807 MOZ_RELEASE_ASSERT(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()" " ("
"CORS preflight must have been finished by the time we " "call OnStartRequest"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1809); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()"
") (" "CORS preflight must have been finished by the time we "
"call OnStartRequest" ")"); do { *((volatile int*)__null) = 1809
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
1808 "CORS preflight must have been finished by the time we "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()" " ("
"CORS preflight must have been finished by the time we " "call OnStartRequest"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1809); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()"
") (" "CORS preflight must have been finished by the time we "
"call OnStartRequest" ")"); do { *((volatile int*)__null) = 1809
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
1809 "call OnStartRequest")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()" " ("
"CORS preflight must have been finished by the time we " "call OnStartRequest"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1809); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()"
") (" "CORS preflight must have been finished by the time we "
"call OnStartRequest" ")"); do { *((volatile int*)__null) = 1809
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
1810
1811 MOZ_RELEASE_ASSERT(mCanceled || LoadProcessCrossOriginSecurityHeadersCalled(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCanceled || LoadProcessCrossOriginSecurityHeadersCalled
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mCanceled || LoadProcessCrossOriginSecurityHeadersCalled
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mCanceled || LoadProcessCrossOriginSecurityHeadersCalled()"
" (" "Security headers need to have been processed before " "calling CallOnStartRequest"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1813); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mCanceled || LoadProcessCrossOriginSecurityHeadersCalled()"
") (" "Security headers need to have been processed before "
"calling CallOnStartRequest" ")"); do { *((volatile int*)__null
) = 1813; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
1812 "Security headers need to have been processed before "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCanceled || LoadProcessCrossOriginSecurityHeadersCalled
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mCanceled || LoadProcessCrossOriginSecurityHeadersCalled
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mCanceled || LoadProcessCrossOriginSecurityHeadersCalled()"
" (" "Security headers need to have been processed before " "calling CallOnStartRequest"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1813); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mCanceled || LoadProcessCrossOriginSecurityHeadersCalled()"
") (" "Security headers need to have been processed before "
"calling CallOnStartRequest" ")"); do { *((volatile int*)__null
) = 1813; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
1813 "calling CallOnStartRequest")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCanceled || LoadProcessCrossOriginSecurityHeadersCalled
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mCanceled || LoadProcessCrossOriginSecurityHeadersCalled
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mCanceled || LoadProcessCrossOriginSecurityHeadersCalled()"
" (" "Security headers need to have been processed before " "calling CallOnStartRequest"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1813); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mCanceled || LoadProcessCrossOriginSecurityHeadersCalled()"
") (" "Security headers need to have been processed before "
"calling CallOnStartRequest" ")"); do { *((volatile int*)__null
) = 1813; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
1814
1815 mEarlyHintObserver = nullptr;
1816
1817 if (LoadOnStartRequestCalled()) {
1818 // This can only happen when a range request loading rest of the data
1819 // after interrupted concurrent cache read asynchronously failed, e.g.
1820 // the response range bytes are not as expected or this channel has
1821 // been externally canceled.
1822 //
1823 // It's legal to bypass CallOnStartRequest for that case since we've
1824 // already called OnStartRequest on our listener and also added all
1825 // content converters before.
1826 MOZ_ASSERT(LoadConcurrentCacheAccess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadConcurrentCacheAccess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadConcurrentCacheAccess())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("LoadConcurrentCacheAccess()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1826); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadConcurrentCacheAccess()"
")"); do { *((volatile int*)__null) = 1826; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1827 LOG(("CallOnStartRequest already invoked before"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "CallOnStartRequest already invoked before"); } } while (0)
;
1828 return mStatus;
1829 }
1830
1831 // Ensure mListener->OnStartRequest will be invoked before exiting
1832 // this function.
1833 auto onStartGuard = MakeScopeExit([&] {
1834 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " calling mListener->OnStartRequest by ScopeExit [this=%p, "
"listener=%p]\n", this, mListener.get()); } } while (0)
1835 (" calling mListener->OnStartRequest by ScopeExit [this=%p, "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " calling mListener->OnStartRequest by ScopeExit [this=%p, "
"listener=%p]\n", this, mListener.get()); } } while (0)
1836 "listener=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " calling mListener->OnStartRequest by ScopeExit [this=%p, "
"listener=%p]\n", this, mListener.get()); } } while (0)
1837 this, mListener.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " calling mListener->OnStartRequest by ScopeExit [this=%p, "
"listener=%p]\n", this, mListener.get()); } } while (0)
;
1838 MOZ_ASSERT(!LoadOnStartRequestCalled())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadOnStartRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadOnStartRequestCalled())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadOnStartRequestCalled()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1838); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
")"); do { *((volatile int*)__null) = 1838; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1839
1840 if (mListener) {
1841 nsCOMPtr<nsIStreamListener> deleteProtector(mListener);
1842 StoreOnStartRequestCalled(true);
1843 deleteProtector->OnStartRequest(this);
1844 }
1845 StoreOnStartRequestCalled(true);
1846 });
1847
1848 nsresult rv = ValidateMIMEType();
1849 // Since ODA and OnStopRequest could be sent from socket process directly, we
1850 // need to update the channel status before calling mListener->OnStartRequest.
1851 // This is the only way to let child process discard the already received ODA
1852 // messages.
1853 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1854 mStatus = rv;
1855 return mStatus;
1856 }
1857
1858 // EnsureOpaqueResponseIsAllowed and EnsureOpauqeResponseIsAllowedAfterSniff
1859 // are the checks for Opaque Response Blocking to ensure that we block as many
1860 // cross-origin responses with CORS headers as possible that are not either
1861 // Javascript or media to avoid leaking their contents through side channels.
1862 OpaqueResponse opaqueResponse =
1863 PerformOpaqueResponseSafelistCheckBeforeSniff();
1864 if (opaqueResponse == OpaqueResponse::Block) {
1865 SetChannelBlockedByOpaqueResponse();
1866 CancelWithReason(NS_ERROR_FAILURE,
1867 "OpaqueResponseBlocker::BlockResponse"_ns);
1868 return NS_ERROR_FAILURE;
1869 }
1870
1871 // Allow consumers to override our content type
1872 if (mLoadFlags & LOAD_CALL_CONTENT_SNIFFERS) {
1873 // NOTE: We can have both a txn pump and a cache pump when the cache
1874 // content is partial. In that case, we need to read from the cache,
1875 // because that's the one that has the initial contents. If that fails
1876 // then give the transaction pump a shot.
1877
1878 nsIChannel* thisChannel = static_cast<nsIChannel*>(this);
1879
1880 bool typeSniffersCalled = false;
1881 if (mCachePump) {
1882 typeSniffersCalled =
1883 NS_SUCCEEDED(mCachePump->PeekStream(CallTypeSniffers, thisChannel))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mCachePump->PeekStream
(CallTypeSniffers, thisChannel))), 1)))
;
1884 }
1885
1886 if (!typeSniffersCalled && mTransactionPump) {
1887 RefPtr<nsInputStreamPump> pump = do_QueryObject(mTransactionPump);
1888 if (pump) {
1889 pump->PeekStream(CallTypeSniffers, thisChannel);
1890 } else {
1891 MOZ_ASSERT(nsIOService::UseSocketProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(nsIOService::UseSocketProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(nsIOService::UseSocketProcess
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("nsIOService::UseSocketProcess()", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1891); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nsIOService::UseSocketProcess()"
")"); do { *((volatile int*)__null) = 1891; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1892 RefPtr<HttpTransactionParent> trans = do_QueryObject(mTransactionPump);
1893 MOZ_ASSERT(trans)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(trans)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(trans))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("trans", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1893); AnnotateMozCrashReason("MOZ_ASSERT" "(" "trans" ")")
; do { *((volatile int*)__null) = 1893; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1894 trans->SetSniffedTypeToChannel(CallTypeSniffers, thisChannel);
1895 }
1896 }
1897 }
1898
1899 // Note that the code below should be synced with the code in
1900 // HttpTransactionChild::CanSendODAToContentProcessDirectly(). We MUST make
1901 // sure HttpTransactionChild::CanSendODAToContentProcessDirectly() returns
1902 // false when a stream converter is applied.
1903 bool unknownDecoderStarted = false;
1904 if (mResponseHead && !mResponseHead->HasContentType()) {
1905 MOZ_ASSERT(mConnectionInfo, "Should have connection info here")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mConnectionInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mConnectionInfo))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mConnectionInfo"
" (" "Should have connection info here" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1905); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mConnectionInfo"
") (" "Should have connection info here" ")"); do { *((volatile
int*)__null) = 1905; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1906 if (!mContentTypeHint.IsEmpty()) {
1907 mResponseHead->SetContentType(mContentTypeHint);
1908 } else if (mResponseHead->Version() == HttpVersion::v0_9 &&
1909 mConnectionInfo->OriginPort() !=
1910 mConnectionInfo->DefaultPort()) {
1911 mResponseHead->SetContentType(nsLiteralCString(TEXT_PLAIN"text/plain"));
1912 } else {
1913 // Uh-oh. We had better find out what type we are!
1914 mListener = new nsUnknownDecoder(mListener);
1915 unknownDecoderStarted = true;
1916 }
1917 }
1918
1919 // If unknownDecoder is not going to be launched, call
1920 // EnsureOpaqueResponseIsAllowedAfterSniff immediately.
1921 if (!unknownDecoderStarted) {
1922 if (opaqueResponse == OpaqueResponse::SniffCompressed) {
1923 mListener = new nsCompressedAudioVideoImageDetector(
1924 mListener, &HttpBaseChannel::CallTypeSniffers);
1925 } else if (opaqueResponse == OpaqueResponse::Sniff) {
1926 MOZ_DIAGNOSTIC_ASSERT(mORB)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mORB)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(mORB))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("mORB", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1926); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mORB"
")"); do { *((volatile int*)__null) = 1926; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1927 nsresult rv = mORB->EnsureOpaqueResponseIsAllowedAfterSniff(this);
1928
1929 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1930 return rv;
1931 }
1932 }
1933 }
1934
1935 // If the content is multipart/x-mixed-replace, we'll insert a MIME decoder
1936 // in the pipeline to handle the content and pass it along to our
1937 // original listener. nsUnknownDecoder doesn't support detecting this type,
1938 // so we only need to insert this using the response header's mime type.
1939 //
1940 // We only do this for unwrapped document loads, since we might want to send
1941 // parts to the external protocol handler without leaving the parent process.
1942 bool mustRunStreamFilterInParent = false;
1943 nsCOMPtr<nsIParentChannel> parentChannel;
1944 NS_QueryNotificationCallbacks(this, parentChannel);
1945 RefPtr<DocumentLoadListener> docListener = do_QueryObject(parentChannel);
1946 if (mResponseHead && docListener && docListener->GetChannel() == this) {
1947 nsAutoCString contentType;
1948 mResponseHead->ContentType(contentType);
1949
1950 if (contentType.Equals("multipart/x-mixed-replace"_ns)) {
1951 nsCOMPtr<nsIStreamConverterService> convServ(
1952 mozilla::components::StreamConverter::Service(&rv));
1953 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1954 nsCOMPtr<nsIStreamListener> toListener(mListener);
1955 nsCOMPtr<nsIStreamListener> fromListener;
1956
1957 rv = convServ->AsyncConvertData("multipart/x-mixed-replace", "*/*",
1958 toListener, nullptr,
1959 getter_AddRefs(fromListener));
1960 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1961 mListener = fromListener;
1962 mustRunStreamFilterInParent = true;
1963 }
1964 }
1965 }
1966 }
1967
1968 // If we installed a multipart converter, then we need to add StreamFilter
1969 // object before it, so that extensions see the un-parsed original stream.
1970 // We may want to add an option for extensions to opt-in to proper multipart
1971 // handling.
1972 // If not, then pass the StreamFilter promise on to DocumentLoadListener,
1973 // where it'll be added in the content process.
1974 for (StreamFilterRequest& request : mStreamFilterRequests) {
1975 if (mustRunStreamFilterInParent) {
1976 mozilla::ipc::Endpoint<extensions::PStreamFilterParent> parent;
1977 mozilla::ipc::Endpoint<extensions::PStreamFilterChild> child;
1978 nsresult rv = extensions::PStreamFilter::CreateEndpoints(&parent, &child);
1979 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1980 request.mPromise->Reject(false, __func__);
1981 } else {
1982 extensions::StreamFilterParent::Attach(this, std::move(parent));
1983 request.mPromise->Resolve(std::move(child), __func__);
1984 }
1985 } else {
1986 if (docListener) {
1987 docListener->AttachStreamFilter()->ChainTo(request.mPromise.forget(),
1988 __func__);
1989 } else {
1990 request.mPromise->Reject(false, __func__);
1991 }
1992 }
1993 request.mPromise = nullptr;
1994 }
1995 mStreamFilterRequests.Clear();
1996 StoreTracingEnabled(false);
1997
1998 if (mResponseHead && !mResponseHead->HasContentCharset()) {
1999 mResponseHead->SetContentCharset(mContentCharsetHint);
2000 }
2001
2002 if (mCacheEntry && LoadCacheEntryIsWriteOnly()) {
2003 SetCachedContentType();
2004 }
2005
2006 LOG((" calling mListener->OnStartRequest [this=%p, listener=%p]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " calling mListener->OnStartRequest [this=%p, listener=%p]\n"
, this, mListener.get()); } } while (0)
2007 mListener.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " calling mListener->OnStartRequest [this=%p, listener=%p]\n"
, this, mListener.get()); } } while (0)
;
2008
2009 // About to call OnStartRequest, dismiss the guard object.
2010 onStartGuard.release();
2011
2012 if (mListener) {
2013 MOZ_ASSERT(!LoadOnStartRequestCalled(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadOnStartRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadOnStartRequestCalled())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadOnStartRequestCalled()"
" (" "We should not call OsStartRequest twice" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2014); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
") (" "We should not call OsStartRequest twice" ")"); do { *
((volatile int*)__null) = 2014; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
2014 "We should not call OsStartRequest twice")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadOnStartRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadOnStartRequestCalled())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadOnStartRequestCalled()"
" (" "We should not call OsStartRequest twice" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2014); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
") (" "We should not call OsStartRequest twice" ")"); do { *
((volatile int*)__null) = 2014; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
2015 nsCOMPtr<nsIStreamListener> deleteProtector(mListener);
2016 StoreOnStartRequestCalled(true);
2017 rv = deleteProtector->OnStartRequest(this);
2018 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
2019 } else {
2020 NS_WARNING("OnStartRequest skipped because of null listener")NS_DebugBreak(NS_DEBUG_WARNING, "OnStartRequest skipped because of null listener"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2020)
;
2021 StoreOnStartRequestCalled(true);
2022 }
2023
2024 // Install stream converter if required.
2025 // Normally, we expect the listener to disable content conversion during
2026 // OnStartRequest if it wants to handle it itself (which is common case with
2027 // HttpChannelParent, disabling so that it can be done in the content
2028 // process). If we've installed an nsUnknownDecoder, then we won't yet have
2029 // called OnStartRequest on the final listener (that happens after we send
2030 // OnDataAvailable to the nsUnknownDecoder), so it can't yet have disabled
2031 // content conversion.
2032 // In that case, assume that the listener will disable content conversion,
2033 // unless it's specifically told us that it won't.
2034 if (!unknownDecoderStarted || LoadListenerRequiresContentConversion()) {
2035 nsCOMPtr<nsIStreamListener> listener;
2036 rv =
2037 DoApplyContentConversions(mListener, getter_AddRefs(listener), nullptr);
2038 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2039 return rv;
2040 }
2041 if (listener) {
2042 MOZ_ASSERT(!LoadDataSentToChildProcess(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadDataSentToChildProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadDataSentToChildProcess(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!LoadDataSentToChildProcess()" " (" "DataSentToChildProcess being true means ODAs are sent to "
"the child process directly. We MUST NOT apply content " "converter in this case."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2045); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadDataSentToChildProcess()"
") (" "DataSentToChildProcess being true means ODAs are sent to "
"the child process directly. We MUST NOT apply content " "converter in this case."
")"); do { *((volatile int*)__null) = 2045; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2043 "DataSentToChildProcess being true means ODAs are sent to "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadDataSentToChildProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadDataSentToChildProcess(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!LoadDataSentToChildProcess()" " (" "DataSentToChildProcess being true means ODAs are sent to "
"the child process directly. We MUST NOT apply content " "converter in this case."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2045); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadDataSentToChildProcess()"
") (" "DataSentToChildProcess being true means ODAs are sent to "
"the child process directly. We MUST NOT apply content " "converter in this case."
")"); do { *((volatile int*)__null) = 2045; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2044 "the child process directly. We MUST NOT apply content "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadDataSentToChildProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadDataSentToChildProcess(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!LoadDataSentToChildProcess()" " (" "DataSentToChildProcess being true means ODAs are sent to "
"the child process directly. We MUST NOT apply content " "converter in this case."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2045); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadDataSentToChildProcess()"
") (" "DataSentToChildProcess being true means ODAs are sent to "
"the child process directly. We MUST NOT apply content " "converter in this case."
")"); do { *((volatile int*)__null) = 2045; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2045 "converter in this case.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadDataSentToChildProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadDataSentToChildProcess(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!LoadDataSentToChildProcess()" " (" "DataSentToChildProcess being true means ODAs are sent to "
"the child process directly. We MUST NOT apply content " "converter in this case."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2045); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadDataSentToChildProcess()"
") (" "DataSentToChildProcess being true means ODAs are sent to "
"the child process directly. We MUST NOT apply content " "converter in this case."
")"); do { *((volatile int*)__null) = 2045; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2046 mListener = listener;
2047 mCompressListener = listener;
2048
2049 StoreHasAppliedConversion(true);
2050 }
2051 }
2052
2053 // if this channel is for a download, close off access to the cache.
2054 if (mCacheEntry && LoadChannelIsForDownload()) {
2055 mCacheEntry->AsyncDoom(nullptr);
2056
2057 // We must keep the cache entry in case of partial request.
2058 // Concurrent access is the same, we need the entry in
2059 // OnStopRequest.
2060 // We also need the cache entry when racing cache with network to find
2061 // out what is the source of the data.
2062 if (!LoadCachedContentIsPartial() && !LoadConcurrentCacheAccess() &&
2063 !(mRaceCacheWithNetwork &&
2064 mFirstResponseSource == RESPONSE_FROM_CACHE)) {
2065 CloseCacheEntry(false);
2066 }
2067 }
2068
2069 return NS_OK;
2070}
2071
2072NS_IMETHODIMPnsresult nsHttpChannel::GetHttpProxyConnectResponseCode(
2073 int32_t* aResponseCode) {
2074 NS_ENSURE_ARG_POINTER(aResponseCode)do { if ((__builtin_expect(!!(!(aResponseCode)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResponseCode" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2074); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2075
2076 if (mConnectionInfo && mConnectionInfo->UsingConnect()) {
2077 *aResponseCode = mProxyConnectResponseCode;
2078 } else {
2079 *aResponseCode = -1;
2080 }
2081 return NS_OK;
2082}
2083
2084nsresult nsHttpChannel::ProcessFailedProxyConnect(uint32_t httpStatus) {
2085 // Failure to set up a proxy tunnel via CONNECT means one of the following:
2086 // 1) Proxy wants authorization, or forbids.
2087 // 2) DNS at proxy couldn't resolve target URL.
2088 // 3) Proxy connection to target failed or timed out.
2089 // 4) Eve intercepted our CONNECT, and is replying with malicious HTML.
2090 //
2091 // Our current architecture would parse the proxy's response content with
2092 // the permission of the target URL. Given #4, we must avoid rendering the
2093 // body of the reply, and instead give the user a (hopefully helpful)
2094 // boilerplate error page, based on just the HTTP status of the reply.
2095
2096 MOZ_ASSERT(mConnectionInfo->UsingConnect(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mConnectionInfo->UsingConnect())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mConnectionInfo->UsingConnect
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mConnectionInfo->UsingConnect()" " (" "proxy connect failed but not using CONNECT?"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2097); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mConnectionInfo->UsingConnect()"
") (" "proxy connect failed but not using CONNECT?" ")"); do
{ *((volatile int*)__null) = 2097; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
2097 "proxy connect failed but not using CONNECT?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mConnectionInfo->UsingConnect())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mConnectionInfo->UsingConnect
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mConnectionInfo->UsingConnect()" " (" "proxy connect failed but not using CONNECT?"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2097); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mConnectionInfo->UsingConnect()"
") (" "proxy connect failed but not using CONNECT?" ")"); do
{ *((volatile int*)__null) = 2097; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
2098 nsresult rv = HttpProxyResponseToErrorCode(httpStatus);
2099 LOG(("Cancelling failed proxy CONNECT [this=%p httpStatus=%u]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Cancelling failed proxy CONNECT [this=%p httpStatus=%u]\n"
, this, httpStatus); } } while (0)
2100 httpStatus))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Cancelling failed proxy CONNECT [this=%p httpStatus=%u]\n"
, this, httpStatus); } } while (0)
;
2101
2102 // Make sure the connection is thrown away as it can be in a bad state
2103 // and the proxy may just hang on the next request.
2104 MOZ_ASSERT(mTransaction)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mTransaction)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mTransaction))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mTransaction", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2104); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mTransaction"
")"); do { *((volatile int*)__null) = 2104; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2105 mTransaction->DontReuseConnection();
2106
2107 Cancel(rv);
2108 {
2109 nsresult rv = CallOnStartRequest();
2110 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2111 LOG(("CallOnStartRequest failed [this=%p httpStatus=%u rv=%08x]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "CallOnStartRequest failed [this=%p httpStatus=%u rv=%08x]\n"
, this, httpStatus, static_cast<uint32_t>(rv)); } } while
(0)
2112 httpStatus, static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "CallOnStartRequest failed [this=%p httpStatus=%u rv=%08x]\n"
, this, httpStatus, static_cast<uint32_t>(rv)); } } while
(0)
;
2113 }
2114 }
2115 return rv;
2116}
2117
2118static void GetSTSConsoleErrorTag(uint32_t failureResult,
2119 nsAString& consoleErrorTag) {
2120 switch (failureResult) {
2121 case nsISiteSecurityService::ERROR_COULD_NOT_PARSE_HEADER:
2122 consoleErrorTag = u"STSCouldNotParseHeader"_ns;
2123 break;
2124 case nsISiteSecurityService::ERROR_NO_MAX_AGE:
2125 consoleErrorTag = u"STSNoMaxAge"_ns;
2126 break;
2127 case nsISiteSecurityService::ERROR_MULTIPLE_MAX_AGES:
2128 consoleErrorTag = u"STSMultipleMaxAges"_ns;
2129 break;
2130 case nsISiteSecurityService::ERROR_INVALID_MAX_AGE:
2131 consoleErrorTag = u"STSInvalidMaxAge"_ns;
2132 break;
2133 case nsISiteSecurityService::ERROR_MULTIPLE_INCLUDE_SUBDOMAINS:
2134 consoleErrorTag = u"STSMultipleIncludeSubdomains"_ns;
2135 break;
2136 case nsISiteSecurityService::ERROR_INVALID_INCLUDE_SUBDOMAINS:
2137 consoleErrorTag = u"STSInvalidIncludeSubdomains"_ns;
2138 break;
2139 case nsISiteSecurityService::ERROR_COULD_NOT_SAVE_STATE:
2140 consoleErrorTag = u"STSCouldNotSaveState"_ns;
2141 break;
2142 default:
2143 consoleErrorTag = u"STSUnknownError"_ns;
2144 break;
2145 }
2146}
2147
2148/**
2149 * Process an HTTP Strict Transport Security (HSTS) header.
2150 */
2151nsresult nsHttpChannel::ProcessHSTSHeader(nsITransportSecurityInfo* aSecInfo) {
2152 nsHttpAtom atom(nsHttp::ResolveAtom("Strict-Transport-Security"_ns));
2153
2154 nsAutoCString securityHeader;
2155 nsresult rv = mResponseHead->GetHeader(atom, securityHeader);
2156 if (rv == NS_ERROR_NOT_AVAILABLE) {
2157 LOG(("nsHttpChannel: No %s header, continuing load.\n", atom.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel: No %s header, continuing load.\n", atom.get
()); } } while (0)
;
2158 return NS_OK;
2159 }
2160 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2160)
) {
2161 return rv;
2162 }
2163
2164 if (!aSecInfo) {
2165 LOG(("nsHttpChannel::ProcessHSTSHeader: no securityInfo?"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessHSTSHeader: no securityInfo?"); } } while
(0)
;
2166 return NS_ERROR_INVALID_ARG;
2167 }
2168 nsITransportSecurityInfo::OverridableErrorCategory overridableErrorCategory;
2169 rv = aSecInfo->GetOverridableErrorCategory(&overridableErrorCategory);
2170 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2170)
) {
2171 return rv;
2172 }
2173 if (overridableErrorCategory !=
2174 nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET) {
2175 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessHSTSHeader: untrustworthy connection - not "
"processing header"); } } while (0)
2176 ("nsHttpChannel::ProcessHSTSHeader: untrustworthy connection - not "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessHSTSHeader: untrustworthy connection - not "
"processing header"); } } while (0)
2177 "processing header"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessHSTSHeader: untrustworthy connection - not "
"processing header"); } } while (0)
;
2178 return NS_ERROR_FAILURE;
2179 }
2180
2181 nsISiteSecurityService* sss = gHttpHandler->GetSSService();
2182 NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY)do { if ((__builtin_expect(!!(!(sss)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "sss" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2182); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
2183
2184 OriginAttributes originAttributes;
2185 if (NS_WARN_IF(!StoragePrincipalHelper::GetOriginAttributesForHSTS(NS_warn_if_impl(!StoragePrincipalHelper::GetOriginAttributesForHSTS
( this, originAttributes), "!StoragePrincipalHelper::GetOriginAttributesForHSTS( this, originAttributes)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2186)
2186 this, originAttributes))NS_warn_if_impl(!StoragePrincipalHelper::GetOriginAttributesForHSTS
( this, originAttributes), "!StoragePrincipalHelper::GetOriginAttributesForHSTS( this, originAttributes)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2186)
) {
2187 return NS_ERROR_FAILURE;
2188 }
2189
2190 uint32_t failureResult;
2191 rv = sss->ProcessHeader(mURI, securityHeader, originAttributes, nullptr,
2192 nullptr, &failureResult);
2193 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2194 nsAutoString consoleErrorCategory(u"Invalid HSTS Headers"_ns);
2195 nsAutoString consoleErrorTag;
2196 GetSTSConsoleErrorTag(failureResult, consoleErrorTag);
2197 Unused << AddSecurityMessage(consoleErrorTag, consoleErrorCategory);
2198 LOG(("nsHttpChannel: Failed to parse %s header, continuing load.\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel: Failed to parse %s header, continuing load.\n"
, atom.get()); } } while (0)
2199 atom.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel: Failed to parse %s header, continuing load.\n"
, atom.get()); } } while (0)
;
2200 }
2201 return NS_OK;
2202}
2203
2204/**
2205 * Decide whether or not to remember Strict-Transport-Security, and whether
2206 * or not to enforce channel integrity.
2207 *
2208 * @return NS_ERROR_FAILURE if there's security information missing even though
2209 * it's an HTTPS connection.
2210 */
2211nsresult nsHttpChannel::ProcessSecurityHeaders() {
2212 // If this channel is not loading securely, STS or PKP doesn't do anything.
2213 // In the case of HSTS, the upgrade to HTTPS takes place earlier in the
2214 // channel load process.
2215 if (!mURI->SchemeIs("https")) {
2216 return NS_OK;
2217 }
2218
2219 if (IsBrowsingContextDiscarded()) {
2220 return NS_OK;
2221 }
2222
2223 nsAutoCString asciiHost;
2224 nsresult rv = mURI->GetAsciiHost(asciiHost);
2225 NS_ENSURE_SUCCESS(rv, NS_OK)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "NS_OK", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2225); return NS_OK; } } while (false)
;
2226
2227 // If the channel is not a hostname, but rather an IP, do not process STS
2228 // or PKP headers
2229 if (HostIsIPLiteral(asciiHost)) {
2230 return NS_OK;
2231 }
2232
2233 // mSecurityInfo may not always be present, and if it's not then it is okay
2234 // to just disregard any security headers since we know nothing about the
2235 // security of the connection.
2236 NS_ENSURE_TRUE(mSecurityInfo, NS_OK)do { if ((__builtin_expect(!!(!(mSecurityInfo)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mSecurityInfo" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2236); return NS_OK; } } while (false)
;
2237
2238 // Only process HSTS headers for first-party loads. This prevents a
2239 // proliferation of useless HSTS state for partitioned third parties.
2240 if (!mLoadInfo->GetIsThirdPartyContextToTopWindow()) {
2241 rv = ProcessHSTSHeader(mSecurityInfo);
2242 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2242); return rv; } } while (false)
;
2243 }
2244
2245 return NS_OK;
2246}
2247
2248bool nsHttpChannel::IsHTTPS() { return mURI->SchemeIs("https"); }
2249
2250void nsHttpChannel::ProcessSSLInformation() {
2251 // If this is HTTPS, record any use of RSA so that Key Exchange Algorithm
2252 // can be whitelisted for TLS False Start in future sessions. We could
2253 // do the same for DH but its rarity doesn't justify the lookup.
2254
2255 if (mCanceled || NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0))) || !mSecurityInfo || !IsHTTPS() ||
2256 mPrivateBrowsing) {
2257 return;
2258 }
2259
2260 if (!mSecurityInfo) {
2261 return;
2262 }
2263
2264 uint32_t state;
2265 if (NS_SUCCEEDED(mSecurityInfo->GetSecurityState(&state))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mSecurityInfo->
GetSecurityState(&state))), 1)))
&&
2266 (state & nsIWebProgressListener::STATE_IS_BROKEN)) {
2267 // Send weak crypto warnings to the web console
2268 if (state & nsIWebProgressListener::STATE_USES_WEAK_CRYPTO) {
2269 nsString consoleErrorTag = u"WeakCipherSuiteWarning"_ns;
2270 nsString consoleErrorCategory = u"SSL"_ns;
2271 Unused << AddSecurityMessage(consoleErrorTag, consoleErrorCategory);
2272 }
2273 }
2274
2275 uint16_t tlsVersion;
2276 nsresult rv = mSecurityInfo->GetProtocolVersion(&tlsVersion);
2277 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) &&
2278 tlsVersion != nsITransportSecurityInfo::TLS_VERSION_1_2 &&
2279 tlsVersion != nsITransportSecurityInfo::TLS_VERSION_1_3) {
2280 nsString consoleErrorTag = u"DeprecatedTLSVersion2"_ns;
2281 nsString consoleErrorCategory = u"TLS"_ns;
2282 Unused << AddSecurityMessage(consoleErrorTag, consoleErrorCategory);
2283 }
2284}
2285
2286void nsHttpChannel::ProcessAltService() {
2287 // e.g. Alt-Svc: h2=":443"; ma=60
2288 // e.g. Alt-Svc: h2="otherhost:443"
2289 // Alt-Svc = 1#( alternative *( OWS ";" OWS parameter ) )
2290 // alternative = protocol-id "=" alt-authority
2291 // protocol-id = token ; percent-encoded ALPN protocol identifier
2292 // alt-authority = quoted-string ; containing [ uri-host ] ":" port
2293
2294 if (!LoadAllowAltSvc()) { // per channel opt out
2295 return;
2296 }
2297
2298 if (mWebTransportSessionEventListener) {
2299 return;
2300 }
2301
2302 if (!gHttpHandler->AllowAltSvc() || (mCaps & NS_HTTP_DISALLOW_SPDY(1 << 7))) {
2303 return;
2304 }
2305
2306 if (IsBrowsingContextDiscarded()) {
2307 return;
2308 }
2309
2310 nsAutoCString scheme;
2311 mURI->GetScheme(scheme);
2312 bool isHttp = scheme.EqualsLiteral("http");
2313 if (!isHttp && !scheme.EqualsLiteral("https")) {
2314 return;
2315 }
2316
2317 nsAutoCString altSvc;
2318 Unused << mResponseHead->GetHeader(nsHttp::Alternate_Service, altSvc);
2319 if (altSvc.IsEmpty()) {
2320 return;
2321 }
2322
2323 if (!nsHttp::IsReasonableHeaderValue(altSvc)) {
2324 LOG(("Alt-Svc Response Header seems unreasonable - skipping\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Alt-Svc Response Header seems unreasonable - skipping\n");
} } while (0)
;
2325 return;
2326 }
2327
2328 nsAutoCString originHost;
2329 int32_t originPort = 80;
2330 mURI->GetPort(&originPort);
2331 if (NS_FAILED(mURI->GetAsciiHost(originHost))((bool)(__builtin_expect(!!(NS_FAILED_impl(mURI->GetAsciiHost
(originHost))), 0)))
) {
2332 return;
2333 }
2334
2335 nsCOMPtr<nsIInterfaceRequestor> callbacks;
2336 nsCOMPtr<nsProxyInfo> proxyInfo;
2337 NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
2338 getter_AddRefs(callbacks));
2339
2340 if (mProxyInfo) {
2341 proxyInfo = do_QueryInterface(mProxyInfo);
2342 }
2343
2344 OriginAttributes originAttributes;
2345 // Regular principal in case we have a proxy.
2346 if (proxyInfo &&
2347 !StaticPrefs::privacy_partition_network_state_connection_with_proxy()) {
2348 StoragePrincipalHelper::GetOriginAttributes(
2349 this, originAttributes, StoragePrincipalHelper::eRegularPrincipal);
2350 } else {
2351 StoragePrincipalHelper::GetOriginAttributesForNetworkState(
2352 this, originAttributes);
2353 }
2354
2355 AltSvcMapping::ProcessHeader(
2356 altSvc, scheme, originHost, originPort, mUsername, mPrivateBrowsing,
2357 callbacks, proxyInfo, mCaps & NS_HTTP_DISALLOW_SPDY(1 << 7), originAttributes);
2358}
2359
2360nsresult nsHttpChannel::ProcessResponse() {
2361 uint32_t httpStatus = mResponseHead->Status();
2362
2363 LOG(("nsHttpChannel::ProcessResponse [this=%p httpStatus=%u]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessResponse [this=%p httpStatus=%u]\n",
this, httpStatus); } } while (0)
2364 httpStatus))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessResponse [this=%p httpStatus=%u]\n",
this, httpStatus); } } while (0)
;
2365
2366 // Gather data on whether the transaction and page (if this is
2367 // the initial page load) is being loaded with SSL.
2368 Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_IS_SSL,
2369 mConnectionInfo->EndToEndSSL());
2370 if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
2371 Telemetry::Accumulate(Telemetry::HTTP_PAGELOAD_IS_SSL,
2372 mConnectionInfo->EndToEndSSL());
2373 }
2374
2375 if (Telemetry::CanRecordPrereleaseData()) {
2376 // how often do we see something like Alt-Svc: "443:quic,p=1"
2377 // and Alt-Svc: "h3-****"
2378 nsAutoCString alt_service;
2379 Unused << mResponseHead->GetHeader(nsHttp::Alternate_Service, alt_service);
2380 uint32_t saw_quic = 0;
2381 if (!alt_service.IsEmpty()) {
2382 if (strstr(alt_service.get(), "h3-")) {
2383 saw_quic = 1;
2384 } else if (strstr(alt_service.get(), "quic")) {
2385 saw_quic = 2;
2386 }
2387 }
2388 Telemetry::Accumulate(Telemetry::HTTP_SAW_QUIC_ALT_PROTOCOL_2, saw_quic);
2389
2390 // Gather data on various response status to monitor any increased frequency
2391 // of auth failures due to Bug 1896350
2392 switch (httpStatus) {
2393 case 200:
2394 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 0);
2395 mozilla::glean::networking::http_response_status_code.Get("200_ok"_ns)
2396 .Add(1);
2397 break;
2398 case 301:
2399 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 1);
2400 mozilla::glean::networking::http_response_status_code
2401 .Get("301_moved_permanently"_ns)
2402 .Add(1);
2403 break;
2404 case 302:
2405 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 2);
2406 mozilla::glean::networking::http_response_status_code
2407 .Get("302_found"_ns)
2408 .Add(1);
2409 break;
2410 case 304:
2411 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 3);
2412 mozilla::glean::networking::http_response_status_code
2413 .Get("304_not_modified"_ns)
2414 .Add(1);
2415 break;
2416 case 307:
2417 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 4);
2418 mozilla::glean::networking::http_response_status_code
2419 .Get("307_temporary_redirect"_ns)
2420 .Add(1);
2421 break;
2422 case 308:
2423 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 5);
2424 mozilla::glean::networking::http_response_status_code
2425 .Get("308_permanent_redirect"_ns)
2426 .Add(1);
2427 break;
2428 case 400:
2429 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 6);
2430 mozilla::glean::networking::http_response_status_code
2431 .Get("400_bad_request"_ns)
2432 .Add(1);
2433 break;
2434 case 401:
2435 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 7);
2436 mozilla::glean::networking::http_response_status_code
2437 .Get("401_unauthorized"_ns)
2438 .Add(1);
2439 break;
2440 case 403:
2441 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 8);
2442 mozilla::glean::networking::http_response_status_code
2443 .Get("403_forbidden"_ns)
2444 .Add(1);
2445 break;
2446 case 404:
2447 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 9);
2448 mozilla::glean::networking::http_response_status_code
2449 .Get("404_not_found"_ns)
2450 .Add(1);
2451 break;
2452 case 421:
2453 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 11);
2454 mozilla::glean::networking::http_response_status_code
2455 .Get("421_misdirected_request"_ns)
2456 .Add(1);
2457 break;
2458 case 425:
2459 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 11);
2460 mozilla::glean::networking::http_response_status_code
2461 .Get("425_too_early"_ns)
2462 .Add(1);
2463 break;
2464 case 429:
2465 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 11);
2466 mozilla::glean::networking::http_response_status_code
2467 .Get("429_too_many_requests"_ns)
2468 .Add(1);
2469 break;
2470 case 500:
2471 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 10);
2472 mozilla::glean::networking::http_response_status_code
2473 .Get("other_5xx"_ns)
2474 .Add(1);
2475 break;
2476 default:
2477 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 11);
2478 if (httpStatus >= 400 && httpStatus < 500) {
2479 mozilla::glean::networking::http_response_status_code
2480 .Get("other_4xx"_ns)
2481 .Add(1);
2482 } else if (httpStatus > 500) {
2483 mozilla::glean::networking::http_response_status_code
2484 .Get("other_5xx"_ns)
2485 .Add(1);
2486 } else {
2487 mozilla::glean::networking::http_response_status_code.Get("other"_ns)
2488 .Add(1);
2489 }
2490 break;
2491 }
2492 }
2493
2494 // Let the predictor know whether this was a cacheable response or not so
2495 // that it knows whether or not to possibly prefetch this resource in the
2496 // future.
2497 // We use GetReferringPage because mReferrerInfo may not be set at all(this is
2498 // especially useful in xpcshell tests, where we don't have an actual pageload
2499 // to get a referrer from).
2500 nsCOMPtr<nsIURI> referrer = GetReferringPage();
2501 if (!referrer && mReferrerInfo) {
2502 referrer = mReferrerInfo->GetOriginalReferrer();
2503 }
2504
2505 if (referrer) {
2506 nsCOMPtr<nsILoadContextInfo> lci = GetLoadContextInfo(this);
2507 mozilla::net::Predictor::UpdateCacheability(
2508 referrer, mURI, httpStatus, mRequestHead, mResponseHead.get(), lci,
2509 IsThirdPartyTrackingResource());
2510 }
2511
2512 // Only allow 407 (authentication required) to continue
2513 if (mTransaction && mTransaction->ProxyConnectFailed() && httpStatus != 407) {
2514 return ProcessFailedProxyConnect(httpStatus);
2515 }
2516
2517 MOZ_ASSERT(!mCachedContentIsValid || mRaceCacheWithNetwork,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCachedContentIsValid || mRaceCacheWithNetwork)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!mCachedContentIsValid || mRaceCacheWithNetwork))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!mCachedContentIsValid || mRaceCacheWithNetwork"
" (" "We should not be hitting the network if we have valid cached "
"content unless we are racing the network and cache" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2519); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCachedContentIsValid || mRaceCacheWithNetwork"
") (" "We should not be hitting the network if we have valid cached "
"content unless we are racing the network and cache" ")"); do
{ *((volatile int*)__null) = 2519; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
2518 "We should not be hitting the network if we have valid cached "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCachedContentIsValid || mRaceCacheWithNetwork)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!mCachedContentIsValid || mRaceCacheWithNetwork))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!mCachedContentIsValid || mRaceCacheWithNetwork"
" (" "We should not be hitting the network if we have valid cached "
"content unless we are racing the network and cache" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2519); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCachedContentIsValid || mRaceCacheWithNetwork"
") (" "We should not be hitting the network if we have valid cached "
"content unless we are racing the network and cache" ")"); do
{ *((volatile int*)__null) = 2519; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
2519 "content unless we are racing the network and cache")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCachedContentIsValid || mRaceCacheWithNetwork)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!mCachedContentIsValid || mRaceCacheWithNetwork))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!mCachedContentIsValid || mRaceCacheWithNetwork"
" (" "We should not be hitting the network if we have valid cached "
"content unless we are racing the network and cache" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2519); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCachedContentIsValid || mRaceCacheWithNetwork"
") (" "We should not be hitting the network if we have valid cached "
"content unless we are racing the network and cache" ")"); do
{ *((volatile int*)__null) = 2519; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
2520
2521 ProcessSSLInformation();
2522
2523 // notify "http-on-examine-response" observers
2524 gHttpHandler->OnExamineResponse(this);
2525
2526 return ContinueProcessResponse1();
2527}
2528
2529void nsHttpChannel::AsyncContinueProcessResponse() {
2530 nsresult rv;
2531 rv = ContinueProcessResponse1();
2532 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2533 // A synchronous failure here would normally be passed as the return
2534 // value from OnStartRequest, which would in turn cancel the request.
2535 // If we're continuing asynchronously, we need to cancel the request
2536 // ourselves.
2537 Unused << Cancel(rv);
2538 }
2539}
2540
2541nsresult nsHttpChannel::ContinueProcessResponse1() {
2542 MOZ_ASSERT(!mCallOnResume, "How did that happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCallOnResume)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mCallOnResume))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mCallOnResume"
" (" "How did that happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2542); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 2542; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
2543 nsresult rv = NS_OK;
2544
2545 if (mSuspendCount) {
2546 LOG(("Waiting until resume to finish processing response [this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to finish processing response [this=%p]\n"
, this); } } while (0)
2547 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to finish processing response [this=%p]\n"
, this); } } while (0)
;
2548 mCallOnResume = [](nsHttpChannel* self) {
2549 self->AsyncContinueProcessResponse();
2550 return NS_OK;
2551 };
2552 return NS_OK;
2553 }
2554
2555 // Check if request was cancelled during http-on-examine-response.
2556 if (mCanceled) {
2557 return CallOnStartRequest();
2558 }
2559
2560 uint32_t httpStatus = mResponseHead->Status();
2561
2562 // STS, Cookies and Alt-Service should not be handled on proxy failure.
2563 // If proxy CONNECT response needs to complete, wait to process connection
2564 // for Strict-Transport-Security.
2565 if (!(mTransaction && mTransaction->ProxyConnectFailed()) &&
2566 (httpStatus != 407)) {
2567 if (nsAutoCString cookie;
2568 NS_SUCCEEDED(mResponseHead->GetHeader(nsHttp::Set_Cookie, cookie))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mResponseHead->
GetHeader(nsHttp::Set_Cookie, cookie))), 1)))
) {
2569 SetCookie(cookie);
2570 nsCOMPtr<nsIParentChannel> parentChannel;
2571 NS_QueryNotificationCallbacks(this, parentChannel);
2572 if (RefPtr<HttpChannelParent> httpParent =
2573 do_QueryObject(parentChannel)) {
2574 httpParent->SetCookie(std::move(cookie));
2575 }
2576 }
2577
2578 // Given a successful connection, process any STS or PKP data that's
2579 // relevant.
2580 nsresult rv = ProcessSecurityHeaders();
2581 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2582 NS_WARNING("ProcessSTSHeader failed, continuing load.")NS_DebugBreak(NS_DEBUG_WARNING, "ProcessSTSHeader failed, continuing load."
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2582)
;
2583 }
2584
2585 if ((httpStatus < 500) && (httpStatus != 421)) {
2586 ProcessAltService();
2587 }
2588 }
2589
2590 if (LoadConcurrentCacheAccess() && LoadCachedContentIsPartial() &&
2591 httpStatus != 206) {
2592 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " only expecting 206 when doing partial request during " "interrupted cache concurrent read"
); } } while (0)
2593 (" only expecting 206 when doing partial request during "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " only expecting 206 when doing partial request during " "interrupted cache concurrent read"
); } } while (0)
2594 "interrupted cache concurrent read"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " only expecting 206 when doing partial request during " "interrupted cache concurrent read"
); } } while (0)
;
2595 return NS_ERROR_CORRUPTED_CONTENT;
2596 }
2597
2598 // handle unused username and password in url (see bug 232567)
2599 if (httpStatus != 401 && httpStatus != 407) {
2600 if (!mAuthRetryPending) {
2601 MOZ_DIAGNOSTIC_ASSERT(mAuthProvider)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAuthProvider)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAuthProvider))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mAuthProvider",
"/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2601); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mAuthProvider"
")"); do { *((volatile int*)__null) = 2601; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2602 rv = mAuthProvider ? mAuthProvider->CheckForSuperfluousAuth()
2603 : NS_ERROR_UNEXPECTED;
2604 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2605 mStatus = rv;
2606 LOG((" CheckForSuperfluousAuth failed (%08x)",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " CheckForSuperfluousAuth failed (%08x)", static_cast<uint32_t
>(rv)); } } while (0)
2607 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " CheckForSuperfluousAuth failed (%08x)", static_cast<uint32_t
>(rv)); } } while (0)
;
2608 }
2609 }
2610 if (mCanceled) return CallOnStartRequest();
2611
2612 // reset the authentication's current continuation state because ourvr
2613 // last authentication attempt has been completed successfully
2614 MOZ_DIAGNOSTIC_ASSERT(mAuthProvider)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAuthProvider)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAuthProvider))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mAuthProvider",
"/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2614); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mAuthProvider"
")"); do { *((volatile int*)__null) = 2614; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2615 rv = mAuthProvider ? mAuthProvider->Disconnect(NS_ERROR_ABORT)
2616 : NS_ERROR_UNEXPECTED;
2617 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2618 LOG((" Disconnect failed (%08x)", static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Disconnect failed (%08x)", static_cast<uint32_t>(rv
)); } } while (0)
;
2619 }
2620 mAuthProvider = nullptr;
2621 LOG((" continuation state has been reset"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " continuation state has been reset"); } } while (0)
;
2622 }
2623
2624 gHttpHandler->OnAfterExamineResponse(this);
2625
2626 // No process switch needed, continue as normal.
2627 return ContinueProcessResponse2(rv);
2628}
2629
2630nsresult nsHttpChannel::ContinueProcessResponse2(nsresult rv) {
2631 if (mSuspendCount) {
2632 LOG(("Waiting until resume to finish processing response [this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to finish processing response [this=%p]\n"
, this); } } while (0)
2633 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to finish processing response [this=%p]\n"
, this); } } while (0)
;
2634 mCallOnResume = [rv](nsHttpChannel* self) {
2635 Unused << self->ContinueProcessResponse2(rv);
2636 return NS_OK;
2637 };
2638 return NS_OK;
2639 }
2640
2641 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && !mCanceled) {
2642 // The process switch failed, cancel this channel.
2643 Cancel(rv);
2644 return CallOnStartRequest();
2645 }
2646
2647 if (mAPIRedirectToURI && !mCanceled) {
2648 MOZ_ASSERT(!LoadOnStartRequestCalled())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadOnStartRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadOnStartRequestCalled())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadOnStartRequestCalled()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2648); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
")"); do { *((volatile int*)__null) = 2648; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2649 nsCOMPtr<nsIURI> redirectTo;
2650 mAPIRedirectToURI.swap(redirectTo);
2651
2652 PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse3);
2653 rv = StartRedirectChannelToURI(redirectTo,
2654 nsIChannelEventSink::REDIRECT_TEMPORARY);
2655 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2656 return NS_OK;
2657 }
2658 PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse3);
2659 }
2660
2661 // Hack: ContinueProcessResponse3 uses NS_OK to detect successful
2662 // redirects, so we distinguish this codepath (a non-redirect that's
2663 // processing normally) by passing in a bogus error code.
2664 return ContinueProcessResponse3(NS_BINDING_FAILED);
2665}
2666
2667nsresult nsHttpChannel::ContinueProcessResponse3(nsresult rv) {
2668 LOG(("nsHttpChannel::ContinueProcessResponse3 [this=%p, rv=%" PRIx32 "]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessResponse3 [this=%p, rv=%" "x"
"]", this, static_cast<uint32_t>(rv)); } } while (0)
2669 this, static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessResponse3 [this=%p, rv=%" "x"
"]", this, static_cast<uint32_t>(rv)); } } while (0)
;
2670
2671 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2672 // redirectTo() has passed through, we don't want to go on with
2673 // this channel. It will now be canceled by the redirect handling
2674 // code that called this function.
2675 return NS_OK;
2676 }
2677
2678 rv = NS_OK;
2679
2680 uint32_t httpStatus = mResponseHead->Status();
2681 bool transactionRestarted = mTransaction->TakeRestartedState();
2682
2683 // handle different server response categories. Note that we handle
2684 // caching or not caching of error pages in
2685 // nsHttpResponseHead::MustValidate; if you change this switch, update that
2686 // one
2687 switch (httpStatus) {
2688 case 200:
2689 case 203:
2690 // Per RFC 2616, 14.35.2, "A server MAY ignore the Range header".
2691 // So if a server does that and sends 200 instead of 206 that we
2692 // expect, notify our caller.
2693 // However, if we wanted to start from the beginning, let it go through
2694 if (LoadResuming() && mStartPos != 0) {
2695 LOG(("Server ignored our Range header, cancelling [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Server ignored our Range header, cancelling [this=%p]\n", this
); } } while (0)
;
2696 Cancel(NS_ERROR_NOT_RESUMABLE);
2697 rv = CallOnStartRequest();
2698 break;
2699 }
2700 // these can normally be cached
2701 rv = ProcessNormal();
2702 MaybeInvalidateCacheEntryForSubsequentGet();
2703 break;
2704 case 206:
2705 if (LoadCachedContentIsPartial()) { // an internal byte range request...
2706 auto func = [](auto* self, nsresult aRv) {
2707 return self->ContinueProcessResponseAfterPartialContent(aRv);
2708 };
2709 rv = ProcessPartialContent(func);
2710 // Directly call ContinueProcessResponseAfterPartialContent if channel
2711 // is not suspended or ProcessPartialContent throws.
2712 if (!mSuspendCount || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2713 return ContinueProcessResponseAfterPartialContent(rv);
2714 }
2715 return NS_OK;
2716 } else {
2717 mCacheInputStream.CloseAndRelease();
2718 rv = ProcessNormal();
2719 }
2720 break;
2721 case 301:
2722 case 302:
2723 case 307:
2724 case 308:
2725 case 303:
2726#if 0
2727 case 305: // disabled as a security measure (see bug 187996).
2728#endif
2729 // don't store the response body for redirects
2730 MaybeInvalidateCacheEntryForSubsequentGet();
2731 PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse4);
2732 rv = AsyncProcessRedirection(httpStatus);
2733 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2734 PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse4);
2735 LOG(("AsyncProcessRedirection failed [rv=%" PRIx32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "AsyncProcessRedirection failed [rv=%" "x" "]\n", static_cast
<uint32_t>(rv)); } } while (0)
2736 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "AsyncProcessRedirection failed [rv=%" "x" "]\n", static_cast
<uint32_t>(rv)); } } while (0)
;
2737 // don't cache failed redirect responses.
2738 if (mCacheEntry) mCacheEntry->AsyncDoom(nullptr);
2739 if (DoNotRender3xxBody(rv)) {
2740 mStatus = rv;
2741 DoNotifyListener();
2742 } else {
2743 rv = ContinueProcessResponse4(rv);
2744 }
2745 }
2746 break;
2747 case 304:
2748 if (!ShouldBypassProcessNotModified()) {
2749 auto func = [](auto* self, nsresult aRv) {
2750 return self->ContinueProcessResponseAfterNotModified(aRv);
2751 };
2752 rv = ProcessNotModified(func);
2753 // Directly call ContinueProcessResponseAfterNotModified if channel
2754 // is not suspended or ProcessNotModified throws.
2755 if (!mSuspendCount || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2756 return ContinueProcessResponseAfterNotModified(rv);
2757 }
2758 return NS_OK;
2759 }
2760
2761 // Don't cache uninformative 304
2762 if (LoadCustomConditionalRequest()) {
2763 CloseCacheEntry(false);
2764 }
2765
2766 if (ShouldBypassProcessNotModified() || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2767 rv = ProcessNormal();
2768 }
2769 break;
2770 case 401:
2771 case 407:
2772 if (MOZ_UNLIKELY(httpStatus == 407 && transactionRestarted)(__builtin_expect(!!(httpStatus == 407 && transactionRestarted
), 0))
) {
2773 // The transaction has been internally restarted. We want to
2774 // authenticate to the proxy again, so reuse either cached credentials
2775 // or use default credentials for NTLM/Negotiate. This prevents
2776 // considering the previously used credentials as invalid.
2777 MOZ_DIAGNOSTIC_ASSERT(mAuthProvider)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAuthProvider)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAuthProvider))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mAuthProvider",
"/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2777); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mAuthProvider"
")"); do { *((volatile int*)__null) = 2777; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2778 if (!mAuthProvider) {
2779 mStatus = NS_ERROR_UNEXPECTED;
2780 return ProcessNormal();
2781 }
2782 mAuthProvider->ClearProxyIdent();
2783 }
2784 if (!LoadAuthRedirectedChannel() &&
2785 MOZ_UNLIKELY(LoadCustomAuthHeader())(__builtin_expect(!!(LoadCustomAuthHeader()), 0)) && httpStatus == 401) {
2786 // When a custom auth header fails, we don't want to try
2787 // any cached credentials, nor we want to ask the user.
2788 // It's up to the consumer to re-try w/o setting a custom
2789 // auth header if cached credentials should be attempted.
2790 rv = NS_ERROR_FAILURE;
2791 } else if (httpStatus == 401 &&
2792 StaticPrefs::
2793 network_auth_supress_auth_prompt_for_XFO_failures() &&
2794 !nsContentSecurityUtils::CheckCSPFrameAncestorAndXFO(this)) {
2795 // CSP Frame Ancestor and X-Frame-Options check has failed
2796 // Do not prompt http auth - Bug 1629307
2797 rv = NS_ERROR_FAILURE;
2798 } else {
2799 MOZ_DIAGNOSTIC_ASSERT(mAuthProvider)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAuthProvider)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAuthProvider))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mAuthProvider",
"/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2799); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mAuthProvider"
")"); do { *((volatile int*)__null) = 2799; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2800 rv = mAuthProvider
2801 ? mAuthProvider->ProcessAuthentication(
2802 httpStatus, mConnectionInfo->EndToEndSSL() &&
2803 mTransaction &&
2804 mTransaction->ProxyConnectFailed())
2805 : NS_ERROR_UNEXPECTED;
2806 }
2807 if (rv == NS_ERROR_IN_PROGRESS) {
2808 // authentication prompt has been invoked and result
2809 // is expected asynchronously
2810 mIsAuthChannel = true;
2811 mAuthRetryPending = true;
2812 if (httpStatus == 407 ||
2813 (mTransaction && mTransaction->ProxyConnectFailed())) {
2814 StoreProxyAuthPending(true);
2815 }
2816
2817 // suspend the transaction pump to stop receiving the
2818 // unauthenticated content data. We will throw that data
2819 // away when user provides credentials or resume the pump
2820 // when user refuses to authenticate.
2821 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Suspending the transaction, asynchronously prompting for "
"credentials"); } } while (0)
2822 ("Suspending the transaction, asynchronously prompting for "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Suspending the transaction, asynchronously prompting for "
"credentials"); } } while (0)
2823 "credentials"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Suspending the transaction, asynchronously prompting for "
"credentials"); } } while (0)
;
2824 mTransactionPump->Suspend();
2825
2826#ifdef DEBUG1
2827 // This is for test purposes only. See bug 1683176 for details.
2828 gHttpHandler->OnTransactionSuspendedDueToAuthentication(this);
2829#endif
2830 rv = NS_OK;
2831 } else if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2832 LOG(("ProcessAuthentication failed [rv=%" PRIx32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ProcessAuthentication failed [rv=%" "x" "]\n", static_cast
<uint32_t>(rv)); } } while (0)
2833 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ProcessAuthentication failed [rv=%" "x" "]\n", static_cast
<uint32_t>(rv)); } } while (0)
;
2834 if (mTransaction && mTransaction->ProxyConnectFailed()) {
2835 return ProcessFailedProxyConnect(httpStatus);
2836 }
2837 if (!mAuthRetryPending) {
2838 MOZ_DIAGNOSTIC_ASSERT(mAuthProvider)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAuthProvider)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAuthProvider))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mAuthProvider",
"/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 2838); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mAuthProvider"
")"); do { *((volatile int*)__null) = 2838; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2839 rv = mAuthProvider ? mAuthProvider->CheckForSuperfluousAuth()
2840 : NS_ERROR_UNEXPECTED;
2841 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2842 mStatus = rv;
2843 LOG(("CheckForSuperfluousAuth failed [rv=%x]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "CheckForSuperfluousAuth failed [rv=%x]\n", static_cast<
uint32_t>(rv)); } } while (0)
2844 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "CheckForSuperfluousAuth failed [rv=%x]\n", static_cast<
uint32_t>(rv)); } } while (0)
;
2845 }
2846 }
2847 rv = ProcessNormal();
2848 } else {
2849 mIsAuthChannel = true;
2850 mAuthRetryPending = true;
2851 if (StaticPrefs::network_auth_use_redirect_for_retries()) {
2852 if (NS_SUCCEEDED(RedirectToNewChannelForAuthRetry())((bool)(__builtin_expect(!!(!NS_FAILED_impl(RedirectToNewChannelForAuthRetry
())), 1)))
) {
2853 return NS_OK;
2854 }
2855 mAuthRetryPending = false;
2856 rv = ProcessNormal();
2857 }
2858 }
2859 break;
2860
2861 case 408:
2862 case 425:
2863 case 429:
2864 // Do not cache 408, 425 and 429.
2865 CloseCacheEntry(false);
2866 [[fallthrough]]; // process normally
2867 default:
2868 rv = ProcessNormal();
2869 MaybeInvalidateCacheEntryForSubsequentGet();
2870 break;
2871 }
2872
2873 UpdateCacheDisposition(false, false);
2874 return rv;
2875}
2876
2877nsresult nsHttpChannel::ContinueProcessResponseAfterPartialContent(
2878 nsresult aRv) {
2879 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessResponseAfterPartialContent "
"[this=%p, rv=%" "x" "]", this, static_cast<uint32_t>(
aRv)); } } while (0)
2880 ("nsHttpChannel::ContinueProcessResponseAfterPartialContent "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessResponseAfterPartialContent "
"[this=%p, rv=%" "x" "]", this, static_cast<uint32_t>(
aRv)); } } while (0)
2881 "[this=%p, rv=%" PRIx32 "]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessResponseAfterPartialContent "
"[this=%p, rv=%" "x" "]", this, static_cast<uint32_t>(
aRv)); } } while (0)
2882 this, static_cast<uint32_t>(aRv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessResponseAfterPartialContent "
"[this=%p, rv=%" "x" "]", this, static_cast<uint32_t>(
aRv)); } } while (0)
;
2883
2884 UpdateCacheDisposition(false, NS_SUCCEEDED(aRv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aRv)), 1))));
2885 return aRv;
2886}
2887
2888nsresult nsHttpChannel::ContinueProcessResponseAfterNotModified(nsresult aRv) {
2889 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessResponseAfterNotModified " "[this=%p, rv=%"
"x" "]", this, static_cast<uint32_t>(aRv)); } } while (
0)
2890 ("nsHttpChannel::ContinueProcessResponseAfterNotModified "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessResponseAfterNotModified " "[this=%p, rv=%"
"x" "]", this, static_cast<uint32_t>(aRv)); } } while (
0)
2891 "[this=%p, rv=%" PRIx32 "]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessResponseAfterNotModified " "[this=%p, rv=%"
"x" "]", this, static_cast<uint32_t>(aRv)); } } while (
0)
2892 this, static_cast<uint32_t>(aRv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessResponseAfterNotModified " "[this=%p, rv=%"
"x" "]", this, static_cast<uint32_t>(aRv)); } } while (
0)
;
2893
2894 if (NS_SUCCEEDED(aRv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aRv)), 1)))) {
2895 StoreTransactionReplaced(true);
2896 UpdateCacheDisposition(true, false);
2897 return NS_OK;
2898 }
2899
2900 LOG(("ProcessNotModified failed [rv=%" PRIx32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ProcessNotModified failed [rv=%" "x" "]\n", static_cast<
uint32_t>(aRv)); } } while (0)
2901 static_cast<uint32_t>(aRv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ProcessNotModified failed [rv=%" "x" "]\n", static_cast<
uint32_t>(aRv)); } } while (0)
;
2902
2903 // We cannot read from the cache entry, it might be in an
2904 // incosistent state. Doom it and redirect the channel
2905 // to the same URI to reload from the network.
2906 mCacheInputStream.CloseAndRelease();
2907 if (mCacheEntry) {
2908 mCacheEntry->AsyncDoom(nullptr);
2909 mCacheEntry = nullptr;
2910 }
2911
2912 nsresult rv =
2913 StartRedirectChannelToURI(mURI, nsIChannelEventSink::REDIRECT_INTERNAL);
2914 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2915 return NS_OK;
2916 }
2917
2918 // Don't cache uninformative 304
2919 if (LoadCustomConditionalRequest()) {
2920 CloseCacheEntry(false);
2921 }
2922
2923 if (ShouldBypassProcessNotModified() || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2924 rv = ProcessNormal();
2925 }
2926
2927 UpdateCacheDisposition(false, false);
2928 return rv;
2929}
2930
2931static void ReportHttpResponseVersion(HttpVersion version) {
2932 if (Telemetry::CanRecordPrereleaseData()) {
2933 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_VERSION,
2934 static_cast<uint32_t>(version));
2935 }
2936 mozilla::glean::networking::http_response_version
2937 .Get(HttpVersionToTelemetryLabel(version))
2938 .Add(1);
2939}
2940
2941void nsHttpChannel::UpdateCacheDisposition(bool aSuccessfulReval,
2942 bool aPartialContentUsed) {
2943 if (mRaceDelay && !mRaceCacheWithNetwork &&
2944 (LoadCachedContentIsPartial() || mDidReval)) {
2945 if (aSuccessfulReval || aPartialContentUsed) {
2946 AccumulateCategorical(
2947 Telemetry::LABELS_NETWORK_RACE_CACHE_VALIDATION::CachedContentUsed);
2948 } else {
2949 AccumulateCategorical(Telemetry::LABELS_NETWORK_RACE_CACHE_VALIDATION::
2950 CachedContentNotUsed);
2951 }
2952 }
2953
2954 if (Telemetry::CanRecordPrereleaseData()) {
2955 CacheDisposition cacheDisposition;
2956 if (!mDidReval) {
2957 cacheDisposition = kCacheMissed;
2958 } else if (aSuccessfulReval) {
2959 cacheDisposition = kCacheHitViaReval;
2960 } else {
2961 cacheDisposition = kCacheMissedViaReval;
2962 }
2963 AccumulateCacheHitTelemetry(cacheDisposition, this);
2964 mCacheDisposition = cacheDisposition;
2965
2966 if (mResponseHead->Version() == HttpVersion::v0_9) {
2967 // DefaultPortTopLevel = 0, DefaultPortSubResource = 1,
2968 // NonDefaultPortTopLevel = 2, NonDefaultPortSubResource = 3
2969 uint32_t v09Info = 0;
2970 if (!(mLoadFlags & LOAD_INITIAL_DOCUMENT_URI)) {
2971 v09Info += 1;
2972 }
2973 if (mConnectionInfo->OriginPort() != mConnectionInfo->DefaultPort()) {
2974 v09Info += 2;
2975 }
2976 Telemetry::Accumulate(Telemetry::HTTP_09_INFO, v09Info);
2977 }
2978 }
2979
2980 ReportHttpResponseVersion(mResponseHead->Version());
2981}
2982
2983nsresult nsHttpChannel::ContinueProcessResponse4(nsresult rv) {
2984 bool doNotRender = DoNotRender3xxBody(rv);
2985
2986 if (rv == NS_ERROR_DOM_BAD_URI && mRedirectURI) {
2987 bool isHTTP =
2988 mRedirectURI->SchemeIs("http") || mRedirectURI->SchemeIs("https");
2989 if (!isHTTP) {
2990 // This was a blocked attempt to redirect and subvert the system by
2991 // redirecting to another protocol (perhaps javascript:)
2992 // In that case we want to throw an error instead of displaying the
2993 // non-redirected response body.
2994 LOG(("ContinueProcessResponse4 detected rejected Non-HTTP Redirection"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueProcessResponse4 detected rejected Non-HTTP Redirection"
); } } while (0)
;
2995 doNotRender = true;
2996 rv = NS_ERROR_CORRUPTED_CONTENT;
2997 }
2998 }
2999
3000 if (doNotRender) {
3001 Cancel(rv);
3002 DoNotifyListener();
3003 return rv;
3004 }
3005
3006 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3007 UpdateInhibitPersistentCachingFlag();
3008
3009 MaybeCreateCacheEntryWhenRCWN();
3010
3011 rv = InitCacheEntry();
3012 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3013 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueProcessResponse4 " "failed to init cache entry [rv=%x]\n"
, static_cast<uint32_t>(rv)); } } while (0)
3014 ("ContinueProcessResponse4 "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueProcessResponse4 " "failed to init cache entry [rv=%x]\n"
, static_cast<uint32_t>(rv)); } } while (0)
3015 "failed to init cache entry [rv=%x]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueProcessResponse4 " "failed to init cache entry [rv=%x]\n"
, static_cast<uint32_t>(rv)); } } while (0)
3016 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueProcessResponse4 " "failed to init cache entry [rv=%x]\n"
, static_cast<uint32_t>(rv)); } } while (0)
;
3017 }
3018 CloseCacheEntry(false);
3019 return NS_OK;
3020 }
3021
3022 LOG(("ContinueProcessResponse4 got failure result [rv=%" PRIx32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueProcessResponse4 got failure result [rv=%" "x" "]\n"
, static_cast<uint32_t>(rv)); } } while (0)
3023 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueProcessResponse4 got failure result [rv=%" "x" "]\n"
, static_cast<uint32_t>(rv)); } } while (0)
;
3024 if (mTransaction && mTransaction->ProxyConnectFailed()) {
3025 return ProcessFailedProxyConnect(mRedirectType);
3026 }
3027 return ProcessNormal();
3028}
3029
3030nsresult nsHttpChannel::ProcessNormal() {
3031 LOG(("nsHttpChannel::ProcessNormal [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessNormal [this=%p]\n", this); } } while
(0)
;
3032
3033 return ContinueProcessNormal(NS_OK);
3034}
3035
3036nsresult nsHttpChannel::ContinueProcessNormal(nsresult rv) {
3037 LOG(("nsHttpChannel::ContinueProcessNormal [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessNormal [this=%p]", this); } }
while (0)
;
3038
3039 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3040 // Fill the failure status here, we have failed to fall back, thus we
3041 // have to report our status as failed.
3042 mStatus = rv;
3043 DoNotifyListener();
3044 return rv;
3045 }
3046
3047 rv = ProcessCrossOriginSecurityHeaders();
3048 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3049 mStatus = rv;
3050 HandleAsyncAbort();
3051 return rv;
3052 }
3053
3054 // if we're here, then any byte-range requests failed to result in a partial
3055 // response. we must clear this flag to prevent BufferPartialContent from
3056 // being called inside our OnDataAvailable (see bug 136678).
3057 StoreCachedContentIsPartial(false);
3058
3059 UpdateInhibitPersistentCachingFlag();
3060
3061 MaybeCreateCacheEntryWhenRCWN();
3062
3063 // this must be called before firing OnStartRequest, since http clients,
3064 // such as imagelib, expect our cache entry to already have the correct
3065 // expiration time (bug 87710).
3066 if (mCacheEntry) {
3067 rv = InitCacheEntry();
3068 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) CloseCacheEntry(true);
3069 }
3070
3071 // Check that the server sent us what we were asking for
3072 if (LoadResuming()) {
3073 // Create an entity id from the response
3074 nsAutoCString id;
3075 rv = GetEntityID(id);
3076 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3077 // If creating an entity id is not possible -> error
3078 Cancel(NS_ERROR_NOT_RESUMABLE);
3079 } else if (mResponseHead->Status() != 206 &&
3080 mResponseHead->Status() != 200) {
3081 // Probably 404 Not Found, 412 Precondition Failed or
3082 // 416 Invalid Range -> error
3083 LOG(("Unexpected response status while resuming, aborting [this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Unexpected response status while resuming, aborting [this=%p]\n"
, this); } } while (0)
3084 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Unexpected response status while resuming, aborting [this=%p]\n"
, this); } } while (0)
;
3085 Cancel(NS_ERROR_ENTITY_CHANGED);
3086 }
3087 // If we were passed an entity id, verify it's equal to the server's
3088 else if (!mEntityID.IsEmpty()) {
3089 if (!mEntityID.Equals(id)) {
3090 LOG(("Entity mismatch, expected '%s', got '%s', aborting [this=%p]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Entity mismatch, expected '%s', got '%s', aborting [this=%p]"
, mEntityID.get(), id.get(), this); } } while (0)
3091 mEntityID.get(), id.get(), this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Entity mismatch, expected '%s', got '%s', aborting [this=%p]"
, mEntityID.get(), id.get(), this); } } while (0)
;
3092 Cancel(NS_ERROR_ENTITY_CHANGED);
3093 }
3094 }
3095 }
3096
3097 rv = CallOnStartRequest();
3098 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3099
3100 // install cache listener if we still have a cache entry open
3101 if (mCacheEntry && !LoadCacheEntryIsReadOnly()) {
3102 rv = InstallCacheListener();
3103 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3104 }
3105
3106 return NS_OK;
3107}
3108
3109nsresult nsHttpChannel::PromptTempRedirect() {
3110 if (!gHttpHandler->PromptTempRedirect()) {
3111 return NS_OK;
3112 }
3113 nsresult rv;
3114 nsCOMPtr<nsIStringBundleService> bundleService;
3115 bundleService = mozilla::components::StringBundle::Service(&rv);
3116 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3117
3118 nsCOMPtr<nsIStringBundle> stringBundle;
3119 rv =
3120 bundleService->CreateBundle(NECKO_MSGS_URL"chrome://necko/locale/necko.properties", getter_AddRefs(stringBundle));
3121 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3122
3123 nsAutoString messageString;
3124 rv = stringBundle->GetStringFromName("RepostFormData", messageString);
3125 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3126 bool repost = false;
3127
3128 nsCOMPtr<nsIPrompt> prompt;
3129 GetCallback(prompt);
3130 if (!prompt) return NS_ERROR_NO_INTERFACE;
3131
3132 prompt->Confirm(nullptr, messageString.get(), &repost);
3133 if (!repost) return NS_ERROR_FAILURE;
3134 }
3135
3136 return rv;
3137}
3138
3139nsresult nsHttpChannel::ProxyFailover() {
3140 LOG(("nsHttpChannel::ProxyFailover [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProxyFailover [this=%p]\n", this); } } while
(0)
;
3141
3142 nsresult rv;
3143
3144 nsCOMPtr<nsIProtocolProxyService> pps;
3145 pps = mozilla::components::ProtocolProxy::Service(&rv);
3146 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3147
3148 nsCOMPtr<nsIProxyInfo> pi;
3149 rv = pps->GetFailoverForProxy(mConnectionInfo->ProxyInfo(), mURI, mStatus,
3150 getter_AddRefs(pi));
3151#ifdef MOZ_PROXY_DIRECT_FAILOVER1
3152 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3153 if (!StaticPrefs::network_proxy_failover_direct()) {
3154 return rv;
3155 }
3156 // If this request used a failed proxy and there is no failover available,
3157 // fallback to DIRECT connections for conservative requests.
3158 if (LoadBeConservative()) {
3159 rv = pps->NewProxyInfo("direct"_ns, ""_ns, 0, ""_ns, ""_ns, 0, UINT32_MAX(4294967295U),
3160 nullptr, getter_AddRefs(pi));
3161 }
3162#endif
3163 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3164 return rv;
3165 }
3166#ifdef MOZ_PROXY_DIRECT_FAILOVER1
3167 }
3168#endif
3169
3170 // XXXbz so where does this codepath remove us from the loadgroup,
3171 // exactly?
3172 return AsyncDoReplaceWithProxy(pi);
3173}
3174
3175void nsHttpChannel::SetHTTPSSVCRecord(
3176 already_AddRefed<nsIDNSHTTPSSVCRecord>&& aRecord) {
3177 LOG(("nsHttpChannel::SetHTTPSSVCRecord [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetHTTPSSVCRecord [this=%p]\n", this); } } while
(0)
;
3178 nsCOMPtr<nsIDNSHTTPSSVCRecord> record = aRecord;
3179 MOZ_ASSERT(!mHTTPSSVCRecord)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mHTTPSSVCRecord)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mHTTPSSVCRecord))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mHTTPSSVCRecord"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3179); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mHTTPSSVCRecord"
")"); do { *((volatile int*)__null) = 3179; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3180 mHTTPSSVCRecord.emplace(std::move(record));
3181}
3182
3183void nsHttpChannel::HandleAsyncRedirectChannelToHttps() {
3184 MOZ_ASSERT(!mCallOnResume, "How did that happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCallOnResume)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mCallOnResume))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mCallOnResume"
" (" "How did that happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3184); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 3184; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
3185
3186 if (mSuspendCount) {
3187 LOG(("Waiting until resume to do async redirect to https [this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to do async redirect to https [this=%p]\n"
, this); } } while (0)
3188 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to do async redirect to https [this=%p]\n"
, this); } } while (0)
;
3189 mCallOnResume = [](nsHttpChannel* self) {
3190 self->HandleAsyncRedirectChannelToHttps();
3191 return NS_OK;
3192 };
3193 return;
3194 }
3195
3196 nsresult rv = StartRedirectChannelToHttps();
3197 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3198 rv = ContinueAsyncRedirectChannelToURI(rv);
3199 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3200 LOG(("ContinueAsyncRedirectChannelToURI failed (%08x) [this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueAsyncRedirectChannelToURI failed (%08x) [this=%p]\n"
, static_cast<uint32_t>(rv), this); } } while (0)
3201 static_cast<uint32_t>(rv), this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueAsyncRedirectChannelToURI failed (%08x) [this=%p]\n"
, static_cast<uint32_t>(rv), this); } } while (0)
;
3202 }
3203 }
3204}
3205
3206nsresult nsHttpChannel::StartRedirectChannelToHttps() {
3207 LOG(("nsHttpChannel::HandleAsyncRedirectChannelToHttps() [STS]\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::HandleAsyncRedirectChannelToHttps() [STS]\n"
); } } while (0)
;
3208
3209 nsCOMPtr<nsIURI> upgradedURI;
3210 nsresult rv = NS_GetSecureUpgradedURI(mURI, getter_AddRefs(upgradedURI));
3211 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3211); return rv; } } while (false)
;
3212
3213 return StartRedirectChannelToURI(
3214 upgradedURI, nsIChannelEventSink::REDIRECT_PERMANENT |
3215 nsIChannelEventSink::REDIRECT_STS_UPGRADE);
3216}
3217
3218void nsHttpChannel::HandleAsyncAPIRedirect() {
3219 MOZ_ASSERT(!mCallOnResume, "How did that happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCallOnResume)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mCallOnResume))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mCallOnResume"
" (" "How did that happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3219); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 3219; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
3220 MOZ_ASSERT(mAPIRedirectToURI, "How did that happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAPIRedirectToURI)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAPIRedirectToURI))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mAPIRedirectToURI"
" (" "How did that happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3220); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAPIRedirectToURI"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 3220; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
3221
3222 if (mSuspendCount) {
3223 LOG(("Waiting until resume to do async API redirect [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to do async API redirect [this=%p]\n"
, this); } } while (0)
;
3224 mCallOnResume = [](nsHttpChannel* self) {
3225 self->HandleAsyncAPIRedirect();
3226 return NS_OK;
3227 };
3228 return;
3229 }
3230
3231 nsresult rv = StartRedirectChannelToURI(
3232 mAPIRedirectToURI, nsIChannelEventSink::REDIRECT_PERMANENT);
3233 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3234 rv = ContinueAsyncRedirectChannelToURI(rv);
3235 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3236 LOG(("ContinueAsyncRedirectChannelToURI failed (%08x) [this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueAsyncRedirectChannelToURI failed (%08x) [this=%p]\n"
, static_cast<uint32_t>(rv), this); } } while (0)
3237 static_cast<uint32_t>(rv), this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueAsyncRedirectChannelToURI failed (%08x) [this=%p]\n"
, static_cast<uint32_t>(rv), this); } } while (0)
;
3238 }
3239 }
3240}
3241
3242void nsHttpChannel::HandleAsyncRedirectToUnstrippedURI() {
3243 MOZ_ASSERT(!mCallOnResume, "How did that happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCallOnResume)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mCallOnResume))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mCallOnResume"
" (" "How did that happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3243); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 3243; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
3244
3245 if (mSuspendCount) {
3246 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to do async redirect to unstripped URI "
"[this=%p]\n", this); } } while (0)
3247 ("Waiting until resume to do async redirect to unstripped URI "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to do async redirect to unstripped URI "
"[this=%p]\n", this); } } while (0)
3248 "[this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to do async redirect to unstripped URI "
"[this=%p]\n", this); } } while (0)
3249 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume to do async redirect to unstripped URI "
"[this=%p]\n", this); } } while (0)
;
3250 mCallOnResume = [](nsHttpChannel* self) {
3251 self->HandleAsyncRedirectToUnstrippedURI();
3252 return NS_OK;
3253 };
3254 return;
3255 }
3256
3257 nsCOMPtr<nsIURI> unstrippedURI;
3258 mLoadInfo->GetUnstrippedURI(getter_AddRefs(unstrippedURI));
3259
3260 // Clear the unstripped URI from the loadInfo before starting redirect in case
3261 // endless redirect.
3262 mLoadInfo->SetUnstrippedURI(nullptr);
3263
3264 nsresult rv = StartRedirectChannelToURI(
3265 unstrippedURI, nsIChannelEventSink::REDIRECT_PERMANENT);
3266
3267 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3268 rv = ContinueAsyncRedirectChannelToURI(rv);
3269 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3270 LOG(("ContinueAsyncRedirectChannelToURI failed (%08x) [this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueAsyncRedirectChannelToURI failed (%08x) [this=%p]\n"
, static_cast<uint32_t>(rv), this); } } while (0)
3271 static_cast<uint32_t>(rv), this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "ContinueAsyncRedirectChannelToURI failed (%08x) [this=%p]\n"
, static_cast<uint32_t>(rv), this); } } while (0)
;
3272 }
3273 }
3274}
3275nsresult nsHttpChannel::RedirectToNewChannelForAuthRetry() {
3276 LOG(("nsHttpChannel::RedirectToNewChannelForAuthRetry %p", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::RedirectToNewChannelForAuthRetry %p", this)
; } } while (0)
;
3277 nsresult rv = NS_OK;
3278
3279 nsCOMPtr<nsILoadInfo> redirectLoadInfo = CloneLoadInfoForRedirect(
3280 mURI, nsIChannelEventSink::REDIRECT_INTERNAL |
3281 nsIChannelEventSink::REDIRECT_AUTH_RETRY);
3282
3283 nsCOMPtr<nsIIOService> ioService;
3284
3285 rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
3286 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3286); return rv; } } while (false)
;
3287
3288 nsCOMPtr<nsIChannel> newChannel;
3289 rv = gHttpHandler->NewProxiedChannel(mURI, mProxyInfo, mProxyResolveFlags,
3290 mProxyURI, mLoadInfo,
3291 getter_AddRefs(newChannel));
3292
3293 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3293); return rv; } } while (false)
;
3294
3295 rv = SetupReplacementChannel(mURI, newChannel, true,
3296 nsIChannelEventSink::REDIRECT_INTERNAL |
3297 nsIChannelEventSink::REDIRECT_AUTH_RETRY);
3298 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3298); return rv; } } while (false)
;
3299
3300 // rewind the upload stream
3301 if (mUploadStream) {
3302 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
3303 nsresult rv = NS_ERROR_NO_INTERFACE;
3304 if (seekable) {
3305 rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
3306 }
3307
3308 // This should not normally happen, but it's possible that big memory
3309 // blobs originating in the other process can't be rewinded.
3310 // In that case we just fail the request, otherwise the content length
3311 // will not match and this load will never complete.
3312 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3312); return rv; } } while (false)
;
3313 }
3314
3315 RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(newChannel);
3316
3317 MOZ_ASSERT(mAuthProvider)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAuthProvider)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAuthProvider))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mAuthProvider",
"/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3317); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAuthProvider"
")"); do { *((volatile int*)__null) = 3317; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3318 httpChannelImpl->mAuthProvider = std::move(mAuthProvider);
3319
3320 httpChannelImpl->mProxyInfo = mProxyInfo;
3321
3322 if ((mCaps & NS_HTTP_STICKY_CONNECTION(1 << 2)) ||
3323 mTransaction->HasStickyConnection()) {
3324 mConnectionInfo = mTransaction->GetConnInfo();
3325
3326 httpChannelImpl->mTransactionSticky = mTransaction;
3327
3328 if (mTransaction->Http2Disabled()) {
3329 httpChannelImpl->mCaps |= NS_HTTP_DISALLOW_SPDY(1 << 7);
3330 }
3331 if (mTransaction->Http3Disabled()) {
3332 httpChannelImpl->mCaps |= NS_HTTP_DISALLOW_HTTP3(1 << 21);
3333 }
3334 }
3335 httpChannelImpl->mCaps |= NS_HTTP_STICKY_CONNECTION(1 << 2);
3336 if (LoadAuthConnectionRestartable()) {
3337 httpChannelImpl->mCaps |= NS_HTTP_CONNECTION_RESTARTABLE(1 << 13);
3338 } else {
3339 httpChannelImpl->mCaps &= ~NS_HTTP_CONNECTION_RESTARTABLE(1 << 13);
3340 }
3341
3342 MOZ_ASSERT(mConnectionInfo)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mConnectionInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mConnectionInfo))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mConnectionInfo"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3342); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mConnectionInfo"
")"); do { *((volatile int*)__null) = 3342; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3343 httpChannelImpl->mConnectionInfo = mConnectionInfo->Clone();
3344
3345 // we need to store the state to skip unnecessary checks in the new channel
3346 httpChannelImpl->StoreAuthRedirectedChannel(true);
3347
3348 // We must copy proxy and auth header to the new channel.
3349 // Although the new channel can populate auth headers from auth cache, we
3350 // would still like to use the auth headers generated in this channel. The
3351 // main reason for doing this is that certain connection-based/stateful auth
3352 // schemes like NTLM will fail when we try generate the credentials more than
3353 // the number of times the server has presented us the challenge due to the
3354 // usage of nonce in generating the credentials Copying the auth header will
3355 // bypass generation of the credentials
3356 nsAutoCString authVal;
3357 if (NS_SUCCEEDED(GetRequestHeader("Proxy-Authorization"_ns, authVal))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetRequestHeader(
"Proxy-Authorization"_ns, authVal))), 1)))
) {
3358 httpChannelImpl->SetRequestHeader("Proxy-Authorization"_ns, authVal, false);
3359 }
3360 if (NS_SUCCEEDED(GetRequestHeader("Authorization"_ns, authVal))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetRequestHeader(
"Authorization"_ns, authVal))), 1)))
) {
3361 httpChannelImpl->SetRequestHeader("Authorization"_ns, authVal, false);
3362 }
3363
3364 httpChannelImpl->SetBlockAuthPrompt(LoadBlockAuthPrompt());
3365 mRedirectChannel = newChannel;
3366
3367 rv = gHttpHandler->AsyncOnChannelRedirect(
3368 this, newChannel,
3369 nsIChannelEventSink::REDIRECT_INTERNAL |
3370 nsIChannelEventSink::REDIRECT_AUTH_RETRY);
3371
3372 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = WaitForRedirectCallback();
3373
3374 // redirected channel will be opened after we receive the OnStopRequest
3375
3376 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3377 AutoRedirectVetoNotifier notifier(this, rv);
3378 mRedirectChannel = nullptr;
3379 }
3380
3381 return rv;
3382}
3383nsresult nsHttpChannel::StartRedirectChannelToURI(nsIURI* upgradedURI,
3384 uint32_t flags) {
3385 nsresult rv = NS_OK;
3386 LOG(("nsHttpChannel::StartRedirectChannelToURI()\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::StartRedirectChannelToURI()\n"); } } while (
0)
;
3387
3388 nsCOMPtr<nsIChannel> newChannel;
3389 nsCOMPtr<nsILoadInfo> redirectLoadInfo =
3390 CloneLoadInfoForRedirect(upgradedURI, flags);
3391
3392 nsCOMPtr<nsIIOService> ioService;
3393 rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
3394 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3394); return rv; } } while (false)
;
3395
3396 rv = NS_NewChannelInternal(getter_AddRefs(newChannel), upgradedURI,
3397 redirectLoadInfo,
3398 nullptr, // PerformanceStorage
3399 nullptr, // aLoadGroup
3400 nullptr, // aCallbacks
3401 nsIRequest::LOAD_NORMAL, ioService);
3402 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3402); return rv; } } while (false)
;
3403
3404 rv = SetupReplacementChannel(upgradedURI, newChannel, true, flags);
3405 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3405); return rv; } } while (false)
;
3406
3407 if (mHTTPSSVCRecord) {
3408 RefPtr<nsHttpChannel> httpChan = do_QueryObject(newChannel);
3409 nsCOMPtr<nsIDNSHTTPSSVCRecord> rec = mHTTPSSVCRecord.ref();
3410 if (httpChan && rec) {
3411 httpChan->SetHTTPSSVCRecord(rec.forget());
3412 }
3413 }
3414
3415 // Inform consumers about this fake redirect
3416 mRedirectChannel = newChannel;
3417
3418 PushRedirectAsyncFunc(&nsHttpChannel::ContinueAsyncRedirectChannelToURI);
3419 rv = gHttpHandler->AsyncOnChannelRedirect(this, newChannel, flags);
3420
3421 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = WaitForRedirectCallback();
3422
3423 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3424 AutoRedirectVetoNotifier notifier(this, rv);
3425
3426 /* Remove the async call to ContinueAsyncRedirectChannelToURI().
3427 * It is called directly by our callers upon return (to clean up
3428 * the failed redirect). */
3429 PopRedirectAsyncFunc(&nsHttpChannel::ContinueAsyncRedirectChannelToURI);
3430 }
3431
3432 return rv;
3433}
3434
3435nsresult nsHttpChannel::ContinueAsyncRedirectChannelToURI(nsresult rv) {
3436 LOG(("nsHttpChannel::ContinueAsyncRedirectChannelToURI [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueAsyncRedirectChannelToURI [this=%p]"
, this); } } while (0)
;
3437
3438 // Since we handle mAPIRedirectToURI also after on-examine-response handler
3439 // rather drop it here to avoid any redirect loops, even just hypothetical.
3440 mAPIRedirectToURI = nullptr;
3441
3442 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3443 rv = OpenRedirectChannel(rv);
3444 }
3445
3446 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3447 // Cancel the channel here, the update to https had been vetoed
3448 // but from the security reasons we have to discard the whole channel
3449 // load.
3450 Cancel(rv);
3451 }
3452
3453 if (mLoadGroup) {
3454 mLoadGroup->RemoveRequest(this, nullptr, mStatus);
3455 }
3456
3457 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && !mCachePump && !mTransactionPump) {
3458 // We have to manually notify the listener because there is not any pump
3459 // that would call our OnStart/StopRequest after resume from waiting for
3460 // the redirect callback.
3461 DoNotifyListener();
3462 }
3463
3464 return rv;
3465}
3466
3467nsresult nsHttpChannel::OpenRedirectChannel(nsresult rv) {
3468 AutoRedirectVetoNotifier notifier(this, rv);
3469
3470 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3471
3472 if (!mRedirectChannel) {
3473 LOG((do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OpenRedirectChannel unexpected null redirect channel"
); } } while (0)
3474 "nsHttpChannel::OpenRedirectChannel unexpected null redirect channel"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OpenRedirectChannel unexpected null redirect channel"
); } } while (0)
;
3475 return NS_ERROR_FAILURE;
3476 }
3477
3478 // Make sure to do this after we received redirect veto answer,
3479 // i.e. after all sinks had been notified
3480 mRedirectChannel->SetOriginalURI(mOriginalURI);
3481
3482 // open new channel
3483 rv = mRedirectChannel->AsyncOpen(mListener);
3484
3485 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3485); return rv; } } while (false)
;
3486
3487 mStatus = NS_BINDING_REDIRECTED;
3488
3489 notifier.RedirectSucceeded();
3490
3491 ReleaseListeners();
3492
3493 return NS_OK;
3494}
3495
3496nsresult nsHttpChannel::AsyncDoReplaceWithProxy(nsIProxyInfo* pi) {
3497 LOG(("nsHttpChannel::AsyncDoReplaceWithProxy [this=%p pi=%p]", this, pi))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AsyncDoReplaceWithProxy [this=%p pi=%p]", this
, pi); } } while (0)
;
3498 nsresult rv;
3499
3500 nsCOMPtr<nsIChannel> newChannel;
3501 rv = gHttpHandler->NewProxiedChannel(mURI, pi, mProxyResolveFlags, mProxyURI,
3502 mLoadInfo, getter_AddRefs(newChannel));
3503 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3504
3505 uint32_t flags = nsIChannelEventSink::REDIRECT_INTERNAL;
3506
3507 rv = SetupReplacementChannel(mURI, newChannel, true, flags);
3508 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3509
3510 // Inform consumers about this fake redirect
3511 mRedirectChannel = newChannel;
3512
3513 PushRedirectAsyncFunc(&nsHttpChannel::OpenRedirectChannel);
3514 rv = gHttpHandler->AsyncOnChannelRedirect(this, newChannel, flags);
3515
3516 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = WaitForRedirectCallback();
3517
3518 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3519 AutoRedirectVetoNotifier notifier(this, rv);
3520 PopRedirectAsyncFunc(&nsHttpChannel::OpenRedirectChannel);
3521 }
3522
3523 return rv;
3524}
3525
3526nsresult nsHttpChannel::ResolveProxy() {
3527 LOG(("nsHttpChannel::ResolveProxy [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResolveProxy [this=%p]\n", this); } } while
(0)
;
3528
3529 nsresult rv;
3530
3531 nsCOMPtr<nsIProtocolProxyService> pps;
3532 pps = mozilla::components::ProtocolProxy::Service(&rv);
3533 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3534
3535 // using the nsIProtocolProxyService2 allows a minor performance
3536 // optimization, but if an add-on has only provided the original interface
3537 // then it is ok to use that version.
3538 nsCOMPtr<nsIProtocolProxyService2> pps2 = do_QueryInterface(pps);
3539 if (pps2) {
3540 rv = pps2->AsyncResolve2(this, mProxyResolveFlags, this, nullptr,
3541 getter_AddRefs(mProxyRequest));
3542 } else {
3543 rv = pps->AsyncResolve(static_cast<nsIChannel*>(this), mProxyResolveFlags,
3544 this, nullptr, getter_AddRefs(mProxyRequest));
3545 }
3546
3547 return rv;
3548}
3549
3550bool nsHttpChannel::ResponseWouldVary(nsICacheEntry* entry) {
3551 nsresult rv;
3552 nsAutoCString buf, metaKey;
3553 Unused << mCachedResponseHead->GetHeader(nsHttp::Vary, buf);
3554
3555 constexpr auto prefix = "request-"_ns;
3556
3557 // enumerate the elements of the Vary header...
3558 for (const nsACString& token :
3559 nsCCharSeparatedTokenizer(buf, NS_HTTP_HEADER_SEP',').ToRange()) {
3560 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResponseWouldVary [channel=%p] " "processing %s\n"
, this, nsPromiseFlatCString(token).get()); } } while (0)
3561 ("nsHttpChannel::ResponseWouldVary [channel=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResponseWouldVary [channel=%p] " "processing %s\n"
, this, nsPromiseFlatCString(token).get()); } } while (0)
3562 "processing %s\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResponseWouldVary [channel=%p] " "processing %s\n"
, this, nsPromiseFlatCString(token).get()); } } while (0)
3563 this, nsPromiseFlatCString(token).get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResponseWouldVary [channel=%p] " "processing %s\n"
, this, nsPromiseFlatCString(token).get()); } } while (0)
;
3564 //
3565 // if "*", then assume response would vary. technically speaking,
3566 // "Vary: header, *" is not permitted, but we allow it anyways.
3567 //
3568 // We hash values of cookie-headers for the following reasons:
3569 //
3570 // 1- cookies can be very large in size
3571 //
3572 // 2- cookies may contain sensitive information. (for parity with
3573 // out policy of not storing Set-cookie headers in the cache
3574 // meta data, we likewise do not want to store cookie headers
3575 // here.)
3576 //
3577 if (token.EqualsLiteral("*")) {
3578 return true; // if we encounter this, just get out of here
3579 }
3580
3581 // build cache meta data key...
3582 metaKey = prefix + token;
3583
3584 // check the last value of the given request header to see if it has
3585 // since changed. if so, then indeed the cached response is invalid.
3586 nsCString lastVal;
3587 entry->GetMetaDataElement(metaKey.get(), getter_Copies(lastVal));
3588 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResponseWouldVary [channel=%p] " "stored value = \"%s\"\n"
, this, lastVal.get()); } } while (0)
3589 ("nsHttpChannel::ResponseWouldVary [channel=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResponseWouldVary [channel=%p] " "stored value = \"%s\"\n"
, this, lastVal.get()); } } while (0)
3590 "stored value = \"%s\"\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResponseWouldVary [channel=%p] " "stored value = \"%s\"\n"
, this, lastVal.get()); } } while (0)
3591 this, lastVal.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResponseWouldVary [channel=%p] " "stored value = \"%s\"\n"
, this, lastVal.get()); } } while (0)
;
3592
3593 // Look for value of "Cookie" in the request headers
3594 nsHttpAtom atom = nsHttp::ResolveAtom(token);
3595 nsAutoCString newVal;
3596 bool hasHeader = NS_SUCCEEDED(mRequestHead.GetHeader(atom, newVal))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mRequestHead.GetHeader
(atom, newVal))), 1)))
;
3597 if (!lastVal.IsEmpty()) {
3598 // value for this header in cache, but no value in request
3599 if (!hasHeader) {
3600 return true; // yes - response would vary
3601 }
3602
3603 // If this is a cookie-header, stored metadata is not
3604 // the value itself but the hash. So we also hash the
3605 // outgoing value here in order to compare the hashes
3606 nsAutoCString hash;
3607 if (atom == nsHttp::Cookie) {
3608 rv = Hash(newVal.get(), hash);
3609 // If hash failed, be conservative (the cached hash
3610 // exists at this point) and claim response would vary
3611 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return true;
3612 newVal = hash;
3613
3614 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResponseWouldVary [this=%p] " "set-cookie value hashed to %s\n"
, this, newVal.get()); } } while (0)
3615 ("nsHttpChannel::ResponseWouldVary [this=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResponseWouldVary [this=%p] " "set-cookie value hashed to %s\n"
, this, newVal.get()); } } while (0)
3616 "set-cookie value hashed to %s\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResponseWouldVary [this=%p] " "set-cookie value hashed to %s\n"
, this, newVal.get()); } } while (0)
3617 this, newVal.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResponseWouldVary [this=%p] " "set-cookie value hashed to %s\n"
, this, newVal.get()); } } while (0)
;
3618 }
3619
3620 if (!newVal.Equals(lastVal)) {
3621 return true; // yes, response would vary
3622 }
3623
3624 } else if (hasHeader) { // old value is empty, but newVal is set
3625 return true;
3626 }
3627 }
3628
3629 return false;
3630}
3631
3632// We need to have an implementation of this function just so that we can keep
3633// all references to mCallOnResume of type nsHttpChannel: it's not OK in C++
3634// to set a member function ptr to a base class function.
3635void nsHttpChannel::HandleAsyncAbort() {
3636 HttpAsyncAborter<nsHttpChannel>::HandleAsyncAbort();
3637}
3638
3639//-----------------------------------------------------------------------------
3640// nsHttpChannel <byte-range>
3641//-----------------------------------------------------------------------------
3642
3643bool nsHttpChannel::IsResumable(int64_t partialLen, int64_t contentLength,
3644 bool ignoreMissingPartialLen) const {
3645 bool hasContentEncoding =
3646 mCachedResponseHead->HasHeader(nsHttp::Content_Encoding);
3647
3648 nsAutoCString etag;
3649 Unused << mCachedResponseHead->GetHeader(nsHttp::ETag, etag);
3650 bool hasWeakEtag = !etag.IsEmpty() && StringBeginsWith(etag, "W/"_ns);
3651
3652 return (partialLen < contentLength) &&
3653 (partialLen > 0 || ignoreMissingPartialLen) && !hasContentEncoding &&
3654 !hasWeakEtag && mCachedResponseHead->IsResumable() &&
3655 !LoadCustomConditionalRequest() && !mCachedResponseHead->NoStore();
3656}
3657
3658nsresult nsHttpChannel::MaybeSetupByteRangeRequest(
3659 int64_t partialLen, int64_t contentLength, bool ignoreMissingPartialLen) {
3660 // Be pesimistic
3661 StoreIsPartialRequest(false);
3662
3663 if (!IsResumable(partialLen, contentLength, ignoreMissingPartialLen)) {
3664 return NS_ERROR_NOT_RESUMABLE;
3665 }
3666
3667 // looks like a partial entry we can reuse; add If-Range
3668 // and Range headers.
3669 nsresult rv = SetupByteRangeRequest(partialLen);
3670 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3671 // Make the request unconditional again.
3672 UntieByteRangeRequest();
3673 }
3674
3675 return rv;
3676}
3677
3678nsresult nsHttpChannel::SetupByteRangeRequest(int64_t partialLen) {
3679 // cached content has been found to be partial, add necessary request
3680 // headers to complete cache entry.
3681
3682 // use strongest validator available...
3683 nsAutoCString val;
3684 Unused << mCachedResponseHead->GetHeader(nsHttp::ETag, val);
3685 if (val.IsEmpty()) {
3686 Unused << mCachedResponseHead->GetHeader(nsHttp::Last_Modified, val);
3687 }
3688 if (val.IsEmpty()) {
3689 // if we hit this code it means mCachedResponseHead->IsResumable() is
3690 // either broken or not being called.
3691 MOZ_ASSERT_UNREACHABLE("no cache validator")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"no cache validator" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3691); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "no cache validator" ")"); do { *
((volatile int*)__null) = 3691; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
3692 StoreIsPartialRequest(false);
3693 return NS_ERROR_FAILURE;
3694 }
3695
3696 char buf[64];
3697 SprintfLiteral(buf, "bytes=%" PRId64"l" "d" "-", partialLen);
3698
3699 DebugOnly<nsresult> rv{};
3700 rv = mRequestHead.SetHeader(nsHttp::Range, nsDependentCString(buf));
3701 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3701); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3701; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3702 rv = mRequestHead.SetHeader(nsHttp::If_Range, val);
3703 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3703); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3703; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3704 StoreIsPartialRequest(true);
3705
3706 return NS_OK;
3707}
3708
3709void nsHttpChannel::UntieByteRangeRequest() {
3710 DebugOnly<nsresult> rv{};
3711 rv = mRequestHead.ClearHeader(nsHttp::Range);
3712 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3712); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3712; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3713 rv = mRequestHead.ClearHeader(nsHttp::If_Range);
3714 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3714); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3714; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3715}
3716
3717nsresult nsHttpChannel::ProcessPartialContent(
3718 const std::function<nsresult(nsHttpChannel*, nsresult)>&
3719 aContinueProcessResponseFunc) {
3720 // ok, we've just received a 206
3721 //
3722 // we need to stream whatever data is in the cache out first, and then
3723 // pick up whatever data is on the wire, writing it into the cache.
3724
3725 LOG(("nsHttpChannel::ProcessPartialContent [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessPartialContent [this=%p]\n", this); }
} while (0)
;
3726
3727 NS_ENSURE_TRUE(mCachedResponseHead, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(mCachedResponseHead)), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mCachedResponseHead"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3727); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
3728 NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_NOT_INITIALIZED)do { if ((__builtin_expect(!!(!(mCacheEntry)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mCacheEntry" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3728); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
3729
3730 // Check if the content-encoding we now got is different from the one we
3731 // got before
3732 nsAutoCString contentEncoding, cachedContentEncoding;
3733 // It is possible that there is not such headers
3734 Unused << mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
3735 Unused << mCachedResponseHead->GetHeader(nsHttp::Content_Encoding,
3736 cachedContentEncoding);
3737 if (nsCRT::strcasecmp(contentEncoding.get(), cachedContentEncoding.get()) !=
3738 0) {
3739 Cancel(NS_ERROR_INVALID_CONTENT_ENCODING);
3740 return CallOnStartRequest();
3741 }
3742
3743 nsresult rv;
3744
3745 int64_t cachedContentLength = mCachedResponseHead->ContentLength();
3746 int64_t entitySize = mResponseHead->TotalEntitySize();
3747
3748 nsAutoCString contentRange;
3749 Unused << mResponseHead->GetHeader(nsHttp::Content_Range, contentRange);
3750 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessPartialContent [this=%p trans=%p] " "original content-length %"
"l" "d" ", entity-size %" "l" "d" ", content-range %s\n", this
, mTransaction.get(), cachedContentLength, entitySize, contentRange
.get()); } } while (0)
3751 ("nsHttpChannel::ProcessPartialContent [this=%p trans=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessPartialContent [this=%p trans=%p] " "original content-length %"
"l" "d" ", entity-size %" "l" "d" ", content-range %s\n", this
, mTransaction.get(), cachedContentLength, entitySize, contentRange
.get()); } } while (0)
3752 "original content-length %" PRId64 ", entity-size %" PRId64do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessPartialContent [this=%p trans=%p] " "original content-length %"
"l" "d" ", entity-size %" "l" "d" ", content-range %s\n", this
, mTransaction.get(), cachedContentLength, entitySize, contentRange
.get()); } } while (0)
3753 ", content-range %s\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessPartialContent [this=%p trans=%p] " "original content-length %"
"l" "d" ", entity-size %" "l" "d" ", content-range %s\n", this
, mTransaction.get(), cachedContentLength, entitySize, contentRange
.get()); } } while (0)
3754 this, mTransaction.get(), cachedContentLength, entitySize,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessPartialContent [this=%p trans=%p] " "original content-length %"
"l" "d" ", entity-size %" "l" "d" ", content-range %s\n", this
, mTransaction.get(), cachedContentLength, entitySize, contentRange
.get()); } } while (0)
3755 contentRange.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessPartialContent [this=%p trans=%p] " "original content-length %"
"l" "d" ", entity-size %" "l" "d" ", content-range %s\n", this
, mTransaction.get(), cachedContentLength, entitySize, contentRange
.get()); } } while (0)
;
3756
3757 if ((entitySize >= 0) && (cachedContentLength >= 0) &&
3758 (entitySize != cachedContentLength)) {
3759 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessPartialContent [this=%p] " "206 has different total entity size than the content length "
"of the original partially cached entity.\n", this); } } while
(0)
3760 ("nsHttpChannel::ProcessPartialContent [this=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessPartialContent [this=%p] " "206 has different total entity size than the content length "
"of the original partially cached entity.\n", this); } } while
(0)
3761 "206 has different total entity size than the content length "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessPartialContent [this=%p] " "206 has different total entity size than the content length "
"of the original partially cached entity.\n", this); } } while
(0)
3762 "of the original partially cached entity.\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessPartialContent [this=%p] " "206 has different total entity size than the content length "
"of the original partially cached entity.\n", this); } } while
(0)
3763 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessPartialContent [this=%p] " "206 has different total entity size than the content length "
"of the original partially cached entity.\n", this); } } while
(0)
;
3764
3765 mCacheEntry->AsyncDoom(nullptr);
3766 Cancel(NS_ERROR_CORRUPTED_CONTENT);
3767 return CallOnStartRequest();
3768 }
3769
3770 if (LoadConcurrentCacheAccess()) {
3771 // We started to read cached data sooner than its write has been done.
3772 // But the concurrent write has not finished completely, so we had to
3773 // do a range request. Now let the content coming from the network
3774 // be presented to consumers and also stored to the cache entry.
3775
3776 rv = InstallCacheListener(mLogicalOffset);
3777 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3778 } else {
3779 // suspend the current transaction
3780 rv = mTransactionPump->Suspend();
3781 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3782 }
3783
3784 // merge any new headers with the cached response headers
3785 mCachedResponseHead->UpdateHeaders(mResponseHead.get());
3786
3787 // update the cached response head
3788 nsAutoCString head;
3789 mCachedResponseHead->Flatten(head, true);
3790 rv = mCacheEntry->SetMetaDataElement("response-head", head.get());
3791 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3792
3793 // make the cached response be the current response
3794 mResponseHead = std::move(mCachedResponseHead);
3795
3796 UpdateInhibitPersistentCachingFlag();
3797
3798 rv = UpdateExpirationTime();
3799 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3800
3801 // notify observers interested in looking at a response that has been
3802 // merged with any cached headers (http-on-examine-merged-response).
3803 gHttpHandler->OnExamineMergedResponse(this);
3804
3805 if (LoadConcurrentCacheAccess()) {
3806 StoreCachedContentIsPartial(false);
3807 // Leave the ConcurrentCacheAccess flag set, we want to use it
3808 // to prevent duplicate OnStartRequest call on the target listener
3809 // in case this channel is canceled before it gets its OnStartRequest
3810 // from the http transaction.
3811 return rv;
3812 }
3813
3814 // Now we continue reading the network response.
3815 // the cached content is valid, although incomplete.
3816 mCachedContentIsValid = true;
3817 return CallOrWaitForResume([aContinueProcessResponseFunc](auto* self) {
3818 nsresult rv = self->ReadFromCache();
3819 return aContinueProcessResponseFunc(self, rv);
3820 });
3821}
3822
3823nsresult nsHttpChannel::OnDoneReadingPartialCacheEntry(bool* streamDone) {
3824 nsresult rv;
3825
3826 LOG(("nsHttpChannel::OnDoneReadingPartialCacheEntry [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnDoneReadingPartialCacheEntry [this=%p]", this
); } } while (0)
;
3827
3828 // by default, assume we would have streamed all data or failed...
3829 *streamDone = true;
3830
3831 // setup cache listener to append to cache entry
3832 int64_t size;
3833 rv = mCacheEntry->GetDataSize(&size);
3834 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3835
3836 rv = InstallCacheListener(size);
3837 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3838
3839 // Entry is valid, do it now, after the output stream has been opened,
3840 // otherwise when done earlier, pending readers would consider the cache
3841 // entry still as partial (CacheEntry::GetDataSize would return the partial
3842 // data size) and consumers would do the conditional request again.
3843 rv = mCacheEntry->SetValid();
3844 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3845
3846 // need to track the logical offset of the data being sent to our listener
3847 mLogicalOffset = size;
3848
3849 // we're now completing the cached content, so we can clear this flag.
3850 // this puts us in the state of a regular download.
3851 StoreCachedContentIsPartial(false);
3852 // The cache input stream pump is finished, we do not need it any more.
3853 // (see bug 1313923)
3854 mCachePump = nullptr;
3855
3856 // resume the transaction if it exists, otherwise the pipe contained the
3857 // remaining part of the document and we've now streamed all of the data.
3858 if (mTransactionPump) {
3859 rv = mTransactionPump->Resume();
3860 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) *streamDone = false;
3861 } else {
3862 MOZ_ASSERT_UNREACHABLE("no transaction")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"no transaction" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3862); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "no transaction" ")"); do { *((volatile
int*)__null) = 3862; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
3863 }
3864 return rv;
3865}
3866
3867//-----------------------------------------------------------------------------
3868// nsHttpChannel <cache>
3869//-----------------------------------------------------------------------------
3870
3871bool nsHttpChannel::ShouldBypassProcessNotModified() {
3872 if (LoadCustomConditionalRequest()) {
3873 LOG(("Bypassing ProcessNotModified due to custom conditional headers"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Bypassing ProcessNotModified due to custom conditional headers"
); } } while (0)
;
3874 return true;
3875 }
3876
3877 if (!mDidReval) {
3878 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Server returned a 304 response even though we did not send a "
"conditional request"); } } while (0)
3879 ("Server returned a 304 response even though we did not send a "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Server returned a 304 response even though we did not send a "
"conditional request"); } } while (0)
3880 "conditional request"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Server returned a 304 response even though we did not send a "
"conditional request"); } } while (0)
;
3881 return true;
3882 }
3883
3884 return false;
3885}
3886
3887nsresult nsHttpChannel::ProcessNotModified(
3888 const std::function<nsresult(nsHttpChannel*, nsresult)>&
3889 aContinueProcessResponseFunc) {
3890 nsresult rv;
3891
3892 LOG(("nsHttpChannel::ProcessNotModified [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ProcessNotModified [this=%p]\n", this); } }
while (0)
;
3893
3894 // Assert ShouldBypassProcessNotModified() has been checked before call to
3895 // ProcessNotModified().
3896 MOZ_ASSERT(!ShouldBypassProcessNotModified())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!ShouldBypassProcessNotModified())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!ShouldBypassProcessNotModified
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!ShouldBypassProcessNotModified()", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3896); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!ShouldBypassProcessNotModified()"
")"); do { *((volatile int*)__null) = 3896; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3897
3898 MOZ_ASSERT(mCachedResponseHead)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCachedResponseHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCachedResponseHead))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("mCachedResponseHead"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3898); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCachedResponseHead"
")"); do { *((volatile int*)__null) = 3898; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3899 MOZ_ASSERT(mCacheEntry)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCacheEntry)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCacheEntry))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("mCacheEntry", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3899); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCacheEntry"
")"); do { *((volatile int*)__null) = 3899; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3900 NS_ENSURE_TRUE(mCachedResponseHead && mCacheEntry, NS_ERROR_UNEXPECTED)do { if ((__builtin_expect(!!(!(mCachedResponseHead &&
mCacheEntry)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE("
"mCachedResponseHead && mCacheEntry" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3900); return NS_ERROR_UNEXPECTED; } } while (false)
;
3901
3902 // If the 304 response contains a Last-Modified different than the
3903 // one in our cache that is pretty suspicious and is, in at least the
3904 // case of bug 716840, a sign of the server having previously corrupted
3905 // our cache with a bad response. Take the minor step here of just dooming
3906 // that cache entry so there is a fighting chance of getting things on the
3907 // right track.
3908
3909 nsAutoCString lastModifiedCached;
3910 nsAutoCString lastModified304;
3911
3912 rv =
3913 mCachedResponseHead->GetHeader(nsHttp::Last_Modified, lastModifiedCached);
3914 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3915 rv = mResponseHead->GetHeader(nsHttp::Last_Modified, lastModified304);
3916 }
3917
3918 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !lastModified304.Equals(lastModifiedCached)) {
3919 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Cache Entry and 304 Last-Modified Headers Do Not Match " "[%s] and [%s]\n"
, lastModifiedCached.get(), lastModified304.get()); } } while
(0)
3920 ("Cache Entry and 304 Last-Modified Headers Do Not Match "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Cache Entry and 304 Last-Modified Headers Do Not Match " "[%s] and [%s]\n"
, lastModifiedCached.get(), lastModified304.get()); } } while
(0)
3921 "[%s] and [%s]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Cache Entry and 304 Last-Modified Headers Do Not Match " "[%s] and [%s]\n"
, lastModifiedCached.get(), lastModified304.get()); } } while
(0)
3922 lastModifiedCached.get(), lastModified304.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Cache Entry and 304 Last-Modified Headers Do Not Match " "[%s] and [%s]\n"
, lastModifiedCached.get(), lastModified304.get()); } } while
(0)
;
3923
3924 mCacheEntry->AsyncDoom(nullptr);
3925 Telemetry::Accumulate(Telemetry::CACHE_LM_INCONSISTENT, true);
3926 }
3927
3928 // merge any new headers with the cached response headers
3929 mCachedResponseHead->UpdateHeaders(mResponseHead.get());
3930
3931 // update the cached response head
3932 nsAutoCString head;
3933 mCachedResponseHead->Flatten(head, true);
3934 rv = mCacheEntry->SetMetaDataElement("response-head", head.get());
3935 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3936
3937 // make the cached response be the current response
3938 mResponseHead = std::move(mCachedResponseHead);
3939
3940 UpdateInhibitPersistentCachingFlag();
3941
3942 rv = UpdateExpirationTime();
3943 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3944
3945 rv = AddCacheEntryHeaders(mCacheEntry);
3946 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3947
3948 // notify observers interested in looking at a reponse that has been
3949 // merged with any cached headers
3950 gHttpHandler->OnExamineMergedResponse(this);
3951
3952 mCachedContentIsValid = true;
3953
3954 // Tell other consumers the entry is OK to use
3955 rv = mCacheEntry->SetValid();
3956 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3957
3958 return CallOrWaitForResume([aContinueProcessResponseFunc](auto* self) {
3959 nsresult rv = self->ReadFromCache();
3960 return aContinueProcessResponseFunc(self, rv);
3961 });
3962}
3963
3964// Determines if a request is a byte range request for a subrange,
3965// i.e. is a byte range request, but not a 0- byte range request.
3966static bool IsSubRangeRequest(nsHttpRequestHead& aRequestHead) {
3967 nsAutoCString byteRange;
3968 if (NS_FAILED(aRequestHead.GetHeader(nsHttp::Range, byteRange))((bool)(__builtin_expect(!!(NS_FAILED_impl(aRequestHead.GetHeader
(nsHttp::Range, byteRange))), 0)))
) {
3969 return false;
3970 }
3971
3972 if (byteRange.EqualsLiteral("bytes=0-")) {
3973#ifndef ANDROID
3974 glean::network::byte_range_request.Get("cacheable"_ns).Add(1);
3975#endif
3976 return false;
3977 }
3978#ifndef ANDROID
3979 glean::network::byte_range_request.Get("not_cacheable"_ns).Add(1);
3980#endif
3981 return true;
3982}
3983
3984nsresult nsHttpChannel::OpenCacheEntry(bool isHttps) {
3985 // Drop this flag here
3986 StoreConcurrentCacheAccess(0);
3987
3988 LOG(("nsHttpChannel::OpenCacheEntry [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OpenCacheEntry [this=%p]", this); } } while
(0)
;
3989
3990 // make sure we're not abusing this function
3991 MOZ_ASSERT(!mCacheEntry, "cache entry already open")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCacheEntry)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mCacheEntry))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!mCacheEntry" " ("
"cache entry already open" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3991); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCacheEntry"
") (" "cache entry already open" ")"); do { *((volatile int*
)__null) = 3991; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
3992
3993 if (mRequestHead.IsPost()) {
3994 // If the post id is already set then this is an attempt to replay
3995 // a post transaction via the cache. Otherwise, we need a unique
3996 // post id for this transaction.
3997 if (mPostID == 0) mPostID = gHttpHandler->GenerateUniqueID();
3998 } else if (!mRequestHead.IsGet() && !mRequestHead.IsHead()) {
3999 // don't use the cache for other types of requests
4000 return NS_OK;
4001 }
4002
4003 return OpenCacheEntryInternal(isHttps);
4004}
4005
4006nsresult nsHttpChannel::OpenCacheEntryInternal(bool isHttps) {
4007 nsresult rv;
4008
4009 if (LoadResuming()) {
4010 // We don't support caching for requests initiated
4011 // via nsIResumableChannel.
4012 return NS_OK;
4013 }
4014
4015 // Don't cache byte range requests which are subranges, only cache 0-
4016 // byte range requests.
4017 if (IsSubRangeRequest(mRequestHead)) {
4018 return NS_OK;
4019 }
4020
4021 // Handle correctly WaitForCacheEntry
4022 AutoCacheWaitFlags waitFlags(this);
4023
4024 nsAutoCString cacheKey;
4025
4026 nsCOMPtr<nsICacheStorageService> cacheStorageService(
4027 components::CacheStorage::Service());
4028 if (!cacheStorageService) {
4029 return NS_ERROR_NOT_AVAILABLE;
4030 }
4031
4032 nsCOMPtr<nsICacheStorage> cacheStorage;
4033 mCacheEntryURI = mURI;
4034
4035 RefPtr<LoadContextInfo> info = GetLoadContextInfo(this);
4036 if (!info) {
4037 return NS_ERROR_FAILURE;
4038 }
4039
4040 uint32_t cacheEntryOpenFlags;
4041 bool offline = gIOService->IsOffline();
4042
4043 RefPtr<mozilla::dom::BrowsingContext> bc;
4044 mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
4045
4046 bool maybeRCWN = false;
4047
4048 nsAutoCString cacheControlRequestHeader;
4049 Unused << mRequestHead.GetHeader(nsHttp::Cache_Control,
4050 cacheControlRequestHeader);
4051 CacheControlParser cacheControlRequest(cacheControlRequestHeader);
4052 if (cacheControlRequest.NoStore()) {
4053 return NS_OK;
4054 }
4055
4056 if (offline || (mLoadFlags & INHIBIT_CACHING) ||
4057 (bc && bc->Top()->GetForceOffline())) {
4058 if (BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass())((mLoadFlags) & (nsIRequest::LOAD_BYPASS_CACHE | nsICachingChannel
::LOAD_BYPASS_LOCAL_CACHE) && !(((mLoadFlags) & nsIRequest
::LOAD_FROM_CACHE) && (LoadPreferCacheLoadOverBypass(
))))
&&
4059 !offline) {
4060 return NS_OK;
4061 }
4062 cacheEntryOpenFlags = nsICacheStorage::OPEN_READONLY;
4063 StoreCacheEntryIsReadOnly(true);
4064 } else if (BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass())((mLoadFlags) & (nsIRequest::LOAD_BYPASS_CACHE | nsICachingChannel
::LOAD_BYPASS_LOCAL_CACHE) && !(((mLoadFlags) & nsIRequest
::LOAD_FROM_CACHE) && (LoadPreferCacheLoadOverBypass(
))))
) {
4065 cacheEntryOpenFlags = nsICacheStorage::OPEN_TRUNCATE;
4066 } else {
4067 cacheEntryOpenFlags =
4068 nsICacheStorage::OPEN_NORMALLY | nsICacheStorage::CHECK_MULTITHREADED;
4069 }
4070
4071 // Remember the request is a custom conditional request so that we can
4072 // process any 304 response correctly.
4073 StoreCustomConditionalRequest(
4074 mRequestHead.HasHeader(nsHttp::If_Modified_Since) ||
4075 mRequestHead.HasHeader(nsHttp::If_None_Match) ||
4076 mRequestHead.HasHeader(nsHttp::If_Unmodified_Since) ||
4077 mRequestHead.HasHeader(nsHttp::If_Match) ||
4078 mRequestHead.HasHeader(nsHttp::If_Range));
4079
4080 if (mLoadFlags & INHIBIT_PERSISTENT_CACHING) {
4081 rv = cacheStorageService->MemoryCacheStorage(
4082 info, // ? choose app cache as well...
4083 getter_AddRefs(cacheStorage));
4084 } else if (LoadPinCacheContent()) {
4085 rv = cacheStorageService->PinningCacheStorage(info,
4086 getter_AddRefs(cacheStorage));
4087 } else {
4088 // Try to race only if we use disk cache storage
4089 maybeRCWN = mRequestHead.IsSafeMethod();
4090 rv = cacheStorageService->DiskCacheStorage(info,
4091 getter_AddRefs(cacheStorage));
4092 }
4093 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4093); return rv; } } while (false)
;
4094
4095 if ((mClassOfService.Flags() & nsIClassOfService::Leader) ||
4096 (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI)) {
4097 cacheEntryOpenFlags |= nsICacheStorage::OPEN_PRIORITY;
4098 }
4099
4100 // Only for backward compatibility with the old cache back end.
4101 // When removed, remove the flags and related code snippets.
4102 if (mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY) {
4103 cacheEntryOpenFlags |= nsICacheStorage::OPEN_BYPASS_IF_BUSY;
4104 }
4105
4106 if (mPostID) {
4107 mCacheIdExtension.Append(nsPrintfCString("%d", mPostID));
4108 }
4109 if (LoadIsTRRServiceChannel()) {
4110 mCacheIdExtension.Append("TRR");
4111 }
4112 if (mRequestHead.IsHead()) {
4113 mCacheIdExtension.Append("HEAD");
4114 }
4115 bool isThirdParty = false;
4116 if (StaticPrefs::network_fetch_cache_partition_cross_origin() &&
4117 (NS_FAILED(mLoadInfo->TriggeringPrincipal()->IsThirdPartyChannel(((bool)(__builtin_expect(!!(NS_FAILED_impl(mLoadInfo->TriggeringPrincipal
()->IsThirdPartyChannel( this, &isThirdParty))), 0)))
4118 this, &isThirdParty))((bool)(__builtin_expect(!!(NS_FAILED_impl(mLoadInfo->TriggeringPrincipal
()->IsThirdPartyChannel( this, &isThirdParty))), 0)))
||
4119 isThirdParty) &&
4120 (mLoadInfo->InternalContentPolicyType() == nsIContentPolicy::TYPE_FETCH ||
4121 mLoadInfo->InternalContentPolicyType() ==
4122 nsIContentPolicy::TYPE_XMLHTTPREQUEST ||
4123 mLoadInfo->InternalContentPolicyType() ==
4124 nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST_ASYNC ||
4125 mLoadInfo->InternalContentPolicyType() ==
4126 nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST_SYNC)) {
4127 mCacheIdExtension.Append("FETCH");
4128 }
4129
4130 mCacheOpenWithPriority = cacheEntryOpenFlags & nsICacheStorage::OPEN_PRIORITY;
4131 mCacheQueueSizeWhenOpen =
4132 CacheStorageService::CacheQueueSize(mCacheOpenWithPriority);
4133
4134 if ((mNetworkTriggerDelay || StaticPrefs::network_http_rcwn_enabled()) &&
4135 maybeRCWN) {
4136 bool hasAltData = false;
4137 uint32_t sizeInKb = 0;
4138 rv = cacheStorage->GetCacheIndexEntryAttrs(
4139 mCacheEntryURI, mCacheIdExtension, &hasAltData, &sizeInKb);
4140
4141 // We will attempt to race the network vs the cache if we've found
4142 // this entry in the cache index, and it has appropriate attributes
4143 // (doesn't have alt-data, and has a small size)
4144 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !hasAltData &&
4145 sizeInKb < StaticPrefs::network_http_rcwn_small_resource_size_kb()) {
4146 MaybeRaceCacheWithNetwork();
4147 }
4148 }
4149
4150 if (!mCacheOpenDelay) {
4151 MOZ_ASSERT(NS_IsMainThread(), "Should be called on the main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Should be called on the main thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4151); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should be called on the main thread" ")"); do { *((volatile
int*)__null) = 4151; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
4152 if (mNetworkTriggered) {
4153 mRaceCacheWithNetwork = StaticPrefs::network_http_rcwn_enabled();
4154 }
4155 rv = cacheStorage->AsyncOpenURI(mCacheEntryURI, mCacheIdExtension,
4156 cacheEntryOpenFlags, this);
4157 } else {
4158 // We pass `this` explicitly as a parameter due to the raw pointer
4159 // to refcounted object in lambda analysis.
4160 mCacheOpenFunc = [cacheEntryOpenFlags,
4161 cacheStorage](nsHttpChannel* self) -> void {
4162 MOZ_ASSERT(NS_IsMainThread(), "Should be called on the main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Should be called on the main thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4162); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should be called on the main thread" ")"); do { *((volatile
int*)__null) = 4162; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
4163 cacheStorage->AsyncOpenURI(self->mCacheEntryURI, self->mCacheIdExtension,
4164 cacheEntryOpenFlags, self);
4165 };
4166
4167 // calls nsHttpChannel::Notify after `mCacheOpenDelay` milliseconds
4168 auto callback = MakeRefPtr<TimerCallback>(this);
4169 NS_NewTimerWithCallback(getter_AddRefs(mCacheOpenTimer), callback,
4170 mCacheOpenDelay, nsITimer::TYPE_ONE_SHOT);
4171 }
4172 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4172); return rv; } } while (false)
;
4173
4174 waitFlags.Keep(WAIT_FOR_CACHE_ENTRY);
4175
4176 return NS_OK;
4177}
4178
4179nsresult nsHttpChannel::CheckPartial(nsICacheEntry* aEntry, int64_t* aSize,
4180 int64_t* aContentLength) {
4181 return nsHttp::CheckPartial(
4182 aEntry, aSize, aContentLength,
4183 mCachedResponseHead ? mCachedResponseHead.get() : mResponseHead.get());
4184}
4185
4186void nsHttpChannel::UntieValidationRequest() {
4187 DebugOnly<nsresult> rv{};
4188 // Make the request unconditional again.
4189 rv = mRequestHead.ClearHeader(nsHttp::If_Modified_Since);
4190 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4190); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4190; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4191 rv = mRequestHead.ClearHeader(nsHttp::If_None_Match);
4192 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4192); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4192; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4193 rv = mRequestHead.ClearHeader(nsHttp::ETag);
4194 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4194); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4194; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4195}
4196
4197NS_IMETHODIMPnsresult
4198nsHttpChannel::OnCacheEntryCheck(nsICacheEntry* entry, uint32_t* aResult) {
4199 nsresult rv = NS_OK;
4200
4201 LOG(("nsHttpChannel::OnCacheEntryCheck enter [channel=%p entry=%p]", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnCacheEntryCheck enter [channel=%p entry=%p]"
, this, entry); } } while (0)
4202 entry))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnCacheEntryCheck enter [channel=%p entry=%p]"
, this, entry); } } while (0)
;
4203
4204 mozilla::MutexAutoLock lock(mRCWNLock);
4205
4206 if (mRaceCacheWithNetwork && mFirstResponseSource == RESPONSE_FROM_NETWORK) {
4207 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Not using cached response because we've already got one from the "
"network\n"); } } while (0)
4208 ("Not using cached response because we've already got one from the "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Not using cached response because we've already got one from the "
"network\n"); } } while (0)
4209 "network\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Not using cached response because we've already got one from the "
"network\n"); } } while (0)
;
4210 *aResult = ENTRY_NOT_WANTED;
4211
4212 // Net-win indicates that mOnStartRequestTimestamp is from net.
4213 int64_t savedTime =
4214 (TimeStamp::Now() - mOnStartRequestTimestamp).ToMilliseconds();
4215 Telemetry::Accumulate(Telemetry::NETWORK_RACE_CACHE_WITH_NETWORK_SAVED_TIME,
4216 savedTime);
4217 return NS_OK;
4218 }
4219 if (mRaceCacheWithNetwork && mFirstResponseSource == RESPONSE_PENDING) {
4220 mOnCacheEntryCheckTimestamp = TimeStamp::Now();
4221 }
4222
4223 nsAutoCString cacheControlRequestHeader;
4224 Unused << mRequestHead.GetHeader(nsHttp::Cache_Control,
4225 cacheControlRequestHeader);
4226 CacheControlParser cacheControlRequest(cacheControlRequestHeader);
4227
4228 if (cacheControlRequest.NoStore()) {
4229 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Not using cached response based on no-store request cache "
"directive\n"); } } while (0)
4230 ("Not using cached response based on no-store request cache "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Not using cached response based on no-store request cache "
"directive\n"); } } while (0)
4231 "directive\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Not using cached response based on no-store request cache "
"directive\n"); } } while (0)
;
4232 *aResult = ENTRY_NOT_WANTED;
4233 return NS_OK;
4234 }
4235
4236 // Be pessimistic: assume the cache entry has no useful data.
4237 *aResult = ENTRY_WANTED;
4238 mCachedContentIsValid = false;
4239
4240 nsCString buf;
4241
4242 // Get the method that was used to generate the cached response
4243 rv = entry->GetMetaDataElement("request-method", getter_Copies(buf));
4244 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4244); return rv; } } while (false)
;
4245
4246 bool methodWasHead = buf.EqualsLiteral("HEAD");
4247 bool methodWasGet = buf.EqualsLiteral("GET");
4248
4249 if (methodWasHead) {
4250 // The cached response does not contain an entity. We can only reuse
4251 // the response if the current request is also HEAD.
4252 if (!mRequestHead.IsHead()) {
4253 *aResult = ENTRY_NOT_WANTED;
4254 return NS_OK;
4255 }
4256 }
4257 buf.Adopt(nullptr);
4258
4259 // We'll need this value in later computations...
4260 uint32_t lastModifiedTime;
4261 rv = entry->GetLastModified(&lastModifiedTime);
4262 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4262); return rv; } } while (false)
;
4263
4264 // Determine if this is the first time that this cache entry
4265 // has been accessed during this session.
4266 bool fromPreviousSession =
4267 (gHttpHandler->SessionStartTime() > lastModifiedTime);
4268
4269 // Get the cached HTTP response headers
4270 mCachedResponseHead = MakeUnique<nsHttpResponseHead>();
4271
4272 rv = nsHttp::GetHttpResponseHeadFromCacheEntry(entry,
4273 mCachedResponseHead.get());
4274 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4274); return rv; } } while (false)
;
4275
4276 bool isCachedRedirect = WillRedirect(*mCachedResponseHead);
4277
4278 // Do not return 304 responses from the cache, and also do not return
4279 // any other non-redirect 3xx responses from the cache (see bug 759043).
4280 NS_ENSURE_TRUE((mCachedResponseHead->Status() / 100 != 3) || isCachedRedirect,do { if ((__builtin_expect(!!(!((mCachedResponseHead->Status
() / 100 != 3) || isCachedRedirect)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "(mCachedResponseHead->Status() / 100 != 3) || isCachedRedirect"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4281); return NS_ERROR_ABORT; } } while (false)
4281 NS_ERROR_ABORT)do { if ((__builtin_expect(!!(!((mCachedResponseHead->Status
() / 100 != 3) || isCachedRedirect)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "(mCachedResponseHead->Status() / 100 != 3) || isCachedRedirect"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4281); return NS_ERROR_ABORT; } } while (false)
;
4282
4283 if (mCachedResponseHead->NoStore() && LoadCacheEntryIsReadOnly()) {
4284 // This prevents loading no-store responses when navigating back
4285 // while the browser is set to work offline.
4286 LOG((" entry loading as read-only but is no-store, set INHIBIT_CACHING"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " entry loading as read-only but is no-store, set INHIBIT_CACHING"
); } } while (0)
;
4287 mLoadFlags |= nsIRequest::INHIBIT_CACHING;
4288 }
4289
4290 // Don't bother to validate items that are read-only,
4291 // unless they are read-only because of INHIBIT_CACHING
4292 if ((LoadCacheEntryIsReadOnly() &&
4293 !(mLoadFlags & nsIRequest::INHIBIT_CACHING))) {
4294 int64_t size, contentLength;
4295 rv = CheckPartial(entry, &size, &contentLength);
4296 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4296); return rv; } } while (false)
;
4297
4298 if (contentLength != int64_t(-1) && contentLength != size) {
4299 *aResult = ENTRY_NOT_WANTED;
4300 return NS_OK;
4301 }
4302
4303 rv = OpenCacheInputStream(entry, true);
4304 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4305 mCachedContentIsValid = true;
4306 }
4307 return rv;
4308 }
4309
4310 bool wantCompleteEntry = false;
4311
4312 if (!methodWasHead && !isCachedRedirect) {
4313 // If the cached content-length is set and it does not match the data
4314 // size of the cached content, then the cached response is partial...
4315 // either we need to issue a byte range request or we need to refetch
4316 // the entire document.
4317 //
4318 // We exclude redirects from this check because we (usually) strip the
4319 // entity when we store the cache entry, and even if we didn't, we
4320 // always ignore a cached redirect's entity anyway. See bug 759043.
4321 int64_t size, contentLength;
4322 rv = CheckPartial(entry, &size, &contentLength);
4323 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4323); return rv; } } while (false)
;
4324
4325 if (size == int64_t(-1)) {
4326 LOG((" write is in progress"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " write is in progress"); } } while (0)
;
4327 if (mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY) {
4328 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " not interested in the entry, " "LOAD_BYPASS_LOCAL_CACHE_IF_BUSY specified"
); } } while (0)
4329 (" not interested in the entry, "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " not interested in the entry, " "LOAD_BYPASS_LOCAL_CACHE_IF_BUSY specified"
); } } while (0)
4330 "LOAD_BYPASS_LOCAL_CACHE_IF_BUSY specified"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " not interested in the entry, " "LOAD_BYPASS_LOCAL_CACHE_IF_BUSY specified"
); } } while (0)
;
4331
4332 *aResult = ENTRY_NOT_WANTED;
4333 return NS_OK;
4334 }
4335
4336 // Ignore !(size > 0) from the resumability condition
4337 if (!IsResumable(size, contentLength, true)) {
4338 if (IsNavigation()) {
4339 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " bypassing wait for the entry, " "this is a navigational load"
); } } while (0)
4340 (" bypassing wait for the entry, "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " bypassing wait for the entry, " "this is a navigational load"
); } } while (0)
4341 "this is a navigational load"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " bypassing wait for the entry, " "this is a navigational load"
); } } while (0)
;
4342 *aResult = ENTRY_NOT_WANTED;
4343 return NS_OK;
4344 }
4345
4346 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " wait for entry completion, " "response is not resumable"
); } } while (0)
4347 (" wait for entry completion, "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " wait for entry completion, " "response is not resumable"
); } } while (0)
4348 "response is not resumable"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " wait for entry completion, " "response is not resumable"
); } } while (0)
;
4349
4350 wantCompleteEntry = true;
4351 } else {
4352 StoreConcurrentCacheAccess(1);
4353 }
4354 } else if (contentLength != int64_t(-1) && contentLength != size) {
4355 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Cached data size does not match the Content-Length header "
"[content-length=%" "l" "d" " size=%" "l" "d" "]\n", contentLength
, size); } } while (0)
4356 ("Cached data size does not match the Content-Length header "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Cached data size does not match the Content-Length header "
"[content-length=%" "l" "d" " size=%" "l" "d" "]\n", contentLength
, size); } } while (0)
4357 "[content-length=%" PRId64 " size=%" PRId64 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Cached data size does not match the Content-Length header "
"[content-length=%" "l" "d" " size=%" "l" "d" "]\n", contentLength
, size); } } while (0)
4358 contentLength, size))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Cached data size does not match the Content-Length header "
"[content-length=%" "l" "d" " size=%" "l" "d" "]\n", contentLength
, size); } } while (0)
;
4359
4360 rv = MaybeSetupByteRangeRequest(size, contentLength);
4361 StoreCachedContentIsPartial(NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && LoadIsPartialRequest());
4362 if (LoadCachedContentIsPartial()) {
4363 rv = OpenCacheInputStream(entry, false);
4364 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4365 UntieByteRangeRequest();
4366 return rv;
4367 }
4368
4369 *aResult = ENTRY_NEEDS_REVALIDATION;
4370 return NS_OK;
4371 }
4372
4373 if (size == 0 && LoadCacheOnlyMetadata()) {
4374 // Don't break cache entry load when the entry's data size
4375 // is 0 and CacheOnlyMetadata flag is set. In that case we
4376 // want to proceed since the LOAD_ONLY_IF_MODIFIED flag is
4377 // also set.
4378 MOZ_ASSERT(mLoadFlags & LOAD_ONLY_IF_MODIFIED)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadFlags & LOAD_ONLY_IF_MODIFIED)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mLoadFlags & LOAD_ONLY_IF_MODIFIED))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mLoadFlags & LOAD_ONLY_IF_MODIFIED"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4378); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadFlags & LOAD_ONLY_IF_MODIFIED"
")"); do { *((volatile int*)__null) = 4378; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4379 } else {
4380 return rv;
4381 }
4382 }
4383 }
4384
4385 bool isHttps = mURI->SchemeIs("https");
4386
4387 bool doValidation = false;
4388 bool doBackgroundValidation = false;
4389 bool canAddImsHeader = true;
4390
4391 bool isForcedValid = false;
4392 entry->GetIsForcedValid(&isForcedValid);
4393 auto prefetchStatus = Telemetry::LABELS_PREDICTOR_PREFETCH_USE_STATUS::Used;
4394
4395 bool weaklyFramed, isImmutable;
4396 nsHttp::DetermineFramingAndImmutability(entry, mCachedResponseHead.get(),
4397 isHttps, &weaklyFramed, &isImmutable);
4398
4399 // Cached entry is not the entity we request (see bug #633743)
4400 if (ResponseWouldVary(entry)) {
4401 LOG(("Validating based on Vary headers returning TRUE\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Validating based on Vary headers returning TRUE\n"); } } while
(0)
;
4402 canAddImsHeader = false;
4403 doValidation = true;
4404 prefetchStatus = Telemetry::LABELS_PREDICTOR_PREFETCH_USE_STATUS::WouldVary;
4405 } else {
4406 if (mCachedResponseHead->ExpiresInPast() ||
4407 mCachedResponseHead->MustValidateIfExpired()) {
4408 prefetchStatus = Telemetry::LABELS_PREDICTOR_PREFETCH_USE_STATUS::Expired;
4409 }
4410 doValidation = nsHttp::ValidationRequired(
4411 isForcedValid, mCachedResponseHead.get(), mLoadFlags,
4412 LoadAllowStaleCacheContent(), LoadForceValidateCacheContent(),
4413 isImmutable, LoadCustomConditionalRequest(), mRequestHead, entry,
4414 cacheControlRequest, fromPreviousSession, &doBackgroundValidation);
4415 }
4416
4417 nsAutoCString requestedETag;
4418 if (!doValidation &&
4419 NS_SUCCEEDED(mRequestHead.GetHeader(nsHttp::If_Match, requestedETag))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mRequestHead.GetHeader
(nsHttp::If_Match, requestedETag))), 1)))
&&
4420 (methodWasGet || methodWasHead)) {
4421 nsAutoCString cachedETag;
4422 Unused << mCachedResponseHead->GetHeader(nsHttp::ETag, cachedETag);
4423 if (!cachedETag.IsEmpty() && (StringBeginsWith(cachedETag, "W/"_ns) ||
4424 !requestedETag.Equals(cachedETag))) {
4425 // User has defined If-Match header, if the cached entry is not
4426 // matching the provided header value or the cached ETag is weak,
4427 // force validation.
4428 doValidation = true;
4429 }
4430 }
4431
4432 // Previous error should not be propagated.
4433 rv = NS_OK;
4434
4435 if (!doValidation) {
4436 //
4437 // Check the authorization headers used to generate the cache entry.
4438 // We must validate the cache entry if:
4439 //
4440 // 1) the cache entry was generated prior to this session w/
4441 // credentials (see bug 103402).
4442 // 2) the cache entry was generated w/o credentials, but would now
4443 // require credentials (see bug 96705).
4444 //
4445 // NOTE: this does not apply to proxy authentication.
4446 //
4447 entry->GetMetaDataElement("auth", getter_Copies(buf));
4448 doValidation =
4449 (fromPreviousSession && !buf.IsEmpty()) ||
4450 (buf.IsEmpty() && mRequestHead.HasHeader(nsHttp::Authorization));
4451 if (doValidation) {
4452 prefetchStatus = Telemetry::LABELS_PREDICTOR_PREFETCH_USE_STATUS::Auth;
4453 }
4454 }
4455
4456 // Bug #561276: We maintain a chain of cache-keys which returns cached
4457 // 3xx-responses (redirects) in order to detect cycles. If a cycle is
4458 // found, ignore the cached response and hit the net. Otherwise, use
4459 // the cached response and add the cache-key to the chain. Note that
4460 // a limited number of redirects (cached or not) is allowed and is
4461 // enforced independently of this mechanism
4462 if (!doValidation && isCachedRedirect) {
4463 nsAutoCString cacheKey;
4464 rv = GenerateCacheKey(mPostID, cacheKey);
4465 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4465); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4465; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4466
4467 auto redirectedCachekeys = mRedirectedCachekeys.Lock();
4468 auto& ref = redirectedCachekeys.ref();
4469 if (!ref) {
4470 ref = MakeUnique<nsTArray<nsCString>>();
4471 } else if (ref->Contains(cacheKey)) {
4472 doValidation = true;
4473 }
4474
4475 LOG(("Redirection-chain %s key %s\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Redirection-chain %s key %s\n", doValidation ? "contains" :
"does not contain", cacheKey.get()); } } while (0)
4476 doValidation ? "contains" : "does not contain", cacheKey.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Redirection-chain %s key %s\n", doValidation ? "contains" :
"does not contain", cacheKey.get()); } } while (0)
;
4477
4478 // Append cacheKey if not in the chain already
4479 if (!doValidation) {
4480 ref->AppendElement(cacheKey);
4481 } else {
4482 prefetchStatus =
4483 Telemetry::LABELS_PREDICTOR_PREFETCH_USE_STATUS::Redirect;
4484 }
4485 }
4486
4487 mCachedContentIsValid = !doValidation;
4488
4489 if (isForcedValid) {
4490 // Telemetry value is only useful if this was a prefetched item
4491 if (!doValidation) {
4492 // Could have gotten to a funky state with some of the if chain above
4493 // and in nsHttp::ValidationRequired. Make sure we get it right here.
4494 prefetchStatus = Telemetry::LABELS_PREDICTOR_PREFETCH_USE_STATUS::Used;
4495
4496 entry->MarkForcedValidUse();
4497 }
4498 Telemetry::AccumulateCategorical(prefetchStatus);
4499 }
4500
4501 if (doValidation) {
4502 //
4503 // now, we are definitely going to issue a HTTP request to the server.
4504 // make it conditional if possible.
4505 //
4506 // do not attempt to validate no-store content, since servers will not
4507 // expect it to be cached. (we only keep it in our cache for the
4508 // purposes of back/forward, etc.)
4509 //
4510 // the request method MUST be either GET or HEAD (see bug 175641) and
4511 // the cached response code must be < 400
4512 //
4513 // the cached content must not be weakly framed
4514 //
4515 // do not override conditional headers when consumer has defined its own
4516 if (!mCachedResponseHead->NoStore() &&
4517 (mRequestHead.IsGet() || mRequestHead.IsHead()) &&
4518 !LoadCustomConditionalRequest() && !weaklyFramed &&
4519 (mCachedResponseHead->Status() < 400)) {
4520 if (LoadConcurrentCacheAccess()) {
4521 // In case of concurrent read and also validation request we
4522 // must wait for the current writer to close the output stream
4523 // first. Otherwise, when the writer's job would have been interrupted
4524 // before all the data were downloaded, we'd have to do a range request
4525 // which would be a second request in line during this channel's
4526 // life-time. nsHttpChannel is not designed to do that, so rather
4527 // turn off concurrent read and wait for entry's completion.
4528 // Then only re-validation or range-re-validation request will go out.
4529 StoreConcurrentCacheAccess(0);
4530 // This will cause that OnCacheEntryCheck is called again with the same
4531 // entry after the writer is done.
4532 wantCompleteEntry = true;
4533 } else {
4534 nsAutoCString val;
4535 // Add If-Modified-Since header if a Last-Modified was given
4536 // and we are allowed to do this (see bugs 510359 and 269303)
4537 if (canAddImsHeader) {
4538 Unused << mCachedResponseHead->GetHeader(nsHttp::Last_Modified, val);
4539 if (!val.IsEmpty()) {
4540 rv = mRequestHead.SetHeader(nsHttp::If_Modified_Since, val);
4541 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4541); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4541; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4542 }
4543 }
4544 // Add If-None-Match header if an ETag was given in the response
4545 Unused << mCachedResponseHead->GetHeader(nsHttp::ETag, val);
4546 if (!val.IsEmpty()) {
4547 rv = mRequestHead.SetHeader(nsHttp::If_None_Match, val);
4548 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4548); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4548; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4549 }
4550 mDidReval = true;
4551 }
4552 }
4553 }
4554
4555 if (mCachedContentIsValid || mDidReval) {
4556 rv = OpenCacheInputStream(entry, mCachedContentIsValid);
4557 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4558 // If we can't get the entity then we have to act as though we
4559 // don't have the cache entry.
4560 if (mDidReval) {
4561 UntieValidationRequest();
4562 mDidReval = false;
4563 }
4564 mCachedContentIsValid = false;
4565 }
4566 }
4567
4568 if (mDidReval) {
4569 *aResult = ENTRY_NEEDS_REVALIDATION;
4570 } else if (wantCompleteEntry) {
4571 *aResult = RECHECK_AFTER_WRITE_FINISHED;
4572 } else {
4573 *aResult = ENTRY_WANTED;
4574
4575 if (doBackgroundValidation) {
4576 PerformBackgroundCacheRevalidation();
4577 }
4578 }
4579
4580 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHTTPChannel::OnCacheEntryCheck exit [this=%p doValidation=%d "
"result=%d]\n", this, doValidation, *aResult); } } while (0)
4581 ("nsHTTPChannel::OnCacheEntryCheck exit [this=%p doValidation=%d "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHTTPChannel::OnCacheEntryCheck exit [this=%p doValidation=%d "
"result=%d]\n", this, doValidation, *aResult); } } while (0)
4582 "result=%d]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHTTPChannel::OnCacheEntryCheck exit [this=%p doValidation=%d "
"result=%d]\n", this, doValidation, *aResult); } } while (0)
4583 this, doValidation, *aResult))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHTTPChannel::OnCacheEntryCheck exit [this=%p doValidation=%d "
"result=%d]\n", this, doValidation, *aResult); } } while (0)
;
4584 return rv;
4585}
4586
4587NS_IMETHODIMPnsresult
4588nsHttpChannel::OnCacheEntryAvailable(nsICacheEntry* entry, bool aNew,
4589 nsresult status) {
4590 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4590); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4590; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4591
4592 nsresult rv;
4593
4594 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnCacheEntryAvailable [this=%p entry=%p " "new=%d status=%"
"x" "]\n", this, entry, aNew, static_cast<uint32_t>(status
)); } } while (0)
4595 ("nsHttpChannel::OnCacheEntryAvailable [this=%p entry=%p "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnCacheEntryAvailable [this=%p entry=%p " "new=%d status=%"
"x" "]\n", this, entry, aNew, static_cast<uint32_t>(status
)); } } while (0)
4596 "new=%d status=%" PRIx32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnCacheEntryAvailable [this=%p entry=%p " "new=%d status=%"
"x" "]\n", this, entry, aNew, static_cast<uint32_t>(status
)); } } while (0)
4597 this, entry, aNew, static_cast<uint32_t>(status)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnCacheEntryAvailable [this=%p entry=%p " "new=%d status=%"
"x" "]\n", this, entry, aNew, static_cast<uint32_t>(status
)); } } while (0)
;
4598
4599 // if the channel's already fired onStopRequest, then we should ignore
4600 // this event.
4601 if (!LoadIsPending()) {
4602 mCacheInputStream.CloseAndRelease();
4603 return NS_OK;
4604 }
4605
4606 rv = OnCacheEntryAvailableInternal(entry, aNew, status);
4607 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4608 CloseCacheEntry(false);
4609 if (mRaceCacheWithNetwork && mNetworkTriggered &&
4610 mFirstResponseSource != RESPONSE_FROM_CACHE) {
4611 // Ignore the error if we're racing cache with network and the cache
4612 // didn't win, The network part will handle cancelation or any other
4613 // error. Otherwise we could end up calling the listener twice, see
4614 // bug 1397593.
4615 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " not calling AsyncAbort() because we're racing cache with "
"network"); } } while (0)
4616 (" not calling AsyncAbort() because we're racing cache with "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " not calling AsyncAbort() because we're racing cache with "
"network"); } } while (0)
4617 "network"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " not calling AsyncAbort() because we're racing cache with "
"network"); } } while (0)
;
4618 } else {
4619 Unused << AsyncAbort(rv);
4620 }
4621 }
4622
4623 return NS_OK;
4624}
4625
4626nsresult nsHttpChannel::OnCacheEntryAvailableInternal(nsICacheEntry* entry,
4627 bool aNew,
4628 nsresult status) {
4629 nsresult rv;
4630
4631 if (mCanceled) {
4632 LOG(("channel was canceled [this=%p status=%" PRIx32 "]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "channel was canceled [this=%p status=%" "x" "]\n", this, static_cast
<uint32_t>(static_cast<nsresult>(mStatus))); } } while
(0)
4633 static_cast<uint32_t>(static_cast<nsresult>(mStatus))))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "channel was canceled [this=%p status=%" "x" "]\n", this, static_cast
<uint32_t>(static_cast<nsresult>(mStatus))); } } while
(0)
;
4634 return mStatus;
4635 }
4636
4637 if (mIgnoreCacheEntry) {
4638 if (!entry || aNew) {
4639 // We use this flag later to decide whether to report
4640 // LABELS_NETWORK_RACE_CACHE_VALIDATION::NotSent. We didn't have
4641 // an usable entry, so drop the flag.
4642 mIgnoreCacheEntry = false;
4643 }
4644 entry = nullptr;
4645 status = NS_ERROR_NOT_AVAILABLE;
4646 }
4647
4648 rv = OnNormalCacheEntryAvailable(entry, aNew, status);
4649
4650 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && (mLoadFlags & LOAD_ONLY_FROM_CACHE)) {
4651 return NS_ERROR_DOCUMENT_NOT_CACHED;
4652 }
4653
4654 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4655 return rv;
4656 }
4657
4658 // We may be waiting for more callbacks...
4659 if (AwaitingCacheCallbacks()) {
4660 return NS_OK;
4661 }
4662
4663 if (mRaceCacheWithNetwork && ((mCacheEntry && !mCachedContentIsValid &&
4664 (mDidReval || LoadCachedContentIsPartial())) ||
4665 mIgnoreCacheEntry)) {
4666 // We won't send the conditional request because the unconditional
4667 // request was already sent (see bug 1377223).
4668 AccumulateCategorical(
4669 Telemetry::LABELS_NETWORK_RACE_CACHE_VALIDATION::NotSent);
4670 }
4671
4672 if (mRaceCacheWithNetwork && mCachedContentIsValid) {
4673 Unused << ReadFromCache();
4674 }
4675
4676 return TriggerNetwork();
4677}
4678
4679nsresult nsHttpChannel::OnNormalCacheEntryAvailable(nsICacheEntry* aEntry,
4680 bool aNew,
4681 nsresult aEntryStatus) {
4682 StoreWaitForCacheEntry(LoadWaitForCacheEntry() & ~WAIT_FOR_CACHE_ENTRY);
4683
4684 if (NS_FAILED(aEntryStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(aEntryStatus)), 0)
))
|| aNew) {
4685 // Make sure this flag is dropped. It may happen the entry is doomed
4686 // between OnCacheEntryCheck and OnCacheEntryAvailable.
4687 mCachedContentIsValid = false;
4688
4689 // From the same reason remove any conditional headers added
4690 // in OnCacheEntryCheck.
4691 if (mDidReval) {
4692 LOG((" Removing conditional request headers"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Removing conditional request headers"); } } while (0)
;
4693 UntieValidationRequest();
4694 mDidReval = false;
4695 }
4696
4697 if (LoadCachedContentIsPartial()) {
4698 LOG((" Removing byte range request headers"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Removing byte range request headers"); } } while (0)
;
4699 UntieByteRangeRequest();
4700 StoreCachedContentIsPartial(false);
4701 }
4702
4703 if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
4704 // if this channel is only allowed to pull from the cache, then
4705 // we must fail if we were unable to open a cache entry for read.
4706 return NS_ERROR_DOCUMENT_NOT_CACHED;
4707 }
4708 }
4709
4710 if (NS_SUCCEEDED(aEntryStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aEntryStatus)), 1
)))
) {
4711 mCacheEntry = aEntry;
4712 StoreCacheEntryIsWriteOnly(aNew);
4713
4714 if (!aNew && !mAsyncOpenTime.IsNull()) {
4715 // We use microseconds for IO operations. For consistency let's use
4716 // microseconds here too.
4717 uint32_t duration = (TimeStamp::Now() - mAsyncOpenTime).ToMicroseconds();
4718 bool isSlow = false;
4719 if ((mCacheOpenWithPriority &&
4720 mCacheQueueSizeWhenOpen >=
4721 StaticPrefs::
4722 network_http_rcwn_cache_queue_priority_threshold()) ||
4723 (!mCacheOpenWithPriority &&
4724 mCacheQueueSizeWhenOpen >=
4725 StaticPrefs::network_http_rcwn_cache_queue_normal_threshold())) {
4726 isSlow = true;
4727 }
4728 CacheFileUtils::CachePerfStats::AddValue(
4729 CacheFileUtils::CachePerfStats::ENTRY_OPEN, duration, isSlow);
4730 }
4731 }
4732
4733 return NS_OK;
4734}
4735
4736// Generates the proper cache-key for this instance of nsHttpChannel
4737nsresult nsHttpChannel::GenerateCacheKey(uint32_t postID,
4738 nsACString& cacheKey) {
4739 AssembleCacheKey(mSpec.get(), postID, cacheKey);
4740 return NS_OK;
4741}
4742
4743// Assembles a cache-key from the given pieces of information and |mLoadFlags|
4744void nsHttpChannel::AssembleCacheKey(const char* spec, uint32_t postID,
4745 nsACString& cacheKey) {
4746 cacheKey.Truncate();
4747
4748 if (mLoadFlags & LOAD_ANONYMOUS) {
4749 cacheKey.AssignLiteral("anon&");
4750 }
4751
4752 if (postID) {
4753 char buf[32];
4754 SprintfLiteral(buf, "id=%x&", postID);
4755 cacheKey.Append(buf);
4756 }
4757
4758 if (!cacheKey.IsEmpty()) {
4759 cacheKey.AppendLiteral("uri=");
4760 }
4761
4762 // Strip any trailing #ref from the URL before using it as the key
4763 const char* p = strchr(spec, '#');
4764 if (p) {
4765 cacheKey.Append(spec, p - spec);
4766 } else {
4767 cacheKey.Append(spec);
4768 }
4769}
4770
4771nsresult DoUpdateExpirationTime(nsHttpChannel* aSelf,
4772 nsICacheEntry* aCacheEntry,
4773 nsHttpResponseHead* aResponseHead,
4774 uint32_t& aExpirationTime) {
4775 MOZ_ASSERT(aExpirationTime == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aExpirationTime == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aExpirationTime == 0))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("aExpirationTime == 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4775); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aExpirationTime == 0"
")"); do { *((volatile int*)__null) = 4775; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4776 NS_ENSURE_TRUE(aResponseHead, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(aResponseHead)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResponseHead" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4776); return NS_ERROR_FAILURE; } } while (false)
;
4777
4778 nsresult rv;
4779
4780 if (!aResponseHead->MustValidate()) {
4781 // For stale-while-revalidate we use expiration time as the absolute base
4782 // for calculation of the stale window absolute end time. Hence, when the
4783 // entry may be served w/o revalidation, we need a non-zero value for the
4784 // expiration time. Let's set it to |now|, which basicly means "expired",
4785 // same as when set to 0.
4786 uint32_t now = NowInSeconds()PRTimeToSeconds(PR_Now());
4787 aExpirationTime = now;
4788
4789 uint32_t freshnessLifetime = 0;
4790
4791 rv = aResponseHead->ComputeFreshnessLifetime(&freshnessLifetime);
4792 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
4793
4794 if (freshnessLifetime > 0) {
4795 uint32_t currentAge = 0;
4796
4797 rv = aResponseHead->ComputeCurrentAge(now, aSelf->GetRequestTime(),
4798 &currentAge);
4799 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
4800
4801 LOG(("freshnessLifetime = %u, currentAge = %u\n", freshnessLifetime,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "freshnessLifetime = %u, currentAge = %u\n", freshnessLifetime
, currentAge); } } while (0)
4802 currentAge))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "freshnessLifetime = %u, currentAge = %u\n", freshnessLifetime
, currentAge); } } while (0)
;
4803
4804 if (freshnessLifetime > currentAge) {
4805 uint32_t timeRemaining = freshnessLifetime - currentAge;
4806 // be careful... now + timeRemaining may overflow
4807 if (now + timeRemaining < now) {
4808 aExpirationTime = uint32_t(-1);
4809 } else {
4810 aExpirationTime = now + timeRemaining;
4811 }
4812 }
4813 }
4814 }
4815
4816 rv = aCacheEntry->SetExpirationTime(aExpirationTime);
4817 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4817); return rv; } } while (false)
;
4818
4819 return rv;
4820}
4821
4822// UpdateExpirationTime is called when a new response comes in from the server.
4823// It updates the stored response-time and sets the expiration time on the
4824// cache entry.
4825//
4826// From section 13.2.4 of RFC2616, we compute expiration time as follows:
4827//
4828// timeRemaining = freshnessLifetime - currentAge
4829// expirationTime = now + timeRemaining
4830//
4831nsresult nsHttpChannel::UpdateExpirationTime() {
4832 uint32_t expirationTime = 0;
4833 nsresult rv = DoUpdateExpirationTime(this, mCacheEntry, mResponseHead.get(),
4834 expirationTime);
4835 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4835); return rv; } } while (false)
;
4836
4837 return NS_OK;
4838}
4839
4840nsresult nsHttpChannel::OpenCacheInputStream(nsICacheEntry* cacheEntry,
4841 bool startBuffering) {
4842 nsresult rv;
4843
4844 if (mURI->SchemeIs("https")) {
4845 rv = cacheEntry->GetSecurityInfo(getter_AddRefs(mCachedSecurityInfo));
4846 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4847 LOG(("failed to parse security-info [channel=%p, entry=%p]", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "failed to parse security-info [channel=%p, entry=%p]", this
, cacheEntry); } } while (0)
4848 cacheEntry))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "failed to parse security-info [channel=%p, entry=%p]", this
, cacheEntry); } } while (0)
;
4849 NS_WARNING("failed to parse security-info")NS_DebugBreak(NS_DEBUG_WARNING, "failed to parse security-info"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4849)
;
4850 cacheEntry->AsyncDoom(nullptr);
4851 return rv;
4852 }
4853
4854 MOZ_ASSERT(mCachedSecurityInfo)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCachedSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCachedSecurityInfo))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("mCachedSecurityInfo"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4854); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCachedSecurityInfo"
")"); do { *((volatile int*)__null) = 4854; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4855 if (!mCachedSecurityInfo) {
4856 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "mCacheEntry->GetSecurityInfo returned success but did not "
"return the security info [channel=%p, entry=%p]", this, cacheEntry
); } } while (0)
4857 ("mCacheEntry->GetSecurityInfo returned success but did not "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "mCacheEntry->GetSecurityInfo returned success but did not "
"return the security info [channel=%p, entry=%p]", this, cacheEntry
); } } while (0)
4858 "return the security info [channel=%p, entry=%p]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "mCacheEntry->GetSecurityInfo returned success but did not "
"return the security info [channel=%p, entry=%p]", this, cacheEntry
); } } while (0)
4859 this, cacheEntry))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "mCacheEntry->GetSecurityInfo returned success but did not "
"return the security info [channel=%p, entry=%p]", this, cacheEntry
); } } while (0)
;
4860 cacheEntry->AsyncDoom(nullptr);
4861 return NS_ERROR_UNEXPECTED; // XXX error code
4862 }
4863 }
4864
4865 // Keep the conditions below in sync with the conditions in ReadFromCache.
4866
4867 rv = NS_OK;
Value stored to 'rv' is never read
4868
4869 if (WillRedirect(*mCachedResponseHead)) {
4870 // Do not even try to read the entity for a redirect because we do not
4871 // return an entity to the application when we process redirects.
4872 LOG(("Will skip read of cached redirect entity\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Will skip read of cached redirect entity\n"); } } while (0
)
;
4873 return NS_OK;
4874 }
4875
4876 if ((mLoadFlags & nsICachingChannel::LOAD_ONLY_IF_MODIFIED) &&
4877 !LoadCachedContentIsPartial()) {
4878 // For LOAD_ONLY_IF_MODIFIED, we usually don't have to deal with the
4879 // cached entity.
4880 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Will skip read from cache based on LOAD_ONLY_IF_MODIFIED "
"load flag\n"); } } while (0)
4881 ("Will skip read from cache based on LOAD_ONLY_IF_MODIFIED "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Will skip read from cache based on LOAD_ONLY_IF_MODIFIED "
"load flag\n"); } } while (0)
4882 "load flag\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Will skip read from cache based on LOAD_ONLY_IF_MODIFIED "
"load flag\n"); } } while (0)
;
4883 return NS_OK;
4884 }
4885
4886 // Open an input stream for the entity, so that the call to OpenInputStream
4887 // happens off the main thread.
4888 nsCOMPtr<nsIInputStream> stream;
4889
4890 // If an alternate representation was requested, try to open the alt
4891 // input stream.
4892 // If the entry has a "is-from-child" metadata, then only open the altdata
4893 // stream if the consumer is also from child.
4894 bool altDataFromChild = false;
4895 {
4896 nsCString value;
4897 rv = cacheEntry->GetMetaDataElement("alt-data-from-child",
4898 getter_Copies(value));
4899 altDataFromChild = !value.IsEmpty();
4900 }
4901
4902 nsAutoCString altDataType;
4903 Unused << cacheEntry->GetAltDataType(altDataType);
4904
4905 nsAutoCString contentType;
4906 mCachedResponseHead->ContentType(contentType);
4907
4908 bool foundAltData = false;
4909 bool deliverAltData = true;
4910 if (!LoadDisableAltDataCache() && !altDataType.IsEmpty() &&
4911 !mPreferredCachedAltDataTypes.IsEmpty() &&
4912 altDataFromChild == LoadAltDataForChild()) {
4913 for (auto& pref : mPreferredCachedAltDataTypes) {
4914 if (pref.type() == altDataType &&
4915 (pref.contentType().IsEmpty() || pref.contentType() == contentType)) {
4916 foundAltData = true;
4917 deliverAltData =
4918 pref.deliverAltData() ==
4919 nsICacheInfoChannel::PreferredAlternativeDataDeliveryType::ASYNC;
4920 break;
4921 }
4922 }
4923 }
4924
4925 nsCOMPtr<nsIInputStream> altData;
4926 int64_t altDataSize = -1;
4927 if (foundAltData) {
4928 rv = cacheEntry->OpenAlternativeInputStream(altDataType,
4929 getter_AddRefs(altData));
4930 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4931 // We have succeeded.
4932 mAvailableCachedAltDataType = altDataType;
4933 StoreDeliveringAltData(deliverAltData);
4934
4935 // Set the correct data size on the channel.
4936 Unused << cacheEntry->GetAltDataSize(&altDataSize);
4937 mAltDataLength = altDataSize;
4938
4939 LOG(("Opened alt-data input stream [type=%s, size=%" PRId64do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opened alt-data input stream [type=%s, size=%" "l" "d" ", deliverAltData=%d]"
, altDataType.get(), mAltDataLength, deliverAltData); } } while
(0)
4940 ", deliverAltData=%d]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opened alt-data input stream [type=%s, size=%" "l" "d" ", deliverAltData=%d]"
, altDataType.get(), mAltDataLength, deliverAltData); } } while
(0)
4941 altDataType.get(), mAltDataLength, deliverAltData))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opened alt-data input stream [type=%s, size=%" "l" "d" ", deliverAltData=%d]"
, altDataType.get(), mAltDataLength, deliverAltData); } } while
(0)
;
4942
4943 if (deliverAltData) {
4944 stream = altData;
4945 }
4946 }
4947 }
4948
4949 if (!stream) {
4950 rv = cacheEntry->OpenInputStream(0, getter_AddRefs(stream));
4951 }
4952
4953 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4954 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Failed to open cache input stream [channel=%p, " "mCacheEntry=%p]"
, this, cacheEntry); } } while (0)
4955 ("Failed to open cache input stream [channel=%p, "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Failed to open cache input stream [channel=%p, " "mCacheEntry=%p]"
, this, cacheEntry); } } while (0)
4956 "mCacheEntry=%p]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Failed to open cache input stream [channel=%p, " "mCacheEntry=%p]"
, this, cacheEntry); } } while (0)
4957 this, cacheEntry))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Failed to open cache input stream [channel=%p, " "mCacheEntry=%p]"
, this, cacheEntry); } } while (0)
;
4958 return rv;
4959 }
4960
4961 if (startBuffering) {
4962 bool nonBlocking;
4963 rv = stream->IsNonBlocking(&nonBlocking);
4964 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && nonBlocking) startBuffering = false;
4965 }
4966
4967 if (!startBuffering) {
4968 // Bypass wrapping the input stream for the new cache back-end since
4969 // nsIStreamTransportService expects a blocking stream. Preloading of
4970 // the data must be done on the level of the cache backend, internally.
4971 //
4972 // We do not connect the stream to the stream transport service if we
4973 // have to validate the entry with the server. If we did, we would get
4974 // into a race condition between the stream transport service reading
4975 // the existing contents and the opening of the cache entry's output
4976 // stream to write the new contents in the case where we get a non-304
4977 // response.
4978 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opened cache input stream without buffering [channel=%p, "
"mCacheEntry=%p, stream=%p]", this, cacheEntry, stream.get()
); } } while (0)
4979 ("Opened cache input stream without buffering [channel=%p, "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opened cache input stream without buffering [channel=%p, "
"mCacheEntry=%p, stream=%p]", this, cacheEntry, stream.get()
); } } while (0)
4980 "mCacheEntry=%p, stream=%p]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opened cache input stream without buffering [channel=%p, "
"mCacheEntry=%p, stream=%p]", this, cacheEntry, stream.get()
); } } while (0)
4981 this, cacheEntry, stream.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opened cache input stream without buffering [channel=%p, "
"mCacheEntry=%p, stream=%p]", this, cacheEntry, stream.get()
); } } while (0)
;
4982 mCacheInputStream.takeOver(stream);
4983 return rv;
4984 }
4985
4986 // Have the stream transport service start reading the entity on one of its
4987 // background threads.
4988
4989 nsCOMPtr<nsITransport> transport;
4990 nsCOMPtr<nsIInputStream> wrapper;
4991
4992 nsCOMPtr<nsIStreamTransportService> sts(
4993 components::StreamTransport::Service());
4994 rv = sts ? NS_OK : NS_ERROR_NOT_AVAILABLE;
4995 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4996 rv = sts->CreateInputTransport(stream, true, getter_AddRefs(transport));
4997 }
4998 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4999 rv = transport->OpenInputStream(0, 0, 0, getter_AddRefs(wrapper));
5000 }
5001 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5002 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opened cache input stream [channel=%p, wrapper=%p, " "transport=%p, stream=%p]"
, this, wrapper.get(), transport.get(), stream.get()); } } while
(0)
5003 ("Opened cache input stream [channel=%p, wrapper=%p, "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opened cache input stream [channel=%p, wrapper=%p, " "transport=%p, stream=%p]"
, this, wrapper.get(), transport.get(), stream.get()); } } while
(0)
5004 "transport=%p, stream=%p]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opened cache input stream [channel=%p, wrapper=%p, " "transport=%p, stream=%p]"
, this, wrapper.get(), transport.get(), stream.get()); } } while
(0)
5005 this, wrapper.get(), transport.get(), stream.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opened cache input stream [channel=%p, wrapper=%p, " "transport=%p, stream=%p]"
, this, wrapper.get(), transport.get(), stream.get()); } } while
(0)
;
5006 } else {
5007 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Failed to open cache input stream [channel=%p, " "wrapper=%p, transport=%p, stream=%p]"
, this, wrapper.get(), transport.get(), stream.get()); } } while
(0)
5008 ("Failed to open cache input stream [channel=%p, "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Failed to open cache input stream [channel=%p, " "wrapper=%p, transport=%p, stream=%p]"
, this, wrapper.get(), transport.get(), stream.get()); } } while
(0)
5009 "wrapper=%p, transport=%p, stream=%p]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Failed to open cache input stream [channel=%p, " "wrapper=%p, transport=%p, stream=%p]"
, this, wrapper.get(), transport.get(), stream.get()); } } while
(0)
5010 this, wrapper.get(), transport.get(), stream.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Failed to open cache input stream [channel=%p, " "wrapper=%p, transport=%p, stream=%p]"
, this, wrapper.get(), transport.get(), stream.get()); } } while
(0)
;
5011
5012 stream->Close();
5013 return rv;
5014 }
5015
5016 mCacheInputStream.takeOver(wrapper);
5017
5018 return NS_OK;
5019}
5020
5021// Actually process the cached response that we started to handle in CheckCache
5022// and/or StartBufferingCachedEntity.
5023nsresult nsHttpChannel::ReadFromCache(void) {
5024 NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(mCacheEntry)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mCacheEntry" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5024); return NS_ERROR_FAILURE; } } while (false)
;
5025 NS_ENSURE_TRUE(mCachedContentIsValid, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(mCachedContentIsValid)), 0)))
{ NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mCachedContentIsValid"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5025); return NS_ERROR_FAILURE; } } while (false)
;
5026 NS_ENSURE_TRUE(!mCachePump, NS_OK)do { if ((__builtin_expect(!!(!(!mCachePump)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!mCachePump" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5026); return NS_OK; } } while (false)
; // already opened
5027
5028 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ReadFromCache [this=%p] " "Using cached copy of: %s\n"
, this, mSpec.get()); } } while (0)
5029 ("nsHttpChannel::ReadFromCache [this=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ReadFromCache [this=%p] " "Using cached copy of: %s\n"
, this, mSpec.get()); } } while (0)
5030 "Using cached copy of: %s\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ReadFromCache [this=%p] " "Using cached copy of: %s\n"
, this, mSpec.get()); } } while (0)
5031 this, mSpec.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ReadFromCache [this=%p] " "Using cached copy of: %s\n"
, this, mSpec.get()); } } while (0)
;
5032
5033 // When racing the cache with the network with a timer, and we get data from
5034 // the cache, we should prevent the timer from triggering a network request.
5035 if (mNetworkTriggerTimer) {
5036 mNetworkTriggerTimer->Cancel();
5037 mNetworkTriggerTimer = nullptr;
5038 }
5039
5040 if (mRaceCacheWithNetwork) {
5041 MOZ_ASSERT(mFirstResponseSource != RESPONSE_FROM_CACHE)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mFirstResponseSource != RESPONSE_FROM_CACHE)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mFirstResponseSource != RESPONSE_FROM_CACHE))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mFirstResponseSource != RESPONSE_FROM_CACHE"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5041); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mFirstResponseSource != RESPONSE_FROM_CACHE"
")"); do { *((volatile int*)__null) = 5041; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5042 if (mFirstResponseSource == RESPONSE_PENDING) {
5043 LOG(("First response from cache\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "First response from cache\n"); } } while (0)
;
5044 mFirstResponseSource = RESPONSE_FROM_CACHE;
5045
5046 // Cancel the transaction because we will serve the request from the cache
5047 CancelNetworkRequest(NS_BINDING_ABORTED);
5048 if (mTransactionPump && mSuspendCount) {
5049 uint32_t suspendCount = mSuspendCount;
5050 while (suspendCount--) {
5051 mTransactionPump->Resume();
5052 }
5053 }
5054 mTransaction = nullptr;
5055 mTransactionPump = nullptr;
5056 } else {
5057 MOZ_ASSERT(mFirstResponseSource == RESPONSE_FROM_NETWORK)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mFirstResponseSource == RESPONSE_FROM_NETWORK)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mFirstResponseSource == RESPONSE_FROM_NETWORK))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("mFirstResponseSource == RESPONSE_FROM_NETWORK"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5057); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mFirstResponseSource == RESPONSE_FROM_NETWORK"
")"); do { *((volatile int*)__null) = 5057; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5058 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Skipping read from cache because first response was from "
"network\n"); } } while (0)
5059 ("Skipping read from cache because first response was from "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Skipping read from cache because first response was from "
"network\n"); } } while (0)
5060 "network\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Skipping read from cache because first response was from "
"network\n"); } } while (0)
;
5061
5062 if (!mOnCacheEntryCheckTimestamp.IsNull()) {
5063 TimeStamp currentTime = TimeStamp::Now();
5064 int64_t savedTime =
5065 (currentTime - mOnStartRequestTimestamp).ToMilliseconds();
5066 Telemetry::Accumulate(
5067 Telemetry::NETWORK_RACE_CACHE_WITH_NETWORK_SAVED_TIME, savedTime);
5068
5069 int64_t diffTime =
5070 (currentTime - mOnCacheEntryCheckTimestamp).ToMilliseconds();
5071 Telemetry::Accumulate(
5072 Telemetry::NETWORK_RACE_CACHE_WITH_NETWORK_OCEC_ON_START_DIFF,
5073 diffTime);
5074 }
5075 return NS_OK;
5076 }
5077 }
5078
5079 if (mCachedResponseHead) mResponseHead = std::move(mCachedResponseHead);
5080
5081 UpdateInhibitPersistentCachingFlag();
5082
5083 // if we don't already have security info, try to get it from the cache
5084 // entry. there are two cases to consider here: 1) we are just reading
5085 // from the cache, or 2) this may be due to a 304 not modified response,
5086 // in which case we could have security info from a socket transport.
5087 if (!mSecurityInfo) mSecurityInfo = mCachedSecurityInfo;
5088
5089 nsresult rv;
5090
5091 // Keep the conditions below in sync with the conditions in
5092 // StartBufferingCachedEntity.
5093
5094 if (WillRedirect(*mResponseHead)) {
5095 // TODO: Bug 759040 - We should call HandleAsyncRedirect directly here,
5096 // to avoid event dispatching latency.
5097 MOZ_ASSERT(!mCacheInputStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCacheInputStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mCacheInputStream))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mCacheInputStream"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5097); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCacheInputStream"
")"); do { *((volatile int*)__null) = 5097; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5098 LOG(("Skipping skip read of cached redirect entity\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Skipping skip read of cached redirect entity\n"); } } while
(0)
;
5099 return AsyncCall(&nsHttpChannel::HandleAsyncRedirect);
5100 }
5101
5102 if ((mLoadFlags & LOAD_ONLY_IF_MODIFIED) && !LoadCachedContentIsPartial()) {
5103 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Skipping read from cache based on LOAD_ONLY_IF_MODIFIED " "load flag\n"
); } } while (0)
5104 ("Skipping read from cache based on LOAD_ONLY_IF_MODIFIED "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Skipping read from cache based on LOAD_ONLY_IF_MODIFIED " "load flag\n"
); } } while (0)
5105 "load flag\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Skipping read from cache based on LOAD_ONLY_IF_MODIFIED " "load flag\n"
); } } while (0)
;
5106 MOZ_ASSERT(!mCacheInputStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCacheInputStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mCacheInputStream))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!mCacheInputStream"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5106); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCacheInputStream"
")"); do { *((volatile int*)__null) = 5106; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5107 // TODO: Bug 759040 - We should call HandleAsyncNotModified directly
5108 // here, to avoid event dispatching latency.
5109 return AsyncCall(&nsHttpChannel::HandleAsyncNotModified);
5110 }
5111
5112 MOZ_ASSERT(mCacheInputStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCacheInputStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCacheInputStream))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mCacheInputStream"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5112); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCacheInputStream"
")"); do { *((volatile int*)__null) = 5112; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5113 if (!mCacheInputStream) {
5114 NS_ERROR(do { NS_DebugBreak(NS_DEBUG_ASSERTION, "mCacheInputStream is null but we're expecting to "
"be able to read from it.", "Error", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5116); MOZ_PretendNoReturn(); } while (0)
5115 "mCacheInputStream is null but we're expecting to "do { NS_DebugBreak(NS_DEBUG_ASSERTION, "mCacheInputStream is null but we're expecting to "
"be able to read from it.", "Error", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5116); MOZ_PretendNoReturn(); } while (0)
5116 "be able to read from it.")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "mCacheInputStream is null but we're expecting to "
"be able to read from it.", "Error", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5116); MOZ_PretendNoReturn(); } while (0)
;
5117 return NS_ERROR_UNEXPECTED;
5118 }
5119
5120 nsCOMPtr<nsIInputStream> inputStream = mCacheInputStream.forget();
5121
5122 rv = nsInputStreamPump::Create(getter_AddRefs(mCachePump), inputStream, 0, 0,
5123 true);
5124 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5125 inputStream->Close();
5126 return rv;
5127 }
5128
5129 rv = mCachePump->AsyncRead(this);
5130 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5131
5132 if (LoadTimingEnabled()) mCacheReadStart = TimeStamp::Now();
5133
5134 uint32_t suspendCount = mSuspendCount;
5135 if (LoadAsyncResumePending()) {
5136 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Suspend()'ing cache pump once because of async resume pending"
", sc=%u, pump=%p, this=%p", suspendCount, mCachePump.get(),
this); } } while (0)
5137 (" Suspend()'ing cache pump once because of async resume pending"do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Suspend()'ing cache pump once because of async resume pending"
", sc=%u, pump=%p, this=%p", suspendCount, mCachePump.get(),
this); } } while (0)
5138 ", sc=%u, pump=%p, this=%p",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Suspend()'ing cache pump once because of async resume pending"
", sc=%u, pump=%p, this=%p", suspendCount, mCachePump.get(),
this); } } while (0)
5139 suspendCount, mCachePump.get(), this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Suspend()'ing cache pump once because of async resume pending"
", sc=%u, pump=%p, this=%p", suspendCount, mCachePump.get(),
this); } } while (0)
;
5140 ++suspendCount;
5141 }
5142 while (suspendCount--) {
5143 mCachePump->Suspend();
5144 }
5145
5146 return NS_OK;
5147}
5148
5149void nsHttpChannel::CloseCacheEntry(bool doomOnFailure) {
5150 mCacheInputStream.CloseAndRelease();
5151
5152 if (!mCacheEntry) return;
5153
5154 LOG(("nsHttpChannel::CloseCacheEntry [this=%p] mStatus=%" PRIx32do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CloseCacheEntry [this=%p] mStatus=%" "x" " CacheEntryIsWriteOnly=%x"
, this, static_cast<uint32_t>(static_cast<nsresult>
(mStatus)), LoadCacheEntryIsWriteOnly()); } } while (0)
5155 " CacheEntryIsWriteOnly=%x",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CloseCacheEntry [this=%p] mStatus=%" "x" " CacheEntryIsWriteOnly=%x"
, this, static_cast<uint32_t>(static_cast<nsresult>
(mStatus)), LoadCacheEntryIsWriteOnly()); } } while (0)
5156 this, static_cast<uint32_t>(static_cast<nsresult>(mStatus)),do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CloseCacheEntry [this=%p] mStatus=%" "x" " CacheEntryIsWriteOnly=%x"
, this, static_cast<uint32_t>(static_cast<nsresult>
(mStatus)), LoadCacheEntryIsWriteOnly()); } } while (0)
5157 LoadCacheEntryIsWriteOnly()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CloseCacheEntry [this=%p] mStatus=%" "x" " CacheEntryIsWriteOnly=%x"
, this, static_cast<uint32_t>(static_cast<nsresult>
(mStatus)), LoadCacheEntryIsWriteOnly()); } } while (0)
;
5158
5159 // If we have begun to create or replace a cache entry, and that cache
5160 // entry is not complete and not resumable, then it needs to be doomed.
5161 // Otherwise, CheckCache will make the mistake of thinking that the
5162 // partial cache entry is complete.
5163
5164 bool doom = false;
5165 if (LoadInitedCacheEntry()) {
5166 MOZ_ASSERT(mResponseHead, "oops")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mResponseHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mResponseHead))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mResponseHead" " ("
"oops" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5166); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mResponseHead"
") (" "oops" ")"); do { *((volatile int*)__null) = 5166; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
5167 if (NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0))) && doomOnFailure && LoadCacheEntryIsWriteOnly() &&
5168 !mResponseHead->IsResumable()) {
5169 doom = true;
5170 }
5171 } else if (LoadCacheEntryIsWriteOnly()) {
5172 doom = true;
5173 }
5174
5175 if (doom) {
5176 LOG((" dooming cache entry!!"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " dooming cache entry!!"); } } while (0)
;
5177 mCacheEntry->AsyncDoom(nullptr);
5178 } else {
5179 // Store updated security info, makes cached EV status race less likely
5180 // (see bug 1040086)
5181 if (mSecurityInfo) {
5182 mCacheEntry->SetSecurityInfo(mSecurityInfo);
5183 }
5184 }
5185
5186 mCachedResponseHead = nullptr;
5187
5188 mCachePump = nullptr;
5189 // This releases the entry for other consumers to use.
5190 // We call Dismiss() in case someone still keeps a reference
5191 // to this entry handle.
5192 mCacheEntry->Dismiss();
5193 mCacheEntry = nullptr;
5194 StoreCacheEntryIsWriteOnly(false);
5195 StoreInitedCacheEntry(false);
5196}
5197
5198void nsHttpChannel::MaybeCreateCacheEntryWhenRCWN() {
5199 mozilla::MutexAutoLock lock(mRCWNLock);
5200
5201 // Create cache entry for writing only when we're racing cache with network
5202 // and we don't have the entry because network won.
5203 if (mCacheEntry || !mRaceCacheWithNetwork ||
5204 mFirstResponseSource != RESPONSE_FROM_NETWORK ||
5205 LoadCacheEntryIsReadOnly()) {
5206 return;
5207 }
5208
5209 LOG(("nsHttpChannel::MaybeCreateCacheEntryWhenRCWN [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeCreateCacheEntryWhenRCWN [this=%p]", this
); } } while (0)
;
5210
5211 nsCOMPtr<nsICacheStorageService> cacheStorageService(
5212 components::CacheStorage::Service());
5213 if (!cacheStorageService) {
5214 return;
5215 }
5216
5217 nsCOMPtr<nsICacheStorage> cacheStorage;
5218 RefPtr<LoadContextInfo> info = GetLoadContextInfo(this);
5219 Unused << cacheStorageService->DiskCacheStorage(info,
5220 getter_AddRefs(cacheStorage));
5221 if (!cacheStorage) {
5222 return;
5223 }
5224
5225 Unused << cacheStorage->OpenTruncate(mCacheEntryURI, mCacheIdExtension,
5226 getter_AddRefs(mCacheEntry));
5227
5228 LOG((" created entry %p", mCacheEntry.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " created entry %p", mCacheEntry.get()); } } while (0)
;
5229
5230 if (AwaitingCacheCallbacks()) {
5231 // Setting mIgnoreCacheEntry to true ensures that we won't close this
5232 // write-only entry in OnCacheEntryAvailable() if this method was called
5233 // after OnCacheEntryCheck().
5234 mIgnoreCacheEntry = true;
5235 }
5236
5237 mAvailableCachedAltDataType.Truncate();
5238 StoreDeliveringAltData(false);
5239 mAltDataLength = -1;
5240 mCacheInputStream.CloseAndRelease();
5241 mCachedContentIsValid = false;
5242}
5243
5244// Initialize the cache entry for writing.
5245// - finalize storage policy
5246// - store security info
5247// - update expiration time
5248// - store headers and other meta data
5249nsresult nsHttpChannel::InitCacheEntry() {
5250 nsresult rv;
5251
5252 NS_ENSURE_TRUE(mCacheEntry, NS_ERROR_UNEXPECTED)do { if ((__builtin_expect(!!(!(mCacheEntry)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mCacheEntry" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5252); return NS_ERROR_UNEXPECTED; } } while (false)
;
5253 // if only reading, nothing to be done here.
5254 if (LoadCacheEntryIsReadOnly()) return NS_OK;
5255
5256 // Don't cache the response again if already cached...
5257 if (mCachedContentIsValid) return NS_OK;
5258
5259 LOG(("nsHttpChannel::InitCacheEntry [this=%p entry=%p]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::InitCacheEntry [this=%p entry=%p]\n", this,
mCacheEntry.get()); } } while (0)
5260 mCacheEntry.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::InitCacheEntry [this=%p entry=%p]\n", this,
mCacheEntry.get()); } } while (0)
;
5261
5262 bool recreate = !LoadCacheEntryIsWriteOnly();
5263 bool dontPersist = mLoadFlags & INHIBIT_PERSISTENT_CACHING;
5264
5265 if (!recreate && dontPersist) {
5266 // If the current entry is persistent but we inhibit peristence
5267 // then force recreation of the entry as memory/only.
5268 rv = mCacheEntry->GetPersistent(&recreate);
5269 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5270 }
5271
5272 if (recreate) {
5273 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " we have a ready entry, but reading it again from the server -> "
"recreating cache entry\n"); } } while (0)
5274 (" we have a ready entry, but reading it again from the server -> "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " we have a ready entry, but reading it again from the server -> "
"recreating cache entry\n"); } } while (0)
5275 "recreating cache entry\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " we have a ready entry, but reading it again from the server -> "
"recreating cache entry\n"); } } while (0)
;
5276 // clean the altData cache and reset this to avoid wrong content length
5277 mAvailableCachedAltDataType.Truncate();
5278 StoreDeliveringAltData(false);
5279
5280 nsCOMPtr<nsICacheEntry> currentEntry;
5281 currentEntry.swap(mCacheEntry);
5282 rv = currentEntry->Recreate(dontPersist, getter_AddRefs(mCacheEntry));
5283 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5284 LOG((" recreation failed, the response will not be cached"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " recreation failed, the response will not be cached"); } }
while (0)
;
5285 return NS_OK;
5286 }
5287
5288 StoreCacheEntryIsWriteOnly(true);
5289 }
5290
5291 // Set the expiration time for this cache entry
5292 rv = UpdateExpirationTime();
5293 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5294
5295 // mark this weakly framed until a response body is seen
5296 mCacheEntry->SetMetaDataElement("strongly-framed", "0");
5297
5298 rv = AddCacheEntryHeaders(mCacheEntry);
5299 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5300
5301 StoreInitedCacheEntry(true);
5302
5303 // Don't perform the check when writing (doesn't make sense)
5304 StoreConcurrentCacheAccess(0);
5305
5306 return NS_OK;
5307}
5308
5309void nsHttpChannel::UpdateInhibitPersistentCachingFlag() {
5310 // The no-store directive within the 'Cache-Control:' header indicates
5311 // that we must not store the response in a persistent cache.
5312 if (mResponseHead->NoStore()) {
5313 mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
5314 return;
5315 }
5316
5317 if (!StaticPrefs::network_cache_persist_permanent_redirects_http() &&
5318 mURI->SchemeIs("http") &&
5319 nsHttp::IsPermanentRedirect(mResponseHead->Status())) {
5320 mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
5321 return;
5322 }
5323
5324 // Only cache SSL content on disk if the pref is set
5325 if (!gHttpHandler->IsPersistentHttpsCachingEnabled() &&
5326 mURI->SchemeIs("https")) {
5327 mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
5328 }
5329}
5330
5331nsresult DoAddCacheEntryHeaders(nsHttpChannel* self, nsICacheEntry* entry,
5332 nsHttpRequestHead* requestHead,
5333 nsHttpResponseHead* responseHead,
5334 nsITransportSecurityInfo* securityInfo) {
5335 nsresult rv;
5336
5337 LOG(("nsHttpChannel::AddCacheEntryHeaders [this=%p] begin", self))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] begin", self
); } } while (0)
;
5338 // Store secure data in memory only
5339 if (securityInfo) {
5340 entry->SetSecurityInfo(securityInfo);
5341 }
5342
5343 // Store the HTTP request method with the cache entry so we can distinguish
5344 // for example GET and HEAD responses.
5345 nsAutoCString method;
5346 requestHead->Method(method);
5347 rv = entry->SetMetaDataElement("request-method", method.get());
5348 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5349
5350 // Store the HTTP authorization scheme used if any...
5351 rv = StoreAuthorizationMetaData(entry, requestHead);
5352 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5353
5354 // Iterate over the headers listed in the Vary response header, and
5355 // store the value of the corresponding request header so we can verify
5356 // that it has not varied when we try to re-use the cached response at
5357 // a later time. Take care to store "Cookie" headers only as hashes
5358 // due to security considerations and the fact that they can be pretty
5359 // large (bug 468426). We take care of "Vary: cookie" in ResponseWouldVary.
5360 //
5361 // NOTE: if "Vary: accept, cookie", then we will store the "accept" header
5362 // in the cache. we could try to avoid needlessly storing the "accept"
5363 // header in this case, but it doesn't seem worth the extra code to perform
5364 // the check.
5365 {
5366 nsAutoCString buf, metaKey;
5367 Unused << responseHead->GetHeader(nsHttp::Vary, buf);
5368
5369 constexpr auto prefix = "request-"_ns;
5370
5371 for (const nsACString& token :
5372 nsCCharSeparatedTokenizer(buf, NS_HTTP_HEADER_SEP',').ToRange()) {
5373 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] " "processing %s"
, self, nsPromiseFlatCString(token).get()); } } while (0)
5374 ("nsHttpChannel::AddCacheEntryHeaders [this=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] " "processing %s"
, self, nsPromiseFlatCString(token).get()); } } while (0)
5375 "processing %s",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] " "processing %s"
, self, nsPromiseFlatCString(token).get()); } } while (0)
5376 self, nsPromiseFlatCString(token).get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] " "processing %s"
, self, nsPromiseFlatCString(token).get()); } } while (0)
;
5377 if (!token.EqualsLiteral("*")) {
5378 nsHttpAtom atom = nsHttp::ResolveAtom(token);
5379 nsAutoCString val;
5380 nsAutoCString hash;
5381 if (NS_SUCCEEDED(requestHead->GetHeader(atom, val))((bool)(__builtin_expect(!!(!NS_FAILED_impl(requestHead->GetHeader
(atom, val))), 1)))
) {
5382 // If cookie-header, store a hash of the value
5383 if (atom == nsHttp::Cookie) {
5384 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] " "cookie-value %s"
, self, val.get()); } } while (0)
5385 ("nsHttpChannel::AddCacheEntryHeaders [this=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] " "cookie-value %s"
, self, val.get()); } } while (0)
5386 "cookie-value %s",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] " "cookie-value %s"
, self, val.get()); } } while (0)
5387 self, val.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] " "cookie-value %s"
, self, val.get()); } } while (0)
;
5388 rv = Hash(val.get(), hash);
5389 // If hash failed, store a string not very likely
5390 // to be the result of subsequent hashes
5391 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5392 val = "<hash failed>"_ns;
5393 } else {
5394 val = hash;
5395 }
5396
5397 LOG((" hashed to %s\n", val.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " hashed to %s\n", val.get()); } } while (0)
;
5398 }
5399
5400 // build cache meta data key and set meta data element...
5401 metaKey = prefix + token;
5402 entry->SetMetaDataElement(metaKey.get(), val.get());
5403 } else {
5404 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] " "clearing metadata for %s"
, self, nsPromiseFlatCString(token).get()); } } while (0)
5405 ("nsHttpChannel::AddCacheEntryHeaders [this=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] " "clearing metadata for %s"
, self, nsPromiseFlatCString(token).get()); } } while (0)
5406 "clearing metadata for %s",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] " "clearing metadata for %s"
, self, nsPromiseFlatCString(token).get()); } } while (0)
5407 self, nsPromiseFlatCString(token).get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AddCacheEntryHeaders [this=%p] " "clearing metadata for %s"
, self, nsPromiseFlatCString(token).get()); } } while (0)
;
5408 metaKey = prefix + token;
5409 entry->SetMetaDataElement(metaKey.get(), nullptr);
5410 }
5411 }
5412 }
5413 }
5414
5415 // Store the received HTTP head with the cache entry as an element of
5416 // the meta data.
5417 nsAutoCString head;
5418 responseHead->Flatten(head, true);
5419 rv = entry->SetMetaDataElement("response-head", head.get());
5420 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5421 head.Truncate();
5422 responseHead->FlattenNetworkOriginalHeaders(head);
5423 rv = entry->SetMetaDataElement("original-response-headers", head.get());
5424 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5425
5426 // Indicate we have successfully finished setting metadata on the cache entry.
5427 rv = entry->MetaDataReady();
5428
5429 return rv;
5430}
5431
5432nsresult nsHttpChannel::AddCacheEntryHeaders(nsICacheEntry* entry) {
5433 return DoAddCacheEntryHeaders(this, entry, &mRequestHead, mResponseHead.get(),
5434 mSecurityInfo);
5435}
5436
5437inline void GetAuthType(const char* challenge, nsCString& authType) {
5438 const char* p;
5439
5440 // get the challenge type
5441 if ((p = strchr(challenge, ' ')) != nullptr) {
5442 authType.Assign(challenge, p - challenge);
5443 } else {
5444 authType.Assign(challenge);
5445 }
5446}
5447
5448nsresult StoreAuthorizationMetaData(nsICacheEntry* entry,
5449 nsHttpRequestHead* requestHead) {
5450 // Not applicable to proxy authorization...
5451 nsAutoCString val;
5452 if (NS_FAILED(requestHead->GetHeader(nsHttp::Authorization, val))((bool)(__builtin_expect(!!(NS_FAILED_impl(requestHead->GetHeader
(nsHttp::Authorization, val))), 0)))
) {
5453 return NS_OK;
5454 }
5455
5456 // eg. [Basic realm="wally world"]
5457 nsAutoCString buf;
5458 GetAuthType(val.get(), buf);
5459 return entry->SetMetaDataElement("auth", buf.get());
5460}
5461
5462// Finalize the cache entry
5463// - may need to rewrite response headers if any headers changed
5464// - may need to recalculate the expiration time if any headers changed
5465// - called only for freshly written cache entries
5466nsresult nsHttpChannel::FinalizeCacheEntry() {
5467 LOG(("nsHttpChannel::FinalizeCacheEntry [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::FinalizeCacheEntry [this=%p]\n", this); } }
while (0)
;
5468
5469 // Don't update this meta-data on 304
5470 if (LoadStronglyFramed() && !mCachedContentIsValid && mCacheEntry) {
5471 LOG(("nsHttpChannel::FinalizeCacheEntry [this=%p] Is Strongly Framed\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::FinalizeCacheEntry [this=%p] Is Strongly Framed\n"
, this); } } while (0)
5472 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::FinalizeCacheEntry [this=%p] Is Strongly Framed\n"
, this); } } while (0)
;
5473 mCacheEntry->SetMetaDataElement("strongly-framed", "1");
5474 }
5475
5476 if (mResponseHead && LoadResponseHeadersModified()) {
5477 // Set the expiration time for this cache entry
5478 nsresult rv = UpdateExpirationTime();
5479 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5480 }
5481 return NS_OK;
5482}
5483
5484// Open an output stream to the cache entry and insert a listener tee into
5485// the chain of response listeners.
5486nsresult nsHttpChannel::InstallCacheListener(int64_t offset) {
5487 nsresult rv;
5488
5489 LOG(("Preparing to write data into the cache [uri=%s]\n", mSpec.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Preparing to write data into the cache [uri=%s]\n", mSpec.
get()); } } while (0)
;
5490
5491 MOZ_ASSERT(mCacheEntry)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCacheEntry)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCacheEntry))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("mCacheEntry", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5491); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCacheEntry"
")"); do { *((volatile int*)__null) = 5491; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5492 MOZ_ASSERT(LoadCacheEntryIsWriteOnly() || LoadCachedContentIsPartial() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadCacheEntryIsWriteOnly() || LoadCachedContentIsPartial
() || mRaceCacheWithNetwork)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadCacheEntryIsWriteOnly() ||
LoadCachedContentIsPartial() || mRaceCacheWithNetwork))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("LoadCacheEntryIsWriteOnly() || LoadCachedContentIsPartial() || mRaceCacheWithNetwork"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5493); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadCacheEntryIsWriteOnly() || LoadCachedContentIsPartial() || mRaceCacheWithNetwork"
")"); do { *((volatile int*)__null) = 5493; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5493 mRaceCacheWithNetwork)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadCacheEntryIsWriteOnly() || LoadCachedContentIsPartial
() || mRaceCacheWithNetwork)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadCacheEntryIsWriteOnly() ||
LoadCachedContentIsPartial() || mRaceCacheWithNetwork))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("LoadCacheEntryIsWriteOnly() || LoadCachedContentIsPartial() || mRaceCacheWithNetwork"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5493); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadCacheEntryIsWriteOnly() || LoadCachedContentIsPartial() || mRaceCacheWithNetwork"
")"); do { *((volatile int*)__null) = 5493; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5494 MOZ_ASSERT(mListener)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mListener)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mListener))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mListener", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5494); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mListener" ")"
); do { *((volatile int*)__null) = 5494; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5495
5496 nsAutoCString contentEncoding, contentType;
5497 Unused << mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
5498 mResponseHead->ContentType(contentType);
5499 // If the content is compressible and the server has not compressed it,
5500 // mark the cache entry for compression.
5501 if (contentEncoding.IsEmpty() &&
5502 (contentType.EqualsLiteral(TEXT_HTML"text/html") ||
5503 contentType.EqualsLiteral(TEXT_PLAIN"text/plain") ||
5504 contentType.EqualsLiteral(TEXT_CSS"text/css") ||
5505 contentType.EqualsLiteral(TEXT_JAVASCRIPT"text/javascript") ||
5506 contentType.EqualsLiteral(TEXT_ECMASCRIPT"text/ecmascript") ||
5507 contentType.EqualsLiteral(TEXT_XML"text/xml") ||
5508 contentType.EqualsLiteral(APPLICATION_JAVASCRIPT"application/javascript") ||
5509 contentType.EqualsLiteral(APPLICATION_ECMASCRIPT"application/ecmascript") ||
5510 contentType.EqualsLiteral(APPLICATION_XJAVASCRIPT"application/x-javascript") ||
5511 contentType.EqualsLiteral(APPLICATION_XHTML_XML"application/xhtml+xml"))) {
5512 rv = mCacheEntry->SetMetaDataElement("uncompressed-len", "0");
5513 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5514 LOG(("unable to mark cache entry for compression"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "unable to mark cache entry for compression"); } } while (0
)
;
5515 }
5516 }
5517
5518 LOG(("Trading cache input stream for output stream [channel=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Trading cache input stream for output stream [channel=%p]"
, this); } } while (0)
;
5519
5520 // We must close the input stream first because cache entries do not
5521 // correctly handle having an output stream and input streams open at
5522 // the same time.
5523 mCacheInputStream.CloseAndRelease();
5524
5525 int64_t predictedSize = mResponseHead->TotalEntitySize();
5526 if (predictedSize != -1) {
5527 predictedSize -= offset;
5528 }
5529
5530 nsCOMPtr<nsIOutputStream> out;
5531 rv =
5532 mCacheEntry->OpenOutputStream(offset, predictedSize, getter_AddRefs(out));
5533 if (rv == NS_ERROR_NOT_AVAILABLE) {
5534 LOG((" entry doomed, not writing it [channel=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " entry doomed, not writing it [channel=%p]", this); } } while
(0)
;
5535 // Entry is already doomed.
5536 // This may happen when expiration time is set to past and the entry
5537 // has been removed by the background eviction logic.
5538 return NS_OK;
5539 }
5540 if (rv == NS_ERROR_FILE_TOO_BIG) {
5541 LOG((" entry would exceed max allowed size, not writing it [channel=%p]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " entry would exceed max allowed size, not writing it [channel=%p]"
, this); } } while (0)
5542 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " entry would exceed max allowed size, not writing it [channel=%p]"
, this); } } while (0)
;
5543 mCacheEntry->AsyncDoom(nullptr);
5544 return NS_OK;
5545 }
5546 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5547
5548 if (LoadCacheOnlyMetadata()) {
5549 LOG(("Not storing content, cacheOnlyMetadata set"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Not storing content, cacheOnlyMetadata set"); } } while (0
)
;
5550 // We must open and then close the output stream of the cache entry.
5551 // This way we indicate the content has been written (despite with zero
5552 // length) and the entry is now in the ready state with "having data".
5553
5554 out->Close();
5555 return NS_OK;
5556 }
5557
5558 // XXX disk cache does not support overlapped i/o yet
5559#if 0
5560 // Mark entry valid inorder to allow simultaneous reading...
5561 rv = mCacheEntry->MarkValid();
5562 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5563#endif
5564
5565 nsCOMPtr<nsIStreamListenerTee> tee =
5566 do_CreateInstance(kStreamListenerTeeCID, &rv);
5567 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5568
5569 LOG(("nsHttpChannel::InstallCacheListener sync tee %p rv=%" PRIx32, tee.get(),do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::InstallCacheListener sync tee %p rv=%" "x",
tee.get(), static_cast<uint32_t>(rv)); } } while (0)
5570 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::InstallCacheListener sync tee %p rv=%" "x",
tee.get(), static_cast<uint32_t>(rv)); } } while (0)
;
5571 rv = tee->Init(mListener, out, nullptr);
5572 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5573
5574 mListener = tee;
5575 return NS_OK;
5576}
5577
5578//-----------------------------------------------------------------------------
5579// nsHttpChannel <redirect>
5580//-----------------------------------------------------------------------------
5581
5582nsresult nsHttpChannel::SetupReplacementChannel(nsIURI* newURI,
5583 nsIChannel* newChannel,
5584 bool preserveMethod,
5585 uint32_t redirectFlags) {
5586 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d]"
, this, newChannel, preserveMethod); } } while (0)
5587 ("nsHttpChannel::SetupReplacementChannel "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d]"
, this, newChannel, preserveMethod); } } while (0)
5588 "[this=%p newChannel=%p preserveMethod=%d]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d]"
, this, newChannel, preserveMethod); } } while (0)
5589 this, newChannel, preserveMethod))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d]"
, this, newChannel, preserveMethod); } } while (0)
;
5590
5591 if (!mEndMarkerAdded && profiler_thread_is_being_profiled_for_markers()) {
5592 mEndMarkerAdded = true;
5593
5594 nsAutoCString requestMethod;
5595 GetRequestMethod(requestMethod);
5596
5597 int32_t priority = PRIORITY_NORMAL;
5598 GetPriority(&priority);
5599
5600 TimingStruct timings;
5601 if (mTransaction) {
5602 timings = mTransaction->Timings();
5603 }
5604
5605 uint64_t size = 0;
5606 GetEncodedBodySize(&size);
5607
5608 nsAutoCString contentType;
5609 if (mResponseHead) {
5610 mResponseHead->ContentType(contentType);
5611 }
5612
5613 RefPtr<nsIIdentChannel> newIdentChannel = do_QueryObject(newChannel);
5614 uint64_t channelId = 0;
5615 if (newIdentChannel) {
5616 channelId = newIdentChannel->ChannelId();
5617 }
5618 profiler_add_network_marker(
5619 mURI, requestMethod, priority, mChannelId,
5620 NetworkLoadType::LOAD_REDIRECT, mLastStatusReported, TimeStamp::Now(),
5621 size, mCacheDisposition, mLoadInfo->GetInnerWindowID(),
5622 mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(), &timings,
5623 std::move(mSource), Some(nsDependentCString(contentType.get())), newURI,
5624 redirectFlags, channelId);
5625 }
5626
5627 nsresult rv = HttpBaseChannel::SetupReplacementChannel(
5628 newURI, newChannel, preserveMethod, redirectFlags);
5629 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5630
5631 nsAutoCString uriHost;
5632 mURI->GetAsciiHost(uriHost);
5633 // disable https-rr when encountering a downgrade from https to http.
5634 // If the host would have https-rr dns-entries, it would be misconfigured
5635 // due to giving us mixed signals:
5636 // 1. the signal to upgrade all http requests to https,
5637 // 2. but also downgrading to http on https via redirects.
5638 // Add to exclude list for that reason
5639 if (!gHttpHandler->IsHostExcludedForHTTPSRR(uriHost) &&
5640 nsHTTPSOnlyUtils::IsUpgradeDowngradeEndlessLoop(
5641 mURI, newURI, mLoadInfo,
5642 {nsHTTPSOnlyUtils::UpgradeDowngradeEndlessLoopOptions::
5643 EnforceForHTTPSRR})) {
5644 // Add the host to a excluded list because:
5645 // 1. We don't need to do the same check again.
5646 // 2. Other subresources in the same host will be also excluded.
5647 gHttpHandler->ExcludeHTTPSRRHost(uriHost);
5648 LOG(("[%p] skip HTTPS upgrade for host [%s]", this, uriHost.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "[%p] skip HTTPS upgrade for host [%s]", this, uriHost.get(
)); } } while (0)
;
5649 }
5650
5651 rv = CheckRedirectLimit(newURI, redirectFlags);
5652 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5652); return rv; } } while (false)
;
5653
5654 // pass on the early hint observer to be able to process `103 Early Hints`
5655 // responses after cross origin redirects
5656 if (mEarlyHintObserver) {
5657 if (RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(newChannel)) {
5658 httpChannelImpl->SetEarlyHintObserver(mEarlyHintObserver);
5659 }
5660 mEarlyHintObserver = nullptr;
5661 }
5662
5663 // We don't support redirection for WebTransport for now.
5664 mWebTransportSessionEventListener = nullptr;
5665
5666 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
5667 if (!httpChannel) return NS_OK; // no other options to set
5668
5669 // convey the ApplyConversion flag (bug 91862)
5670 nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(httpChannel);
5671 if (encodedChannel) encodedChannel->SetApplyConversion(LoadApplyConversion());
5672
5673 // transfer the resume information
5674 if (LoadResuming()) {
5675 nsCOMPtr<nsIResumableChannel> resumableChannel(
5676 do_QueryInterface(newChannel));
5677 if (!resumableChannel) {
5678 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "Got asked to resume, but redirected to non-resumable channel!"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5679)
5679 "Got asked to resume, but redirected to non-resumable channel!")NS_DebugBreak(NS_DEBUG_WARNING, "Got asked to resume, but redirected to non-resumable channel!"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5679)
;
5680 return NS_ERROR_NOT_RESUMABLE;
5681 }
5682 resumableChannel->ResumeAt(mStartPos, mEntityID);
5683 }
5684
5685 nsCOMPtr<nsIHttpChannelInternal> internalChannel =
5686 do_QueryInterface(newChannel, &rv);
5687 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5688 TimeStamp timestamp;
5689 rv = GetNavigationStartTimeStamp(&timestamp);
5690 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5690)
) {
5691 return rv;
5692 }
5693 if (timestamp) {
5694 Unused << internalChannel->SetNavigationStartTimeStamp(timestamp);
5695 }
5696 }
5697
5698 return NS_OK;
5699}
5700
5701nsresult nsHttpChannel::AsyncProcessRedirection(uint32_t redirectType) {
5702 LOG(("nsHttpChannel::AsyncProcessRedirection [this=%p type=%u]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AsyncProcessRedirection [this=%p type=%u]\n"
, this, redirectType); } } while (0)
5703 redirectType))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AsyncProcessRedirection [this=%p type=%u]\n"
, this, redirectType); } } while (0)
;
5704
5705 nsresult rv = ProcessCrossOriginSecurityHeaders();
5706 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5707 mStatus = rv;
5708 HandleAsyncAbort();
5709 return rv;
5710 }
5711
5712 nsAutoCString location;
5713
5714 // if a location header was not given, then we can't perform the redirect,
5715 // so just carry on as though this were a normal response.
5716 if (NS_FAILED(mResponseHead->GetHeader(nsHttp::Location, location))((bool)(__builtin_expect(!!(NS_FAILED_impl(mResponseHead->
GetHeader(nsHttp::Location, location))), 0)))
) {
5717 return NS_ERROR_FAILURE;
5718 }
5719
5720 // If we were told to not follow redirects automatically, then again
5721 // carry on as though this were a normal response.
5722 if (mLoadInfo->GetDontFollowRedirects()) {
5723 return NS_ERROR_FAILURE;
5724 }
5725
5726 // make sure non-ASCII characters in the location header are escaped.
5727 nsAutoCString locationBuf;
5728 if (NS_EscapeURL(location.get(), -1, esc_OnlyNonASCII | esc_Spaces,
5729 locationBuf)) {
5730 location = locationBuf;
5731 }
5732
5733 mRedirectType = redirectType;
5734
5735 LOG(("redirecting to: %s [redirection-limit=%u]\n", location.get(),do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "redirecting to: %s [redirection-limit=%u]\n", location.get
(), uint32_t(mRedirectionLimit)); } } while (0)
5736 uint32_t(mRedirectionLimit)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "redirecting to: %s [redirection-limit=%u]\n", location.get
(), uint32_t(mRedirectionLimit)); } } while (0)
;
5737
5738 rv = CreateNewURI(location.get(), getter_AddRefs(mRedirectURI));
5739
5740 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5741 LOG(("Invalid URI for redirect: Location: %s\n", location.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Invalid URI for redirect: Location: %s\n", location.get())
; } } while (0)
;
5742 return NS_ERROR_CORRUPTED_CONTENT;
5743 }
5744
5745 if (!StaticPrefs::network_allow_redirect_to_data() &&
5746 !mLoadInfo->GetAllowInsecureRedirectToDataURI() &&
5747 mRedirectURI->SchemeIs("data")) {
5748 LOG(("Invalid data URI for redirect!"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Invalid data URI for redirect!"); } } while (0)
;
5749 nsContentSecurityManager::ReportBlockedDataURI(mRedirectURI, mLoadInfo,
5750 true);
5751 return NS_ERROR_DOM_BAD_URI;
5752 }
5753
5754 // Perform the URL query string stripping for redirects. We will only strip
5755 // the query string if it is redirecting to a third-party URI in the top
5756 // level.
5757 if (StaticPrefs::privacy_query_stripping_redirect()) {
5758 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
5759 bool isThirdPartyRedirectURI = true;
5760 thirdPartyUtil->IsThirdPartyURI(mURI, mRedirectURI,
5761 &isThirdPartyRedirectURI);
5762 if (isThirdPartyRedirectURI && mLoadInfo->GetExternalContentPolicyType() ==
5763 ExtContentPolicy::TYPE_DOCUMENT) {
5764 Telemetry::AccumulateCategorical(
5765 Telemetry::LABELS_QUERY_STRIPPING_COUNT::Redirect);
5766
5767 nsCOMPtr<nsIPrincipal> prin;
5768 ContentBlockingAllowList::RecomputePrincipal(
5769 mRedirectURI, mLoadInfo->GetOriginAttributes(), getter_AddRefs(prin));
5770
5771 bool isRedirectURIInAllowList = false;
5772 if (prin) {
5773 ContentBlockingAllowList::Check(prin, mPrivateBrowsing,
5774 isRedirectURIInAllowList);
5775 }
5776
5777 if (!isRedirectURIInAllowList) {
5778 nsCOMPtr<nsIURI> strippedURI;
5779
5780 nsCOMPtr<nsIURLQueryStringStripper> queryStripper;
5781 queryStripper =
5782 mozilla::components::URLQueryStringStripper::Service(&rv);
5783 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5783); return rv; } } while (false)
;
5784
5785 uint32_t numStripped;
5786
5787 rv = queryStripper->Strip(mRedirectURI, mPrivateBrowsing,
5788 getter_AddRefs(strippedURI), &numStripped);
5789 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5789); return rv; } } while (false)
;
5790
5791 if (numStripped) {
5792 mUnstrippedRedirectURI = mRedirectURI;
5793 mRedirectURI = strippedURI;
5794
5795 // Record telemetry, but only if we stripped any query params.
5796 Telemetry::AccumulateCategorical(
5797 Telemetry::LABELS_QUERY_STRIPPING_COUNT::StripForRedirect);
5798 Telemetry::Accumulate(Telemetry::QUERY_STRIPPING_PARAM_COUNT,
5799 numStripped);
5800 }
5801 }
5802 }
5803 }
5804
5805 if (NS_WARN_IF(!mRedirectURI)NS_warn_if_impl(!mRedirectURI, "!mRedirectURI", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5805)
) {
5806 LOG(("Invalid redirect URI after performaing query string stripping"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Invalid redirect URI after performaing query string stripping"
); } } while (0)
;
5807 return NS_ERROR_FAILURE;
5808 }
5809
5810 return ContinueProcessRedirectionAfterFallback(NS_OK);
5811}
5812
5813nsresult nsHttpChannel::ContinueProcessRedirectionAfterFallback(nsresult rv) {
5814 // Kill the current cache entry if we are redirecting
5815 // back to ourself.
5816 bool redirectingBackToSameURI = false;
5817 if (mCacheEntry && LoadCacheEntryIsWriteOnly() &&
5818 NS_SUCCEEDED(mURI->Equals(mRedirectURI, &redirectingBackToSameURI))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mURI->Equals(mRedirectURI
, &redirectingBackToSameURI))), 1)))
&&
5819 redirectingBackToSameURI) {
5820 mCacheEntry->AsyncDoom(nullptr);
5821 }
5822
5823 // move the reference of the old location to the new one if the new
5824 // one has none.
5825 PropagateReferenceIfNeeded(mURI, mRedirectURI);
5826
5827 bool rewriteToGET =
5828 ShouldRewriteRedirectToGET(mRedirectType, mRequestHead.ParsedMethod());
5829
5830 // prompt if the method is not safe (such as POST, PUT, DELETE, ...)
5831 if (!rewriteToGET && !mRequestHead.IsSafeMethod()) {
5832 rv = PromptTempRedirect();
5833 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5834 }
5835
5836 uint32_t redirectFlags;
5837 if (nsHttp::IsPermanentRedirect(mRedirectType)) {
5838 redirectFlags = nsIChannelEventSink::REDIRECT_PERMANENT;
5839 } else {
5840 redirectFlags = nsIChannelEventSink::REDIRECT_TEMPORARY;
5841 }
5842
5843 nsCOMPtr<nsIIOService> ioService;
5844 rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
5845 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5846
5847 nsCOMPtr<nsIChannel> newChannel;
5848 nsCOMPtr<nsILoadInfo> redirectLoadInfo =
5849 CloneLoadInfoForRedirect(mRedirectURI, redirectFlags);
5850
5851 // Propagate the unstripped redirect URI.
5852 redirectLoadInfo->SetUnstrippedURI(mUnstrippedRedirectURI);
5853
5854 rv = NS_NewChannelInternal(getter_AddRefs(newChannel), mRedirectURI,
5855 redirectLoadInfo,
5856 nullptr, // PerformanceStorage
5857 nullptr, // aLoadGroup
5858 nullptr, // aCallbacks
5859 nsIRequest::LOAD_NORMAL, ioService);
5860 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5860); return rv; } } while (false)
;
5861
5862 rv = SetupReplacementChannel(mRedirectURI, newChannel, !rewriteToGET,
5863 redirectFlags);
5864 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5865
5866 // verify that this is a legal redirect
5867 mRedirectChannel = newChannel;
5868
5869 PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessRedirection);
5870 rv = gHttpHandler->AsyncOnChannelRedirect(this, newChannel, redirectFlags);
5871
5872 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = WaitForRedirectCallback();
5873
5874 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5875 AutoRedirectVetoNotifier notifier(this, rv);
5876 PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessRedirection);
5877 }
5878
5879 return rv;
5880}
5881
5882nsresult nsHttpChannel::ContinueProcessRedirection(nsresult rv) {
5883 AutoRedirectVetoNotifier notifier(this, rv);
5884
5885 LOG(("nsHttpChannel::ContinueProcessRedirection [rv=%" PRIx32 ",this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessRedirection [rv=%" "x" ",this=%p]\n"
, static_cast<uint32_t>(rv), this); } } while (0)
5886 static_cast<uint32_t>(rv), this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueProcessRedirection [rv=%" "x" ",this=%p]\n"
, static_cast<uint32_t>(rv), this); } } while (0)
;
5887 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5888
5889 MOZ_ASSERT(mRedirectChannel, "No redirect channel?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRedirectChannel)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mRedirectChannel))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mRedirectChannel"
" (" "No redirect channel?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5889); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRedirectChannel"
") (" "No redirect channel?" ")"); do { *((volatile int*)__null
) = 5889; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
5890
5891 // Make sure to do this after we received redirect veto answer,
5892 // i.e. after all sinks had been notified
5893 mRedirectChannel->SetOriginalURI(mOriginalURI);
5894
5895 // XXX we used to talk directly with the script security manager, but that
5896 // should really be handled by the event sink implementation.
5897
5898 // begin loading the new channel
5899 rv = mRedirectChannel->AsyncOpen(mListener);
5900 LOG((" new channel AsyncOpen returned %" PRIX32, static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " new channel AsyncOpen returned %" "X", static_cast<uint32_t
>(rv)); } } while (0)
;
5901 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5901); return rv; } } while (false)
;
5902
5903 // close down this channel
5904 Cancel(NS_BINDING_REDIRECTED);
5905
5906 notifier.RedirectSucceeded();
5907
5908 ReleaseListeners();
5909
5910 return NS_OK;
5911}
5912
5913//-----------------------------------------------------------------------------
5914// nsHttpChannel <auth>
5915//-----------------------------------------------------------------------------
5916
5917NS_IMETHODIMPnsresult nsHttpChannel::OnAuthAvailable() {
5918 LOG(("nsHttpChannel::OnAuthAvailable [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnAuthAvailable [this=%p]", this); } } while
(0)
;
5919
5920 // setting mAuthRetryPending flag and resuming the transaction
5921 // triggers process of throwing away the unauthenticated data already
5922 // coming from the network
5923 mIsAuthChannel = true;
5924 mAuthRetryPending = true;
5925 StoreProxyAuthPending(false);
5926 LOG(("Resuming the transaction, we got credentials from user"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Resuming the transaction, we got credentials from user"); }
} while (0)
;
5927 if (mTransactionPump) {
5928 mTransactionPump->Resume();
5929 }
5930
5931 if (StaticPrefs::network_auth_use_redirect_for_retries()) {
5932 return CallOrWaitForResume(
5933 [](auto* self) { return self->RedirectToNewChannelForAuthRetry(); });
5934 }
5935
5936 return NS_OK;
5937}
5938
5939NS_IMETHODIMPnsresult nsHttpChannel::OnAuthCancelled(bool userCancel) {
5940 LOG(("nsHttpChannel::OnAuthCancelled [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnAuthCancelled [this=%p]", this); } } while
(0)
;
5941 MOZ_ASSERT(mAuthRetryPending, "OnAuthCancelled should not be called twice")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAuthRetryPending)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAuthRetryPending))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mAuthRetryPending"
" (" "OnAuthCancelled should not be called twice" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5941); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAuthRetryPending"
") (" "OnAuthCancelled should not be called twice" ")"); do {
*((volatile int*)__null) = 5941; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
5942
5943 if (mTransactionPump) {
5944 // If the channel is trying to authenticate to a proxy and
5945 // that was canceled we cannot show the http response body
5946 // from the 40x as that might mislead the user into thinking
5947 // it was a end host response instead of a proxy reponse.
5948 // This must check explicitly whether a proxy auth was being done
5949 // because we do want to show the content if this is an error from
5950 // the origin server.
5951 if (LoadProxyAuthPending()) Cancel(NS_ERROR_PROXY_CONNECTION_REFUSED);
5952
5953 // Make sure to process security headers before calling CallOnStartRequest.
5954 nsresult rv = ProcessCrossOriginSecurityHeaders();
5955 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5956 mStatus = rv;
5957 HandleAsyncAbort();
5958 return rv;
5959 }
5960
5961 // ensure call of OnStartRequest of the current listener here,
5962 // it would not be called otherwise at all
5963 rv = CallOnStartRequest();
5964
5965 // drop mAuthRetryPending flag and resume the transaction
5966 // this resumes load of the unauthenticated content data (which
5967 // may have been canceled if we don't want to show it)
5968 mAuthRetryPending = false;
5969 LOG(("Resuming the transaction, user cancelled the auth dialog"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Resuming the transaction, user cancelled the auth dialog")
; } } while (0)
;
5970 mTransactionPump->Resume();
5971
5972 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) mTransactionPump->Cancel(rv);
5973 }
5974
5975 StoreProxyAuthPending(false);
5976 return NS_OK;
5977}
5978
5979NS_IMETHODIMPnsresult nsHttpChannel::CloseStickyConnection() {
5980 LOG(("nsHttpChannel::CloseStickyConnection this=%p", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CloseStickyConnection this=%p", this); } } while
(0)
;
5981
5982 // Require we are between OnStartRequest and OnStopRequest, because
5983 // what we do here takes effect in OnStopRequest (not reusing the
5984 // connection for next authentication round).
5985 if (!LoadIsPending()) {
5986 LOG((" channel not pending"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " channel not pending"); } } while (0)
;
5987 NS_ERROR(do { NS_DebugBreak(NS_DEBUG_ASSERTION, "CloseStickyConnection not called before OnStopRequest, won't have any "
"effect", "Error", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5989); MOZ_PretendNoReturn(); } while (0)
5988 "CloseStickyConnection not called before OnStopRequest, won't have any "do { NS_DebugBreak(NS_DEBUG_ASSERTION, "CloseStickyConnection not called before OnStopRequest, won't have any "
"effect", "Error", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5989); MOZ_PretendNoReturn(); } while (0)
5989 "effect")do { NS_DebugBreak(NS_DEBUG_ASSERTION, "CloseStickyConnection not called before OnStopRequest, won't have any "
"effect", "Error", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5989); MOZ_PretendNoReturn(); } while (0)
;
5990 return NS_ERROR_UNEXPECTED;
5991 }
5992
5993 MOZ_ASSERT(mTransaction)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mTransaction)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mTransaction))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mTransaction", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5993); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mTransaction"
")"); do { *((volatile int*)__null) = 5993; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5994 if (!mTransaction) {
5995 return NS_ERROR_UNEXPECTED;
5996 }
5997
5998 if (!(mCaps & NS_HTTP_STICKY_CONNECTION(1 << 2) ||
5999 mTransaction->HasStickyConnection())) {
6000 LOG((" not sticky"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " not sticky"); } } while (0)
;
6001 return NS_OK;
6002 }
6003
6004 mTransaction->DontReuseConnection();
6005 return NS_OK;
6006}
6007
6008NS_IMETHODIMPnsresult nsHttpChannel::ConnectionRestartable(bool aRestartable) {
6009 LOG(("nsHttpChannel::ConnectionRestartable this=%p, restartable=%d", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ConnectionRestartable this=%p, restartable=%d"
, this, aRestartable); } } while (0)
6010 aRestartable))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ConnectionRestartable this=%p, restartable=%d"
, this, aRestartable); } } while (0)
;
6011 StoreAuthConnectionRestartable(aRestartable);
6012 return NS_OK;
6013}
6014
6015//-----------------------------------------------------------------------------
6016// nsHttpChannel::nsISupports
6017//-----------------------------------------------------------------------------
6018
6019NS_IMPL_ADDREF_INHERITED(nsHttpChannel, HttpBaseChannel)MozExternalRefCountType nsHttpChannel::AddRef(void) { static_assert
(!std::is_destructible_v<nsHttpChannel>, "Reference-counted class "
"nsHttpChannel" " should not have a public destructor. " "Make this class's destructor non-public"
); nsrefcnt r = HttpBaseChannel::AddRef(); if constexpr (::mozilla
::detail::ShouldLogInheritedRefcnt<nsHttpChannel>) { NS_LogAddRef
((this), (r), ("nsHttpChannel"), (uint32_t)(sizeof(*this))); }
return r; }
6020NS_IMPL_RELEASE_INHERITED(nsHttpChannel, HttpBaseChannel)MozExternalRefCountType nsHttpChannel::Release(void) { nsrefcnt
r = HttpBaseChannel::Release(); if constexpr (::mozilla::detail
::ShouldLogInheritedRefcnt<nsHttpChannel>) { NS_LogRelease
((this), (r), ("nsHttpChannel")); } return r; }
6021
6022NS_INTERFACE_MAP_BEGIN(nsHttpChannel)nsresult nsHttpChannel::QueryInterface(const nsIID& aIID,
void** aInstancePtr) { do { if (!(aInstancePtr)) { NS_DebugBreak
(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6022); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
6023 NS_INTERFACE_MAP_ENTRY(nsIRequest)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequest>)) foundInterface = static_cast
<nsIRequest*>(this); else
6024 NS_INTERFACE_MAP_ENTRY(nsIChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIChannel>)) foundInterface = static_cast
<nsIChannel*>(this); else
6025 NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequestObserver>)) foundInterface
= static_cast<nsIRequestObserver*>(this); else
6026 NS_INTERFACE_MAP_ENTRY(nsIStreamListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIStreamListener>)) foundInterface
= static_cast<nsIStreamListener*>(this); else
6027 NS_INTERFACE_MAP_ENTRY(nsIHttpChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIHttpChannel>)) foundInterface =
static_cast<nsIHttpChannel*>(this); else
6028 NS_INTERFACE_MAP_ENTRY(nsICacheInfoChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICacheInfoChannel>)) foundInterface
= static_cast<nsICacheInfoChannel*>(this); else
6029 NS_INTERFACE_MAP_ENTRY(nsICachingChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICachingChannel>)) foundInterface
= static_cast<nsICachingChannel*>(this); else
6030 NS_INTERFACE_MAP_ENTRY(nsIClassOfService)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIClassOfService>)) foundInterface
= static_cast<nsIClassOfService*>(this); else
6031 NS_INTERFACE_MAP_ENTRY(nsIUploadChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIUploadChannel>)) foundInterface
= static_cast<nsIUploadChannel*>(this); else
6032 NS_INTERFACE_MAP_ENTRY(nsIFormPOSTActionChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIFormPOSTActionChannel>)) foundInterface
= static_cast<nsIFormPOSTActionChannel*>(this); else
6033 NS_INTERFACE_MAP_ENTRY(nsIUploadChannel2)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIUploadChannel2>)) foundInterface
= static_cast<nsIUploadChannel2*>(this); else
6034 NS_INTERFACE_MAP_ENTRY(nsICacheEntryOpenCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICacheEntryOpenCallback>)) foundInterface
= static_cast<nsICacheEntryOpenCallback*>(this); else
6035 NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIHttpChannelInternal>)) foundInterface
= static_cast<nsIHttpChannelInternal*>(this); else
6036 NS_INTERFACE_MAP_ENTRY(nsIResumableChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIResumableChannel>)) foundInterface
= static_cast<nsIResumableChannel*>(this); else
6037 NS_INTERFACE_MAP_ENTRY(nsITransportEventSink)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsITransportEventSink>)) foundInterface
= static_cast<nsITransportEventSink*>(this); else
6038 NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsPriority>)) foundInterface
= static_cast<nsISupportsPriority*>(this); else
6039 NS_INTERFACE_MAP_ENTRY(nsIProtocolProxyCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIProtocolProxyCallback>)) foundInterface
= static_cast<nsIProtocolProxyCallback*>(this); else
6040 NS_INTERFACE_MAP_ENTRY(nsIProxiedChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIProxiedChannel>)) foundInterface
= static_cast<nsIProxiedChannel*>(this); else
6041 NS_INTERFACE_MAP_ENTRY(nsIHttpAuthenticableChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIHttpAuthenticableChannel>)) foundInterface
= static_cast<nsIHttpAuthenticableChannel*>(this); else
6042 NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIAsyncVerifyRedirectCallback>))
foundInterface = static_cast<nsIAsyncVerifyRedirectCallback
*>(this); else
6043 NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableRequest)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIThreadRetargetableRequest>)) foundInterface
= static_cast<nsIThreadRetargetableRequest*>(this); else
6044 NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIThreadRetargetableStreamListener>
)) foundInterface = static_cast<nsIThreadRetargetableStreamListener
*>(this); else
6045 NS_INTERFACE_MAP_ENTRY(nsIDNSListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIDNSListener>)) foundInterface =
static_cast<nsIDNSListener*>(this); else
6046 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsWeakReference>)) foundInterface
= static_cast<nsISupportsWeakReference*>(this); else
6047 NS_INTERFACE_MAP_ENTRY(nsICorsPreflightCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICorsPreflightCallback>)) foundInterface
= static_cast<nsICorsPreflightCallback*>(this); else
6048 NS_INTERFACE_MAP_ENTRY(nsIRaceCacheWithNetwork)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRaceCacheWithNetwork>)) foundInterface
= static_cast<nsIRaceCacheWithNetwork*>(this); else
6049 NS_INTERFACE_MAP_ENTRY(nsIRequestTailUnblockCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequestTailUnblockCallback>)) foundInterface
= static_cast<nsIRequestTailUnblockCallback*>(this); else
6050 NS_INTERFACE_MAP_ENTRY_CONCRETE(nsHttpChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsHttpChannel>)) { *aInstancePtr =
do_AddRef(static_cast<nsHttpChannel*>(this)).take(); return
NS_OK; } else
6051 NS_INTERFACE_MAP_ENTRY(nsIEarlyHintObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIEarlyHintObserver>)) foundInterface
= static_cast<nsIEarlyHintObserver*>(this); else
6052NS_INTERFACE_MAP_END_INHERITING(HttpBaseChannel)foundInterface = 0; nsresult status; if (!foundInterface) status
= HttpBaseChannel::QueryInterface(aIID, (void**)&foundInterface
); else { (foundInterface)->AddRef(); status = NS_OK; } *aInstancePtr
= foundInterface; return status; }
6053
6054//-----------------------------------------------------------------------------
6055// nsHttpChannel::nsIRequest
6056//-----------------------------------------------------------------------------
6057
6058NS_IMETHODIMPnsresult nsHttpChannel::SetCanceledReason(const nsACString& aReason) {
6059 return SetCanceledReasonImpl(aReason);
6060}
6061
6062NS_IMETHODIMPnsresult nsHttpChannel::GetCanceledReason(nsACString& aReason) {
6063 return GetCanceledReasonImpl(aReason);
6064}
6065
6066NS_IMETHODIMPnsresult
6067nsHttpChannel::CancelWithReason(nsresult aStatus, const nsACString& aReason) {
6068 return CancelWithReasonImpl(aStatus, aReason);
6069}
6070
6071NS_IMETHODIMPnsresult
6072nsHttpChannel::Cancel(nsresult status) {
6073 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6073); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 6073; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6074 // We should never have a pump open while a CORS preflight is in progress.
6075 MOZ_ASSERT_IF(mPreflightChannel, !mCachePump)do { if (mPreflightChannel) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(!mCachePump)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mCachePump))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!mCachePump", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6075); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCachePump"
")"); do { *((volatile int*)__null) = 6075; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6076#ifdef DEBUG1
6077 // We want to perform this check only when the chanel is being cancelled the
6078 // first time with a URL classifier blocking error code. If mStatus is
6079 // already set to such an error code then Cancel() may be called for some
6080 // other reason, for example because we've received notification about our
6081 // parent process side channel being canceled, in which case we cannot expect
6082 // that CancelByURLClassifier() would have handled this case.
6083 if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status) &&
6084 !UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(mStatus)) {
6085 MOZ_CRASH_UNSAFE_PRINTF("Blocking classifier error %" PRIx32do { static_assert(1 > 0, "Did you forget arguments to MOZ_CRASH_UNSAFE_PRINTF? "
"Or maybe you want MOZ_CRASH instead?"); static_assert(1 <=
sPrintfMaxArgs, "Only up to 4 additional arguments are allowed!"
); static_assert(sizeof("Blocking classifier error %" "x" " need to be handled by CancelByURLClassifier()"
) <= sPrintfCrashReasonSize, "The supplied format string is too long!"
); MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6087, MOZ_CrashPrintf("" "Blocking classifier error %" "x" " need to be handled by CancelByURLClassifier()"
, static_cast<uint32_t>(status))); } while (false)
6086 " need to be handled by CancelByURLClassifier()",do { static_assert(1 > 0, "Did you forget arguments to MOZ_CRASH_UNSAFE_PRINTF? "
"Or maybe you want MOZ_CRASH instead?"); static_assert(1 <=
sPrintfMaxArgs, "Only up to 4 additional arguments are allowed!"
); static_assert(sizeof("Blocking classifier error %" "x" " need to be handled by CancelByURLClassifier()"
) <= sPrintfCrashReasonSize, "The supplied format string is too long!"
); MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6087, MOZ_CrashPrintf("" "Blocking classifier error %" "x" " need to be handled by CancelByURLClassifier()"
, static_cast<uint32_t>(status))); } while (false)
6087 static_cast<uint32_t>(status))do { static_assert(1 > 0, "Did you forget arguments to MOZ_CRASH_UNSAFE_PRINTF? "
"Or maybe you want MOZ_CRASH instead?"); static_assert(1 <=
sPrintfMaxArgs, "Only up to 4 additional arguments are allowed!"
); static_assert(sizeof("Blocking classifier error %" "x" " need to be handled by CancelByURLClassifier()"
) <= sPrintfCrashReasonSize, "The supplied format string is too long!"
); MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6087, MOZ_CrashPrintf("" "Blocking classifier error %" "x" " need to be handled by CancelByURLClassifier()"
, static_cast<uint32_t>(status))); } while (false)
;
6088 }
6089#endif
6090
6091 LOG(("nsHttpChannel::Cancel [this=%p status=%" PRIx32 ", reason=%s]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::Cancel [this=%p status=%" "x" ", reason=%s]\n"
, this, static_cast<uint32_t>(status), mCanceledReason.
get()); } } while (0)
6092 static_cast<uint32_t>(status), mCanceledReason.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::Cancel [this=%p status=%" "x" ", reason=%s]\n"
, this, static_cast<uint32_t>(status), mCanceledReason.
get()); } } while (0)
;
6093 MOZ_ASSERT_IF(!(mConnectionInfo && mConnectionInfo->UsingConnect()) &&do { if (!(mConnectionInfo && mConnectionInfo->UsingConnect
()) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus
)), 1)))) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(!AllowedErrorForHTTPSRRFallback(status))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!AllowedErrorForHTTPSRRFallback(status)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!AllowedErrorForHTTPSRRFallback(status)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6095); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!AllowedErrorForHTTPSRRFallback(status)"
")"); do { *((volatile int*)__null) = 6095; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
6094 NS_SUCCEEDED(mStatus),do { if (!(mConnectionInfo && mConnectionInfo->UsingConnect
()) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus
)), 1)))) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(!AllowedErrorForHTTPSRRFallback(status))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!AllowedErrorForHTTPSRRFallback(status)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!AllowedErrorForHTTPSRRFallback(status)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6095); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!AllowedErrorForHTTPSRRFallback(status)"
")"); do { *((volatile int*)__null) = 6095; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
6095 !AllowedErrorForHTTPSRRFallback(status))do { if (!(mConnectionInfo && mConnectionInfo->UsingConnect
()) && ((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus
)), 1)))) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(!AllowedErrorForHTTPSRRFallback(status))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!AllowedErrorForHTTPSRRFallback(status)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!AllowedErrorForHTTPSRRFallback(status)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6095); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!AllowedErrorForHTTPSRRFallback(status)"
")"); do { *((volatile int*)__null) = 6095; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6096
6097 mEarlyHintObserver = nullptr;
6098 mWebTransportSessionEventListener = nullptr;
6099
6100 if (mCanceled) {
6101 LOG((" ignoring; already canceled\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " ignoring; already canceled\n"); } } while (0)
;
6102 return NS_OK;
6103 }
6104
6105 LogCallingScriptLocation(this);
6106
6107 if (LoadWaitingForRedirectCallback()) {
6108 LOG(("channel canceled during wait for redirect callback"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "channel canceled during wait for redirect callback"); } } while
(0)
;
6109 }
6110
6111 return CancelInternal(status);
6112}
6113
6114NS_IMETHODIMPnsresult
6115nsHttpChannel::CancelByURLClassifier(nsresult aErrorCode) {
6116 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6117); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6117; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6117 UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6117); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6117; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6118 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6118); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 6118; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6119 // We should never have a pump open while a CORS preflight is in progress.
6120 MOZ_ASSERT_IF(mPreflightChannel, !mCachePump)do { if (mPreflightChannel) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(!mCachePump)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mCachePump))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!mCachePump", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6120); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCachePump"
")"); do { *((volatile int*)__null) = 6120; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6121
6122 LOG(("nsHttpChannel::CancelByURLClassifier [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CancelByURLClassifier [this=%p]\n", this); }
} while (0)
;
6123
6124 if (mCanceled) {
6125 LOG((" ignoring; already canceled\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " ignoring; already canceled\n"); } } while (0)
;
6126 return NS_OK;
6127 }
6128
6129 // We are being canceled by the channel classifier because of tracking
6130 // protection, but we haven't yet had a chance to dispatch the
6131 // "http-on-modify-request" notifications yet (this would normally be
6132 // done in PrepareToConnect()). So do that now, before proceeding to
6133 // cancel.
6134 //
6135 // Note that running these observers can itself result in the channel
6136 // being canceled. In that case, we accept that cancelation code as
6137 // the cause of the cancelation, as if the classification of the channel
6138 // would have occurred past this point!
6139
6140 // notify "http-on-modify-request" observers
6141 CallOnModifyRequestObservers();
6142
6143 // Check if request was cancelled during on-modify-request
6144 if (mCanceled) {
6145 return mStatus;
6146 }
6147
6148 if (mSuspendCount) {
6149 LOG(("Waiting until resume in Cancel [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume in Cancel [this=%p]\n", this); } } while
(0)
;
6150 MOZ_ASSERT(!mCallOnResume)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCallOnResume)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mCallOnResume))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mCallOnResume"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6150); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
")"); do { *((volatile int*)__null) = 6150; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6151 StoreChannelClassifierCancellationPending(1);
6152 mCallOnResume = [aErrorCode](nsHttpChannel* self) {
6153 self->HandleContinueCancellingByURLClassifier(aErrorCode);
6154 return NS_OK;
6155 };
6156 return NS_OK;
6157 }
6158
6159 // Check to see if we should redirect this channel elsewhere by
6160 // nsIHttpChannel.redirectTo API request
6161 if (mAPIRedirectToURI) {
6162 StoreChannelClassifierCancellationPending(1);
6163 return AsyncCall(&nsHttpChannel::HandleAsyncAPIRedirect);
6164 }
6165
6166 return CancelInternal(aErrorCode);
6167}
6168
6169void nsHttpChannel::ContinueCancellingByURLClassifier(nsresult aErrorCode) {
6170 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6171); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6171; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6171 UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode
(aErrorCode)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6171); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6171; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6172 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6172); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 6172; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6173 // We should never have a pump open while a CORS preflight is in progress.
6174 MOZ_ASSERT_IF(mPreflightChannel, !mCachePump)do { if (mPreflightChannel) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(!mCachePump)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mCachePump))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!mCachePump", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6174); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCachePump"
")"); do { *((volatile int*)__null) = 6174; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6175
6176 LOG(("nsHttpChannel::ContinueCancellingByURLClassifier [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueCancellingByURLClassifier [this=%p]\n"
, this); } } while (0)
;
6177 if (mCanceled) {
6178 LOG((" ignoring; already canceled\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " ignoring; already canceled\n"); } } while (0)
;
6179 return;
6180 }
6181
6182 // Check to see if we should redirect this channel elsewhere by
6183 // nsIHttpChannel.redirectTo API request
6184 if (mAPIRedirectToURI) {
6185 Unused << AsyncCall(&nsHttpChannel::HandleAsyncAPIRedirect);
6186 return;
6187 }
6188
6189 Unused << CancelInternal(aErrorCode);
6190}
6191
6192nsresult nsHttpChannel::CancelInternal(nsresult status) {
6193 LOG(("nsHttpChannel::CancelInternal [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CancelInternal [this=%p]\n", this); } } while
(0)
;
6194 bool channelClassifierCancellationPending =
6195 !!LoadChannelClassifierCancellationPending();
6196 if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status)) {
6197 StoreChannelClassifierCancellationPending(0);
6198 }
6199
6200 // We don't want the content process to see any header values
6201 // when the request is blocked by ORB
6202 if (mChannelBlockedByOpaqueResponse && mCachedOpaqueResponseBlockingPref) {
6203 mResponseHead->ClearHeaders();
6204 }
6205
6206 mEarlyHintObserver = nullptr;
6207 mWebTransportSessionEventListener = nullptr;
6208 mCanceled = true;
6209 mStatus = NS_FAILED(status)((bool)(__builtin_expect(!!(NS_FAILED_impl(status)), 0))) ? status : NS_ERROR_ABORT;
6210
6211 if (mLastStatusReported && !mEndMarkerAdded &&
6212 profiler_thread_is_being_profiled_for_markers()) {
6213 // These do allocations/frees/etc; avoid if not active
6214 // mLastStatusReported can be null if Cancel is called before we added the
6215 // start marker.
6216 mEndMarkerAdded = true;
6217
6218 nsAutoCString requestMethod;
6219 GetRequestMethod(requestMethod);
6220
6221 int32_t priority = PRIORITY_NORMAL;
6222 GetPriority(&priority);
6223
6224 uint64_t size = 0;
6225 GetEncodedBodySize(&size);
6226
6227 profiler_add_network_marker(
6228 mURI, requestMethod, priority, mChannelId, NetworkLoadType::LOAD_CANCEL,
6229 mLastStatusReported, TimeStamp::Now(), size, mCacheDisposition,
6230 mLoadInfo->GetInnerWindowID(),
6231 mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(),
6232 &mTransactionTimings, std::move(mSource));
6233 }
6234
6235 // If we don't have mTransactionPump and mCachePump, we need to call
6236 // AsyncAbort to make sure this channel's listener got notified.
6237 bool needAsyncAbort = !mTransactionPump && !mCachePump;
6238
6239 if (mProxyRequest) mProxyRequest->Cancel(status);
6240 CancelNetworkRequest(status);
6241 mCacheInputStream.CloseAndRelease();
6242 if (mCachePump) mCachePump->Cancel(status);
6243 if (mAuthProvider) mAuthProvider->Cancel(status);
6244 if (mPreflightChannel) mPreflightChannel->Cancel(status);
6245 if (mRequestContext && mOnTailUnblock) {
6246 mOnTailUnblock = nullptr;
6247 mRequestContext->CancelTailedRequest(this);
6248 CloseCacheEntry(false);
6249 needAsyncAbort = false;
6250 Unused << AsyncAbort(status);
6251 } else if (channelClassifierCancellationPending) {
6252 // If mCallOnResume is not null here, it's set in
6253 // nsHttpChannel::CancelByURLClassifier. We can override mCallOnResume since
6254 // mCanceled is true and nsHttpChannel::ContinueCancellingByURLClassifier
6255 // does nothing.
6256 if (mCallOnResume) {
6257 mCallOnResume = nullptr;
6258 }
6259 // If we're coming from an asynchronous path when canceling a channel due
6260 // to safe-browsing protection, we need to AsyncAbort the channel now.
6261 needAsyncAbort = false;
6262 Unused << AsyncAbort(status);
6263 }
6264
6265 // If we already have mCallOnResume, AsyncAbort will be called in
6266 // ResumeInternal.
6267 if (needAsyncAbort && !mCallOnResume && !mSuspendCount) {
6268 LOG(("nsHttpChannel::CancelInternal do AsyncAbort [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CancelInternal do AsyncAbort [this=%p]\n", this
); } } while (0)
;
6269 CloseCacheEntry(false);
6270 Unused << AsyncAbort(status);
6271 }
6272 return NS_OK;
6273}
6274
6275void nsHttpChannel::CancelNetworkRequest(nsresult aStatus) {
6276 if (mTransaction) {
6277 nsresult rv = gHttpHandler->CancelTransaction(mTransaction, aStatus);
6278 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6279 LOG(("failed to cancel the transaction\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "failed to cancel the transaction\n"); } } while (0)
;
6280 }
6281 }
6282 if (mTransactionPump) mTransactionPump->Cancel(aStatus);
6283
6284 mEarlyHintObserver = nullptr;
6285 mWebTransportSessionEventListener = nullptr;
6286}
6287
6288NS_IMETHODIMPnsresult
6289nsHttpChannel::Suspend() {
6290 NS_ENSURE_TRUE(LoadIsPending(), NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(LoadIsPending())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "LoadIsPending()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6290); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
6291
6292 LOG(("nsHttpChannel::SuspendInternal [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SuspendInternal [this=%p]\n", this); } } while
(0)
;
6293 LogCallingScriptLocation(this);
6294
6295 ++mSuspendCount;
6296
6297 if (mSuspendCount == 1) {
6298 mSuspendTimestamp = TimeStamp::NowLoRes();
6299 }
6300
6301 nsresult rvTransaction = NS_OK;
6302 if (mTransactionPump) {
6303 rvTransaction = mTransactionPump->Suspend();
6304 }
6305 nsresult rvCache = NS_OK;
6306 if (mCachePump) {
6307 rvCache = mCachePump->Suspend();
6308 }
6309
6310 return NS_FAILED(rvTransaction)((bool)(__builtin_expect(!!(NS_FAILED_impl(rvTransaction)), 0
)))
? rvTransaction : rvCache;
6311}
6312
6313NS_IMETHODIMPnsresult
6314nsHttpChannel::Resume() {
6315 NS_ENSURE_TRUE(mSuspendCount > 0, NS_ERROR_UNEXPECTED)do { if ((__builtin_expect(!!(!(mSuspendCount > 0)), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mSuspendCount > 0"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6315); return NS_ERROR_UNEXPECTED; } } while (false)
;
6316
6317 LOG(("nsHttpChannel::ResumeInternal [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResumeInternal [this=%p]\n", this); } } while
(0)
;
6318 LogCallingScriptLocation(this);
6319
6320 if (--mSuspendCount == 0) {
6321 mSuspendTotalTime += TimeStamp::NowLoRes() - mSuspendTimestamp;
6322
6323 if (mCallOnResume) {
6324 // Resume the interrupted procedure first, then resume
6325 // the pump to continue process the input stream.
6326 // Any newly created pump MUST be suspended to prevent calling
6327 // its OnStartRequest before OnStopRequest of any pre-existing
6328 // pump. AsyncResumePending ensures that.
6329 MOZ_ASSERT(!LoadAsyncResumePending())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadAsyncResumePending())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadAsyncResumePending())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadAsyncResumePending()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6329); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadAsyncResumePending()"
")"); do { *((volatile int*)__null) = 6329; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6330 StoreAsyncResumePending(1);
6331
6332 std::function<nsresult(nsHttpChannel*)> callOnResume = nullptr;
6333 std::swap(callOnResume, mCallOnResume);
6334
6335 RefPtr<nsHttpChannel> self(this);
6336 nsCOMPtr<nsIRequest> transactionPump = mTransactionPump;
6337 RefPtr<nsInputStreamPump> cachePump = mCachePump;
6338
6339 nsresult rv = NS_DispatchToCurrentThread(NS_NewRunnableFunction(
6340 "nsHttpChannel::CallOnResume",
6341 [callOnResume{std::move(callOnResume)}, self{std::move(self)},
6342 transactionPump{std::move(transactionPump)},
6343 cachePump{std::move(cachePump)}]() {
6344 MOZ_ASSERT(self->LoadAsyncResumePending())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(self->LoadAsyncResumePending())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(self->LoadAsyncResumePending
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("self->LoadAsyncResumePending()", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6344); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->LoadAsyncResumePending()"
")"); do { *((volatile int*)__null) = 6344; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6345 nsresult rv = self->CallOrWaitForResume(callOnResume);
6346 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6347 self->CloseCacheEntry(false);
6348 Unused << self->AsyncAbort(rv);
6349 }
6350 MOZ_ASSERT(self->LoadAsyncResumePending())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(self->LoadAsyncResumePending())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(self->LoadAsyncResumePending
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("self->LoadAsyncResumePending()", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6350); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->LoadAsyncResumePending()"
")"); do { *((volatile int*)__null) = 6350; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6351
6352 self->StoreAsyncResumePending(0);
6353
6354 // And now actually resume the previously existing pumps.
6355 if (transactionPump) {
6356 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume resuming previous transaction "
"pump %p, this=%p", transactionPump.get(), self.get()); } } while
(0)
6357 ("nsHttpChannel::CallOnResume resuming previous transaction "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume resuming previous transaction "
"pump %p, this=%p", transactionPump.get(), self.get()); } } while
(0)
6358 "pump %p, this=%p",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume resuming previous transaction "
"pump %p, this=%p", transactionPump.get(), self.get()); } } while
(0)
6359 transactionPump.get(), self.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume resuming previous transaction "
"pump %p, this=%p", transactionPump.get(), self.get()); } } while
(0)
;
6360 transactionPump->Resume();
6361 }
6362 if (cachePump) {
6363 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume resuming previous cache pump "
"%p, this=%p", cachePump.get(), self.get()); } } while (0)
6364 ("nsHttpChannel::CallOnResume resuming previous cache pump "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume resuming previous cache pump "
"%p, this=%p", cachePump.get(), self.get()); } } while (0)
6365 "%p, this=%p",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume resuming previous cache pump "
"%p, this=%p", cachePump.get(), self.get()); } } while (0)
6366 cachePump.get(), self.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume resuming previous cache pump "
"%p, this=%p", cachePump.get(), self.get()); } } while (0)
;
6367 cachePump->Resume();
6368 }
6369
6370 // Any newly created pumps were suspended once because of
6371 // AsyncResumePending. Problem is that the stream listener
6372 // notification is already pending in the queue right now, because
6373 // AsyncRead doesn't (regardless if called after Suspend) respect
6374 // the suspend coutner and the right order would not be preserved.
6375 // Hence, we do another dispatch round to actually Resume after
6376 // the notification from the original pump.
6377 if (transactionPump != self->mTransactionPump &&
6378 self->mTransactionPump) {
6379 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume async-resuming new " "transaction "
"pump %p, this=%p", self->mTransactionPump.get(), self.get
()); } } while (0)
6380 ("nsHttpChannel::CallOnResume async-resuming new "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume async-resuming new " "transaction "
"pump %p, this=%p", self->mTransactionPump.get(), self.get
()); } } while (0)
6381 "transaction "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume async-resuming new " "transaction "
"pump %p, this=%p", self->mTransactionPump.get(), self.get
()); } } while (0)
6382 "pump %p, this=%p",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume async-resuming new " "transaction "
"pump %p, this=%p", self->mTransactionPump.get(), self.get
()); } } while (0)
6383 self->mTransactionPump.get(), self.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume async-resuming new " "transaction "
"pump %p, this=%p", self->mTransactionPump.get(), self.get
()); } } while (0)
;
6384
6385 nsCOMPtr<nsIRequest> pump = self->mTransactionPump;
6386 NS_DispatchToCurrentThread(NS_NewRunnableFunction(
6387 "nsHttpChannel::CallOnResume new transaction",
6388 [pump{std::move(pump)}]() { pump->Resume(); }));
6389 }
6390 if (cachePump != self->mCachePump && self->mCachePump) {
6391 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume async-resuming new cache pump "
"%p, this=%p", self->mCachePump.get(), self.get()); } } while
(0)
6392 ("nsHttpChannel::CallOnResume async-resuming new cache pump "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume async-resuming new cache pump "
"%p, this=%p", self->mCachePump.get(), self.get()); } } while
(0)
6393 "%p, this=%p",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume async-resuming new cache pump "
"%p, this=%p", self->mCachePump.get(), self.get()); } } while
(0)
6394 self->mCachePump.get(), self.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::CallOnResume async-resuming new cache pump "
"%p, this=%p", self->mCachePump.get(), self.get()); } } while
(0)
;
6395
6396 RefPtr<nsInputStreamPump> pump = self->mCachePump;
6397 NS_DispatchToCurrentThread(NS_NewRunnableFunction(
6398 "nsHttpChannel::CallOnResume new pump",
6399 [pump{std::move(pump)}]() { pump->Resume(); }));
6400 }
6401 }));
6402 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6402); return rv; } } while (false)
;
6403 return rv;
6404 }
6405 }
6406
6407 nsresult rvTransaction = NS_OK;
6408 if (mTransactionPump) {
6409 rvTransaction = mTransactionPump->Resume();
6410 }
6411
6412 nsresult rvCache = NS_OK;
6413 if (mCachePump) {
6414 rvCache = mCachePump->Resume();
6415 }
6416
6417 return NS_FAILED(rvTransaction)((bool)(__builtin_expect(!!(NS_FAILED_impl(rvTransaction)), 0
)))
? rvTransaction : rvCache;
6418}
6419
6420//-----------------------------------------------------------------------------
6421// nsHttpChannel::nsIChannel
6422//-----------------------------------------------------------------------------
6423
6424NS_IMETHODIMPnsresult
6425nsHttpChannel::GetSecurityInfo(nsITransportSecurityInfo** securityInfo) {
6426 NS_ENSURE_ARG_POINTER(securityInfo)do { if ((__builtin_expect(!!(!(securityInfo)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "securityInfo" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6426); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6427 *securityInfo = do_AddRef(mSecurityInfo).take();
6428 return NS_OK;
6429}
6430
6431// If any of the functions that AsyncOpen calls returns immediately an error
6432// AsyncAbort(which calls onStart/onStopRequest) does not need to be call.
6433// To be sure that they are not call ReleaseListeners() is called.
6434// If AsyncOpen returns NS_OK, after that point AsyncAbort must be called on
6435// any error.
6436NS_IMETHODIMPnsresult
6437nsHttpChannel::AsyncOpen(nsIStreamListener* aListener) {
6438 nsCOMPtr<nsIStreamListener> listener = aListener;
6439 nsresult rv =
6440 nsContentSecurityManager::doContentSecurityCheck(this, listener);
6441 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6441)
) {
6442 ReleaseListeners();
6443 return rv;
6444 }
6445
6446 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->
GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode
() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal()))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone
() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal())))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
" (" "security flags in loadInfo but doContentSecurityCheck() not called"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
") (" "security flags in loadInfo but doContentSecurityCheck() not called"
")"); do { *((volatile int*)__null) = 6453; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6447 mLoadInfo->GetSecurityMode() == 0 ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->
GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode
() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal()))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone
() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal())))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
" (" "security flags in loadInfo but doContentSecurityCheck() not called"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
") (" "security flags in loadInfo but doContentSecurityCheck() not called"
")"); do { *((volatile int*)__null) = 6453; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6448 mLoadInfo->GetInitialSecurityCheckDone() ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->
GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode
() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal()))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone
() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal())))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
" (" "security flags in loadInfo but doContentSecurityCheck() not called"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
") (" "security flags in loadInfo but doContentSecurityCheck() not called"
")"); do { *((volatile int*)__null) = 6453; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6449 (mLoadInfo->GetSecurityMode() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->
GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode
() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal()))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone
() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal())))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
" (" "security flags in loadInfo but doContentSecurityCheck() not called"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
") (" "security flags in loadInfo but doContentSecurityCheck() not called"
")"); do { *((volatile int*)__null) = 6453; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6450 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL &&do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->
GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode
() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal()))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone
() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal())))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
" (" "security flags in loadInfo but doContentSecurityCheck() not called"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
") (" "security flags in loadInfo but doContentSecurityCheck() not called"
")"); do { *((volatile int*)__null) = 6453; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6451 mLoadInfo->GetLoadingPrincipal() &&do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->
GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode
() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal()))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone
() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal())))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
" (" "security flags in loadInfo but doContentSecurityCheck() not called"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
") (" "security flags in loadInfo but doContentSecurityCheck() not called"
")"); do { *((volatile int*)__null) = 6453; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6452 mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal()),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->
GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode
() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal()))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone
() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal())))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
" (" "security flags in loadInfo but doContentSecurityCheck() not called"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
") (" "security flags in loadInfo but doContentSecurityCheck() not called"
")"); do { *((volatile int*)__null) = 6453; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6453 "security flags in loadInfo but doContentSecurityCheck() not called")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->
GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode
() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal()))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone
() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL
&& mLoadInfo->GetLoadingPrincipal() && mLoadInfo
->GetLoadingPrincipal()->IsSystemPrincipal())))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
" (" "security flags in loadInfo but doContentSecurityCheck() not called"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetSecurityMode() == 0 || mLoadInfo->GetInitialSecurityCheckDone() || (mLoadInfo->GetSecurityMode() == nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL && mLoadInfo->GetLoadingPrincipal() && mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal())"
") (" "security flags in loadInfo but doContentSecurityCheck() not called"
")"); do { *((volatile int*)__null) = 6453; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6454
6455 LOG(("nsHttpChannel::AsyncOpen [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AsyncOpen [this=%p]\n", this); } } while (0
)
;
6456 mOpenerCallingScriptLocation = CallingScriptLocationString();
6457 LogCallingScriptLocation(this, mOpenerCallingScriptLocation);
6458 NS_CompareLoadInfoAndLoadContext(this);
6459
6460#ifdef DEBUG1
6461 AssertPrivateBrowsingId();
6462#endif
6463
6464 NS_ENSURE_ARG_POINTER(listener)do { if ((__builtin_expect(!!(!(listener)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "listener" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6464); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6465 NS_ENSURE_TRUE(!LoadIsPending(), NS_ERROR_IN_PROGRESS)do { if ((__builtin_expect(!!(!(!LoadIsPending())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!LoadIsPending()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6465); return NS_ERROR_IN_PROGRESS; } } while (false)
;
6466 NS_ENSURE_TRUE(!LoadWasOpened(), NS_ERROR_ALREADY_OPENED)do { if ((__builtin_expect(!!(!(!LoadWasOpened())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!LoadWasOpened()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6466); return NS_ERROR_ALREADY_OPENED; } } while (false)
;
6467
6468 if (mCanceled) {
6469 ReleaseListeners();
6470 return NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0))) ? mStatus : NS_ERROR_FAILURE;
6471 }
6472
6473 if (MaybeWaitForUploadStreamNormalization(listener, nullptr)) {
6474 return NS_OK;
6475 }
6476
6477 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6477); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 6477; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6478
6479 if (!gHttpHandler->Active()) {
6480 LOG((" after HTTP shutdown..."))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " after HTTP shutdown..."); } } while (0)
;
6481 ReleaseListeners();
6482 return NS_ERROR_NOT_AVAILABLE;
6483 }
6484
6485 rv = NS_CheckPortSafety(mURI);
6486 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6487 ReleaseListeners();
6488 return rv;
6489 }
6490
6491 // If no one called SetLoadGroup or SetNotificationCallbacks, the private
6492 // state has not been updated on PrivateBrowsingChannel (which we derive
6493 // from) Same if the loadinfo has changed since the creation of the channel.
6494 // Hence, we have to call UpdatePrivateBrowsing() here
6495 UpdatePrivateBrowsing();
6496
6497 AntiTrackingUtils::UpdateAntiTrackingInfoForChannel(this);
6498
6499 // Recalculate the default userAgent header after the AntiTrackingInfo gets
6500 // updated because we can only know whether the site is exempted from
6501 // fingerprinting protection after we have the AntiTracking Info.
6502 //
6503 // Note that we don't recalculate the header if it has been modified since the
6504 // channel was created because we want to preserve the modified header.
6505 if (!LoadIsUserAgentHeaderModified()) {
6506 rv = mRequestHead.SetHeader(
6507 nsHttp::User_Agent,
6508 gHttpHandler->UserAgent(nsContentUtils::ShouldResistFingerprinting(
6509 this, RFPTarget::HttpUserAgent)),
6510 false, nsHttpHeaderArray::eVarietyRequestEnforceDefault);
6511 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6511); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 6511; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6512 }
6513
6514 if (WaitingForTailUnblock()) {
6515 // This channel is marked as Tail and is part of a request context
6516 // that has positive number of non-tailed requestst, hence this channel
6517 // has been put to a queue.
6518 // When tail is unblocked, OnTailUnblock on this channel will be called
6519 // to continue AsyncOpen.
6520 mListener = listener;
6521 MOZ_DIAGNOSTIC_ASSERT(!mOnTailUnblock)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mOnTailUnblock)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mOnTailUnblock))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mOnTailUnblock"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6521); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mOnTailUnblock"
")"); do { *((volatile int*)__null) = 6521; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6522 mOnTailUnblock = &nsHttpChannel::AsyncOpenOnTailUnblock;
6523
6524 LOG((" put on hold until tail is unblocked"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " put on hold until tail is unblocked"); } } while (0)
;
6525 return NS_OK;
6526 }
6527
6528 // Remember the cookie header that was set, if any
6529 nsAutoCString cookieHeader;
6530 if (NS_SUCCEEDED(mRequestHead.GetHeader(nsHttp::Cookie, cookieHeader))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mRequestHead.GetHeader
(nsHttp::Cookie, cookieHeader))), 1)))
) {
6531 mUserSetCookieHeader = cookieHeader;
6532 }
6533
6534 // Set user agent override, do so before OnOpeningRequest notification
6535 // since we want to allow consumers of that notification change or remove
6536 // the User-Agent request header.
6537 HttpBaseChannel::SetDocshellUserAgentOverride();
6538
6539 // After we notify any observers (on-opening-request, loadGroup, etc) we
6540 // must return NS_OK and return any errors asynchronously via
6541 // OnStart/OnStopRequest. Observers may add a reference to the channel
6542 // and expect to get OnStopRequest so they know when to drop the reference,
6543 // etc.
6544
6545 // notify "http-on-opening-request" observers, but not if this is a redirect
6546 if (!(mLoadFlags & LOAD_REPLACE)) {
6547 gHttpHandler->OnOpeningRequest(this);
6548 }
6549
6550 StoreIsPending(true);
6551 StoreWasOpened(true);
6552
6553 mListener = listener;
6554
6555 if (nsIOService::UseSocketProcess() &&
6556 !gIOService->IsSocketProcessLaunchComplete()) {
6557 RefPtr<nsHttpChannel> self = this;
6558 gIOService->CallOrWaitForSocketProcess(
6559 [self]() { self->AsyncOpenFinal(TimeStamp::Now()); });
6560 return NS_OK;
6561 }
6562
6563 AsyncOpenFinal(TimeStamp::Now());
6564
6565 return NS_OK;
6566}
6567
6568void nsHttpChannel::AsyncOpenFinal(TimeStamp aTimeStamp) {
6569 // We save this timestamp from outside of the if block in case we enable the
6570 // profiler after AsyncOpen().
6571 mLastStatusReported = TimeStamp::Now();
6572 if (profiler_thread_is_being_profiled_for_markers()) {
6573 nsAutoCString requestMethod;
6574 GetRequestMethod(requestMethod);
6575
6576 profiler_add_network_marker(
6577 mURI, requestMethod, mPriority, mChannelId, NetworkLoadType::LOAD_START,
6578 mChannelCreationTimestamp, mLastStatusReported, 0, mCacheDisposition,
6579 mLoadInfo->GetInnerWindowID(),
6580 mLoadInfo->GetOriginAttributes().IsPrivateBrowsing());
6581 }
6582
6583 // Added due to PauseTask/DelayHttpChannel
6584 if (mLoadGroup) mLoadGroup->AddRequest(this, nullptr);
6585
6586 // record asyncopen time unconditionally and clear it if we
6587 // don't want it after OnModifyRequest() weighs in. But waiting for
6588 // that to complete would mean we don't include proxy resolution in the
6589 // timing.
6590 if (!LoadAsyncOpenTimeOverriden()) {
6591 mAsyncOpenTime = aTimeStamp;
6592 }
6593
6594 // Remember we have Authorization header set here. We need to check on it
6595 // just once and early, AsyncOpen is the best place.
6596 StoreCustomAuthHeader(mRequestHead.HasHeader(nsHttp::Authorization));
6597
6598 bool willCallback = false;
6599 // We are about to do an async lookup to check if the URI is a tracker. If
6600 // yes, this channel will be canceled by channel classifier. Chances are the
6601 // lookup is not needed so CheckIsTrackerWithLocalTable() will return an
6602 // error and then we can MaybeResolveProxyAndBeginConnect() right away.
6603 // We skip the check in case this is an internal redirected channel
6604 if (!LoadAuthRedirectedChannel() && NS_ShouldClassifyChannel(this)) {
6605 RefPtr<nsHttpChannel> self = this;
6606 willCallback = NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(AsyncUrlChannelClassifier
::CheckChannel(this, [self]() -> void { nsCOMPtr<nsIURI
> uri; self->GetURI(getter_AddRefs(uri)); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(uri)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(uri))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("uri", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6610; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6607 AsyncUrlChannelClassifier::CheckChannel(this, [self]() -> void {((bool)(__builtin_expect(!!(!NS_FAILED_impl(AsyncUrlChannelClassifier
::CheckChannel(this, [self]() -> void { nsCOMPtr<nsIURI
> uri; self->GetURI(getter_AddRefs(uri)); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(uri)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(uri))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("uri", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6610; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6608 nsCOMPtr<nsIURI> uri;((bool)(__builtin_expect(!!(!NS_FAILED_impl(AsyncUrlChannelClassifier
::CheckChannel(this, [self]() -> void { nsCOMPtr<nsIURI
> uri; self->GetURI(getter_AddRefs(uri)); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(uri)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(uri))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("uri", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6610; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6609 self->GetURI(getter_AddRefs(uri));((bool)(__builtin_expect(!!(!NS_FAILED_impl(AsyncUrlChannelClassifier
::CheckChannel(this, [self]() -> void { nsCOMPtr<nsIURI
> uri; self->GetURI(getter_AddRefs(uri)); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(uri)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(uri))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("uri", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6610; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6610 MOZ_ASSERT(uri);((bool)(__builtin_expect(!!(!NS_FAILED_impl(AsyncUrlChannelClassifier
::CheckChannel(this, [self]() -> void { nsCOMPtr<nsIURI
> uri; self->GetURI(getter_AddRefs(uri)); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(uri)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(uri))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("uri", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6610; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6611
6612 // Finish the AntiTracking Heuristic before((bool)(__builtin_expect(!!(!NS_FAILED_impl(AsyncUrlChannelClassifier
::CheckChannel(this, [self]() -> void { nsCOMPtr<nsIURI
> uri; self->GetURI(getter_AddRefs(uri)); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(uri)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(uri))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("uri", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6610; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6613 // MaybeResolveProxyAndBeginConnect().((bool)(__builtin_expect(!!(!NS_FAILED_impl(AsyncUrlChannelClassifier
::CheckChannel(this, [self]() -> void { nsCOMPtr<nsIURI
> uri; self->GetURI(getter_AddRefs(uri)); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(uri)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(uri))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("uri", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6610; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6614 FinishAntiTrackingRedirectHeuristic(self, uri);((bool)(__builtin_expect(!!(!NS_FAILED_impl(AsyncUrlChannelClassifier
::CheckChannel(this, [self]() -> void { nsCOMPtr<nsIURI
> uri; self->GetURI(getter_AddRefs(uri)); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(uri)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(uri))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("uri", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6610; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6615
6616 self->MaybeResolveProxyAndBeginConnect();((bool)(__builtin_expect(!!(!NS_FAILED_impl(AsyncUrlChannelClassifier
::CheckChannel(this, [self]() -> void { nsCOMPtr<nsIURI
> uri; self->GetURI(getter_AddRefs(uri)); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(uri)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(uri))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("uri", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6610; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6617 }))((bool)(__builtin_expect(!!(!NS_FAILED_impl(AsyncUrlChannelClassifier
::CheckChannel(this, [self]() -> void { nsCOMPtr<nsIURI
> uri; self->GetURI(getter_AddRefs(uri)); do { static_assert
( mozilla::detail::AssertionConditionType<decltype(uri)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(uri))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("uri", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6610; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
;
6618 }
6619
6620 if (!willCallback) {
6621 // We can do MaybeResolveProxyAndBeginConnect immediately if
6622 // CheckIsTrackerWithLocalTable is failed. Note that we don't need to
6623 // handle the failure because BeginConnect() will return synchronously and
6624 // the caller will be responsible for handling it.
6625 MaybeResolveProxyAndBeginConnect();
6626 }
6627}
6628
6629void nsHttpChannel::MaybeResolveProxyAndBeginConnect() {
6630 nsresult rv;
6631
6632 // The common case for HTTP channels is to begin proxy resolution and return
6633 // at this point. The only time we know mProxyInfo already is if we're
6634 // proxying a non-http protocol like ftp. We don't need to discover proxy
6635 // settings if we are never going to make a network connection.
6636 if (!mProxyInfo &&
6637 !(mLoadFlags & (LOAD_ONLY_FROM_CACHE | LOAD_NO_NETWORK_IO)) &&
6638 !BypassProxy() && NS_SUCCEEDED(ResolveProxy())((bool)(__builtin_expect(!!(!NS_FAILED_impl(ResolveProxy())),
1)))
) {
6639 return;
6640 }
6641
6642 if (!gHttpHandler->Active()) {
6643 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeResolveProxyAndBeginConnect [this=%p] "
"Handler no longer active.\n", this); } } while (0)
6644 ("nsHttpChannel::MaybeResolveProxyAndBeginConnect [this=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeResolveProxyAndBeginConnect [this=%p] "
"Handler no longer active.\n", this); } } while (0)
6645 "Handler no longer active.\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeResolveProxyAndBeginConnect [this=%p] "
"Handler no longer active.\n", this); } } while (0)
6646 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeResolveProxyAndBeginConnect [this=%p] "
"Handler no longer active.\n", this); } } while (0)
;
6647 rv = NS_ERROR_NOT_AVAILABLE;
6648 } else {
6649 rv = BeginConnect();
6650 }
6651 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6652 CloseCacheEntry(false);
6653 Unused << AsyncAbort(rv);
6654 }
6655}
6656
6657nsresult nsHttpChannel::AsyncOpenOnTailUnblock() {
6658 return AsyncOpen(mListener);
6659}
6660
6661already_AddRefed<nsChannelClassifier>
6662nsHttpChannel::GetOrCreateChannelClassifier() {
6663 if (!mChannelClassifier) {
6664 mChannelClassifier = new nsChannelClassifier(this);
6665 LOG(("nsHttpChannel [%p] created nsChannelClassifier [%p]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel [%p] created nsChannelClassifier [%p]\n", this
, mChannelClassifier.get()); } } while (0)
6666 mChannelClassifier.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel [%p] created nsChannelClassifier [%p]\n", this
, mChannelClassifier.get()); } } while (0)
;
6667 }
6668
6669 RefPtr<nsChannelClassifier> classifier = mChannelClassifier;
6670 return classifier.forget();
6671}
6672
6673uint16_t nsHttpChannel::GetProxyDNSStrategy() {
6674 // This function currently only supports returning DNS_PREFETCH_ORIGIN.
6675 // Support for the rest of the DNS_* flags will be added later.
6676
6677 // When network_dns_force_use_https_rr is true, return DNS_PREFETCH_ORIGIN.
6678 // This ensures that we always perform HTTPS RR query.
6679 if (!mProxyInfo || StaticPrefs::network_dns_force_use_https_rr()) {
6680 return DNS_PREFETCH_ORIGIN;
6681 }
6682
6683 uint32_t flags = 0;
6684 nsAutoCString type;
6685 mProxyInfo->GetFlags(&flags);
6686 mProxyInfo->GetType(type);
6687
6688 // If the proxy is not to perform name resolution itself.
6689 if (!(flags & nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST)) {
6690 if (type.EqualsLiteral("socks")) {
6691 return DNS_PREFETCH_ORIGIN;
6692 }
6693 }
6694
6695 return 0;
6696}
6697
6698// BeginConnect() SHOULD NOT call AsyncAbort(). AsyncAbort will be called by
6699// functions that called BeginConnect if needed. Only
6700// MaybeResolveProxyAndBeginConnect and OnProxyAvailable ever call
6701// BeginConnect.
6702nsresult nsHttpChannel::BeginConnect() {
6703 LOG(("nsHttpChannel::BeginConnect [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::BeginConnect [this=%p]\n", this); } } while
(0)
;
6704 nsresult rv;
6705
6706 // It is the caller's responsibility to not call us late in shutdown.
6707 MOZ_ASSERT(gHttpHandler->Active())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(gHttpHandler->Active())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(gHttpHandler->Active())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("gHttpHandler->Active()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6707); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gHttpHandler->Active()"
")"); do { *((volatile int*)__null) = 6707; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6708
6709 // Construct connection info object
6710 nsAutoCString host;
6711 nsAutoCString scheme;
6712 int32_t port = -1;
6713 bool isHttps = mURI->SchemeIs("https");
6714
6715 rv = mURI->GetScheme(scheme);
6716 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = mURI->GetAsciiHost(host);
6717 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = mURI->GetPort(&port);
6718 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = mURI->GetAsciiSpec(mSpec);
6719 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6720 return rv;
6721 }
6722
6723 // Just a warning here because some nsIURIs do not implement this method.
6724 Unused << NS_WARN_IF(NS_FAILED(mURI->GetUsername(mUsername)))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(mURI
->GetUsername(mUsername))), 0))), "NS_FAILED(mURI->GetUsername(mUsername))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6724)
;
6725
6726 // Reject the URL if it doesn't specify a host
6727 if (host.IsEmpty()) {
6728 rv = NS_ERROR_MALFORMED_URI;
6729 return rv;
6730 }
6731 LOG(("host=%s port=%d\n", host.get(), port))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "host=%s port=%d\n", host.get(), port); } } while (0)
;
6732 LOG(("uri=%s\n", mSpec.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "uri=%s\n", mSpec.get()); } } while (0)
;
6733
6734 nsCOMPtr<nsProxyInfo> proxyInfo;
6735 if (mProxyInfo) proxyInfo = do_QueryInterface(mProxyInfo);
6736
6737 if (mCaps & NS_HTTP_CONNECT_ONLY(1 << 16)) {
6738 if (!proxyInfo) {
6739 LOG(("return failure: no proxy for connect-only channel\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "return failure: no proxy for connect-only channel\n"); } }
while (0)
;
6740 return NS_ERROR_FAILURE;
6741 }
6742
6743 if (!proxyInfo->IsHTTP() && !proxyInfo->IsHTTPS()) {
6744 LOG(("return failure: non-http proxy for connect-only channel\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "return failure: non-http proxy for connect-only channel\n"
); } } while (0)
;
6745 return NS_ERROR_FAILURE;
6746 }
6747 }
6748
6749 mRequestHead.SetHTTPS(isHttps);
6750 mRequestHead.SetOrigin(scheme, host, port);
6751
6752 SetOriginHeader();
6753 SetDoNotTrack();
6754 SetGlobalPrivacyControl();
6755
6756 OriginAttributes originAttributes;
6757 // Regular principal in case we have a proxy.
6758 if (proxyInfo &&
6759 !StaticPrefs::privacy_partition_network_state_connection_with_proxy()) {
6760 StoragePrincipalHelper::GetOriginAttributes(
6761 this, originAttributes, StoragePrincipalHelper::eRegularPrincipal);
6762 } else {
6763 StoragePrincipalHelper::GetOriginAttributesForNetworkState(
6764 this, originAttributes);
6765 }
6766
6767 // Adjust mCaps according to our request headers:
6768 // - If "Connection: close" is set as a request header, then do not bother
6769 // trying to establish a keep-alive connection.
6770 if (mRequestHead.HasHeaderValue(nsHttp::Connection, "close")) {
6771 mCaps &= ~(NS_HTTP_ALLOW_KEEPALIVE(1 << 0));
6772 StoreAllowHttp3(false);
6773 }
6774
6775 gHttpHandler->MaybeAddAltSvcForTesting(mURI, mUsername, mPrivateBrowsing,
6776 mCallbacks, originAttributes);
6777
6778 RefPtr<nsHttpConnectionInfo> connInfo;
6779#ifdef FUZZING
6780 if (StaticPrefs::fuzzing_necko_http3()) {
6781 connInfo =
6782 new nsHttpConnectionInfo(host, port, "h3"_ns, mUsername, proxyInfo,
6783 originAttributes, host, port, true);
6784 } else {
6785#endif
6786 if (mWebTransportSessionEventListener) {
6787 connInfo =
6788 new nsHttpConnectionInfo(host, port, "h3"_ns, mUsername, proxyInfo,
6789 originAttributes, isHttps, true, true);
6790 bool dedicated = true;
6791 nsresult rv;
6792 nsCOMPtr<WebTransportConnectionSettings> wtconSettings =
6793 do_QueryInterface(mWebTransportSessionEventListener, &rv);
6794 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6794); return rv; } } while (false)
;
6795 wtconSettings->GetDedicated(&dedicated);
6796 if (dedicated) {
6797 connInfo->SetWebTransportId(
6798 gHttpHandler->ConnMgr()->GenerateNewWebTransportId());
6799 }
6800 } else {
6801 connInfo = new nsHttpConnectionInfo(host, port, ""_ns, mUsername,
6802 proxyInfo, originAttributes, isHttps);
6803 }
6804#ifdef FUZZING
6805 }
6806#endif
6807
6808 bool http2Allowed = !gHttpHandler->IsHttp2Excluded(connInfo);
6809
6810 bool http3Allowed = Http3Allowed();
6811 if (!http3Allowed) {
6812 mCaps |= NS_HTTP_DISALLOW_HTTP3(1 << 21);
6813 }
6814
6815 RefPtr<AltSvcMapping> mapping;
6816 if (!mConnectionInfo && LoadAllowAltSvc() && // per channel
6817 !mWebTransportSessionEventListener && (http2Allowed || http3Allowed) &&
6818 !(mLoadFlags & LOAD_FRESH_CONNECTION) &&
6819 AltSvcMapping::AcceptableProxy(proxyInfo) &&
6820 (scheme.EqualsLiteral("http") || scheme.EqualsLiteral("https")) &&
6821 (mapping = gHttpHandler->GetAltServiceMapping(
6822 scheme, host, port, mPrivateBrowsing, originAttributes, http2Allowed,
6823 http3Allowed))) {
6824 LOG(("nsHttpChannel %p Alt Service Mapping Found %s://%s:%d [%s]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p Alt Service Mapping Found %s://%s:%d [%s]\n"
, this, scheme.get(), mapping->AlternateHost().get(), mapping
->AlternatePort(), mapping->HashKey().get()); } } while
(0)
6825 scheme.get(), mapping->AlternateHost().get(), mapping->AlternatePort(),do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p Alt Service Mapping Found %s://%s:%d [%s]\n"
, this, scheme.get(), mapping->AlternateHost().get(), mapping
->AlternatePort(), mapping->HashKey().get()); } } while
(0)
6826 mapping->HashKey().get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p Alt Service Mapping Found %s://%s:%d [%s]\n"
, this, scheme.get(), mapping->AlternateHost().get(), mapping
->AlternatePort(), mapping->HashKey().get()); } } while
(0)
;
6827
6828 if (!(mLoadFlags & LOAD_ANONYMOUS) && !mPrivateBrowsing) {
6829 nsAutoCString altUsedLine(mapping->AlternateHost());
6830 bool defaultPort =
6831 mapping->AlternatePort() ==
6832 (isHttps ? NS_HTTPS_DEFAULT_PORT443 : NS_HTTP_DEFAULT_PORT80);
6833 if (!defaultPort) {
6834 altUsedLine.AppendLiteral(":");
6835 altUsedLine.AppendInt(mapping->AlternatePort());
6836 }
6837 // Like what we did for 'Authorization' header, we need to do the same for
6838 // 'Alt-Used' for avoiding this header being shown in the ServiceWorker
6839 // FetchEvent.
6840 Unused << mRequestHead.ClearHeader(nsHttp::Alternate_Service_Used);
6841 rv = mRequestHead.SetHeader(nsHttp::Alternate_Service_Used, altUsedLine,
6842 false,
6843 nsHttpHeaderArray::eVarietyRequestDefault);
6844 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 6844); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 6844; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6845 }
6846
6847 nsCOMPtr<nsIConsoleService> consoleService;
6848 consoleService = mozilla::components::Console::Service();
6849 if (consoleService && !host.Equals(mapping->AlternateHost())) {
6850 nsAutoString message(u"Alternate Service Mapping found: "_ns);
6851 AppendASCIItoUTF16(scheme, message);
6852 message.AppendLiteral(u"://");
6853 AppendASCIItoUTF16(host, message);
6854 message.AppendLiteral(u":");
6855 message.AppendInt(port);
6856 message.AppendLiteral(u" to ");
6857 AppendASCIItoUTF16(scheme, message);
6858 message.AppendLiteral(u"://");
6859 AppendASCIItoUTF16(mapping->AlternateHost(), message);
6860 message.AppendLiteral(u":");
6861 message.AppendInt(mapping->AlternatePort());
6862 consoleService->LogStringMessage(message.get());
6863 }
6864
6865 LOG(("nsHttpChannel %p Using connection info from altsvc mapping", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p Using connection info from altsvc mapping"
, this); } } while (0)
;
6866 mapping->GetConnectionInfo(getter_AddRefs(mConnectionInfo), proxyInfo,
6867 originAttributes);
6868 Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC, true);
6869 Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC_OE, !isHttps);
6870 } else if (mConnectionInfo) {
6871 LOG(("nsHttpChannel %p Using channel supplied connection info", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p Using channel supplied connection info", this
); } } while (0)
;
6872 Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC, false);
6873 } else {
6874 LOG(("nsHttpChannel %p Using default connection info", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p Using default connection info", this); } }
while (0)
;
6875
6876 mConnectionInfo = connInfo;
6877 Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC, false);
6878 }
6879
6880 bool trrEnabled = false;
6881 bool httpsRRAllowed =
6882 !LoadBeConservative() && !(mCaps & NS_HTTP_BE_CONSERVATIVE(1 << 11)) &&
6883 !(mLoadInfo->TriggeringPrincipal()->IsSystemPrincipal() &&
6884 mLoadInfo->GetExternalContentPolicyType() !=
6885 ExtContentPolicy::TYPE_DOCUMENT) &&
6886 !mConnectionInfo->UsingConnect() && canUseHTTPSRRonNetwork(&trrEnabled) &&
6887 StaticPrefs::network_dns_use_https_rr_as_altsvc();
6888 if (!httpsRRAllowed) {
6889 DisallowHTTPSRR(mCaps);
6890 } else if (trrEnabled) {
6891 if (nsIRequest::GetTRRMode() != nsIRequest::TRR_DISABLED_MODE) {
6892 mCaps |= NS_HTTP_FORCE_WAIT_HTTP_RR(1 << 22);
6893 }
6894 }
6895 // No need to lookup HTTPSSVC record if mHTTPSSVCRecord already contains a
6896 // value.
6897 StoreUseHTTPSSVC(StaticPrefs::network_dns_upgrade_with_https_rr() &&
6898 httpsRRAllowed && mHTTPSSVCRecord.isNothing());
6899
6900 // Need to re-ask the handler, since mConnectionInfo may not be the connInfo
6901 // we used earlier
6902 if (!mConnectionInfo->IsHttp3() &&
6903 gHttpHandler->IsHttp2Excluded(mConnectionInfo)) {
6904 StoreAllowSpdy(0);
6905 mCaps |= NS_HTTP_DISALLOW_SPDY(1 << 7);
6906 mConnectionInfo->SetNoSpdy(true);
6907 }
6908
6909 // We can be passed with the auth provider if this channel was
6910 // a result of redirect due to auth retry
6911 if (!mAuthProvider) {
6912 mAuthProvider = new nsHttpChannelAuthProvider();
6913 }
6914
6915 rv = mAuthProvider->Init(this);
6916 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6917 return rv;
6918 }
6919
6920 // check to see if authorization headers should be included
6921 // CustomAuthHeader is set in AsyncOpen if we find Authorization header
6922 rv = mAuthProvider->AddAuthorizationHeaders(LoadCustomAuthHeader());
6923 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6924 LOG(("nsHttpChannel %p AddAuthorizationHeaders failed (%08x)", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p AddAuthorizationHeaders failed (%08x)", this
, static_cast<uint32_t>(rv)); } } while (0)
6925 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p AddAuthorizationHeaders failed (%08x)", this
, static_cast<uint32_t>(rv)); } } while (0)
;
6926 }
6927
6928 // If TimingEnabled flag is not set after OnModifyRequest() then
6929 // clear the already recorded AsyncOpen value for consistency.
6930 if (!LoadTimingEnabled()) mAsyncOpenTime = TimeStamp();
6931
6932 // if this somehow fails we can go on without it
6933 Unused << gHttpHandler->AddConnectionHeader(&mRequestHead, mCaps);
6934
6935 if (!LoadIsTRRServiceChannel() &&
6936 ((mLoadFlags & LOAD_FRESH_CONNECTION) ||
6937 (!StaticPrefs::network_dns_only_refresh_on_fresh_connection() &&
6938 (mLoadFlags & VALIDATE_ALWAYS ||
6939 BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass())((mLoadFlags) & (nsIRequest::LOAD_BYPASS_CACHE | nsICachingChannel
::LOAD_BYPASS_LOCAL_CACHE) && !(((mLoadFlags) & nsIRequest
::LOAD_FROM_CACHE) && (LoadPreferCacheLoadOverBypass(
))))
)))) {
6940 mCaps |= NS_HTTP_REFRESH_DNS(1 << 3);
6941 }
6942
6943 if (gHttpHandler->CriticalRequestPrioritization()) {
6944 if (mClassOfService.Flags() & nsIClassOfService::Leader) {
6945 mCaps |= NS_HTTP_LOAD_AS_BLOCKING(1 << 6);
6946 }
6947 if (mClassOfService.Flags() & nsIClassOfService::Unblocked) {
6948 mCaps |= NS_HTTP_LOAD_UNBLOCKED(1 << 8);
6949 }
6950 if (mClassOfService.Flags() & nsIClassOfService::UrgentStart &&
6951 gHttpHandler->IsUrgentStartEnabled()) {
6952 mCaps |= NS_HTTP_URGENT_START(1 << 12);
6953 SetPriority(nsISupportsPriority::PRIORITY_HIGHEST);
6954 }
6955 }
6956
6957 // Force-Reload should reset the persistent connection pool for this host
6958 if (mLoadFlags & LOAD_FRESH_CONNECTION) {
6959 // just the initial document resets the whole pool
6960 if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
6961 gHttpHandler->AltServiceCache()->ClearAltServiceMappings();
6962 rv = gHttpHandler->DoShiftReloadConnectionCleanupWithConnInfo(
6963 mConnectionInfo);
6964 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6965 LOG((do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::BeginConnect " "DoShiftReloadConnectionCleanupWithConnInfo failed: %08x [this=%p]"
, static_cast<uint32_t>(rv), this); } } while (0)
6966 "nsHttpChannel::BeginConnect "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::BeginConnect " "DoShiftReloadConnectionCleanupWithConnInfo failed: %08x [this=%p]"
, static_cast<uint32_t>(rv), this); } } while (0)
6967 "DoShiftReloadConnectionCleanupWithConnInfo failed: %08x [this=%p]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::BeginConnect " "DoShiftReloadConnectionCleanupWithConnInfo failed: %08x [this=%p]"
, static_cast<uint32_t>(rv), this); } } while (0)
6968 static_cast<uint32_t>(rv), this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::BeginConnect " "DoShiftReloadConnectionCleanupWithConnInfo failed: %08x [this=%p]"
, static_cast<uint32_t>(rv), this); } } while (0)
;
6969 }
6970 }
6971 }
6972
6973 // We may have been cancelled already, either by on-modify-request
6974 // listeners or load group observers; in that case, we should not send the
6975 // request to the server
6976 if (mCanceled) {
6977 return mStatus;
6978 }
6979 // skip classifier checks if this channel was the result of internal auth
6980 // redirect
6981 bool shouldBeClassified =
6982 !LoadAuthRedirectedChannel() && NS_ShouldClassifyChannel(this);
6983
6984 if (shouldBeClassified) {
6985 if (LoadChannelClassifierCancellationPending()) {
6986 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting for safe-browsing protection cancellation in BeginConnect "
"[this=%p]\n", this); } } while (0)
6987 ("Waiting for safe-browsing protection cancellation in BeginConnect "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting for safe-browsing protection cancellation in BeginConnect "
"[this=%p]\n", this); } } while (0)
6988 "[this=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting for safe-browsing protection cancellation in BeginConnect "
"[this=%p]\n", this); } } while (0)
6989 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting for safe-browsing protection cancellation in BeginConnect "
"[this=%p]\n", this); } } while (0)
;
6990 return NS_OK;
6991 }
6992
6993 ReEvaluateReferrerAfterTrackingStatusIsKnown();
6994 }
6995
6996 rv = MaybeStartDNSPrefetch();
6997 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6998 auto dnsStrategy = GetProxyDNSStrategy();
6999 if (dnsStrategy & DNS_BLOCK_ON_ORIGIN_RESOLVE) {
7000 // TODO: Should this be fatal?
7001 return rv;
7002 }
7003 // Otherwise this shouldn't be fatal.
7004 return NS_OK;
7005 }
7006
7007 rv = CallOrWaitForResume(
7008 [](nsHttpChannel* self) { return self->PrepareToConnect(); });
7009 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7010 return rv;
7011 }
7012
7013 if (shouldBeClassified) {
7014 // Start nsChannelClassifier to catch phishing and malware URIs.
7015 RefPtr<nsChannelClassifier> channelClassifier =
7016 GetOrCreateChannelClassifier();
7017 LOG(("nsHttpChannel::Starting nsChannelClassifier %p [this=%p]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::Starting nsChannelClassifier %p [this=%p]",
channelClassifier.get(), this); } } while (0)
7018 channelClassifier.get(), this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::Starting nsChannelClassifier %p [this=%p]",
channelClassifier.get(), this); } } while (0)
;
7019 channelClassifier->Start();
7020 }
7021
7022 return NS_OK;
7023}
7024
7025nsresult nsHttpChannel::MaybeStartDNSPrefetch() {
7026 // Start a DNS lookup very early in case the real open is queued the DNS can
7027 // happen in parallel. Do not do so in the presence of an HTTP proxy as
7028 // all lookups other than for the proxy itself are done by the proxy.
7029 // Also we don't do a lookup if the LOAD_NO_NETWORK_IO or
7030 // LOAD_ONLY_FROM_CACHE flags are set.
7031 //
7032 // We keep the DNS prefetch object around so that we can retrieve
7033 // timing information from it. There is no guarantee that we actually
7034 // use the DNS prefetch data for the real connection, but as we keep
7035 // this data around for 3 minutes by default, this should almost always
7036 // be correct, and even when it isn't, the timing still represents _a_
7037 // valid DNS lookup timing for the site, even if it is not _the_
7038 // timing we used.
7039 if ((mLoadFlags & (LOAD_NO_NETWORK_IO | LOAD_ONLY_FROM_CACHE)) ||
7040 LoadAuthRedirectedChannel()) {
7041 return NS_OK;
7042 }
7043
7044 auto dnsStrategy = GetProxyDNSStrategy();
7045
7046 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeStartDNSPrefetch [this=%p, strategy=%u] "
"prefetching%s\n", this, dnsStrategy, mCaps & (1 <<
3) ? ", refresh requested" : ""); } } while (0)
7047 ("nsHttpChannel::MaybeStartDNSPrefetch [this=%p, strategy=%u] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeStartDNSPrefetch [this=%p, strategy=%u] "
"prefetching%s\n", this, dnsStrategy, mCaps & (1 <<
3) ? ", refresh requested" : ""); } } while (0)
7048 "prefetching%s\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeStartDNSPrefetch [this=%p, strategy=%u] "
"prefetching%s\n", this, dnsStrategy, mCaps & (1 <<
3) ? ", refresh requested" : ""); } } while (0)
7049 this, dnsStrategy,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeStartDNSPrefetch [this=%p, strategy=%u] "
"prefetching%s\n", this, dnsStrategy, mCaps & (1 <<
3) ? ", refresh requested" : ""); } } while (0)
7050 mCaps & NS_HTTP_REFRESH_DNS ? ", refresh requested" : ""))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeStartDNSPrefetch [this=%p, strategy=%u] "
"prefetching%s\n", this, dnsStrategy, mCaps & (1 <<
3) ? ", refresh requested" : ""); } } while (0)
;
7051
7052 if (dnsStrategy & DNS_PREFETCH_ORIGIN) {
7053 OriginAttributes originAttributes;
7054 StoragePrincipalHelper::GetOriginAttributesForNetworkState(
7055 this, originAttributes);
7056
7057 mDNSPrefetch =
7058 new nsDNSPrefetch(mURI, originAttributes, nsIRequest::GetTRRMode(),
7059 this, LoadTimingEnabled());
7060 nsIDNSService::DNSFlags dnsFlags = nsIDNSService::RESOLVE_DEFAULT_FLAGS;
7061 if (mCaps & NS_HTTP_REFRESH_DNS(1 << 3)) {
7062 dnsFlags |= nsIDNSService::RESOLVE_BYPASS_CACHE;
7063 }
7064 nsresult rv = mDNSPrefetch->PrefetchHigh(dnsFlags);
7065
7066 if (dnsStrategy & DNS_BLOCK_ON_ORIGIN_RESOLVE) {
7067 LOG((" blocking on prefetching origin"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " blocking on prefetching origin"); } } while (0)
;
7068
7069 if (NS_WARN_IF(NS_FAILED(rv))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(rv
)), 0))), "NS_FAILED(rv)", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7069)
) {
7070 LOG((" lookup failed with 0x%08" PRIx32 ", aborting request",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " lookup failed with 0x%08" "x" ", aborting request", static_cast
<uint32_t>(rv)); } } while (0)
7071 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " lookup failed with 0x%08" "x" ", aborting request", static_cast
<uint32_t>(rv)); } } while (0)
;
7072 return rv;
7073 }
7074
7075 // Resolved in OnLookupComplete.
7076 mDNSBlockingThenable = mDNSBlockingPromise.Ensure(__func__);
7077 }
7078
7079 if (StaticPrefs::network_dns_use_https_rr_as_altsvc() && !mHTTPSSVCRecord &&
7080 !(mCaps & NS_HTTP_DISALLOW_HTTPS_RR(1 << 24)) && canUseHTTPSRRonNetwork()) {
7081 MOZ_ASSERT(!mHTTPSSVCRecord)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mHTTPSSVCRecord)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mHTTPSSVCRecord))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mHTTPSSVCRecord"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7081); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mHTTPSSVCRecord"
")"); do { *((volatile int*)__null) = 7081; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7082
7083 OriginAttributes originAttributes;
7084 StoragePrincipalHelper::GetOriginAttributesForHTTPSRR(this,
7085 originAttributes);
7086
7087 RefPtr<nsDNSPrefetch> resolver =
7088 new nsDNSPrefetch(mURI, originAttributes, nsIRequest::GetTRRMode());
7089 Unused << resolver->FetchHTTPSSVC(mCaps & NS_HTTP_REFRESH_DNS(1 << 3), true,
7090 [](nsIDNSHTTPSSVCRecord*) {
7091 // Do nothing. This is a DNS prefetch.
7092 });
7093 }
7094 }
7095
7096 return NS_OK;
7097}
7098
7099NS_IMETHODIMPnsresult
7100nsHttpChannel::GetEncodedBodySize(uint64_t* aEncodedBodySize) {
7101 if (mCacheEntry && !LoadCacheEntryIsWriteOnly()) {
7102 int64_t dataSize = 0;
7103 mCacheEntry->GetDataSize(&dataSize);
7104 *aEncodedBodySize = dataSize;
7105 } else {
7106 *aEncodedBodySize = mLogicalOffset;
7107 }
7108 return NS_OK;
7109}
7110
7111//-----------------------------------------------------------------------------
7112// nsHttpChannel::nsIHttpChannelInternal
7113//-----------------------------------------------------------------------------
7114
7115NS_IMETHODIMPnsresult
7116nsHttpChannel::GetIsAuthChannel(bool* aIsAuthChannel) {
7117 *aIsAuthChannel = mIsAuthChannel;
7118 return NS_OK;
7119}
7120
7121NS_IMETHODIMPnsresult
7122nsHttpChannel::SetChannelIsForDownload(bool aChannelIsForDownload) {
7123 if (aChannelIsForDownload) {
7124 AddClassFlags(nsIClassOfService::Throttleable);
7125 } else {
7126 ClearClassFlags(nsIClassOfService::Throttleable);
7127 }
7128
7129 return HttpBaseChannel::SetChannelIsForDownload(aChannelIsForDownload);
7130}
7131
7132base::ProcessId nsHttpChannel::ProcessId() {
7133 nsCOMPtr<nsIParentChannel> parentChannel;
7134 NS_QueryNotificationCallbacks(this, parentChannel);
7135 if (RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel)) {
7136 return httpParent->OtherPid();
7137 }
7138 if (RefPtr<DocumentLoadListener> docParent = do_QueryObject(parentChannel)) {
7139 return docParent->OtherPid();
7140 }
7141 return base::GetCurrentProcId();
7142}
7143
7144auto nsHttpChannel::AttachStreamFilter() -> RefPtr<ChildEndpointPromise> {
7145 LOG(("nsHttpChannel::AttachStreamFilter [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::AttachStreamFilter [this=%p]", this); } } while
(0)
;
7146 MOZ_ASSERT(!LoadOnStartRequestCalled())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadOnStartRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadOnStartRequestCalled())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadOnStartRequestCalled()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7146); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
")"); do { *((volatile int*)__null) = 7146; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7147
7148 if (!ProcessId()) {
7149 return ChildEndpointPromise::CreateAndReject(false, __func__);
7150 }
7151
7152 nsCOMPtr<nsIParentChannel> parentChannel;
7153 NS_QueryNotificationCallbacks(this, parentChannel);
7154
7155 // If our listener is a DocumentLoadListener, then we might handle
7156 // multi-part responses here in the parent process. The current extension
7157 // API doesn't understand the parsed multipart format, so we defer responding
7158 // here until CallOnStartRequest, and attach the StreamFilter before the
7159 // multipart handler (in the parent process!) if applicable.
7160 if (RefPtr<DocumentLoadListener> docParent = do_QueryObject(parentChannel)) {
7161 StreamFilterRequest* request = mStreamFilterRequests.AppendElement();
7162 request->mPromise = new ChildEndpointPromise::Private(__func__);
7163 return request->mPromise;
7164 }
7165
7166 mozilla::ipc::Endpoint<extensions::PStreamFilterParent> parent;
7167 mozilla::ipc::Endpoint<extensions::PStreamFilterChild> child;
7168 nsresult rv = extensions::PStreamFilter::CreateEndpoints(&parent, &child);
7169 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7170 return ChildEndpointPromise::CreateAndReject(false, __func__);
7171 }
7172
7173 if (RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel)) {
7174 return httpParent->AttachStreamFilter(std::move(parent), std::move(child));
7175 }
7176
7177 extensions::StreamFilterParent::Attach(this, std::move(parent));
7178 return ChildEndpointPromise::CreateAndResolve(std::move(child), __func__);
7179}
7180
7181NS_IMETHODIMPnsresult
7182nsHttpChannel::GetNavigationStartTimeStamp(TimeStamp* aTimeStamp) {
7183 LOG(("nsHttpChannel::GetNavigationStartTimeStamp [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::GetNavigationStartTimeStamp [this=%p]", this
); } } while (0)
;
7184 MOZ_ASSERT(aTimeStamp)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aTimeStamp)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aTimeStamp))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aTimeStamp", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7184); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTimeStamp"
")"); do { *((volatile int*)__null) = 7184; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7185 *aTimeStamp = mNavigationStartTimeStamp;
7186 return NS_OK;
7187}
7188
7189NS_IMETHODIMPnsresult
7190nsHttpChannel::SetNavigationStartTimeStamp(TimeStamp aTimeStamp) {
7191 LOG(("nsHttpChannel::SetNavigationStartTimeStamp [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetNavigationStartTimeStamp [this=%p]", this
); } } while (0)
;
7192 mNavigationStartTimeStamp = aTimeStamp;
7193 return NS_OK;
7194}
7195
7196//-----------------------------------------------------------------------------
7197// nsHttpChannel::nsISupportsPriority
7198//-----------------------------------------------------------------------------
7199
7200NS_IMETHODIMPnsresult
7201nsHttpChannel::SetPriority(int32_t value) {
7202 int16_t newValue = clamped<int32_t>(value, INT16_MIN(-32767-1), INT16_MAX(32767));
7203 if (mPriority == newValue) return NS_OK;
7204
7205 LOG(("nsHttpChannel::SetPriority %p p=%d", this, newValue))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetPriority %p p=%d", this, newValue); } } while
(0)
;
7206
7207 mPriority = newValue;
7208 if (mTransaction) {
7209 nsresult rv = gHttpHandler->RescheduleTransaction(mTransaction, mPriority);
7210 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7211 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetPriority [this=%p] " "RescheduleTransaction failed (%08x)"
, this, static_cast<uint32_t>(rv)); } } while (0)
7212 ("nsHttpChannel::SetPriority [this=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetPriority [this=%p] " "RescheduleTransaction failed (%08x)"
, this, static_cast<uint32_t>(rv)); } } while (0)
7213 "RescheduleTransaction failed (%08x)",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetPriority [this=%p] " "RescheduleTransaction failed (%08x)"
, this, static_cast<uint32_t>(rv)); } } while (0)
7214 this, static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetPriority [this=%p] " "RescheduleTransaction failed (%08x)"
, this, static_cast<uint32_t>(rv)); } } while (0)
;
7215 }
7216 }
7217
7218 // If this channel is the real channel for an e10s channel, notify the
7219 // child side about the priority change as well.
7220 nsCOMPtr<nsIParentChannel> parentChannel;
7221 NS_QueryNotificationCallbacks(this, parentChannel);
7222 RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel);
7223 if (httpParent) {
7224 httpParent->DoSendSetPriority(newValue);
7225 }
7226
7227 return NS_OK;
7228}
7229
7230//-----------------------------------------------------------------------------
7231// HttpChannel::nsIClassOfService
7232//-----------------------------------------------------------------------------
7233
7234void nsHttpChannel::OnClassOfServiceUpdated() {
7235 LOG(("nsHttpChannel::OnClassOfServiceUpdated this=%p, cos=%lu, inc=%d", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnClassOfServiceUpdated this=%p, cos=%lu, inc=%d"
, this, mClassOfService.Flags(), mClassOfService.Incremental(
)); } } while (0)
7236 mClassOfService.Flags(), mClassOfService.Incremental()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnClassOfServiceUpdated this=%p, cos=%lu, inc=%d"
, this, mClassOfService.Flags(), mClassOfService.Incremental(
)); } } while (0)
;
7237
7238 if (mTransaction) {
7239 gHttpHandler->UpdateClassOfServiceOnTransaction(mTransaction,
7240 mClassOfService);
7241 }
7242 if (EligibleForTailing()) {
7243 RemoveAsNonTailRequest();
7244 } else {
7245 AddAsNonTailRequest();
7246 }
7247}
7248
7249NS_IMETHODIMPnsresult
7250nsHttpChannel::SetClassFlags(uint32_t inFlags) {
7251 uint32_t previous = mClassOfService.Flags();
7252 mClassOfService.SetFlags(inFlags);
7253 if (previous != mClassOfService.Flags()) {
7254 OnClassOfServiceUpdated();
7255 }
7256 return NS_OK;
7257}
7258
7259NS_IMETHODIMPnsresult
7260nsHttpChannel::AddClassFlags(uint32_t inFlags) {
7261 uint32_t previous = mClassOfService.Flags();
7262 mClassOfService.SetFlags(inFlags | mClassOfService.Flags());
7263 if (previous != mClassOfService.Flags()) {
7264 OnClassOfServiceUpdated();
7265 }
7266 return NS_OK;
7267}
7268
7269NS_IMETHODIMPnsresult
7270nsHttpChannel::ClearClassFlags(uint32_t inFlags) {
7271 uint32_t previous = mClassOfService.Flags();
7272 mClassOfService.SetFlags(~inFlags & mClassOfService.Flags());
7273 if (previous != mClassOfService.Flags()) {
7274 OnClassOfServiceUpdated();
7275 }
7276 return NS_OK;
7277}
7278
7279NS_IMETHODIMPnsresult
7280nsHttpChannel::SetClassOfService(ClassOfService cos) {
7281 ClassOfService previous = mClassOfService;
7282 mClassOfService = cos;
7283 if (previous != mClassOfService) {
7284 OnClassOfServiceUpdated();
7285 }
7286 return NS_OK;
7287}
7288
7289NS_IMETHODIMPnsresult
7290nsHttpChannel::SetIncremental(bool incremental) {
7291 bool previous = mClassOfService.Incremental();
7292 mClassOfService.SetIncremental(incremental);
7293 if (previous != mClassOfService.Incremental()) {
7294 OnClassOfServiceUpdated();
7295 }
7296 return NS_OK;
7297}
7298
7299//-----------------------------------------------------------------------------
7300// nsHttpChannel::nsIProtocolProxyCallback
7301//-----------------------------------------------------------------------------
7302
7303NS_IMETHODIMPnsresult
7304nsHttpChannel::OnProxyAvailable(nsICancelable* request, nsIChannel* channel,
7305 nsIProxyInfo* pi, nsresult status) {
7306 LOG(("nsHttpChannel::OnProxyAvailable [this=%p pi=%p status=%" PRIx32do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnProxyAvailable [this=%p pi=%p status=%" "x"
" mStatus=%" "x" "]\n", this, pi, static_cast<uint32_t>
(status), static_cast<uint32_t>(static_cast<nsresult
>(mStatus))); } } while (0)
7307 " mStatus=%" PRIx32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnProxyAvailable [this=%p pi=%p status=%" "x"
" mStatus=%" "x" "]\n", this, pi, static_cast<uint32_t>
(status), static_cast<uint32_t>(static_cast<nsresult
>(mStatus))); } } while (0)
7308 this, pi, static_cast<uint32_t>(status),do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnProxyAvailable [this=%p pi=%p status=%" "x"
" mStatus=%" "x" "]\n", this, pi, static_cast<uint32_t>
(status), static_cast<uint32_t>(static_cast<nsresult
>(mStatus))); } } while (0)
7309 static_cast<uint32_t>(static_cast<nsresult>(mStatus))))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnProxyAvailable [this=%p pi=%p status=%" "x"
" mStatus=%" "x" "]\n", this, pi, static_cast<uint32_t>
(status), static_cast<uint32_t>(static_cast<nsresult
>(mStatus))); } } while (0)
;
7310 mProxyRequest = nullptr;
7311
7312 nsresult rv;
7313
7314 // If status is a failure code, then it means that we failed to resolve
7315 // proxy info. That is a non-fatal error assuming it wasn't because the
7316 // request was canceled. We just failover to DIRECT when proxy resolution
7317 // fails (failure can mean that the PAC URL could not be loaded).
7318
7319 if (NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1)))) {
7320 mProxyInfo = pi;
7321
7322 if (mProxyInfo) {
7323 nsAutoCStringN<8> type;
7324 mProxyInfo->GetType(type);
7325 uint32_t flags = 0;
7326 mProxyInfo->GetFlags(&flags);
7327
7328 if (type.EqualsLiteral("socks")) {
7329 if (flags & nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST) {
7330 glean::networking::proxy_info_type
7331 .EnumGet(glean::networking::ProxyInfoTypeLabel::eSocks5h)
7332 .Add(1);
7333 } else {
7334 glean::networking::proxy_info_type
7335 .EnumGet(glean::networking::ProxyInfoTypeLabel::eSocks5)
7336 .Add(1);
7337 }
7338 } else if (type.EqualsLiteral("socks4")) {
7339 if (flags & nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST) {
7340 glean::networking::proxy_info_type
7341 .EnumGet(glean::networking::ProxyInfoTypeLabel::eSocks4a)
7342 .Add(1);
7343 } else {
7344 glean::networking::proxy_info_type
7345 .EnumGet(glean::networking::ProxyInfoTypeLabel::eSocks4)
7346 .Add(1);
7347 }
7348 } else if (type.EqualsLiteral("http")) {
7349 glean::networking::proxy_info_type
7350 .EnumGet(glean::networking::ProxyInfoTypeLabel::eHttp)
7351 .Add(1);
7352 } else if (type.EqualsLiteral("https")) {
7353 glean::networking::proxy_info_type
7354 .EnumGet(glean::networking::ProxyInfoTypeLabel::eHttps)
7355 .Add(1);
7356 } else if (type.EqualsLiteral("direct")) {
7357 glean::networking::proxy_info_type
7358 .EnumGet(glean::networking::ProxyInfoTypeLabel::eDirect)
7359 .Add(1);
7360 } else {
7361 glean::networking::proxy_info_type
7362 .EnumGet(glean::networking::ProxyInfoTypeLabel::eUnknown)
7363 .Add(1);
7364 }
7365 }
7366 }
7367
7368 if (!gHttpHandler->Active()) {
7369 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnProxyAvailable [this=%p] " "Handler no longer active.\n"
, this); } } while (0)
7370 ("nsHttpChannel::OnProxyAvailable [this=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnProxyAvailable [this=%p] " "Handler no longer active.\n"
, this); } } while (0)
7371 "Handler no longer active.\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnProxyAvailable [this=%p] " "Handler no longer active.\n"
, this); } } while (0)
7372 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnProxyAvailable [this=%p] " "Handler no longer active.\n"
, this); } } while (0)
;
7373 rv = NS_ERROR_NOT_AVAILABLE;
7374 } else {
7375 rv = BeginConnect();
7376 }
7377
7378 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7379 CloseCacheEntry(false);
7380 Unused << AsyncAbort(rv);
7381 }
7382 return rv;
7383}
7384
7385//-----------------------------------------------------------------------------
7386// nsHttpChannel::nsIProxiedChannel
7387//-----------------------------------------------------------------------------
7388
7389NS_IMETHODIMPnsresult
7390nsHttpChannel::GetProxyInfo(nsIProxyInfo** result) {
7391 if (!mConnectionInfo) {
7392 *result = do_AddRef(mProxyInfo).take();
7393 } else {
7394 *result = do_AddRef(mConnectionInfo->ProxyInfo()).take();
7395 }
7396 return NS_OK;
7397}
7398
7399//-----------------------------------------------------------------------------
7400// nsHttpChannel::nsITimedChannel
7401//-----------------------------------------------------------------------------
7402
7403NS_IMETHODIMPnsresult
7404nsHttpChannel::GetDomainLookupStart(TimeStamp* _retval) {
7405 if (mTransaction) {
7406 *_retval = mTransaction->GetDomainLookupStart();
7407 } else {
7408 *_retval = mTransactionTimings.domainLookupStart;
7409 }
7410 return NS_OK;
7411}
7412
7413NS_IMETHODIMPnsresult
7414nsHttpChannel::GetDomainLookupEnd(TimeStamp* _retval) {
7415 if (mTransaction) {
7416 *_retval = mTransaction->GetDomainLookupEnd();
7417 } else {
7418 *_retval = mTransactionTimings.domainLookupEnd;
7419 }
7420 return NS_OK;
7421}
7422
7423NS_IMETHODIMPnsresult
7424nsHttpChannel::GetConnectStart(TimeStamp* _retval) {
7425 if (mTransaction) {
7426 *_retval = mTransaction->GetConnectStart();
7427 } else {
7428 *_retval = mTransactionTimings.connectStart;
7429 }
7430 return NS_OK;
7431}
7432
7433NS_IMETHODIMPnsresult
7434nsHttpChannel::GetTcpConnectEnd(TimeStamp* _retval) {
7435 if (mTransaction) {
7436 *_retval = mTransaction->GetTcpConnectEnd();
7437 } else {
7438 *_retval = mTransactionTimings.tcpConnectEnd;
7439 }
7440 return NS_OK;
7441}
7442
7443NS_IMETHODIMPnsresult
7444nsHttpChannel::GetSecureConnectionStart(TimeStamp* _retval) {
7445 if (mTransaction) {
7446 *_retval = mTransaction->GetSecureConnectionStart();
7447 } else {
7448 *_retval = mTransactionTimings.secureConnectionStart;
7449 }
7450 return NS_OK;
7451}
7452
7453NS_IMETHODIMPnsresult
7454nsHttpChannel::GetConnectEnd(TimeStamp* _retval) {
7455 if (mTransaction) {
7456 *_retval = mTransaction->GetConnectEnd();
7457 } else {
7458 *_retval = mTransactionTimings.connectEnd;
7459 }
7460 return NS_OK;
7461}
7462
7463NS_IMETHODIMPnsresult
7464nsHttpChannel::GetRequestStart(TimeStamp* _retval) {
7465 if (mTransaction) {
7466 *_retval = mTransaction->GetRequestStart();
7467 } else {
7468 *_retval = mTransactionTimings.requestStart;
7469 }
7470 return NS_OK;
7471}
7472
7473NS_IMETHODIMPnsresult
7474nsHttpChannel::GetResponseStart(TimeStamp* _retval) {
7475 if (mTransaction) {
7476 *_retval = mTransaction->GetResponseStart();
7477 } else {
7478 *_retval = mTransactionTimings.responseStart;
7479 }
7480 return NS_OK;
7481}
7482
7483NS_IMETHODIMPnsresult
7484nsHttpChannel::GetResponseEnd(TimeStamp* _retval) {
7485 if (mTransaction) {
7486 *_retval = mTransaction->GetResponseEnd();
7487 } else {
7488 *_retval = mTransactionTimings.responseEnd;
7489 }
7490 return NS_OK;
7491}
7492
7493NS_IMETHODIMPnsresult
7494nsHttpChannel::GetTransactionPending(TimeStamp* _retval) {
7495 if (mTransaction) {
7496 *_retval = mTransaction->GetPendingTime();
7497 } else {
7498 *_retval = mTransactionTimings.transactionPending;
7499 }
7500 return NS_OK;
7501}
7502
7503//-----------------------------------------------------------------------------
7504// nsHttpChannel::nsIHttpAuthenticableChannel
7505//-----------------------------------------------------------------------------
7506
7507NS_IMETHODIMPnsresult
7508nsHttpChannel::GetIsSSL(bool* aIsSSL) {
7509 // this attribute is really misnamed - it wants to know if
7510 // https:// is being used. SSL might be used to cover http://
7511 // in some circumstances (proxies, http/2, etc..)
7512 return mURI->SchemeIs("https", aIsSSL);
7513}
7514
7515NS_IMETHODIMPnsresult
7516nsHttpChannel::GetProxyMethodIsConnect(bool* aProxyMethodIsConnect) {
7517 *aProxyMethodIsConnect = mConnectionInfo->UsingConnect();
7518 return NS_OK;
7519}
7520
7521NS_IMETHODIMPnsresult
7522nsHttpChannel::GetServerResponseHeader(nsACString& value) {
7523 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
7524 return mResponseHead->GetHeader(nsHttp::Server, value);
7525}
7526
7527NS_IMETHODIMPnsresult
7528nsHttpChannel::GetProxyChallenges(nsACString& value) {
7529 if (!mResponseHead) return NS_ERROR_UNEXPECTED;
7530 return mResponseHead->GetHeader(nsHttp::Proxy_Authenticate, value);
7531}
7532
7533NS_IMETHODIMPnsresult
7534nsHttpChannel::GetWWWChallenges(nsACString& value) {
7535 if (!mResponseHead) return NS_ERROR_UNEXPECTED;
7536 return mResponseHead->GetHeader(nsHttp::WWW_Authenticate, value);
7537}
7538
7539NS_IMETHODIMPnsresult
7540nsHttpChannel::SetProxyCredentials(const nsACString& value) {
7541 return mRequestHead.SetHeader(nsHttp::Proxy_Authorization, value);
7542}
7543
7544NS_IMETHODIMPnsresult
7545nsHttpChannel::SetWWWCredentials(const nsACString& value) {
7546 // This method is called when various browser initiated authorization
7547 // code sets the credentials. We need to flag this header as the
7548 // "browser default" so it does not show up in the ServiceWorker
7549 // FetchEvent. This may actually get called more than once, though,
7550 // so we clear the header first since "default" headers are not
7551 // allowed to overwrite normally.
7552 Unused << mRequestHead.ClearHeader(nsHttp::Authorization);
7553 return mRequestHead.SetHeader(nsHttp::Authorization, value, false,
7554 nsHttpHeaderArray::eVarietyRequestDefault);
7555}
7556
7557//-----------------------------------------------------------------------------
7558// Methods that nsIHttpAuthenticableChannel dupes from other IDLs, which we
7559// get from HttpBaseChannel, must be explicitly forwarded, because C++ sucks.
7560//-----------------------------------------------------------------------------
7561
7562NS_IMETHODIMPnsresult
7563nsHttpChannel::GetLoadFlags(nsLoadFlags* aLoadFlags) {
7564 return HttpBaseChannel::GetLoadFlags(aLoadFlags);
7565}
7566
7567NS_IMETHODIMPnsresult
7568nsHttpChannel::GetURI(nsIURI** aURI) { return HttpBaseChannel::GetURI(aURI); }
7569
7570NS_IMETHODIMPnsresult
7571nsHttpChannel::GetNotificationCallbacks(nsIInterfaceRequestor** aCallbacks) {
7572 return HttpBaseChannel::GetNotificationCallbacks(aCallbacks);
7573}
7574
7575NS_IMETHODIMPnsresult
7576nsHttpChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) {
7577 return HttpBaseChannel::GetLoadGroup(aLoadGroup);
7578}
7579
7580NS_IMETHODIMPnsresult
7581nsHttpChannel::GetRequestMethod(nsACString& aMethod) {
7582 return HttpBaseChannel::GetRequestMethod(aMethod);
7583}
7584
7585//-----------------------------------------------------------------------------
7586// nsHttpChannel::nsIRequestObserver
7587//-----------------------------------------------------------------------------
7588
7589void nsHttpChannel::RecordOnStartTelemetry(nsresult aStatus,
7590 bool aIsNavigation) {
7591 Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_ONSTART_SUCCESS,
7592 NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1))));
7593
7594 mozilla::glean::networking::http_channel_onstart_status
7595 .Get(NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1))) ? "successful"_ns : "fail"_ns)
7596 .Add(1);
7597
7598 if (mTransaction) {
7599 Telemetry::Accumulate(
7600 Telemetry::HTTP3_CHANNEL_ONSTART_SUCCESS,
7601 (mTransaction->IsHttp3Used()) ? "http3"_ns : "no_http3"_ns,
7602 NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1))));
7603 }
7604
7605 enum class HttpOnStartState : uint32_t {
7606 Success = 0,
7607 DNSError = 1,
7608 Others = 2,
7609 };
7610
7611 if (TRRService::Get() && TRRService::Get()->IsConfirmed()) {
7612 // Note this telemetry probe is not working when DNS resolution is done in
7613 // the socket process.
7614 HttpOnStartState state = HttpOnStartState::Others;
7615 if (NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1)))) {
7616 state = HttpOnStartState::Success;
7617 } else if (aStatus == NS_ERROR_UNKNOWN_HOST ||
7618 aStatus == NS_ERROR_UNKNOWN_PROXY_HOST) {
7619 state = HttpOnStartState::DNSError;
7620 }
7621
7622 if (aIsNavigation) {
7623 Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_PAGE_ONSTART_SUCCESS_TRR3,
7624 TRRService::ProviderKey(),
7625 static_cast<uint32_t>(state));
7626 } else {
7627 Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_SUB_ONSTART_SUCCESS_TRR3,
7628 TRRService::ProviderKey(),
7629 static_cast<uint32_t>(state));
7630 }
7631 }
7632
7633 if (nsIOService::UseSocketProcess() && mTransaction) {
7634 const TimeStamp now = TimeStamp::Now();
7635 TimeStamp responseEnd = mTransaction->GetResponseEnd();
7636 if (!responseEnd.IsNull()) {
7637 PerfStats::RecordMeasurement(PerfStats::Metric::ResponseEndSocketToParent,
7638 now - responseEnd);
7639 }
7640
7641 mOnStartRequestStartTime = mTransaction->GetOnStartRequestStartTime();
7642 if (!mOnStartRequestStartTime.IsNull()) {
7643 PerfStats::RecordMeasurement(
7644 PerfStats::Metric::OnStartRequestSocketToParent,
7645 now - mOnStartRequestStartTime);
7646 }
7647 } else {
7648 mOnStartRequestStartTime = TimeStamp::Now();
7649 }
7650}
7651
7652NS_IMETHODIMPnsresult
7653nsHttpChannel::OnStartRequest(nsIRequest* request) {
7654 nsresult rv;
7655
7656 MOZ_ASSERT(LoadRequestObserversCalled())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadRequestObserversCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadRequestObserversCalled()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"LoadRequestObserversCalled()", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7656); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadRequestObserversCalled()"
")"); do { *((volatile int*)__null) = 7656; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7657
7658 AUTO_PROFILER_LABEL("nsHttpChannel::OnStartRequest", NETWORK)mozilla::AutoProfilerLabel raiiObject7658( "nsHttpChannel::OnStartRequest"
, nullptr, JS::ProfilingCategoryPair::NETWORK)
;
7659
7660 if (!(mCanceled || NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0)))) &&
7661 !WRONG_RACING_RESPONSE_SOURCE(request)(mRaceCacheWithNetwork && (((mFirstResponseSource == RESPONSE_FROM_CACHE
) && ((request) != mCachePump)) || ((mFirstResponseSource
== RESPONSE_FROM_NETWORK) && ((request) != mTransactionPump
))))
) {
7662 // capture the request's status, so our consumers will know ASAP of any
7663 // connection failures, etc - bug 93581
7664 nsresult status;
7665 request->GetStatus(&status);
7666 mStatus = status;
7667 }
7668
7669 if (mStatus == NS_ERROR_NON_LOCAL_CONNECTION_REFUSED) {
7670 MOZ_CRASH_UNSAFE(nsPrintfCString("Attempting to connect to non-local "MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7677, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7671 "address! opener is [%s], uri is "MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7677, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7672 "[%s]",MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7677, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7673 mOpenerCallingScriptLocationMOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7677, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7674 ? mOpenerCallingScriptLocation->get()MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7677, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7675 : "unknown",MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7677, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7676 mURI->GetSpecOrDefault().get())MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7677, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7677 .get())MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7677, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
;
7678 }
7679
7680 LOG(("nsHttpChannel::OnStartRequest [this=%p request=%p status=%" PRIx32do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnStartRequest [this=%p request=%p status=%"
"x" "]\n", this, request, static_cast<uint32_t>(static_cast
<nsresult>(mStatus))); } } while (0)
7681 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnStartRequest [this=%p request=%p status=%"
"x" "]\n", this, request, static_cast<uint32_t>(static_cast
<nsresult>(mStatus))); } } while (0)
7682 this, request, static_cast<uint32_t>(static_cast<nsresult>(mStatus))))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnStartRequest [this=%p request=%p status=%"
"x" "]\n", this, request, static_cast<uint32_t>(static_cast
<nsresult>(mStatus))); } } while (0)
;
7683
7684 RecordOnStartTelemetry(mStatus, IsNavigation());
7685
7686 if (mRaceCacheWithNetwork) {
7687 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " racingNetAndCache - mFirstResponseSource:%d fromCache:%d "
"fromNet:%d\n", static_cast<int32_t>(mFirstResponseSource
), request == mCachePump, request == mTransactionPump); } } while
(0)
7688 (" racingNetAndCache - mFirstResponseSource:%d fromCache:%d "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " racingNetAndCache - mFirstResponseSource:%d fromCache:%d "
"fromNet:%d\n", static_cast<int32_t>(mFirstResponseSource
), request == mCachePump, request == mTransactionPump); } } while
(0)
7689 "fromNet:%d\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " racingNetAndCache - mFirstResponseSource:%d fromCache:%d "
"fromNet:%d\n", static_cast<int32_t>(mFirstResponseSource
), request == mCachePump, request == mTransactionPump); } } while
(0)
7690 static_cast<int32_t>(mFirstResponseSource), request == mCachePump,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " racingNetAndCache - mFirstResponseSource:%d fromCache:%d "
"fromNet:%d\n", static_cast<int32_t>(mFirstResponseSource
), request == mCachePump, request == mTransactionPump); } } while
(0)
7691 request == mTransactionPump))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " racingNetAndCache - mFirstResponseSource:%d fromCache:%d "
"fromNet:%d\n", static_cast<int32_t>(mFirstResponseSource
), request == mCachePump, request == mTransactionPump); } } while
(0)
;
7692 if (mFirstResponseSource == RESPONSE_PENDING) {
7693 // When the cache wins mFirstResponseSource is set to
7694 // RESPONSE_FROM_CACHE earlier in ReadFromCache, so this must be a
7695 // response from the network.
7696 MOZ_ASSERT(request == mTransactionPump)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(request == mTransactionPump)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(request == mTransactionPump)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("request == mTransactionPump"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7696); AnnotateMozCrashReason("MOZ_ASSERT" "(" "request == mTransactionPump"
")"); do { *((volatile int*)__null) = 7696; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7697 LOG((" First response from network\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " First response from network\n"); } } while (0)
;
7698 {
7699 // Race condition with OnCacheEntryCheck, which is not limited
7700 // to main thread.
7701 mozilla::MutexAutoLock lock(mRCWNLock);
7702 mFirstResponseSource = RESPONSE_FROM_NETWORK;
7703 mOnStartRequestTimestamp = TimeStamp::Now();
7704
7705 // Conditional or byte range header could be added in
7706 // OnCacheEntryCheck. We need to remove them because the
7707 // request might be sent again due to auth retry and we must
7708 // not send these headers without having the entry.
7709 if (mDidReval) {
7710 LOG((" Removing conditional request headers"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Removing conditional request headers"); } } while (0)
;
7711 UntieValidationRequest();
7712 mDidReval = false;
7713 }
7714 if (LoadCachedContentIsPartial()) {
7715 LOG((" Removing byte range request headers"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Removing byte range request headers"); } } while (0)
;
7716 UntieByteRangeRequest();
7717 StoreCachedContentIsPartial(false);
7718 }
7719 }
7720 mAvailableCachedAltDataType.Truncate();
7721 StoreDeliveringAltData(false);
7722 } else if (WRONG_RACING_RESPONSE_SOURCE(request)(mRaceCacheWithNetwork && (((mFirstResponseSource == RESPONSE_FROM_CACHE
) && ((request) != mCachePump)) || ((mFirstResponseSource
== RESPONSE_FROM_NETWORK) && ((request) != mTransactionPump
))))
) {
7723 LOG((" Early return when racing. This response not needed."))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Early return when racing. This response not needed."); }
} while (0)
;
7724 return NS_OK;
7725 }
7726 }
7727
7728 // Make sure things are what we expect them to be...
7729 MOZ_ASSERT(request == mCachePump || request == mTransactionPump,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(request == mCachePump || request == mTransactionPump
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(request == mCachePump || request == mTransactionPump
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"request == mCachePump || request == mTransactionPump" " (" "Unexpected request"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7730); AnnotateMozCrashReason("MOZ_ASSERT" "(" "request == mCachePump || request == mTransactionPump"
") (" "Unexpected request" ")"); do { *((volatile int*)__null
) = 7730; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
7730 "Unexpected request")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(request == mCachePump || request == mTransactionPump
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(request == mCachePump || request == mTransactionPump
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"request == mCachePump || request == mTransactionPump" " (" "Unexpected request"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7730); AnnotateMozCrashReason("MOZ_ASSERT" "(" "request == mCachePump || request == mTransactionPump"
") (" "Unexpected request" ")"); do { *((volatile int*)__null
) = 7730; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
7731
7732 MOZ_ASSERT(mRaceCacheWithNetwork || !(mTransactionPump && mCachePump) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRaceCacheWithNetwork || !(mTransactionPump &&
mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mRaceCacheWithNetwork || !(mTransactionPump &&
mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mRaceCacheWithNetwork || !(mTransactionPump && mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced()"
" (" "If we have both pumps, we're racing cache with network, the cache"
" content is partial, or the cache entry was revalidated and "
"OnStopRequest was not called yet for the transaction pump."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7736); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRaceCacheWithNetwork || !(mTransactionPump && mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced()"
") (" "If we have both pumps, we're racing cache with network, the cache"
" content is partial, or the cache entry was revalidated and "
"OnStopRequest was not called yet for the transaction pump."
")"); do { *((volatile int*)__null) = 7736; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
7733 LoadCachedContentIsPartial() || LoadTransactionReplaced(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRaceCacheWithNetwork || !(mTransactionPump &&
mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mRaceCacheWithNetwork || !(mTransactionPump &&
mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mRaceCacheWithNetwork || !(mTransactionPump && mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced()"
" (" "If we have both pumps, we're racing cache with network, the cache"
" content is partial, or the cache entry was revalidated and "
"OnStopRequest was not called yet for the transaction pump."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7736); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRaceCacheWithNetwork || !(mTransactionPump && mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced()"
") (" "If we have both pumps, we're racing cache with network, the cache"
" content is partial, or the cache entry was revalidated and "
"OnStopRequest was not called yet for the transaction pump."
")"); do { *((volatile int*)__null) = 7736; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
7734 "If we have both pumps, we're racing cache with network, the cache"do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRaceCacheWithNetwork || !(mTransactionPump &&
mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mRaceCacheWithNetwork || !(mTransactionPump &&
mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mRaceCacheWithNetwork || !(mTransactionPump && mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced()"
" (" "If we have both pumps, we're racing cache with network, the cache"
" content is partial, or the cache entry was revalidated and "
"OnStopRequest was not called yet for the transaction pump."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7736); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRaceCacheWithNetwork || !(mTransactionPump && mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced()"
") (" "If we have both pumps, we're racing cache with network, the cache"
" content is partial, or the cache entry was revalidated and "
"OnStopRequest was not called yet for the transaction pump."
")"); do { *((volatile int*)__null) = 7736; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
7735 " content is partial, or the cache entry was revalidated and "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRaceCacheWithNetwork || !(mTransactionPump &&
mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mRaceCacheWithNetwork || !(mTransactionPump &&
mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mRaceCacheWithNetwork || !(mTransactionPump && mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced()"
" (" "If we have both pumps, we're racing cache with network, the cache"
" content is partial, or the cache entry was revalidated and "
"OnStopRequest was not called yet for the transaction pump."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7736); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRaceCacheWithNetwork || !(mTransactionPump && mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced()"
") (" "If we have both pumps, we're racing cache with network, the cache"
" content is partial, or the cache entry was revalidated and "
"OnStopRequest was not called yet for the transaction pump."
")"); do { *((volatile int*)__null) = 7736; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
7736 "OnStopRequest was not called yet for the transaction pump.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRaceCacheWithNetwork || !(mTransactionPump &&
mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mRaceCacheWithNetwork || !(mTransactionPump &&
mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mRaceCacheWithNetwork || !(mTransactionPump && mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced()"
" (" "If we have both pumps, we're racing cache with network, the cache"
" content is partial, or the cache entry was revalidated and "
"OnStopRequest was not called yet for the transaction pump."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7736); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRaceCacheWithNetwork || !(mTransactionPump && mCachePump) || LoadCachedContentIsPartial() || LoadTransactionReplaced()"
") (" "If we have both pumps, we're racing cache with network, the cache"
" content is partial, or the cache entry was revalidated and "
"OnStopRequest was not called yet for the transaction pump."
")"); do { *((volatile int*)__null) = 7736; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7737
7738 StoreAfterOnStartRequestBegun(true);
7739 if (mOnStartRequestTimestamp.IsNull()) {
7740 mOnStartRequestTimestamp = TimeStamp::Now();
7741 }
7742
7743 mozilla::glean::networking::http_onstart_suspend_total_time
7744 .AccumulateRawDuration(mSuspendTotalTime);
7745
7746 if (mTransaction) {
7747 mProxyConnectResponseCode = mTransaction->GetProxyConnectResponseCode();
7748 if (request == mTransactionPump) {
7749 StoreDataSentToChildProcess(mTransaction->DataSentToChildProcess());
7750 }
7751
7752 if (!mSecurityInfo && !mCachePump) {
7753 // grab the security info from the connection object; the transaction
7754 // is guaranteed to own a reference to the connection.
7755 mSecurityInfo = mTransaction->SecurityInfo();
7756 }
7757
7758 uint32_t stage = mTransaction->HTTPSSVCReceivedStage();
7759 if (!LoadHTTPSSVCTelemetryReported() && stage != HTTPSSVC_NOT_USED) {
7760 Telemetry::Accumulate(Telemetry::DNS_HTTPSSVC_RECORD_RECEIVING_STAGE,
7761 stage);
7762 }
7763
7764 if (HTTPS_RR_IS_USED(stage)(stage > HTTPSSVC_NOT_PRESENT && stage < HTTPSSVC_WITH_IPHINT_RECEIVED_STAGE_2
)
) {
7765 nsAutoCString suffix(LoadEchConfigUsed() ? "_ech_used" : "");
7766 // Determine the result string based on the status.
7767 nsAutoCString result(NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1))) ? "success" : "failure");
7768 result.Append(suffix);
7769
7770 mozilla::glean::networking::http_channel_onstart_success_https_rr
7771 .Get(result)
7772 .Add(1);
7773 StoreHasHTTPSRR(true);
7774 }
7775
7776 StoreLoadedBySocketProcess(mTransaction->AsHttpTransactionParent() !=
7777 nullptr);
7778
7779 bool isTrr;
7780 bool echConfigUsed;
7781 mTransaction->GetNetworkAddresses(mSelfAddr, mPeerAddr, isTrr,
7782 mEffectiveTRRMode, mTRRSkipReason,
7783 echConfigUsed);
7784 StoreResolvedByTRR(isTrr);
7785 StoreEchConfigUsed(echConfigUsed);
7786 }
7787
7788 // don't enter this block if we're reading from the cache...
7789 if (NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1))) && !mCachePump && mTransaction) {
7790 // mTransactionPump doesn't hit OnInputStreamReady and call this until
7791 // all of the response headers have been acquired, so we can take
7792 // ownership of them from the transaction.
7793 mResponseHead = mTransaction->TakeResponseHead();
7794 mSupportsHTTP3 = mTransaction->GetSupportsHTTP3();
7795 // the response head may be null if the transaction was cancelled. in
7796 // which case we just need to call OnStartRequest/OnStopRequest.
7797 if (mResponseHead) return ProcessResponse();
7798
7799 NS_WARNING("No response head in OnStartRequest")NS_DebugBreak(NS_DEBUG_WARNING, "No response head in OnStartRequest"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7799)
;
7800 }
7801
7802 // cache file could be deleted on our behalf, it could contain errors or
7803 // it failed to allocate memory, reload from network here.
7804 if (mCacheEntry && mCachePump && RECOVER_FROM_CACHE_FILE_ERROR(mStatus)((mStatus) == NS_ERROR_FILE_NOT_FOUND || (mStatus) == NS_ERROR_FILE_CORRUPTED
|| (mStatus) == NS_ERROR_OUT_OF_MEMORY)
) {
7805 LOG((" cache file error, reloading from server"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " cache file error, reloading from server"); } } while (0)
;
7806 mCacheEntry->AsyncDoom(nullptr);
7807 rv =
7808 StartRedirectChannelToURI(mURI, nsIChannelEventSink::REDIRECT_INTERNAL);
7809 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) return NS_OK;
7810 }
7811
7812 // avoid crashing if mListener happens to be null...
7813 if (!mListener) {
7814 MOZ_ASSERT_UNREACHABLE("mListener is null")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"mListener is null" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7814); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "mListener is null" ")"); do { *(
(volatile int*)__null) = 7814; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
7815 return NS_OK;
7816 }
7817
7818 rv = ProcessCrossOriginSecurityHeaders();
7819 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7820 mStatus = rv;
7821 HandleAsyncAbort();
7822 return rv;
7823 }
7824
7825 // No process change is needed, so continue on to ContinueOnStartRequest1.
7826 return ContinueOnStartRequest1(rv);
7827}
7828
7829nsresult nsHttpChannel::ContinueOnStartRequest1(nsresult result) {
7830 nsresult rv;
7831
7832 // if process selection failed, cancel this load.
7833 if (NS_FAILED(result)((bool)(__builtin_expect(!!(NS_FAILED_impl(result)), 0))) && !mCanceled) {
7834 Cancel(result);
7835 return CallOnStartRequest();
7836 }
7837
7838 // before we start any content load, check for redirectTo being called
7839 // this code is executed mainly before we start load from the cache
7840 if (mAPIRedirectToURI && !mCanceled) {
7841 nsAutoCString redirectToSpec;
7842 mAPIRedirectToURI->GetAsciiSpec(redirectToSpec);
7843 LOG((" redirectTo called with uri=%s", redirectToSpec.BeginReading()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " redirectTo called with uri=%s", redirectToSpec.BeginReading
()); } } while (0)
;
7844
7845 MOZ_ASSERT(!LoadOnStartRequestCalled())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadOnStartRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadOnStartRequestCalled())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadOnStartRequestCalled()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7845); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
")"); do { *((volatile int*)__null) = 7845; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7846
7847 nsCOMPtr<nsIURI> redirectTo;
7848 mAPIRedirectToURI.swap(redirectTo);
7849
7850 PushRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest2);
7851 rv = StartRedirectChannelToURI(redirectTo,
7852 nsIChannelEventSink::REDIRECT_TEMPORARY);
7853 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
7854 return NS_OK;
7855 }
7856 PopRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest2);
7857 }
7858
7859 // Hack: ContinueOnStartRequest2 uses NS_OK to detect successful redirects,
7860 // so we distinguish this codepath (a non-redirect that's processing
7861 // normally) by passing in a bogus error code.
7862 return ContinueOnStartRequest2(NS_BINDING_FAILED);
7863}
7864
7865nsresult nsHttpChannel::ContinueOnStartRequest2(nsresult result) {
7866 if (NS_SUCCEEDED(result)((bool)(__builtin_expect(!!(!NS_FAILED_impl(result)), 1)))) {
7867 // Redirect has passed through, we don't want to go on with this
7868 // channel. It will now be canceled by the redirect handling code
7869 // that called this function.
7870 return NS_OK;
7871 }
7872
7873 // on proxy errors, try to failover
7874 if (mConnectionInfo->ProxyInfo() &&
7875 (mStatus == NS_ERROR_PROXY_CONNECTION_REFUSED ||
7876 mStatus == NS_ERROR_UNKNOWN_PROXY_HOST ||
7877 mStatus == NS_ERROR_NET_TIMEOUT || mStatus == NS_ERROR_NET_RESET)) {
7878 PushRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest3);
7879 if (NS_SUCCEEDED(ProxyFailover())((bool)(__builtin_expect(!!(!NS_FAILED_impl(ProxyFailover()))
, 1)))
) {
7880 mProxyConnectResponseCode = 0;
7881 return NS_OK;
7882 }
7883 PopRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest3);
7884 }
7885
7886 // Hack: ContinueOnStartRequest3 uses NS_OK to detect successful redirects,
7887 // so we distinguish this codepath (a non-redirect that's processing
7888 // normally) by passing in a bogus error code.
7889 return ContinueOnStartRequest3(NS_BINDING_FAILED);
7890}
7891
7892nsresult nsHttpChannel::ContinueOnStartRequest3(nsresult result) {
7893 if (NS_SUCCEEDED(result)((bool)(__builtin_expect(!!(!NS_FAILED_impl(result)), 1)))) {
7894 // Redirect has passed through, we don't want to go on with this
7895 // channel. It will now be canceled by the redirect handling code
7896 // that called this function.
7897 return NS_OK;
7898 }
7899
7900 return ContinueOnStartRequest4(NS_OK);
7901}
7902
7903nsresult nsHttpChannel::ContinueOnStartRequest4(nsresult result) {
7904 LOG(("nsHttpChannel::ContinueOnStartRequest4 [this=%p]", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnStartRequest4 [this=%p]", this); }
} while (0)
;
7905
7906 if (NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1))) && mResponseHead && mAuthProvider) {
7907 uint32_t httpStatus = mResponseHead->Status();
7908 if (httpStatus != 401 && httpStatus != 407) {
7909 nsresult rv = mAuthProvider->CheckForSuperfluousAuth();
7910 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7911 mStatus = rv;
7912 LOG((" CheckForSuperfluousAuth failed (%08x)",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " CheckForSuperfluousAuth failed (%08x)", static_cast<uint32_t
>(rv)); } } while (0)
7913 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " CheckForSuperfluousAuth failed (%08x)", static_cast<uint32_t
>(rv)); } } while (0)
;
7914 }
7915 }
7916 }
7917
7918 return CallOnStartRequest();
7919}
7920
7921static void ReportHTTPSRRTelemetry(
7922 const Maybe<nsCOMPtr<nsIDNSHTTPSSVCRecord>>& aMaybeRecord) {
7923 bool hasHTTPSRR = aMaybeRecord && (aMaybeRecord.ref() != nullptr);
7924 if (!hasHTTPSRR) {
7925 mozilla::glean::networking::https_rr_presented.Get("none"_ns).Add(1);
7926 return;
7927 }
7928
7929 const nsCOMPtr<nsIDNSHTTPSSVCRecord>& record = aMaybeRecord.ref();
7930 nsCOMPtr<nsISVCBRecord> svcbRecord;
7931 if (NS_SUCCEEDED(record->GetServiceModeRecord(false, false,((bool)(__builtin_expect(!!(!NS_FAILED_impl(record->GetServiceModeRecord
(false, false, getter_AddRefs(svcbRecord)))), 1)))
7932 getter_AddRefs(svcbRecord)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(record->GetServiceModeRecord
(false, false, getter_AddRefs(svcbRecord)))), 1)))
) {
7933 MOZ_ASSERT(svcbRecord)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(svcbRecord)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(svcbRecord))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("svcbRecord", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7933); AnnotateMozCrashReason("MOZ_ASSERT" "(" "svcbRecord"
")"); do { *((volatile int*)__null) = 7933; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7934
7935 Maybe<std::tuple<nsCString, SupportedAlpnRank>> alpn =
7936 svcbRecord->GetAlpn();
7937 bool isHttp3 = alpn ? IsHttp3(std::get<1>(*alpn)) : false;
7938 mozilla::glean::networking::https_rr_presented
7939 .Get(isHttp3 ? "presented_with_http3"_ns : "presented"_ns)
7940 .Add(1);
7941 }
7942}
7943
7944static void RecordHttpChanDispositionGlean(ChannelDisposition chanDisposition) {
7945 switch (chanDisposition) {
7946 case kHttpCanceled:
7947 mozilla::glean::networking::http_channel_disposition
7948 .Get("http_cancelled"_ns)
7949 .Add(1);
7950 break;
7951 case kHttpDisk:
7952 mozilla::glean::networking::http_channel_disposition.Get("http_disk"_ns)
7953 .Add(1);
7954 break;
7955 case kHttpNetOK:
7956 mozilla::glean::networking::http_channel_disposition.Get("http_net_ok"_ns)
7957 .Add(1);
7958 break;
7959 case kHttpNetEarlyFail:
7960 mozilla::glean::networking::http_channel_disposition
7961 .Get("http_net_early_fail"_ns)
7962 .Add(1);
7963 break;
7964 case kHttpNetLateFail:
7965 mozilla::glean::networking::http_channel_disposition
7966 .Get("http_net_late_fail"_ns)
7967 .Add(1);
7968 break;
7969 case kHttpsCanceled:
7970 mozilla::glean::networking::http_channel_disposition
7971 .Get("https_cancelled"_ns)
7972 .Add(1);
7973 break;
7974 case kHttpsDisk:
7975 mozilla::glean::networking::http_channel_disposition.Get("http_disk"_ns)
7976 .Add(1);
7977 break;
7978 case kHttpsNetOK:
7979 mozilla::glean::networking::http_channel_disposition
7980 .Get("https_net_ok"_ns)
7981 .Add(1);
7982 break;
7983 case kHttpsNetEarlyFail:
7984 mozilla::glean::networking::http_channel_disposition
7985 .Get("https_net_early_fail"_ns)
7986 .Add(1);
7987 break;
7988 case kHttpsNetLateFail:
7989 mozilla::glean::networking::http_channel_disposition
7990 .Get("https_net_late_fail"_ns)
7991 .Add(1);
7992 break;
7993 default:
7994 MOZ_ASSERT_UNREACHABLE("Unknown value for chanDisposition")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Unknown value for chanDisposition" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7994); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unknown value for chanDisposition"
")"); do { *((volatile int*)__null) = 7994; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7995 }
7996}
7997
7998static nsLiteralCString HttpChanDispositionToTelemetryLabel(
7999 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE upgradeChanDisposition) {
8000 if (upgradeChanDisposition ==
8001 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::cancel) {
8002 return "cancel"_ns;
8003 }
8004 if (upgradeChanDisposition ==
8005 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::disk) {
8006 return "disk"_ns;
8007 }
8008 if (upgradeChanDisposition ==
8009 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::netOk) {
8010 return "net_ok"_ns;
8011 }
8012 if (upgradeChanDisposition ==
8013 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::netEarlyFail) {
8014 return "net_early_fail"_ns;
8015 }
8016 if (upgradeChanDisposition ==
8017 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::netLateFail) {
8018 return "net_late_fail"_ns;
8019 }
8020
8021 MOZ_ASSERT_UNREACHABLE("Unknown value for upgradeChanDecomposition")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Unknown value for upgradeChanDecomposition" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8021); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unknown value for upgradeChanDecomposition"
")"); do { *((volatile int*)__null) = 8021; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8022 return "other"_ns;
8023}
8024
8025nsresult nsHttpChannel::LogConsoleError(const char* aTag) {
8026 nsCOMPtr<nsIConsoleService> console(mozilla::components::Console::Service());
8027 NS_ENSURE_TRUE(console, NS_ERROR_OUT_OF_MEMORY)do { if ((__builtin_expect(!!(!(console)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "console" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8027); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
8028
8029 nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
8030 NS_ENSURE_TRUE(console, NS_ERROR_OUT_OF_MEMORY)do { if ((__builtin_expect(!!(!(console)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "console" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8030); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
8031 uint64_t innerWindowID = loadInfo->GetInnerWindowID();
8032
8033 nsAutoString errorText;
8034 nsresult rv = nsContentUtils::GetLocalizedString(
8035 nsContentUtils::eNECKO_PROPERTIES, aTag, errorText);
8036 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8036); return rv; } } while (false)
;
8037
8038 nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID"@mozilla.org/scripterror;1"));
8039 NS_ENSURE_TRUE(error, NS_ERROR_OUT_OF_MEMORY)do { if ((__builtin_expect(!!(!(error)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "error" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8039); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
8040
8041 rv = error->InitWithSourceURI(errorText, mURI, u""_ns, 0, 0,
8042 nsIScriptError::errorFlag,
8043 "Invalid HTTP Status Lines"_ns, innerWindowID);
8044 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8044); return rv; } } while (false)
;
8045 console->LogMessage(error);
8046 return NS_OK;
8047}
8048
8049static void RecordHTTPSUpgradeTelemetry(nsIURI* aURI, nsILoadInfo* aLoadInfo) {
8050 // we record https telemetry only for top-level loads
8051 if (aLoadInfo->GetExternalContentPolicyType() !=
8052 ExtContentPolicy::TYPE_DOCUMENT) {
8053 return;
8054 }
8055
8056 // exempt loopback addresses because we only want to record telemetry
8057 // for actual web requests
8058 if (nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackURL(aURI)) {
8059 return;
8060 }
8061
8062 nsILoadInfo::HTTPSUpgradeTelemetryType httpsTelemetry =
8063 nsILoadInfo::NOT_INITIALIZED;
8064 aLoadInfo->GetHttpsUpgradeTelemetry(&httpsTelemetry);
8065 switch (httpsTelemetry) {
8066 case nsILoadInfo::NOT_INITIALIZED:
8067 mozilla::glean::networking::http_to_https_upgrade_reason
8068 .Get("not_initialized"_ns)
8069 .Add(1);
8070 break;
8071 case nsILoadInfo::NO_UPGRADE:
8072 mozilla::glean::networking::http_to_https_upgrade_reason
8073 .Get("no_upgrade"_ns)
8074 .Add(1);
8075 break;
8076 case nsILoadInfo::ALREADY_HTTPS:
8077 mozilla::glean::networking::http_to_https_upgrade_reason
8078 .Get("already_https"_ns)
8079 .Add(1);
8080 break;
8081 case nsILoadInfo::HSTS:
8082 mozilla::glean::networking::http_to_https_upgrade_reason.Get("hsts"_ns)
8083 .Add(1);
8084 break;
8085 case nsILoadInfo::HTTPS_ONLY_UPGRADE:
8086 mozilla::glean::networking::http_to_https_upgrade_reason
8087 .Get("https_only_upgrade"_ns)
8088 .Add(1);
8089 break;
8090 case nsILoadInfo::HTTPS_ONLY_UPGRADE_DOWNGRADE:
8091 mozilla::glean::networking::http_to_https_upgrade_reason
8092 .Get("https_only_upgrade_downgrade"_ns)
8093 .Add(1);
8094 break;
8095 case nsILoadInfo::HTTPS_FIRST_UPGRADE:
8096 mozilla::glean::networking::http_to_https_upgrade_reason
8097 .Get("https_first_upgrade"_ns)
8098 .Add(1);
8099 break;
8100 case nsILoadInfo::HTTPS_FIRST_UPGRADE_DOWNGRADE:
8101 mozilla::glean::networking::http_to_https_upgrade_reason
8102 .Get("https_first_upgrade_downgrade"_ns)
8103 .Add(1);
8104 break;
8105 case nsILoadInfo::HTTPS_FIRST_SCHEMELESS_UPGRADE:
8106 mozilla::glean::networking::http_to_https_upgrade_reason
8107 .Get("https_first_schemeless_upgrade"_ns)
8108 .Add(1);
8109 break;
8110 case nsILoadInfo::HTTPS_FIRST_SCHEMELESS_UPGRADE_DOWNGRADE:
8111 mozilla::glean::networking::http_to_https_upgrade_reason
8112 .Get("https_first_schemeless_upgrade_downgrade"_ns)
8113 .Add(1);
8114 break;
8115 case nsILoadInfo::HTTPS_RR:
8116 mozilla::glean::networking::http_to_https_upgrade_reason
8117 .Get("https_rr"_ns)
8118 .Add(1);
8119 break;
8120 case nsILoadInfo::WEB_EXTENSION_UPGRADE:
8121 mozilla::glean::networking::http_to_https_upgrade_reason
8122 .Get("web_extension_upgrade"_ns)
8123 .Add(1);
8124 break;
8125 case nsILoadInfo::UPGRADE_EXCEPTION:
8126 mozilla::glean::networking::http_to_https_upgrade_reason
8127 .Get("upgrade_exception"_ns)
8128 .Add(1);
8129 break;
8130 default:
8131 MOZ_ASSERT(false, "what telemetry flag is set to end up here?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "what telemetry flag is set to end up here?"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8131); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"what telemetry flag is set to end up here?" ")"); do { *((volatile
int*)__null) = 8131; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
8132 }
8133}
8134
8135NS_IMETHODIMPnsresult
8136nsHttpChannel::OnStopRequest(nsIRequest* request, nsresult status) {
8137 AUTO_PROFILER_LABEL("nsHttpChannel::OnStopRequest", NETWORK)mozilla::AutoProfilerLabel raiiObject8137( "nsHttpChannel::OnStopRequest"
, nullptr, JS::ProfilingCategoryPair::NETWORK)
;
8138
8139 LOG(("nsHttpChannel::OnStopRequest [this=%p request=%p status=%" PRIx32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnStopRequest [this=%p request=%p status=%"
"x" "]\n", this, request, static_cast<uint32_t>(status
)); } } while (0)
8140 this, request, static_cast<uint32_t>(status)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnStopRequest [this=%p request=%p status=%"
"x" "]\n", this, request, static_cast<uint32_t>(status
)); } } while (0)
;
8141
8142 LOG(("OnStopRequest %p requestFromCache: %d mFirstResponseSource: %d\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "OnStopRequest %p requestFromCache: %d mFirstResponseSource: %d\n"
, this, request == mCachePump, static_cast<int32_t>(mFirstResponseSource
)); } } while (0)
8143 request == mCachePump, static_cast<int32_t>(mFirstResponseSource)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "OnStopRequest %p requestFromCache: %d mFirstResponseSource: %d\n"
, this, request == mCachePump, static_cast<int32_t>(mFirstResponseSource
)); } } while (0)
;
8144
8145 MOZ_ASSERT(NS_IsMainThread(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "OnStopRequest should only be called from the main thread"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8146); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "OnStopRequest should only be called from the main thread"
")"); do { *((volatile int*)__null) = 8146; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
8146 "OnStopRequest should only be called from the main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "OnStopRequest should only be called from the main thread"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8146); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "OnStopRequest should only be called from the main thread"
")"); do { *((volatile int*)__null) = 8146; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8147
8148 if (mStatus == NS_ERROR_PARSING_HTTP_STATUS_LINE) {
8149 Unused << LogConsoleError("InvalidHTTPResponseStatusLine");
8150 }
8151
8152 if (WRONG_RACING_RESPONSE_SOURCE(request)(mRaceCacheWithNetwork && (((mFirstResponseSource == RESPONSE_FROM_CACHE
) && ((request) != mCachePump)) || ((mFirstResponseSource
== RESPONSE_FROM_NETWORK) && ((request) != mTransactionPump
))))
) {
8153 return NS_OK;
8154 }
8155
8156 // It's possible that LoadUseHTTPSSVC() is false, but we already have
8157 // mHTTPSSVCRecord.
8158 if (LoadUseHTTPSSVC() || mHTTPSSVCRecord) {
8159 ReportHTTPSRRTelemetry(mHTTPSSVCRecord);
8160 }
8161
8162 // If this load failed because of a security error, it may be because we
8163 // are in a captive portal - trigger an async check to make sure.
8164 int32_t nsprError = -1 * NS_ERROR_GET_CODE(status);
8165 if (mozilla::psm::IsNSSErrorCode(nsprError) && IsHTTPS()) {
8166 gIOService->RecheckCaptivePortal();
8167 }
8168
8169 if (LoadTimingEnabled() && request == mCachePump) {
8170 mCacheReadEnd = TimeStamp::Now();
8171
8172 ReportNetVSCacheTelemetry();
8173 }
8174
8175 // allow content to be cached if it was loaded successfully (bug #482935)
8176 bool contentComplete = NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1)));
8177
8178 // honor the cancelation status even if the underlying transaction
8179 // completed.
8180 if (mCanceled || NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0)))) status = mStatus;
8181
8182 if (LoadCachedContentIsPartial()) {
8183 if (NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1)))) {
8184 // mTransactionPump should be suspended
8185 MOZ_ASSERT(request != mTransactionPump,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(request != mTransactionPump)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(request != mTransactionPump)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("request != mTransactionPump"
" (" "byte-range transaction finished prematurely" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8186); AnnotateMozCrashReason("MOZ_ASSERT" "(" "request != mTransactionPump"
") (" "byte-range transaction finished prematurely" ")"); do
{ *((volatile int*)__null) = 8186; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
8186 "byte-range transaction finished prematurely")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(request != mTransactionPump)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(request != mTransactionPump)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("request != mTransactionPump"
" (" "byte-range transaction finished prematurely" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8186); AnnotateMozCrashReason("MOZ_ASSERT" "(" "request != mTransactionPump"
") (" "byte-range transaction finished prematurely" ")"); do
{ *((volatile int*)__null) = 8186; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
8187
8188 if (request == mCachePump) {
8189 bool streamDone;
8190 status = OnDoneReadingPartialCacheEntry(&streamDone);
8191 if (NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1))) && !streamDone) return status;
8192 // otherwise, fall through and fire OnStopRequest...
8193 } else if (request == mTransactionPump) {
8194 MOZ_ASSERT(LoadConcurrentCacheAccess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadConcurrentCacheAccess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadConcurrentCacheAccess())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("LoadConcurrentCacheAccess()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8194); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadConcurrentCacheAccess()"
")"); do { *((volatile int*)__null) = 8194; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8195 } else {
8196 MOZ_ASSERT_UNREACHABLE("unexpected request")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"unexpected request" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8196); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "unexpected request" ")"); do { *
((volatile int*)__null) = 8196; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
8197 }
8198 }
8199 // Do not to leave the transaction in a suspended state in error cases.
8200 if (NS_FAILED(status)((bool)(__builtin_expect(!!(NS_FAILED_impl(status)), 0))) && mTransaction) {
8201 nsresult rv = gHttpHandler->CancelTransaction(mTransaction, status);
8202 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
8203 LOG((" CancelTransaction failed (%08x)", static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " CancelTransaction failed (%08x)", static_cast<uint32_t
>(rv)); } } while (0)
;
8204 }
8205 }
8206 }
8207
8208 nsCOMPtr<nsICompressConvStats> conv = do_QueryInterface(mCompressListener);
8209 if (conv) {
8210 conv->GetDecodedDataLength(&mDecodedBodySize);
8211 }
8212
8213 bool isFromNet = request == mTransactionPump;
8214
8215 if (mTransaction) {
8216 // determine if we should call DoAuthRetry
8217 bool authRetry = (mAuthRetryPending && NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1))) &&
8218 // we should only auth retry in this channel if are not
8219 // redirecting a new channel for authentication retries
8220 !StaticPrefs::network_auth_use_redirect_for_retries());
8221
8222 StoreStronglyFramed(mTransaction->ResponseIsComplete());
8223 LOG(("nsHttpChannel %p has a strongly framed transaction: %d", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p has a strongly framed transaction: %d", this
, LoadStronglyFramed()); } } while (0)
8224 LoadStronglyFramed()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p has a strongly framed transaction: %d", this
, LoadStronglyFramed()); } } while (0)
;
8225
8226 // Save the reference of |mTransaction| to |transactionWithStickyConn|
8227 // when it has a sticky connection.
8228 // In the case we need to retry an authentication request, we need to
8229 // reuse the connection of |transactionWithStickyConn|.
8230 RefPtr<HttpTransactionShell> transactionWithStickyConn;
8231 if (mCaps & NS_HTTP_STICKY_CONNECTION(1 << 2) ||
8232 mTransaction->HasStickyConnection()) {
8233 transactionWithStickyConn = mTransaction;
8234 // Make sure we use the updated caps and connection info from transaction.
8235 // We read these values when the transaction is already closed, so there
8236 // should be no race.
8237 if (mTransaction->Http2Disabled()) {
8238 mCaps |= NS_HTTP_DISALLOW_SPDY(1 << 7);
8239 }
8240 if (mTransaction->Http3Disabled()) {
8241 mCaps |= NS_HTTP_DISALLOW_HTTP3(1 << 21);
8242 }
8243 mConnectionInfo = mTransaction->GetConnInfo();
8244 LOG((" transaction %p has sticky connection",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " transaction %p has sticky connection", transactionWithStickyConn
.get()); } } while (0)
8245 transactionWithStickyConn.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " transaction %p has sticky connection", transactionWithStickyConn
.get()); } } while (0)
;
8246 }
8247
8248 // this code relies on the code in nsHttpTransaction::Close, which
8249 // tests for NS_HTTP_STICKY_CONNECTION to determine whether or not to
8250 // keep the connection around after the transaction is finished.
8251 //
8252 LOG((" mAuthRetryPending=%d, status=%" PRIx32 ", sticky conn cap=%d",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " mAuthRetryPending=%d, status=%" "x" ", sticky conn cap=%d"
, static_cast<bool>(mAuthRetryPending), static_cast<
uint32_t>(status), mCaps & (1 << 2)); } } while (
0)
8253 static_cast<bool>(mAuthRetryPending), static_cast<uint32_t>(status),do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " mAuthRetryPending=%d, status=%" "x" ", sticky conn cap=%d"
, static_cast<bool>(mAuthRetryPending), static_cast<
uint32_t>(status), mCaps & (1 << 2)); } } while (
0)
8254 mCaps & NS_HTTP_STICKY_CONNECTION))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " mAuthRetryPending=%d, status=%" "x" ", sticky conn cap=%d"
, static_cast<bool>(mAuthRetryPending), static_cast<
uint32_t>(status), mCaps & (1 << 2)); } } while (
0)
;
8255 // We must check caps for stickinness also on the transaction because it
8256 // might have been updated by the transaction itself during inspection of
8257 // the reposnse headers yet on the socket thread (found connection based
8258 // auth schema).
8259
8260 if ((NS_FAILED(status)((bool)(__builtin_expect(!!(NS_FAILED_impl(status)), 0)))) && transactionWithStickyConn) {
8261 // Close (don't reuse) the sticky connection if this channel has been
8262 // cancelled. There are proxy servers known to get confused when we send
8263 // a new request over such a half-stated connection.
8264 if (!LoadAuthConnectionRestartable()) {
8265 LOG((" not reusing a half-authenticated sticky connection"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " not reusing a half-authenticated sticky connection"); } }
while (0)
;
8266 transactionWithStickyConn->DontReuseConnection();
8267 }
8268 }
8269
8270 if (mCaps & NS_HTTP_STICKY_CONNECTION(1 << 2)) {
8271 mTransaction->SetH2WSConnRefTaken();
8272 }
8273
8274 mTransferSize = mTransaction->GetTransferSize();
8275 mRequestSize = mTransaction->GetRequestSize();
8276
8277 RecordHTTPSUpgradeTelemetry(mURI, mLoadInfo);
8278
8279 // If we are using the transaction to serve content, we also save the
8280 // time since async open in the cache entry so we can compare telemetry
8281 // between cache and net response.
8282 // Do not store the time of conditional requests because even if we
8283 // fetch the data from the server, the time includes loading of the old
8284 // cache entry which would skew the network load time.
8285 if (request == mTransactionPump && mCacheEntry && !mDidReval &&
8286 !LoadCustomConditionalRequest() && !mAsyncOpenTime.IsNull() &&
8287 !mOnStartRequestTimestamp.IsNull()) {
8288 uint64_t onStartTime =
8289 (mOnStartRequestTimestamp - mAsyncOpenTime).ToMilliseconds();
8290 uint64_t onStopTime =
8291 (TimeStamp::Now() - mAsyncOpenTime).ToMilliseconds();
8292 Unused << mCacheEntry->SetNetworkTimes(onStartTime, onStopTime);
8293 }
8294
8295 mResponseTrailers = mTransaction->TakeResponseTrailers();
8296
8297 if (nsIOService::UseSocketProcess() && mTransaction) {
8298 mOnStopRequestStartTime = mTransaction->GetOnStopRequestStartTime();
8299 if (!mOnStopRequestStartTime.IsNull()) {
8300 PerfStats::RecordMeasurement(
8301 PerfStats::Metric::OnStopRequestSocketToParent,
8302 TimeStamp::Now() - mOnStopRequestStartTime);
8303 }
8304 } else {
8305 mOnStopRequestStartTime = TimeStamp::Now();
8306 }
8307
8308 // at this point, we're done with the transaction
8309 mTransactionTimings = mTransaction->Timings();
8310 mTransaction = nullptr;
8311 mTransactionPump = nullptr;
8312
8313 // We no longer need the dns prefetch object
8314 if (mDNSPrefetch && mDNSPrefetch->TimingsValid() &&
8315 !mTransactionTimings.requestStart.IsNull() &&
8316 !mTransactionTimings.connectStart.IsNull() &&
8317 mDNSPrefetch->EndTimestamp() <= mTransactionTimings.connectStart) {
8318 // We only need the domainLookup timestamps when not using a
8319 // persistent connection, meaning if the endTimestamp < connectStart
8320 mTransactionTimings.domainLookupStart = mDNSPrefetch->StartTimestamp();
8321 mTransactionTimings.domainLookupEnd = mDNSPrefetch->EndTimestamp();
8322 }
8323 mDNSPrefetch = nullptr;
8324
8325 // handle auth retry...
8326 if (authRetry) {
8327 mAuthRetryPending = false;
8328 auto continueOSR = [authRetry, isFromNet, contentComplete,
8329 transactionWithStickyConn](auto* self,
8330 nsresult aStatus) {
8331 return self->ContinueOnStopRequestAfterAuthRetry(
8332 aStatus, authRetry, isFromNet, contentComplete,
8333 transactionWithStickyConn);
8334 };
8335 status = DoAuthRetry(transactionWithStickyConn, continueOSR);
8336 if (NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1)))) {
8337 return NS_OK;
8338 }
8339 }
8340 return ContinueOnStopRequestAfterAuthRetry(status, authRetry, isFromNet,
8341 contentComplete,
8342 transactionWithStickyConn);
8343 }
8344
8345 return ContinueOnStopRequest(status, isFromNet, contentComplete);
8346}
8347
8348nsresult nsHttpChannel::ContinueOnStopRequestAfterAuthRetry(
8349 nsresult aStatus, bool aAuthRetry, bool aIsFromNet, bool aContentComplete,
8350 HttpTransactionShell* aTransWithStickyConn) {
8351 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnStopRequestAfterAuthRetry " "[this=%p, aStatus=%"
"x" " aAuthRetry=%d, aIsFromNet=%d, aTransWithStickyConn=%p]\n"
, this, static_cast<uint32_t>(aStatus), aAuthRetry, aIsFromNet
, aTransWithStickyConn); } } while (0)
8352 ("nsHttpChannel::ContinueOnStopRequestAfterAuthRetry "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnStopRequestAfterAuthRetry " "[this=%p, aStatus=%"
"x" " aAuthRetry=%d, aIsFromNet=%d, aTransWithStickyConn=%p]\n"
, this, static_cast<uint32_t>(aStatus), aAuthRetry, aIsFromNet
, aTransWithStickyConn); } } while (0)
8353 "[this=%p, aStatus=%" PRIx32do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnStopRequestAfterAuthRetry " "[this=%p, aStatus=%"
"x" " aAuthRetry=%d, aIsFromNet=%d, aTransWithStickyConn=%p]\n"
, this, static_cast<uint32_t>(aStatus), aAuthRetry, aIsFromNet
, aTransWithStickyConn); } } while (0)
8354 " aAuthRetry=%d, aIsFromNet=%d, aTransWithStickyConn=%p]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnStopRequestAfterAuthRetry " "[this=%p, aStatus=%"
"x" " aAuthRetry=%d, aIsFromNet=%d, aTransWithStickyConn=%p]\n"
, this, static_cast<uint32_t>(aStatus), aAuthRetry, aIsFromNet
, aTransWithStickyConn); } } while (0)
8355 this, static_cast<uint32_t>(aStatus), aAuthRetry, aIsFromNet,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnStopRequestAfterAuthRetry " "[this=%p, aStatus=%"
"x" " aAuthRetry=%d, aIsFromNet=%d, aTransWithStickyConn=%p]\n"
, this, static_cast<uint32_t>(aStatus), aAuthRetry, aIsFromNet
, aTransWithStickyConn); } } while (0)
8356 aTransWithStickyConn))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnStopRequestAfterAuthRetry " "[this=%p, aStatus=%"
"x" " aAuthRetry=%d, aIsFromNet=%d, aTransWithStickyConn=%p]\n"
, this, static_cast<uint32_t>(aStatus), aAuthRetry, aIsFromNet
, aTransWithStickyConn); } } while (0)
;
8357
8358 if (aAuthRetry && NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1)))) {
8359 return NS_OK;
8360 }
8361
8362 // If DoAuthRetry failed, or if we have been cancelled since showing
8363 // the auth. dialog, then we need to send OnStartRequest now
8364 if (aAuthRetry || (mAuthRetryPending && NS_FAILED(aStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus)), 0))))) {
8365 MOZ_ASSERT(NS_FAILED(aStatus), "should have a failure code here")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus))
, 0))))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus))
, 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus)), 0)))"
" (" "should have a failure code here" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8365); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus)), 0)))"
") (" "should have a failure code here" ")"); do { *((volatile
int*)__null) = 8365; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
8366 // NOTE: since we have a failure status, we can ignore the return
8367 // value from onStartRequest.
8368 LOG((" calling mListener->OnStartRequest [this=%p, listener=%p]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " calling mListener->OnStartRequest [this=%p, listener=%p]\n"
, this, mListener.get()); } } while (0)
8369 mListener.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " calling mListener->OnStartRequest [this=%p, listener=%p]\n"
, this, mListener.get()); } } while (0)
;
8370 if (mListener) {
8371 MOZ_ASSERT(!LoadOnStartRequestCalled(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadOnStartRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadOnStartRequestCalled())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadOnStartRequestCalled()"
" (" "We should not call OnStartRequest twice." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8372); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
") (" "We should not call OnStartRequest twice." ")"); do { *
((volatile int*)__null) = 8372; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
8372 "We should not call OnStartRequest twice.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadOnStartRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadOnStartRequestCalled())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadOnStartRequestCalled()"
" (" "We should not call OnStartRequest twice." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8372); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
") (" "We should not call OnStartRequest twice." ")"); do { *
((volatile int*)__null) = 8372; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
8373 if (!LoadOnStartRequestCalled()) {
8374 nsCOMPtr<nsIStreamListener> listener(mListener);
8375 StoreOnStartRequestCalled(true);
8376 listener->OnStartRequest(this);
8377 }
8378 } else {
8379 StoreOnStartRequestCalled(true);
8380 NS_WARNING("OnStartRequest skipped because of null listener")NS_DebugBreak(NS_DEBUG_WARNING, "OnStartRequest skipped because of null listener"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8380)
;
8381 }
8382 mAuthRetryPending = false;
8383 }
8384
8385 // if this transaction has been replaced, then bail.
8386 if (LoadTransactionReplaced()) {
8387 LOG(("Transaction replaced\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Transaction replaced\n"); } } while (0)
;
8388 // This was just the network check for a 304 response.
8389 mFirstResponseSource = RESPONSE_PENDING;
8390 return NS_OK;
8391 }
8392
8393 bool upgradeWebsocket = mUpgradeProtocolCallback && aTransWithStickyConn &&
8394 mResponseHead &&
8395 ((mResponseHead->Status() == 101 &&
8396 mResponseHead->Version() == HttpVersion::v1_1) ||
8397 (mResponseHead->Status() == 200 &&
8398 mResponseHead->Version() == HttpVersion::v2_0));
8399
8400 bool upgradeConnect = mUpgradeProtocolCallback && aTransWithStickyConn &&
8401 (mCaps & NS_HTTP_CONNECT_ONLY(1 << 16)) && mResponseHead &&
8402 mResponseHead->Status() == 200;
8403
8404 if (upgradeWebsocket || upgradeConnect) {
8405 if (nsIOService::UseSocketProcess() && upgradeConnect) {
8406 // TODO: Support connection upgrade for socket process in bug 1632809.
8407 Unused << mUpgradeProtocolCallback->OnUpgradeFailed(
8408 NS_ERROR_NOT_IMPLEMENTED);
8409 return ContinueOnStopRequest(aStatus, aIsFromNet, aContentComplete);
8410 }
8411
8412 nsresult rv = gHttpHandler->CompleteUpgrade(aTransWithStickyConn,
8413 mUpgradeProtocolCallback);
8414 mUpgradeProtocolCallback = nullptr;
8415 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
8416 LOG((" CompleteUpgrade failed with %" PRIx32,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " CompleteUpgrade failed with %" "x", static_cast<uint32_t
>(rv)); } } while (0)
8417 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " CompleteUpgrade failed with %" "x", static_cast<uint32_t
>(rv)); } } while (0)
;
8418
8419 // This ensures that WebSocketChannel::OnStopRequest will be
8420 // called with an error so the session is properly aborted.
8421 aStatus = rv;
8422 }
8423 }
8424
8425 return ContinueOnStopRequest(aStatus, aIsFromNet, aContentComplete);
8426}
8427
8428nsresult nsHttpChannel::ContinueOnStopRequest(nsresult aStatus, bool aIsFromNet,
8429 bool aContentComplete) {
8430 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnStopRequest " "[this=%p aStatus=%"
"x" ", aIsFromNet=%d]\n", this, static_cast<uint32_t>(
aStatus), aIsFromNet); } } while (0)
8431 ("nsHttpChannel::ContinueOnStopRequest "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnStopRequest " "[this=%p aStatus=%"
"x" ", aIsFromNet=%d]\n", this, static_cast<uint32_t>(
aStatus), aIsFromNet); } } while (0)
8432 "[this=%p aStatus=%" PRIx32 ", aIsFromNet=%d]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnStopRequest " "[this=%p aStatus=%"
"x" ", aIsFromNet=%d]\n", this, static_cast<uint32_t>(
aStatus), aIsFromNet); } } while (0)
8433 this, static_cast<uint32_t>(aStatus), aIsFromNet))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueOnStopRequest " "[this=%p aStatus=%"
"x" ", aIsFromNet=%d]\n", this, static_cast<uint32_t>(
aStatus), aIsFromNet); } } while (0)
;
8434
8435 // HTTP_CHANNEL_DISPOSITION TELEMETRY
8436 ChannelDisposition chanDisposition = kHttpCanceled;
8437 // HTTP_CHANNEL_DISPOSITION_UPGRADE TELEMETRY
8438 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE upgradeChanDisposition =
8439 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::cancel;
8440
8441 // HTTP 0.9 is more likely to be an error than really 0.9, so count it that
8442 // way
8443 if (mCanceled) {
8444 chanDisposition = kHttpCanceled;
8445 upgradeChanDisposition =
8446 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::cancel;
8447 } else if (!LoadUsedNetwork() ||
8448 (mRaceCacheWithNetwork &&
8449 mFirstResponseSource == RESPONSE_FROM_CACHE)) {
8450 chanDisposition = kHttpDisk;
8451 upgradeChanDisposition =
8452 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::disk;
8453 } else if (NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1))) && mResponseHead &&
8454 mResponseHead->Version() != HttpVersion::v0_9) {
8455 chanDisposition = kHttpNetOK;
8456 upgradeChanDisposition =
8457 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::netOk;
8458 } else if (!mTransferSize) {
8459 chanDisposition = kHttpNetEarlyFail;
8460 upgradeChanDisposition =
8461 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::netEarlyFail;
8462 } else {
8463 chanDisposition = kHttpNetLateFail;
8464 upgradeChanDisposition =
8465 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::netLateFail;
8466 }
8467 // Browser upgrading only happens on HTTPS pages for mixed passive content
8468 // when upgrading is enabled.
8469 nsCString upgradeKey;
8470 nsLiteralCString upgradeChanDispositionLabel =
8471 HttpChanDispositionToTelemetryLabel(upgradeChanDisposition);
8472 if (IsHTTPS()) {
8473 // Browser upgrading is disabled and the content is already HTTPS
8474 upgradeKey = "disabledNoReason"_ns;
8475 // Checks "security.mixed_content.upgrade_display_content" is true
8476 if (StaticPrefs::security_mixed_content_upgrade_display_content()) {
8477 if (mLoadInfo->GetBrowserUpgradeInsecureRequests()) {
8478 // HTTP content the browser has upgraded to HTTPS
8479 mozilla::glean::networking::http_channel_disposition_enabled_upgrade
8480 .Get(upgradeChanDispositionLabel)
8481 .Add(1);
8482 upgradeKey = "enabledUpgrade"_ns;
8483 } else {
8484 // Content wasn't upgraded but is already HTTPS
8485 mozilla::glean::networking::http_channel_disposition_enabled_no_reason
8486 .Get(upgradeChanDispositionLabel)
8487 .Add(1);
8488 upgradeKey = "enabledNoReason"_ns;
8489 }
8490 } else {
8491 mozilla::glean::networking::http_channel_disposition_disabled_no_reason
8492 .Get(upgradeChanDispositionLabel)
8493 .Add(1);
8494 }
8495 // shift http to https disposition enums
8496 chanDisposition =
8497 static_cast<ChannelDisposition>(chanDisposition + kHttpsCanceled);
8498 } else if (mLoadInfo->GetBrowserWouldUpgradeInsecureRequests()) {
8499 // HTTP content the browser would upgrade to HTTPS if upgrading was
8500 // enabled
8501 mozilla::glean::networking::http_channel_disposition_disabled_upgrade
8502 .Get(upgradeChanDispositionLabel)
8503 .Add(1);
8504 upgradeKey = "disabledUpgrade"_ns;
8505 } else if (StaticPrefs::security_mixed_content_upgrade_display_content()) {
8506 // HTTP content that wouldn't upgrade
8507 mozilla::glean::networking::http_channel_disposition_enabled_wont
8508 .Get(upgradeChanDispositionLabel)
8509 .Add(1);
8510 upgradeKey = "enabledWont"_ns;
8511 } else {
8512 mozilla::glean::networking::http_channel_disposition_disabled_wont
8513 .Get(upgradeChanDispositionLabel)
8514 .Add(1);
8515 upgradeKey = "disabledWont"_ns;
8516 }
8517
8518 Telemetry::AccumulateCategoricalKeyed(upgradeKey, upgradeChanDisposition);
8519
8520 LOG((" nsHttpChannel::OnStopRequest ChannelDisposition %d\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " nsHttpChannel::OnStopRequest ChannelDisposition %d\n", chanDisposition
); } } while (0)
8521 chanDisposition))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " nsHttpChannel::OnStopRequest ChannelDisposition %d\n", chanDisposition
); } } while (0)
;
8522 Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_DISPOSITION, chanDisposition);
8523 RecordHttpChanDispositionGlean(chanDisposition);
8524
8525 // Collect specific telemetry for measuring image, video, audio
8526 // success/failure rates in regular browsing mode and when auto upgrading of
8527 // subresources is enabled. Note that we only evaluate actual image types, not
8528 // favicons.
8529 nsContentPolicyType internalLoadType;
8530 mLoadInfo->GetInternalContentPolicyType(&internalLoadType);
8531 bool statusIsSuccess = NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1)));
8532 if (internalLoadType == nsIContentPolicy::TYPE_INTERNAL_IMAGE ||
8533 internalLoadType == nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD) {
8534 if (mLoadInfo->GetBrowserDidUpgradeInsecureRequests()) {
8535 Telemetry::AccumulateCategorical(
8536 statusIsSuccess
8537 ? Telemetry::LABELS_MIXED_CONTENT_IMAGES::ImgUpSuccess
8538 : Telemetry::LABELS_MIXED_CONTENT_IMAGES::ImgUpFailure);
8539 } else {
8540 Telemetry::AccumulateCategorical(
8541 statusIsSuccess
8542 ? Telemetry::LABELS_MIXED_CONTENT_IMAGES::ImgNoUpSuccess
8543 : Telemetry::LABELS_MIXED_CONTENT_IMAGES::ImgNoUpFailure);
8544 }
8545 }
8546 if (internalLoadType == nsIContentPolicy::TYPE_INTERNAL_VIDEO) {
8547 if (mLoadInfo->GetBrowserDidUpgradeInsecureRequests()) {
8548 Telemetry::AccumulateCategorical(
8549 statusIsSuccess
8550 ? Telemetry::LABELS_MIXED_CONTENT_VIDEO::VideoUpSuccess
8551 : Telemetry::LABELS_MIXED_CONTENT_VIDEO::VideoUpFailure);
8552 } else {
8553 Telemetry::AccumulateCategorical(
8554 statusIsSuccess
8555 ? Telemetry::LABELS_MIXED_CONTENT_VIDEO::VideoNoUpSuccess
8556 : Telemetry::LABELS_MIXED_CONTENT_VIDEO::VideoNoUpFailure);
8557 }
8558 }
8559 if (internalLoadType == nsIContentPolicy::TYPE_INTERNAL_AUDIO) {
8560 if (mLoadInfo->GetBrowserDidUpgradeInsecureRequests()) {
8561 Telemetry::AccumulateCategorical(
8562 statusIsSuccess
8563 ? Telemetry::LABELS_MIXED_CONTENT_AUDIO::AudioUpSuccess
8564 : Telemetry::LABELS_MIXED_CONTENT_AUDIO::AudioUpFailure);
8565 } else {
8566 Telemetry::AccumulateCategorical(
8567 statusIsSuccess
8568 ? Telemetry::LABELS_MIXED_CONTENT_AUDIO::AudioNoUpSuccess
8569 : Telemetry::LABELS_MIXED_CONTENT_AUDIO::AudioNoUpFailure);
8570 }
8571 }
8572
8573 // if needed, check cache entry has all data we expect
8574 if (mCacheEntry && mCachePump && LoadConcurrentCacheAccess() &&
8575 aContentComplete) {
8576 int64_t size, contentLength;
8577 nsresult rv = CheckPartial(mCacheEntry, &size, &contentLength);
8578 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
8579 if (size == int64_t(-1)) {
8580 // mayhemer TODO - we have to restart read from cache here at the size
8581 // offset
8582 MOZ_ASSERT(false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8582); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")")
; do { *((volatile int*)__null) = 8582; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8583 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " cache entry write is still in progress, but we just " "finished reading the cache entry"
); } } while (0)
8584 (" cache entry write is still in progress, but we just "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " cache entry write is still in progress, but we just " "finished reading the cache entry"
); } } while (0)
8585 "finished reading the cache entry"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " cache entry write is still in progress, but we just " "finished reading the cache entry"
); } } while (0)
;
8586 } else if (contentLength != int64_t(-1) && contentLength != size) {
8587 LOG((" concurrent cache entry write has been interrupted"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " concurrent cache entry write has been interrupted"); } }
while (0)
;
8588 mCachedResponseHead = std::move(mResponseHead);
8589 // Ignore zero partial length because we also want to resume when
8590 // no data at all has been read from the cache.
8591 rv = MaybeSetupByteRangeRequest(size, contentLength, true);
8592 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && LoadIsPartialRequest()) {
8593 // Prevent read from cache again
8594 mCachedContentIsValid = false;
8595 StoreCachedContentIsPartial(1);
8596
8597 // We are about to perform a different network request.
8598 // We must set mRaceCacheWithNetwork to false because otherwise
8599 // we would ignore the network response thinking we didn't need it.
8600 mRaceCacheWithNetwork = false;
8601
8602 // Perform the range request
8603 rv = ContinueConnect();
8604 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
8605 LOG((" performing range request"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " performing range request"); } } while (0)
;
8606 mCachePump = nullptr;
8607 return NS_OK;
8608 }
8609 LOG((" but range request perform failed 0x%08" PRIx32,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " but range request perform failed 0x%08" "x", static_cast
<uint32_t>(rv)); } } while (0)
8610 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " but range request perform failed 0x%08" "x", static_cast
<uint32_t>(rv)); } } while (0)
;
8611 aStatus = NS_ERROR_NET_INTERRUPT;
8612 } else {
8613 LOG((" but range request setup failed rv=0x%08" PRIx32do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " but range request setup failed rv=0x%08" "x" ", failing load"
, static_cast<uint32_t>(rv)); } } while (0)
8614 ", failing load",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " but range request setup failed rv=0x%08" "x" ", failing load"
, static_cast<uint32_t>(rv)); } } while (0)
8615 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " but range request setup failed rv=0x%08" "x" ", failing load"
, static_cast<uint32_t>(rv)); } } while (0)
;
8616 }
8617 }
8618 }
8619 }
8620
8621 StoreIsPending(false);
8622 mStatus = aStatus;
8623
8624 // perform any final cache operations before we close the cache entry.
8625 if (mCacheEntry && LoadRequestTimeInitialized()) {
8626 // New implementation just returns value of the !LoadCacheEntryIsReadOnly()
8627 // flag passed in. Old implementation checks on nsICache::ACCESS_WRITE
8628 // flag.
8629
8630 // Assume that write access is granted
8631 if (!LoadCacheEntryIsReadOnly()) {
8632 nsresult rv = FinalizeCacheEntry();
8633 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
8634 LOG(("FinalizeCacheEntry failed (%08x)", static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "FinalizeCacheEntry failed (%08x)", static_cast<uint32_t
>(rv)); } } while (0)
;
8635 }
8636 }
8637 }
8638
8639 ReportRcwnStats(aIsFromNet);
8640
8641 // Register entry to the PerformanceStorage resource timing
8642 MaybeReportTimingData();
8643
8644 MaybeFlushConsoleReports();
8645
8646 if (!mEndMarkerAdded && profiler_thread_is_being_profiled_for_markers()) {
8647 // These do allocations/frees/etc; avoid if not active
8648 mEndMarkerAdded = true;
8649
8650 nsAutoCString requestMethod;
8651 GetRequestMethod(requestMethod);
8652
8653 int32_t priority = PRIORITY_NORMAL;
8654 GetPriority(&priority);
8655
8656 uint64_t size = 0;
8657 GetEncodedBodySize(&size);
8658
8659 nsAutoCString contentType;
8660 if (mResponseHead) {
8661 mResponseHead->ContentType(contentType);
8662 }
8663 profiler_add_network_marker(
8664 mURI, requestMethod, priority, mChannelId, NetworkLoadType::LOAD_STOP,
8665 mLastStatusReported, TimeStamp::Now(), size, mCacheDisposition,
8666 mLoadInfo->GetInnerWindowID(),
8667 mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(),
8668 &mTransactionTimings, std::move(mSource),
8669 Some(nsDependentCString(contentType.get())));
8670 }
8671
8672 if (mAuthRetryPending &&
8673 StaticPrefs::network_auth_use_redirect_for_retries()) {
8674 nsresult rv = OpenRedirectChannel(aStatus);
8675 LOG(("Opening redirect channel for auth retry %x",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opening redirect channel for auth retry %x", static_cast<
uint32_t>(rv)); } } while (0)
8676 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Opening redirect channel for auth retry %x", static_cast<
uint32_t>(rv)); } } while (0)
;
8677 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
8678 if (mListener) {
8679 MOZ_ASSERT(!LoadOnStartRequestCalled(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadOnStartRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadOnStartRequestCalled())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadOnStartRequestCalled()"
" (" "We should not call OnStartRequest twice." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8680); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
") (" "We should not call OnStartRequest twice." ")"); do { *
((volatile int*)__null) = 8680; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
8680 "We should not call OnStartRequest twice.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadOnStartRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadOnStartRequestCalled())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadOnStartRequestCalled()"
" (" "We should not call OnStartRequest twice." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8680); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
") (" "We should not call OnStartRequest twice." ")"); do { *
((volatile int*)__null) = 8680; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
8681 if (!LoadOnStartRequestCalled()) {
8682 nsCOMPtr<nsIStreamListener> listener(mListener);
8683 StoreOnStartRequestCalled(true);
8684 listener->OnStartRequest(this);
8685 }
8686 } else {
8687 StoreOnStartRequestCalled(true);
8688 NS_WARNING("OnStartRequest skipped because of null listener")NS_DebugBreak(NS_DEBUG_WARNING, "OnStartRequest skipped because of null listener"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8688)
;
8689 }
8690 }
8691 mAuthRetryPending = false;
8692 }
8693
8694 // notify "http-on-before-stop-request" observers
8695 gHttpHandler->OnBeforeStopRequest(this);
8696
8697 if (mListener) {
8698 LOG(("nsHttpChannel %p calling OnStopRequest\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p calling OnStopRequest\n", this); } } while
(0)
;
8699 MOZ_ASSERT(LoadOnStartRequestCalled(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadOnStartRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadOnStartRequestCalled()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("LoadOnStartRequestCalled()"
" (" "OnStartRequest should be called before OnStopRequest" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8700); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadOnStartRequestCalled()"
") (" "OnStartRequest should be called before OnStopRequest"
")"); do { *((volatile int*)__null) = 8700; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
8700 "OnStartRequest should be called before OnStopRequest")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadOnStartRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadOnStartRequestCalled()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("LoadOnStartRequestCalled()"
" (" "OnStartRequest should be called before OnStopRequest" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8700); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadOnStartRequestCalled()"
") (" "OnStartRequest should be called before OnStopRequest"
")"); do { *((volatile int*)__null) = 8700; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8701 MOZ_ASSERT(!LoadOnStopRequestCalled(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadOnStopRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadOnStopRequestCalled()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadOnStopRequestCalled()"
" (" "We should not call OnStopRequest twice" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8702); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStopRequestCalled()"
") (" "We should not call OnStopRequest twice" ")"); do { *(
(volatile int*)__null) = 8702; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
8702 "We should not call OnStopRequest twice")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadOnStopRequestCalled())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!LoadOnStopRequestCalled()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!LoadOnStopRequestCalled()"
" (" "We should not call OnStopRequest twice" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8702); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStopRequestCalled()"
") (" "We should not call OnStopRequest twice" ")"); do { *(
(volatile int*)__null) = 8702; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
8703 StoreOnStopRequestCalled(true);
8704 mListener->OnStopRequest(this, aStatus);
8705 }
8706 StoreOnStopRequestCalled(true);
8707
8708 // The prefetch needs to be released on the main thread
8709 mDNSPrefetch = nullptr;
8710
8711 mRedirectChannel = nullptr;
8712
8713 // notify "http-on-stop-request" observers
8714 gHttpHandler->OnStopRequest(this);
8715
8716 RemoveAsNonTailRequest();
8717
8718 if (mChannelBlockedByOpaqueResponse && mCachedOpaqueResponseBlockingPref) {
8719 mResponseHead->ClearHeaders();
8720 }
8721 // If a preferred alt-data type was set, this signals the consumer is
8722 // interested in reading and/or writing the alt-data representation.
8723 // We need to hold a reference to the cache entry in case the listener calls
8724 // openAlternativeOutputStream() after CloseCacheEntry() clears mCacheEntry.
8725 if (!mPreferredCachedAltDataTypes.IsEmpty()) {
8726 mAltDataCacheEntry = mCacheEntry;
8727 }
8728
8729 CloseCacheEntry(!aContentComplete);
8730
8731 if (mLoadGroup) {
8732 mLoadGroup->RemoveRequest(this, nullptr, aStatus);
8733 }
8734
8735 // We don't need this info anymore
8736 CleanRedirectCacheChainIfNecessary();
8737
8738 ReleaseListeners();
8739
8740 return NS_OK;
8741}
8742
8743//-----------------------------------------------------------------------------
8744// nsHttpChannel::nsIStreamListener
8745//-----------------------------------------------------------------------------
8746
8747class OnTransportStatusAsyncEvent : public Runnable {
8748 public:
8749 OnTransportStatusAsyncEvent(nsITransportEventSink* aEventSink,
8750 nsresult aTransportStatus, int64_t aProgress,
8751 int64_t aProgressMax)
8752 : Runnable("net::OnTransportStatusAsyncEvent"),
8753 mEventSink(aEventSink),
8754 mTransportStatus(aTransportStatus),
8755 mProgress(aProgress),
8756 mProgressMax(aProgressMax) {
8757 MOZ_ASSERT(!NS_IsMainThread(), "Shouldn't be created on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!NS_IsMainThread()"
" (" "Shouldn't be created on main thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8757); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
") (" "Shouldn't be created on main thread" ")"); do { *((volatile
int*)__null) = 8757; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
8758 }
8759
8760 NS_IMETHODvirtual nsresult Run() override {
8761 MOZ_ASSERT(NS_IsMainThread(), "Should run on main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Should run on main thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8761); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should run on main thread" ")"); do { *((volatile int
*)__null) = 8761; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
8762 if (mEventSink) {
8763 mEventSink->OnTransportStatus(nullptr, mTransportStatus, mProgress,
8764 mProgressMax);
8765 }
8766 return NS_OK;
8767 }
8768
8769 private:
8770 nsCOMPtr<nsITransportEventSink> mEventSink;
8771 nsresult mTransportStatus;
8772 int64_t mProgress;
8773 int64_t mProgressMax;
8774};
8775
8776NS_IMETHODIMPnsresult
8777nsHttpChannel::OnDataAvailable(nsIRequest* request, nsIInputStream* input,
8778 uint64_t offset, uint32_t count) {
8779 nsresult rv;
8780 AUTO_PROFILER_LABEL("nsHttpChannel::OnDataAvailable", NETWORK)mozilla::AutoProfilerLabel raiiObject8780( "nsHttpChannel::OnDataAvailable"
, nullptr, JS::ProfilingCategoryPair::NETWORK)
;
8781
8782 LOG(("nsHttpChannel::OnDataAvailable [this=%p request=%p offset=%" PRIu64do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnDataAvailable [this=%p request=%p offset=%"
"l" "u" " count=%" "u" "]\n", this, request, offset, count);
} } while (0)
8783 " count=%" PRIu32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnDataAvailable [this=%p request=%p offset=%"
"l" "u" " count=%" "u" "]\n", this, request, offset, count);
} } while (0)
8784 this, request, offset, count))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnDataAvailable [this=%p request=%p offset=%"
"l" "u" " count=%" "u" "]\n", this, request, offset, count);
} } while (0)
;
8785
8786 LOG((" requestFromCache: %d mFirstResponseSource: %d\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " requestFromCache: %d mFirstResponseSource: %d\n", request
== mCachePump, static_cast<int32_t>(mFirstResponseSource
)); } } while (0)
8787 request == mCachePump, static_cast<int32_t>(mFirstResponseSource)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " requestFromCache: %d mFirstResponseSource: %d\n", request
== mCachePump, static_cast<int32_t>(mFirstResponseSource
)); } } while (0)
;
8788
8789 // don't send out OnDataAvailable notifications if we've been canceled.
8790 if (mCanceled) return mStatus;
8791
8792 if (mAuthRetryPending || WRONG_RACING_RESPONSE_SOURCE(request)(mRaceCacheWithNetwork && (((mFirstResponseSource == RESPONSE_FROM_CACHE
) && ((request) != mCachePump)) || ((mFirstResponseSource
== RESPONSE_FROM_NETWORK) && ((request) != mTransactionPump
))))
||
8793 (request == mTransactionPump && LoadTransactionReplaced())) {
8794 uint32_t n;
8795 return input->ReadSegments(NS_DiscardSegment, nullptr, count, &n);
8796 }
8797
8798 MOZ_ASSERT(mResponseHead, "No response head in ODA!!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mResponseHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mResponseHead))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mResponseHead" " ("
"No response head in ODA!!" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8798); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mResponseHead"
") (" "No response head in ODA!!" ")"); do { *((volatile int
*)__null) = 8798; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
8799
8800 MOZ_ASSERT(!(LoadCachedContentIsPartial() && (request == mTransactionPump)),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!(LoadCachedContentIsPartial() && (request ==
mTransactionPump)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!(LoadCachedContentIsPartial
() && (request == mTransactionPump))))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!(LoadCachedContentIsPartial() && (request == mTransactionPump))"
" (" "transaction pump not suspended" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8801); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(LoadCachedContentIsPartial() && (request == mTransactionPump))"
") (" "transaction pump not suspended" ")"); do { *((volatile
int*)__null) = 8801; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
8801 "transaction pump not suspended")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!(LoadCachedContentIsPartial() && (request ==
mTransactionPump)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!(LoadCachedContentIsPartial
() && (request == mTransactionPump))))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("!(LoadCachedContentIsPartial() && (request == mTransactionPump))"
" (" "transaction pump not suspended" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8801); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(LoadCachedContentIsPartial() && (request == mTransactionPump))"
") (" "transaction pump not suspended" ")"); do { *((volatile
int*)__null) = 8801; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
8802
8803 mIsReadingFromCache = (request == mCachePump);
8804
8805 if (mListener) {
8806 //
8807 // synthesize transport progress event. we do this here since we want
8808 // to delay OnProgress events until we start streaming data. this is
8809 // crucially important since it impacts the lock icon (see bug 240053).
8810 //
8811 nsresult transportStatus;
8812 if (request == mCachePump) {
8813 transportStatus = NS_NET_STATUS_READING;
8814 } else {
8815 transportStatus = NS_NET_STATUS_RECEIVING_FROM;
8816 }
8817
8818 // mResponseHead may reference new or cached headers, but either way it
8819 // holds our best estimate of the total content length. Even in the case
8820 // of a byte range request, the content length stored in the cached
8821 // response headers is what we want to use here.
8822
8823 int64_t progressMax = -1;
8824 rv = GetContentLength(&progressMax);
8825 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
8826 NS_WARNING("GetContentLength failed")NS_DebugBreak(NS_DEBUG_WARNING, "GetContentLength failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8826)
;
8827 }
8828 int64_t progress = mLogicalOffset + count;
8829
8830 if ((progress > progressMax) && (progressMax != -1)) {
8831 NS_WARNING(NS_DebugBreak(NS_DEBUG_WARNING, "unexpected progress values - "
"is server exceeding content length?", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8833)
8832 "unexpected progress values - "NS_DebugBreak(NS_DEBUG_WARNING, "unexpected progress values - "
"is server exceeding content length?", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8833)
8833 "is server exceeding content length?")NS_DebugBreak(NS_DEBUG_WARNING, "unexpected progress values - "
"is server exceeding content length?", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8833)
;
8834 }
8835
8836 // make sure params are in range for js
8837 if (!InScriptableRange(progressMax)) {
8838 progressMax = -1;
8839 }
8840
8841 if (!InScriptableRange(progress)) {
8842 progress = -1;
8843 }
8844
8845 if (NS_IsMainThread()) {
8846 OnTransportStatus(nullptr, transportStatus, progress, progressMax);
8847 } else {
8848 rv = NS_DispatchToMainThread(new OnTransportStatusAsyncEvent(
8849 this, transportStatus, progress, progressMax));
8850 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8850); return rv; } } while (false)
;
8851 }
8852
8853 //
8854 // we have to manually keep the logical offset of the stream up-to-date.
8855 // we cannot depend solely on the offset provided, since we may have
8856 // already streamed some data from another source (see, for example,
8857 // OnDoneReadingPartialCacheEntry).
8858 //
8859 int64_t offsetBefore = 0;
8860 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(input);
8861 if (seekable && NS_FAILED(seekable->Tell(&offsetBefore))((bool)(__builtin_expect(!!(NS_FAILED_impl(seekable->Tell(
&offsetBefore))), 0)))
) {
8862 seekable = nullptr;
8863 }
8864
8865 if (nsIOService::UseSocketProcess() && mTransaction) {
8866 mOnDataAvailableStartTime = mTransaction->GetDataAvailableStartTime();
8867 if (!mOnDataAvailableStartTime.IsNull()) {
8868 PerfStats::RecordMeasurement(
8869 PerfStats::Metric::OnDataAvailableSocketToParent,
8870 TimeStamp::Now() - mOnDataAvailableStartTime);
8871 }
8872 } else {
8873 mOnDataAvailableStartTime = TimeStamp::Now();
8874 }
8875 nsresult rv =
8876 mListener->OnDataAvailable(this, input, mLogicalOffset, count);
8877 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
8878 // by contract mListener must read all of "count" bytes, but
8879 // nsInputStreamPump is tolerant to seekable streams that violate that
8880 // and it will redeliver incompletely read data. So we need to do
8881 // the same thing when updating the progress counter to stay in sync.
8882 int64_t offsetAfter, delta;
8883 if (seekable && NS_SUCCEEDED(seekable->Tell(&offsetAfter))((bool)(__builtin_expect(!!(!NS_FAILED_impl(seekable->Tell
(&offsetAfter))), 1)))
) {
8884 delta = offsetAfter - offsetBefore;
8885 if (delta != count) {
8886 count = delta;
8887
8888 NS_WARNING("Listener OnDataAvailable contract violation")NS_DebugBreak(NS_DEBUG_WARNING, "Listener OnDataAvailable contract violation"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8888)
;
8889 nsCOMPtr<nsIConsoleService> consoleService;
8890 consoleService = mozilla::components::Console::Service();
8891 nsAutoString message(nsLiteralString(
8892 u"http channel Listener OnDataAvailable contract violation"));
8893 if (consoleService) {
8894 consoleService->LogStringMessage(message.get());
8895 }
8896 }
8897 }
8898 mLogicalOffset += count;
8899 }
8900
8901 return rv;
8902 }
8903
8904 return NS_ERROR_ABORT;
8905}
8906
8907//-----------------------------------------------------------------------------
8908// nsHttpChannel::nsIThreadRetargetableRequest
8909//-----------------------------------------------------------------------------
8910
8911NS_IMETHODIMPnsresult
8912nsHttpChannel::RetargetDeliveryTo(nsISerialEventTarget* aNewTarget) {
8913 MOZ_ASSERT(NS_IsMainThread(), "Should be called on main thread only")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Should be called on main thread only" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8913); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should be called on main thread only" ")"); do { *((volatile
int*)__null) = 8913; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
8914
8915 NS_ENSURE_ARG(aNewTarget)do { if ((__builtin_expect(!!(!(aNewTarget)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aNewTarget" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8915); return NS_ERROR_INVALID_ARG; } } while (false)
;
8916 if (aNewTarget->IsOnCurrentThread()) {
8917 NS_WARNING("Retargeting delivery to same thread")NS_DebugBreak(NS_DEBUG_WARNING, "Retargeting delivery to same thread"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8917)
;
8918 return NS_OK;
8919 }
8920 if (!mTransactionPump && !mCachePump) {
8921 LOG(("nsHttpChannel::RetargetDeliveryTo %p %p no pump available\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::RetargetDeliveryTo %p %p no pump available\n"
, this, aNewTarget); } } while (0)
8922 aNewTarget))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::RetargetDeliveryTo %p %p no pump available\n"
, this, aNewTarget); } } while (0)
;
8923 return NS_ERROR_NOT_AVAILABLE;
8924 }
8925
8926 nsresult rv = NS_OK;
8927 // If both cache pump and transaction pump exist, we're probably dealing
8928 // with partially cached content. So, we must be able to retarget both.
8929 nsCOMPtr<nsIThreadRetargetableRequest> retargetableCachePump;
8930 nsCOMPtr<nsIThreadRetargetableRequest> retargetableTransactionPump;
8931 if (mCachePump) {
8932 retargetableCachePump = do_QueryObject(mCachePump);
8933 // nsInputStreamPump should implement this interface.
8934 MOZ_ASSERT(retargetableCachePump)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(retargetableCachePump)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(retargetableCachePump))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("retargetableCachePump"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8934); AnnotateMozCrashReason("MOZ_ASSERT" "(" "retargetableCachePump"
")"); do { *((volatile int*)__null) = 8934; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8935 rv = retargetableCachePump->RetargetDeliveryTo(aNewTarget);
8936 }
8937 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && mTransactionPump) {
8938 retargetableTransactionPump = do_QueryObject(mTransactionPump);
8939 // nsInputStreamPump should implement this interface.
8940 MOZ_ASSERT(retargetableTransactionPump)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(retargetableTransactionPump)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(retargetableTransactionPump)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("retargetableTransactionPump"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8940); AnnotateMozCrashReason("MOZ_ASSERT" "(" "retargetableTransactionPump"
")"); do { *((volatile int*)__null) = 8940; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8941 rv = retargetableTransactionPump->RetargetDeliveryTo(aNewTarget);
8942
8943 // If retarget fails for transaction pump, we must restore mCachePump.
8944 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && retargetableCachePump) {
8945 nsCOMPtr<nsISerialEventTarget> main = GetMainThreadSerialEventTarget();
8946 NS_ENSURE_TRUE(main, NS_ERROR_UNEXPECTED)do { if ((__builtin_expect(!!(!(main)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "main" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8946); return NS_ERROR_UNEXPECTED; } } while (false)
;
8947 rv = retargetableCachePump->RetargetDeliveryTo(main);
8948 }
8949 }
8950 return rv;
8951}
8952
8953NS_IMETHODIMPnsresult
8954nsHttpChannel::GetDeliveryTarget(nsISerialEventTarget** aEventTarget) {
8955 if (mCachePump) {
8956 return mCachePump->GetDeliveryTarget(aEventTarget);
8957 }
8958 if (mTransactionPump) {
8959 nsCOMPtr<nsIThreadRetargetableRequest> request =
8960 do_QueryInterface(mTransactionPump);
8961 return request->GetDeliveryTarget(aEventTarget);
8962 }
8963 return NS_ERROR_NOT_AVAILABLE;
8964}
8965
8966//-----------------------------------------------------------------------------
8967// nsHttpChannel::nsThreadRetargetableStreamListener
8968//-----------------------------------------------------------------------------
8969
8970NS_IMETHODIMPnsresult
8971nsHttpChannel::CheckListenerChain() {
8972 NS_ASSERTION(NS_IsMainThread(), "Should be on main thread!")do { if (!(NS_IsMainThread())) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "Should be on main thread!", "NS_IsMainThread()", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8972); MOZ_PretendNoReturn(); } } while (0)
;
8973 nsresult rv = NS_OK;
8974 nsCOMPtr<nsIThreadRetargetableStreamListener> retargetableListener =
8975 do_QueryInterface(mListener, &rv);
8976 if (retargetableListener) {
8977 rv = retargetableListener->CheckListenerChain();
8978 }
8979 return rv;
8980}
8981
8982NS_IMETHODIMPnsresult
8983nsHttpChannel::OnDataFinished(nsresult aStatus) {
8984 nsCOMPtr<nsIThreadRetargetableStreamListener> listener =
8985 do_QueryInterface(mListener);
8986
8987 if (listener) {
8988 return listener->OnDataFinished(aStatus);
8989 }
8990
8991 return NS_OK;
8992}
8993
8994//-----------------------------------------------------------------------------
8995// nsHttpChannel::nsITransportEventSink
8996//-----------------------------------------------------------------------------
8997
8998NS_IMETHODIMPnsresult
8999nsHttpChannel::OnTransportStatus(nsITransport* trans, nsresult status,
9000 int64_t progress, int64_t progressMax) {
9001 MOZ_ASSERT(NS_IsMainThread(), "Should be on main thread only")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Should be on main thread only" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9001); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should be on main thread only" ")"); do { *((volatile
int*)__null) = 9001; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9002 // cache the progress sink so we don't have to query for it each time.
9003 if (!mProgressSink) GetCallback(mProgressSink);
9004
9005 if (status == NS_NET_STATUS_CONNECTED_TO ||
9006 status == NS_NET_STATUS_WAITING_FOR) {
9007 bool isTrr = false;
9008 bool echConfigUsed = false;
9009 if (mTransaction) {
9010 mTransaction->GetNetworkAddresses(mSelfAddr, mPeerAddr, isTrr,
9011 mEffectiveTRRMode, mTRRSkipReason,
9012 echConfigUsed);
9013 } else {
9014 nsCOMPtr<nsISocketTransport> socketTransport = do_QueryInterface(trans);
9015 if (socketTransport) {
9016 socketTransport->GetSelfAddr(&mSelfAddr);
9017 socketTransport->GetPeerAddr(&mPeerAddr);
9018 socketTransport->ResolvedByTRR(&isTrr);
9019 socketTransport->GetEffectiveTRRMode(&mEffectiveTRRMode);
9020 socketTransport->GetEchConfigUsed(&echConfigUsed);
9021 }
9022 }
9023
9024 StoreResolvedByTRR(isTrr);
9025 StoreEchConfigUsed(echConfigUsed);
9026 }
9027
9028 // block socket status event after Cancel or OnStopRequest has been called.
9029 if (mProgressSink && NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1))) && LoadIsPending()) {
9030 LOG(("sending progress%s notification [this=%p status=%" PRIx32do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "sending progress%s notification [this=%p status=%" "x" " progress=%"
"l" "d" "/%" "l" "d" "]\n", (mLoadFlags & LOAD_BACKGROUND
) ? "" : " and status", this, static_cast<uint32_t>(status
), progress, progressMax); } } while (0)
9031 " progress=%" PRId64 "/%" PRId64 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "sending progress%s notification [this=%p status=%" "x" " progress=%"
"l" "d" "/%" "l" "d" "]\n", (mLoadFlags & LOAD_BACKGROUND
) ? "" : " and status", this, static_cast<uint32_t>(status
), progress, progressMax); } } while (0)
9032 (mLoadFlags & LOAD_BACKGROUND) ? "" : " and status", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "sending progress%s notification [this=%p status=%" "x" " progress=%"
"l" "d" "/%" "l" "d" "]\n", (mLoadFlags & LOAD_BACKGROUND
) ? "" : " and status", this, static_cast<uint32_t>(status
), progress, progressMax); } } while (0)
9033 static_cast<uint32_t>(status), progress, progressMax))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "sending progress%s notification [this=%p status=%" "x" " progress=%"
"l" "d" "/%" "l" "d" "]\n", (mLoadFlags & LOAD_BACKGROUND
) ? "" : " and status", this, static_cast<uint32_t>(status
), progress, progressMax); } } while (0)
;
9034
9035 nsAutoCString host;
9036 mURI->GetHost(host);
9037 if (!(mLoadFlags & LOAD_BACKGROUND)) {
9038 mProgressSink->OnStatus(this, status, NS_ConvertUTF8toUTF16(host).get());
9039 } else {
9040 nsCOMPtr<nsIParentChannel> parentChannel;
9041 NS_QueryNotificationCallbacks(this, parentChannel);
9042 // If the event sink is |HttpChannelParent|, we have to send status
9043 // events to it even if LOAD_BACKGROUND is set. |HttpChannelParent|
9044 // needs to be aware of whether the status is
9045 // |NS_NET_STATUS_RECEIVING_FROM| or |NS_NET_STATUS_READING|.
9046 // LOAD_BACKGROUND is checked again in |HttpChannelChild|, so the final
9047 // consumer won't get this event.
9048 if (SameCOMIdentity(parentChannel, mProgressSink)) {
9049 mProgressSink->OnStatus(this, status,
9050 NS_ConvertUTF8toUTF16(host).get());
9051 }
9052 }
9053
9054 if (progress > 0) {
9055 if ((progress > progressMax) && (progressMax != -1)) {
9056 NS_WARNING("unexpected progress values")NS_DebugBreak(NS_DEBUG_WARNING, "unexpected progress values",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9056)
;
9057 }
9058
9059 // Try to get mProgressSink if it was nulled out during OnStatus.
9060 if (!mProgressSink) {
9061 GetCallback(mProgressSink);
9062 }
9063 if (mProgressSink) {
9064 mProgressSink->OnProgress(this, progress, progressMax);
9065 }
9066 }
9067 }
9068
9069 return NS_OK;
9070}
9071
9072//-----------------------------------------------------------------------------
9073// nsHttpChannel::nsICacheInfoChannel
9074//-----------------------------------------------------------------------------
9075
9076NS_IMETHODIMPnsresult
9077nsHttpChannel::IsFromCache(bool* value) {
9078 if (!LoadIsPending()) return NS_ERROR_NOT_AVAILABLE;
9079
9080 if (!mRaceCacheWithNetwork) {
9081 // return false if reading a partial cache entry; the data isn't
9082 // entirely from the cache!
9083 *value = (mCachePump || (mLoadFlags & LOAD_ONLY_IF_MODIFIED)) &&
9084 mCachedContentIsValid && !LoadCachedContentIsPartial();
9085 return NS_OK;
9086 }
9087
9088 // If we are racing network and cache (or skipping the cache)
9089 // we just return the first response source.
9090 *value = mFirstResponseSource == RESPONSE_FROM_CACHE;
9091
9092 return NS_OK;
9093}
9094
9095NS_IMETHODIMPnsresult
9096nsHttpChannel::GetCacheEntryId(uint64_t* aCacheEntryId) {
9097 bool fromCache = false;
9098 if (NS_FAILED(IsFromCache(&fromCache))((bool)(__builtin_expect(!!(NS_FAILED_impl(IsFromCache(&fromCache
))), 0)))
|| !fromCache || !mCacheEntry ||
9099 NS_FAILED(mCacheEntry->GetCacheEntryId(aCacheEntryId))((bool)(__builtin_expect(!!(NS_FAILED_impl(mCacheEntry->GetCacheEntryId
(aCacheEntryId))), 0)))
) {
9100 return NS_ERROR_NOT_AVAILABLE;
9101 }
9102
9103 return NS_OK;
9104}
9105
9106NS_IMETHODIMPnsresult
9107nsHttpChannel::GetCacheTokenFetchCount(uint32_t* _retval) {
9108 NS_ENSURE_ARG_POINTER(_retval)do { if ((__builtin_expect(!!(!(_retval)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "_retval" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9108); return NS_ERROR_INVALID_POINTER; } } while (false)
;
9109 nsCOMPtr<nsICacheEntry> cacheEntry =
9110 mCacheEntry ? mCacheEntry : mAltDataCacheEntry;
9111 if (!cacheEntry) {
9112 return NS_ERROR_NOT_AVAILABLE;
9113 }
9114
9115 return cacheEntry->GetFetchCount(_retval);
9116}
9117
9118NS_IMETHODIMPnsresult
9119nsHttpChannel::GetCacheTokenExpirationTime(uint32_t* _retval) {
9120 NS_ENSURE_ARG_POINTER(_retval)do { if ((__builtin_expect(!!(!(_retval)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "_retval" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9120); return NS_ERROR_INVALID_POINTER; } } while (false)
;
9121 if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
9122
9123 return mCacheEntry->GetExpirationTime(_retval);
9124}
9125
9126NS_IMETHODIMPnsresult
9127nsHttpChannel::SetAllowStaleCacheContent(bool aAllowStaleCacheContent) {
9128 LOG(("nsHttpChannel::SetAllowStaleCacheContent [this=%p, allow=%d]", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetAllowStaleCacheContent [this=%p, allow=%d]"
, this, aAllowStaleCacheContent); } } while (0)
9129 aAllowStaleCacheContent))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetAllowStaleCacheContent [this=%p, allow=%d]"
, this, aAllowStaleCacheContent); } } while (0)
;
9130 StoreAllowStaleCacheContent(aAllowStaleCacheContent);
9131 return NS_OK;
9132}
9133NS_IMETHODIMPnsresult
9134nsHttpChannel::GetAllowStaleCacheContent(bool* aAllowStaleCacheContent) {
9135 NS_ENSURE_ARG(aAllowStaleCacheContent)do { if ((__builtin_expect(!!(!(aAllowStaleCacheContent)), 0)
)) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aAllowStaleCacheContent"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9135); return NS_ERROR_INVALID_ARG; } } while (false)
;
9136 *aAllowStaleCacheContent = LoadAllowStaleCacheContent();
9137 return NS_OK;
9138}
9139
9140NS_IMETHODIMPnsresult
9141nsHttpChannel::SetForceValidateCacheContent(bool aForceValidateCacheContent) {
9142 LOG(("nsHttpChannel::SetForceValidateCacheContent [this=%p, allow=%d]", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetForceValidateCacheContent [this=%p, allow=%d]"
, this, aForceValidateCacheContent); } } while (0)
9143 aForceValidateCacheContent))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetForceValidateCacheContent [this=%p, allow=%d]"
, this, aForceValidateCacheContent); } } while (0)
;
9144 StoreForceValidateCacheContent(aForceValidateCacheContent);
9145 return NS_OK;
9146}
9147NS_IMETHODIMPnsresult
9148nsHttpChannel::GetForceValidateCacheContent(bool* aForceValidateCacheContent) {
9149 NS_ENSURE_ARG(aForceValidateCacheContent)do { if ((__builtin_expect(!!(!(aForceValidateCacheContent)),
0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aForceValidateCacheContent"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9149); return NS_ERROR_INVALID_ARG; } } while (false)
;
9150 *aForceValidateCacheContent = LoadForceValidateCacheContent();
9151 return NS_OK;
9152}
9153
9154NS_IMETHODIMPnsresult
9155nsHttpChannel::SetPreferCacheLoadOverBypass(bool aPreferCacheLoadOverBypass) {
9156 StorePreferCacheLoadOverBypass(aPreferCacheLoadOverBypass);
9157 return NS_OK;
9158}
9159NS_IMETHODIMPnsresult
9160nsHttpChannel::GetPreferCacheLoadOverBypass(bool* aPreferCacheLoadOverBypass) {
9161 NS_ENSURE_ARG(aPreferCacheLoadOverBypass)do { if ((__builtin_expect(!!(!(aPreferCacheLoadOverBypass)),
0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aPreferCacheLoadOverBypass"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9161); return NS_ERROR_INVALID_ARG; } } while (false)
;
9162 *aPreferCacheLoadOverBypass = LoadPreferCacheLoadOverBypass();
9163 return NS_OK;
9164}
9165
9166NS_IMETHODIMPnsresult
9167nsHttpChannel::PreferAlternativeDataType(
9168 const nsACString& aType, const nsACString& aContentType,
9169 PreferredAlternativeDataDeliveryType aDeliverAltData) {
9170 ENSURE_CALLED_BEFORE_ASYNC_OPEN()do { if (LoadIsPending() || LoadWasOpened()) { nsPrintfCString
msg("'%s' called after AsyncOpen: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9170); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9170, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9170); } } while (0); } do { if ((__builtin_expect(!!(!(!LoadIsPending
())), 0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE("
"!LoadIsPending()" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9170); return NS_ERROR_IN_PROGRESS; } } while (false); do {
if ((__builtin_expect(!!(!(!LoadWasOpened())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!LoadWasOpened()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9170); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
9171 mPreferredCachedAltDataTypes.AppendElement(PreferredAlternativeDataTypeParams(
9172 nsCString(aType), nsCString(aContentType), aDeliverAltData));
9173 return NS_OK;
9174}
9175
9176const nsTArray<PreferredAlternativeDataTypeParams>&
9177nsHttpChannel::PreferredAlternativeDataTypes() {
9178 return mPreferredCachedAltDataTypes;
9179}
9180
9181NS_IMETHODIMPnsresult
9182nsHttpChannel::GetAlternativeDataType(nsACString& aType) {
9183 // must be called during or after OnStartRequest
9184 if (!LoadAfterOnStartRequestBegun()) {
9185 return NS_ERROR_NOT_AVAILABLE;
9186 }
9187 aType = mAvailableCachedAltDataType;
9188 return NS_OK;
9189}
9190
9191NS_IMETHODIMPnsresult
9192nsHttpChannel::OpenAlternativeOutputStream(const nsACString& type,
9193 int64_t predictedSize,
9194 nsIAsyncOutputStream** _retval) {
9195 // OnStopRequest will clear mCacheEntry, but we may use mAltDataCacheEntry
9196 // if the consumer called PreferAlternativeDataType()
9197 nsCOMPtr<nsICacheEntry> cacheEntry =
9198 mCacheEntry ? mCacheEntry : mAltDataCacheEntry;
9199 if (!cacheEntry) {
9200 return NS_ERROR_NOT_AVAILABLE;
9201 }
9202 nsresult rv =
9203 cacheEntry->OpenAlternativeOutputStream(type, predictedSize, _retval);
9204 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
9205 // Clear this metadata flag in case it exists.
9206 // The caller of this method may set it again.
9207 cacheEntry->SetMetaDataElement("alt-data-from-child", nullptr);
9208 }
9209 return rv;
9210}
9211
9212NS_IMETHODIMPnsresult
9213nsHttpChannel::GetOriginalInputStream(nsIInputStreamReceiver* aReceiver) {
9214 if (aReceiver == nullptr) {
9215 return NS_ERROR_INVALID_ARG;
9216 }
9217 nsCOMPtr<nsIInputStream> inputStream;
9218
9219 nsCOMPtr<nsICacheEntry> cacheEntry =
9220 mCacheEntry ? mCacheEntry : mAltDataCacheEntry;
9221 if (cacheEntry) {
9222 cacheEntry->OpenInputStream(0, getter_AddRefs(inputStream));
9223 }
9224 aReceiver->OnInputStreamReady(inputStream);
9225 return NS_OK;
9226}
9227
9228NS_IMETHODIMPnsresult
9229nsHttpChannel::GetAlternativeDataInputStream(nsIInputStream** aInputStream) {
9230 NS_ENSURE_ARG_POINTER(aInputStream)do { if ((__builtin_expect(!!(!(aInputStream)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aInputStream" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9230); return NS_ERROR_INVALID_POINTER; } } while (false)
;
9231
9232 *aInputStream = nullptr;
9233
9234 nsCOMPtr<nsICacheEntry> cacheEntry =
9235 mCacheEntry ? mCacheEntry : mAltDataCacheEntry;
9236 if (!mAvailableCachedAltDataType.IsEmpty() && cacheEntry) {
9237 nsresult rv = cacheEntry->OpenAlternativeInputStream(
9238 mAvailableCachedAltDataType, aInputStream);
9239 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9239); return rv; } } while (false)
;
9240 }
9241 return NS_OK;
9242}
9243
9244//-----------------------------------------------------------------------------
9245// nsHttpChannel::nsICachingChannel
9246//-----------------------------------------------------------------------------
9247
9248NS_IMETHODIMPnsresult
9249nsHttpChannel::IsRacing(bool* aIsRacing) {
9250 if (!LoadAfterOnStartRequestBegun()) {
9251 return NS_ERROR_NOT_AVAILABLE;
9252 }
9253 *aIsRacing = mRaceCacheWithNetwork;
9254 return NS_OK;
9255}
9256
9257NS_IMETHODIMPnsresult
9258nsHttpChannel::GetCacheToken(nsISupports** token) {
9259 NS_ENSURE_ARG_POINTER(token)do { if ((__builtin_expect(!!(!(token)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "token" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9259); return NS_ERROR_INVALID_POINTER; } } while (false)
;
9260 if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
9261 return CallQueryInterface(mCacheEntry, token);
9262}
9263
9264NS_IMETHODIMPnsresult
9265nsHttpChannel::SetCacheToken(nsISupports* token) {
9266 return NS_ERROR_NOT_IMPLEMENTED;
9267}
9268
9269NS_IMETHODIMPnsresult
9270nsHttpChannel::GetCacheKey(uint32_t* key) {
9271 NS_ENSURE_ARG_POINTER(key)do { if ((__builtin_expect(!!(!(key)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "key" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9271); return NS_ERROR_INVALID_POINTER; } } while (false)
;
9272
9273 LOG(("nsHttpChannel::GetCacheKey [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::GetCacheKey [this=%p]\n", this); } } while (
0)
;
9274
9275 *key = mPostID;
9276 return NS_OK;
9277}
9278
9279NS_IMETHODIMPnsresult
9280nsHttpChannel::SetCacheKey(uint32_t key) {
9281 LOG(("nsHttpChannel::SetCacheKey [this=%p key=%u]\n", this, key))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetCacheKey [this=%p key=%u]\n", this, key)
; } } while (0)
;
9282
9283 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9283); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9283, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9283); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9283); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 9283; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
9284
9285 mPostID = key;
9286 return NS_OK;
9287}
9288
9289NS_IMETHODIMPnsresult
9290nsHttpChannel::GetCacheOnlyMetadata(bool* aOnlyMetadata) {
9291 NS_ENSURE_ARG(aOnlyMetadata)do { if ((__builtin_expect(!!(!(aOnlyMetadata)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOnlyMetadata" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9291); return NS_ERROR_INVALID_ARG; } } while (false)
;
9292 *aOnlyMetadata = LoadCacheOnlyMetadata();
9293 return NS_OK;
9294}
9295
9296NS_IMETHODIMPnsresult
9297nsHttpChannel::SetCacheOnlyMetadata(bool aOnlyMetadata) {
9298 LOG(("nsHttpChannel::SetCacheOnlyMetadata [this=%p only-metadata=%d]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetCacheOnlyMetadata [this=%p only-metadata=%d]\n"
, this, aOnlyMetadata); } } while (0)
9299 aOnlyMetadata))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetCacheOnlyMetadata [this=%p only-metadata=%d]\n"
, this, aOnlyMetadata); } } while (0)
;
9300
9301 ENSURE_CALLED_BEFORE_ASYNC_OPEN()do { if (LoadIsPending() || LoadWasOpened()) { nsPrintfCString
msg("'%s' called after AsyncOpen: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9301); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9301, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9301); } } while (0); } do { if ((__builtin_expect(!!(!(!LoadIsPending
())), 0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE("
"!LoadIsPending()" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9301); return NS_ERROR_IN_PROGRESS; } } while (false); do {
if ((__builtin_expect(!!(!(!LoadWasOpened())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!LoadWasOpened()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9301); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
9302
9303 StoreCacheOnlyMetadata(aOnlyMetadata);
9304 if (aOnlyMetadata) {
9305 mLoadFlags |= LOAD_ONLY_IF_MODIFIED;
9306 }
9307
9308 return NS_OK;
9309}
9310
9311NS_IMETHODIMPnsresult
9312nsHttpChannel::GetPin(bool* aPin) {
9313 NS_ENSURE_ARG(aPin)do { if ((__builtin_expect(!!(!(aPin)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aPin" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9313); return NS_ERROR_INVALID_ARG; } } while (false)
;
9314 *aPin = LoadPinCacheContent();
9315 return NS_OK;
9316}
9317
9318NS_IMETHODIMPnsresult
9319nsHttpChannel::SetPin(bool aPin) {
9320 LOG(("nsHttpChannel::SetPin [this=%p pin=%d]\n", this, aPin))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetPin [this=%p pin=%d]\n", this, aPin); } }
while (0)
;
9321
9322 ENSURE_CALLED_BEFORE_CONNECT()do { if (LoadRequestObserversCalled()) { nsPrintfCString msg(
"'%s' called too late: %s +%d", __FUNCTION__, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9322); do { bool abort = true; const char* e = PR_GetEnv("NECKO_ERRORS_ARE_FATAL"
); if (e) abort = (*e == '0') ? false : true; if (abort) { msg
.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=0 in your environment "
"to convert this error into a warning.)"); MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9322, msg.get()); } else { msg.AppendLiteral( " (set NECKO_ERRORS_ARE_FATAL=1 in your environment "
"to convert this warning into a fatal error.)"); NS_DebugBreak
(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9322); } } while (0); if (LoadIsPending()) return NS_ERROR_IN_PROGRESS
; do { static_assert( mozilla::detail::AssertionConditionType
<decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9322); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 9322; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
9323
9324 StorePinCacheContent(aPin);
9325 return NS_OK;
9326}
9327
9328NS_IMETHODIMPnsresult
9329nsHttpChannel::ForceCacheEntryValidFor(uint32_t aSecondsToTheFuture) {
9330 if (!mCacheEntry) {
9331 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ForceCacheEntryValidFor found no cache entry "
"for this channel [this=%p].", this); } } while (0)
9332 ("nsHttpChannel::ForceCacheEntryValidFor found no cache entry "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ForceCacheEntryValidFor found no cache entry "
"for this channel [this=%p].", this); } } while (0)
9333 "for this channel [this=%p].",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ForceCacheEntryValidFor found no cache entry "
"for this channel [this=%p].", this); } } while (0)
9334 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ForceCacheEntryValidFor found no cache entry "
"for this channel [this=%p].", this); } } while (0)
;
9335 } else {
9336 mCacheEntry->ForceValidFor(aSecondsToTheFuture);
9337
9338 nsAutoCString key;
9339 mCacheEntry->GetKey(key);
9340
9341 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ForceCacheEntryValidFor successfully forced valid "
"entry with key %s for %d seconds. [this=%p]", key.get(), aSecondsToTheFuture
, this); } } while (0)
9342 ("nsHttpChannel::ForceCacheEntryValidFor successfully forced valid "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ForceCacheEntryValidFor successfully forced valid "
"entry with key %s for %d seconds. [this=%p]", key.get(), aSecondsToTheFuture
, this); } } while (0)
9343 "entry with key %s for %d seconds. [this=%p]",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ForceCacheEntryValidFor successfully forced valid "
"entry with key %s for %d seconds. [this=%p]", key.get(), aSecondsToTheFuture
, this); } } while (0)
9344 key.get(), aSecondsToTheFuture, this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ForceCacheEntryValidFor successfully forced valid "
"entry with key %s for %d seconds. [this=%p]", key.get(), aSecondsToTheFuture
, this); } } while (0)
;
9345 }
9346
9347 return NS_OK;
9348}
9349
9350//-----------------------------------------------------------------------------
9351// nsHttpChannel::nsIResumableChannel
9352//-----------------------------------------------------------------------------
9353
9354NS_IMETHODIMPnsresult
9355nsHttpChannel::ResumeAt(uint64_t aStartPos, const nsACString& aEntityID) {
9356 LOG(("nsHttpChannel::ResumeAt [this=%p startPos=%" PRIu64 " id='%s']\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResumeAt [this=%p startPos=%" "l" "u" " id='%s']\n"
, this, aStartPos, TPromiseFlatString<char>(aEntityID).
get()); } } while (0)
9357 aStartPos, PromiseFlatCString(aEntityID).get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ResumeAt [this=%p startPos=%" "l" "u" " id='%s']\n"
, this, aStartPos, TPromiseFlatString<char>(aEntityID).
get()); } } while (0)
;
9358 mEntityID = aEntityID;
9359 mStartPos = aStartPos;
9360 StoreResuming(true);
9361 return NS_OK;
9362}
9363
9364nsresult nsHttpChannel::DoAuthRetry(
9365 HttpTransactionShell* aTransWithStickyConn,
9366 const std::function<nsresult(nsHttpChannel*, nsresult)>&
9367 aContinueOnStopRequestFunc) {
9368 LOG(("nsHttpChannel::DoAuthRetry [this=%p, aTransWithStickyConn=%p]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::DoAuthRetry [this=%p, aTransWithStickyConn=%p]\n"
, this, aTransWithStickyConn); } } while (0)
9369 aTransWithStickyConn))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::DoAuthRetry [this=%p, aTransWithStickyConn=%p]\n"
, this, aTransWithStickyConn); } } while (0)
;
9370
9371 MOZ_ASSERT(!mTransaction, "should not have a transaction")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mTransaction)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mTransaction))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!mTransaction" " ("
"should not have a transaction" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9371); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mTransaction"
") (" "should not have a transaction" ")"); do { *((volatile
int*)__null) = 9371; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9372
9373 // Note that we don't have to toggle |IsPending| anymore. See the reasons
9374 // below.
9375 // 1. We can't suspend the channel during "http-on-modify-request"
9376 // when |IsPending| is false.
9377 // 2. We don't check |IsPending| in SetRequestHeader now.
9378
9379 // Reset RequestObserversCalled because we've probably called the request
9380 // observers once already.
9381 StoreRequestObserversCalled(false);
9382
9383 // fetch cookies, and add them to the request header.
9384 // the server response could have included cookies that must be sent with
9385 // this authentication attempt (bug 84794).
9386 // TODO: save cookies from auth response and send them here (bug 572151).
9387 AddCookiesToRequest();
9388
9389 // notify "http-on-modify-request" observers
9390 CallOnModifyRequestObservers();
9391
9392 RefPtr<HttpTransactionShell> trans(aTransWithStickyConn);
9393 return CallOrWaitForResume(
9394 [trans{std::move(trans)}, aContinueOnStopRequestFunc](auto* self) {
9395 return self->ContinueDoAuthRetry(trans, aContinueOnStopRequestFunc);
9396 });
9397}
9398
9399nsresult nsHttpChannel::ContinueDoAuthRetry(
9400 HttpTransactionShell* aTransWithStickyConn,
9401 const std::function<nsresult(nsHttpChannel*, nsresult)>&
9402 aContinueOnStopRequestFunc) {
9403 LOG(("nsHttpChannel::ContinueDoAuthRetry [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::ContinueDoAuthRetry [this=%p]\n", this); } }
while (0)
;
9404 StoreIsPending(true);
9405
9406 // get rid of the old response headers
9407 mResponseHead = nullptr;
9408
9409 // rewind the upload stream
9410 if (mUploadStream) {
9411 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
9412 nsresult rv = NS_ERROR_NO_INTERFACE;
9413 if (seekable) {
9414 rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
9415 }
9416
9417 // This should not normally happen, but it's possible that big memory
9418 // blobs originating in the other process can't be rewinded.
9419 // In that case we just fail the request, otherwise the content length
9420 // will not match and this load will never complete.
9421 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9421); return rv; } } while (false)
;
9422 }
9423
9424 // always set sticky connection flag
9425 mCaps |= NS_HTTP_STICKY_CONNECTION(1 << 2);
9426 // and when needed, allow restart regardless the sticky flag
9427 if (LoadAuthConnectionRestartable()) {
9428 LOG((" connection made restartable"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " connection made restartable"); } } while (0)
;
9429 mCaps |= NS_HTTP_CONNECTION_RESTARTABLE(1 << 13);
9430 StoreAuthConnectionRestartable(false);
9431 } else {
9432 LOG((" connection made non-restartable"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " connection made non-restartable"); } } while (0)
;
9433 mCaps &= ~NS_HTTP_CONNECTION_RESTARTABLE(1 << 13);
9434 }
9435
9436 // notify "http-on-before-connect" observers
9437 gHttpHandler->OnBeforeConnect(this);
9438
9439 RefPtr<HttpTransactionShell> trans(aTransWithStickyConn);
9440 return CallOrWaitForResume(
9441 [trans{std::move(trans)}, aContinueOnStopRequestFunc](auto* self) {
9442 nsresult rv = self->DoConnect(trans);
9443 return aContinueOnStopRequestFunc(self, rv);
9444 });
9445}
9446
9447//-----------------------------------------------------------------------------
9448// nsHttpChannel::nsIAsyncVerifyRedirectCallback
9449//-----------------------------------------------------------------------------
9450
9451nsresult nsHttpChannel::WaitForRedirectCallback() {
9452 nsresult rv;
9453 LOG(("nsHttpChannel::WaitForRedirectCallback [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::WaitForRedirectCallback [this=%p]\n", this)
; } } while (0)
;
9454
9455 if (mTransactionPump) {
9456 rv = mTransactionPump->Suspend();
9457 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9457); return rv; } } while (false)
;
9458 }
9459 if (mCachePump) {
9460 rv = mCachePump->Suspend();
9461 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && mTransactionPump) {
9462#ifdef DEBUG1
9463 nsresult resume =
9464#endif
9465 mTransactionPump->Resume();
9466 MOZ_ASSERT(NS_SUCCEEDED(resume), "Failed to resume transaction pump")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(resume))
, 1))))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(resume))
, 1)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(resume)), 1)))"
" (" "Failed to resume transaction pump" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9466); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(resume)), 1)))"
") (" "Failed to resume transaction pump" ")"); do { *((volatile
int*)__null) = 9466; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9467 }
9468 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9468); return rv; } } while (false)
;
9469 }
9470
9471 StoreWaitingForRedirectCallback(true);
9472 return NS_OK;
9473}
9474
9475NS_IMETHODIMPnsresult
9476nsHttpChannel::OnRedirectVerifyCallback(nsresult result) {
9477 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnRedirectVerifyCallback [this=%p] " "result=%"
"x" " stack=%zu WaitingForRedirectCallback=%u\n", this, static_cast
<uint32_t>(result), mRedirectFuncStack.Length(), LoadWaitingForRedirectCallback
()); } } while (0)
9478 ("nsHttpChannel::OnRedirectVerifyCallback [this=%p] "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnRedirectVerifyCallback [this=%p] " "result=%"
"x" " stack=%zu WaitingForRedirectCallback=%u\n", this, static_cast
<uint32_t>(result), mRedirectFuncStack.Length(), LoadWaitingForRedirectCallback
()); } } while (0)
9479 "result=%" PRIx32 " stack=%zu WaitingForRedirectCallback=%u\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnRedirectVerifyCallback [this=%p] " "result=%"
"x" " stack=%zu WaitingForRedirectCallback=%u\n", this, static_cast
<uint32_t>(result), mRedirectFuncStack.Length(), LoadWaitingForRedirectCallback
()); } } while (0)
9480 this, static_cast<uint32_t>(result), mRedirectFuncStack.Length(),do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnRedirectVerifyCallback [this=%p] " "result=%"
"x" " stack=%zu WaitingForRedirectCallback=%u\n", this, static_cast
<uint32_t>(result), mRedirectFuncStack.Length(), LoadWaitingForRedirectCallback
()); } } while (0)
9481 LoadWaitingForRedirectCallback()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnRedirectVerifyCallback [this=%p] " "result=%"
"x" " stack=%zu WaitingForRedirectCallback=%u\n", this, static_cast
<uint32_t>(result), mRedirectFuncStack.Length(), LoadWaitingForRedirectCallback
()); } } while (0)
;
9482 MOZ_ASSERT(LoadWaitingForRedirectCallback(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadWaitingForRedirectCallback())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWaitingForRedirectCallback
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("LoadWaitingForRedirectCallback()" " (" "Someone forgot to call WaitForRedirectCallback() ?!"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9483); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWaitingForRedirectCallback()"
") (" "Someone forgot to call WaitForRedirectCallback() ?!" ")"
); do { *((volatile int*)__null) = 9483; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9483 "Someone forgot to call WaitForRedirectCallback() ?!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadWaitingForRedirectCallback())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWaitingForRedirectCallback
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("LoadWaitingForRedirectCallback()" " (" "Someone forgot to call WaitForRedirectCallback() ?!"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9483); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWaitingForRedirectCallback()"
") (" "Someone forgot to call WaitForRedirectCallback() ?!" ")"
); do { *((volatile int*)__null) = 9483; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9484 StoreWaitingForRedirectCallback(false);
9485
9486 if (mCanceled && NS_SUCCEEDED(result)((bool)(__builtin_expect(!!(!NS_FAILED_impl(result)), 1)))) result = NS_BINDING_ABORTED;
9487
9488 for (uint32_t i = mRedirectFuncStack.Length(); i > 0;) {
9489 --i;
9490 // Pop the last function pushed to the stack
9491 nsContinueRedirectionFunc func = mRedirectFuncStack.PopLastElement();
9492
9493 // Call it with the result we got from the callback or the deeper
9494 // function call.
9495 result = (this->*func)(result);
9496
9497 // If a new function has been pushed to the stack and placed us in the
9498 // waiting state, we need to break the chain and wait for the callback
9499 // again.
9500 if (LoadWaitingForRedirectCallback()) break;
9501 }
9502
9503 if (NS_FAILED(result)((bool)(__builtin_expect(!!(NS_FAILED_impl(result)), 0))) && !mCanceled) {
9504 // First, cancel this channel if we are in failure state to set mStatus
9505 // and let it be propagated to pumps.
9506 Cancel(result);
9507 }
9508
9509 if (!LoadWaitingForRedirectCallback()) {
9510 // We are not waiting for the callback. At this moment we must release
9511 // reference to the redirect target channel, otherwise we may leak.
9512 // However, if we are redirecting due to auth retries, we open the
9513 // redirected channel after OnStopRequest. In that case we should not
9514 // release the reference
9515 if (!StaticPrefs::network_auth_use_redirect_for_retries() ||
9516 !mAuthRetryPending) {
9517 mRedirectChannel = nullptr;
9518 }
9519 }
9520
9521 // We always resume the pumps here. If all functions on stack have been
9522 // called we need OnStopRequest to be triggered, and if we broke out of the
9523 // loop above (and are thus waiting for a new callback) the suspension
9524 // count must be balanced in the pumps.
9525 if (mTransactionPump) mTransactionPump->Resume();
9526 if (mCachePump) mCachePump->Resume();
9527
9528 return result;
9529}
9530
9531void nsHttpChannel::PushRedirectAsyncFunc(nsContinueRedirectionFunc func) {
9532 mRedirectFuncStack.AppendElement(func);
9533}
9534
9535void nsHttpChannel::PopRedirectAsyncFunc(nsContinueRedirectionFunc func) {
9536 MOZ_ASSERT(func == mRedirectFuncStack.LastElement(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(func == mRedirectFuncStack.LastElement())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(func == mRedirectFuncStack.LastElement()))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("func == mRedirectFuncStack.LastElement()"
" (" "Trying to pop wrong method from redirect async stack!"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9537); AnnotateMozCrashReason("MOZ_ASSERT" "(" "func == mRedirectFuncStack.LastElement()"
") (" "Trying to pop wrong method from redirect async stack!"
")"); do { *((volatile int*)__null) = 9537; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9537 "Trying to pop wrong method from redirect async stack!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(func == mRedirectFuncStack.LastElement())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(func == mRedirectFuncStack.LastElement()))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("func == mRedirectFuncStack.LastElement()"
" (" "Trying to pop wrong method from redirect async stack!"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9537); AnnotateMozCrashReason("MOZ_ASSERT" "(" "func == mRedirectFuncStack.LastElement()"
") (" "Trying to pop wrong method from redirect async stack!"
")"); do { *((volatile int*)__null) = 9537; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9538
9539 mRedirectFuncStack.RemoveLastElement();
9540}
9541
9542//-----------------------------------------------------------------------------
9543// nsIDNSListener functions
9544//-----------------------------------------------------------------------------
9545
9546NS_IMETHODIMPnsresult
9547nsHttpChannel::OnLookupComplete(nsICancelable* request, nsIDNSRecord* rec,
9548 nsresult status) {
9549 MOZ_ASSERT(NS_IsMainThread(), "Expecting DNS callback on main thread.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Expecting DNS callback on main thread." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9549); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Expecting DNS callback on main thread." ")"); do { *(
(volatile int*)__null) = 9549; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
9550
9551 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnLookupComplete [this=%p] prefetch complete%s: "
"%s status[0x%" "x" "]\n", this, mCaps & (1 << 3) ?
", refresh requested" : "", ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(status)), 1))) ? "success" : "failure", static_cast<uint32_t
>(status)); } } while (0)
9552 ("nsHttpChannel::OnLookupComplete [this=%p] prefetch complete%s: "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnLookupComplete [this=%p] prefetch complete%s: "
"%s status[0x%" "x" "]\n", this, mCaps & (1 << 3) ?
", refresh requested" : "", ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(status)), 1))) ? "success" : "failure", static_cast<uint32_t
>(status)); } } while (0)
9553 "%s status[0x%" PRIx32 "]\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnLookupComplete [this=%p] prefetch complete%s: "
"%s status[0x%" "x" "]\n", this, mCaps & (1 << 3) ?
", refresh requested" : "", ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(status)), 1))) ? "success" : "failure", static_cast<uint32_t
>(status)); } } while (0)
9554 this, mCaps & NS_HTTP_REFRESH_DNS ? ", refresh requested" : "",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnLookupComplete [this=%p] prefetch complete%s: "
"%s status[0x%" "x" "]\n", this, mCaps & (1 << 3) ?
", refresh requested" : "", ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(status)), 1))) ? "success" : "failure", static_cast<uint32_t
>(status)); } } while (0)
9555 NS_SUCCEEDED(status) ? "success" : "failure",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnLookupComplete [this=%p] prefetch complete%s: "
"%s status[0x%" "x" "]\n", this, mCaps & (1 << 3) ?
", refresh requested" : "", ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(status)), 1))) ? "success" : "failure", static_cast<uint32_t
>(status)); } } while (0)
9556 static_cast<uint32_t>(status)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnLookupComplete [this=%p] prefetch complete%s: "
"%s status[0x%" "x" "]\n", this, mCaps & (1 << 3) ?
", refresh requested" : "", ((bool)(__builtin_expect(!!(!NS_FAILED_impl
(status)), 1))) ? "success" : "failure", static_cast<uint32_t
>(status)); } } while (0)
;
9557
9558 // Unset DNS cache refresh if it was requested,
9559 if (mCaps & NS_HTTP_REFRESH_DNS(1 << 3)) {
9560 mCaps &= ~NS_HTTP_REFRESH_DNS(1 << 3);
9561 if (mTransaction) {
9562 mTransaction->SetDNSWasRefreshed();
9563 }
9564 }
9565
9566 if (!mDNSBlockingPromise.IsEmpty()) {
9567 if (NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1)))) {
9568 nsCOMPtr<nsIDNSRecord> record(rec);
9569 mDNSBlockingPromise.Resolve(record, __func__);
9570 } else {
9571 mDNSBlockingPromise.Reject(status, __func__);
9572 }
9573 }
9574
9575 return NS_OK;
9576}
9577
9578void nsHttpChannel::OnHTTPSRRAvailable(nsIDNSHTTPSSVCRecord* aRecord) {
9579 MOZ_ASSERT(NS_IsMainThread(), "Expecting DNS callback on main thread.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Expecting DNS callback on main thread." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9579); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Expecting DNS callback on main thread." ")"); do { *(
(volatile int*)__null) = 9579; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
9580
9581 LOG(("nsHttpChannel::OnHTTPSRRAvailable [this=%p, aRecord=%p]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnHTTPSRRAvailable [this=%p, aRecord=%p]\n"
, this, aRecord); } } while (0)
9582 aRecord))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnHTTPSRRAvailable [this=%p, aRecord=%p]\n"
, this, aRecord); } } while (0)
;
9583
9584 if (mHTTPSSVCRecord) {
9585 MOZ_ASSERT(false, "OnHTTPSRRAvailable called twice!")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "OnHTTPSRRAvailable called twice!"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9585); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"OnHTTPSRRAvailable called twice!" ")"); do { *((volatile int
*)__null) = 9585; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9586 return;
9587 }
9588
9589 nsCOMPtr<nsIDNSHTTPSSVCRecord> record = aRecord;
9590 mHTTPSSVCRecord.emplace(std::move(record));
9591 const nsCOMPtr<nsIDNSHTTPSSVCRecord>& httprr = mHTTPSSVCRecord.ref();
9592
9593 if (LoadWaitHTTPSSVCRecord()) {
9594 MOZ_ASSERT(mURI->SchemeIs("http"))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mURI->SchemeIs("http"))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mURI->SchemeIs("http"))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("mURI->SchemeIs(\"http\")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9594); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mURI->SchemeIs(\"http\")"
")"); do { *((volatile int*)__null) = 9594; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9595
9596 StoreWaitHTTPSSVCRecord(false);
9597 nsresult rv = ContinueOnBeforeConnect(!!httprr, mStatus, !!httprr);
9598 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
9599 CloseCacheEntry(false);
9600 Unused << AsyncAbort(rv);
9601 }
9602 } else {
9603 // This channel is not canceled and the transaction is not created.
9604 if (httprr && NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1))) && !mTransaction &&
9605 (mFirstResponseSource != RESPONSE_FROM_CACHE)) {
9606 bool hasIPAddress = false;
9607 Unused << httprr->GetHasIPAddresses(&hasIPAddress);
9608 Telemetry::Accumulate(Telemetry::DNS_HTTPSSVC_RECORD_RECEIVING_STAGE,
9609 hasIPAddress
9610 ? HTTPSSVC_WITH_IPHINT_RECEIVED_STAGE_0
9611 : HTTPSSVC_WITHOUT_IPHINT_RECEIVED_STAGE_0);
9612 StoreHTTPSSVCTelemetryReported(true);
9613 }
9614 }
9615}
9616
9617//-----------------------------------------------------------------------------
9618// nsHttpChannel internal functions
9619//-----------------------------------------------------------------------------
9620
9621// Creates an URI to the given location using current URI for base and charset
9622nsresult nsHttpChannel::CreateNewURI(const char* loc, nsIURI** newURI) {
9623 nsCOMPtr<nsIIOService> ioService;
9624 nsresult rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
9625 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
9626
9627 return ioService->NewURI(nsDependentCString(loc), nullptr, mURI, newURI);
9628}
9629
9630void nsHttpChannel::MaybeInvalidateCacheEntryForSubsequentGet() {
9631 // See RFC 2616 section 5.1.1. These are considered valid
9632 // methods which DO NOT invalidate cache-entries for the
9633 // referred resource. POST, PUT and DELETE as well as any
9634 // other method not listed here will potentially invalidate
9635 // any cached copy of the resource
9636 if (mRequestHead.IsGet() || mRequestHead.IsOptions() ||
9637 mRequestHead.IsHead() || mRequestHead.IsTrace() ||
9638 mRequestHead.IsConnect()) {
9639 return;
9640 }
9641
9642 // Invalidate the request-uri.
9643 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(mozilla::net::
gHttpLog, mozilla::LogLevel::Verbose)), 0))
) {
9644 nsAutoCString key;
9645 mURI->GetAsciiSpec(key);
9646 LOG(("MaybeInvalidateCacheEntryForSubsequentGet [this=%p uri=%s]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "MaybeInvalidateCacheEntryForSubsequentGet [this=%p uri=%s]\n"
, this, key.get()); } } while (0)
9647 key.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "MaybeInvalidateCacheEntryForSubsequentGet [this=%p uri=%s]\n"
, this, key.get()); } } while (0)
;
9648 }
9649
9650 DoInvalidateCacheEntry(mURI);
9651
9652 // Invalidate Location-header if set
9653 nsAutoCString location;
9654 Unused << mResponseHead->GetHeader(nsHttp::Location, location);
9655 if (!location.IsEmpty()) {
9656 LOG((" Location-header=%s\n", location.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Location-header=%s\n", location.get()); } } while (0)
;
9657 InvalidateCacheEntryForLocation(location.get());
9658 }
9659
9660 // Invalidate Content-Location-header if set
9661 Unused << mResponseHead->GetHeader(nsHttp::Content_Location, location);
9662 if (!location.IsEmpty()) {
9663 LOG((" Content-Location-header=%s\n", location.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " Content-Location-header=%s\n", location.get()); } } while
(0)
;
9664 InvalidateCacheEntryForLocation(location.get());
9665 }
9666}
9667
9668void nsHttpChannel::InvalidateCacheEntryForLocation(const char* location) {
9669 nsAutoCString tmpCacheKey, tmpSpec;
9670 nsCOMPtr<nsIURI> resultingURI;
9671 nsresult rv = CreateNewURI(location, getter_AddRefs(resultingURI));
9672 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && HostPartIsTheSame(resultingURI)) {
9673 DoInvalidateCacheEntry(resultingURI);
9674 } else {
9675 LOG((" hosts not matching\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " hosts not matching\n"); } } while (0)
;
9676 }
9677}
9678
9679void nsHttpChannel::DoInvalidateCacheEntry(nsIURI* aURI) {
9680 // NOTE:
9681 // Following comments 24,32 and 33 in bug #327765, we only care about
9682 // the cache in the protocol-handler.
9683 // The logic below deviates from the original logic in OpenCacheEntry on
9684 // one point by using only READ_ONLY access-policy. I think this is safe.
9685
9686 nsresult rv;
9687
9688 nsAutoCString key;
9689 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(mozilla::net::
gHttpLog, mozilla::LogLevel::Verbose)), 0))
) {
9690 aURI->GetAsciiSpec(key);
9691 }
9692
9693 LOG(("DoInvalidateCacheEntry [channel=%p key=%s]", this, key.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "DoInvalidateCacheEntry [channel=%p key=%s]", this, key.get
()); } } while (0)
;
9694
9695 nsCOMPtr<nsICacheStorageService> cacheStorageService(
9696 components::CacheStorage::Service());
9697 rv = cacheStorageService ? NS_OK : NS_ERROR_FAILURE;
9698
9699 nsCOMPtr<nsICacheStorage> cacheStorage;
9700 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
9701 RefPtr<LoadContextInfo> info = GetLoadContextInfo(this);
9702 rv = cacheStorageService->DiskCacheStorage(info,
9703 getter_AddRefs(cacheStorage));
9704 }
9705
9706 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
9707 rv = cacheStorage->AsyncDoomURI(aURI, ""_ns, nullptr);
9708 }
9709
9710 LOG(("DoInvalidateCacheEntry [channel=%p key=%s rv=%d]", this, key.get(),do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "DoInvalidateCacheEntry [channel=%p key=%s rv=%d]", this, key
.get(), int(rv)); } } while (0)
9711 int(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "DoInvalidateCacheEntry [channel=%p key=%s rv=%d]", this, key
.get(), int(rv)); } } while (0)
;
9712}
9713
9714void nsHttpChannel::AsyncOnExamineCachedResponse() {
9715 gHttpHandler->OnExamineCachedResponse(this);
9716}
9717
9718void nsHttpChannel::UpdateAggregateCallbacks() {
9719 if (!mTransaction) {
9720 return;
9721 }
9722 nsCOMPtr<nsIInterfaceRequestor> callbacks;
9723 NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
9724 GetCurrentSerialEventTarget(),
9725 getter_AddRefs(callbacks));
9726 mTransaction->SetSecurityCallbacks(callbacks);
9727}
9728
9729NS_IMETHODIMPnsresult
9730nsHttpChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) {
9731 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Wrong thread." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9731); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Wrong thread." ")"); do { *((volatile int*)__null) = 9731
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
9732
9733 nsresult rv = HttpBaseChannel::SetLoadGroup(aLoadGroup);
9734 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
9735 UpdateAggregateCallbacks();
9736 }
9737 return rv;
9738}
9739
9740NS_IMETHODIMPnsresult
9741nsHttpChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks) {
9742 MOZ_ASSERT(NS_IsMainThread(), "Wrong thread.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Wrong thread." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9742); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Wrong thread." ")"); do { *((volatile int*)__null) = 9742
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
9743
9744 nsresult rv = HttpBaseChannel::SetNotificationCallbacks(aCallbacks);
9745 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
9746 UpdateAggregateCallbacks();
9747 }
9748 return rv;
9749}
9750
9751bool nsHttpChannel::AwaitingCacheCallbacks() {
9752 return LoadWaitForCacheEntry() != 0;
9753}
9754
9755void nsHttpChannel::SetPushedStreamTransactionAndId(
9756 HttpTransactionShell* aTransWithPushedStream, uint32_t aPushedStreamId) {
9757 MOZ_ASSERT(!mTransWithPushedStream)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mTransWithPushedStream)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mTransWithPushedStream))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!mTransWithPushedStream"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9757); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mTransWithPushedStream"
")"); do { *((volatile int*)__null) = 9757; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9758 LOG(("nsHttpChannel::SetPushedStreamTransaction [this=%p] trans=%p", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetPushedStreamTransaction [this=%p] trans=%p"
, this, aTransWithPushedStream); } } while (0)
9759 aTransWithPushedStream))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetPushedStreamTransaction [this=%p] trans=%p"
, this, aTransWithPushedStream); } } while (0)
;
9760
9761 mTransWithPushedStream = aTransWithPushedStream;
9762 mPushedStreamId = aPushedStreamId;
9763}
9764
9765nsresult nsHttpChannel::OnPush(uint32_t aPushedStreamId, const nsACString& aUrl,
9766 const nsACString& aRequestString,
9767 HttpTransactionShell* aTransaction) {
9768 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9768); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 9768; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9769 MOZ_ASSERT(aTransaction)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aTransaction)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aTransaction))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aTransaction", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9769); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTransaction"
")"); do { *((volatile int*)__null) = 9769; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9770 LOG(("nsHttpChannel::OnPush [this=%p, trans=%p]\n", this, aTransaction))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnPush [this=%p, trans=%p]\n", this, aTransaction
); } } while (0)
;
9771
9772 MOZ_ASSERT(mCaps & NS_HTTP_ONPUSH_LISTENER)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCaps & (1 << 9))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCaps & (1 << 9)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("mCaps & (1 << 9)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9772); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCaps & (1 << 9)"
")"); do { *((volatile int*)__null) = 9772; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9773 nsCOMPtr<nsIHttpPushListener> pushListener;
9774 NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
9775 NS_GET_IID(nsIHttpPushListener)(nsIHttpPushListener::COMTypeInfo<nsIHttpPushListener, void
>::kIID)
,
9776 getter_AddRefs(pushListener));
9777
9778 if (!pushListener) {
9779 LOG(do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnPush [this=%p] notification callbacks do not "
"implement nsIHttpPushListener\n", this); } } while (0)
9780 ("nsHttpChannel::OnPush [this=%p] notification callbacks do not "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnPush [this=%p] notification callbacks do not "
"implement nsIHttpPushListener\n", this); } } while (0)
9781 "implement nsIHttpPushListener\n",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnPush [this=%p] notification callbacks do not "
"implement nsIHttpPushListener\n", this); } } while (0)
9782 this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnPush [this=%p] notification callbacks do not "
"implement nsIHttpPushListener\n", this); } } while (0)
;
9783 return NS_ERROR_NOT_AVAILABLE;
9784 }
9785
9786 nsCOMPtr<nsIURI> pushResource;
9787 nsresult rv;
9788
9789 // Create a Channel for the Push Resource
9790 rv = NS_NewURI(getter_AddRefs(pushResource), aUrl);
9791 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
9792 return NS_ERROR_FAILURE;
9793 }
9794
9795 nsCOMPtr<nsIIOService> ioService;
9796 rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
9797 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9797); return rv; } } while (false)
;
9798
9799 nsCOMPtr<nsIChannel> pushChannel;
9800 rv = NS_NewChannelInternal(getter_AddRefs(pushChannel), pushResource,
9801 mLoadInfo,
9802 nullptr, // PerformanceStorage
9803 nullptr, // aLoadGroup
9804 nullptr, // aCallbacks
9805 nsIRequest::LOAD_NORMAL, ioService);
9806 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9806); return rv; } } while (false)
;
9807
9808 nsCOMPtr<nsIHttpChannel> pushHttpChannel = do_QueryInterface(pushChannel);
9809 MOZ_ASSERT(pushHttpChannel)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pushHttpChannel)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pushHttpChannel))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("pushHttpChannel"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pushHttpChannel"
")"); do { *((volatile int*)__null) = 9809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9810 if (!pushHttpChannel) {
9811 return NS_ERROR_UNEXPECTED;
9812 }
9813
9814 RefPtr<nsHttpChannel> channel;
9815 CallQueryInterface(pushHttpChannel, channel.StartAssignment());
9816 MOZ_ASSERT(channel)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(channel)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(channel))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("channel", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9816); AnnotateMozCrashReason("MOZ_ASSERT" "(" "channel" ")"
); do { *((volatile int*)__null) = 9816; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9817 if (!channel) {
9818 return NS_ERROR_UNEXPECTED;
9819 }
9820
9821 // new channel needs mrqeuesthead and headers from pushedStream
9822 channel->mRequestHead.ParseHeaderSet(aRequestString.BeginReading());
9823 channel->mLoadGroup = mLoadGroup;
9824 channel->mLoadInfo = mLoadInfo;
9825 channel->mCallbacks = mCallbacks;
9826
9827 // Link the trans with pushed stream and the new channel and call listener
9828 channel->SetPushedStreamTransactionAndId(aTransaction, aPushedStreamId);
9829 rv = pushListener->OnPush(this, pushHttpChannel);
9830 return rv;
9831}
9832
9833// static
9834bool nsHttpChannel::IsRedirectStatus(uint32_t status) {
9835 // 305 disabled as a security measure (see bug 187996).
9836 return status == 301 || status == 302 || status == 303 || status == 307 ||
9837 status == 308;
9838}
9839
9840void nsHttpChannel::SetCouldBeSynthesized() {
9841 MOZ_ASSERT(!BypassServiceWorker())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!BypassServiceWorker())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!BypassServiceWorker()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!BypassServiceWorker()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9841); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
")"); do { *((volatile int*)__null) = 9841; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9842 StoreResponseCouldBeSynthesized(true);
9843}
9844
9845NS_IMETHODIMPnsresult
9846nsHttpChannel::OnPreflightSucceeded() {
9847 MOZ_ASSERT(LoadRequireCORSPreflight(), "Why did a preflight happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadRequireCORSPreflight())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadRequireCORSPreflight()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("LoadRequireCORSPreflight()"
" (" "Why did a preflight happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9847); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadRequireCORSPreflight()"
") (" "Why did a preflight happen?" ")"); do { *((volatile int
*)__null) = 9847; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9848 StoreIsCorsPreflightDone(1);
9849 mPreflightChannel = nullptr;
9850
9851 return ContinueConnect();
9852}
9853
9854NS_IMETHODIMPnsresult
9855nsHttpChannel::OnPreflightFailed(nsresult aError) {
9856 MOZ_ASSERT(LoadRequireCORSPreflight(), "Why did a preflight happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadRequireCORSPreflight())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadRequireCORSPreflight()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("LoadRequireCORSPreflight()"
" (" "Why did a preflight happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9856); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadRequireCORSPreflight()"
") (" "Why did a preflight happen?" ")"); do { *((volatile int
*)__null) = 9856; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9857 StoreIsCorsPreflightDone(1);
9858 mPreflightChannel = nullptr;
9859
9860 CloseCacheEntry(false);
9861 Unused << AsyncAbort(aError);
9862 return NS_OK;
9863}
9864
9865nsresult nsHttpChannel::CallOrWaitForResume(
9866 const std::function<nsresult(nsHttpChannel*)>& aFunc) {
9867 if (mCanceled) {
9868 MOZ_ASSERT(NS_FAILED(mStatus))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus))
, 0))))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus))
, 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0)))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0)))"
")"); do { *((volatile int*)__null) = 9868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9869 return mStatus;
9870 }
9871
9872 if (mSuspendCount) {
9873 LOG(("Waiting until resume [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Waiting until resume [this=%p]\n", this); } } while (0)
;
9874 MOZ_ASSERT(!mCallOnResume)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mCallOnResume)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mCallOnResume))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mCallOnResume"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9874); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
")"); do { *((volatile int*)__null) = 9874; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9875 mCallOnResume = aFunc;
9876 return NS_OK;
9877 }
9878
9879 return aFunc(this);
9880}
9881
9882// This is loosely based on:
9883// https://fetch.spec.whatwg.org/#serializing-a-request-origin
9884static bool HasNullRequestOrigin(nsHttpChannel* aChannel, nsIURI* aURI,
9885 bool isAddonRequest) {
9886 // Step 1. If request has a redirect-tainted origin, then return "null".
9887 if (aChannel->HasRedirectTaintedOrigin()) {
9888 if (StaticPrefs::network_http_origin_redirectTainted()) {
9889 return true;
9890 }
9891 }
9892
9893 // Non-standard: Only allow HTTP and HTTPS origins.
9894 if (!ReferrerInfo::IsReferrerSchemeAllowed(aURI)) {
9895 // And moz-extension: for add-on initiated requests.
9896 if (!aURI->SchemeIs("moz-extension") || !isAddonRequest) {
9897 return true;
9898 }
9899 }
9900
9901 // Non-standard: Hide onion URLs.
9902 if (StaticPrefs::network_http_referer_hideOnionSource()) {
9903 nsAutoCString host;
9904 if (NS_SUCCEEDED(aURI->GetAsciiHost(host))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aURI->GetAsciiHost
(host))), 1)))
&&
9905 StringEndsWith(host, ".onion"_ns)) {
9906 return ReferrerInfo::IsCrossOriginRequest(aChannel);
9907 }
9908 }
9909
9910 // Step 2. Return request’s origin, serialized.
9911 return false;
9912}
9913
9914// Step 8.12. of HTTP-network-or-cache fetch
9915//
9916// https://fetch.spec.whatwg.org/#append-a-request-origin-header
9917void nsHttpChannel::SetOriginHeader() {
9918 auto* triggeringPrincipal =
9919 BasePrincipal::Cast(mLoadInfo->TriggeringPrincipal());
9920
9921 if (triggeringPrincipal->IsSystemPrincipal()) {
9922 // We can't infer an Origin header from the system principal,
9923 // this means system requests use whatever Origin header was specified.
9924 return;
9925 }
9926 bool isAddonRequest = triggeringPrincipal->AddonPolicy() ||
9927 triggeringPrincipal->ContentScriptAddonPolicy();
9928
9929 // Non-standard: Handle already existing Origin header.
9930 nsAutoCString existingHeader;
9931 Unused << mRequestHead.GetHeader(nsHttp::Origin, existingHeader);
9932 if (!existingHeader.IsEmpty()) {
9933 LOG(("nsHttpChannel::SetOriginHeader Origin header already present"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetOriginHeader Origin header already present"
); } } while (0)
;
9934 auto const shouldNullifyOriginHeader =
9935 [&existingHeader, isAddonRequest](nsHttpChannel* aChannel) {
9936 nsCOMPtr<nsIURI> uri;
9937 nsresult rv = NS_NewURI(getter_AddRefs(uri), existingHeader);
9938 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
9939 return false;
9940 }
9941
9942 if (HasNullRequestOrigin(aChannel, uri, isAddonRequest)) {
9943 return true;
9944 }
9945
9946 nsCOMPtr<nsILoadInfo> info = aChannel->LoadInfo();
9947 if (info->GetTainting() == mozilla::LoadTainting::CORS) {
9948 return false;
9949 }
9950
9951 return ReferrerInfo::ShouldSetNullOriginHeader(aChannel, uri);
9952 };
9953
9954 if (!existingHeader.EqualsLiteral("null") &&
9955 shouldNullifyOriginHeader(this)) {
9956 LOG(("nsHttpChannel::SetOriginHeader null Origin by Referrer-Policy"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::SetOriginHeader null Origin by Referrer-Policy"
); } } while (0)
;
9957 MOZ_ALWAYS_SUCCEEDS(do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mRequestHead.SetHeader(nsHttp::Origin, "null"_ns, false ))),
1)))), 1))) { } else { do { static_assert( mozilla::detail::
AssertionConditionType<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, \"null\"_ns, false ))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9958); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, \"null\"_ns, false ))"
")"); do { *((volatile int*)__null) = 9958; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
9958 mRequestHead.SetHeader(nsHttp::Origin, "null"_ns, false /* merge */))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mRequestHead.SetHeader(nsHttp::Origin, "null"_ns, false ))),
1)))), 1))) { } else { do { static_assert( mozilla::detail::
AssertionConditionType<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, \"null\"_ns, false ))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9958); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, \"null\"_ns, false ))"
")"); do { *((volatile int*)__null) = 9958; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
9959 }
9960 return;
9961 }
9962
9963 if (StaticPrefs::network_http_sendOriginHeader() == 0) {
9964 // Custom user setting: 0 means never send Origin header.
9965 return;
9966 }
9967
9968 // Step 1. Let serializedOrigin be the result of byte-serializing a request
9969 // origin with request.
9970 nsAutoCString serializedOrigin;
9971 nsCOMPtr<nsIURI> uri;
9972 {
9973 if (NS_FAILED(triggeringPrincipal->GetURI(getter_AddRefs(uri)))((bool)(__builtin_expect(!!(NS_FAILED_impl(triggeringPrincipal
->GetURI(getter_AddRefs(uri)))), 0)))
) {
9974 return;
9975 }
9976
9977 if (!uri) {
9978 if (isAddonRequest) {
9979 // For add-on compatibility prefer sending no header at all
9980 // instead of `Origin: null`.
9981 return;
9982 }
9983
9984 // Otherwise use "null" when the triggeringPrincipal's URI is nullptr.
9985 serializedOrigin.AssignLiteral("null");
9986 } else if (HasNullRequestOrigin(this, uri, isAddonRequest)) {
9987 serializedOrigin.AssignLiteral("null");
9988 } else {
9989 nsContentUtils::GetWebExposedOriginSerialization(uri, serializedOrigin);
9990 }
9991 }
9992
9993 // Step 2. If request’s response tainting is "cors" or request’s mode is
9994 // "websocket", then append (`Origin`, serializedOrigin) to request’s header
9995 // list.
9996 //
9997 // Note: We don't handle "websocket" here (yet?).
9998 if (mLoadInfo->GetTainting() == mozilla::LoadTainting::CORS) {
9999 MOZ_ALWAYS_SUCCEEDS(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin,do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false
))), 1)))), 1))) { } else { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10000); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
")"); do { *((volatile int*)__null) = 10000; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
10000 false /* merge */))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false
))), 1)))), 1))) { } else { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10000); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
")"); do { *((volatile int*)__null) = 10000; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
;
10001 return;
10002 }
10003
10004 // Step 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then:
10005 if (mRequestHead.IsGet() || mRequestHead.IsHead()) {
10006 return;
10007 }
10008
10009 if (!serializedOrigin.EqualsLiteral("null")) {
10010 // Step 3.1. (Implemented by ReferrerInfo::ShouldSetNullOriginHeader)
10011 if (ReferrerInfo::ShouldSetNullOriginHeader(this, uri)) {
10012 serializedOrigin.AssignLiteral("null");
10013 } else if (StaticPrefs::network_http_sendOriginHeader() == 1) {
10014 // Non-standard: Restrict Origin to same-origin loads if requested by user
10015 nsAutoCString currentOrigin;
10016 nsContentUtils::GetWebExposedOriginSerialization(mURI, currentOrigin);
10017 if (!serializedOrigin.EqualsIgnoreCase(currentOrigin.get())) {
10018 // Origin header suppressed by user setting.
10019 serializedOrigin.AssignLiteral("null");
10020 }
10021 }
10022 }
10023
10024 // Step 3.2. Append (`Origin`, serializedOrigin) to request’s header list.
10025 MOZ_ALWAYS_SUCCEEDS(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin,do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false
))), 1)))), 1))) { } else { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10026); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
")"); do { *((volatile int*)__null) = 10026; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
10026 false /* merge */))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false
))), 1)))), 1))) { } else { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10026); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
")"); do { *((volatile int*)__null) = 10026; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
;
10027}
10028
10029void nsHttpChannel::SetDoNotTrack() {
10030 /**
10031 * 'DoNotTrack' header should be added if 'privacy.donottrackheader.enabled'
10032 * is true or tracking protection is enabled. See bug 1258033.
10033 */
10034 nsCOMPtr<nsILoadContext> loadContext;
10035 NS_QueryNotificationCallbacks(this, loadContext);
10036
10037 if ((loadContext && loadContext->UseTrackingProtection()) ||
10038 StaticPrefs::privacy_donottrackheader_enabled()) {
10039 DebugOnly<nsresult> rv =
10040 mRequestHead.SetHeader(nsHttp::DoNotTrack, "1"_ns, false);
10041 MOZ_ASSERT(NS_SUCCEEDED(rv))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
)))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)
))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10041); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 10041; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10042 }
10043}
10044
10045void nsHttpChannel::SetGlobalPrivacyControl() {
10046 MOZ_ASSERT(NS_IsMainThread(), "Must be called on the main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Must be called on the main thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10046); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Must be called on the main thread" ")"); do { *((volatile
int*)__null) = 10046; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10047
10048 if (StaticPrefs::privacy_globalprivacycontrol_functionality_enabled() &&
10049 (StaticPrefs::privacy_globalprivacycontrol_enabled() ||
10050 (StaticPrefs::privacy_globalprivacycontrol_pbmode_enabled() &&
10051 NS_UsePrivateBrowsing(this)))) {
10052 // Send the header with a value of 1 to indicate opting-out
10053 DebugOnly<nsresult> rv =
10054 mRequestHead.SetHeader(nsHttp::GlobalPrivacyControl, "1"_ns, false);
10055 }
10056}
10057
10058void nsHttpChannel::ReportRcwnStats(bool isFromNet) {
10059 if (!StaticPrefs::network_http_rcwn_enabled()) {
10060 return;
10061 }
10062
10063 if (isFromNet) {
10064 if (mRaceCacheWithNetwork) {
10065 gIOService->IncrementNetWonRequestNumber();
10066 Telemetry::Accumulate(
10067 Telemetry::NETWORK_RACE_CACHE_BANDWIDTH_RACE_NETWORK_WIN,
10068 mTransferSize);
10069 if (mRaceDelay) {
10070 AccumulateCategorical(
10071 Telemetry::LABELS_NETWORK_RACE_CACHE_WITH_NETWORK_USAGE_2::
10072 NetworkDelayedRace);
10073 } else {
10074 AccumulateCategorical(
10075 Telemetry::LABELS_NETWORK_RACE_CACHE_WITH_NETWORK_USAGE_2::
10076 NetworkRace);
10077 }
10078 } else {
10079 Telemetry::Accumulate(Telemetry::NETWORK_RACE_CACHE_BANDWIDTH_NOT_RACE,
10080 mTransferSize);
10081 AccumulateCategorical(
10082 Telemetry::LABELS_NETWORK_RACE_CACHE_WITH_NETWORK_USAGE_2::
10083 NetworkNoRace);
10084 }
10085 } else {
10086 if (mRaceCacheWithNetwork || mRaceDelay) {
10087 gIOService->IncrementCacheWonRequestNumber();
10088 Telemetry::Accumulate(
10089 Telemetry::NETWORK_RACE_CACHE_BANDWIDTH_RACE_CACHE_WIN,
10090 mTransferSize);
10091 if (mRaceDelay) {
10092 AccumulateCategorical(
10093 Telemetry::LABELS_NETWORK_RACE_CACHE_WITH_NETWORK_USAGE_2::
10094 CacheDelayedRace);
10095 } else {
10096 AccumulateCategorical(
10097 Telemetry::LABELS_NETWORK_RACE_CACHE_WITH_NETWORK_USAGE_2::
10098 CacheRace);
10099 }
10100 } else {
10101 Telemetry::Accumulate(Telemetry::NETWORK_RACE_CACHE_BANDWIDTH_NOT_RACE,
10102 mTransferSize);
10103 AccumulateCategorical(
10104 Telemetry::LABELS_NETWORK_RACE_CACHE_WITH_NETWORK_USAGE_2::
10105 CacheNoRace);
10106 }
10107 }
10108
10109 gIOService->IncrementRequestNumber();
10110}
10111
10112static const size_t kPositiveBucketNumbers = 34;
10113static const int64_t kPositiveBucketLevels[kPositiveBucketNumbers] = {
10114 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200,
10115 300, 400, 500, 600, 700, 800, 900, 1000, 2000, 3000, 4000, 5000,
10116 6000, 7000, 8000, 9000, 10000, 20000, 30000, 40000, 50000, 60000};
10117
10118/**
10119 * For space efficiency, we collect finer resolution for small difference
10120 * between net and cache time, coarser for larger.
10121 * Bucket #40 for a tie.
10122 * #41 to #50 indicates cache wins by 1ms to 100ms, split equally.
10123 * #51 to #59 indicates cache wins by 101ms to 1000ms.
10124 * #60 to #68 indicates cache wins by 1s to 10s.
10125 * #69 to #73 indicates cache wins by 11s to 60s.
10126 * #74 indicates cache wins by more than 1 minute.
10127 *
10128 * #39 to #30 indicates network wins by 1ms to 100ms, split equally.
10129 * #29 to #21 indicates network wins by 101ms to 1000ms.
10130 * #20 to #12 indicates network wins by 1s to 10s.
10131 * #11 to #7 indicates network wins by 11s to 60s.
10132 * #6 indicates network wins by more than 1 minute.
10133 *
10134 * Other bucket numbers are reserved.
10135 */
10136inline int64_t nsHttpChannel::ComputeTelemetryBucketNumber(
10137 int64_t difftime_ms) {
10138 int64_t absBucketIndex =
10139 std::lower_bound(kPositiveBucketLevels,
10140 kPositiveBucketLevels + kPositiveBucketNumbers,
10141 static_cast<int64_t>(mozilla::Abs(difftime_ms))) -
10142 kPositiveBucketLevels;
10143
10144 return difftime_ms >= 0 ? 40 + absBucketIndex : 40 - absBucketIndex;
10145}
10146
10147void nsHttpChannel::ReportNetVSCacheTelemetry() {
10148 nsresult rv;
10149 if (!mCacheEntry) {
10150 return;
10151 }
10152
10153 // We only report telemetry if the entry is persistent (on disk)
10154 bool persistent;
10155 rv = mCacheEntry->GetPersistent(&persistent);
10156 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !persistent) {
10157 return;
10158 }
10159
10160 uint64_t onStartNetTime = 0;
10161 if (NS_FAILED(mCacheEntry->GetOnStartTime(&onStartNetTime))((bool)(__builtin_expect(!!(NS_FAILED_impl(mCacheEntry->GetOnStartTime
(&onStartNetTime))), 0)))
) {
10162 return;
10163 }
10164
10165 uint64_t onStopNetTime = 0;
10166 if (NS_FAILED(mCacheEntry->GetOnStopTime(&onStopNetTime))((bool)(__builtin_expect(!!(NS_FAILED_impl(mCacheEntry->GetOnStopTime
(&onStopNetTime))), 0)))
) {
10167 return;
10168 }
10169
10170 uint64_t onStartCacheTime =
10171 (mOnStartRequestTimestamp - mAsyncOpenTime).ToMilliseconds();
10172 int64_t onStartDiff = onStartNetTime - onStartCacheTime;
10173 onStartDiff = ComputeTelemetryBucketNumber(onStartDiff);
10174
10175 uint64_t onStopCacheTime = (mCacheReadEnd - mAsyncOpenTime).ToMilliseconds();
10176 int64_t onStopDiff = onStopNetTime - onStopCacheTime;
10177 onStopDiff = ComputeTelemetryBucketNumber(onStopDiff);
10178
10179 if (mDidReval) {
10180 Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTART_REVALIDATED_V2,
10181 onStartDiff);
10182 Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_REVALIDATED_V2,
10183 onStopDiff);
10184 } else {
10185 Telemetry::Accumulate(
10186 Telemetry::HTTP_NET_VS_CACHE_ONSTART_NOTREVALIDATED_V2, onStartDiff);
10187 Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_NOTREVALIDATED_V2,
10188 onStopDiff);
10189 }
10190
10191 if (mDidReval) {
10192 // We don't report revalidated probes as the data would be skewed.
10193 return;
10194 }
10195
10196 if (mCacheOpenWithPriority) {
10197 if (mCacheQueueSizeWhenOpen < 5) {
10198 Telemetry::Accumulate(
10199 Telemetry::HTTP_NET_VS_CACHE_ONSTART_QSMALL_HIGHPRI_V2, onStartDiff);
10200 Telemetry::Accumulate(
10201 Telemetry::HTTP_NET_VS_CACHE_ONSTOP_QSMALL_HIGHPRI_V2, onStopDiff);
10202 } else if (mCacheQueueSizeWhenOpen < 10) {
10203 Telemetry::Accumulate(
10204 Telemetry::HTTP_NET_VS_CACHE_ONSTART_QMED_HIGHPRI_V2, onStartDiff);
10205 Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_QMED_HIGHPRI_V2,
10206 onStopDiff);
10207 } else {
10208 Telemetry::Accumulate(
10209 Telemetry::HTTP_NET_VS_CACHE_ONSTART_QBIG_HIGHPRI_V2, onStartDiff);
10210 Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_QBIG_HIGHPRI_V2,
10211 onStopDiff);
10212 }
10213 } else { // The limits are higher for normal priority cache queues
10214 if (mCacheQueueSizeWhenOpen < 10) {
10215 Telemetry::Accumulate(
10216 Telemetry::HTTP_NET_VS_CACHE_ONSTART_QSMALL_NORMALPRI_V2,
10217 onStartDiff);
10218 Telemetry::Accumulate(
10219 Telemetry::HTTP_NET_VS_CACHE_ONSTOP_QSMALL_NORMALPRI_V2, onStopDiff);
10220 } else if (mCacheQueueSizeWhenOpen < 50) {
10221 Telemetry::Accumulate(
10222 Telemetry::HTTP_NET_VS_CACHE_ONSTART_QMED_NORMALPRI_V2, onStartDiff);
10223 Telemetry::Accumulate(
10224 Telemetry::HTTP_NET_VS_CACHE_ONSTOP_QMED_NORMALPRI_V2, onStopDiff);
10225 } else {
10226 Telemetry::Accumulate(
10227 Telemetry::HTTP_NET_VS_CACHE_ONSTART_QBIG_NORMALPRI_V2, onStartDiff);
10228 Telemetry::Accumulate(
10229 Telemetry::HTTP_NET_VS_CACHE_ONSTOP_QBIG_NORMALPRI_V2, onStopDiff);
10230 }
10231 }
10232
10233 uint32_t diskStorageSizeK = 0;
10234 rv = mCacheEntry->GetDiskStorageSizeInKB(&diskStorageSizeK);
10235 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10236 return;
10237 }
10238
10239 // No significant difference was observed between different sizes for
10240 // |onStartDiff|
10241 if (diskStorageSizeK < 256) {
10242 Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_SMALL_V2,
10243 onStopDiff);
10244 } else {
10245 Telemetry::Accumulate(Telemetry::HTTP_NET_VS_CACHE_ONSTOP_LARGE_V2,
10246 onStopDiff);
10247 }
10248}
10249
10250NS_IMETHODIMPnsresult
10251nsHttpChannel::Test_delayCacheEntryOpeningBy(int32_t aTimeout) {
10252 LOG(("nsHttpChannel::Test_delayCacheEntryOpeningBy this=%p timeout=%d", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::Test_delayCacheEntryOpeningBy this=%p timeout=%d"
, this, aTimeout); } } while (0)
10253 aTimeout))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::Test_delayCacheEntryOpeningBy this=%p timeout=%d"
, this, aTimeout); } } while (0)
;
10254 MOZ_ASSERT(NS_IsMainThread(), "Must be called on the main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Must be called on the main thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10254); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Must be called on the main thread" ")"); do { *((volatile
int*)__null) = 10254; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10255 mRaceCacheWithNetwork = true;
10256 mCacheOpenDelay = aTimeout;
10257 if (mCacheOpenTimer) {
10258 mCacheOpenTimer->SetDelay(aTimeout);
10259 }
10260 return NS_OK;
10261}
10262
10263NS_IMETHODIMPnsresult
10264nsHttpChannel::Test_triggerDelayedOpenCacheEntry() {
10265 LOG(("nsHttpChannel::Test_triggerDelayedOpenCacheEntry this=%p", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::Test_triggerDelayedOpenCacheEntry this=%p",
this); } } while (0)
;
10266 MOZ_ASSERT(NS_IsMainThread(), "Must be called on the main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Must be called on the main thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10266); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Must be called on the main thread" ")"); do { *((volatile
int*)__null) = 10266; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10267 nsresult rv;
10268 if (!mCacheOpenDelay) {
10269 // No delay was set.
10270 return NS_ERROR_NOT_AVAILABLE;
10271 }
10272 if (!mCacheOpenFunc) {
10273 // There should be a runnable.
10274 return NS_ERROR_FAILURE;
10275 }
10276 if (mCacheOpenTimer) {
10277 rv = mCacheOpenTimer->Cancel();
10278 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10279 return rv;
10280 }
10281 mCacheOpenTimer = nullptr;
10282 }
10283 mCacheOpenDelay = 0;
10284 // Avoid re-entrancy issues by nulling our mCacheOpenFunc before calling it.
10285 std::function<void(nsHttpChannel*)> cacheOpenFunc = nullptr;
10286 std::swap(cacheOpenFunc, mCacheOpenFunc);
10287 cacheOpenFunc(this);
10288
10289 return NS_OK;
10290}
10291
10292nsresult nsHttpChannel::TriggerNetworkWithDelay(uint32_t aDelay) {
10293 MOZ_ASSERT(NS_IsMainThread(), "Must be called on the main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Must be called on the main thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10293); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Must be called on the main thread" ")"); do { *((volatile
int*)__null) = 10293; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10294
10295 LOG(("nsHttpChannel::TriggerNetworkWithDelay [this=%p, delay=%u]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::TriggerNetworkWithDelay [this=%p, delay=%u]\n"
, this, aDelay); } } while (0)
10296 aDelay))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::TriggerNetworkWithDelay [this=%p, delay=%u]\n"
, this, aDelay); } } while (0)
;
10297
10298 if (mCanceled) {
10299 LOG((" channel was canceled.\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " channel was canceled.\n"); } } while (0)
;
10300 return mStatus;
10301 }
10302
10303 // If a network request has already gone out, there is no point in
10304 // doing this again.
10305 if (mNetworkTriggered) {
10306 LOG((" network already triggered. Returning.\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " network already triggered. Returning.\n"); } } while (0)
;
10307 return NS_OK;
10308 }
10309
10310 if (mNetworkTriggerDelay) {
10311 aDelay = mNetworkTriggerDelay;
10312 }
10313
10314 if (!aDelay) {
10315 // We cannot call TriggerNetwork() directly here, because it would
10316 // cause performance regression in tp6 tests, see bug 1398847.
10317 return NS_DispatchToMainThread(
10318 NewRunnableMethod("net::nsHttpChannel::TriggerNetworkWithDelay", this,
10319 &nsHttpChannel::TriggerNetwork),
10320 NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL);
10321 }
10322
10323 MOZ_ASSERT(!mNetworkTriggerTimer)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mNetworkTriggerTimer)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mNetworkTriggerTimer))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!mNetworkTriggerTimer"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10323); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mNetworkTriggerTimer"
")"); do { *((volatile int*)__null) = 10323; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10324 mNetworkTriggerTimer = NS_NewTimer();
10325 auto callback = MakeRefPtr<TimerCallback>(this);
10326 LOG(("Creating new networkTriggertimer for delay"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Creating new networkTriggertimer for delay"); } } while (0
)
;
10327 mNetworkTriggerTimer->InitWithCallback(callback, aDelay,
10328 nsITimer::TYPE_ONE_SHOT);
10329 return NS_OK;
10330}
10331
10332nsresult nsHttpChannel::TriggerNetwork() {
10333 MOZ_ASSERT(NS_IsMainThread(), "Must be called on the main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Must be called on the main thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10333); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Must be called on the main thread" ")"); do { *((volatile
int*)__null) = 10333; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10334
10335 LOG(("nsHttpChannel::TriggerNetwork [this=%p]\n", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::TriggerNetwork [this=%p]\n", this); } } while
(0)
;
10336
10337 if (mCanceled) {
10338 LOG((" channel was canceled.\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " channel was canceled.\n"); } } while (0)
;
10339 return mStatus;
10340 }
10341
10342 // If a network request has already gone out, there is no point in
10343 // doing this again.
10344 if (mNetworkTriggered) {
10345 LOG((" network already triggered. Returning.\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " network already triggered. Returning.\n"); } } while (0)
;
10346 return NS_OK;
10347 }
10348
10349 mNetworkTriggered = true;
10350 if (mNetworkTriggerTimer) {
10351 mNetworkTriggerTimer->Cancel();
10352 mNetworkTriggerTimer = nullptr;
10353 }
10354
10355 // If we are waiting for a proxy request, that means we can't trigger
10356 // the next step just yet. We need for mConnectionInfo to be non-null
10357 // before we call ContinueConnect. OnProxyAvailable will trigger
10358 // BeginConnect, and Connect will call ContinueConnect even if it's
10359 // for the cache callbacks.
10360 if (mProxyRequest) {
10361 LOG((" proxy request in progress. Delaying network trigger.\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " proxy request in progress. Delaying network trigger.\n")
; } } while (0)
;
10362 mWaitingForProxy = true;
10363 return NS_OK;
10364 }
10365
10366 // If |mCacheOpenFunc| is assigned, we're delaying opening the entry to
10367 // simulate racing. Although cache entry opening hasn't started yet, we're
10368 // actually racing, so we must set mRaceCacheWithNetwork to true now.
10369 mRaceCacheWithNetwork =
10370 AwaitingCacheCallbacks() &&
10371 (mCacheOpenFunc || StaticPrefs::network_http_rcwn_enabled());
10372
10373 LOG((" triggering network rcwn=%d\n", bool(mRaceCacheWithNetwork)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " triggering network rcwn=%d\n", bool(mRaceCacheWithNetwork
)); } } while (0)
;
10374 return ContinueConnect();
10375}
10376
10377void nsHttpChannel::MaybeRaceCacheWithNetwork() {
10378 nsresult rv;
10379
10380 nsCOMPtr<nsINetworkLinkService> netLinkSvc;
10381 netLinkSvc = do_GetService(NS_NETWORK_LINK_SERVICE_CONTRACTID"@mozilla.org/network/network-link-service;1", &rv);
10382 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10383 return;
10384 }
10385
10386 uint32_t linkType;
10387 rv = netLinkSvc->GetLinkType(&linkType);
10388 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10389 return;
10390 }
10391
10392 if (!(linkType == nsINetworkLinkService::LINK_TYPE_ETHERNET ||
10393#ifndef MOZ_WIDGET_ANDROID
10394 // On Android we don't assume an unknown link type is unmetered
10395 linkType == nsINetworkLinkService::LINK_TYPE_UNKNOWN ||
10396#endif
10397 linkType == nsINetworkLinkService::LINK_TYPE_USB ||
10398 linkType == nsINetworkLinkService::LINK_TYPE_WIFI)) {
10399 return;
10400 }
10401
10402 // Don't trigger the network if the load flags say so.
10403 if (mLoadFlags & (LOAD_ONLY_FROM_CACHE | LOAD_NO_NETWORK_IO)) {
10404 return;
10405 }
10406
10407 // We must not race if the channel has a failure status code.
10408 if (NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0)))) {
10409 return;
10410 }
10411
10412 // If a CORS Preflight is required we must not race.
10413 if (LoadRequireCORSPreflight() && !LoadIsCorsPreflightDone()) {
10414 return;
10415 }
10416
10417 if (CacheFileUtils::CachePerfStats::IsCacheSlow()) {
10418 // If the cache is slow, trigger the network request immediately.
10419 mRaceDelay = 0;
10420 } else {
10421 // Give cache a headstart of 3 times the average cache entry open time.
10422 mRaceDelay = CacheFileUtils::CachePerfStats::GetAverage(
10423 CacheFileUtils::CachePerfStats::ENTRY_OPEN, true) *
10424 3;
10425 // We use microseconds in CachePerfStats but we need milliseconds
10426 // for TriggerNetwork.
10427 mRaceDelay /= 1000;
10428 }
10429
10430 mRaceDelay = clamped<uint32_t>(
10431 mRaceDelay, StaticPrefs::network_http_rcwn_min_wait_before_racing_ms(),
10432 StaticPrefs::network_http_rcwn_max_wait_before_racing_ms());
10433
10434 MOZ_ASSERT(StaticPrefs::network_http_rcwn_enabled() || mNetworkTriggerDelay,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(StaticPrefs::network_http_rcwn_enabled() || mNetworkTriggerDelay
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(StaticPrefs::network_http_rcwn_enabled() || mNetworkTriggerDelay
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"StaticPrefs::network_http_rcwn_enabled() || mNetworkTriggerDelay"
" (" "The pref must be turned on." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10435); AnnotateMozCrashReason("MOZ_ASSERT" "(" "StaticPrefs::network_http_rcwn_enabled() || mNetworkTriggerDelay"
") (" "The pref must be turned on." ")"); do { *((volatile int
*)__null) = 10435; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
10435 "The pref must be turned on.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(StaticPrefs::network_http_rcwn_enabled() || mNetworkTriggerDelay
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(StaticPrefs::network_http_rcwn_enabled() || mNetworkTriggerDelay
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"StaticPrefs::network_http_rcwn_enabled() || mNetworkTriggerDelay"
" (" "The pref must be turned on." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10435); AnnotateMozCrashReason("MOZ_ASSERT" "(" "StaticPrefs::network_http_rcwn_enabled() || mNetworkTriggerDelay"
") (" "The pref must be turned on." ")"); do { *((volatile int
*)__null) = 10435; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10436 LOG(("nsHttpChannel::MaybeRaceCacheWithNetwork [this=%p, delay=%u]\n", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeRaceCacheWithNetwork [this=%p, delay=%u]\n"
, this, mRaceDelay); } } while (0)
10437 mRaceDelay))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::MaybeRaceCacheWithNetwork [this=%p, delay=%u]\n"
, this, mRaceDelay); } } while (0)
;
10438
10439 TriggerNetworkWithDelay(mRaceDelay);
10440}
10441
10442NS_IMETHODIMPnsresult
10443nsHttpChannel::Test_triggerNetwork(int32_t aTimeout) {
10444 LOG(("nsHttpChannel::Test_triggerNetwork this=%p timeout=%d", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::Test_triggerNetwork this=%p timeout=%d", this
, aTimeout); } } while (0)
10445 aTimeout))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::Test_triggerNetwork this=%p timeout=%d", this
, aTimeout); } } while (0)
;
10446 MOZ_ASSERT(NS_IsMainThread(), "Must be called on the main thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
" (" "Must be called on the main thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10446); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Must be called on the main thread" ")"); do { *((volatile
int*)__null) = 10446; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10447
10448 // We set the trigger delay to the specified timeout.
10449 mRaceCacheWithNetwork = true;
10450 mNetworkTriggerDelay = aTimeout;
10451
10452 // If we already have a timer, set the delay/
10453 if (mNetworkTriggerTimer) {
10454 // If the timeout is 0 and there is a timer, we can trigger
10455 // the network immediately.
10456 MOZ_ASSERT(LoadWasOpened(), "Must have been opened before")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadWasOpened())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadWasOpened()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("LoadWasOpened()"
" (" "Must have been opened before" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10456); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
") (" "Must have been opened before" ")"); do { *((volatile int
*)__null) = 10456; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10457 if (!aTimeout) {
10458 return TriggerNetwork();
10459 }
10460 mNetworkTriggerTimer->SetDelay(aTimeout);
10461 }
10462 return NS_OK;
10463}
10464
10465nsHttpChannel::TimerCallback::TimerCallback(nsHttpChannel* aChannel)
10466 : mChannel(aChannel) {}
10467
10468NS_IMPL_ISUPPORTS(nsHttpChannel::TimerCallback, nsITimerCallback, nsINamed)MozExternalRefCountType nsHttpChannel::TimerCallback::AddRef(
void) { static_assert(!std::is_destructible_v<nsHttpChannel
::TimerCallback>, "Reference-counted class " "nsHttpChannel::TimerCallback"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10468); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
10468; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsHttpChannel::TimerCallback" != nullptr)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("nsHttpChannel::TimerCallback" != nullptr))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("\"nsHttpChannel::TimerCallback\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10468); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsHttpChannel::TimerCallback\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 10468; __attribute__((nomerge)) ::abort(); } while (false
); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("nsHttpChannel::TimerCallback" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"nsHttpChannel::TimerCallback"), (uint32_t)(sizeof(*this))); return
count; } MozExternalRefCountType nsHttpChannel::TimerCallback
::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10468); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 10468
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("nsHttpChannel::TimerCallback" != nullptr)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("nsHttpChannel::TimerCallback" != nullptr))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("\"nsHttpChannel::TimerCallback\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10468); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsHttpChannel::TimerCallback\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 10468; __attribute__((nomerge)) ::abort(); } while (false
); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("nsHttpChannel::TimerCallback" " not thread-safe"
); const char* const nametmp = "nsHttpChannel::TimerCallback"
; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; } nsresult nsHttpChannel::TimerCallback::
QueryInterface(const nsIID& aIID, void** aInstancePtr) { do
{ if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10468); MOZ_PretendNoReturn(); } } while (0); nsresult rv =
NS_ERROR_FAILURE; static_assert(2 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<nsHttpChannel::TimerCallback, nsITimerCallback
>, int32_t( reinterpret_cast<char*>(static_cast<nsITimerCallback
*>((nsHttpChannel::TimerCallback*)0x1000)) - reinterpret_cast
<char*>((nsHttpChannel::TimerCallback*)0x1000))}, {&
mozilla::detail::kImplementedIID<nsHttpChannel::TimerCallback
, nsINamed>, int32_t( reinterpret_cast<char*>(static_cast
<nsINamed*>((nsHttpChannel::TimerCallback*)0x1000)) - reinterpret_cast
<char*>((nsHttpChannel::TimerCallback*)0x1000))}, {&
mozilla::detail::kImplementedIID<nsHttpChannel::TimerCallback
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsITimerCallback*>((nsHttpChannel
::TimerCallback*)0x1000))) - reinterpret_cast<char*>((nsHttpChannel
::TimerCallback*)0x1000))}, { nullptr, 0 } } ; static_assert(
(sizeof(table) / sizeof(table[0])) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
10469
10470NS_IMETHODIMPnsresult
10471nsHttpChannel::TimerCallback::GetName(nsACString& aName) {
10472 aName.AssignLiteral("nsHttpChannel");
10473 return NS_OK;
10474}
10475
10476NS_IMETHODIMPnsresult
10477nsHttpChannel::TimerCallback::Notify(nsITimer* aTimer) {
10478 if (aTimer == mChannel->mCacheOpenTimer) {
10479 return mChannel->Test_triggerDelayedOpenCacheEntry();
10480 }
10481 if (aTimer == mChannel->mNetworkTriggerTimer) {
10482 return mChannel->TriggerNetwork();
10483 }
10484 MOZ_CRASH("Unknown timer")do { do { } while (false); MOZ_ReportCrash("" "Unknown timer"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10484); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown timer"
")"); do { *((volatile int*)__null) = 10484; __attribute__((
nomerge)) ::abort(); } while (false); } while (false)
;
10485
10486 return NS_OK;
10487}
10488
10489bool nsHttpChannel::EligibleForTailing() {
10490 if (!(mClassOfService.Flags() & nsIClassOfService::Tail)) {
10491 return false;
10492 }
10493
10494 if (mClassOfService.Flags() &
10495 (nsIClassOfService::UrgentStart | nsIClassOfService::Leader |
10496 nsIClassOfService::TailForbidden)) {
10497 return false;
10498 }
10499
10500 if (mClassOfService.Flags() & nsIClassOfService::Unblocked &&
10501 !(mClassOfService.Flags() & nsIClassOfService::TailAllowed)) {
10502 return false;
10503 }
10504
10505 if (IsNavigation()) {
10506 return false;
10507 }
10508
10509 return true;
10510}
10511
10512bool nsHttpChannel::WaitingForTailUnblock() {
10513 nsresult rv;
10514
10515 if (!gHttpHandler->IsTailBlockingEnabled()) {
10516 LOG(("nsHttpChannel %p tail-blocking disabled", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p tail-blocking disabled", this); } } while
(0)
;
10517 return false;
10518 }
10519
10520 if (!EligibleForTailing()) {
10521 LOG(("nsHttpChannel %p not eligible for tail-blocking", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p not eligible for tail-blocking", this); }
} while (0)
;
10522 AddAsNonTailRequest();
10523 return false;
10524 }
10525
10526 if (!EnsureRequestContext()) {
10527 LOG(("nsHttpChannel %p no request context", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel %p no request context", this); } } while (0)
;
10528 return false;
10529 }
10530
10531 LOG(("nsHttpChannel::WaitingForTailUnblock this=%p, rc=%p", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::WaitingForTailUnblock this=%p, rc=%p", this
, mRequestContext.get()); } } while (0)
10532 mRequestContext.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::WaitingForTailUnblock this=%p, rc=%p", this
, mRequestContext.get()); } } while (0)
;
10533
10534 bool blocked;
10535 rv = mRequestContext->IsContextTailBlocked(this, &blocked);
10536 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10537 return false;
10538 }
10539
10540 LOG((" blocked=%d", blocked))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " blocked=%d", blocked); } } while (0)
;
10541
10542 return blocked;
10543}
10544
10545//-----------------------------------------------------------------------------
10546// nsHttpChannel::nsIRequestTailUnblockCallback
10547//-----------------------------------------------------------------------------
10548
10549// Must be implemented in the leaf class because we don't have
10550// AsyncAbort in HttpBaseChannel.
10551NS_IMETHODIMPnsresult
10552nsHttpChannel::OnTailUnblock(nsresult rv) {
10553 LOG(("nsHttpChannel::OnTailUnblock this=%p rv=%" PRIx32 " rc=%p", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnTailUnblock this=%p rv=%" "x" " rc=%p", this
, static_cast<uint32_t>(rv), mRequestContext.get()); } }
while (0)
10554 static_cast<uint32_t>(rv), mRequestContext.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::OnTailUnblock this=%p rv=%" "x" " rc=%p", this
, static_cast<uint32_t>(rv), mRequestContext.get()); } }
while (0)
;
10555
10556 MOZ_RELEASE_ASSERT(mOnTailUnblock)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mOnTailUnblock)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mOnTailUnblock))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mOnTailUnblock"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10556); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mOnTailUnblock"
")"); do { *((volatile int*)__null) = 10556; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10557
10558 if (NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0)))) {
10559 rv = mStatus;
10560 }
10561
10562 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
10563 auto callback = mOnTailUnblock;
10564 mOnTailUnblock = nullptr;
10565 rv = (this->*callback)();
10566 }
10567
10568 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10569 CloseCacheEntry(false);
10570 return AsyncAbort(rv);
10571 }
10572
10573 return NS_OK;
10574}
10575
10576void nsHttpChannel::SetWarningReporter(
10577 HttpChannelSecurityWarningReporter* aReporter) {
10578 LOG(("nsHttpChannel [this=%p] SetWarningReporter [%p]", this, aReporter))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel [this=%p] SetWarningReporter [%p]", this, aReporter
); } } while (0)
;
10579 mWarningReporter = aReporter;
10580}
10581
10582HttpChannelSecurityWarningReporter* nsHttpChannel::GetWarningReporter() {
10583 LOG(("nsHttpChannel [this=%p] GetWarningReporter [%p]", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel [this=%p] GetWarningReporter [%p]", this, mWarningReporter
.get()); } } while (0)
10584 mWarningReporter.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel [this=%p] GetWarningReporter [%p]", this, mWarningReporter
.get()); } } while (0)
;
10585 return mWarningReporter.get();
10586}
10587
10588// The specification for ORB is currently being written:
10589// https://whatpr.org/fetch/1442.html#orb-algorithm
10590// The `opaque-response-safelist check` is implemented in:
10591// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff`
10592// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
10593// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
10594// * `OpaqueResponseBlocker::ValidateJavaScript`
10595//
10596// Should only be called by nsMediaSniffer::GetMIMETypeFromContent and
10597// imageLoader::GetMIMETypeFromContent when the content type can be
10598// recognized by these sniffers.
10599void nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck(
10600 SnifferType aType) {
10601 // https://whatpr.org/fetch/1442.html#orb-algorithm
10602 // This method covers steps, 8 and 10.
10603 MOZ_ASSERT(XRE_IsParentProcess())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(XRE_IsParentProcess())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(XRE_IsParentProcess()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("XRE_IsParentProcess()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10603); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 10603; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10604
10605 if (NeedOpaqueResponseAllowedCheckAfterSniff()) {
10606 MOZ_ASSERT(mCachedOpaqueResponseBlockingPref)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCachedOpaqueResponseBlockingPref)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCachedOpaqueResponseBlockingPref
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"mCachedOpaqueResponseBlockingPref", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10606); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCachedOpaqueResponseBlockingPref"
")"); do { *((volatile int*)__null) = 10606; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10607
10608 // If the sniffer type is media and the request comes from a media element,
10609 // we would like to check:
10610 // - Whether the information provided by the media element shows it's an
10611 // initial request.
10612 // - Whether the response's status is either 200 or 206.
10613 //
10614 // If any of the results is false, then we set
10615 // mBlockOpaqueResponseAfterSniff to true and block the response later.
10616 if (aType == SnifferType::Media) {
10617 // Step 8
10618 MOZ_ASSERT(mLoadInfo)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mLoadInfo", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10618); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo"
")"); do { *((volatile int*)__null) = 10618; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10619
10620 bool isMediaRequest;
10621 mLoadInfo->GetIsMediaRequest(&isMediaRequest);
10622 if (isMediaRequest) {
10623 bool isInitialRequest;
10624 mLoadInfo->GetIsMediaInitialRequest(&isInitialRequest);
10625 MOZ_ASSERT(isInitialRequest)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isInitialRequest)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isInitialRequest))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("isInitialRequest"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10625); AnnotateMozCrashReason("MOZ_ASSERT" "(" "isInitialRequest"
")"); do { *((volatile int*)__null) = 10625; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10626
10627 if (!isInitialRequest) {
10628 // Step 8.1
10629 BlockOpaqueResponseAfterSniff(
10630 u"media request after sniffing, but not initial request"_ns,
10631 OpaqueResponseBlockedTelemetryReason::MEDIA_NOT_INITIAL);
10632 return;
10633 }
10634
10635 if (mResponseHead->Status() != 200 && mResponseHead->Status() != 206) {
10636 // Step 8.2
10637 BlockOpaqueResponseAfterSniff(
10638 u"media request's response status is neither 200 nor 206"_ns,
10639 OpaqueResponseBlockedTelemetryReason::MEDIA_INCORRECT_RESP);
10640 return;
10641 }
10642 }
10643 }
10644
10645 // Step 8.3 if `aType == SnifferType::Media`
10646 // Step 9 can be skipped, only `HTMLMediaElement` ever sets isMediaRequest.
10647 // Step 10 if `aType == SnifferType::Image`
10648 AllowOpaqueResponseAfterSniff();
10649 }
10650}
10651
10652namespace {
10653
10654class CopyNonDefaultHeaderVisitor final : public nsIHttpHeaderVisitor {
10655 nsCOMPtr<nsIHttpChannel> mTarget;
10656
10657 ~CopyNonDefaultHeaderVisitor() = default;
10658
10659 NS_IMETHODvirtual nsresult
10660 VisitHeader(const nsACString& aHeader, const nsACString& aValue) override {
10661 if (aValue.IsEmpty()) {
10662 return mTarget->SetEmptyRequestHeader(aHeader);
10663 }
10664 return mTarget->SetRequestHeader(aHeader, aValue, false /* merge */);
10665 }
10666
10667 public:
10668 explicit CopyNonDefaultHeaderVisitor(nsIHttpChannel* aTarget)
10669 : mTarget(aTarget) {
10670 MOZ_DIAGNOSTIC_ASSERT(mTarget)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mTarget)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mTarget))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mTarget", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10670); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mTarget"
")"); do { *((volatile int*)__null) = 10670; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10671 }
10672
10673 NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::false_type;
protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public:
10674};
10675
10676NS_IMPL_ISUPPORTS(CopyNonDefaultHeaderVisitor, nsIHttpHeaderVisitor)MozExternalRefCountType CopyNonDefaultHeaderVisitor::AddRef(void
) { static_assert(!std::is_destructible_v<CopyNonDefaultHeaderVisitor
>, "Reference-counted class " "CopyNonDefaultHeaderVisitor"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
10676; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("CopyNonDefaultHeaderVisitor" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("CopyNonDefaultHeaderVisitor" != nullptr))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("\"CopyNonDefaultHeaderVisitor\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"CopyNonDefaultHeaderVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 10676; __attribute__((nomerge)) ::abort(); } while (false
); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("CopyNonDefaultHeaderVisitor" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"CopyNonDefaultHeaderVisitor"), (uint32_t)(sizeof(*this))); return
count; } MozExternalRefCountType CopyNonDefaultHeaderVisitor
::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 10676
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("CopyNonDefaultHeaderVisitor" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("CopyNonDefaultHeaderVisitor" != nullptr))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("\"CopyNonDefaultHeaderVisitor\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"CopyNonDefaultHeaderVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 10676; __attribute__((nomerge)) ::abort(); } while (false
); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("CopyNonDefaultHeaderVisitor" " not thread-safe"
); const char* const nametmp = "CopyNonDefaultHeaderVisitor";
nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; } nsresult CopyNonDefaultHeaderVisitor::QueryInterface
(const nsIID& aIID, void** aInstancePtr) { do { if (!(aInstancePtr
)) { NS_DebugBreak(NS_DEBUG_ASSERTION, "QueryInterface requires a non-NULL destination!"
, "aInstancePtr", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10676); MOZ_PretendNoReturn(); } } while (0); nsresult rv =
NS_ERROR_FAILURE; static_assert(1 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<CopyNonDefaultHeaderVisitor, nsIHttpHeaderVisitor
>, int32_t( reinterpret_cast<char*>(static_cast<nsIHttpHeaderVisitor
*>((CopyNonDefaultHeaderVisitor*)0x1000)) - reinterpret_cast
<char*>((CopyNonDefaultHeaderVisitor*)0x1000))}, {&
mozilla::detail::kImplementedIID<CopyNonDefaultHeaderVisitor
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIHttpHeaderVisitor*>
((CopyNonDefaultHeaderVisitor*)0x1000))) - reinterpret_cast<
char*>((CopyNonDefaultHeaderVisitor*)0x1000))}, { nullptr,
0 } } ; static_assert((sizeof(table) / sizeof(table[0])) >
1, "need at least 1 interface"); rv = NS_TableDrivenQI(static_cast
<void*>(this), aIID, aInstancePtr, table); return rv; }
10677
10678} // anonymous namespace
10679
10680nsresult nsHttpChannel::RedirectToInterceptedChannel() {
10681 nsCOMPtr<nsINetworkInterceptController> controller;
10682 GetCallback(controller);
10683
10684 RefPtr<InterceptedHttpChannel> intercepted =
10685 InterceptedHttpChannel::CreateForInterception(
10686 mChannelCreationTime, mChannelCreationTimestamp, mAsyncOpenTime);
10687
10688 ExtContentPolicyType type = mLoadInfo->GetExternalContentPolicyType();
10689
10690 nsCOMPtr<nsILoadInfo> redirectLoadInfo =
10691 CloneLoadInfoForRedirect(mURI, nsIChannelEventSink::REDIRECT_INTERNAL);
10692
10693 nsresult rv = intercepted->Init(
10694 mURI, mCaps, static_cast<nsProxyInfo*>(mProxyInfo.get()),
10695 mProxyResolveFlags, mProxyURI, mChannelId, type, redirectLoadInfo);
10696
10697 rv = SetupReplacementChannel(mURI, intercepted, true,
10698 nsIChannelEventSink::REDIRECT_INTERNAL);
10699 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10699); return rv; } } while (false)
;
10700
10701 // Some APIs, like fetch(), allow content to set non-standard headers.
10702 // Normally these APIs are responsible for copying these headers across
10703 // redirects. In the e10s parent-side intercept case, though, we currently
10704 // "hide" the internal redirect to the InterceptedHttpChannel. So the
10705 // fetch() API does not have the opportunity to move headers over.
10706 // Therefore, we do it automatically here.
10707 //
10708 // Once child-side interception is removed and the internal redirect no
10709 // longer needs to be "hidden", then this header copying code can be
10710 // removed.
10711 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
10712 new CopyNonDefaultHeaderVisitor(intercepted);
10713 rv = VisitNonDefaultRequestHeaders(visitor);
10714 NS_ENSURE_SUCCESS(rv, rv)do { nsresult __rv = rv; if (((bool)(__builtin_expect(!!(NS_FAILED_impl
(__rv)), 0)))) { const char* name = mozilla::GetStaticErrorName
(__rv); mozilla::SmprintfPointer msg = mozilla::Smprintf( "NS_ENSURE_SUCCESS(%s, %s) failed with "
"result 0x%" "X" "%s%s%s", "rv", "rv", static_cast<uint32_t
>(__rv), name ? " (" : "", name ? name : "", name ? ")" : ""
); NS_DebugBreak(NS_DEBUG_WARNING, msg.get(), nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10714); return rv; } } while (false)
;
10715
10716 mRedirectChannel = intercepted;
10717
10718 PushRedirectAsyncFunc(&nsHttpChannel::ContinueAsyncRedirectChannelToURI);
10719
10720 rv = gHttpHandler->AsyncOnChannelRedirect(
10721 this, intercepted, nsIChannelEventSink::REDIRECT_INTERNAL);
10722
10723 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
10724 rv = WaitForRedirectCallback();
10725 }
10726
10727 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10728 AutoRedirectVetoNotifier notifier(this, rv);
10729
10730 PopRedirectAsyncFunc(&nsHttpChannel::ContinueAsyncRedirectChannelToURI);
10731 }
10732
10733 return rv;
10734}
10735
10736void nsHttpChannel::ReEvaluateReferrerAfterTrackingStatusIsKnown() {
10737 nsCOMPtr<nsICookieJarSettings> cjs;
10738 if (mLoadInfo) {
10739 Unused << mLoadInfo->GetCookieJarSettings(getter_AddRefs(cjs));
10740 }
10741 if (!cjs) {
10742 cjs = net::CookieJarSettings::Create(mLoadInfo->GetLoadingPrincipal());
10743 }
10744 if (cjs->GetRejectThirdPartyContexts()) {
10745 bool isPrivate = mLoadInfo->GetOriginAttributes().IsPrivateBrowsing();
10746 // If our referrer has been set before, and our referrer policy is unset
10747 // (default policy) if we thought the channel wasn't a third-party
10748 // tracking channel, we may need to set our referrer with referrer policy
10749 // once again to ensure our defaults properly take effect now.
10750 if (mReferrerInfo) {
10751 ReferrerInfo* referrerInfo =
10752 static_cast<ReferrerInfo*>(mReferrerInfo.get());
10753
10754 if (referrerInfo->IsPolicyOverrided() &&
10755 referrerInfo->ReferrerPolicy() ==
10756 ReferrerInfo::GetDefaultReferrerPolicy(nullptr, nullptr,
10757 isPrivate)) {
10758 nsCOMPtr<nsIReferrerInfo> newReferrerInfo =
10759 referrerInfo->CloneWithNewPolicy(
10760 ReferrerInfo::GetDefaultReferrerPolicy(this, mURI, isPrivate));
10761 // The arguments passed to SetReferrerInfoInternal here should mirror
10762 // the arguments passed in
10763 // HttpChannelChild::RecvOverrideReferrerInfoDuringBeginConnect().
10764 SetReferrerInfoInternal(newReferrerInfo, false, true, true);
10765
10766 nsCOMPtr<nsIParentChannel> parentChannel;
10767 NS_QueryNotificationCallbacks(this, parentChannel);
10768 RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel);
10769 if (httpParent) {
10770 httpParent->OverrideReferrerInfoDuringBeginConnect(newReferrerInfo);
10771 }
10772 }
10773 }
10774 }
10775}
10776
10777namespace {
10778
10779class BackgroundRevalidatingListener : public nsIStreamListener {
10780 NS_DECL_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::false_type;
protected: nsAutoRefCnt mRefCnt; nsAutoOwningThread _mOwningThread
; public:
10781
10782 NS_DECL_NSISTREAMLISTENERvirtual nsresult OnDataAvailable(nsIRequest *aRequest, nsIInputStream
*aInputStream, uint64_t aOffset, uint32_t aCount) override;
10783 NS_DECL_NSIREQUESTOBSERVERvirtual nsresult OnStartRequest(nsIRequest *aRequest) override
; virtual nsresult OnStopRequest(nsIRequest *aRequest, nsresult
aStatusCode) override;
10784
10785 private:
10786 virtual ~BackgroundRevalidatingListener() = default;
10787};
10788
10789NS_IMETHODIMPnsresult
10790BackgroundRevalidatingListener::OnStartRequest(nsIRequest* request) {
10791 return NS_OK;
10792}
10793
10794NS_IMETHODIMPnsresult
10795BackgroundRevalidatingListener::OnDataAvailable(nsIRequest* request,
10796 nsIInputStream* input,
10797 uint64_t offset,
10798 uint32_t count) {
10799 uint32_t bytesRead = 0;
10800 return input->ReadSegments(NS_DiscardSegment, nullptr, count, &bytesRead);
10801}
10802
10803NS_IMETHODIMPnsresult
10804BackgroundRevalidatingListener::OnStopRequest(nsIRequest* request,
10805 nsresult status) {
10806 if (NS_FAILED(status)((bool)(__builtin_expect(!!(NS_FAILED_impl(status)), 0)))) {
10807 return status;
10808 }
10809
10810 nsCOMPtr<nsIHttpChannel> channel(do_QueryInterface(request));
10811 if (gHttpHandler) {
10812 gHttpHandler->OnBackgroundRevalidation(channel);
10813 }
10814 return NS_OK;
10815}
10816
10817NS_IMPL_ISUPPORTS(BackgroundRevalidatingListener, nsIStreamListener,MozExternalRefCountType BackgroundRevalidatingListener::AddRef
(void) { static_assert(!std::is_destructible_v<BackgroundRevalidatingListener
>, "Reference-counted class " "BackgroundRevalidatingListener"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10818); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
10818; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("BackgroundRevalidatingListener" != nullptr)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("BackgroundRevalidatingListener" != nullptr))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("\"BackgroundRevalidatingListener\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10818); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"BackgroundRevalidatingListener\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 10818; __attribute__((nomerge)) ::abort(); } while (false
); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("BackgroundRevalidatingListener" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"BackgroundRevalidatingListener"), (uint32_t)(sizeof(*this)))
; return count; } MozExternalRefCountType BackgroundRevalidatingListener
::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10818); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 10818
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("BackgroundRevalidatingListener" != nullptr)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("BackgroundRevalidatingListener" != nullptr))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("\"BackgroundRevalidatingListener\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10818); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"BackgroundRevalidatingListener\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 10818; __attribute__((nomerge)) ::abort(); } while (false
); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("BackgroundRevalidatingListener" " not thread-safe"
); const char* const nametmp = "BackgroundRevalidatingListener"
; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; } nsresult BackgroundRevalidatingListener
::QueryInterface(const nsIID& aIID, void** aInstancePtr) {
do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "QueryInterface requires a non-NULL destination!", "aInstancePtr"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10818); MOZ_PretendNoReturn(); } } while (0); nsresult rv =
NS_ERROR_FAILURE; static_assert(2 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<BackgroundRevalidatingListener, nsIStreamListener
>, int32_t( reinterpret_cast<char*>(static_cast<nsIStreamListener
*>((BackgroundRevalidatingListener*)0x1000)) - reinterpret_cast
<char*>((BackgroundRevalidatingListener*)0x1000))}, {&
mozilla::detail::kImplementedIID<BackgroundRevalidatingListener
, nsIRequestObserver>, int32_t( reinterpret_cast<char*>
(static_cast<nsIRequestObserver*>((BackgroundRevalidatingListener
*)0x1000)) - reinterpret_cast<char*>((BackgroundRevalidatingListener
*)0x1000))}, {&mozilla::detail::kImplementedIID<BackgroundRevalidatingListener
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIStreamListener*>((
BackgroundRevalidatingListener*)0x1000))) - reinterpret_cast<
char*>((BackgroundRevalidatingListener*)0x1000))}, { nullptr
, 0 } } ; static_assert((sizeof(table) / sizeof(table[0])) >
1, "need at least 1 interface"); rv = NS_TableDrivenQI(static_cast
<void*>(this), aIID, aInstancePtr, table); return rv; }
10818 nsIRequestObserver)MozExternalRefCountType BackgroundRevalidatingListener::AddRef
(void) { static_assert(!std::is_destructible_v<BackgroundRevalidatingListener
>, "Reference-counted class " "BackgroundRevalidatingListener"
" should not have a public destructor. " "Make this class's destructor non-public"
); do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) >= 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) >= 0))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) >= 0"
" (" "illegal refcnt" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10818); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
10818; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("BackgroundRevalidatingListener" != nullptr)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("BackgroundRevalidatingListener" != nullptr))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("\"BackgroundRevalidatingListener\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10818); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"BackgroundRevalidatingListener\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 10818; __attribute__((nomerge)) ::abort(); } while (false
); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("BackgroundRevalidatingListener" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"BackgroundRevalidatingListener"), (uint32_t)(sizeof(*this)))
; return count; } MozExternalRefCountType BackgroundRevalidatingListener
::Release(void) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(int32_t(mRefCnt) > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(int32_t(mRefCnt) > 0))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("int32_t(mRefCnt) > 0"
" (" "dup release" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10818); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 10818
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("BackgroundRevalidatingListener" != nullptr)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("BackgroundRevalidatingListener" != nullptr))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("\"BackgroundRevalidatingListener\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10818); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"BackgroundRevalidatingListener\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 10818; __attribute__((nomerge)) ::abort(); } while (false
); } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("BackgroundRevalidatingListener" " not thread-safe"
); const char* const nametmp = "BackgroundRevalidatingListener"
; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; } nsresult BackgroundRevalidatingListener
::QueryInterface(const nsIID& aIID, void** aInstancePtr) {
do { if (!(aInstancePtr)) { NS_DebugBreak(NS_DEBUG_ASSERTION
, "QueryInterface requires a non-NULL destination!", "aInstancePtr"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10818); MOZ_PretendNoReturn(); } } while (0); nsresult rv =
NS_ERROR_FAILURE; static_assert(2 > 0, "Need more arguments to NS_INTERFACE_TABLE"
); static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<BackgroundRevalidatingListener, nsIStreamListener
>, int32_t( reinterpret_cast<char*>(static_cast<nsIStreamListener
*>((BackgroundRevalidatingListener*)0x1000)) - reinterpret_cast
<char*>((BackgroundRevalidatingListener*)0x1000))}, {&
mozilla::detail::kImplementedIID<BackgroundRevalidatingListener
, nsIRequestObserver>, int32_t( reinterpret_cast<char*>
(static_cast<nsIRequestObserver*>((BackgroundRevalidatingListener
*)0x1000)) - reinterpret_cast<char*>((BackgroundRevalidatingListener
*)0x1000))}, {&mozilla::detail::kImplementedIID<BackgroundRevalidatingListener
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIStreamListener*>((
BackgroundRevalidatingListener*)0x1000))) - reinterpret_cast<
char*>((BackgroundRevalidatingListener*)0x1000))}, { nullptr
, 0 } } ; static_assert((sizeof(table) / sizeof(table[0])) >
1, "need at least 1 interface"); rv = NS_TableDrivenQI(static_cast
<void*>(this), aIID, aInstancePtr, table); return rv; }
10819
10820} // namespace
10821
10822void nsHttpChannel::PerformBackgroundCacheRevalidation() {
10823 if (!StaticPrefs::network_http_stale_while_revalidate_enabled()) {
10824 return;
10825 }
10826
10827 // This is a channel doing a revalidation. It shouldn't do it again.
10828 if (mStaleRevalidation) {
10829 return;
10830 }
10831
10832 LOG(("nsHttpChannel::PerformBackgroundCacheRevalidation %p", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::PerformBackgroundCacheRevalidation %p", this
); } } while (0)
;
10833
10834 Unused << NS_DispatchToMainThreadQueue(
10835 NewIdleRunnableMethod(
10836 "nsHttpChannel::PerformBackgroundCacheRevalidation", this,
10837 &nsHttpChannel::PerformBackgroundCacheRevalidationNow),
10838 EventQueuePriority::Idle);
10839}
10840
10841void nsHttpChannel::PerformBackgroundCacheRevalidationNow() {
10842 LOG(("nsHttpChannel::PerformBackgroundCacheRevalidationNow %p", this))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::PerformBackgroundCacheRevalidationNow %p", this
); } } while (0)
;
10843
10844 MOZ_ASSERT(NS_IsMainThread())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(NS_IsMainThread())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(NS_IsMainThread()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("NS_IsMainThread()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10844); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 10844; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10845
10846 nsresult rv;
10847
10848 nsLoadFlags loadFlags = mLoadFlags | LOAD_ONLY_IF_MODIFIED | VALIDATE_ALWAYS |
10849 LOAD_BACKGROUND | LOAD_BYPASS_SERVICE_WORKER;
10850
10851 nsCOMPtr<nsIChannel> validatingChannel;
10852 rv = NS_NewChannelInternal(getter_AddRefs(validatingChannel), mURI, mLoadInfo,
10853 nullptr /* performance storage */, mLoadGroup,
10854 mCallbacks, loadFlags);
10855 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10856 LOG((" failed to created the channel, rv=0x%08x",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " failed to created the channel, rv=0x%08x", static_cast<
uint32_t>(rv)); } } while (0)
10857 static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " failed to created the channel, rv=0x%08x", static_cast<
uint32_t>(rv)); } } while (0)
;
10858 return;
10859 }
10860
10861 nsCOMPtr<nsISupportsPriority> priority(do_QueryInterface(validatingChannel));
10862 if (priority) {
10863 priority->SetPriority(nsISupportsPriority::PRIORITY_LOWEST);
10864 }
10865
10866 nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(validatingChannel));
10867 if (cos) {
10868 cos->AddClassFlags(nsIClassOfService::Tail);
10869 }
10870
10871 RefPtr<nsHttpChannel> httpChan = do_QueryObject(validatingChannel);
10872 if (httpChan) {
10873 httpChan->mStaleRevalidation = true;
10874 }
10875
10876 RefPtr<BackgroundRevalidatingListener> listener =
10877 new BackgroundRevalidatingListener();
10878 rv = validatingChannel->AsyncOpen(listener);
10879 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10880 LOG((" failed to open the channel, rv=0x%08x", static_cast<uint32_t>(rv)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " failed to open the channel, rv=0x%08x", static_cast<uint32_t
>(rv)); } } while (0)
;
10881 return;
10882 }
10883
10884 LOG((" %p is re-validating with a new channel %p", this,do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " %p is re-validating with a new channel %p", this, validatingChannel
.get()); } } while (0)
10885 validatingChannel.get()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, " %p is re-validating with a new channel %p", this, validatingChannel
.get()); } } while (0)
;
10886}
10887
10888NS_IMETHODIMPnsresult
10889nsHttpChannel::SetEarlyHintObserver(nsIEarlyHintObserver* aObserver) {
10890 mEarlyHintObserver = aObserver;
10891 return NS_OK;
10892}
10893
10894NS_IMETHODIMPnsresult
10895nsHttpChannel::EarlyHint(const nsACString& aLinkHeader,
10896 const nsACString& aReferrerPolicy,
10897 const nsACString& aCspHeader) {
10898 LOG(("nsHttpChannel::EarlyHint.\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::EarlyHint.\n"); } } while (0)
;
10899
10900 if (mEarlyHintObserver && nsContentUtils::ComputeIsSecureContext(this)) {
10901 LOG(("nsHttpChannel::EarlyHint propagated.\n"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "nsHttpChannel::EarlyHint propagated.\n"); } } while (0)
;
10902 mEarlyHintObserver->EarlyHint(aLinkHeader, aReferrerPolicy, aCspHeader);
10903 }
10904 return NS_OK;
10905}
10906
10907NS_IMETHODIMPnsresult nsHttpChannel::SetResponseOverride(
10908 nsIReplacedHttpResponse* aReplacedHttpResponse) {
10909 mOverrideResponse = new nsMainThreadPtrHolder<nsIReplacedHttpResponse>(
10910 "nsIReplacedHttpResponse", aReplacedHttpResponse);
10911 return NS_OK;
10912}
10913
10914NS_IMETHODIMPnsresult nsHttpChannel::SetWebTransportSessionEventListener(
10915 WebTransportSessionEventListener* aListener) {
10916 mWebTransportSessionEventListener = aListener;
10917 return NS_OK;
10918}
10919
10920already_AddRefed<WebTransportSessionEventListener>
10921nsHttpChannel::GetWebTransportSessionEventListener() {
10922 RefPtr<WebTransportSessionEventListener> wt =
10923 mWebTransportSessionEventListener;
10924 return wt.forget();
10925}
10926
10927} // namespace net
10928} // namespace mozilla