Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp
Warning:line 10974, column 12
Value stored to 'rv' during its initialization 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-20/lib/clang/20 -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 _GLIBCXX_ASSERTIONS -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-20/lib/clang/20/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 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -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-2025-01-20-090804-167946-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 "nsQueryObject.h"
56#include "nsThreadUtils.h"
57#include "nsIConsoleService.h"
58#include "nsINetworkErrorLogging.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 "CookieService.h"
76#include "nsIPrincipal.h"
77#include "nsIScriptError.h"
78#include "nsIScriptSecurityManager.h"
79#include "nsITransportSecurityInfo.h"
80#include "nsIWebProgressListener.h"
81#include "LoadContextInfo.h"
82#include "netCore.h"
83#include "nsHttpTransaction.h"
84#include "nsICancelable.h"
85#include "nsIHttpChannelInternal.h"
86#include "nsIPrompt.h"
87#include "nsInputStreamPump.h"
88#include "nsURLHelper.h"
89#include "nsISocketTransport.h"
90#include "nsIStreamConverterService.h"
91#include "nsISiteSecurityService.h"
92#include "nsString.h"
93#include "nsStringStream.h"
94#include "mozilla/dom/PerformanceStorage.h"
95#include "mozilla/dom/ReferrerInfo.h"
96#include "mozilla/Telemetry.h"
97#include "AlternateServices.h"
98#include "NetworkMarker.h"
99#include "nsIHttpPushListener.h"
100#include "nsIDNSRecord.h"
101#include "mozilla/dom/Document.h"
102#include "nsICompressConvStats.h"
103#include "nsCORSListenerProxy.h"
104#include "nsISocketProvider.h"
105#include "mozilla/extensions/StreamFilterParent.h"
106#include "mozilla/net/Predictor.h"
107#include "mozilla/MathAlgorithms.h"
108#include "mozilla/NullPrincipal.h"
109#include "CacheControlParser.h"
110#include "nsMixedContentBlocker.h"
111#include "CacheStorageService.h"
112#include "HttpChannelParent.h"
113#include "HttpTransactionParent.h"
114#include "ThirdPartyUtil.h"
115#include "InterceptedHttpChannel.h"
116#include "../../cache2/CacheFileUtils.h"
117#include "nsINetworkLinkService.h"
118#include "mozilla/ContentBlockingAllowList.h"
119#include "mozilla/dom/ServiceWorkerUtils.h"
120#include "mozilla/dom/nsHTTPSOnlyStreamListener.h"
121#include "mozilla/dom/nsHTTPSOnlyUtils.h"
122#include "mozilla/net/AsyncUrlChannelClassifier.h"
123#include "mozilla/net/CookieJarSettings.h"
124#include "mozilla/net/NeckoChannelParams.h"
125#include "mozilla/net/OpaqueResponseUtils.h"
126#include "mozilla/net/UrlClassifierFeatureFactory.h"
127#include "HttpTrafficAnalyzer.h"
128#include "mozilla/net/SocketProcessParent.h"
129#include "mozilla/dom/SecFetch.h"
130#include "mozilla/net/TRRService.h"
131#include "nsUnknownDecoder.h"
132#ifdef XP_WIN
133# include "HttpWinUtils.h"
134#endif
135#ifdef XP_MACOSX
136# include "MicrosoftEntraSSOUtils.h"
137#endif
138#ifdef FUZZING
139# include "mozilla/StaticPrefs_fuzzing.h"
140#endif
141
142namespace mozilla {
143
144using namespace dom;
145
146namespace net {
147
148namespace {
149
150// True if the local cache should be bypassed when processing a request.
151#define BYPASS_LOCAL_CACHE(loadFlags, isPreferCacheLoadOverBypass)((loadFlags) & (nsIRequest::LOAD_BYPASS_CACHE | nsICachingChannel
::LOAD_BYPASS_LOCAL_CACHE) && !(((loadFlags) & nsIRequest
::LOAD_FROM_CACHE) && (isPreferCacheLoadOverBypass)))
\
152 ((loadFlags) & (nsIRequest::LOAD_BYPASS_CACHE | \
153 nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE) && \
154 !(((loadFlags) & nsIRequest::LOAD_FROM_CACHE) && \
155 (isPreferCacheLoadOverBypass)))
156
157#define RECOVER_FROM_CACHE_FILE_ERROR(result)((result) == NS_ERROR_FILE_NOT_FOUND || (result) == NS_ERROR_FILE_CORRUPTED
|| (result) == NS_ERROR_OUT_OF_MEMORY)
\
158 ((result) == NS_ERROR_FILE_NOT_FOUND || \
159 (result) == NS_ERROR_FILE_CORRUPTED || (result) == NS_ERROR_OUT_OF_MEMORY)
160
161#define WRONG_RACING_RESPONSE_SOURCE(req)(mRaceCacheWithNetwork && (((mFirstResponseSource == RESPONSE_FROM_CACHE
) && ((req) != mCachePump)) || ((mFirstResponseSource
== RESPONSE_FROM_NETWORK) && ((req) != mTransactionPump
))))
\
162 (mRaceCacheWithNetwork && \
163 (((mFirstResponseSource == RESPONSE_FROM_CACHE) && \
164 ((req) != mCachePump)) || \
165 ((mFirstResponseSource == RESPONSE_FROM_NETWORK) && \
166 ((req) != mTransactionPump))))
167
168static NS_DEFINE_CID(kStreamListenerTeeCID, NS_STREAMLISTENERTEE_CID)const nsCID kStreamListenerTeeCID = { 0x831f8f13, 0x7aa8, 0x485f
, { 0xb0, 0x2e, 0x77, 0xc8, 0x81, 0xcc, 0x57, 0x73 } }
;
169
170enum ChannelDisposition {
171 kHttpCanceled = 0,
172 kHttpDisk = 1,
173 kHttpNetOK = 2,
174 kHttpNetEarlyFail = 3,
175 kHttpNetLateFail = 4,
176 kHttpsCanceled = 8,
177 kHttpsDisk = 9,
178 kHttpsNetOK = 10,
179 kHttpsNetEarlyFail = 11,
180 kHttpsNetLateFail = 12
181};
182
183void AccumulateCacheHitTelemetry(CacheDisposition hitOrMiss,
184 nsIChannel* aChannel) {
185 nsCString key("UNKNOWN");
186
187 nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo();
188
189 nsAutoCString contentType;
190 if (NS_SUCCEEDED(aChannel->GetContentType(contentType))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aChannel->GetContentType
(contentType))), 1)))
) {
191 if (nsContentUtils::IsJavascriptMIMEType(
192 NS_ConvertUTF8toUTF16(contentType))) {
193 key.AssignLiteral("JAVASCRIPT");
194 } else if (StringBeginsWith(contentType, "text/css"_ns) ||
195 (loadInfo && loadInfo->GetExternalContentPolicyType() ==
196 ExtContentPolicy::TYPE_STYLESHEET)) {
197 key.AssignLiteral("STYLESHEET");
198 } else if (StringBeginsWith(contentType, "application/wasm"_ns)) {
199 key.AssignLiteral("WASM");
200 } else if (StringBeginsWith(contentType, "image/"_ns)) {
201 key.AssignLiteral("IMAGE");
202 } else if (StringBeginsWith(contentType, "video/"_ns)) {
203 key.AssignLiteral("MEDIA");
204 } else if (StringBeginsWith(contentType, "audio/"_ns)) {
205 key.AssignLiteral("MEDIA");
206 } else if (!StringBeginsWith(contentType,
207 nsLiteralCString(UNKNOWN_CONTENT_TYPE"application/x-unknown-content-type"))) {
208 key.AssignLiteral("OTHER");
209 }
210 }
211
212 Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3 label =
213 Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::Unresolved;
214 switch (hitOrMiss) {
215 case kCacheUnresolved:
216 label = Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::Unresolved;
217 break;
218 case kCacheHit:
219 label = Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::Hit;
220 break;
221 case kCacheHitViaReval:
222 label = Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::HitViaReval;
223 break;
224 case kCacheMissedViaReval:
225 label = Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::MissedViaReval;
226 break;
227 case kCacheMissed:
228 label = Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::Missed;
229 break;
230 case kCacheUnknown:
231 label = Telemetry::LABELS_HTTP_CACHE_DISPOSITION_3::Unknown;
232 break;
233 }
234
235 Telemetry::AccumulateCategoricalKeyed(key, label);
236 Telemetry::AccumulateCategoricalKeyed("ALL"_ns, label);
237}
238
239// Computes and returns a SHA1 hash of the input buffer. The input buffer
240// must be a null-terminated string.
241nsresult Hash(const char* buf, nsACString& hash) {
242 nsresult rv;
243
244 nsCOMPtr<nsICryptoHash> hasher =
245 do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID"@mozilla.org/security/hash;1", &rv);
246 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"
, 246); return rv; } } while (false)
;
247
248 rv = hasher->Init(nsICryptoHash::SHA1);
249 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"
, 249); return rv; } } while (false)
;
250
251 rv = hasher->Update(reinterpret_cast<unsigned const char*>(buf), strlen(buf));
252 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"
, 252); return rv; } } while (false)
;
253
254 rv = hasher->Finish(true, hash);
255 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"
, 255); return rv; } } while (false)
;
256
257 return NS_OK;
258}
259
260class CookieVisitor final {
261 public:
262 explicit CookieVisitor(nsHttpResponseHead* aResponseHead) {
263 nsAutoCString cookieHeader;
264 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(aResponseHead->
GetHeader(nsHttp::Set_Cookie, cookieHeader))), 1)))
265 aResponseHead->GetHeader(nsHttp::Set_Cookie, cookieHeader))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aResponseHead->
GetHeader(nsHttp::Set_Cookie, cookieHeader))), 1)))
) {
266 for (const auto& cookie : cookieHeader.Split('\n')) {
267 mCookieHeaders.AppendElement(cookie);
268 }
269 }
270 }
271
272 ~CookieVisitor() = default;
273
274 const nsTArray<nsCString>& CookieHeaders() const { return mCookieHeaders; }
275
276 private:
277 nsTArray<nsCString> mCookieHeaders;
278};
279} // unnamed namespace
280
281// We only treat 3xx responses as redirects if they have a Location header and
282// the status code is in a whitelist.
283bool nsHttpChannel::WillRedirect(const nsHttpResponseHead& response) {
284 return IsRedirectStatus(response.Status()) &&
285 response.HasHeader(nsHttp::Location);
286}
287
288nsresult StoreAuthorizationMetaData(nsICacheEntry* entry,
289 nsHttpRequestHead* requestHead);
290
291class MOZ_STACK_CLASS AutoRedirectVetoNotifier {
292 public:
293 explicit AutoRedirectVetoNotifier(nsHttpChannel* channel, nsresult& aRv)
294 : mChannel(channel), mRv(aRv) {
295 if (mChannel->LoadHasAutoRedirectVetoNotifier()) {
296 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"
, 296); AnnotateMozCrashReason("MOZ_CRASH(" "Nested AutoRedirectVetoNotifier on the stack"
")"); do { *((volatile int*)__null) = 296; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
297 mChannel = nullptr;
298 return;
299 }
300
301 mChannel->StoreHasAutoRedirectVetoNotifier(true);
302 }
303 ~AutoRedirectVetoNotifier() { ReportRedirectResult(mRv); }
304 void RedirectSucceeded() { ReportRedirectResult(NS_OK); }
305
306 private:
307 nsHttpChannel* mChannel;
308 bool mCalledReport = false;
309 nsresult& mRv;
310 void ReportRedirectResult(nsresult aRv);
311};
312
313void AutoRedirectVetoNotifier::ReportRedirectResult(nsresult aRv) {
314 if (!mChannel) return;
315
316 if (mCalledReport) {
317 return;
318 }
319 mCalledReport = true;
320
321 mChannel->mRedirectChannel = nullptr;
322
323 if (NS_SUCCEEDED(aRv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aRv)), 1)))) {
324 mChannel->RemoveAsNonTailRequest();
325 }
326
327 nsCOMPtr<nsIRedirectResultListener> vetoHook;
328 NS_QueryNotificationCallbacks(mChannel, NS_GET_IID(nsIRedirectResultListener)(nsIRedirectResultListener::COMTypeInfo<nsIRedirectResultListener
, void>::kIID)
,
329 getter_AddRefs(vetoHook));
330
331 nsHttpChannel* channel = mChannel;
332 mChannel = nullptr;
333
334 if (vetoHook) vetoHook->OnRedirectResult(aRv);
335
336 // Drop after the notification
337 channel->StoreHasAutoRedirectVetoNotifier(false);
338}
339
340//-----------------------------------------------------------------------------
341// nsHttpChannel <public>
342//-----------------------------------------------------------------------------
343
344nsHttpChannel::nsHttpChannel() : HttpAsyncAborter<nsHttpChannel>(this) {
345 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)
346 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)
;
347 mChannelCreationTime = PR_Now();
348 mChannelCreationTimestamp = TimeStamp::Now();
349}
350
351nsHttpChannel::~nsHttpChannel() {
352 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)
353 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)
;
354
355 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(mozilla::net::
gHttpLog, mozilla::LogLevel::Verbose)), 0))
) {
356 nsCString webExtension;
357 this->GetPropertyAsACString(u"cancelledByExtension"_ns, webExtension);
358 if (!webExtension.IsEmpty()) {
359 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)
360 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)
;
361 }
362 }
363
364 if (mAuthProvider) {
365 DebugOnly<nsresult> rv = mAuthProvider->Disconnect(NS_ERROR_ABORT);
366 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"
, 366); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 366; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
367 }
368
369 ReleaseMainThreadOnlyReferences();
370 if (gHttpHandler) {
371 gHttpHandler->RemoveHttpChannel(mChannelId);
372 }
373}
374
375void nsHttpChannel::ReleaseMainThreadOnlyReferences() {
376 if (NS_IsMainThread()) {
377 // Already on main thread, let dtor to
378 // take care of releasing references
379 return;
380 }
381
382 nsTArray<nsCOMPtr<nsISupports>> arrayToRelease;
383 arrayToRelease.AppendElement(mAuthProvider.forget());
384 arrayToRelease.AppendElement(mRedirectChannel.forget());
385 arrayToRelease.AppendElement(mPreflightChannel.forget());
386 arrayToRelease.AppendElement(mDNSPrefetch.forget());
387
388 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"
, 390); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mEarlyHintObserver"
") (" "Early hint observer should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 390; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
389 !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"
, 390); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mEarlyHintObserver"
") (" "Early hint observer should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 390; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
390 "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"
, 390); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mEarlyHintObserver"
") (" "Early hint observer should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 390; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
391 arrayToRelease.AppendElement(mEarlyHintObserver.forget());
392 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"
, 394); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mChannelClassifier"
") (" "Channel classifier should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 394; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
393 !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"
, 394); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mChannelClassifier"
") (" "Channel classifier should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 394; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
394 "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"
, 394); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mChannelClassifier"
") (" "Channel classifier should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 394; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
395 arrayToRelease.AppendElement(
396 mChannelClassifier.forget().downcast<nsIURIClassifierCallback>());
397 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"
, 399); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mWarningReporter"
") (" "Warning reporter should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 399; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
398 !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"
, 399); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mWarningReporter"
") (" "Warning reporter should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 399; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
399 "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"
, 399); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mWarningReporter"
") (" "Warning reporter should have been released in ReleaseListeners()"
")"); do { *((volatile int*)__null) = 399; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
400 arrayToRelease.AppendElement(mWarningReporter.forget());
401
402 NS_DispatchToMainThread(new ProxyReleaseRunnable(std::move(arrayToRelease)));
403}
404
405nsresult nsHttpChannel::Init(nsIURI* uri, uint32_t caps, nsProxyInfo* proxyInfo,
406 uint32_t proxyResolveFlags, nsIURI* proxyURI,
407 uint64_t channelId,
408 ExtContentPolicyType aContentPolicyType,
409 nsILoadInfo* aLoadInfo) {
410 nsresult rv =
411 HttpBaseChannel::Init(uri, caps, proxyInfo, proxyResolveFlags, proxyURI,
412 channelId, aContentPolicyType, aLoadInfo);
413 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
414
415 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)
;
416
417 return rv;
418}
419
420nsresult nsHttpChannel::AddSecurityMessage(const nsAString& aMessageTag,
421 const nsAString& aMessageCategory) {
422 if (mWarningReporter) {
423 return mWarningReporter->ReportSecurityMessage(aMessageTag,
424 aMessageCategory);
425 }
426 return HttpBaseChannel::AddSecurityMessage(aMessageTag, aMessageCategory);
427}
428
429NS_IMETHODIMPnsresult
430nsHttpChannel::LogBlockedCORSRequest(const nsAString& aMessage,
431 const nsACString& aCategory,
432 bool aIsWarning) {
433 if (mWarningReporter) {
434 return mWarningReporter->LogBlockedCORSRequest(aMessage, aCategory,
435 aIsWarning);
436 }
437 return NS_ERROR_UNEXPECTED;
438}
439
440NS_IMETHODIMPnsresult
441nsHttpChannel::LogMimeTypeMismatch(const nsACString& aMessageName,
442 bool aWarning, const nsAString& aURL,
443 const nsAString& aContentType) {
444 if (mWarningReporter) {
445 return mWarningReporter->LogMimeTypeMismatch(aMessageName, aWarning, aURL,
446 aContentType);
447 }
448 return NS_ERROR_UNEXPECTED;
449}
450
451//-----------------------------------------------------------------------------
452// nsHttpChannel <private>
453//-----------------------------------------------------------------------------
454
455nsresult nsHttpChannel::PrepareToConnect() {
456 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)
;
457
458 // notify "http-on-modify-request-before-cookies" observers
459 gHttpHandler->OnModifyRequestBeforeCookies(this);
460
461 AddCookiesToRequest();
462
463#if defined(XP_WIN) || defined(XP_MACOSX)
464
465 auto prefEnabledForCurrentContainer = [&]() {
466 uint32_t containerId = mLoadInfo->GetOriginAttributes().mUserContextId;
467 // Make sure that the default container ID is 0
468 static_assert(nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID == 0);
469
470 nsAutoCString prefName;
471# ifdef XP_WIN
472 prefName = nsPrintfCString("network.http.windows-sso.container-enabled.%u",
473 containerId);
474# endif
475
476# ifdef XP_MACOSX
477 prefName = nsPrintfCString(
478 "network.http.microsoft-entra-sso.container-enabled.%u", containerId);
479# endif
480
481 bool enabled = false;
482 Preferences::GetBool(prefName.get(), &enabled);
483
484 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)
;
485
486 return enabled;
487 };
488
489#endif // defined(XP_WIN) || defined(XP_MACOSX)
490
491#ifdef XP_WIN
492
493 // If Windows 10 SSO is enabled, we potentially add auth
494 // information to secure top level loads (DOCUMENTs) and iframes
495 // (SUBDOCUMENTs) that aren't anonymous or private browsing.
496 if (StaticPrefs::network_http_windows_sso_enabled() &&
497 mURI->SchemeIs("https") && !(mLoadFlags & LOAD_ANONYMOUS) &&
498 !mPrivateBrowsing) {
499 ExtContentPolicyType type = mLoadInfo->GetExternalContentPolicyType();
500 if ((type == ExtContentPolicy::TYPE_DOCUMENT ||
501 type == ExtContentPolicy::TYPE_SUBDOCUMENT) &&
502 prefEnabledForCurrentContainer()) {
503 AddWindowsSSO(this);
504 }
505 }
506#endif
507
508#ifdef XP_MACOSX
509
510 auto isUriMSAuthority = [&]() {
511 nsAutoCString endPoint;
512 nsresult rv = mURI->GetHost(endPoint);
513 if (!NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
514 return false;
515 }
516 LOG(("endPoint is %s\n", endPoint.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
, "endPoint is %s\n", endPoint.get()); } } while (0)
;
517
518 return gHttpHandler->IsHostMSAuthority(endPoint);
519 };
520
521 // If macOS SSO is enabled, we potentially add auth
522 // information to secure top level loads (DOCUMENTs) and iframes
523 // (SUBDOCUMENTs) that aren't anonymous or private browsing.
524 if (StaticPrefs::network_http_microsoft_entra_sso_enabled() &&
525 mURI->SchemeIs("https") && !(mLoadFlags & LOAD_ANONYMOUS) &&
526 !mPrivateBrowsing) {
527 ExtContentPolicyType type = mLoadInfo->GetExternalContentPolicyType();
528 if ((type == ExtContentPolicy::TYPE_DOCUMENT ||
529 type == ExtContentPolicy::TYPE_SUBDOCUMENT) &&
530 prefEnabledForCurrentContainer() && isUriMSAuthority()) {
531 nsMainThreadPtrHandle<nsHttpChannel> self(
532 new nsMainThreadPtrHolder<nsHttpChannel>(
533 "nsHttpChannel::PrepareToConnect::self", this));
534 auto resultCallback = [self(self)]() {
535 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"
, 535); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 535; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
536 nsresult rv = self->ContinuePrepareToConnect();
537 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
538 self->CloseCacheEntry(false);
539 Unused << self->AsyncAbort(rv);
540 }
541 };
542
543 nsresult rv = AddMicrosoftEntraSSO(this, std::move(resultCallback));
544
545 // Returns NS_OK if performRequests is called in MicrosoftEntraSSOUtils
546 // This temporarily stops the channel setup for the delegate.
547 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
548 return rv;
549 }
550 }
551 }
552
553#endif
554
555 return ContinuePrepareToConnect();
556}
557
558nsresult nsHttpChannel::ContinuePrepareToConnect() {
559 // notify "http-on-modify-request" observers
560 CallOnModifyRequestObservers();
561
562 return CallOrWaitForResume(
563 [](auto* self) { return self->OnBeforeConnect(); });
564}
565
566void nsHttpChannel::HandleContinueCancellingByURLClassifier(
567 nsresult aErrorCode) {
568 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"
, 569); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 569; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
569 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"
, 569); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 569; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
570 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"
, 570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 570; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
571
572 if (mSuspendCount) {
573 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)
574 ("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)
575 "[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)
576 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)
;
577 mCallOnResume = [aErrorCode](nsHttpChannel* self) {
578 self->HandleContinueCancellingByURLClassifier(aErrorCode);
579 return NS_OK;
580 };
581 return;
582 }
583
584 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)
585 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)
;
586 ContinueCancellingByURLClassifier(aErrorCode);
587}
588
589void nsHttpChannel::SetPriorityHeader() {
590 nsAutoCString userSetPriority;
591 Unused << GetRequestHeader("Priority"_ns, userSetPriority);
592 if (!userSetPriority.IsEmpty()) {
593 // If the Priority header is set by the user, do not override it.
594 return;
595 }
596
597 uint8_t urgency =
598 nsHttpHandler::UrgencyFromCoSFlags(mClassOfService.Flags(), mPriority);
599 bool incremental = mClassOfService.Incremental();
600
601 nsPrintfCString value(
602 "%s", urgency != 3 ? nsPrintfCString("u=%d", urgency).get() : "");
603
604 if (incremental) {
605 if (!value.IsEmpty()) {
606 value.Append(", ");
607 }
608 value.Append("i");
609 }
610
611 if (!value.IsEmpty()) {
612 SetRequestHeader("Priority"_ns, value, false);
613 }
614}
615
616nsresult nsHttpChannel::OnBeforeConnect() {
617 nsresult rv = NS_OK;
618
619 // Check if request was cancelled during suspend AFTER on-modify-request
620 if (mCanceled) {
621 return mStatus;
622 }
623
624 // Check to see if we should redirect this channel elsewhere by
625 // nsIHttpChannel.redirectTo API request
626 if (mAPIRedirectTo) {
627 return AsyncCall(&nsHttpChannel::HandleAsyncAPIRedirect);
628 }
629
630 // Note that we are only setting the "Upgrade-Insecure-Requests" request
631 // header for *all* navigational requests instead of all requests as
632 // defined in the spec, see:
633 // https://www.w3.org/TR/upgrade-insecure-requests/#preference
634 ExtContentPolicyType type = mLoadInfo->GetExternalContentPolicyType();
635
636 if (type == ExtContentPolicy::TYPE_DOCUMENT ||
637 type == ExtContentPolicy::TYPE_SUBDOCUMENT) {
638 rv = SetRequestHeader("Upgrade-Insecure-Requests"_ns, "1"_ns, false);
639 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"
, 639); return rv; } } while (false)
;
640 }
641
642 if (LoadAuthRedirectedChannel()) {
643 // This channel is a result of a redirect due to auth retry
644 // We have already checked for HSTS upgarde in the redirecting channel.
645 // We can safely skip those checks
646 return ContinueOnBeforeConnect(false, rv);
647 }
648
649 SecFetch::AddSecFetchHeader(this);
650
651 // Check to see if we should redirect this channel to the unstripped URI. To
652 // revert the query stripping if the loading channel is in the content
653 // blocking allow list.
654 if (ContentBlockingAllowList::Check(this)) {
655 nsCOMPtr<nsIURI> unstrippedURI;
656 mLoadInfo->GetUnstrippedURI(getter_AddRefs(unstrippedURI));
657
658 if (unstrippedURI) {
659 return AsyncCall(&nsHttpChannel::HandleAsyncRedirectToUnstrippedURI);
660 }
661 }
662
663 nsCOMPtr<nsIPrincipal> resultPrincipal;
664 if (!mURI->SchemeIs("https")) {
665 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
666 this, getter_AddRefs(resultPrincipal));
667 }
668
669 // Check if we already know about the HSTS status of the host
670 nsISiteSecurityService* sss = gHttpHandler->GetSSService();
671 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"
, 671); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
672 bool isSecureURI;
673 OriginAttributes originAttributes;
674 if (!StoragePrincipalHelper::GetOriginAttributesForHSTS(this,
675 originAttributes)) {
676 return NS_ERROR_FAILURE;
677 }
678 rv = sss->IsSecureURI(mURI, originAttributes, &isSecureURI);
679 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"
, 679); return rv; } } while (false)
;
680 // Save that on the loadInfo so it can later be consumed by
681 // SecurityInfo.sys.mjs
682 mLoadInfo->SetHstsStatus(isSecureURI);
683
684 RefPtr<mozilla::dom::BrowsingContext> bc;
685 mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
686 // If bypassing the cache and we're forced offline
687 // we can just return the error here.
688 if (bc && bc->Top()->GetForceOffline() &&
689 BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass())((mLoadFlags) & (nsIRequest::LOAD_BYPASS_CACHE | nsICachingChannel
::LOAD_BYPASS_LOCAL_CACHE) && !(((mLoadFlags) & nsIRequest
::LOAD_FROM_CACHE) && (LoadPreferCacheLoadOverBypass(
))))
) {
690 return NS_ERROR_OFFLINE;
691 }
692
693 // At this point it is no longer possible to call
694 // HttpBaseChannel::UpgradeToSecure.
695 StoreUpgradableToSecure(false);
696 bool shouldUpgrade = LoadUpgradeToSecure();
697 if (mURI->SchemeIs("http")) {
698 OriginAttributes originAttributes;
699 if (!StoragePrincipalHelper::GetOriginAttributesForHSTS(this,
700 originAttributes)) {
701 return NS_ERROR_FAILURE;
702 }
703
704 if (!shouldUpgrade) {
705 // Make sure http channel is released on main thread.
706 // See bug 1539148 for details.
707 nsMainThreadPtrHandle<nsHttpChannel> self(
708 new nsMainThreadPtrHolder<nsHttpChannel>(
709 "nsHttpChannel::OnBeforeConnect::self", this));
710 auto resultCallback = [self(self)](bool aResult, nsresult aStatus) {
711 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"
, 711); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 711; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
712
713 nsresult rv = self->MaybeUseHTTPSRRForUpgrade(aResult, aStatus);
714 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
715 self->CloseCacheEntry(false);
716 Unused << self->AsyncAbort(rv);
717 }
718 };
719
720 bool willCallback = false;
721 rv = NS_ShouldSecureUpgrade(
722 mURI, mLoadInfo, resultPrincipal, LoadAllowSTS(), originAttributes,
723 shouldUpgrade, std::move(resultCallback), willCallback);
724 // If the request gets upgraded because of the HTTPS-Only mode, but no
725 // event listener has been registered so far, we want to do that here.
726 uint32_t httpOnlyStatus = mLoadInfo->GetHttpsOnlyStatus();
727 if (httpOnlyStatus &
728 nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_NOT_REGISTERED) {
729 RefPtr<nsHTTPSOnlyStreamListener> httpsOnlyListener =
730 new nsHTTPSOnlyStreamListener(mListener, mLoadInfo);
731 mListener = httpsOnlyListener;
732
733 httpOnlyStatus ^=
734 nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_NOT_REGISTERED;
735 httpOnlyStatus |= nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_REGISTERED;
736 mLoadInfo->SetHttpsOnlyStatus(httpOnlyStatus);
737 }
738 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)
739 ("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)
740 "[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)
741 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)
;
742
743 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || MOZ_UNLIKELY(willCallback)(__builtin_expect(!!(willCallback), 0))) {
744 return rv;
745 }
746 }
747 }
748
749 return MaybeUseHTTPSRRForUpgrade(shouldUpgrade, NS_OK);
750}
751
752// Returns true if the network connectivity checker indicated
753// that HTTPS records can be resolved on this network - false otherwise.
754// When TRR is enabled, we always return true, as resolving HTTPS
755// records don't depend on the network.
756static bool canUseHTTPSRRonNetwork(bool& aTRREnabled) {
757 // Respect the pref.
758 if (StaticPrefs::network_dns_force_use_https_rr()) {
759 aTRREnabled = true;
760 return true;
761 }
762
763 aTRREnabled = false;
764
765 if (nsCOMPtr<nsIDNSService> dns = mozilla::components::DNS::Service()) {
766 nsIDNSService::ResolverMode mode;
767 // If the browser is currently using TRR/DoH, then it can
768 // definitely resolve HTTPS records.
769 if (NS_SUCCEEDED(dns->GetCurrentTrrMode(&mode))((bool)(__builtin_expect(!!(!NS_FAILED_impl(dns->GetCurrentTrrMode
(&mode))), 1)))
) {
770 if (mode == nsIDNSService::MODE_TRRFIRST) {
771 RefPtr<TRRService> trr = TRRService::Get();
772 if (trr && trr->IsConfirmed()) {
773 aTRREnabled = true;
774 }
775 } else if (mode == nsIDNSService::MODE_TRRONLY) {
776 aTRREnabled = true;
777 }
778 if (aTRREnabled) {
779 return true;
780 }
781 }
782 }
783
784 if (RefPtr<NetworkConnectivityService> ncs =
785 NetworkConnectivityService::GetSingleton()) {
786 nsINetworkConnectivityService::ConnectivityState state;
787 if (NS_SUCCEEDED(ncs->GetDNS_HTTPS(&state))((bool)(__builtin_expect(!!(!NS_FAILED_impl(ncs->GetDNS_HTTPS
(&state))), 1)))
&&
788 state == nsINetworkConnectivityService::NOT_AVAILABLE) {
789 return false;
790 }
791 }
792 return true;
793}
794
795nsresult nsHttpChannel::MaybeUseHTTPSRRForUpgrade(bool aShouldUpgrade,
796 nsresult aStatus) {
797 if (NS_FAILED(aStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus)), 0)))) {
798 return aStatus;
799 }
800
801 RefPtr<mozilla::dom::BrowsingContext> bc;
802 mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
803 bool forceOffline = bc && bc->Top()->GetForceOffline();
804
805 if (mURI->SchemeIs("https") || aShouldUpgrade || !LoadUseHTTPSSVC() ||
806 forceOffline) {
807 return ContinueOnBeforeConnect(aShouldUpgrade, aStatus);
808 }
809
810 auto shouldSkipUpgradeWithHTTPSRR = [&]() -> bool {
811 if (mCaps & NS_HTTP_DISALLOW_HTTPS_RR(1 << 24)) {
812 return true;
813 }
814
815 // Skip using HTTPS RR to upgrade when this is not a top-level load and the
816 // loading principal is http.
817 if ((mLoadInfo->GetExternalContentPolicyType() !=
818 ExtContentPolicy::TYPE_DOCUMENT) &&
819 (mLoadInfo->GetLoadingPrincipal() &&
820 mLoadInfo->GetLoadingPrincipal()->SchemeIs("http"))) {
821 return true;
822 }
823
824 // If the network connectivity checker indicates the network is
825 // blocking HTTPS requests, then we should skip them so we don't
826 // needlessly wait for a timeout.
827 bool trrEnabled = false;
828 if (!canUseHTTPSRRonNetwork(trrEnabled)) {
829 return true;
830 }
831
832 // Don't block the channel when TRR is not used.
833 if (!trrEnabled) {
834 return true;
835 }
836
837 auto dnsStrategy = GetProxyDNSStrategy();
838 if (dnsStrategy != ProxyDNSStrategy::ORIGIN) {
839 return true;
840 }
841
842 nsAutoCString uriHost;
843 mURI->GetAsciiHost(uriHost);
844
845 return gHttpHandler->IsHostExcludedForHTTPSRR(uriHost);
846 };
847
848 if (shouldSkipUpgradeWithHTTPSRR()) {
849 StoreUseHTTPSSVC(false);
850 // If the website does not want to use HTTPS RR, we should set
851 // NS_HTTP_DISALLOW_HTTPS_RR. This is for avoiding HTTPS RR being used by
852 // the transaction.
853 DisallowHTTPSRR(mCaps);
854 return ContinueOnBeforeConnect(aShouldUpgrade, aStatus);
855 }
856
857 if (mHTTPSSVCRecord.isSome()) {
858 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)
859 "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)
860 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)
;
861 StoreWaitHTTPSSVCRecord(false);
862 bool hasHTTPSRR = (mHTTPSSVCRecord.ref() != nullptr);
863 return ContinueOnBeforeConnect(hasHTTPSRR, aStatus, hasHTTPSRR);
864 }
865
866 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)
867 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)
;
868
869 OriginAttributes originAttributes;
870 StoragePrincipalHelper::GetOriginAttributesForHTTPSRR(this, originAttributes);
871
872 RefPtr<nsDNSPrefetch> resolver =
873 new nsDNSPrefetch(mURI, originAttributes, nsIRequest::GetTRRMode());
874 nsWeakPtr weakPtrThis(
875 do_GetWeakReference(static_cast<nsIHttpChannel*>(this)));
876 nsresult rv = resolver->FetchHTTPSSVC(
877 mCaps & NS_HTTP_REFRESH_DNS(1 << 3), !LoadUseHTTPSSVC(),
878 [weakPtrThis](nsIDNSHTTPSSVCRecord* aRecord) {
879 nsCOMPtr<nsIHttpChannel> channel = do_QueryReferent(weakPtrThis);
880 RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(channel);
881 if (httpChannelImpl) {
882 httpChannelImpl->OnHTTPSRRAvailable(aRecord);
883 }
884 });
885 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
886 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)
887 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)
;
888 return ContinueOnBeforeConnect(aShouldUpgrade, aStatus);
889 }
890
891 StoreWaitHTTPSSVCRecord(true);
892 return NS_OK;
893}
894
895nsresult nsHttpChannel::ContinueOnBeforeConnect(bool aShouldUpgrade,
896 nsresult aStatus,
897 bool aUpgradeWithHTTPSRR) {
898 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)
899 ("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)
900 "[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)
901 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)
;
902
903 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"
, 903); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadWaitHTTPSSVCRecord()"
")"); do { *((volatile int*)__null) = 903; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
904
905 if (NS_FAILED(aStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus)), 0)))) {
906 return aStatus;
907 }
908
909 if (aShouldUpgrade && !mURI->SchemeIs("https")) {
910 // only set HTTPS_RR to be responsbile for the upgrade in the loadinfo
911 // if it actually was responsible, otherwise the correct flag is
912 // already present in the loadinfo.
913 if (aUpgradeWithHTTPSRR) {
914 mLoadInfo->SetHttpsUpgradeTelemetry(nsILoadInfo::HTTPS_RR);
915 }
916 return AsyncCall(&nsHttpChannel::HandleAsyncRedirectChannelToHttps);
917 }
918
919 // ensure that we are using a valid hostname
920 if (!net_IsValidDNSHost(nsDependentCString(mConnectionInfo->Origin()))) {
921 return NS_ERROR_UNKNOWN_HOST;
922 }
923
924 if (mUpgradeProtocolCallback) {
925 // Websockets can run over HTTP/2, but other upgrades can't.
926 if (mUpgradeProtocol.EqualsLiteral("websocket") &&
927 StaticPrefs::network_http_http2_websockets()) {
928 // Need to tell the conn manager that we're ok with http/2 even with
929 // the allow keepalive bit not set. That bit needs to stay off,
930 // though, in case we end up having to fallback to http/1.1 (where
931 // we absolutely do want to disable keepalive).
932 mCaps |= NS_HTTP_ALLOW_SPDY_WITHOUT_KEEPALIVE(1 << 15);
933 } else {
934 mCaps |= NS_HTTP_DISALLOW_SPDY(1 << 7);
935 }
936 // Upgrades cannot use HTTP/3.
937 mCaps |= NS_HTTP_DISALLOW_HTTP3(1 << 21);
938 // Because NS_HTTP_STICKY_CONNECTION breaks HTTPS RR fallabck mecnahism, we
939 // can not use HTTPS RR for upgrade requests.
940 DisallowHTTPSRR(mCaps);
941 }
942
943 if (LoadIsTRRServiceChannel()) {
944 mCaps |= NS_HTTP_LARGE_KEEPALIVE(1 << 1);
945 DisallowHTTPSRR(mCaps);
946 }
947
948 if (mTransactionSticky) {
949 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"
, 949); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadAuthRedirectedChannel()"
")"); do { *((volatile int*)__null) = 949; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
950 // this means this is a redirected channel channel due to auth retry and a
951 // connection based auth scheme was used
952 // we have a reference to the old-transaction with sticky connection which
953 // we need to use
954 mCaps |= NS_HTTP_STICKY_CONNECTION(1 << 2);
955 }
956
957 mCaps |= NS_HTTP_TRR_FLAGS_FROM_MODE(nsIRequest::GetTRRMode())((static_cast<uint32_t>(nsIRequest::GetTRRMode()) &
3) << 19)
;
958
959 // Finalize ConnectionInfo flags before SpeculativeConnect
960 mConnectionInfo->SetAnonymous((mLoadFlags & LOAD_ANONYMOUS) != 0);
961 mConnectionInfo->SetPrivate(mPrivateBrowsing);
962 mConnectionInfo->SetNoSpdy(mCaps & NS_HTTP_DISALLOW_SPDY(1 << 7));
963 mConnectionInfo->SetBeConservative((mCaps & NS_HTTP_BE_CONSERVATIVE(1 << 11)) ||
964 LoadBeConservative());
965 mConnectionInfo->SetTlsFlags(mTlsFlags);
966 mConnectionInfo->SetIsTrrServiceChannel(LoadIsTRRServiceChannel());
967 mConnectionInfo->SetTRRMode(nsIRequest::GetTRRMode());
968 mConnectionInfo->SetIPv4Disabled(mCaps & NS_HTTP_DISABLE_IPV4(1 << 17));
969 mConnectionInfo->SetIPv6Disabled(mCaps & NS_HTTP_DISABLE_IPV6(1 << 18));
970 mConnectionInfo->SetAnonymousAllowClientCert(
971 (mLoadFlags & LOAD_ANONYMOUS_ALLOW_CLIENT_CERT) != 0);
972
973 if (mWebTransportSessionEventListener) {
974 nsTArray<RefPtr<nsIWebTransportHash>> aServerCertHashes;
975 nsresult rv;
976 nsCOMPtr<WebTransportConnectionSettings> wtconSettings =
977 do_QueryInterface(mWebTransportSessionEventListener, &rv);
978 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"
, 978); return rv; } } while (false)
;
979
980 wtconSettings->GetServerCertificateHashes(aServerCertHashes);
981 gHttpHandler->ConnMgr()->StoreServerCertHashes(
982 mConnectionInfo, gHttpHandler->IsHttp2Excluded(mConnectionInfo),
983 !Http3Allowed(), std::move(aServerCertHashes));
984 }
985
986 if (ShouldIntercept()) {
987 return RedirectToInterceptedChannel();
988 }
989
990 // notify "http-on-before-connect" observers
991 gHttpHandler->OnBeforeConnect(this);
992
993 return CallOrWaitForResume([](auto* self) { return self->Connect(); });
994}
995
996class MOZ_STACK_CLASS AddResponseHeadersToResponseHead final
997 : public nsIHttpHeaderVisitor {
998 public:
999 explicit AddResponseHeadersToResponseHead(nsHttpResponseHead* aResponseHead)
1000 : mResponseHead(aResponseHead) {}
1001
1002 NS_IMETHODvirtual nsresult VisitHeader(const nsACString& aHeader,
1003 const nsACString& aValue) override {
1004 nsAutoCString headerLine = aHeader + ": "_ns + aValue;
1005 DebugOnly<nsresult> rv = mResponseHead->ParseHeaderLine(headerLine);
1006 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"
, 1006); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1006; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1007
1008 return NS_OK;
1009 }
1010
1011 NS_IMETHODvirtual nsresult QueryInterface(REFNSIIDconst nsIID& aIID, void** aInstancePtr) override;
1012
1013 // Stub AddRef/Release since this is a stack class.
1014 NS_IMETHOD_(MozExternalRefCountType)virtual MozExternalRefCountType AddRef(void) override {
1015 return ++mRefCnt;
1016 }
1017
1018 NS_IMETHOD_(MozExternalRefCountType)virtual MozExternalRefCountType Release(void) override {
1019 return --mRefCnt;
1020 }
1021
1022 virtual ~AddResponseHeadersToResponseHead() {
1023 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"
, 1023); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mRefCnt == 0"
")"); do { *((volatile int*)__null) = 1023; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1024 }
1025
1026 private:
1027 nsHttpResponseHead* mResponseHead;
1028
1029 nsrefcnt mRefCnt = 0;
1030};
1031
1032NS_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"
, 1032); 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(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
1033
1034nsresult nsHttpChannel::HandleOverrideResponse() {
1035 // Start building a response with the data from mOverrideResponse.
1036 mResponseHead = MakeUnique<nsHttpResponseHead>();
1037
1038 // Apply override response status code and status text.
1039 uint32_t statusCode;
1040 nsresult rv = mOverrideResponse->GetResponseStatus(&statusCode);
1041 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"
, 1041); return rv; } } while (false)
;
1042
1043 nsAutoCString statusText;
1044 rv = mOverrideResponse->GetResponseStatusText(statusText);
1045 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"
, 1045); return rv; } } while (false)
;
1046
1047 // Hardcoding protocol HTTP/1.1
1048 nsPrintfCString line("HTTP/1.1 %u %s", statusCode, statusText.get());
1049 rv = mResponseHead->ParseStatusLine(line);
1050 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"
, 1050); return rv; } } while (false)
;
1051
1052 // Apply override response headers.
1053 AddResponseHeadersToResponseHead visitor(mResponseHead.get());
1054 rv = mOverrideResponse->VisitResponseHeaders(&visitor);
1055 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"
, 1055); return rv; } } while (false)
;
1056
1057 if (WillRedirect(*mResponseHead)) {
1058 // TODO: Bug 759040 - We should call HandleAsyncRedirect directly here,
1059 // to avoid event dispatching latency.
1060 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)
;
1061 return AsyncCall(&nsHttpChannel::HandleAsyncRedirect);
1062 }
1063
1064 // Handle Set-Cookie headers as if the response was from networking.
1065 CookieVisitor cookieVisitor(mResponseHead.get());
1066 SetCookieHeaders(cookieVisitor.CookieHeaders());
1067 nsCOMPtr<nsIParentChannel> parentChannel;
1068 NS_QueryNotificationCallbacks(this, parentChannel);
1069 if (RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel)) {
1070 httpParent->SetCookieHeaders(cookieVisitor.CookieHeaders());
1071 }
1072
1073 rv = ProcessSecurityHeaders();
1074 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1075 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"
, 1075)
;
1076 }
1077
1078 if ((statusCode < 500) && (statusCode != 421)) {
1079 ProcessAltService();
1080 }
1081
1082 nsAutoCString body;
1083 rv = mOverrideResponse->GetResponseBody(body);
1084 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"
, 1084); return rv; } } while (false)
;
1085
1086 nsCOMPtr<nsIInputStream> stringStream;
1087 rv = NS_NewCStringInputStream(getter_AddRefs(stringStream), body);
1088 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"
, 1088); return rv; } } while (false)
;
1089 rv = nsInputStreamPump::Create(getter_AddRefs(mCachePump), stringStream, 0, 0,
1090 true);
1091 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1092 stringStream->Close();
1093 return rv;
1094 }
1095
1096 rv = mCachePump->AsyncRead(this);
1097 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
1098
1099 return NS_OK;
1100}
1101
1102nsresult nsHttpChannel::Connect() {
1103 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)
;
1104
1105 if (mAPIRedirectTo) {
1106 LOG(("nsHttpChannel::Connect [transparent=%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::Connect [transparent=%d]\n", mAPIRedirectTo
->second()); } } while (0)
1107 mAPIRedirectTo->second()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__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 [transparent=%d]\n", mAPIRedirectTo
->second()); } } while (0)
;
1108
1109 nsresult rv = StartRedirectChannelToURI(
1110 mAPIRedirectTo->first(),
1111 mAPIRedirectTo->second() ? nsIChannelEventSink::REDIRECT_PERMANENT |
1112 nsIChannelEventSink::REDIRECT_TRANSPARENT
1113 : nsIChannelEventSink::REDIRECT_PERMANENT);
1114 mAPIRedirectTo = Nothing();
1115 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
1116 return NS_OK;
1117 }
1118 return NS_ERROR_FAILURE;
1119 }
1120
1121 // If mOverrideResponse is set, bypass the rest of the connection and reply
1122 // immediately with a response built using the data from mOverrideResponse.
1123 if (mOverrideResponse) {
1124 return HandleOverrideResponse();
1125 }
1126
1127 // Don't allow resuming when cache must be used
1128 if (LoadResuming() && (mLoadFlags & LOAD_ONLY_FROM_CACHE)) {
1129 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)
;
1130 return NS_ERROR_DOCUMENT_NOT_CACHED;
1131 }
1132
1133 // Step 8.18 of HTTP-network-or-cache fetch
1134 // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch
1135 nsAutoCString rangeVal;
1136 if (NS_SUCCEEDED(GetRequestHeader("Range"_ns, rangeVal))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetRequestHeader(
"Range"_ns, rangeVal))), 1)))
) {
1137 SetRequestHeader("Accept-Encoding"_ns, "identity"_ns, true);
1138 }
1139
1140 if (mRequestHead.IsPost() || mRequestHead.IsPatch()) {
1141 // If the post id is already set then this is an attempt to replay
1142 // a post/patch transaction via the cache. Otherwise, we need a unique
1143 // post id for this transaction.
1144 if (mPostID == 0) {
1145 mPostID = gHttpHandler->GenerateUniqueID();
1146 }
1147
1148 if (StaticPrefs::network_http_idempotencyKey_enabled() &&
1149 !mRequestHead.HasHeader(nsHttp::Idempotency_Key)) {
1150 // check if we need to add
1151 // idempotency-key header
1152 // See Bug 1830022 for more details
1153 nsAutoCString key;
1154 gHttpHandler->GenerateIdempotencyKeyForPost(mPostID, mLoadInfo, key);
1155 MOZ_ALWAYS_SUCCEEDS(do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mRequestHead.SetHeader(nsHttp::Idempotency_Key, key, false))
), 1)))), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Idempotency_Key, key, false))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1156); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Idempotency_Key, key, false))"
")"); do { *((volatile int*)__null) = 1156; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1156 mRequestHead.SetHeader(nsHttp::Idempotency_Key, key, false))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mRequestHead.SetHeader(nsHttp::Idempotency_Key, key, false))
), 1)))), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Idempotency_Key, key, false))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1156); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Idempotency_Key, key, false))"
")"); do { *((volatile int*)__null) = 1156; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
1157 }
1158 }
1159
1160#ifdef MOZ_WIDGET_ANDROID
1161 bool val = false;
1162 if (nsIOService::ShouldAddAdditionalSearchHeaders(mURI, &val)) {
1163 SetRequestHeader("X-Search-Subdivision"_ns, val ? "1"_ns : "0"_ns, false);
1164 }
1165#endif
1166
1167 bool isTrackingResource = IsThirdPartyTrackingResource();
1168 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)
1169 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)
1170 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)
;
1171
1172 if (isTrackingResource) {
1173 AddClassFlags(nsIClassOfService::Tail);
1174 }
1175
1176 if (WaitingForTailUnblock()) {
1177 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"
, 1177); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mOnTailUnblock"
")"); do { *((volatile int*)__null) = 1177; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1178 mOnTailUnblock = &nsHttpChannel::ConnectOnTailUnblock;
1179 return NS_OK;
1180 }
1181
1182 return ConnectOnTailUnblock();
1183}
1184
1185nsresult nsHttpChannel::ConnectOnTailUnblock() {
1186 nsresult rv;
1187
1188 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)
;
1189
1190 // Consider opening a TCP connection right away.
1191 SpeculativeConnect();
1192
1193 // open a cache entry for this channel...
1194 rv = OpenCacheEntry(mURI->SchemeIs("https"));
1195
1196 // do not continue if asyncOpenCacheEntry is in progress
1197 if (AwaitingCacheCallbacks()) {
1198 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)
1199 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)
;
1200 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"
, 1200); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
") (" "Unexpected state" ")"); do { *((volatile int*)__null)
= 1200; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
1201
1202 if (mNetworkTriggered && mWaitingForProxy) {
1203 // Someone has called TriggerNetwork(), meaning we are racing the
1204 // network with the cache.
1205 mWaitingForProxy = false;
1206 return ContinueConnect();
1207 }
1208
1209 return NS_OK;
1210 }
1211
1212 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1213 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)
1214 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)
;
1215 // if this channel is only allowed to pull from the cache, then
1216 // we must fail if we were unable to open a cache entry.
1217 if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
1218 return NS_ERROR_DOCUMENT_NOT_CACHED;
1219 }
1220 // otherwise, let's just proceed without using the cache.
1221 }
1222
1223 if (mRaceCacheWithNetwork && ((mCacheEntry && !CachedContentIsValid() &&
1224 (mDidReval || LoadCachedContentIsPartial())) ||
1225 mIgnoreCacheEntry)) {
1226 // We won't send the conditional request because the unconditional
1227 // request was already sent (see bug 1377223).
1228 AccumulateCategorical(
1229 Telemetry::LABELS_NETWORK_RACE_CACHE_VALIDATION::NotSent);
1230 }
1231
1232 // When racing, if OnCacheEntryAvailable is called before AsyncOpenURI
1233 // returns, then we may not have started reading from the cache.
1234 // If the content is valid, we should attempt to do so, as technically the
1235 // cache has won the race.
1236 if (mRaceCacheWithNetwork && CachedContentIsValid()) {
1237 Unused << ReadFromCache();
1238 }
1239
1240 return TriggerNetwork();
1241}
1242
1243nsresult nsHttpChannel::ContinueConnect() {
1244 // If we need to start a CORS preflight, do it now!
1245 // Note that it is important to do this before the early returns below.
1246 if (!LoadIsCorsPreflightDone() && LoadRequireCORSPreflight()) {
1247 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"
, 1247); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mPreflightChannel"
")"); do { *((volatile int*)__null) = 1247; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1248 nsresult rv = nsCORSListenerProxy::StartCORSPreflight(
1249 this, this, mUnsafeHeaders, getter_AddRefs(mPreflightChannel));
1250 return rv;
1251 }
1252
1253 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"
, 1255); 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) = 1255; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
1254 "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"
, 1255); 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) = 1255; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
1255 "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"
, 1255); 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) = 1255; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1256
1257 RefPtr<mozilla::dom::BrowsingContext> bc;
1258 mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
1259
1260 // we may or may not have a cache entry at this point
1261 if (mCacheEntry) {
1262 // read straight from the cache if possible...
1263 if (CachedContentIsValid()) {
1264 // If we're forced offline, and set to bypass the cache, return offline.
1265 if (bc && bc->Top()->GetForceOffline() &&
1266 BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass())((mLoadFlags) & (nsIRequest::LOAD_BYPASS_CACHE | nsICachingChannel
::LOAD_BYPASS_LOCAL_CACHE) && !(((mLoadFlags) & nsIRequest
::LOAD_FROM_CACHE) && (LoadPreferCacheLoadOverBypass(
))))
) {
1267 return NS_ERROR_OFFLINE;
1268 }
1269
1270 nsRunnableMethod<nsHttpChannel>* event = nullptr;
1271 nsresult rv;
1272 if (!LoadCachedContentIsPartial()) {
1273 rv = AsyncCall(&nsHttpChannel::AsyncOnExamineCachedResponse, &event);
1274 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1275 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)
;
1276 }
1277 }
1278 rv = ReadFromCache();
1279 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && event) {
1280 event->Revoke();
1281 }
1282
1283 AccumulateCacheHitTelemetry(kCacheHit, this);
1284 mCacheDisposition = kCacheHit;
1285
1286 return rv;
1287 }
1288 if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
1289 // the cache contains the requested resource, but it must be
1290 // validated before we can reuse it. since we are not allowed
1291 // to hit the net, there's nothing more to do. the document
1292 // is effectively not in the cache.
1293 LOG((" !CachedContentIsValid() && 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
, " !CachedContentIsValid() && mLoadFlags & LOAD_ONLY_FROM_CACHE"
); } } while (0)
;
1294 return NS_ERROR_DOCUMENT_NOT_CACHED;
1295 }
1296 } else if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
1297 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)
;
1298 return NS_ERROR_DOCUMENT_NOT_CACHED;
1299 }
1300
1301 if (mLoadFlags & LOAD_NO_NETWORK_IO) {
1302 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)
;
1303 return NS_ERROR_DOCUMENT_NOT_CACHED;
1304 }
1305
1306 // We're about to hit the network. Don't if we're forced offline.
1307 if (bc && bc->Top()->GetForceOffline()) {
1308 return NS_ERROR_OFFLINE;
1309 }
1310
1311 // hit the net...
1312 nsresult rv = DoConnect(mTransactionSticky);
1313 mTransactionSticky = nullptr;
1314 return rv;
1315}
1316
1317nsresult nsHttpChannel::DoConnect(HttpTransactionShell* aTransWithStickyConn) {
1318 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
)
;
1319
1320 if (!mDNSBlockingPromise.IsEmpty()) {
1321 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)
;
1322
1323 // Transaction is passed only from auth retry for which we will definitely
1324 // not block on DNS to alter the origin server name for IP; it has already
1325 // been done.
1326 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"
, 1326); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aTransWithStickyConn"
")"); do { *((volatile int*)__null) = 1326; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1327 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"
, 1327); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mDNSBlockingThenable"
")"); do { *((volatile int*)__null) = 1327; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1328
1329 nsCOMPtr<nsISerialEventTarget> target(do_GetMainThread());
1330 RefPtr<nsHttpChannel> self(this);
1331 mDNSBlockingThenable->Then(
1332 target, __func__,
1333 [self](const nsCOMPtr<nsIDNSRecord>& aRec) {
1334 nsresult rv = self->DoConnectActual(nullptr);
1335 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1336 self->CloseCacheEntry(false);
1337 Unused << self->AsyncAbort(rv);
1338 }
1339 },
1340 [self](nsresult err) {
1341 self->CloseCacheEntry(false);
1342 Unused << self->AsyncAbort(err);
1343 });
1344
1345 // The connection will continue when the promise is resolved in
1346 // OnLookupComplete.
1347 return NS_OK;
1348 }
1349
1350 return DoConnectActual(aTransWithStickyConn);
1351}
1352
1353nsresult nsHttpChannel::DoConnectActual(
1354 HttpTransactionShell* aTransWithStickyConn) {
1355 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)
1356 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)
;
1357
1358 nsresult rv = SetupChannelForTransaction();
1359 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1360 return rv;
1361 }
1362
1363 return DispatchTransaction(aTransWithStickyConn);
1364}
1365
1366nsresult nsHttpChannel::DispatchTransaction(
1367 HttpTransactionShell* aTransWithStickyConn) {
1368 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)
1369 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)
;
1370 nsresult rv = InitTransaction();
1371 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1372 return rv;
1373 }
1374 if (aTransWithStickyConn) {
1375 rv = gHttpHandler->InitiateTransactionWithStickyConn(
1376 mTransaction, mPriority, aTransWithStickyConn);
1377 } else {
1378 rv = gHttpHandler->InitiateTransaction(mTransaction, mPriority);
1379 }
1380
1381 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1382 return rv;
1383 }
1384
1385 rv = mTransaction->AsyncRead(this, getter_AddRefs(mTransactionPump));
1386 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1387 return rv;
1388 }
1389
1390 uint32_t suspendCount = mSuspendCount;
1391 if (LoadAsyncResumePending()) {
1392 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)
1393 (" 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)
1394 ", 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)
1395 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)
;
1396 ++suspendCount;
1397 }
1398 while (suspendCount--) {
1399 mTransactionPump->Suspend();
1400 }
1401
1402 return NS_OK;
1403}
1404
1405void nsHttpChannel::SpeculativeConnect() {
1406 // Before we take the latency hit of dealing with the cache, try and
1407 // get the TCP (and SSL) handshakes going so they can overlap.
1408
1409 // don't speculate if we are offline, when doing http upgrade (i.e.
1410 // websockets bootstrap), or if we can't do keep-alive (because then we
1411 // couldn't reuse the speculative connection anyhow).
1412 RefPtr<mozilla::dom::BrowsingContext> bc;
1413 mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
1414
1415 if (gIOService->IsOffline() || mUpgradeProtocolCallback ||
1416 !(mCaps & NS_HTTP_ALLOW_KEEPALIVE(1 << 0)) ||
1417 (bc && bc->Top()->GetForceOffline())) {
1418 return;
1419 }
1420
1421 // LOAD_ONLY_FROM_CACHE and LOAD_NO_NETWORK_IO must not hit network.
1422 // LOAD_FROM_CACHE is unlikely to hit network, so skip preconnects for it.
1423 if (mLoadFlags &
1424 (LOAD_ONLY_FROM_CACHE | LOAD_FROM_CACHE | LOAD_NO_NETWORK_IO)) {
1425 return;
1426 }
1427
1428 if (LoadAllowStaleCacheContent()) {
1429 return;
1430 }
1431
1432 nsCOMPtr<nsIInterfaceRequestor> callbacks;
1433 NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
1434 getter_AddRefs(callbacks));
1435 if (!callbacks) return;
1436 bool httpsRRAllowed = !(mCaps & NS_HTTP_DISALLOW_HTTPS_RR(1 << 24));
1437 Unused << gHttpHandler->MaybeSpeculativeConnectWithHTTPSRR(
1438 mConnectionInfo, callbacks,
1439 mCaps & (NS_HTTP_DISALLOW_SPDY(1 << 7) | NS_HTTP_TRR_MODE_MASK((1 << 19) | (1 << 20)) |
1440 NS_HTTP_DISABLE_IPV4(1 << 17) | NS_HTTP_DISABLE_IPV6(1 << 18) |
1441 NS_HTTP_DISALLOW_HTTP3(1 << 21) | NS_HTTP_REFRESH_DNS(1 << 3)),
1442 gHttpHandler->EchConfigEnabled() && httpsRRAllowed);
1443}
1444
1445void nsHttpChannel::DoNotifyListenerCleanup() {
1446 // We don't need this info anymore
1447 CleanRedirectCacheChainIfNecessary();
1448}
1449
1450void nsHttpChannel::ReleaseListeners() {
1451 HttpBaseChannel::ReleaseListeners();
1452 mChannelClassifier = nullptr;
1453 mWarningReporter = nullptr;
1454 mEarlyHintObserver = nullptr;
1455 mWebTransportSessionEventListener = nullptr;
1456
1457 for (StreamFilterRequest& request : mStreamFilterRequests) {
1458 request.mPromise->Reject(false, __func__);
1459 }
1460 mStreamFilterRequests.Clear();
1461}
1462
1463void nsHttpChannel::DoAsyncAbort(nsresult aStatus) {
1464 Unused << AsyncAbort(aStatus);
1465}
1466
1467void nsHttpChannel::HandleAsyncRedirect() {
1468 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"
, 1468); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 1468; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
1469
1470 if (mSuspendCount) {
1471 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)
;
1472 mCallOnResume = [](nsHttpChannel* self) {
1473 self->HandleAsyncRedirect();
1474 return NS_OK;
1475 };
1476 return;
1477 }
1478
1479 nsresult rv = NS_OK;
1480
1481 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)
;
1482
1483 // since this event is handled asynchronously, it is possible that this
1484 // channel could have been canceled, in which case there would be no point
1485 // in processing the redirect.
1486 if (NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1)))) {
1487 PushRedirectAsyncFunc(&nsHttpChannel::ContinueHandleAsyncRedirect);
1488 rv = AsyncProcessRedirection(mResponseHead->Status());
1489 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1490 PopRedirectAsyncFunc(&nsHttpChannel::ContinueHandleAsyncRedirect);
1491 // TODO: if !DoNotRender3xxBody(), render redirect body instead.
1492 // But first we need to cache 3xx bodies (bug 748510)
1493 rv = ContinueHandleAsyncRedirect(rv);
1494 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"
, 1494); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1494; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1495 }
1496 } else {
1497 rv = ContinueHandleAsyncRedirect(mStatus);
1498 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"
, 1498); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1498; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1499 }
1500}
1501
1502nsresult nsHttpChannel::ContinueHandleAsyncRedirect(nsresult rv) {
1503 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1504 // If AsyncProcessRedirection fails, then we have to send out the
1505 // OnStart/OnStop notifications.
1506 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)
1507 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)
;
1508
1509 bool redirectsEnabled = !mLoadInfo->GetDontFollowRedirects();
1510
1511 if (redirectsEnabled) {
1512 // TODO: stop failing original channel if redirect vetoed?
1513 mStatus = rv;
1514
1515 DoNotifyListener();
1516
1517 // Blow away cache entry if we couldn't process the redirect
1518 // for some reason (the cache entry might be corrupt).
1519 if (mCacheEntry) {
1520 mCacheEntry->AsyncDoom(nullptr);
1521 }
1522 } else {
1523 DoNotifyListener();
1524 }
1525 }
1526
1527 CloseCacheEntry(true);
1528
1529 StoreIsPending(false);
1530
1531 if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, mStatus);
1532
1533 return NS_OK;
1534}
1535
1536void nsHttpChannel::HandleAsyncNotModified() {
1537 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"
, 1537); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 1537; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
1538
1539 if (mSuspendCount) {
1540 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)
;
1541 mCallOnResume = [](nsHttpChannel* self) {
1542 self->HandleAsyncNotModified();
1543 return NS_OK;
1544 };
1545 return;
1546 }
1547
1548 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)
;
1549
1550 DoNotifyListener();
1551
1552 CloseCacheEntry(false);
1553
1554 StoreIsPending(false);
1555
1556 if (mLoadGroup) mLoadGroup->RemoveRequest(this, nullptr, mStatus);
1557}
1558
1559nsresult nsHttpChannel::SetupChannelForTransaction() {
1560 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)
1561 "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)
1562 "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)
1563 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)
;
1564
1565 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"
, 1565); return NS_ERROR_ALREADY_INITIALIZED; } } while (false
)
;
1566
1567 nsresult rv;
1568
1569 mozilla::MutexAutoLock lock(mRCWNLock);
1570
1571 if (StaticPrefs::network_http_priority_header_enabled()) {
1572 SetPriorityHeader();
1573 }
1574
1575 // If we're racing cache with network, conditional or byte range header
1576 // could be added in OnCacheEntryCheck. We cannot send conditional request
1577 // without having the entry, so we need to remove the headers here and
1578 // ignore the cache entry in OnCacheEntryAvailable.
1579 if (mRaceCacheWithNetwork && AwaitingCacheCallbacks()) {
1580 if (mDidReval) {
1581 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)
;
1582 UntieValidationRequest();
1583 mDidReval = false;
1584 mIgnoreCacheEntry = true;
1585 }
1586
1587 if (LoadCachedContentIsPartial()) {
1588 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)
;
1589 UntieByteRangeRequest();
1590 StoreCachedContentIsPartial(false);
1591 mIgnoreCacheEntry = true;
1592 }
1593
1594 if (mIgnoreCacheEntry) {
1595 mAvailableCachedAltDataType.Truncate();
1596 StoreDeliveringAltData(false);
1597 mAltDataLength = -1;
1598 mCacheInputStream.CloseAndRelease();
1599 }
1600 }
1601
1602 StoreUsedNetwork(1);
1603
1604 if (!LoadAllowSpdy()) {
1605 mCaps |= NS_HTTP_DISALLOW_SPDY(1 << 7);
1606 }
1607 if (!LoadAllowHttp3()) {
1608 mCaps |= NS_HTTP_DISALLOW_HTTP3(1 << 21);
1609 }
1610 if (LoadBeConservative()) {
1611 mCaps |= NS_HTTP_BE_CONSERVATIVE(1 << 11);
1612 }
1613
1614 if (mLoadFlags & LOAD_ANONYMOUS_ALLOW_CLIENT_CERT) {
1615 mCaps |= NS_HTTP_LOAD_ANONYMOUS_CONNECT_ALLOW_CLIENT_CERT(1 << 23);
1616 }
1617
1618 if (nsContentUtils::ShouldResistFingerprinting(this,
1619 RFPTarget::HttpUserAgent)) {
1620 mCaps |= NS_HTTP_USE_RFP(1 << 26);
1621 }
1622
1623 // Use the URI path if not proxying (transparent proxying such as proxy
1624 // CONNECT does not count here). Also figure out what HTTP version to use.
1625 nsAutoCString buf, path;
1626 nsCString* requestURI;
1627
1628 // This is the normal e2e H1 path syntax "/index.html"
1629 rv = mURI->GetPathQueryRef(path);
1630 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1631 return rv;
1632 }
1633
1634 // path may contain UTF-8 characters, so ensure that they're escaped.
1635 if (NS_EscapeURL(path.get(), path.Length(), esc_OnlyNonASCII | esc_Spaces,
1636 buf)) {
1637 requestURI = &buf;
1638 } else {
1639 requestURI = &path;
1640 }
1641
1642 // trim off the #ref portion if any...
1643 int32_t ref1 = requestURI->FindChar('#');
1644 if (ref1 != kNotFound) {
1645 requestURI->SetLength(ref1);
1646 }
1647
1648 if (mConnectionInfo->UsingConnect() || !mConnectionInfo->UsingHttpProxy()) {
1649 mRequestHead.SetVersion(gHttpHandler->HttpVersion());
1650 } else {
1651 mRequestHead.SetPath(*requestURI);
1652
1653 // RequestURI should be the absolute uri H1 proxy syntax
1654 // "http://foo/index.html" so we will overwrite the relative version in
1655 // requestURI
1656 rv = mURI->GetUserPass(buf);
1657 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
1658 if (!buf.IsEmpty() && ((strncmp(mSpec.get(), "http:", 5) == 0) ||
1659 strncmp(mSpec.get(), "https:", 6) == 0)) {
1660 nsCOMPtr<nsIURI> tempURI = nsIOService::CreateExposableURI(mURI);
1661 rv = tempURI->GetAsciiSpec(path);
1662 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
1663 requestURI = &path;
1664 } else {
1665 requestURI = &mSpec;
1666 }
1667
1668 // trim off the #ref portion if any...
1669 int32_t ref2 = requestURI->FindChar('#');
1670 if (ref2 != kNotFound) {
1671 requestURI->SetLength(ref2);
1672 }
1673
1674 mRequestHead.SetVersion(gHttpHandler->ProxyHttpVersion());
1675 }
1676
1677 mRequestHead.SetRequestURI(*requestURI);
1678
1679 // set the request time for cache expiration calculations
1680 mRequestTime = NowInSeconds()PRTimeToSeconds(PR_Now());
1681 StoreRequestTimeInitialized(true);
1682
1683 // if doing a reload, force end-to-end
1684 if (mLoadFlags & LOAD_BYPASS_CACHE) {
1685 // We need to send 'Pragma:no-cache' to inhibit proxy caching even if
1686 // no proxy is configured since we might be talking with a transparent
1687 // proxy, i.e. one that operates at the network level. See bug #14772.
1688 // But we should not touch Pragma if Cache-Control is already set
1689 // (https://fetch.spec.whatwg.org/#ref-for-concept-request-cache-mode%E2%91%A3)
1690 if (!mRequestHead.HasHeader(nsHttp::Pragma)) {
1691 rv = mRequestHead.SetHeaderOnce(nsHttp::Pragma, "no-cache", true);
1692 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"
, 1692); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1692; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1693 }
1694 // If we're configured to speak HTTP/1.1 then also send 'Cache-control:
1695 // no-cache'. But likewise don't touch Cache-Control if it's already set.
1696 if (mRequestHead.Version() >= HttpVersion::v1_1 &&
1697 !mRequestHead.HasHeader(nsHttp::Cache_Control)) {
1698 rv = mRequestHead.SetHeaderOnce(nsHttp::Cache_Control, "no-cache", true);
1699 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"
, 1699); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1699; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1700 }
1701 } else if (mLoadFlags & VALIDATE_ALWAYS) {
1702 // We need to send 'Cache-Control: max-age=0' to force each cache along
1703 // the path to the origin server to revalidate its own entry, if any,
1704 // with the next cache or server. See bug #84847.
1705 //
1706 // If we're configured to speak HTTP/1.0 then just send 'Pragma: no-cache'
1707 //
1708 // But don't send the headers if they're already set:
1709 // https://fetch.spec.whatwg.org/#ref-for-concept-request-cache-mode%E2%91%A2
1710 if (mRequestHead.Version() >= HttpVersion::v1_1) {
1711 if (!mRequestHead.HasHeader(nsHttp::Cache_Control)) {
1712 rv = mRequestHead.SetHeaderOnce(nsHttp::Cache_Control, "max-age=0",
1713 true);
1714 }
1715 } else {
1716 if (!mRequestHead.HasHeader(nsHttp::Pragma)) {
1717 rv = mRequestHead.SetHeaderOnce(nsHttp::Pragma, "no-cache", true);
1718 }
1719 }
1720 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"
, 1720); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1720; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1721 }
1722
1723 if (LoadResuming()) {
1724 char byteRange[32];
1725 SprintfLiteral(byteRange, "bytes=%" PRIu64"l" "u" "-", mStartPos);
1726 rv = mRequestHead.SetHeader(nsHttp::Range, nsDependentCString(byteRange));
1727 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"
, 1727); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1727; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1728
1729 if (!mEntityID.IsEmpty()) {
1730 // Also, we want an error if this resource changed in the meantime
1731 // Format of the entity id is: escaped_etag/size/lastmod
1732 nsCString::const_iterator start, end, slash;
1733 mEntityID.BeginReading(start);
1734 mEntityID.EndReading(end);
1735 mEntityID.BeginReading(slash);
1736
1737 if (FindCharInReadable('/', slash, end)) {
1738 nsAutoCString ifMatch;
1739 rv = mRequestHead.SetHeader(
1740 nsHttp::If_Match,
1741 NS_UnescapeURL(Substring(start, slash), 0, ifMatch));
1742 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"
, 1742); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1742; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1743
1744 ++slash; // Incrementing, so that searching for '/' won't find
1745 // the same slash again
1746 }
1747
1748 if (FindCharInReadable('/', slash, end)) {
1749 rv = mRequestHead.SetHeader(nsHttp::If_Unmodified_Since,
1750 Substring(++slash, end));
1751 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"
, 1751); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1751; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1752 }
1753 }
1754 }
1755
1756 // See bug #466080. Transfer LOAD_ANONYMOUS flag to socket-layer.
1757 if (mLoadFlags & LOAD_ANONYMOUS) mCaps |= NS_HTTP_LOAD_ANONYMOUS(1 << 4);
1758
1759 if (mUpgradeProtocolCallback) {
1760 rv = mRequestHead.SetHeader(nsHttp::Upgrade, mUpgradeProtocol, false);
1761 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"
, 1761); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1761; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1762 rv = mRequestHead.SetHeaderOnce(nsHttp::Connection, nsHttp::Upgrade.get(),
1763 true);
1764 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"
, 1764); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 1764; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1765 mCaps |= NS_HTTP_STICKY_CONNECTION(1 << 2);
1766 mCaps &= ~NS_HTTP_ALLOW_KEEPALIVE(1 << 0);
1767 }
1768
1769 if (mWebTransportSessionEventListener) {
1770 mCaps |= NS_HTTP_STICKY_CONNECTION(1 << 2);
1771 }
1772
1773 return NS_OK;
1774}
1775
1776nsresult nsHttpChannel::InitTransaction() {
1777 nsresult rv;
1778 // create wrapper for this channel's notification callbacks
1779 nsCOMPtr<nsIInterfaceRequestor> callbacks;
1780 NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
1781 getter_AddRefs(callbacks));
1782
1783 // create the transaction object
1784 if (nsIOService::UseSocketProcess()) {
1785 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"
, 1785)
) {
1786 return NS_ERROR_NOT_AVAILABLE;
1787 }
1788 RefPtr<SocketProcessParent> socketProcess =
1789 SocketProcessParent::GetSingleton();
1790 if (!socketProcess->CanSend()) {
1791 return NS_ERROR_NOT_AVAILABLE;
1792 }
1793
1794 nsCOMPtr<nsIParentChannel> parentChannel;
1795 NS_QueryNotificationCallbacks(this, parentChannel);
1796 RefPtr<DocumentLoadListener> documentChannelParent =
1797 do_QueryObject(parentChannel);
1798 // See HttpTransactionChild::CanSendODAToContentProcessDirectly() and
1799 // nsHttpChannel::CallOnStartRequest() for the reason why we need to know if
1800 // this is a document load. We only send ODA directly to child process for
1801 // non document loads.
1802 RefPtr<HttpTransactionParent> transParent =
1803 new HttpTransactionParent(!!documentChannelParent);
1804 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)
1805 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)
;
1806
1807 // Since OnStopRequest could be sent to child process from socket process
1808 // directly, we need to store these two values in HttpTransactionChild and
1809 // forward to child process until HttpTransactionChild::OnStopRequest is
1810 // called.
1811 transParent->SetRedirectTimestamp(mRedirectStartTimeStamp,
1812 mRedirectEndTimeStamp);
1813
1814 if (socketProcess) {
1815 MOZ_ALWAYS_TRUE(do { if ((__builtin_expect(!!(socketProcess->SendPHttpTransactionConstructor
(transParent)), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "socketProcess->SendPHttpTransactionConstructor(transParent)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1816); AnnotateMozCrashReason("MOZ_CRASH(" "socketProcess->SendPHttpTransactionConstructor(transParent)"
")"); do { *((volatile int*)__null) = 1816; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
1816 socketProcess->SendPHttpTransactionConstructor(transParent))do { if ((__builtin_expect(!!(socketProcess->SendPHttpTransactionConstructor
(transParent)), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "socketProcess->SendPHttpTransactionConstructor(transParent)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 1816); AnnotateMozCrashReason("MOZ_CRASH(" "socketProcess->SendPHttpTransactionConstructor(transParent)"
")"); do { *((volatile int*)__null) = 1816; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
1817 }
1818 mTransaction = transParent;
1819 } else {
1820 mTransaction = new nsHttpTransaction();
1821 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)
1822 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)
;
1823 }
1824
1825 // Save the mapping of channel id and the channel. We need this mapping for
1826 // nsIHttpActivityObserver.
1827 gHttpHandler->AddHttpChannel(mChannelId, ToSupports(this));
1828
1829 nsCOMPtr<nsIHttpPushListener> pushListener;
1830 NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
1831 NS_GET_IID(nsIHttpPushListener)(nsIHttpPushListener::COMTypeInfo<nsIHttpPushListener, void
>::kIID)
,
1832 getter_AddRefs(pushListener));
1833 HttpTransactionShell::OnPushCallback pushCallback = nullptr;
1834 if (pushListener) {
1835 mCaps |= NS_HTTP_ONPUSH_LISTENER(1 << 9);
1836 nsWeakPtr weakPtrThis(
1837 do_GetWeakReference(static_cast<nsIHttpChannel*>(this)));
1838 pushCallback = [weakPtrThis](uint32_t aPushedStreamId,
1839 const nsACString& aUrl,
1840 const nsACString& aRequestString,
1841 HttpTransactionShell* aTransaction) {
1842 if (nsCOMPtr<nsIHttpChannel> channel = do_QueryReferent(weakPtrThis)) {
1843 return static_cast<nsHttpChannel*>(channel.get())
1844 ->OnPush(aPushedStreamId, aUrl, aRequestString, aTransaction);
1845 }
1846 return NS_ERROR_NOT_AVAILABLE;
1847 };
1848 }
1849
1850 EnsureBrowserId();
1851 EnsureRequestContext();
1852
1853 HttpTrafficCategory category = CreateTrafficCategory();
1854 std::function<void(TransactionObserverResult&&)> observer;
1855 if (mTransactionObserver) {
1856 observer = [transactionObserver{std::move(mTransactionObserver)}](
1857 TransactionObserverResult&& aResult) {
1858 transactionObserver->Complete(aResult.versionOk(), aResult.authOk(),
1859 aResult.closeReason());
1860 };
1861 }
1862 mTransaction->SetIsForWebTransport(!!mWebTransportSessionEventListener);
1863 rv = mTransaction->Init(
1864 mCaps, mConnectionInfo, &mRequestHead, mUploadStream, mReqContentLength,
1865 LoadUploadStreamHasHeaders(), GetCurrentSerialEventTarget(), callbacks,
1866 this, mBrowserId, category, mRequestContext, mClassOfService,
1867 mInitialRwin, LoadResponseTimeoutEnabled(), mChannelId,
1868 std::move(observer), std::move(pushCallback), mTransWithPushedStream,
1869 mPushedStreamId);
1870 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1871 mTransaction = nullptr;
1872 return rv;
1873 }
1874
1875 return rv;
1876}
1877
1878HttpTrafficCategory nsHttpChannel::CreateTrafficCategory() {
1879 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"
, 1880); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
")"); do { *((volatile int*)__null) = 1880; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1880 !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"
, 1880); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
")"); do { *((volatile int*)__null) = 1880; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1881
1882 if (!StaticPrefs::network_traffic_analyzer_enabled()) {
1883 return HttpTrafficCategory::eInvalid;
1884 }
1885
1886 HttpTrafficAnalyzer::ClassOfService cos;
1887 {
1888 if ((mClassOfService.Flags() & nsIClassOfService::Leader) &&
1889 mLoadInfo->GetExternalContentPolicyType() ==
1890 ExtContentPolicy::TYPE_SCRIPT) {
1891 cos = HttpTrafficAnalyzer::ClassOfService::eLeader;
1892 } else if (mLoadFlags & nsIRequest::LOAD_BACKGROUND) {
1893 cos = HttpTrafficAnalyzer::ClassOfService::eBackground;
1894 } else {
1895 cos = HttpTrafficAnalyzer::ClassOfService::eOther;
1896 }
1897 }
1898
1899 bool isThirdParty = AntiTrackingUtils::IsThirdPartyChannel(this);
1900
1901 HttpTrafficAnalyzer::TrackingClassification tc;
1902 {
1903 uint32_t flags = isThirdParty ? mThirdPartyClassificationFlags
1904 : mFirstPartyClassificationFlags;
1905
1906 using CF = nsIClassifiedChannel::ClassificationFlags;
1907 using TC = HttpTrafficAnalyzer::TrackingClassification;
1908
1909 if (flags & CF::CLASSIFIED_TRACKING_CONTENT) {
1910 tc = TC::eContent;
1911 } else if (flags & CF::CLASSIFIED_FINGERPRINTING_CONTENT) {
1912 tc = TC::eFingerprinting;
1913 } else if (flags & CF::CLASSIFIED_ANY_BASIC_TRACKING) {
1914 tc = TC::eBasic;
1915 } else {
1916 tc = TC::eNone;
1917 }
1918 }
1919
1920 bool isSystemPrincipal =
1921 mLoadInfo->GetLoadingPrincipal() &&
1922 mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal();
1923 return HttpTrafficAnalyzer::CreateTrafficCategory(
1924 NS_UsePrivateBrowsing(this), isSystemPrincipal, isThirdParty, cos, tc);
1925}
1926
1927void nsHttpChannel::SetCachedContentType() {
1928 if (!mResponseHead) {
1929 return;
1930 }
1931
1932 nsAutoCString contentTypeStr;
1933 mResponseHead->ContentType(contentTypeStr);
1934
1935 uint8_t contentType = nsICacheEntry::CONTENT_TYPE_OTHER;
1936 if (nsContentUtils::IsJavascriptMIMEType(
1937 NS_ConvertUTF8toUTF16(contentTypeStr))) {
1938 contentType = nsICacheEntry::CONTENT_TYPE_JAVASCRIPT;
1939 } else if (StringBeginsWith(contentTypeStr, "text/css"_ns) ||
1940 (mLoadInfo->GetExternalContentPolicyType() ==
1941 ExtContentPolicy::TYPE_STYLESHEET)) {
1942 contentType = nsICacheEntry::CONTENT_TYPE_STYLESHEET;
1943 } else if (StringBeginsWith(contentTypeStr, "application/wasm"_ns)) {
1944 contentType = nsICacheEntry::CONTENT_TYPE_WASM;
1945 } else if (StringBeginsWith(contentTypeStr, "image/"_ns)) {
1946 contentType = nsICacheEntry::CONTENT_TYPE_IMAGE;
1947 } else if (StringBeginsWith(contentTypeStr, "video/"_ns)) {
1948 contentType = nsICacheEntry::CONTENT_TYPE_MEDIA;
1949 } else if (StringBeginsWith(contentTypeStr, "audio/"_ns)) {
1950 contentType = nsICacheEntry::CONTENT_TYPE_MEDIA;
1951 }
1952
1953 mCacheEntry->SetContentType(contentType);
1954}
1955
1956nsresult nsHttpChannel::CallOnStartRequest() {
1957 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)
;
1958
1959 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"
, 1961); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()"
") (" "CORS preflight must have been finished by the time we "
"call OnStartRequest" ")"); do { *((volatile int*)__null) = 1961
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
1960 "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"
, 1961); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()"
") (" "CORS preflight must have been finished by the time we "
"call OnStartRequest" ")"); do { *((volatile int*)__null) = 1961
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
1961 "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"
, 1961); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequireCORSPreflight() || LoadIsCorsPreflightDone()"
") (" "CORS preflight must have been finished by the time we "
"call OnStartRequest" ")"); do { *((volatile int*)__null) = 1961
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
1962
1963 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"
, 1965); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mCanceled || LoadProcessCrossOriginSecurityHeadersCalled()"
") (" "Security headers need to have been processed before "
"calling CallOnStartRequest" ")"); do { *((volatile int*)__null
) = 1965; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
1964 "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"
, 1965); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mCanceled || LoadProcessCrossOriginSecurityHeadersCalled()"
") (" "Security headers need to have been processed before "
"calling CallOnStartRequest" ")"); do { *((volatile int*)__null
) = 1965; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
1965 "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"
, 1965); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mCanceled || LoadProcessCrossOriginSecurityHeadersCalled()"
") (" "Security headers need to have been processed before "
"calling CallOnStartRequest" ")"); do { *((volatile int*)__null
) = 1965; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
1966
1967 mEarlyHintObserver = nullptr;
1968
1969 if (StaticPrefs::network_http_network_error_logging_enabled() &&
1970 mResponseHead && mResponseHead->HasHeader(nsHttp::NEL) &&
1971 LoadUsedNetwork()) {
1972 // If the policy gets cleared, but this response is still in the cache,
1973 // we probably don't want to reinstall the policy when the entry is
1974 // reloaded. That means it's important to only call RegisterPolicy when
1975 // LoadUsedNetwork() is true.
1976 if (nsCOMPtr<nsINetworkErrorLogging> nel =
1977 components::NetworkErrorLogging::Service()) {
1978 nel->RegisterPolicy(this);
1979 }
1980 }
1981
1982 if (LoadOnStartRequestCalled()) {
1983 // This can only happen when a range request loading rest of the data
1984 // after interrupted concurrent cache read asynchronously failed, e.g.
1985 // the response range bytes are not as expected or this channel has
1986 // been externally canceled.
1987 //
1988 // It's legal to bypass CallOnStartRequest for that case since we've
1989 // already called OnStartRequest on our listener and also added all
1990 // content converters before.
1991 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"
, 1991); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadConcurrentCacheAccess()"
")"); do { *((volatile int*)__null) = 1991; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1992 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)
;
1993 return mStatus;
1994 }
1995
1996 // Ensure mListener->OnStartRequest will be invoked before exiting
1997 // this function.
1998 auto onStartGuard = MakeScopeExit([&] {
1999 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)
2000 (" 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)
2001 "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)
2002 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)
;
2003 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"
, 2003); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
")"); do { *((volatile int*)__null) = 2003; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2004
2005 if (mListener) {
2006 nsCOMPtr<nsIStreamListener> deleteProtector(mListener);
2007 StoreOnStartRequestCalled(true);
2008 deleteProtector->OnStartRequest(this);
2009 }
2010 StoreOnStartRequestCalled(true);
2011 });
2012
2013 nsresult rv = ValidateMIMEType();
2014 // Since ODA and OnStopRequest could be sent from socket process directly, we
2015 // need to update the channel status before calling mListener->OnStartRequest.
2016 // This is the only way to let child process discard the already received ODA
2017 // messages.
2018 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2019 mStatus = rv;
2020 return mStatus;
2021 }
2022
2023 // EnsureOpaqueResponseIsAllowed and EnsureOpauqeResponseIsAllowedAfterSniff
2024 // are the checks for Opaque Response Blocking to ensure that we block as many
2025 // cross-origin responses with CORS headers as possible that are not either
2026 // Javascript or media to avoid leaking their contents through side channels.
2027 OpaqueResponse opaqueResponse =
2028 PerformOpaqueResponseSafelistCheckBeforeSniff();
2029 if (opaqueResponse == OpaqueResponse::Block) {
2030 SetChannelBlockedByOpaqueResponse();
2031 CancelWithReason(NS_BINDING_ABORTED,
2032 "OpaqueResponseBlocker::BlockResponse"_ns);
2033 return NS_BINDING_ABORTED;
2034 }
2035
2036 // Allow consumers to override our content type
2037 if (mLoadFlags & LOAD_CALL_CONTENT_SNIFFERS) {
2038 // NOTE: We can have both a txn pump and a cache pump when the cache
2039 // content is partial. In that case, we need to read from the cache,
2040 // because that's the one that has the initial contents. If that fails
2041 // then give the transaction pump a shot.
2042
2043 nsIChannel* thisChannel = static_cast<nsIChannel*>(this);
2044
2045 bool typeSniffersCalled = false;
2046 if (mCachePump) {
2047 typeSniffersCalled =
2048 NS_SUCCEEDED(mCachePump->PeekStream(CallTypeSniffers, thisChannel))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mCachePump->PeekStream
(CallTypeSniffers, thisChannel))), 1)))
;
2049 }
2050
2051 if (!typeSniffersCalled && mTransactionPump) {
2052 RefPtr<nsInputStreamPump> pump = do_QueryObject(mTransactionPump);
2053 if (pump) {
2054 pump->PeekStream(CallTypeSniffers, thisChannel);
2055 } else {
2056 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"
, 2056); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nsIOService::UseSocketProcess()"
")"); do { *((volatile int*)__null) = 2056; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2057 RefPtr<HttpTransactionParent> trans = do_QueryObject(mTransactionPump);
2058 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"
, 2058); AnnotateMozCrashReason("MOZ_ASSERT" "(" "trans" ")")
; do { *((volatile int*)__null) = 2058; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2059 trans->SetSniffedTypeToChannel(CallTypeSniffers, thisChannel);
2060 }
2061 }
2062 }
2063
2064 // Note that the code below should be synced with the code in
2065 // HttpTransactionChild::CanSendODAToContentProcessDirectly(). We MUST make
2066 // sure HttpTransactionChild::CanSendODAToContentProcessDirectly() returns
2067 // false when a stream converter is applied.
2068 bool unknownDecoderStarted = false;
2069 if (mResponseHead && !mResponseHead->HasContentType()) {
2070 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"
, 2070); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mConnectionInfo"
") (" "Should have connection info here" ")"); do { *((volatile
int*)__null) = 2070; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
2071 if (!mContentTypeHint.IsEmpty()) {
2072 mResponseHead->SetContentType(mContentTypeHint);
2073 } else if (mResponseHead->Version() == HttpVersion::v0_9 &&
2074 mConnectionInfo->OriginPort() !=
2075 mConnectionInfo->DefaultPort()) {
2076 mResponseHead->SetContentType(nsLiteralCString(TEXT_PLAIN"text/plain"));
2077 } else {
2078 // Uh-oh. We had better find out what type we are!
2079 mListener = new nsUnknownDecoder(mListener);
2080 unknownDecoderStarted = true;
2081 }
2082 }
2083
2084 // If unknownDecoder is not going to be launched, call
2085 // EnsureOpaqueResponseIsAllowedAfterSniff immediately.
2086 if (!unknownDecoderStarted) {
2087 if (opaqueResponse == OpaqueResponse::SniffCompressed) {
2088 mListener = new nsCompressedAudioVideoImageDetector(
2089 mListener, &HttpBaseChannel::CallTypeSniffers);
2090 } else if (opaqueResponse == OpaqueResponse::Sniff) {
2091 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"
, 2091); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mORB"
")"); do { *((volatile int*)__null) = 2091; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2092 nsresult rv = mORB->EnsureOpaqueResponseIsAllowedAfterSniff(this);
2093
2094 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2095 return rv;
2096 }
2097 }
2098 }
2099
2100 // If the content is multipart/x-mixed-replace, we'll insert a MIME decoder
2101 // in the pipeline to handle the content and pass it along to our
2102 // original listener. nsUnknownDecoder doesn't support detecting this type,
2103 // so we only need to insert this using the response header's mime type.
2104 //
2105 // We only do this for unwrapped document loads, since we might want to send
2106 // parts to the external protocol handler without leaving the parent process.
2107 bool mustRunStreamFilterInParent = false;
2108 nsCOMPtr<nsIParentChannel> parentChannel;
2109 NS_QueryNotificationCallbacks(this, parentChannel);
2110 RefPtr<DocumentLoadListener> docListener = do_QueryObject(parentChannel);
2111 if (mResponseHead && docListener && docListener->GetChannel() == this) {
2112 nsAutoCString contentType;
2113 mResponseHead->ContentType(contentType);
2114
2115 if (contentType.Equals("multipart/x-mixed-replace"_ns)) {
2116 nsCOMPtr<nsIStreamConverterService> convServ(
2117 mozilla::components::StreamConverter::Service(&rv));
2118 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2119 nsCOMPtr<nsIStreamListener> toListener(mListener);
2120 nsCOMPtr<nsIStreamListener> fromListener;
2121
2122 rv = convServ->AsyncConvertData("multipart/x-mixed-replace", "*/*",
2123 toListener, nullptr,
2124 getter_AddRefs(fromListener));
2125 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2126 mListener = fromListener;
2127 mustRunStreamFilterInParent = true;
2128 }
2129 }
2130 }
2131 }
2132
2133 // If we installed a multipart converter, then we need to add StreamFilter
2134 // object before it, so that extensions see the un-parsed original stream.
2135 // We may want to add an option for extensions to opt-in to proper multipart
2136 // handling.
2137 // If not, then pass the StreamFilter promise on to DocumentLoadListener,
2138 // where it'll be added in the content process.
2139 for (StreamFilterRequest& request : mStreamFilterRequests) {
2140 if (mustRunStreamFilterInParent) {
2141 mozilla::ipc::Endpoint<extensions::PStreamFilterParent> parent;
2142 mozilla::ipc::Endpoint<extensions::PStreamFilterChild> child;
2143 nsresult rv = extensions::PStreamFilter::CreateEndpoints(&parent, &child);
2144 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2145 request.mPromise->Reject(false, __func__);
2146 } else {
2147 extensions::StreamFilterParent::Attach(this, std::move(parent));
2148 request.mPromise->Resolve(std::move(child), __func__);
2149 }
2150 } else {
2151 if (docListener) {
2152 docListener->AttachStreamFilter()->ChainTo(request.mPromise.forget(),
2153 __func__);
2154 } else {
2155 request.mPromise->Reject(false, __func__);
2156 }
2157 }
2158 request.mPromise = nullptr;
2159 }
2160 mStreamFilterRequests.Clear();
2161 StoreTracingEnabled(false);
2162
2163 if (mResponseHead && !mResponseHead->HasContentCharset()) {
2164 mResponseHead->SetContentCharset(mContentCharsetHint);
2165 }
2166
2167 if (mCacheEntry && LoadCacheEntryIsWriteOnly()) {
2168 SetCachedContentType();
2169 }
2170
2171 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)
2172 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)
;
2173
2174 // About to call OnStartRequest, dismiss the guard object.
2175 onStartGuard.release();
2176
2177 if (mListener) {
2178 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"
, 2179); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
") (" "We should not call OsStartRequest twice" ")"); do { *
((volatile int*)__null) = 2179; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
2179 "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"
, 2179); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
") (" "We should not call OsStartRequest twice" ")"); do { *
((volatile int*)__null) = 2179; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
2180 nsCOMPtr<nsIStreamListener> deleteProtector(mListener);
2181 StoreOnStartRequestCalled(true);
2182 rv = deleteProtector->OnStartRequest(this);
2183 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
2184 } else {
2185 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"
, 2185)
;
2186 StoreOnStartRequestCalled(true);
2187 }
2188
2189 // Install stream converter if required.
2190 // Normally, we expect the listener to disable content conversion during
2191 // OnStartRequest if it wants to handle it itself (which is common case with
2192 // HttpChannelParent, disabling so that it can be done in the content
2193 // process). If we've installed an nsUnknownDecoder, then we won't yet have
2194 // called OnStartRequest on the final listener (that happens after we send
2195 // OnDataAvailable to the nsUnknownDecoder), so it can't yet have disabled
2196 // content conversion.
2197 // In that case, assume that the listener will disable content conversion,
2198 // unless it's specifically told us that it won't.
2199 if (!unknownDecoderStarted || LoadListenerRequiresContentConversion()) {
2200 nsCOMPtr<nsIStreamListener> listener;
2201 rv =
2202 DoApplyContentConversions(mListener, getter_AddRefs(listener), nullptr);
2203 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2204 return rv;
2205 }
2206 if (listener) {
2207 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"
, 2210); 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) = 2210; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2208 "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"
, 2210); 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) = 2210; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2209 "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"
, 2210); 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) = 2210; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2210 "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"
, 2210); 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) = 2210; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2211 mListener = listener;
2212 mCompressListener = listener;
2213
2214 StoreHasAppliedConversion(true);
2215 }
2216 }
2217
2218 // if this channel is for a download, close off access to the cache.
2219 if (mCacheEntry && LoadChannelIsForDownload()) {
2220 mCacheEntry->AsyncDoom(nullptr);
2221
2222 // We must keep the cache entry in case of partial request.
2223 // Concurrent access is the same, we need the entry in
2224 // OnStopRequest.
2225 // We also need the cache entry when racing cache with network to find
2226 // out what is the source of the data.
2227 if (!LoadCachedContentIsPartial() && !LoadConcurrentCacheAccess() &&
2228 !(mRaceCacheWithNetwork &&
2229 mFirstResponseSource == RESPONSE_FROM_CACHE)) {
2230 CloseCacheEntry(false);
2231 }
2232 }
2233
2234 return NS_OK;
2235}
2236
2237NS_IMETHODIMPnsresult nsHttpChannel::GetHttpProxyConnectResponseCode(
2238 int32_t* aResponseCode) {
2239 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"
, 2239); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2240
2241 if (mConnectionInfo && mConnectionInfo->UsingConnect()) {
2242 *aResponseCode = mProxyConnectResponseCode;
2243 } else {
2244 *aResponseCode = -1;
2245 }
2246 return NS_OK;
2247}
2248
2249nsresult nsHttpChannel::ProcessFailedProxyConnect(uint32_t httpStatus) {
2250 // Failure to set up a proxy tunnel via CONNECT means one of the following:
2251 // 1) Proxy wants authorization, or forbids.
2252 // 2) DNS at proxy couldn't resolve target URL.
2253 // 3) Proxy connection to target failed or timed out.
2254 // 4) Eve intercepted our CONNECT, and is replying with malicious HTML.
2255 //
2256 // Our current architecture would parse the proxy's response content with
2257 // the permission of the target URL. Given #4, we must avoid rendering the
2258 // body of the reply, and instead give the user a (hopefully helpful)
2259 // boilerplate error page, based on just the HTTP status of the reply.
2260
2261 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"
, 2262); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mConnectionInfo->UsingConnect()"
") (" "proxy connect failed but not using CONNECT?" ")"); do
{ *((volatile int*)__null) = 2262; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
2262 "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"
, 2262); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mConnectionInfo->UsingConnect()"
") (" "proxy connect failed but not using CONNECT?" ")"); do
{ *((volatile int*)__null) = 2262; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
2263 nsresult rv = HttpProxyResponseToErrorCode(httpStatus);
2264 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)
2265 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)
;
2266
2267 // Make sure the connection is thrown away as it can be in a bad state
2268 // and the proxy may just hang on the next request.
2269 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"
, 2269); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mTransaction"
")"); do { *((volatile int*)__null) = 2269; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2270 mTransaction->DontReuseConnection();
2271
2272 Cancel(rv);
2273 {
2274 nsresult rv = CallOnStartRequest();
2275 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2276 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)
2277 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)
;
2278 }
2279 }
2280 return rv;
2281}
2282
2283static void GetSTSConsoleErrorTag(uint32_t failureResult,
2284 nsAString& consoleErrorTag) {
2285 switch (failureResult) {
2286 case nsISiteSecurityService::ERROR_COULD_NOT_PARSE_HEADER:
2287 consoleErrorTag = u"STSCouldNotParseHeader"_ns;
2288 break;
2289 case nsISiteSecurityService::ERROR_NO_MAX_AGE:
2290 consoleErrorTag = u"STSNoMaxAge"_ns;
2291 break;
2292 case nsISiteSecurityService::ERROR_MULTIPLE_MAX_AGES:
2293 consoleErrorTag = u"STSMultipleMaxAges"_ns;
2294 break;
2295 case nsISiteSecurityService::ERROR_INVALID_MAX_AGE:
2296 consoleErrorTag = u"STSInvalidMaxAge"_ns;
2297 break;
2298 case nsISiteSecurityService::ERROR_MULTIPLE_INCLUDE_SUBDOMAINS:
2299 consoleErrorTag = u"STSMultipleIncludeSubdomains"_ns;
2300 break;
2301 case nsISiteSecurityService::ERROR_INVALID_INCLUDE_SUBDOMAINS:
2302 consoleErrorTag = u"STSInvalidIncludeSubdomains"_ns;
2303 break;
2304 case nsISiteSecurityService::ERROR_COULD_NOT_SAVE_STATE:
2305 consoleErrorTag = u"STSCouldNotSaveState"_ns;
2306 break;
2307 default:
2308 consoleErrorTag = u"STSUnknownError"_ns;
2309 break;
2310 }
2311}
2312
2313/**
2314 * Process an HTTP Strict Transport Security (HSTS) header.
2315 */
2316nsresult nsHttpChannel::ProcessHSTSHeader(nsITransportSecurityInfo* aSecInfo) {
2317 nsHttpAtom atom(nsHttp::ResolveAtom("Strict-Transport-Security"_ns));
2318
2319 nsAutoCString securityHeader;
2320 nsresult rv = mResponseHead->GetHeader(atom, securityHeader);
2321 if (rv == NS_ERROR_NOT_AVAILABLE) {
2322 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)
;
2323 return NS_OK;
2324 }
2325 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"
, 2325)
) {
2326 return rv;
2327 }
2328
2329 if (!aSecInfo) {
2330 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)
;
2331 return NS_ERROR_INVALID_ARG;
2332 }
2333 nsITransportSecurityInfo::OverridableErrorCategory overridableErrorCategory;
2334 rv = aSecInfo->GetOverridableErrorCategory(&overridableErrorCategory);
2335 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"
, 2335)
) {
2336 return rv;
2337 }
2338 if (overridableErrorCategory !=
2339 nsITransportSecurityInfo::OverridableErrorCategory::ERROR_UNSET) {
2340 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)
2341 ("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)
2342 "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)
;
2343 return NS_ERROR_FAILURE;
2344 }
2345
2346 nsISiteSecurityService* sss = gHttpHandler->GetSSService();
2347 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"
, 2347); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
2348
2349 OriginAttributes originAttributes;
2350 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"
, 2351)
2351 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"
, 2351)
) {
2352 return NS_ERROR_FAILURE;
2353 }
2354
2355 uint32_t failureResult;
2356 rv = sss->ProcessHeader(mURI, securityHeader, originAttributes, nullptr,
2357 nullptr, &failureResult);
2358 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2359 nsAutoString consoleErrorCategory(u"Invalid HSTS Headers"_ns);
2360 nsAutoString consoleErrorTag;
2361 GetSTSConsoleErrorTag(failureResult, consoleErrorTag);
2362 Unused << AddSecurityMessage(consoleErrorTag, consoleErrorCategory);
2363 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)
2364 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)
;
2365 }
2366 return NS_OK;
2367}
2368
2369/**
2370 * Decide whether or not to remember Strict-Transport-Security, and whether
2371 * or not to enforce channel integrity.
2372 *
2373 * @return NS_ERROR_FAILURE if there's security information missing even though
2374 * it's an HTTPS connection.
2375 */
2376nsresult nsHttpChannel::ProcessSecurityHeaders() {
2377 // If this channel is not loading securely, STS or PKP doesn't do anything.
2378 // In the case of HSTS, the upgrade to HTTPS takes place earlier in the
2379 // channel load process.
2380 if (!mURI->SchemeIs("https")) {
2381 return NS_OK;
2382 }
2383
2384 if (IsBrowsingContextDiscarded()) {
2385 return NS_OK;
2386 }
2387
2388 nsAutoCString asciiHost;
2389 nsresult rv = mURI->GetAsciiHost(asciiHost);
2390 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"
, 2390); return NS_OK; } } while (false)
;
2391
2392 // If the channel is not a hostname, but rather an IP, do not process STS
2393 // or PKP headers
2394 if (HostIsIPLiteral(asciiHost)) {
2395 return NS_OK;
2396 }
2397
2398 // mSecurityInfo may not always be present, and if it's not then it is okay
2399 // to just disregard any security headers since we know nothing about the
2400 // security of the connection.
2401 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"
, 2401); return NS_OK; } } while (false)
;
2402
2403 // Only process HSTS headers for first-party loads. This prevents a
2404 // proliferation of useless HSTS state for partitioned third parties.
2405 if (!mLoadInfo->GetIsThirdPartyContextToTopWindow()) {
2406 rv = ProcessHSTSHeader(mSecurityInfo);
2407 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"
, 2407); return rv; } } while (false)
;
2408 }
2409
2410 return NS_OK;
2411}
2412
2413bool nsHttpChannel::IsHTTPS() { return mURI->SchemeIs("https"); }
2414
2415void nsHttpChannel::ProcessSSLInformation() {
2416 // If this is HTTPS, record any use of RSA so that Key Exchange Algorithm
2417 // can be whitelisted for TLS False Start in future sessions. We could
2418 // do the same for DH but its rarity doesn't justify the lookup.
2419
2420 if (mCanceled || NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0))) || !mSecurityInfo || !IsHTTPS() ||
2421 mPrivateBrowsing) {
2422 return;
2423 }
2424
2425 if (!mSecurityInfo) {
2426 return;
2427 }
2428
2429 uint32_t state;
2430 if (NS_SUCCEEDED(mSecurityInfo->GetSecurityState(&state))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mSecurityInfo->
GetSecurityState(&state))), 1)))
&&
2431 (state & nsIWebProgressListener::STATE_IS_BROKEN)) {
2432 // Send weak crypto warnings to the web console
2433 if (state & nsIWebProgressListener::STATE_USES_WEAK_CRYPTO) {
2434 nsString consoleErrorTag = u"WeakCipherSuiteWarning"_ns;
2435 nsString consoleErrorCategory = u"SSL"_ns;
2436 Unused << AddSecurityMessage(consoleErrorTag, consoleErrorCategory);
2437 }
2438 }
2439
2440 uint16_t tlsVersion;
2441 nsresult rv = mSecurityInfo->GetProtocolVersion(&tlsVersion);
2442 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) &&
2443 tlsVersion != nsITransportSecurityInfo::TLS_VERSION_1_2 &&
2444 tlsVersion != nsITransportSecurityInfo::TLS_VERSION_1_3) {
2445 nsString consoleErrorTag = u"DeprecatedTLSVersion2"_ns;
2446 nsString consoleErrorCategory = u"TLS"_ns;
2447 Unused << AddSecurityMessage(consoleErrorTag, consoleErrorCategory);
2448 }
2449}
2450
2451void nsHttpChannel::ProcessAltService() {
2452 // e.g. Alt-Svc: h2=":443"; ma=60
2453 // e.g. Alt-Svc: h2="otherhost:443"
2454 // Alt-Svc = 1#( alternative *( OWS ";" OWS parameter ) )
2455 // alternative = protocol-id "=" alt-authority
2456 // protocol-id = token ; percent-encoded ALPN protocol identifier
2457 // alt-authority = quoted-string ; containing [ uri-host ] ":" port
2458
2459 if (!LoadAllowAltSvc()) { // per channel opt out
2460 return;
2461 }
2462
2463 if (mWebTransportSessionEventListener) {
2464 return;
2465 }
2466
2467 if (!gHttpHandler->AllowAltSvc() || (mCaps & NS_HTTP_DISALLOW_SPDY(1 << 7))) {
2468 return;
2469 }
2470
2471 if (IsBrowsingContextDiscarded()) {
2472 return;
2473 }
2474
2475 nsAutoCString scheme;
2476 mURI->GetScheme(scheme);
2477 bool isHttp = scheme.EqualsLiteral("http");
2478 if (!isHttp && !scheme.EqualsLiteral("https")) {
2479 return;
2480 }
2481
2482 nsAutoCString altSvc;
2483 Unused << mResponseHead->GetHeader(nsHttp::Alternate_Service, altSvc);
2484 if (altSvc.IsEmpty()) {
2485 return;
2486 }
2487
2488 if (!nsHttp::IsReasonableHeaderValue(altSvc)) {
2489 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)
;
2490 return;
2491 }
2492
2493 nsAutoCString originHost;
2494 int32_t originPort = 80;
2495 mURI->GetPort(&originPort);
2496 if (NS_FAILED(mURI->GetAsciiHost(originHost))((bool)(__builtin_expect(!!(NS_FAILED_impl(mURI->GetAsciiHost
(originHost))), 0)))
) {
2497 return;
2498 }
2499
2500 nsCOMPtr<nsIInterfaceRequestor> callbacks;
2501 nsCOMPtr<nsProxyInfo> proxyInfo;
2502 NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
2503 getter_AddRefs(callbacks));
2504
2505 if (mProxyInfo) {
2506 proxyInfo = do_QueryInterface(mProxyInfo);
2507 }
2508
2509 OriginAttributes originAttributes;
2510 // Regular principal in case we have a proxy.
2511 if (proxyInfo &&
2512 !StaticPrefs::privacy_partition_network_state_connection_with_proxy()) {
2513 StoragePrincipalHelper::GetOriginAttributes(
2514 this, originAttributes, StoragePrincipalHelper::eRegularPrincipal);
2515 } else {
2516 StoragePrincipalHelper::GetOriginAttributesForNetworkState(
2517 this, originAttributes);
2518 }
2519
2520 AltSvcMapping::ProcessHeader(
2521 altSvc, scheme, originHost, originPort, mUsername, mPrivateBrowsing,
2522 callbacks, proxyInfo, mCaps & NS_HTTP_DISALLOW_SPDY(1 << 7), originAttributes);
2523}
2524
2525nsresult nsHttpChannel::ProcessResponse() {
2526 uint32_t httpStatus = mResponseHead->Status();
2527
2528 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)
2529 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)
;
2530
2531 // Gather data on whether the transaction and page (if this is
2532 // the initial page load) is being loaded with SSL.
2533 Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_IS_SSL,
2534 mConnectionInfo->EndToEndSSL());
2535 if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
2536 Telemetry::Accumulate(Telemetry::HTTP_PAGELOAD_IS_SSL,
2537 mConnectionInfo->EndToEndSSL());
2538 }
2539
2540 if (Telemetry::CanRecordPrereleaseData()) {
2541 // how often do we see something like Alt-Svc: "443:quic,p=1"
2542 // and Alt-Svc: "h3-****"
2543 nsAutoCString alt_service;
2544 Unused << mResponseHead->GetHeader(nsHttp::Alternate_Service, alt_service);
2545 uint32_t saw_quic = 0;
2546 if (!alt_service.IsEmpty()) {
2547 if (strstr(alt_service.get(), "h3-")) {
2548 saw_quic = 1;
2549 } else if (strstr(alt_service.get(), "quic")) {
2550 saw_quic = 2;
2551 }
2552 }
2553 Telemetry::Accumulate(Telemetry::HTTP_SAW_QUIC_ALT_PROTOCOL_2, saw_quic);
2554
2555 // Gather data on various response status to monitor any increased frequency
2556 // of auth failures due to Bug 1896350
2557 switch (httpStatus) {
2558 case 200:
2559 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 0);
2560 mozilla::glean::networking::http_response_status_code.Get("200_ok"_ns)
2561 .Add(1);
2562 break;
2563 case 301:
2564 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 1);
2565 mozilla::glean::networking::http_response_status_code
2566 .Get("301_moved_permanently"_ns)
2567 .Add(1);
2568 break;
2569 case 302:
2570 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 2);
2571 mozilla::glean::networking::http_response_status_code
2572 .Get("302_found"_ns)
2573 .Add(1);
2574 break;
2575 case 304:
2576 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 3);
2577 mozilla::glean::networking::http_response_status_code
2578 .Get("304_not_modified"_ns)
2579 .Add(1);
2580 break;
2581 case 307:
2582 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 4);
2583 mozilla::glean::networking::http_response_status_code
2584 .Get("307_temporary_redirect"_ns)
2585 .Add(1);
2586 break;
2587 case 308:
2588 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 5);
2589 mozilla::glean::networking::http_response_status_code
2590 .Get("308_permanent_redirect"_ns)
2591 .Add(1);
2592 break;
2593 case 400:
2594 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 6);
2595 mozilla::glean::networking::http_response_status_code
2596 .Get("400_bad_request"_ns)
2597 .Add(1);
2598 break;
2599 case 401:
2600 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 7);
2601 mozilla::glean::networking::http_response_status_code
2602 .Get("401_unauthorized"_ns)
2603 .Add(1);
2604 break;
2605 case 403:
2606 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 8);
2607 mozilla::glean::networking::http_response_status_code
2608 .Get("403_forbidden"_ns)
2609 .Add(1);
2610 break;
2611 case 404:
2612 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 9);
2613 mozilla::glean::networking::http_response_status_code
2614 .Get("404_not_found"_ns)
2615 .Add(1);
2616 break;
2617 case 421:
2618 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 11);
2619 mozilla::glean::networking::http_response_status_code
2620 .Get("421_misdirected_request"_ns)
2621 .Add(1);
2622 break;
2623 case 425:
2624 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 11);
2625 mozilla::glean::networking::http_response_status_code
2626 .Get("425_too_early"_ns)
2627 .Add(1);
2628 break;
2629 case 429:
2630 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 11);
2631 mozilla::glean::networking::http_response_status_code
2632 .Get("429_too_many_requests"_ns)
2633 .Add(1);
2634 break;
2635 case 500:
2636 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 10);
2637 mozilla::glean::networking::http_response_status_code
2638 .Get("other_5xx"_ns)
2639 .Add(1);
2640 break;
2641 default:
2642 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_STATUS_CODE, 11);
2643 if (httpStatus >= 400 && httpStatus < 500) {
2644 mozilla::glean::networking::http_response_status_code
2645 .Get("other_4xx"_ns)
2646 .Add(1);
2647 } else if (httpStatus > 500) {
2648 mozilla::glean::networking::http_response_status_code
2649 .Get("other_5xx"_ns)
2650 .Add(1);
2651 } else {
2652 mozilla::glean::networking::http_response_status_code.Get("other"_ns)
2653 .Add(1);
2654 }
2655 break;
2656 }
2657 }
2658
2659 // Let the predictor know whether this was a cacheable response or not so
2660 // that it knows whether or not to possibly prefetch this resource in the
2661 // future.
2662 // We use GetReferringPage because mReferrerInfo may not be set at all(this is
2663 // especially useful in xpcshell tests, where we don't have an actual pageload
2664 // to get a referrer from).
2665 nsCOMPtr<nsIURI> referrer = GetReferringPage();
2666 if (!referrer && mReferrerInfo) {
2667 referrer = mReferrerInfo->GetOriginalReferrer();
2668 }
2669
2670 if (referrer) {
2671 nsCOMPtr<nsILoadContextInfo> lci = GetLoadContextInfo(this);
2672 mozilla::net::Predictor::UpdateCacheability(
2673 referrer, mURI, httpStatus, mRequestHead, mResponseHead.get(), lci,
2674 IsThirdPartyTrackingResource());
2675 }
2676
2677 // Only allow 407 (authentication required) to continue
2678 if (mTransaction && mTransaction->ProxyConnectFailed() && httpStatus != 407) {
2679 return ProcessFailedProxyConnect(httpStatus);
2680 }
2681
2682 MOZ_ASSERT(!CachedContentIsValid() || mRaceCacheWithNetwork,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!CachedContentIsValid() || mRaceCacheWithNetwork)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!CachedContentIsValid() || mRaceCacheWithNetwork))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("!CachedContentIsValid() || 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"
, 2684); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!CachedContentIsValid() || 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) = 2684; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
2683 "We should not be hitting the network if we have valid cached "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!CachedContentIsValid() || mRaceCacheWithNetwork)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!CachedContentIsValid() || mRaceCacheWithNetwork))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("!CachedContentIsValid() || 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"
, 2684); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!CachedContentIsValid() || 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) = 2684; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
2684 "content unless we are racing the network and cache")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!CachedContentIsValid() || mRaceCacheWithNetwork)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!CachedContentIsValid() || mRaceCacheWithNetwork))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("!CachedContentIsValid() || 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"
, 2684); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!CachedContentIsValid() || 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) = 2684; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
2685
2686 ProcessSSLInformation();
2687
2688 // notify "http-on-examine-response" observers
2689 gHttpHandler->OnExamineResponse(this);
2690
2691 return ContinueProcessResponse1();
2692}
2693
2694void nsHttpChannel::AsyncContinueProcessResponse() {
2695 nsresult rv;
2696 rv = ContinueProcessResponse1();
2697 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2698 // A synchronous failure here would normally be passed as the return
2699 // value from OnStartRequest, which would in turn cancel the request.
2700 // If we're continuing asynchronously, we need to cancel the request
2701 // ourselves.
2702 Unused << Cancel(rv);
2703 }
2704}
2705
2706nsresult nsHttpChannel::ContinueProcessResponse1() {
2707 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"
, 2707); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 2707; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
2708 nsresult rv = NS_OK;
2709
2710 if (mSuspendCount) {
2711 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)
2712 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)
;
2713 mCallOnResume = [](nsHttpChannel* self) {
2714 self->AsyncContinueProcessResponse();
2715 return NS_OK;
2716 };
2717 return NS_OK;
2718 }
2719
2720 // Check if request was cancelled during http-on-examine-response.
2721 if (mCanceled) {
2722 return CallOnStartRequest();
2723 }
2724
2725 uint32_t httpStatus = mResponseHead->Status();
2726
2727 // STS, Cookies and Alt-Service should not be handled on proxy failure.
2728 // If proxy CONNECT response needs to complete, wait to process connection
2729 // for Strict-Transport-Security.
2730 if (!(mTransaction && mTransaction->ProxyConnectFailed()) &&
2731 (httpStatus != 407)) {
2732 CookieVisitor cookieVisitor(mResponseHead.get());
2733 SetCookieHeaders(cookieVisitor.CookieHeaders());
2734 nsCOMPtr<nsIParentChannel> parentChannel;
2735 NS_QueryNotificationCallbacks(this, parentChannel);
2736 if (RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel)) {
2737 httpParent->SetCookieHeaders(cookieVisitor.CookieHeaders());
2738 }
2739
2740 // Given a successful connection, process any STS or PKP data that's
2741 // relevant.
2742 nsresult rv = ProcessSecurityHeaders();
2743 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2744 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"
, 2744)
;
2745 }
2746
2747 if ((httpStatus < 500) && (httpStatus != 421)) {
2748 ProcessAltService();
2749 }
2750 }
2751
2752 if (LoadConcurrentCacheAccess() && LoadCachedContentIsPartial() &&
2753 httpStatus != 206) {
2754 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)
2755 (" 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)
2756 "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)
;
2757 return NS_ERROR_CORRUPTED_CONTENT;
2758 }
2759
2760 // handle unused username and password in url (see bug 232567)
2761 if (httpStatus != 401 && httpStatus != 407) {
2762 if (!mAuthRetryPending) {
2763 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"
, 2763); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mAuthProvider"
")"); do { *((volatile int*)__null) = 2763; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2764 rv = mAuthProvider ? mAuthProvider->CheckForSuperfluousAuth()
2765 : NS_ERROR_UNEXPECTED;
2766 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2767 mStatus = rv;
2768 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)
2769 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)
;
2770 }
2771 }
2772 if (mCanceled) return CallOnStartRequest();
2773
2774 // reset the authentication's current continuation state because ourvr
2775 // last authentication attempt has been completed successfully
2776 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"
, 2776); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mAuthProvider"
")"); do { *((volatile int*)__null) = 2776; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2777 rv = mAuthProvider ? mAuthProvider->Disconnect(NS_ERROR_ABORT)
2778 : NS_ERROR_UNEXPECTED;
2779 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2780 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)
;
2781 }
2782 mAuthProvider = nullptr;
2783 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)
;
2784 }
2785
2786 gHttpHandler->OnAfterExamineResponse(this);
2787
2788 // No process switch needed, continue as normal.
2789 return ContinueProcessResponse2(rv);
2790}
2791
2792nsresult nsHttpChannel::ContinueProcessResponse2(nsresult rv) {
2793 if (mSuspendCount) {
2794 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)
2795 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)
;
2796 mCallOnResume = [rv](nsHttpChannel* self) {
2797 Unused << self->ContinueProcessResponse2(rv);
2798 return NS_OK;
2799 };
2800 return NS_OK;
2801 }
2802
2803 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && !mCanceled) {
2804 // The process switch failed, cancel this channel.
2805 Cancel(rv);
2806 return CallOnStartRequest();
2807 }
2808
2809 if (mAPIRedirectTo && !mCanceled) {
2810 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"
, 2810); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
")"); do { *((volatile int*)__null) = 2810; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2811
2812 PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse3);
2813 rv = StartRedirectChannelToURI(
2814 mAPIRedirectTo->first(),
2815 mAPIRedirectTo->second() ? nsIChannelEventSink::REDIRECT_TEMPORARY |
2816 nsIChannelEventSink::REDIRECT_TRANSPARENT
2817 : nsIChannelEventSink::REDIRECT_TEMPORARY);
2818 mAPIRedirectTo = Nothing();
2819 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2820 return NS_OK;
2821 }
2822 PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse3);
2823 }
2824
2825 // Hack: ContinueProcessResponse3 uses NS_OK to detect successful
2826 // redirects, so we distinguish this codepath (a non-redirect that's
2827 // processing normally) by passing in a bogus error code.
2828 return ContinueProcessResponse3(NS_BINDING_FAILED);
2829}
2830
2831nsresult nsHttpChannel::ContinueProcessResponse3(nsresult rv) {
2832 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)
2833 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)
;
2834
2835 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2836 // redirectTo() has passed through, we don't want to go on with
2837 // this channel. It will now be canceled by the redirect handling
2838 // code that called this function.
2839 return NS_OK;
2840 }
2841
2842 rv = NS_OK;
2843
2844 uint32_t httpStatus = mResponseHead->Status();
2845 bool transactionRestarted = mTransaction->TakeRestartedState();
2846
2847 // handle different server response categories. Note that we handle
2848 // caching or not caching of error pages in
2849 // nsHttpResponseHead::MustValidate; if you change this switch, update that
2850 // one
2851 switch (httpStatus) {
2852 case 200:
2853 case 203:
2854 // Per RFC 2616, 14.35.2, "A server MAY ignore the Range header".
2855 // So if a server does that and sends 200 instead of 206 that we
2856 // expect, notify our caller.
2857 // However, if we wanted to start from the beginning, let it go through
2858 if (LoadResuming() && mStartPos != 0) {
2859 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)
;
2860 Cancel(NS_ERROR_NOT_RESUMABLE);
2861 rv = CallOnStartRequest();
2862 break;
2863 }
2864 // these can normally be cached
2865 rv = ProcessNormal();
2866 MaybeInvalidateCacheEntryForSubsequentGet();
2867 break;
2868 case 206:
2869 if (LoadCachedContentIsPartial()) { // an internal byte range request...
2870 auto func = [](auto* self, nsresult aRv) {
2871 return self->ContinueProcessResponseAfterPartialContent(aRv);
2872 };
2873 rv = ProcessPartialContent(func);
2874 // Directly call ContinueProcessResponseAfterPartialContent if channel
2875 // is not suspended or ProcessPartialContent throws.
2876 if (!mSuspendCount || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2877 return ContinueProcessResponseAfterPartialContent(rv);
2878 }
2879 return NS_OK;
2880 } else {
2881 mCacheInputStream.CloseAndRelease();
2882 rv = ProcessNormal();
2883 }
2884 break;
2885 case 301:
2886 case 302:
2887 case 307:
2888 case 308:
2889 case 303:
2890#if 0
2891 case 305: // disabled as a security measure (see bug 187996).
2892#endif
2893 // don't store the response body for redirects
2894 MaybeInvalidateCacheEntryForSubsequentGet();
2895 PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse4);
2896 rv = AsyncProcessRedirection(httpStatus);
2897 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2898 PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessResponse4);
2899 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)
2900 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)
;
2901 // don't cache failed redirect responses.
2902 if (mCacheEntry) mCacheEntry->AsyncDoom(nullptr);
2903 if (DoNotRender3xxBody(rv)) {
2904 mStatus = rv;
2905 DoNotifyListener();
2906 } else {
2907 rv = ContinueProcessResponse4(rv);
2908 }
2909 }
2910 break;
2911 case 304:
2912 if (!ShouldBypassProcessNotModified()) {
2913 auto func = [](auto* self, nsresult aRv) {
2914 return self->ContinueProcessResponseAfterNotModified(aRv);
2915 };
2916 rv = ProcessNotModified(func);
2917 // Directly call ContinueProcessResponseAfterNotModified if channel
2918 // is not suspended or ProcessNotModified throws.
2919 if (!mSuspendCount || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2920 return ContinueProcessResponseAfterNotModified(rv);
2921 }
2922 return NS_OK;
2923 }
2924
2925 // Don't cache uninformative 304
2926 if (LoadCustomConditionalRequest()) {
2927 CloseCacheEntry(false);
2928 }
2929
2930 if (ShouldBypassProcessNotModified() || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2931 rv = ProcessNormal();
2932 }
2933 break;
2934 case 401:
2935 case 407:
2936 if (MOZ_UNLIKELY(httpStatus == 407 && transactionRestarted)(__builtin_expect(!!(httpStatus == 407 && transactionRestarted
), 0))
) {
2937 // The transaction has been internally restarted. We want to
2938 // authenticate to the proxy again, so reuse either cached credentials
2939 // or use default credentials for NTLM/Negotiate. This prevents
2940 // considering the previously used credentials as invalid.
2941 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"
, 2941); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mAuthProvider"
")"); do { *((volatile int*)__null) = 2941; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2942 if (!mAuthProvider) {
2943 mStatus = NS_ERROR_UNEXPECTED;
2944 return ProcessNormal();
2945 }
2946 mAuthProvider->ClearProxyIdent();
2947 }
2948 if (!LoadAuthRedirectedChannel() &&
2949 MOZ_UNLIKELY(LoadCustomAuthHeader())(__builtin_expect(!!(LoadCustomAuthHeader()), 0)) && httpStatus == 401) {
2950 // When a custom auth header fails, we don't want to try
2951 // any cached credentials, nor we want to ask the user.
2952 // It's up to the consumer to re-try w/o setting a custom
2953 // auth header if cached credentials should be attempted.
2954 rv = NS_ERROR_FAILURE;
2955 } else if (httpStatus == 401 &&
2956 StaticPrefs::
2957 network_auth_supress_auth_prompt_for_XFO_failures() &&
2958 !nsContentSecurityUtils::CheckCSPFrameAncestorAndXFO(this)) {
2959 // CSP Frame Ancestor and X-Frame-Options check has failed
2960 // Do not prompt http auth - Bug 1629307
2961 rv = NS_ERROR_FAILURE;
2962 } else {
2963 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"
, 2963); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mAuthProvider"
")"); do { *((volatile int*)__null) = 2963; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2964 rv = mAuthProvider
2965 ? mAuthProvider->ProcessAuthentication(
2966 httpStatus, mConnectionInfo->EndToEndSSL() &&
2967 mTransaction &&
2968 mTransaction->ProxyConnectFailed())
2969 : NS_ERROR_UNEXPECTED;
2970 }
2971 if (rv == NS_ERROR_IN_PROGRESS) {
2972 // authentication prompt has been invoked and result
2973 // is expected asynchronously
2974 mIsAuthChannel = true;
2975 mAuthRetryPending = true;
2976 if (httpStatus == 407 ||
2977 (mTransaction && mTransaction->ProxyConnectFailed())) {
2978 StoreProxyAuthPending(true);
2979 }
2980
2981 // suspend the transaction pump to stop receiving the
2982 // unauthenticated content data. We will throw that data
2983 // away when user provides credentials or resume the pump
2984 // when user refuses to authenticate.
2985 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)
2986 ("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)
2987 "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)
;
2988 mTransactionPump->Suspend();
2989
2990#ifdef DEBUG1
2991 // This is for test purposes only. See bug 1683176 for details.
2992 gHttpHandler->OnTransactionSuspendedDueToAuthentication(this);
2993#endif
2994 rv = NS_OK;
2995 } else if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2996 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)
2997 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)
;
2998 if (mTransaction && mTransaction->ProxyConnectFailed()) {
2999 return ProcessFailedProxyConnect(httpStatus);
3000 }
3001 if (!mAuthRetryPending) {
3002 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"
, 3002); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mAuthProvider"
")"); do { *((volatile int*)__null) = 3002; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3003 rv = mAuthProvider ? mAuthProvider->CheckForSuperfluousAuth()
3004 : NS_ERROR_UNEXPECTED;
3005 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3006 mStatus = rv;
3007 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)
3008 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)
;
3009 }
3010 }
3011 rv = ProcessNormal();
3012 } else {
3013 mIsAuthChannel = true;
3014 mAuthRetryPending = true;
3015 if (StaticPrefs::network_auth_use_redirect_for_retries()) {
3016 if (NS_SUCCEEDED(RedirectToNewChannelForAuthRetry())((bool)(__builtin_expect(!!(!NS_FAILED_impl(RedirectToNewChannelForAuthRetry
())), 1)))
) {
3017 return NS_OK;
3018 }
3019 mAuthRetryPending = false;
3020 rv = ProcessNormal();
3021 }
3022 }
3023 break;
3024
3025 case 408:
3026 case 425:
3027 case 429:
3028 // Do not cache 408, 425 and 429.
3029 CloseCacheEntry(false);
3030 [[fallthrough]]; // process normally
3031 default:
3032 rv = ProcessNormal();
3033 MaybeInvalidateCacheEntryForSubsequentGet();
3034 break;
3035 }
3036
3037 UpdateCacheDisposition(false, false);
3038 return rv;
3039}
3040
3041nsresult nsHttpChannel::ContinueProcessResponseAfterPartialContent(
3042 nsresult aRv) {
3043 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)
3044 ("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)
3045 "[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)
3046 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)
;
3047
3048 UpdateCacheDisposition(false, NS_SUCCEEDED(aRv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aRv)), 1))));
3049 return aRv;
3050}
3051
3052nsresult nsHttpChannel::ContinueProcessResponseAfterNotModified(nsresult aRv) {
3053 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)
3054 ("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)
3055 "[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)
3056 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)
;
3057
3058 if (NS_SUCCEEDED(aRv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aRv)), 1)))) {
3059 StoreTransactionReplaced(true);
3060 UpdateCacheDisposition(true, false);
3061 return NS_OK;
3062 }
3063
3064 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)
3065 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)
;
3066
3067 // We cannot read from the cache entry, it might be in an
3068 // incosistent state. Doom it and redirect the channel
3069 // to the same URI to reload from the network.
3070 mCacheInputStream.CloseAndRelease();
3071 if (mCacheEntry) {
3072 mCacheEntry->AsyncDoom(nullptr);
3073 mCacheEntry = nullptr;
3074 }
3075
3076 nsresult rv =
3077 StartRedirectChannelToURI(mURI, nsIChannelEventSink::REDIRECT_INTERNAL);
3078 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3079 return NS_OK;
3080 }
3081
3082 // Don't cache uninformative 304
3083 if (LoadCustomConditionalRequest()) {
3084 CloseCacheEntry(false);
3085 }
3086
3087 if (ShouldBypassProcessNotModified() || NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3088 rv = ProcessNormal();
3089 }
3090
3091 UpdateCacheDisposition(false, false);
3092 return rv;
3093}
3094
3095static void ReportHttpResponseVersion(HttpVersion version) {
3096 if (Telemetry::CanRecordPrereleaseData()) {
3097 Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_VERSION,
3098 static_cast<uint32_t>(version));
3099 }
3100 mozilla::glean::networking::http_response_version
3101 .Get(HttpVersionToTelemetryLabel(version))
3102 .Add(1);
3103}
3104
3105void nsHttpChannel::UpdateCacheDisposition(bool aSuccessfulReval,
3106 bool aPartialContentUsed) {
3107 if (mRaceDelay && !mRaceCacheWithNetwork &&
3108 (LoadCachedContentIsPartial() || mDidReval)) {
3109 if (aSuccessfulReval || aPartialContentUsed) {
3110 AccumulateCategorical(
3111 Telemetry::LABELS_NETWORK_RACE_CACHE_VALIDATION::CachedContentUsed);
3112 } else {
3113 AccumulateCategorical(Telemetry::LABELS_NETWORK_RACE_CACHE_VALIDATION::
3114 CachedContentNotUsed);
3115 }
3116 }
3117
3118 PROFILER_MARKER_TEXT(do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("CacheDisposition", ::geckoprofiler::category::NETWORK, {}, ::
geckoprofiler::markers::TextMarker{}, nsPrintfCString( !mDidReval
? "Missed" : (aSuccessfulReval ? "HitViaReval" : "MissedViaReval"
))); } } while (false); } while (false)
3119 "CacheDisposition", NETWORK, {},do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("CacheDisposition", ::geckoprofiler::category::NETWORK, {}, ::
geckoprofiler::markers::TextMarker{}, nsPrintfCString( !mDidReval
? "Missed" : (aSuccessfulReval ? "HitViaReval" : "MissedViaReval"
))); } } while (false); } while (false)
3120 nsPrintfCString(do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("CacheDisposition", ::geckoprofiler::category::NETWORK, {}, ::
geckoprofiler::markers::TextMarker{}, nsPrintfCString( !mDidReval
? "Missed" : (aSuccessfulReval ? "HitViaReval" : "MissedViaReval"
))); } } while (false); } while (false)
3121 !mDidReval ? "Missed"do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("CacheDisposition", ::geckoprofiler::category::NETWORK, {}, ::
geckoprofiler::markers::TextMarker{}, nsPrintfCString( !mDidReval
? "Missed" : (aSuccessfulReval ? "HitViaReval" : "MissedViaReval"
))); } } while (false); } while (false)
3122 : (aSuccessfulReval ? "HitViaReval" : "MissedViaReval")))do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("CacheDisposition", ::geckoprofiler::category::NETWORK, {}, ::
geckoprofiler::markers::TextMarker{}, nsPrintfCString( !mDidReval
? "Missed" : (aSuccessfulReval ? "HitViaReval" : "MissedViaReval"
))); } } while (false); } while (false)
;
3123 if (Telemetry::CanRecordPrereleaseData()) {
3124 CacheDisposition cacheDisposition;
3125 if (!mDidReval) {
3126 cacheDisposition = kCacheMissed;
3127 } else if (aSuccessfulReval) {
3128 cacheDisposition = kCacheHitViaReval;
3129 } else {
3130 cacheDisposition = kCacheMissedViaReval;
3131 }
3132 AccumulateCacheHitTelemetry(cacheDisposition, this);
3133 mCacheDisposition = cacheDisposition;
3134 }
3135
3136 ReportHttpResponseVersion(mResponseHead->Version());
3137}
3138
3139nsresult nsHttpChannel::ContinueProcessResponse4(nsresult rv) {
3140 bool doNotRender = DoNotRender3xxBody(rv);
3141
3142 if (rv == NS_ERROR_DOM_BAD_URI && mRedirectURI) {
3143 bool isHTTP =
3144 mRedirectURI->SchemeIs("http") || mRedirectURI->SchemeIs("https");
3145 if (!isHTTP) {
3146 // This was a blocked attempt to redirect and subvert the system by
3147 // redirecting to another protocol (perhaps javascript:)
3148 // In that case we want to throw an error instead of displaying the
3149 // non-redirected response body.
3150 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)
;
3151 doNotRender = true;
3152 rv = NS_ERROR_CORRUPTED_CONTENT;
3153 }
3154 }
3155
3156 if (doNotRender) {
3157 Cancel(rv);
3158 DoNotifyListener();
3159 return rv;
3160 }
3161
3162 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3163 UpdateInhibitPersistentCachingFlag();
3164
3165 MaybeCreateCacheEntryWhenRCWN();
3166
3167 rv = InitCacheEntry();
3168 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3169 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)
3170 ("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)
3171 "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)
3172 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)
;
3173 }
3174 CloseCacheEntry(false);
3175 return NS_OK;
3176 }
3177
3178 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)
3179 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)
;
3180 if (mTransaction && mTransaction->ProxyConnectFailed()) {
3181 return ProcessFailedProxyConnect(mRedirectType);
3182 }
3183 return ProcessNormal();
3184}
3185
3186nsresult nsHttpChannel::ProcessNormal() {
3187 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)
;
3188
3189 return ContinueProcessNormal(NS_OK);
3190}
3191
3192nsresult nsHttpChannel::ContinueProcessNormal(nsresult rv) {
3193 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)
;
3194
3195 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3196 // Fill the failure status here, we have failed to fall back, thus we
3197 // have to report our status as failed.
3198 mStatus = rv;
3199 DoNotifyListener();
3200 return rv;
3201 }
3202
3203 rv = ProcessCrossOriginSecurityHeaders();
3204 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3205 mStatus = rv;
3206 HandleAsyncAbort();
3207 return rv;
3208 }
3209
3210 // if we're here, then any byte-range requests failed to result in a partial
3211 // response. we must clear this flag to prevent BufferPartialContent from
3212 // being called inside our OnDataAvailable (see bug 136678).
3213 StoreCachedContentIsPartial(false);
3214
3215 UpdateInhibitPersistentCachingFlag();
3216
3217 MaybeCreateCacheEntryWhenRCWN();
3218
3219 // this must be called before firing OnStartRequest, since http clients,
3220 // such as imagelib, expect our cache entry to already have the correct
3221 // expiration time (bug 87710).
3222 if (mCacheEntry) {
3223 rv = InitCacheEntry();
3224 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) CloseCacheEntry(true);
3225 }
3226
3227 // Check that the server sent us what we were asking for
3228 if (LoadResuming()) {
3229 // Create an entity id from the response
3230 nsAutoCString id;
3231 rv = GetEntityID(id);
3232 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3233 // If creating an entity id is not possible -> error
3234 Cancel(NS_ERROR_NOT_RESUMABLE);
3235 } else if (mResponseHead->Status() != 206 &&
3236 mResponseHead->Status() != 200) {
3237 // Probably 404 Not Found, 412 Precondition Failed or
3238 // 416 Invalid Range -> error
3239 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)
3240 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)
;
3241 Cancel(NS_ERROR_ENTITY_CHANGED);
3242 }
3243 // If we were passed an entity id, verify it's equal to the server's
3244 else if (!mEntityID.IsEmpty()) {
3245 if (!mEntityID.Equals(id)) {
3246 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)
3247 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)
;
3248 Cancel(NS_ERROR_ENTITY_CHANGED);
3249 }
3250 }
3251 }
3252
3253 rv = CallOnStartRequest();
3254 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3255
3256 // install cache listener if we still have a cache entry open
3257 if (mCacheEntry && !LoadCacheEntryIsReadOnly()) {
3258 rv = InstallCacheListener();
3259 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3260 }
3261
3262 return NS_OK;
3263}
3264
3265nsresult nsHttpChannel::PromptTempRedirect() {
3266 if (!gHttpHandler->PromptTempRedirect()) {
3267 return NS_OK;
3268 }
3269 nsresult rv;
3270 nsCOMPtr<nsIStringBundleService> bundleService;
3271 bundleService = mozilla::components::StringBundle::Service(&rv);
3272 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3273
3274 nsCOMPtr<nsIStringBundle> stringBundle;
3275 rv =
3276 bundleService->CreateBundle(NECKO_MSGS_URL"chrome://necko/locale/necko.properties", getter_AddRefs(stringBundle));
3277 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3278
3279 nsAutoString messageString;
3280 rv = stringBundle->GetStringFromName("RepostFormData", messageString);
3281 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3282 bool repost = false;
3283
3284 nsCOMPtr<nsIPrompt> prompt;
3285 GetCallback(prompt);
3286 if (!prompt) return NS_ERROR_NO_INTERFACE;
3287
3288 prompt->Confirm(nullptr, messageString.get(), &repost);
3289 if (!repost) return NS_ERROR_FAILURE;
3290 }
3291
3292 return rv;
3293}
3294
3295nsresult nsHttpChannel::ProxyFailover() {
3296 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)
;
3297
3298 nsresult rv;
3299
3300 nsCOMPtr<nsIProtocolProxyService> pps;
3301 pps = mozilla::components::ProtocolProxy::Service(&rv);
3302 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3303
3304 nsCOMPtr<nsIProxyInfo> pi;
3305 rv = pps->GetFailoverForProxy(mConnectionInfo->ProxyInfo(), mURI, mStatus,
3306 getter_AddRefs(pi));
3307#ifdef MOZ_PROXY_DIRECT_FAILOVER1
3308 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3309 if (!StaticPrefs::network_proxy_failover_direct()) {
3310 return rv;
3311 }
3312 // If this request used a failed proxy and there is no failover available,
3313 // fallback to DIRECT connections for conservative requests.
3314 if (LoadBeConservative()) {
3315 rv = pps->NewProxyInfo("direct"_ns, ""_ns, 0, ""_ns, ""_ns, 0, UINT32_MAX(4294967295U),
3316 nullptr, getter_AddRefs(pi));
3317 }
3318#endif
3319 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3320 return rv;
3321 }
3322#ifdef MOZ_PROXY_DIRECT_FAILOVER1
3323 }
3324#endif
3325
3326 // XXXbz so where does this codepath remove us from the loadgroup,
3327 // exactly?
3328 return AsyncDoReplaceWithProxy(pi);
3329}
3330
3331void nsHttpChannel::SetHTTPSSVCRecord(
3332 already_AddRefed<nsIDNSHTTPSSVCRecord>&& aRecord) {
3333 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)
;
3334 nsCOMPtr<nsIDNSHTTPSSVCRecord> record = aRecord;
3335 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"
, 3335); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mHTTPSSVCRecord"
")"); do { *((volatile int*)__null) = 3335; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3336 mHTTPSSVCRecord.emplace(std::move(record));
3337}
3338
3339void nsHttpChannel::HandleAsyncRedirectChannelToHttps() {
3340 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"
, 3340); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 3340; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
3341
3342 if (mSuspendCount) {
3343 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)
3344 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)
;
3345 mCallOnResume = [](nsHttpChannel* self) {
3346 self->HandleAsyncRedirectChannelToHttps();
3347 return NS_OK;
3348 };
3349 return;
3350 }
3351
3352 nsresult rv = StartRedirectChannelToHttps();
3353 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3354 rv = ContinueAsyncRedirectChannelToURI(rv);
3355 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3356 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)
3357 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)
;
3358 }
3359 }
3360}
3361
3362nsresult nsHttpChannel::StartRedirectChannelToHttps() {
3363 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)
;
3364
3365 nsCOMPtr<nsIURI> upgradedURI;
3366 nsresult rv = NS_GetSecureUpgradedURI(mURI, getter_AddRefs(upgradedURI));
3367 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"
, 3367); return rv; } } while (false)
;
3368
3369 return StartRedirectChannelToURI(
3370 upgradedURI, nsIChannelEventSink::REDIRECT_PERMANENT |
3371 nsIChannelEventSink::REDIRECT_STS_UPGRADE);
3372}
3373
3374void nsHttpChannel::HandleAsyncAPIRedirect() {
3375 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"
, 3375); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 3375; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
3376 MOZ_ASSERT(mAPIRedirectTo, "How did that happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAPIRedirectTo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAPIRedirectTo))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mAPIRedirectTo"
" (" "How did that happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3376); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAPIRedirectTo"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 3376; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
3377 MOZ_ASSERT(mAPIRedirectTo->first(), "How did that happen?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mAPIRedirectTo->first())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mAPIRedirectTo->first()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("mAPIRedirectTo->first()"
" (" "How did that happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 3377); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAPIRedirectTo->first()"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 3377; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
3378
3379 if (mSuspendCount) {
3380 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)
;
3381 mCallOnResume = [](nsHttpChannel* self) {
3382 self->HandleAsyncAPIRedirect();
3383 return NS_OK;
3384 };
3385 return;
3386 }
3387
3388 nsresult rv = StartRedirectChannelToURI(
3389 mAPIRedirectTo->first(),
3390 mAPIRedirectTo->second() ? nsIChannelEventSink::REDIRECT_PERMANENT |
3391 nsIChannelEventSink::REDIRECT_TRANSPARENT
3392 : nsIChannelEventSink::REDIRECT_PERMANENT);
3393 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3394 rv = ContinueAsyncRedirectChannelToURI(rv);
3395 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3396 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)
3397 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)
;
3398 }
3399 }
3400}
3401
3402void nsHttpChannel::HandleAsyncRedirectToUnstrippedURI() {
3403 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"
, 3403); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
") (" "How did that happen?" ")"); do { *((volatile int*)__null
) = 3403; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
3404
3405 if (mSuspendCount) {
3406 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)
3407 ("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)
3408 "[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)
3409 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)
;
3410 mCallOnResume = [](nsHttpChannel* self) {
3411 self->HandleAsyncRedirectToUnstrippedURI();
3412 return NS_OK;
3413 };
3414 return;
3415 }
3416
3417 nsCOMPtr<nsIURI> unstrippedURI;
3418 mLoadInfo->GetUnstrippedURI(getter_AddRefs(unstrippedURI));
3419
3420 // Clear the unstripped URI from the loadInfo before starting redirect in case
3421 // endless redirect.
3422 mLoadInfo->SetUnstrippedURI(nullptr);
3423
3424 nsresult rv = StartRedirectChannelToURI(
3425 unstrippedURI, nsIChannelEventSink::REDIRECT_PERMANENT);
3426
3427 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3428 rv = ContinueAsyncRedirectChannelToURI(rv);
3429 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3430 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)
3431 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)
;
3432 }
3433 }
3434}
3435nsresult nsHttpChannel::RedirectToNewChannelForAuthRetry() {
3436 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)
;
3437 nsresult rv = NS_OK;
3438
3439 nsCOMPtr<nsILoadInfo> redirectLoadInfo = CloneLoadInfoForRedirect(
3440 mURI, nsIChannelEventSink::REDIRECT_INTERNAL |
3441 nsIChannelEventSink::REDIRECT_AUTH_RETRY);
3442
3443 nsCOMPtr<nsIIOService> ioService;
3444
3445 rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
3446 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"
, 3446); return rv; } } while (false)
;
3447
3448 nsCOMPtr<nsIChannel> newChannel;
3449 rv = gHttpHandler->NewProxiedChannel(mURI, mProxyInfo, mProxyResolveFlags,
3450 mProxyURI, mLoadInfo,
3451 getter_AddRefs(newChannel));
3452
3453 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"
, 3453); return rv; } } while (false)
;
3454
3455 rv = SetupReplacementChannel(mURI, newChannel, true,
3456 nsIChannelEventSink::REDIRECT_INTERNAL |
3457 nsIChannelEventSink::REDIRECT_AUTH_RETRY);
3458 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"
, 3458); return rv; } } while (false)
;
3459
3460 // rewind the upload stream
3461 if (mUploadStream) {
3462 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
3463 nsresult rv = NS_ERROR_NO_INTERFACE;
3464 if (seekable) {
3465 rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
3466 }
3467
3468 // This should not normally happen, but it's possible that big memory
3469 // blobs originating in the other process can't be rewinded.
3470 // In that case we just fail the request, otherwise the content length
3471 // will not match and this load will never complete.
3472 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"
, 3472); return rv; } } while (false)
;
3473 }
3474
3475 RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(newChannel);
3476
3477 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"
, 3477); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAuthProvider"
")"); do { *((volatile int*)__null) = 3477; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3478 httpChannelImpl->mAuthProvider = std::move(mAuthProvider);
3479
3480 httpChannelImpl->mProxyInfo = mProxyInfo;
3481
3482 if ((mCaps & NS_HTTP_STICKY_CONNECTION(1 << 2)) ||
3483 mTransaction->HasStickyConnection()) {
3484 mConnectionInfo = mTransaction->GetConnInfo();
3485
3486 httpChannelImpl->mTransactionSticky = mTransaction;
3487
3488 if (mTransaction->Http2Disabled()) {
3489 httpChannelImpl->mCaps |= NS_HTTP_DISALLOW_SPDY(1 << 7);
3490 }
3491 if (mTransaction->Http3Disabled()) {
3492 httpChannelImpl->mCaps |= NS_HTTP_DISALLOW_HTTP3(1 << 21);
3493 }
3494 }
3495 httpChannelImpl->mCaps |= NS_HTTP_STICKY_CONNECTION(1 << 2);
3496 if (LoadAuthConnectionRestartable()) {
3497 httpChannelImpl->mCaps |= NS_HTTP_CONNECTION_RESTARTABLE(1 << 13);
3498 } else {
3499 httpChannelImpl->mCaps &= ~NS_HTTP_CONNECTION_RESTARTABLE(1 << 13);
3500 }
3501
3502 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"
, 3502); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mConnectionInfo"
")"); do { *((volatile int*)__null) = 3502; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3503 httpChannelImpl->mConnectionInfo = mConnectionInfo->Clone();
3504
3505 // we need to store the state to skip unnecessary checks in the new channel
3506 httpChannelImpl->StoreAuthRedirectedChannel(true);
3507
3508 // We must copy proxy and auth header to the new channel.
3509 // Although the new channel can populate auth headers from auth cache, we
3510 // would still like to use the auth headers generated in this channel. The
3511 // main reason for doing this is that certain connection-based/stateful auth
3512 // schemes like NTLM will fail when we try generate the credentials more than
3513 // the number of times the server has presented us the challenge due to the
3514 // usage of nonce in generating the credentials Copying the auth header will
3515 // bypass generation of the credentials
3516 nsAutoCString authVal;
3517 if (NS_SUCCEEDED(GetRequestHeader("Proxy-Authorization"_ns, authVal))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetRequestHeader(
"Proxy-Authorization"_ns, authVal))), 1)))
) {
3518 httpChannelImpl->SetRequestHeader("Proxy-Authorization"_ns, authVal, false);
3519 }
3520 if (NS_SUCCEEDED(GetRequestHeader("Authorization"_ns, authVal))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetRequestHeader(
"Authorization"_ns, authVal))), 1)))
) {
3521 httpChannelImpl->SetRequestHeader("Authorization"_ns, authVal, false);
3522 }
3523
3524 httpChannelImpl->SetBlockAuthPrompt(LoadBlockAuthPrompt());
3525 mRedirectChannel = newChannel;
3526
3527 rv = gHttpHandler->AsyncOnChannelRedirect(
3528 this, newChannel,
3529 nsIChannelEventSink::REDIRECT_INTERNAL |
3530 nsIChannelEventSink::REDIRECT_AUTH_RETRY);
3531
3532 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = WaitForRedirectCallback();
3533
3534 // redirected channel will be opened after we receive the OnStopRequest
3535
3536 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3537 AutoRedirectVetoNotifier notifier(this, rv);
3538 mRedirectChannel = nullptr;
3539 }
3540
3541 return rv;
3542}
3543nsresult nsHttpChannel::StartRedirectChannelToURI(nsIURI* upgradedURI,
3544 uint32_t flags) {
3545 nsresult rv = NS_OK;
3546 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)
;
3547
3548 nsCOMPtr<nsIChannel> newChannel;
3549 nsCOMPtr<nsILoadInfo> redirectLoadInfo =
3550 CloneLoadInfoForRedirect(upgradedURI, flags);
3551
3552 nsCOMPtr<nsIIOService> ioService;
3553 rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
3554 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"
, 3554); return rv; } } while (false)
;
3555
3556 rv = NS_NewChannelInternal(getter_AddRefs(newChannel), upgradedURI,
3557 redirectLoadInfo,
3558 nullptr, // PerformanceStorage
3559 nullptr, // aLoadGroup
3560 nullptr, // aCallbacks
3561 nsIRequest::LOAD_NORMAL, ioService);
3562 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"
, 3562); return rv; } } while (false)
;
3563
3564 rv = SetupReplacementChannel(upgradedURI, newChannel, true, flags);
3565 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"
, 3565); return rv; } } while (false)
;
3566
3567 if (mHTTPSSVCRecord) {
3568 RefPtr<nsHttpChannel> httpChan = do_QueryObject(newChannel);
3569 nsCOMPtr<nsIDNSHTTPSSVCRecord> rec = mHTTPSSVCRecord.ref();
3570 if (httpChan && rec) {
3571 httpChan->SetHTTPSSVCRecord(rec.forget());
3572 }
3573 }
3574
3575 // Inform consumers about this fake redirect
3576 mRedirectChannel = newChannel;
3577
3578 PushRedirectAsyncFunc(&nsHttpChannel::ContinueAsyncRedirectChannelToURI);
3579 rv = gHttpHandler->AsyncOnChannelRedirect(this, newChannel, flags);
3580
3581 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = WaitForRedirectCallback();
3582
3583 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3584 AutoRedirectVetoNotifier notifier(this, rv);
3585
3586 /* Remove the async call to ContinueAsyncRedirectChannelToURI().
3587 * It is called directly by our callers upon return (to clean up
3588 * the failed redirect). */
3589 PopRedirectAsyncFunc(&nsHttpChannel::ContinueAsyncRedirectChannelToURI);
3590 }
3591
3592 return rv;
3593}
3594
3595nsresult nsHttpChannel::ContinueAsyncRedirectChannelToURI(nsresult rv) {
3596 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)
;
3597
3598 // Since we handle mAPIRedirectTo uri also after on-examine-response handler
3599 // rather drop it here to avoid any redirect loops, even just hypothetical.
3600 mAPIRedirectTo = Nothing();
3601
3602 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3603 rv = OpenRedirectChannel(rv);
3604 }
3605
3606 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3607 // Cancel the channel here, the update to https had been vetoed
3608 // but from the security reasons we have to discard the whole channel
3609 // load.
3610 Cancel(rv);
3611 }
3612
3613 if (mLoadGroup) {
3614 mLoadGroup->RemoveRequest(this, nullptr, mStatus);
3615 }
3616
3617 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && !mCachePump && !mTransactionPump) {
3618 // We have to manually notify the listener because there is not any pump
3619 // that would call our OnStart/StopRequest after resume from waiting for
3620 // the redirect callback.
3621 DoNotifyListener();
3622 }
3623
3624 return rv;
3625}
3626
3627nsresult nsHttpChannel::OpenRedirectChannel(nsresult rv) {
3628 AutoRedirectVetoNotifier notifier(this, rv);
3629
3630 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3631
3632 if (!mRedirectChannel) {
3633 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)
3634 "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)
;
3635 return NS_ERROR_FAILURE;
3636 }
3637
3638 // Make sure to do this after we received redirect veto answer,
3639 // i.e. after all sinks had been notified
3640 mRedirectChannel->SetOriginalURI(mOriginalURI);
3641
3642 // open new channel
3643 rv = mRedirectChannel->AsyncOpen(mListener);
3644
3645 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"
, 3645); return rv; } } while (false)
;
3646
3647 mStatus = NS_BINDING_REDIRECTED;
3648
3649 notifier.RedirectSucceeded();
3650
3651 ReleaseListeners();
3652
3653 return NS_OK;
3654}
3655
3656nsresult nsHttpChannel::AsyncDoReplaceWithProxy(nsIProxyInfo* pi) {
3657 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)
;
3658 nsresult rv;
3659
3660 nsCOMPtr<nsIChannel> newChannel;
3661 rv = gHttpHandler->NewProxiedChannel(mURI, pi, mProxyResolveFlags, mProxyURI,
3662 mLoadInfo, getter_AddRefs(newChannel));
3663 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3664
3665 uint32_t flags = nsIChannelEventSink::REDIRECT_INTERNAL;
3666
3667 rv = SetupReplacementChannel(mURI, newChannel, true, flags);
3668 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3669
3670 // Inform consumers about this fake redirect
3671 mRedirectChannel = newChannel;
3672
3673 PushRedirectAsyncFunc(&nsHttpChannel::OpenRedirectChannel);
3674 rv = gHttpHandler->AsyncOnChannelRedirect(this, newChannel, flags);
3675
3676 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = WaitForRedirectCallback();
3677
3678 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3679 AutoRedirectVetoNotifier notifier(this, rv);
3680 PopRedirectAsyncFunc(&nsHttpChannel::OpenRedirectChannel);
3681 }
3682
3683 return rv;
3684}
3685
3686nsresult nsHttpChannel::ResolveProxy() {
3687 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)
;
3688
3689 nsresult rv;
3690
3691 nsCOMPtr<nsIProtocolProxyService> pps;
3692 pps = mozilla::components::ProtocolProxy::Service(&rv);
3693 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3694
3695 // using the nsIProtocolProxyService2 allows a minor performance
3696 // optimization, but if an add-on has only provided the original interface
3697 // then it is ok to use that version.
3698 nsCOMPtr<nsIProtocolProxyService2> pps2 = do_QueryInterface(pps);
3699 if (pps2) {
3700 rv = pps2->AsyncResolve2(this, mProxyResolveFlags, this, nullptr,
3701 getter_AddRefs(mProxyRequest));
3702 } else {
3703 rv = pps->AsyncResolve(static_cast<nsIChannel*>(this), mProxyResolveFlags,
3704 this, nullptr, getter_AddRefs(mProxyRequest));
3705 }
3706
3707 return rv;
3708}
3709
3710bool nsHttpChannel::ResponseWouldVary(nsICacheEntry* entry) {
3711 nsresult rv;
3712 nsAutoCString buf, metaKey;
3713 Unused << mCachedResponseHead->GetHeader(nsHttp::Vary, buf);
3714
3715 constexpr auto prefix = "request-"_ns;
3716
3717 // enumerate the elements of the Vary header...
3718 for (const nsACString& token :
3719 nsCCharSeparatedTokenizer(buf, NS_HTTP_HEADER_SEP',').ToRange()) {
3720 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)
3721 ("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)
3722 "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)
3723 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)
;
3724 //
3725 // if "*", then assume response would vary. technically speaking,
3726 // "Vary: header, *" is not permitted, but we allow it anyways.
3727 //
3728 // We hash values of cookie-headers for the following reasons:
3729 //
3730 // 1- cookies can be very large in size
3731 //
3732 // 2- cookies may contain sensitive information. (for parity with
3733 // out policy of not storing Set-cookie headers in the cache
3734 // meta data, we likewise do not want to store cookie headers
3735 // here.)
3736 //
3737 if (token.EqualsLiteral("*")) {
3738 return true; // if we encounter this, just get out of here
3739 }
3740
3741 // build cache meta data key...
3742 metaKey = prefix + token;
3743
3744 // check the last value of the given request header to see if it has
3745 // since changed. if so, then indeed the cached response is invalid.
3746 nsCString lastVal;
3747 entry->GetMetaDataElement(metaKey.get(), getter_Copies(lastVal));
3748 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)
3749 ("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)
3750 "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)
3751 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)
;
3752
3753 // Look for value of "Cookie" in the request headers
3754 nsHttpAtom atom = nsHttp::ResolveAtom(token);
3755 nsAutoCString newVal;
3756 bool hasHeader = NS_SUCCEEDED(mRequestHead.GetHeader(atom, newVal))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mRequestHead.GetHeader
(atom, newVal))), 1)))
;
3757 if (!lastVal.IsEmpty()) {
3758 // value for this header in cache, but no value in request
3759 if (!hasHeader) {
3760 return true; // yes - response would vary
3761 }
3762
3763 // If this is a cookie-header, stored metadata is not
3764 // the value itself but the hash. So we also hash the
3765 // outgoing value here in order to compare the hashes
3766 nsAutoCString hash;
3767 if (atom == nsHttp::Cookie) {
3768 rv = Hash(newVal.get(), hash);
3769 // If hash failed, be conservative (the cached hash
3770 // exists at this point) and claim response would vary
3771 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return true;
3772 newVal = hash;
3773
3774 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)
3775 ("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)
3776 "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)
3777 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)
;
3778 }
3779
3780 if (!newVal.Equals(lastVal)) {
3781 return true; // yes, response would vary
3782 }
3783
3784 } else if (hasHeader) { // old value is empty, but newVal is set
3785 return true;
3786 }
3787 }
3788
3789 return false;
3790}
3791
3792// We need to have an implementation of this function just so that we can keep
3793// all references to mCallOnResume of type nsHttpChannel: it's not OK in C++
3794// to set a member function ptr to a base class function.
3795void nsHttpChannel::HandleAsyncAbort() {
3796 HttpAsyncAborter<nsHttpChannel>::HandleAsyncAbort();
3797}
3798
3799//-----------------------------------------------------------------------------
3800// nsHttpChannel <byte-range>
3801//-----------------------------------------------------------------------------
3802
3803bool nsHttpChannel::IsResumable(int64_t partialLen, int64_t contentLength,
3804 bool ignoreMissingPartialLen) const {
3805 bool hasContentEncoding =
3806 mCachedResponseHead->HasHeader(nsHttp::Content_Encoding);
3807
3808 nsAutoCString etag;
3809 Unused << mCachedResponseHead->GetHeader(nsHttp::ETag, etag);
3810 bool hasWeakEtag = !etag.IsEmpty() && StringBeginsWith(etag, "W/"_ns);
3811
3812 return (partialLen < contentLength) &&
3813 (partialLen > 0 || ignoreMissingPartialLen) && !hasContentEncoding &&
3814 !hasWeakEtag && mCachedResponseHead->IsResumable() &&
3815 !LoadCustomConditionalRequest() && !mCachedResponseHead->NoStore();
3816}
3817
3818nsresult nsHttpChannel::MaybeSetupByteRangeRequest(
3819 int64_t partialLen, int64_t contentLength, bool ignoreMissingPartialLen) {
3820 // Be pesimistic
3821 StoreIsPartialRequest(false);
3822
3823 if (!IsResumable(partialLen, contentLength, ignoreMissingPartialLen)) {
3824 return NS_ERROR_NOT_RESUMABLE;
3825 }
3826
3827 // looks like a partial entry we can reuse; add If-Range
3828 // and Range headers.
3829 nsresult rv = SetupByteRangeRequest(partialLen);
3830 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3831 // Make the request unconditional again.
3832 UntieByteRangeRequest();
3833 }
3834
3835 return rv;
3836}
3837
3838nsresult nsHttpChannel::SetupByteRangeRequest(int64_t partialLen) {
3839 // cached content has been found to be partial, add necessary request
3840 // headers to complete cache entry.
3841
3842 // use strongest validator available...
3843 nsAutoCString val;
3844 Unused << mCachedResponseHead->GetHeader(nsHttp::ETag, val);
3845 if (val.IsEmpty()) {
3846 Unused << mCachedResponseHead->GetHeader(nsHttp::Last_Modified, val);
3847 }
3848 if (val.IsEmpty()) {
3849 // if we hit this code it means mCachedResponseHead->IsResumable() is
3850 // either broken or not being called.
3851 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"
, 3851); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "no cache validator" ")"); do { *
((volatile int*)__null) = 3851; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
3852 StoreIsPartialRequest(false);
3853 return NS_ERROR_FAILURE;
3854 }
3855
3856 char buf[64];
3857 SprintfLiteral(buf, "bytes=%" PRId64"l" "d" "-", partialLen);
3858
3859 DebugOnly<nsresult> rv{};
3860 rv = mRequestHead.SetHeader(nsHttp::Range, nsDependentCString(buf));
3861 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"
, 3861); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3861; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3862 rv = mRequestHead.SetHeader(nsHttp::If_Range, val);
3863 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"
, 3863); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3863; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3864 StoreIsPartialRequest(true);
3865
3866 return NS_OK;
3867}
3868
3869void nsHttpChannel::UntieByteRangeRequest() {
3870 DebugOnly<nsresult> rv{};
3871 rv = mRequestHead.ClearHeader(nsHttp::Range);
3872 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"
, 3872); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3872; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3873 rv = mRequestHead.ClearHeader(nsHttp::If_Range);
3874 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"
, 3874); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 3874; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3875}
3876
3877nsresult nsHttpChannel::ProcessPartialContent(
3878 const std::function<nsresult(nsHttpChannel*, nsresult)>&
3879 aContinueProcessResponseFunc) {
3880 // ok, we've just received a 206
3881 //
3882 // we need to stream whatever data is in the cache out first, and then
3883 // pick up whatever data is on the wire, writing it into the cache.
3884
3885 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)
;
3886
3887 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"
, 3887); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
3888 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"
, 3888); return NS_ERROR_NOT_INITIALIZED; } } while (false)
;
3889
3890 // Check if the content-encoding we now got is different from the one we
3891 // got before
3892 nsAutoCString contentEncoding, cachedContentEncoding;
3893 // It is possible that there is not such headers
3894 Unused << mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
3895 Unused << mCachedResponseHead->GetHeader(nsHttp::Content_Encoding,
3896 cachedContentEncoding);
3897 if (nsCRT::strcasecmp(contentEncoding.get(), cachedContentEncoding.get()) !=
3898 0) {
3899 Cancel(NS_ERROR_INVALID_CONTENT_ENCODING);
3900 return CallOnStartRequest();
3901 }
3902
3903 nsresult rv;
3904
3905 int64_t cachedContentLength = mCachedResponseHead->ContentLength();
3906 int64_t entitySize = mResponseHead->TotalEntitySize();
3907
3908 nsAutoCString contentRange;
3909 Unused << mResponseHead->GetHeader(nsHttp::Content_Range, contentRange);
3910 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)
3911 ("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)
3912 "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)
3913 ", 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)
3914 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)
3915 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)
;
3916
3917 if ((entitySize >= 0) && (cachedContentLength >= 0) &&
3918 (entitySize != cachedContentLength)) {
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
, "nsHttpChannel::ProcessPartialContent [this=%p] " "206 has different total entity size than the content length "
"of the original partially cached entity.\n", this); } } while
(0)
3920 ("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)
3921 "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)
3922 "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)
3923 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)
;
3924
3925 mCacheEntry->AsyncDoom(nullptr);
3926 Cancel(NS_ERROR_CORRUPTED_CONTENT);
3927 return CallOnStartRequest();
3928 }
3929
3930 if (LoadConcurrentCacheAccess()) {
3931 // We started to read cached data sooner than its write has been done.
3932 // But the concurrent write has not finished completely, so we had to
3933 // do a range request. Now let the content coming from the network
3934 // be presented to consumers and also stored to the cache entry.
3935
3936 rv = InstallCacheListener(mLogicalOffset);
3937 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3938 } else {
3939 // suspend the current transaction
3940 rv = mTransactionPump->Suspend();
3941 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3942 }
3943
3944 // merge any new headers with the cached response headers
3945 mCachedResponseHead->UpdateHeaders(mResponseHead.get());
3946
3947 // update the cached response head
3948 nsAutoCString head;
3949 mCachedResponseHead->Flatten(head, true);
3950 rv = mCacheEntry->SetMetaDataElement("response-head", head.get());
3951 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3952
3953 // make the cached response be the current response
3954 mResponseHead = std::move(mCachedResponseHead);
3955
3956 UpdateInhibitPersistentCachingFlag();
3957
3958 rv = UpdateExpirationTime();
3959 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3960
3961 // notify observers interested in looking at a response that has been
3962 // merged with any cached headers (http-on-examine-merged-response).
3963 gHttpHandler->OnExamineMergedResponse(this);
3964
3965 if (LoadConcurrentCacheAccess()) {
3966 StoreCachedContentIsPartial(false);
3967 // Leave the ConcurrentCacheAccess flag set, we want to use it
3968 // to prevent duplicate OnStartRequest call on the target listener
3969 // in case this channel is canceled before it gets its OnStartRequest
3970 // from the http transaction.
3971 return rv;
3972 }
3973
3974 // Now we continue reading the network response.
3975 // the cached content is valid, although incomplete.
3976 StoreCachedContentIsValid(CachedContentValidity::Valid);
3977 return CallOrWaitForResume([aContinueProcessResponseFunc](auto* self) {
3978 nsresult rv = self->ReadFromCache();
3979 return aContinueProcessResponseFunc(self, rv);
3980 });
3981}
3982
3983nsresult nsHttpChannel::OnDoneReadingPartialCacheEntry(bool* streamDone) {
3984 nsresult rv;
3985
3986 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)
;
3987
3988 // by default, assume we would have streamed all data or failed...
3989 *streamDone = true;
3990
3991 // setup cache listener to append to cache entry
3992 int64_t size;
3993 rv = mCacheEntry->GetDataSize(&size);
3994 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3995
3996 rv = InstallCacheListener(size);
3997 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
3998
3999 // Entry is valid, do it now, after the output stream has been opened,
4000 // otherwise when done earlier, pending readers would consider the cache
4001 // entry still as partial (CacheEntry::GetDataSize would return the partial
4002 // data size) and consumers would do the conditional request again.
4003 rv = mCacheEntry->SetValid();
4004 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
4005
4006 // need to track the logical offset of the data being sent to our listener
4007 mLogicalOffset = size;
4008
4009 // we're now completing the cached content, so we can clear this flag.
4010 // this puts us in the state of a regular download.
4011 StoreCachedContentIsPartial(false);
4012 // The cache input stream pump is finished, we do not need it any more.
4013 // (see bug 1313923)
4014 mCachePump = nullptr;
4015
4016 // resume the transaction if it exists, otherwise the pipe contained the
4017 // remaining part of the document and we've now streamed all of the data.
4018 if (mTransactionPump) {
4019 rv = mTransactionPump->Resume();
4020 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) *streamDone = false;
4021 } else {
4022 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"
, 4022); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "no transaction" ")"); do { *((volatile
int*)__null) = 4022; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
4023 }
4024 return rv;
4025}
4026
4027//-----------------------------------------------------------------------------
4028// nsHttpChannel <cache>
4029//-----------------------------------------------------------------------------
4030
4031bool nsHttpChannel::ShouldBypassProcessNotModified() {
4032 if (LoadCustomConditionalRequest()) {
4033 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)
;
4034 return true;
4035 }
4036
4037 if (!mDidReval) {
4038 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)
4039 ("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)
4040 "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)
;
4041 return true;
4042 }
4043
4044 return false;
4045}
4046
4047nsresult nsHttpChannel::ProcessNotModified(
4048 const std::function<nsresult(nsHttpChannel*, nsresult)>&
4049 aContinueProcessResponseFunc) {
4050 nsresult rv;
4051
4052 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)
;
4053
4054 // Assert ShouldBypassProcessNotModified() has been checked before call to
4055 // ProcessNotModified().
4056 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"
, 4056); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!ShouldBypassProcessNotModified()"
")"); do { *((volatile int*)__null) = 4056; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4057
4058 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"
, 4058); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCachedResponseHead"
")"); do { *((volatile int*)__null) = 4058; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4059 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"
, 4059); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCacheEntry"
")"); do { *((volatile int*)__null) = 4059; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4060 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"
, 4060); return NS_ERROR_UNEXPECTED; } } while (false)
;
4061
4062 // If the 304 response contains a Last-Modified different than the
4063 // one in our cache that is pretty suspicious and is, in at least the
4064 // case of bug 716840, a sign of the server having previously corrupted
4065 // our cache with a bad response. Take the minor step here of just dooming
4066 // that cache entry so there is a fighting chance of getting things on the
4067 // right track.
4068
4069 nsAutoCString lastModifiedCached;
4070 nsAutoCString lastModified304;
4071
4072 rv =
4073 mCachedResponseHead->GetHeader(nsHttp::Last_Modified, lastModifiedCached);
4074 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4075 rv = mResponseHead->GetHeader(nsHttp::Last_Modified, lastModified304);
4076 }
4077
4078 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !lastModified304.Equals(lastModifiedCached)) {
4079 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)
4080 ("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)
4081 "[%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)
4082 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)
;
4083
4084 mCacheEntry->AsyncDoom(nullptr);
4085 Telemetry::Accumulate(Telemetry::CACHE_LM_INCONSISTENT, true);
4086 }
4087
4088 // merge any new headers with the cached response headers
4089 mCachedResponseHead->UpdateHeaders(mResponseHead.get());
4090
4091 // update the cached response head
4092 nsAutoCString head;
4093 mCachedResponseHead->Flatten(head, true);
4094 rv = mCacheEntry->SetMetaDataElement("response-head", head.get());
4095 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
4096
4097 if (StaticPrefs::network_http_network_error_logging_enabled() &&
4098 LoadUsedNetwork() && !mReportedNEL) {
4099 if (nsCOMPtr<nsINetworkErrorLogging> nel =
4100 components::NetworkErrorLogging::Service()) {
4101 nel->GenerateNELReport(this);
4102 }
4103 mReportedNEL = true;
4104 }
4105
4106 // make the cached response be the current response
4107 mResponseHead = std::move(mCachedResponseHead);
4108
4109 UpdateInhibitPersistentCachingFlag();
4110
4111 rv = UpdateExpirationTime();
4112 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
4113
4114 rv = AddCacheEntryHeaders(mCacheEntry);
4115 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
4116
4117 // notify observers interested in looking at a reponse that has been
4118 // merged with any cached headers
4119 gHttpHandler->OnExamineMergedResponse(this);
4120
4121 StoreCachedContentIsValid(CachedContentValidity::Valid);
4122
4123 // Tell other consumers the entry is OK to use
4124 rv = mCacheEntry->SetValid();
4125 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
4126
4127 return CallOrWaitForResume([aContinueProcessResponseFunc](auto* self) {
4128 nsresult rv = self->ReadFromCache();
4129 return aContinueProcessResponseFunc(self, rv);
4130 });
4131}
4132
4133// Determines if a request is a byte range request for a subrange,
4134// i.e. is a byte range request, but not a 0- byte range request.
4135static bool IsSubRangeRequest(nsHttpRequestHead& aRequestHead) {
4136 nsAutoCString byteRange;
4137 if (NS_FAILED(aRequestHead.GetHeader(nsHttp::Range, byteRange))((bool)(__builtin_expect(!!(NS_FAILED_impl(aRequestHead.GetHeader
(nsHttp::Range, byteRange))), 0)))
) {
4138 return false;
4139 }
4140
4141 if (byteRange.EqualsLiteral("bytes=0-")) {
4142#ifndef ANDROID
4143 glean::network::byte_range_request.Get("cacheable"_ns).Add(1);
4144#endif
4145 return false;
4146 }
4147#ifndef ANDROID
4148 glean::network::byte_range_request.Get("not_cacheable"_ns).Add(1);
4149#endif
4150 return true;
4151}
4152
4153nsresult nsHttpChannel::OpenCacheEntry(bool isHttps) {
4154 // Drop this flag here
4155 StoreConcurrentCacheAccess(0);
4156
4157 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)
;
4158
4159 // make sure we're not abusing this function
4160 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"
, 4160); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCacheEntry"
") (" "cache entry already open" ")"); do { *((volatile int*
)__null) = 4160; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
4161 if (!mRequestHead.IsGet() && !mRequestHead.IsHead() &&
4162 !mRequestHead.IsPost() && !mRequestHead.IsPatch()) {
4163 // don't use the cache for other types of requests
4164 return NS_OK;
4165 }
4166
4167 MOZ_ASSERT_IF(mRequestHead.IsPost() || mRequestHead.IsPatch(), mPostID > 0)do { if (mRequestHead.IsPost() || mRequestHead.IsPatch()) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(mPostID > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mPostID > 0))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mPostID > 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 4167); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mPostID > 0"
")"); do { *((volatile int*)__null) = 4167; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
4168
4169 return OpenCacheEntryInternal(isHttps);
4170}
4171
4172nsresult nsHttpChannel::OpenCacheEntryInternal(bool isHttps) {
4173 nsresult rv;
4174
4175 if (LoadResuming()) {
4176 // We don't support caching for requests initiated
4177 // via nsIResumableChannel.
4178 return NS_OK;
4179 }
4180
4181 // Don't cache byte range requests which are subranges, only cache 0-
4182 // byte range requests.
4183 if (IsSubRangeRequest(mRequestHead)) {
4184 return NS_OK;
4185 }
4186
4187 // Handle correctly WaitForCacheEntry
4188 AutoCacheWaitFlags waitFlags(this);
4189
4190 nsAutoCString cacheKey;
4191
4192 nsCOMPtr<nsICacheStorageService> cacheStorageService(
4193 components::CacheStorage::Service());
4194 if (!cacheStorageService) {
4195 return NS_ERROR_NOT_AVAILABLE;
4196 }
4197
4198 nsCOMPtr<nsICacheStorage> cacheStorage;
4199 mCacheEntryURI = mURI;
4200
4201 RefPtr<LoadContextInfo> info = GetLoadContextInfo(this);
4202 if (!info) {
4203 return NS_ERROR_FAILURE;
4204 }
4205
4206 uint32_t cacheEntryOpenFlags;
4207 bool offline = gIOService->IsOffline();
4208
4209 RefPtr<mozilla::dom::BrowsingContext> bc;
4210 mLoadInfo->GetBrowsingContext(getter_AddRefs(bc));
4211
4212 bool maybeRCWN = false;
4213
4214 nsAutoCString cacheControlRequestHeader;
4215 Unused << mRequestHead.GetHeader(nsHttp::Cache_Control,
4216 cacheControlRequestHeader);
4217 CacheControlParser cacheControlRequest(cacheControlRequestHeader);
4218 if (cacheControlRequest.NoStore()) {
4219 return NS_OK;
4220 }
4221
4222 bool forceOffline = bc && bc->Top()->GetForceOffline();
4223 if (offline || (mLoadFlags & INHIBIT_CACHING) || forceOffline) {
4224 if (BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass())((mLoadFlags) & (nsIRequest::LOAD_BYPASS_CACHE | nsICachingChannel
::LOAD_BYPASS_LOCAL_CACHE) && !(((mLoadFlags) & nsIRequest
::LOAD_FROM_CACHE) && (LoadPreferCacheLoadOverBypass(
))))
&&
4225 !offline && !forceOffline) {
4226 return NS_OK;
4227 }
4228 cacheEntryOpenFlags = nsICacheStorage::OPEN_READONLY;
4229 StoreCacheEntryIsReadOnly(true);
4230 } else if (BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass())((mLoadFlags) & (nsIRequest::LOAD_BYPASS_CACHE | nsICachingChannel
::LOAD_BYPASS_LOCAL_CACHE) && !(((mLoadFlags) & nsIRequest
::LOAD_FROM_CACHE) && (LoadPreferCacheLoadOverBypass(
))))
) {
4231 cacheEntryOpenFlags = nsICacheStorage::OPEN_TRUNCATE;
4232 } else {
4233 cacheEntryOpenFlags =
4234 nsICacheStorage::OPEN_NORMALLY | nsICacheStorage::CHECK_MULTITHREADED;
4235 }
4236
4237 // Remember the request is a custom conditional request so that we can
4238 // process any 304 response correctly.
4239 StoreCustomConditionalRequest(
4240 mRequestHead.HasHeader(nsHttp::If_Modified_Since) ||
4241 mRequestHead.HasHeader(nsHttp::If_None_Match) ||
4242 mRequestHead.HasHeader(nsHttp::If_Unmodified_Since) ||
4243 mRequestHead.HasHeader(nsHttp::If_Match) ||
4244 mRequestHead.HasHeader(nsHttp::If_Range));
4245
4246 if (mLoadFlags & INHIBIT_PERSISTENT_CACHING) {
4247 rv = cacheStorageService->MemoryCacheStorage(
4248 info, // ? choose app cache as well...
4249 getter_AddRefs(cacheStorage));
4250 } else if (LoadPinCacheContent()) {
4251 rv = cacheStorageService->PinningCacheStorage(info,
4252 getter_AddRefs(cacheStorage));
4253 } else {
4254 // Try to race only if we use disk cache storage
4255 maybeRCWN = mRequestHead.IsSafeMethod();
4256 rv = cacheStorageService->DiskCacheStorage(info,
4257 getter_AddRefs(cacheStorage));
4258 }
4259 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"
, 4259); return rv; } } while (false)
;
4260
4261 if ((mClassOfService.Flags() & nsIClassOfService::Leader) ||
4262 (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI)) {
4263 cacheEntryOpenFlags |= nsICacheStorage::OPEN_PRIORITY;
4264 }
4265
4266 // Only for backward compatibility with the old cache back end.
4267 // When removed, remove the flags and related code snippets.
4268 if (mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY) {
4269 cacheEntryOpenFlags |= nsICacheStorage::OPEN_BYPASS_IF_BUSY;
4270 }
4271
4272 if (mPostID) {
4273 mCacheIdExtension.Append(nsPrintfCString("%d", mPostID));
4274 }
4275 if (LoadIsTRRServiceChannel()) {
4276 mCacheIdExtension.Append("TRR");
4277 }
4278 if (mRequestHead.IsHead()) {
4279 mCacheIdExtension.Append("HEAD");
4280 }
4281 bool isThirdParty = false;
4282 if (StaticPrefs::network_fetch_cache_partition_cross_origin() &&
4283 (NS_FAILED(mLoadInfo->TriggeringPrincipal()->IsThirdPartyChannel(((bool)(__builtin_expect(!!(NS_FAILED_impl(mLoadInfo->TriggeringPrincipal
()->IsThirdPartyChannel( this, &isThirdParty))), 0)))
4284 this, &isThirdParty))((bool)(__builtin_expect(!!(NS_FAILED_impl(mLoadInfo->TriggeringPrincipal
()->IsThirdPartyChannel( this, &isThirdParty))), 0)))
||
4285 isThirdParty) &&
4286 (mLoadInfo->InternalContentPolicyType() == nsIContentPolicy::TYPE_FETCH ||
4287 mLoadInfo->InternalContentPolicyType() ==
4288 nsIContentPolicy::TYPE_XMLHTTPREQUEST ||
4289 mLoadInfo->InternalContentPolicyType() ==
4290 nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST_ASYNC ||
4291 mLoadInfo->InternalContentPolicyType() ==
4292 nsIContentPolicy::TYPE_INTERNAL_XMLHTTPREQUEST_SYNC)) {
4293 mCacheIdExtension.Append("FETCH");
4294 }
4295
4296 mCacheOpenWithPriority = cacheEntryOpenFlags & nsICacheStorage::OPEN_PRIORITY;
4297 mCacheQueueSizeWhenOpen =
4298 CacheStorageService::CacheQueueSize(mCacheOpenWithPriority);
4299
4300 if ((mNetworkTriggerDelay || StaticPrefs::network_http_rcwn_enabled()) &&
4301 maybeRCWN && mAllowRCWN) {
4302 bool hasAltData = false;
4303 uint32_t sizeInKb = 0;
4304 rv = cacheStorage->GetCacheIndexEntryAttrs(
4305 mCacheEntryURI, mCacheIdExtension, &hasAltData, &sizeInKb);
4306
4307 // We will attempt to race the network vs the cache if we've found
4308 // this entry in the cache index, and it has appropriate attributes
4309 // (doesn't have alt-data, and has a small size)
4310 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !hasAltData &&
4311 sizeInKb < StaticPrefs::network_http_rcwn_small_resource_size_kb()) {
4312 MaybeRaceCacheWithNetwork();
4313 }
4314 }
4315
4316 if (!mCacheOpenDelay) {
4317 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"
, 4317); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should be called on the main thread" ")"); do { *((volatile
int*)__null) = 4317; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
4318 if (mNetworkTriggered) {
4319 mRaceCacheWithNetwork = StaticPrefs::network_http_rcwn_enabled();
4320 }
4321 rv = cacheStorage->AsyncOpenURI(mCacheEntryURI, mCacheIdExtension,
4322 cacheEntryOpenFlags, this);
4323 } else {
4324 // We pass `this` explicitly as a parameter due to the raw pointer
4325 // to refcounted object in lambda analysis.
4326 mCacheOpenFunc = [cacheEntryOpenFlags,
4327 cacheStorage](nsHttpChannel* self) -> void {
4328 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"
, 4328); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should be called on the main thread" ")"); do { *((volatile
int*)__null) = 4328; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
4329 cacheStorage->AsyncOpenURI(self->mCacheEntryURI, self->mCacheIdExtension,
4330 cacheEntryOpenFlags, self);
4331 };
4332
4333 // calls nsHttpChannel::Notify after `mCacheOpenDelay` milliseconds
4334 auto callback = MakeRefPtr<TimerCallback>(this);
4335 NS_NewTimerWithCallback(getter_AddRefs(mCacheOpenTimer), callback,
4336 mCacheOpenDelay, nsITimer::TYPE_ONE_SHOT);
4337 }
4338 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"
, 4338); return rv; } } while (false)
;
4339
4340 waitFlags.Keep(WAIT_FOR_CACHE_ENTRY);
4341
4342 return NS_OK;
4343}
4344
4345nsresult nsHttpChannel::CheckPartial(nsICacheEntry* aEntry, int64_t* aSize,
4346 int64_t* aContentLength) {
4347 return nsHttp::CheckPartial(
4348 aEntry, aSize, aContentLength,
4349 mCachedResponseHead ? mCachedResponseHead.get() : mResponseHead.get());
4350}
4351
4352void nsHttpChannel::UntieValidationRequest() {
4353 DebugOnly<nsresult> rv{};
4354 // Make the request unconditional again.
4355 rv = mRequestHead.ClearHeader(nsHttp::If_Modified_Since);
4356 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"
, 4356); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4356; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4357 rv = mRequestHead.ClearHeader(nsHttp::If_None_Match);
4358 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"
, 4358); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4358; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4359 rv = mRequestHead.ClearHeader(nsHttp::ETag);
4360 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"
, 4360); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4360; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4361}
4362
4363NS_IMETHODIMPnsresult
4364nsHttpChannel::OnCacheEntryCheck(nsICacheEntry* entry, uint32_t* aResult) {
4365 nsresult rv = NS_OK;
4366
4367 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)
4368 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)
;
4369
4370 mozilla::MutexAutoLock lock(mRCWNLock);
4371
4372 if (mRaceCacheWithNetwork && mFirstResponseSource == RESPONSE_FROM_NETWORK) {
4373 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 %p", this); } } while (0)
4374 ("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 %p", this); } } while (0)
4375 "network %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
, "Not using cached response because we've already got one from the "
"network %p", this); } } while (0)
4376 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
, "Not using cached response because we've already got one from the "
"network %p", this); } } while (0)
;
4377 *aResult = ENTRY_NOT_WANTED;
4378
4379 // Net-win indicates that mOnStartRequestTimestamp is from net.
4380 int64_t savedTime =
4381 (TimeStamp::Now() - mOnStartRequestTimestamp).ToMilliseconds();
4382 Telemetry::Accumulate(Telemetry::NETWORK_RACE_CACHE_WITH_NETWORK_SAVED_TIME,
4383 savedTime);
4384 PROFILER_MARKER_TEXT(do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won by %" "l"
"d" "ms", savedTime)); } } while (false); } while (false)
4385 "RCWN", NETWORK, {},do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won by %" "l"
"d" "ms", savedTime)); } } while (false); } while (false)
4386 nsPrintfCString("Network won by %" PRId64 "ms", savedTime))do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won by %" "l"
"d" "ms", savedTime)); } } while (false); } while (false)
;
4387 return NS_OK;
4388 }
4389 if (mRaceCacheWithNetwork && mFirstResponseSource == RESPONSE_PENDING) {
4390 mOnCacheEntryCheckTimestamp = TimeStamp::Now();
4391 }
4392
4393 nsAutoCString cacheControlRequestHeader;
4394 Unused << mRequestHead.GetHeader(nsHttp::Cache_Control,
4395 cacheControlRequestHeader);
4396 CacheControlParser cacheControlRequest(cacheControlRequestHeader);
4397
4398 if (cacheControlRequest.NoStore()) {
4399 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)
4400 ("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)
4401 "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)
;
4402 *aResult = ENTRY_NOT_WANTED;
4403 return NS_OK;
4404 }
4405
4406 // Be pessimistic: assume the cache entry has no useful data.
4407 *aResult = ENTRY_WANTED;
4408 StoreCachedContentIsValid(CachedContentValidity::Invalid);
4409
4410 nsCString buf;
4411
4412 // Get the method that was used to generate the cached response
4413 rv = entry->GetMetaDataElement("request-method", getter_Copies(buf));
4414 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"
, 4414); return rv; } } while (false)
;
4415
4416 bool methodWasHead = buf.EqualsLiteral("HEAD");
4417 bool methodWasGet = buf.EqualsLiteral("GET");
4418
4419 if (methodWasHead) {
4420 // The cached response does not contain an entity. We can only reuse
4421 // the response if the current request is also HEAD.
4422 if (!mRequestHead.IsHead()) {
4423 *aResult = ENTRY_NOT_WANTED;
4424 return NS_OK;
4425 }
4426 }
4427 buf.Adopt(nullptr);
4428
4429 // We'll need this value in later computations...
4430 uint32_t lastModifiedTime;
4431 rv = entry->GetLastModified(&lastModifiedTime);
4432 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"
, 4432); return rv; } } while (false)
;
4433
4434 // Determine if this is the first time that this cache entry
4435 // has been accessed during this session.
4436 bool fromPreviousSession =
4437 (gHttpHandler->SessionStartTime() > lastModifiedTime);
4438
4439 // Get the cached HTTP response headers
4440 mCachedResponseHead = MakeUnique<nsHttpResponseHead>();
4441
4442 rv = nsHttp::GetHttpResponseHeadFromCacheEntry(entry,
4443 mCachedResponseHead.get());
4444 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"
, 4444); return rv; } } while (false)
;
4445
4446 bool isCachedRedirect = WillRedirect(*mCachedResponseHead);
4447
4448 // Do not return 304 responses from the cache, and also do not return
4449 // any other non-redirect 3xx responses from the cache (see bug 759043).
4450 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"
, 4451); return NS_ERROR_ABORT; } } while (false)
4451 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"
, 4451); return NS_ERROR_ABORT; } } while (false)
;
4452
4453 if (mCachedResponseHead->NoStore() && LoadCacheEntryIsReadOnly()) {
4454 // This prevents loading no-store responses when navigating back
4455 // while the browser is set to work offline.
4456 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)
;
4457 mLoadFlags |= nsIRequest::INHIBIT_CACHING;
4458 }
4459
4460 // Don't bother to validate items that are read-only,
4461 // unless they are read-only because of INHIBIT_CACHING
4462 if ((LoadCacheEntryIsReadOnly() &&
4463 !(mLoadFlags & nsIRequest::INHIBIT_CACHING))) {
4464 int64_t size, contentLength;
4465 rv = CheckPartial(entry, &size, &contentLength);
4466 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"
, 4466); return rv; } } while (false)
;
4467
4468 if (contentLength != int64_t(-1) && contentLength != size) {
4469 *aResult = ENTRY_NOT_WANTED;
4470 return NS_OK;
4471 }
4472
4473 rv = OpenCacheInputStream(entry, true);
4474 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4475 StoreCachedContentIsValid(CachedContentValidity::Valid);
4476 }
4477 return rv;
4478 }
4479
4480 bool wantCompleteEntry = false;
4481
4482 if (!methodWasHead && !isCachedRedirect) {
4483 // If the cached content-length is set and it does not match the data
4484 // size of the cached content, then the cached response is partial...
4485 // either we need to issue a byte range request or we need to refetch
4486 // the entire document.
4487 //
4488 // We exclude redirects from this check because we (usually) strip the
4489 // entity when we store the cache entry, and even if we didn't, we
4490 // always ignore a cached redirect's entity anyway. See bug 759043.
4491 int64_t size, contentLength;
4492 rv = CheckPartial(entry, &size, &contentLength);
4493 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"
, 4493); return rv; } } while (false)
;
4494
4495 if (size == int64_t(-1)) {
4496 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)
;
4497 if (mLoadFlags & LOAD_BYPASS_LOCAL_CACHE_IF_BUSY) {
4498 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)
4499 (" 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)
4500 "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)
;
4501
4502 *aResult = ENTRY_NOT_WANTED;
4503 return NS_OK;
4504 }
4505
4506 // Ignore !(size > 0) from the resumability condition
4507 if (!IsResumable(size, contentLength, true)) {
4508 if (IsNavigation()) {
4509 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)
4510 (" 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)
4511 "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)
;
4512 *aResult = ENTRY_NOT_WANTED;
4513 return NS_OK;
4514 }
4515
4516 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)
4517 (" 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)
4518 "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)
;
4519
4520 wantCompleteEntry = true;
4521 } else {
4522 StoreConcurrentCacheAccess(1);
4523 }
4524 } else if (contentLength != int64_t(-1) && contentLength != size) {
4525 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)
4526 ("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)
4527 "[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)
4528 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)
;
4529
4530 rv = MaybeSetupByteRangeRequest(size, contentLength);
4531 StoreCachedContentIsPartial(NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && LoadIsPartialRequest());
4532 if (LoadCachedContentIsPartial()) {
4533 rv = OpenCacheInputStream(entry, false);
4534 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4535 UntieByteRangeRequest();
4536 return rv;
4537 }
4538
4539 *aResult = ENTRY_NEEDS_REVALIDATION;
4540 return NS_OK;
4541 }
4542
4543 if (size == 0 && LoadCacheOnlyMetadata()) {
4544 // Don't break cache entry load when the entry's data size
4545 // is 0 and CacheOnlyMetadata flag is set. In that case we
4546 // want to proceed since the LOAD_ONLY_IF_MODIFIED flag is
4547 // also set.
4548 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"
, 4548); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadFlags & LOAD_ONLY_IF_MODIFIED"
")"); do { *((volatile int*)__null) = 4548; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4549 } else {
4550 return rv;
4551 }
4552 }
4553 }
4554
4555 bool isHttps = mURI->SchemeIs("https");
4556
4557 bool doValidation = false;
4558 bool doBackgroundValidation = false;
4559 bool canAddImsHeader = true;
4560
4561 bool isForcedValid = false;
4562 entry->GetIsForcedValid(&isForcedValid);
4563 auto prefetchStatus = Telemetry::LABELS_PREDICTOR_PREFETCH_USE_STATUS::Used;
4564
4565 bool weaklyFramed, isImmutable;
4566 nsHttp::DetermineFramingAndImmutability(entry, mCachedResponseHead.get(),
4567 isHttps, &weaklyFramed, &isImmutable);
4568
4569 // Cached entry is not the entity we request (see bug #633743)
4570 if (ResponseWouldVary(entry)) {
4571 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)
;
4572 canAddImsHeader = false;
4573 doValidation = true;
4574 prefetchStatus = Telemetry::LABELS_PREDICTOR_PREFETCH_USE_STATUS::WouldVary;
4575 } else {
4576 if (mCachedResponseHead->ExpiresInPast() ||
4577 mCachedResponseHead->MustValidateIfExpired()) {
4578 prefetchStatus = Telemetry::LABELS_PREDICTOR_PREFETCH_USE_STATUS::Expired;
4579 }
4580 doValidation = nsHttp::ValidationRequired(
4581 isForcedValid, mCachedResponseHead.get(), mLoadFlags,
4582 LoadAllowStaleCacheContent(), LoadForceValidateCacheContent(),
4583 isImmutable, LoadCustomConditionalRequest(), mRequestHead, entry,
4584 cacheControlRequest, fromPreviousSession, &doBackgroundValidation);
4585 }
4586
4587 nsAutoCString requestedETag;
4588 if (!doValidation &&
4589 NS_SUCCEEDED(mRequestHead.GetHeader(nsHttp::If_Match, requestedETag))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mRequestHead.GetHeader
(nsHttp::If_Match, requestedETag))), 1)))
&&
4590 (methodWasGet || methodWasHead)) {
4591 nsAutoCString cachedETag;
4592 Unused << mCachedResponseHead->GetHeader(nsHttp::ETag, cachedETag);
4593 if (!cachedETag.IsEmpty() && (StringBeginsWith(cachedETag, "W/"_ns) ||
4594 !requestedETag.Equals(cachedETag))) {
4595 // User has defined If-Match header, if the cached entry is not
4596 // matching the provided header value or the cached ETag is weak,
4597 // force validation.
4598 doValidation = true;
4599 }
4600 }
4601
4602 // Previous error should not be propagated.
4603 rv = NS_OK;
4604
4605 if (!doValidation) {
4606 //
4607 // Check the authorization headers used to generate the cache entry.
4608 // We must validate the cache entry if:
4609 //
4610 // 1) the cache entry was generated prior to this session w/
4611 // credentials (see bug 103402).
4612 // 2) the cache entry was generated w/o credentials, but would now
4613 // require credentials (see bug 96705).
4614 //
4615 // NOTE: this does not apply to proxy authentication.
4616 //
4617 entry->GetMetaDataElement("auth", getter_Copies(buf));
4618 doValidation =
4619 (fromPreviousSession && !buf.IsEmpty()) ||
4620 (buf.IsEmpty() && mRequestHead.HasHeader(nsHttp::Authorization));
4621 if (doValidation) {
4622 prefetchStatus = Telemetry::LABELS_PREDICTOR_PREFETCH_USE_STATUS::Auth;
4623 }
4624 }
4625
4626 // Bug #561276: We maintain a chain of cache-keys which returns cached
4627 // 3xx-responses (redirects) in order to detect cycles. If a cycle is
4628 // found, ignore the cached response and hit the net. Otherwise, use
4629 // the cached response and add the cache-key to the chain. Note that
4630 // a limited number of redirects (cached or not) is allowed and is
4631 // enforced independently of this mechanism
4632 if (!doValidation && isCachedRedirect) {
4633 nsAutoCString cacheKey;
4634 rv = GenerateCacheKey(mPostID, cacheKey);
4635 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"
, 4635); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4635; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4636
4637 auto redirectedCachekeys = mRedirectedCachekeys.Lock();
4638 auto& ref = redirectedCachekeys.ref();
4639 if (!ref) {
4640 ref = MakeUnique<nsTArray<nsCString>>();
4641 } else if (ref->Contains(cacheKey)) {
4642 doValidation = true;
4643 }
4644
4645 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)
4646 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)
;
4647
4648 // Append cacheKey if not in the chain already
4649 if (!doValidation) {
4650 ref->AppendElement(cacheKey);
4651 } else {
4652 prefetchStatus =
4653 Telemetry::LABELS_PREDICTOR_PREFETCH_USE_STATUS::Redirect;
4654 }
4655 }
4656
4657 StoreCachedContentIsValid(!doValidation ? CachedContentValidity::Valid
4658 : CachedContentValidity::Invalid);
4659
4660 if (isForcedValid) {
4661 // Telemetry value is only useful if this was a prefetched item
4662 if (!doValidation) {
4663 // Could have gotten to a funky state with some of the if chain above
4664 // and in nsHttp::ValidationRequired. Make sure we get it right here.
4665 prefetchStatus = Telemetry::LABELS_PREDICTOR_PREFETCH_USE_STATUS::Used;
4666
4667 entry->MarkForcedValidUse();
4668 }
4669 Telemetry::AccumulateCategorical(prefetchStatus);
4670 }
4671
4672 if (doValidation) {
4673 //
4674 // now, we are definitely going to issue a HTTP request to the server.
4675 // make it conditional if possible.
4676 //
4677 // do not attempt to validate no-store content, since servers will not
4678 // expect it to be cached. (we only keep it in our cache for the
4679 // purposes of back/forward, etc.)
4680 //
4681 // the request method MUST be either GET or HEAD (see bug 175641) and
4682 // the cached response code must be < 400
4683 //
4684 // the cached content must not be weakly framed
4685 //
4686 // do not override conditional headers when consumer has defined its own
4687 if (!mCachedResponseHead->NoStore() &&
4688 (mRequestHead.IsGet() || mRequestHead.IsHead()) &&
4689 !LoadCustomConditionalRequest() && !weaklyFramed &&
4690 (mCachedResponseHead->Status() < 400)) {
4691 if (LoadConcurrentCacheAccess()) {
4692 // In case of concurrent read and also validation request we
4693 // must wait for the current writer to close the output stream
4694 // first. Otherwise, when the writer's job would have been interrupted
4695 // before all the data were downloaded, we'd have to do a range request
4696 // which would be a second request in line during this channel's
4697 // life-time. nsHttpChannel is not designed to do that, so rather
4698 // turn off concurrent read and wait for entry's completion.
4699 // Then only re-validation or range-re-validation request will go out.
4700 StoreConcurrentCacheAccess(0);
4701 // This will cause that OnCacheEntryCheck is called again with the same
4702 // entry after the writer is done.
4703 wantCompleteEntry = true;
4704 } else {
4705 nsAutoCString val;
4706 // Add If-Modified-Since header if a Last-Modified was given
4707 // and we are allowed to do this (see bugs 510359 and 269303)
4708 if (canAddImsHeader) {
4709 Unused << mCachedResponseHead->GetHeader(nsHttp::Last_Modified, val);
4710 if (!val.IsEmpty()) {
4711 rv = mRequestHead.SetHeader(nsHttp::If_Modified_Since, val);
4712 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"
, 4712); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4712; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4713 }
4714 }
4715 // Add If-None-Match header if an ETag was given in the response
4716 Unused << mCachedResponseHead->GetHeader(nsHttp::ETag, val);
4717 if (!val.IsEmpty()) {
4718 rv = mRequestHead.SetHeader(nsHttp::If_None_Match, val);
4719 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"
, 4719); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4719; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4720 }
4721 mDidReval = true;
4722 }
4723 }
4724 }
4725
4726 bool valid = CachedContentIsValid();
4727 if (valid || mDidReval) {
4728 rv = OpenCacheInputStream(entry, valid);
4729 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4730 // If we can't get the entity then we have to act as though we
4731 // don't have the cache entry.
4732 if (mDidReval) {
4733 UntieValidationRequest();
4734 mDidReval = false;
4735 }
4736 StoreCachedContentIsValid(CachedContentValidity::Invalid);
4737 }
4738 }
4739
4740 if (mDidReval) {
4741 *aResult = ENTRY_NEEDS_REVALIDATION;
4742 } else if (wantCompleteEntry) {
4743 *aResult = RECHECK_AFTER_WRITE_FINISHED;
4744 } else {
4745 *aResult = ENTRY_WANTED;
4746
4747 if (doBackgroundValidation) {
4748 PerformBackgroundCacheRevalidation();
4749 }
4750 }
4751
4752 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)
4753 ("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)
4754 "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)
4755 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)
;
4756 return rv;
4757}
4758
4759NS_IMETHODIMPnsresult
4760nsHttpChannel::OnCacheEntryAvailable(nsICacheEntry* entry, bool aNew,
4761 nsresult status) {
4762 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"
, 4762); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4762; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4763
4764 nsresult rv;
4765
4766 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" "] for %s", this, entry, aNew, static_cast<uint32_t>
(status), mSpec.get()); } } while (0)
4767 ("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" "] for %s", this, entry, aNew, static_cast<uint32_t>
(status), mSpec.get()); } } while (0)
4768 "new=%d status=%" PRIx32 "] 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::OnCacheEntryAvailable [this=%p entry=%p " "new=%d status=%"
"x" "] for %s", this, entry, aNew, static_cast<uint32_t>
(status), mSpec.get()); } } while (0)
4769 this, entry, aNew, static_cast<uint32_t>(status), 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::OnCacheEntryAvailable [this=%p entry=%p " "new=%d status=%"
"x" "] for %s", this, entry, aNew, static_cast<uint32_t>
(status), mSpec.get()); } } while (0)
;
4770
4771 // if the channel's already fired onStopRequest, then we should ignore
4772 // this event.
4773 if (!LoadIsPending()) {
4774 mCacheInputStream.CloseAndRelease();
4775 return NS_OK;
4776 }
4777
4778 rv = OnCacheEntryAvailableInternal(entry, aNew, status);
4779 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4780 CloseCacheEntry(false);
4781 if (mRaceCacheWithNetwork && mNetworkTriggered &&
4782 mFirstResponseSource != RESPONSE_FROM_CACHE) {
4783 // Ignore the error if we're racing cache with network and the cache
4784 // didn't win, The network part will handle cancelation or any other
4785 // error. Otherwise we could end up calling the listener twice, see
4786 // bug 1397593.
4787 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)
4788 (" 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)
4789 "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)
;
4790 } else {
4791 Unused << AsyncAbort(rv);
4792 }
4793 }
4794
4795 return NS_OK;
4796}
4797
4798nsresult nsHttpChannel::OnCacheEntryAvailableInternal(nsICacheEntry* entry,
4799 bool aNew,
4800 nsresult status) {
4801 nsresult rv;
4802
4803 if (mCanceled) {
4804 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)
4805 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)
;
4806 return mStatus;
4807 }
4808
4809 if (mIgnoreCacheEntry) {
4810 if (!entry || aNew) {
4811 // We use this flag later to decide whether to report
4812 // LABELS_NETWORK_RACE_CACHE_VALIDATION::NotSent. We didn't have
4813 // an usable entry, so drop the flag.
4814 mIgnoreCacheEntry = false;
4815 }
4816 entry = nullptr;
4817 status = NS_ERROR_NOT_AVAILABLE;
4818 }
4819
4820 rv = OnNormalCacheEntryAvailable(entry, aNew, status);
4821
4822 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && (mLoadFlags & LOAD_ONLY_FROM_CACHE)) {
4823 return NS_ERROR_DOCUMENT_NOT_CACHED;
4824 }
4825
4826 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4827 return rv;
4828 }
4829
4830 // We may be waiting for more callbacks...
4831 if (AwaitingCacheCallbacks()) {
4832 return NS_OK;
4833 }
4834
4835 bool valid = CachedContentIsValid();
4836 if (mRaceCacheWithNetwork &&
4837 ((mCacheEntry && !valid && (mDidReval || LoadCachedContentIsPartial())) ||
4838 mIgnoreCacheEntry)) {
4839 // We won't send the conditional request because the unconditional
4840 // request was already sent (see bug 1377223).
4841 AccumulateCategorical(
4842 Telemetry::LABELS_NETWORK_RACE_CACHE_VALIDATION::NotSent);
4843 }
4844
4845 if (mRaceCacheWithNetwork && valid) {
4846 Unused << ReadFromCache();
4847 }
4848
4849 return TriggerNetwork();
4850}
4851
4852nsresult nsHttpChannel::OnNormalCacheEntryAvailable(nsICacheEntry* aEntry,
4853 bool aNew,
4854 nsresult aEntryStatus) {
4855 StoreWaitForCacheEntry(LoadWaitForCacheEntry() & ~WAIT_FOR_CACHE_ENTRY);
4856
4857 if (NS_FAILED(aEntryStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(aEntryStatus)), 0)
))
|| aNew) {
4858 // Make sure this flag is dropped. It may happen the entry is doomed
4859 // between OnCacheEntryCheck and OnCacheEntryAvailable.
4860 StoreCachedContentIsValid(CachedContentValidity::Invalid);
4861
4862 // From the same reason remove any conditional headers added
4863 // in OnCacheEntryCheck.
4864 if (mDidReval) {
4865 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)
;
4866 UntieValidationRequest();
4867 mDidReval = false;
4868 }
4869
4870 if (LoadCachedContentIsPartial()) {
4871 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)
;
4872 UntieByteRangeRequest();
4873 StoreCachedContentIsPartial(false);
4874 }
4875
4876 if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
4877 // if this channel is only allowed to pull from the cache, then
4878 // we must fail if we were unable to open a cache entry for read.
4879 return NS_ERROR_DOCUMENT_NOT_CACHED;
4880 }
4881 }
4882
4883 if (NS_SUCCEEDED(aEntryStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aEntryStatus)), 1
)))
) {
4884 mCacheEntry = aEntry;
4885 StoreCacheEntryIsWriteOnly(aNew);
4886
4887 if (!aNew && !mAsyncOpenTime.IsNull()) {
4888 // We use microseconds for IO operations. For consistency let's use
4889 // microseconds here too.
4890 uint32_t duration = (TimeStamp::Now() - mAsyncOpenTime).ToMicroseconds();
4891 bool isSlow = false;
4892 if ((mCacheOpenWithPriority &&
4893 mCacheQueueSizeWhenOpen >=
4894 StaticPrefs::
4895 network_http_rcwn_cache_queue_priority_threshold()) ||
4896 (!mCacheOpenWithPriority &&
4897 mCacheQueueSizeWhenOpen >=
4898 StaticPrefs::network_http_rcwn_cache_queue_normal_threshold())) {
4899 isSlow = true;
4900 }
4901 CacheFileUtils::CachePerfStats::AddValue(
4902 CacheFileUtils::CachePerfStats::ENTRY_OPEN, duration, isSlow);
4903 }
4904 }
4905
4906 return NS_OK;
4907}
4908
4909// Generates the proper cache-key for this instance of nsHttpChannel
4910nsresult nsHttpChannel::GenerateCacheKey(uint32_t postID,
4911 nsACString& cacheKey) {
4912 AssembleCacheKey(mSpec.get(), postID, cacheKey);
4913 return NS_OK;
4914}
4915
4916// Assembles a cache-key from the given pieces of information and |mLoadFlags|
4917void nsHttpChannel::AssembleCacheKey(const char* spec, uint32_t postID,
4918 nsACString& cacheKey) {
4919 cacheKey.Truncate();
4920
4921 if (mLoadFlags & LOAD_ANONYMOUS) {
4922 cacheKey.AssignLiteral("anon&");
4923 }
4924
4925 if (postID) {
4926 char buf[32];
4927 SprintfLiteral(buf, "id=%x&", postID);
4928 cacheKey.Append(buf);
4929 }
4930
4931 if (!cacheKey.IsEmpty()) {
4932 cacheKey.AppendLiteral("uri=");
4933 }
4934
4935 // Strip any trailing #ref from the URL before using it as the key
4936 const char* p = strchr(spec, '#');
4937 if (p) {
4938 cacheKey.Append(spec, p - spec);
4939 } else {
4940 cacheKey.Append(spec);
4941 }
4942}
4943
4944nsresult DoUpdateExpirationTime(nsHttpChannel* aSelf,
4945 nsICacheEntry* aCacheEntry,
4946 nsHttpResponseHead* aResponseHead,
4947 uint32_t& aExpirationTime) {
4948 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"
, 4948); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aExpirationTime == 0"
")"); do { *((volatile int*)__null) = 4948; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4949 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"
, 4949); return NS_ERROR_FAILURE; } } while (false)
;
4950
4951 nsresult rv;
4952
4953 if (!aResponseHead->MustValidate()) {
4954 // For stale-while-revalidate we use expiration time as the absolute base
4955 // for calculation of the stale window absolute end time. Hence, when the
4956 // entry may be served w/o revalidation, we need a non-zero value for the
4957 // expiration time. Let's set it to |now|, which basicly means "expired",
4958 // same as when set to 0.
4959 uint32_t now = NowInSeconds()PRTimeToSeconds(PR_Now());
4960 aExpirationTime = now;
4961
4962 uint32_t freshnessLifetime = 0;
4963
4964 rv = aResponseHead->ComputeFreshnessLifetime(&freshnessLifetime);
4965 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
4966
4967 if (freshnessLifetime > 0) {
4968 uint32_t currentAge = 0;
4969
4970 rv = aResponseHead->ComputeCurrentAge(now, aSelf->GetRequestTime(),
4971 &currentAge);
4972 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
4973
4974 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)
4975 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)
;
4976
4977 if (freshnessLifetime > currentAge) {
4978 uint32_t timeRemaining = freshnessLifetime - currentAge;
4979 // be careful... now + timeRemaining may overflow
4980 if (now + timeRemaining < now) {
4981 aExpirationTime = uint32_t(-1);
4982 } else {
4983 aExpirationTime = now + timeRemaining;
4984 }
4985 }
4986 }
4987 }
4988
4989 rv = aCacheEntry->SetExpirationTime(aExpirationTime);
4990 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"
, 4990); return rv; } } while (false)
;
4991
4992 return rv;
4993}
4994
4995// UpdateExpirationTime is called when a new response comes in from the server.
4996// It updates the stored response-time and sets the expiration time on the
4997// cache entry.
4998//
4999// From section 13.2.4 of RFC2616, we compute expiration time as follows:
5000//
5001// timeRemaining = freshnessLifetime - currentAge
5002// expirationTime = now + timeRemaining
5003//
5004nsresult nsHttpChannel::UpdateExpirationTime() {
5005 uint32_t expirationTime = 0;
5006 nsresult rv = DoUpdateExpirationTime(this, mCacheEntry, mResponseHead.get(),
5007 expirationTime);
5008 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"
, 5008); return rv; } } while (false)
;
5009
5010 return NS_OK;
5011}
5012
5013nsresult nsHttpChannel::OpenCacheInputStream(nsICacheEntry* cacheEntry,
5014 bool startBuffering) {
5015 nsresult rv;
5016
5017 if (mURI->SchemeIs("https")) {
5018 rv = cacheEntry->GetSecurityInfo(getter_AddRefs(mCachedSecurityInfo));
5019 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5020 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)
5021 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)
;
5022 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"
, 5022)
;
5023 cacheEntry->AsyncDoom(nullptr);
5024 return rv;
5025 }
5026
5027 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"
, 5027); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCachedSecurityInfo"
")"); do { *((volatile int*)__null) = 5027; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5028 if (!mCachedSecurityInfo) {
5029 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)
5030 ("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)
5031 "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)
5032 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)
;
5033 cacheEntry->AsyncDoom(nullptr);
5034 return NS_ERROR_UNEXPECTED; // XXX error code
5035 }
5036 }
5037
5038 // Keep the conditions below in sync with the conditions in ReadFromCache.
5039
5040 rv = NS_OK;
5041
5042 if (WillRedirect(*mCachedResponseHead)) {
5043 // Do not even try to read the entity for a redirect because we do not
5044 // return an entity to the application when we process redirects.
5045 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
)
;
5046 return NS_OK;
5047 }
5048
5049 if ((mLoadFlags & nsICachingChannel::LOAD_ONLY_IF_MODIFIED) &&
5050 !LoadCachedContentIsPartial()) {
5051 // For LOAD_ONLY_IF_MODIFIED, we usually don't have to deal with the
5052 // cached entity.
5053 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)
5054 ("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)
5055 "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)
;
5056 return NS_OK;
5057 }
5058
5059 // Open an input stream for the entity, so that the call to OpenInputStream
5060 // happens off the main thread.
5061 nsCOMPtr<nsIInputStream> stream;
5062
5063 // If an alternate representation was requested, try to open the alt
5064 // input stream.
5065 // If the entry has a "is-from-child" metadata, then only open the altdata
5066 // stream if the consumer is also from child.
5067 bool altDataFromChild = false;
5068 {
5069 nsCString value;
5070 rv = cacheEntry->GetMetaDataElement("alt-data-from-child",
5071 getter_Copies(value));
5072 altDataFromChild = !value.IsEmpty();
5073 }
5074
5075 nsAutoCString altDataType;
5076 Unused << cacheEntry->GetAltDataType(altDataType);
5077
5078 nsAutoCString contentType;
5079 mCachedResponseHead->ContentType(contentType);
5080
5081 bool foundAltData = false;
5082 bool deliverAltData = true;
5083 if (!LoadDisableAltDataCache() && !altDataType.IsEmpty() &&
5084 !mPreferredCachedAltDataTypes.IsEmpty() &&
5085 altDataFromChild == LoadAltDataForChild()) {
5086 for (auto& pref : mPreferredCachedAltDataTypes) {
5087 if (pref.type() == altDataType &&
5088 (pref.contentType().IsEmpty() || pref.contentType() == contentType)) {
5089 foundAltData = true;
5090 deliverAltData =
5091 pref.deliverAltData() ==
5092 nsICacheInfoChannel::PreferredAlternativeDataDeliveryType::ASYNC;
5093 break;
5094 }
5095 }
5096 }
5097
5098 nsCOMPtr<nsIInputStream> altData;
5099 int64_t altDataSize = -1;
5100 if (foundAltData) {
5101 rv = cacheEntry->OpenAlternativeInputStream(altDataType,
5102 getter_AddRefs(altData));
5103 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5104 // We have succeeded.
5105 mAvailableCachedAltDataType = altDataType;
5106 StoreDeliveringAltData(deliverAltData);
5107
5108 // Set the correct data size on the channel.
5109 Unused << cacheEntry->GetAltDataSize(&altDataSize);
5110 mAltDataLength = altDataSize;
5111
5112 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)
5113 ", 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)
5114 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)
;
5115
5116 if (deliverAltData) {
5117 stream = altData;
5118 }
5119 }
5120 }
5121
5122 if (!stream) {
5123 rv = cacheEntry->OpenInputStream(0, getter_AddRefs(stream));
5124 }
5125
5126 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5127 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)
5128 ("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)
5129 "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)
5130 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)
;
5131 return rv;
5132 }
5133
5134 if (startBuffering) {
5135 bool nonBlocking;
5136 rv = stream->IsNonBlocking(&nonBlocking);
5137 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && nonBlocking) startBuffering = false;
5138 }
5139
5140 if (!startBuffering) {
5141 // Bypass wrapping the input stream for the new cache back-end since
5142 // nsIStreamTransportService expects a blocking stream. Preloading of
5143 // the data must be done on the level of the cache backend, internally.
5144 //
5145 // We do not connect the stream to the stream transport service if we
5146 // have to validate the entry with the server. If we did, we would get
5147 // into a race condition between the stream transport service reading
5148 // the existing contents and the opening of the cache entry's output
5149 // stream to write the new contents in the case where we get a non-304
5150 // response.
5151 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)
5152 ("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)
5153 "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)
5154 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)
;
5155 mCacheInputStream.takeOver(stream);
5156 return rv;
5157 }
5158
5159 // Have the stream transport service start reading the entity on one of its
5160 // background threads.
5161
5162 nsCOMPtr<nsITransport> transport;
5163 nsCOMPtr<nsIInputStream> wrapper;
5164
5165 nsCOMPtr<nsIStreamTransportService> sts(
5166 components::StreamTransport::Service());
5167 rv = sts ? NS_OK : NS_ERROR_NOT_AVAILABLE;
5168 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5169 rv = sts->CreateInputTransport(stream, true, getter_AddRefs(transport));
5170 }
5171 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5172 rv = transport->OpenInputStream(0, 0, 0, getter_AddRefs(wrapper));
5173 }
5174 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5175 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)
5176 ("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)
5177 "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)
5178 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)
;
5179 } else {
5180 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)
5181 ("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)
5182 "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)
5183 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)
;
5184
5185 stream->Close();
5186 return rv;
5187 }
5188
5189 mCacheInputStream.takeOver(wrapper);
5190
5191 return NS_OK;
5192}
5193
5194// Actually process the cached response that we started to handle in CheckCache
5195// and/or StartBufferingCachedEntity.
5196nsresult nsHttpChannel::ReadFromCache(void) {
5197 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"
, 5197); return NS_ERROR_FAILURE; } } while (false)
;
5198 NS_ENSURE_TRUE(CachedContentIsValid(), NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(CachedContentIsValid())), 0))
) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "CachedContentIsValid()"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5198); return NS_ERROR_FAILURE; } } while (false)
;
5199 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"
, 5199); return NS_OK; } } while (false)
; // already opened
5200
5201 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)
5202 ("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)
5203 "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)
5204 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)
;
5205
5206 // When racing the cache with the network with a timer, and we get data from
5207 // the cache, we should prevent the timer from triggering a network request.
5208 if (mNetworkTriggerTimer) {
5209 mNetworkTriggerTimer->Cancel();
5210 mNetworkTriggerTimer = nullptr;
5211 }
5212
5213 if (mRaceCacheWithNetwork) {
5214 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"
, 5214); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mFirstResponseSource != RESPONSE_FROM_CACHE"
")"); do { *((volatile int*)__null) = 5214; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5215 if (mFirstResponseSource == RESPONSE_PENDING) {
5216 LOG(("First response 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
, "First response from cache"); } } while (0)
;
5217 PROFILER_MARKER_TEXT(do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Cache won for %s (%p)"
, mSpec.get(), this)); } } while (false); } while (false)
5218 "RCWN", NETWORK, {},do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Cache won for %s (%p)"
, mSpec.get(), this)); } } while (false); } while (false)
5219 nsPrintfCString("Cache won for %s (%p)", mSpec.get(), this))do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Cache won for %s (%p)"
, mSpec.get(), this)); } } while (false); } while (false)
;
5220 mFirstResponseSource = RESPONSE_FROM_CACHE;
5221
5222 // Cancel the transaction because we will serve the request from the cache
5223 CancelNetworkRequest(NS_BINDING_ABORTED);
5224 if (mTransactionPump && mSuspendCount) {
5225 uint32_t suspendCount = mSuspendCount;
5226 while (suspendCount--) {
5227 mTransactionPump->Resume();
5228 }
5229 }
5230 mTransaction = nullptr;
5231 mTransactionPump = nullptr;
5232 } else {
5233 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"
, 5233); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mFirstResponseSource == RESPONSE_FROM_NETWORK"
")"); do { *((volatile int*)__null) = 5233; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5234 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)
5235 ("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)
5236 "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)
;
5237
5238 if (!mOnCacheEntryCheckTimestamp.IsNull()) {
5239 TimeStamp currentTime = TimeStamp::Now();
5240 int64_t savedTime =
5241 (currentTime - mOnStartRequestTimestamp).ToMilliseconds();
5242 Telemetry::Accumulate(
5243 Telemetry::NETWORK_RACE_CACHE_WITH_NETWORK_SAVED_TIME, savedTime);
5244
5245 PROFILER_MARKER_TEXT(do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won by %" "l"
"d" "ms for %s", savedTime, mSpec.get())); } } while (false)
; } while (false)
5246 "RCWN", NETWORK, {},do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won by %" "l"
"d" "ms for %s", savedTime, mSpec.get())); } } while (false)
; } while (false)
5247 nsPrintfCString("Network won by %" PRId64 "ms for %s", savedTime,do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won by %" "l"
"d" "ms for %s", savedTime, mSpec.get())); } } while (false)
; } while (false)
5248 mSpec.get()))do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won by %" "l"
"d" "ms for %s", savedTime, mSpec.get())); } } while (false)
; } while (false)
;
5249 int64_t diffTime =
5250 (currentTime - mOnCacheEntryCheckTimestamp).ToMilliseconds();
5251 Telemetry::Accumulate(
5252 Telemetry::NETWORK_RACE_CACHE_WITH_NETWORK_OCEC_ON_START_DIFF,
5253 diffTime);
5254 }
5255 return NS_OK;
5256 }
5257 }
5258
5259 if (mCachedResponseHead) mResponseHead = std::move(mCachedResponseHead);
5260
5261 UpdateInhibitPersistentCachingFlag();
5262
5263 // if we don't already have security info, try to get it from the cache
5264 // entry. there are two cases to consider here: 1) we are just reading
5265 // from the cache, or 2) this may be due to a 304 not modified response,
5266 // in which case we could have security info from a socket transport.
5267 if (!mSecurityInfo) mSecurityInfo = mCachedSecurityInfo;
5268
5269 nsresult rv;
5270
5271 // Keep the conditions below in sync with the conditions in
5272 // StartBufferingCachedEntity.
5273
5274 if (WillRedirect(*mResponseHead)) {
5275 // TODO: Bug 759040 - We should call HandleAsyncRedirect directly here,
5276 // to avoid event dispatching latency.
5277 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"
, 5277); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCacheInputStream"
")"); do { *((volatile int*)__null) = 5277; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5278 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)
;
5279 return AsyncCall(&nsHttpChannel::HandleAsyncRedirect);
5280 }
5281
5282 if ((mLoadFlags & LOAD_ONLY_IF_MODIFIED) && !LoadCachedContentIsPartial()) {
5283 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)
5284 ("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)
5285 "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)
;
5286 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"
, 5286); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCacheInputStream"
")"); do { *((volatile int*)__null) = 5286; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5287 // TODO: Bug 759040 - We should call HandleAsyncNotModified directly
5288 // here, to avoid event dispatching latency.
5289 return AsyncCall(&nsHttpChannel::HandleAsyncNotModified);
5290 }
5291
5292 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"
, 5292); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCacheInputStream"
")"); do { *((volatile int*)__null) = 5292; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5293 if (!mCacheInputStream) {
5294 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"
, 5296); MOZ_PretendNoReturn(); } while (0)
5295 "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"
, 5296); MOZ_PretendNoReturn(); } while (0)
5296 "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"
, 5296); MOZ_PretendNoReturn(); } while (0)
;
5297 return NS_ERROR_UNEXPECTED;
5298 }
5299
5300 nsCOMPtr<nsIInputStream> inputStream = mCacheInputStream.forget();
5301
5302 rv = nsInputStreamPump::Create(getter_AddRefs(mCachePump), inputStream, 0, 0,
5303 true);
5304 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5305 inputStream->Close();
5306 return rv;
5307 }
5308
5309 rv = mCachePump->AsyncRead(this);
5310 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5311
5312 uint32_t suspendCount = mSuspendCount;
5313 if (LoadAsyncResumePending()) {
5314 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)
5315 (" 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)
5316 ", 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)
5317 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)
;
5318 ++suspendCount;
5319 }
5320 while (suspendCount--) {
5321 mCachePump->Suspend();
5322 }
5323
5324 return NS_OK;
5325}
5326
5327void nsHttpChannel::CloseCacheEntry(bool doomOnFailure) {
5328 mCacheInputStream.CloseAndRelease();
5329
5330 if (!mCacheEntry) return;
5331
5332 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)
5333 " 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)
5334 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)
5335 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)
;
5336
5337 // If we have begun to create or replace a cache entry, and that cache
5338 // entry is not complete and not resumable, then it needs to be doomed.
5339 // Otherwise, CheckCache will make the mistake of thinking that the
5340 // partial cache entry is complete.
5341
5342 bool doom = false;
5343 if (LoadInitedCacheEntry()) {
5344 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"
, 5344); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mResponseHead"
") (" "oops" ")"); do { *((volatile int*)__null) = 5344; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
5345 if (NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0))) && doomOnFailure && LoadCacheEntryIsWriteOnly() &&
5346 !mResponseHead->IsResumable()) {
5347 doom = true;
5348 }
5349 } else if (LoadCacheEntryIsWriteOnly()) {
5350 doom = true;
5351 }
5352
5353 if (doom) {
5354 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)
;
5355 mCacheEntry->AsyncDoom(nullptr);
5356 } else {
5357 // Store updated security info, makes cached EV status race less likely
5358 // (see bug 1040086)
5359 if (mSecurityInfo) {
5360 mCacheEntry->SetSecurityInfo(mSecurityInfo);
5361 }
5362 }
5363
5364 mCachedResponseHead = nullptr;
5365
5366 mCachePump = nullptr;
5367 // This releases the entry for other consumers to use.
5368 // We call Dismiss() in case someone still keeps a reference
5369 // to this entry handle.
5370 mCacheEntry->Dismiss();
5371 mCacheEntry = nullptr;
5372 StoreCacheEntryIsWriteOnly(false);
5373 StoreInitedCacheEntry(false);
5374}
5375
5376void nsHttpChannel::MaybeCreateCacheEntryWhenRCWN() {
5377 mozilla::MutexAutoLock lock(mRCWNLock);
5378
5379 // Create cache entry for writing only when we're racing cache with network
5380 // and we don't have the entry because network won.
5381 if (mCacheEntry || !mRaceCacheWithNetwork ||
5382 mFirstResponseSource != RESPONSE_FROM_NETWORK ||
5383 LoadCacheEntryIsReadOnly()) {
5384 return;
5385 }
5386
5387 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)
;
5388
5389 nsCOMPtr<nsICacheStorageService> cacheStorageService(
5390 components::CacheStorage::Service());
5391 if (!cacheStorageService) {
5392 return;
5393 }
5394
5395 nsCOMPtr<nsICacheStorage> cacheStorage;
5396 RefPtr<LoadContextInfo> info = GetLoadContextInfo(this);
5397 Unused << cacheStorageService->DiskCacheStorage(info,
5398 getter_AddRefs(cacheStorage));
5399 if (!cacheStorage) {
5400 return;
5401 }
5402
5403 Unused << cacheStorage->OpenTruncate(mCacheEntryURI, mCacheIdExtension,
5404 getter_AddRefs(mCacheEntry));
5405
5406 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)
;
5407
5408 if (AwaitingCacheCallbacks()) {
5409 // Setting mIgnoreCacheEntry to true ensures that we won't close this
5410 // write-only entry in OnCacheEntryAvailable() if this method was called
5411 // after OnCacheEntryCheck().
5412 mIgnoreCacheEntry = true;
5413 }
5414
5415 mAvailableCachedAltDataType.Truncate();
5416 StoreDeliveringAltData(false);
5417 mAltDataLength = -1;
5418 mCacheInputStream.CloseAndRelease();
5419 StoreCachedContentIsValid(CachedContentValidity::Invalid);
5420}
5421
5422// Initialize the cache entry for writing.
5423// - finalize storage policy
5424// - store security info
5425// - update expiration time
5426// - store headers and other meta data
5427nsresult nsHttpChannel::InitCacheEntry() {
5428 nsresult rv;
5429
5430 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"
, 5430); return NS_ERROR_UNEXPECTED; } } while (false)
;
5431 // if only reading, nothing to be done here.
5432 if (LoadCacheEntryIsReadOnly()) return NS_OK;
5433
5434 // Don't cache the response again if already cached...
5435 if (CachedContentIsValid()) return NS_OK;
5436
5437 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)
5438 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)
;
5439
5440 bool recreate = !LoadCacheEntryIsWriteOnly();
5441 bool dontPersist = mLoadFlags & INHIBIT_PERSISTENT_CACHING;
5442
5443 if (!recreate && dontPersist) {
5444 // If the current entry is persistent but we inhibit peristence
5445 // then force recreation of the entry as memory/only.
5446 rv = mCacheEntry->GetPersistent(&recreate);
5447 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5448 }
5449
5450 if (recreate) {
5451 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)
5452 (" 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)
5453 "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)
;
5454 // clean the altData cache and reset this to avoid wrong content length
5455 mAvailableCachedAltDataType.Truncate();
5456 StoreDeliveringAltData(false);
5457
5458 nsCOMPtr<nsICacheEntry> currentEntry;
5459 currentEntry.swap(mCacheEntry);
5460 rv = currentEntry->Recreate(dontPersist, getter_AddRefs(mCacheEntry));
5461 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5462 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)
;
5463 return NS_OK;
5464 }
5465
5466 StoreCacheEntryIsWriteOnly(true);
5467 }
5468
5469 // Set the expiration time for this cache entry
5470 rv = UpdateExpirationTime();
5471 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5472
5473 // mark this weakly framed until a response body is seen
5474 mCacheEntry->SetMetaDataElement("strongly-framed", "0");
5475
5476 rv = AddCacheEntryHeaders(mCacheEntry);
5477 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5478
5479 StoreInitedCacheEntry(true);
5480
5481 // Don't perform the check when writing (doesn't make sense)
5482 StoreConcurrentCacheAccess(0);
5483
5484 return NS_OK;
5485}
5486
5487void nsHttpChannel::UpdateInhibitPersistentCachingFlag() {
5488 // The no-store directive within the 'Cache-Control:' header indicates
5489 // that we must not store the response in a persistent cache.
5490 if (mResponseHead->NoStore()) {
5491 mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
5492 return;
5493 }
5494
5495 if (!StaticPrefs::network_cache_persist_permanent_redirects_http() &&
5496 mURI->SchemeIs("http") &&
5497 nsHttp::IsPermanentRedirect(mResponseHead->Status())) {
5498 mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
5499 return;
5500 }
5501
5502 // Only cache SSL content on disk if the pref is set
5503 if (!gHttpHandler->IsPersistentHttpsCachingEnabled() &&
5504 mURI->SchemeIs("https")) {
5505 mLoadFlags |= INHIBIT_PERSISTENT_CACHING;
5506 }
5507}
5508
5509nsresult DoAddCacheEntryHeaders(nsHttpChannel* self, nsICacheEntry* entry,
5510 nsHttpRequestHead* requestHead,
5511 nsHttpResponseHead* responseHead,
5512 nsITransportSecurityInfo* securityInfo) {
5513 nsresult rv;
5514
5515 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)
;
5516 // Store secure data in memory only
5517 if (securityInfo) {
5518 entry->SetSecurityInfo(securityInfo);
5519 }
5520
5521 // Store the HTTP request method with the cache entry so we can distinguish
5522 // for example GET and HEAD responses.
5523 nsAutoCString method;
5524 requestHead->Method(method);
5525 rv = entry->SetMetaDataElement("request-method", method.get());
5526 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5527
5528 // Store the HTTP authorization scheme used if any...
5529 rv = StoreAuthorizationMetaData(entry, requestHead);
5530 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5531
5532 // Iterate over the headers listed in the Vary response header, and
5533 // store the value of the corresponding request header so we can verify
5534 // that it has not varied when we try to re-use the cached response at
5535 // a later time. Take care to store "Cookie" headers only as hashes
5536 // due to security considerations and the fact that they can be pretty
5537 // large (bug 468426). We take care of "Vary: cookie" in ResponseWouldVary.
5538 //
5539 // NOTE: if "Vary: accept, cookie", then we will store the "accept" header
5540 // in the cache. we could try to avoid needlessly storing the "accept"
5541 // header in this case, but it doesn't seem worth the extra code to perform
5542 // the check.
5543 {
5544 nsAutoCString buf, metaKey;
5545 Unused << responseHead->GetHeader(nsHttp::Vary, buf);
5546
5547 constexpr auto prefix = "request-"_ns;
5548
5549 for (const nsACString& token :
5550 nsCCharSeparatedTokenizer(buf, NS_HTTP_HEADER_SEP',').ToRange()) {
5551 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)
5552 ("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)
5553 "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)
5554 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)
;
5555 if (!token.EqualsLiteral("*")) {
5556 nsHttpAtom atom = nsHttp::ResolveAtom(token);
5557 nsAutoCString val;
5558 nsAutoCString hash;
5559 if (NS_SUCCEEDED(requestHead->GetHeader(atom, val))((bool)(__builtin_expect(!!(!NS_FAILED_impl(requestHead->GetHeader
(atom, val))), 1)))
) {
5560 // If cookie-header, store a hash of the value
5561 if (atom == nsHttp::Cookie) {
5562 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)
5563 ("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)
5564 "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)
5565 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)
;
5566 rv = Hash(val.get(), hash);
5567 // If hash failed, store a string not very likely
5568 // to be the result of subsequent hashes
5569 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5570 val = "<hash failed>"_ns;
5571 } else {
5572 val = hash;
5573 }
5574
5575 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)
;
5576 }
5577
5578 // build cache meta data key and set meta data element...
5579 metaKey = prefix + token;
5580 entry->SetMetaDataElement(metaKey.get(), val.get());
5581 } else {
5582 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)
5583 ("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)
5584 "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)
5585 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)
;
5586 metaKey = prefix + token;
5587 entry->SetMetaDataElement(metaKey.get(), nullptr);
5588 }
5589 }
5590 }
5591 }
5592
5593 // Store the received HTTP head with the cache entry as an element of
5594 // the meta data.
5595 nsAutoCString head;
5596 responseHead->Flatten(head, true);
5597 rv = entry->SetMetaDataElement("response-head", head.get());
5598 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5599 head.Truncate();
5600 responseHead->FlattenNetworkOriginalHeaders(head);
5601 rv = entry->SetMetaDataElement("original-response-headers", head.get());
5602 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5603
5604 // Indicate we have successfully finished setting metadata on the cache entry.
5605 rv = entry->MetaDataReady();
5606
5607 return rv;
5608}
5609
5610nsresult nsHttpChannel::AddCacheEntryHeaders(nsICacheEntry* entry) {
5611 return DoAddCacheEntryHeaders(this, entry, &mRequestHead, mResponseHead.get(),
5612 mSecurityInfo);
5613}
5614
5615inline void GetAuthType(const char* challenge, nsCString& authType) {
5616 const char* p;
5617
5618 // get the challenge type
5619 if ((p = strchr(challenge, ' ')) != nullptr) {
5620 authType.Assign(challenge, p - challenge);
5621 } else {
5622 authType.Assign(challenge);
5623 }
5624}
5625
5626nsresult StoreAuthorizationMetaData(nsICacheEntry* entry,
5627 nsHttpRequestHead* requestHead) {
5628 // Not applicable to proxy authorization...
5629 nsAutoCString val;
5630 if (NS_FAILED(requestHead->GetHeader(nsHttp::Authorization, val))((bool)(__builtin_expect(!!(NS_FAILED_impl(requestHead->GetHeader
(nsHttp::Authorization, val))), 0)))
) {
5631 return NS_OK;
5632 }
5633
5634 // eg. [Basic realm="wally world"]
5635 nsAutoCString buf;
5636 GetAuthType(val.get(), buf);
5637 return entry->SetMetaDataElement("auth", buf.get());
5638}
5639
5640// Finalize the cache entry
5641// - may need to rewrite response headers if any headers changed
5642// - may need to recalculate the expiration time if any headers changed
5643// - called only for freshly written cache entries
5644nsresult nsHttpChannel::FinalizeCacheEntry() {
5645 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)
;
5646
5647 // Don't update this meta-data on 304
5648 if (LoadStronglyFramed() && !CachedContentIsValid() && mCacheEntry) {
5649 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)
5650 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)
;
5651 mCacheEntry->SetMetaDataElement("strongly-framed", "1");
5652 }
5653
5654 if (mResponseHead && LoadResponseHeadersModified()) {
5655 // Set the expiration time for this cache entry
5656 nsresult rv = UpdateExpirationTime();
5657 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5658 }
5659 return NS_OK;
5660}
5661
5662// Open an output stream to the cache entry and insert a listener tee into
5663// the chain of response listeners.
5664nsresult nsHttpChannel::InstallCacheListener(int64_t offset) {
5665 nsresult rv;
5666
5667 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)
;
5668
5669 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"
, 5669); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCacheEntry"
")"); do { *((volatile int*)__null) = 5669; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5670 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"
, 5671); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadCacheEntryIsWriteOnly() || LoadCachedContentIsPartial() || mRaceCacheWithNetwork"
")"); do { *((volatile int*)__null) = 5671; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5671 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"
, 5671); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadCacheEntryIsWriteOnly() || LoadCachedContentIsPartial() || mRaceCacheWithNetwork"
")"); do { *((volatile int*)__null) = 5671; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5672 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"
, 5672); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mListener" ")"
); do { *((volatile int*)__null) = 5672; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5673
5674 nsAutoCString contentEncoding, contentType;
5675 Unused << mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
5676 mResponseHead->ContentType(contentType);
5677 // If the content is compressible and the server has not compressed it,
5678 // mark the cache entry for compression.
5679 if (contentEncoding.IsEmpty() &&
5680 (contentType.EqualsLiteral(TEXT_HTML"text/html") ||
5681 contentType.EqualsLiteral(TEXT_PLAIN"text/plain") ||
5682 contentType.EqualsLiteral(TEXT_CSS"text/css") ||
5683 contentType.EqualsLiteral(TEXT_JAVASCRIPT"text/javascript") ||
5684 contentType.EqualsLiteral(TEXT_ECMASCRIPT"text/ecmascript") ||
5685 contentType.EqualsLiteral(TEXT_XML"text/xml") ||
5686 contentType.EqualsLiteral(APPLICATION_JAVASCRIPT"application/javascript") ||
5687 contentType.EqualsLiteral(APPLICATION_ECMASCRIPT"application/ecmascript") ||
5688 contentType.EqualsLiteral(APPLICATION_XJAVASCRIPT"application/x-javascript") ||
5689 contentType.EqualsLiteral(APPLICATION_XHTML_XML"application/xhtml+xml"))) {
5690 rv = mCacheEntry->SetMetaDataElement("uncompressed-len", "0");
5691 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5692 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
)
;
5693 }
5694 }
5695
5696 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)
;
5697
5698 // We must close the input stream first because cache entries do not
5699 // correctly handle having an output stream and input streams open at
5700 // the same time.
5701 mCacheInputStream.CloseAndRelease();
5702
5703 int64_t predictedSize = mResponseHead->TotalEntitySize();
5704 if (predictedSize != -1) {
5705 predictedSize -= offset;
5706 }
5707
5708 nsCOMPtr<nsIOutputStream> out;
5709 rv =
5710 mCacheEntry->OpenOutputStream(offset, predictedSize, getter_AddRefs(out));
5711 if (rv == NS_ERROR_NOT_AVAILABLE) {
5712 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)
;
5713 // Entry is already doomed.
5714 // This may happen when expiration time is set to past and the entry
5715 // has been removed by the background eviction logic.
5716 return NS_OK;
5717 }
5718 if (rv == NS_ERROR_FILE_TOO_BIG) {
5719 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)
5720 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)
;
5721 mCacheEntry->AsyncDoom(nullptr);
5722 return NS_OK;
5723 }
5724 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5725
5726 if (LoadCacheOnlyMetadata()) {
5727 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
)
;
5728 // We must open and then close the output stream of the cache entry.
5729 // This way we indicate the content has been written (despite with zero
5730 // length) and the entry is now in the ready state with "having data".
5731
5732 out->Close();
5733 return NS_OK;
5734 }
5735
5736 // XXX disk cache does not support overlapped i/o yet
5737#if 0
5738 // Mark entry valid inorder to allow simultaneous reading...
5739 rv = mCacheEntry->MarkValid();
5740 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5741#endif
5742
5743 nsCOMPtr<nsIStreamListenerTee> tee =
5744 do_CreateInstance(kStreamListenerTeeCID, &rv);
5745 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5746
5747 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)
5748 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)
;
5749 rv = tee->Init(mListener, out, nullptr);
5750 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5751
5752 mListener = tee;
5753 return NS_OK;
5754}
5755
5756//-----------------------------------------------------------------------------
5757// nsHttpChannel <redirect>
5758//-----------------------------------------------------------------------------
5759
5760nsresult nsHttpChannel::SetupReplacementChannel(nsIURI* newURI,
5761 nsIChannel* newChannel,
5762 bool preserveMethod,
5763 uint32_t redirectFlags) {
5764 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)
5765 ("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)
5766 "[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)
5767 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)
;
5768
5769 if (!mEndMarkerAdded && profiler_thread_is_being_profiled_for_markers()) {
5770 mEndMarkerAdded = true;
5771
5772 nsAutoCString requestMethod;
5773 GetRequestMethod(requestMethod);
5774
5775 int32_t priority = PRIORITY_NORMAL;
5776 GetPriority(&priority);
5777
5778 TimingStruct timings;
5779 if (mTransaction) {
5780 timings = mTransaction->Timings();
5781 }
5782
5783 uint64_t size = 0;
5784 GetEncodedBodySize(&size);
5785
5786 nsAutoCString contentType;
5787 mozilla::Maybe<mozilla::net::HttpVersion> httpVersion = Nothing();
5788 mozilla::Maybe<uint32_t> responseStatus = Nothing();
5789 if (mResponseHead) {
5790 mResponseHead->ContentType(contentType);
5791 httpVersion = Some(mResponseHead->Version());
5792 responseStatus = Some(mResponseHead->Status());
5793 }
5794
5795 RefPtr<nsIIdentChannel> newIdentChannel = do_QueryObject(newChannel);
5796 uint64_t channelId = 0;
5797 if (newIdentChannel) {
5798 channelId = newIdentChannel->ChannelId();
5799 }
5800 profiler_add_network_marker(
5801 mURI, requestMethod, priority, mChannelId,
5802 NetworkLoadType::LOAD_REDIRECT, mLastStatusReported, TimeStamp::Now(),
5803 size, mCacheDisposition, mLoadInfo->GetInnerWindowID(),
5804 mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(),
5805 mClassOfService.Flags(), &timings, std::move(mSource), httpVersion,
5806 responseStatus, Some(nsDependentCString(contentType.get())), newURI,
5807 redirectFlags, channelId);
5808 }
5809
5810 nsresult rv = HttpBaseChannel::SetupReplacementChannel(
5811 newURI, newChannel, preserveMethod, redirectFlags);
5812 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
5813
5814 nsAutoCString uriHost;
5815 mURI->GetAsciiHost(uriHost);
5816 // disable https-rr when encountering a downgrade from https to http.
5817 // If the host would have https-rr dns-entries, it would be misconfigured
5818 // due to giving us mixed signals:
5819 // 1. the signal to upgrade all http requests to https,
5820 // 2. but also downgrading to http on https via redirects.
5821 // Add to exclude list for that reason
5822 if (!gHttpHandler->IsHostExcludedForHTTPSRR(uriHost) &&
5823 nsHTTPSOnlyUtils::IsUpgradeDowngradeEndlessLoop(
5824 mURI, newURI, mLoadInfo,
5825 {nsHTTPSOnlyUtils::UpgradeDowngradeEndlessLoopOptions::
5826 EnforceForHTTPSRR})) {
5827 // Add the host to a excluded list because:
5828 // 1. We don't need to do the same check again.
5829 // 2. Other subresources in the same host will be also excluded.
5830 gHttpHandler->ExcludeHTTPSRRHost(uriHost);
5831 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)
;
5832 }
5833
5834 rv = CheckRedirectLimit(newURI, redirectFlags);
5835 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"
, 5835); return rv; } } while (false)
;
5836
5837 // pass on the early hint observer to be able to process `103 Early Hints`
5838 // responses after cross origin redirects
5839 if (mEarlyHintObserver) {
5840 if (RefPtr<nsHttpChannel> httpChannelImpl = do_QueryObject(newChannel)) {
5841 httpChannelImpl->SetEarlyHintObserver(mEarlyHintObserver);
5842 }
5843 mEarlyHintObserver = nullptr;
5844 }
5845
5846 // We don't support redirection for WebTransport for now.
5847 mWebTransportSessionEventListener = nullptr;
5848
5849 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
5850 if (!httpChannel) return NS_OK; // no other options to set
5851
5852 // convey the ApplyConversion flag (bug 91862)
5853 nsCOMPtr<nsIEncodedChannel> encodedChannel = do_QueryInterface(httpChannel);
5854 if (encodedChannel) encodedChannel->SetApplyConversion(LoadApplyConversion());
5855
5856 // transfer the resume information
5857 if (LoadResuming()) {
5858 nsCOMPtr<nsIResumableChannel> resumableChannel(
5859 do_QueryInterface(newChannel));
5860 if (!resumableChannel) {
5861 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"
, 5862)
5862 "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"
, 5862)
;
5863 return NS_ERROR_NOT_RESUMABLE;
5864 }
5865 resumableChannel->ResumeAt(mStartPos, mEntityID);
5866 }
5867
5868 nsCOMPtr<nsIHttpChannelInternal> internalChannel =
5869 do_QueryInterface(newChannel, &rv);
5870 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5871 TimeStamp timestamp;
5872 rv = GetNavigationStartTimeStamp(&timestamp);
5873 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"
, 5873)
) {
5874 return rv;
5875 }
5876 if (timestamp) {
5877 Unused << internalChannel->SetNavigationStartTimeStamp(timestamp);
5878 }
5879 }
5880
5881 return NS_OK;
5882}
5883
5884nsresult nsHttpChannel::AsyncProcessRedirection(uint32_t redirectType) {
5885 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)
5886 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)
;
5887
5888 nsresult rv = ProcessCrossOriginSecurityHeaders();
5889 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5890 mStatus = rv;
5891 HandleAsyncAbort();
5892 return rv;
5893 }
5894
5895 nsAutoCString location;
5896
5897 // if a location header was not given, then we can't perform the redirect,
5898 // so just carry on as though this were a normal response.
5899 if (NS_FAILED(mResponseHead->GetHeader(nsHttp::Location, location))((bool)(__builtin_expect(!!(NS_FAILED_impl(mResponseHead->
GetHeader(nsHttp::Location, location))), 0)))
) {
5900 return NS_ERROR_FAILURE;
5901 }
5902
5903 // If we were told to not follow redirects automatically, then again
5904 // carry on as though this were a normal response.
5905 if (mLoadInfo->GetDontFollowRedirects()) {
5906 return NS_ERROR_FAILURE;
5907 }
5908
5909 // make sure non-ASCII characters in the location header are escaped.
5910 nsAutoCString locationBuf;
5911 if (NS_EscapeURL(location.get(), -1, esc_OnlyNonASCII | esc_Spaces,
5912 locationBuf)) {
5913 location = locationBuf;
5914 }
5915
5916 mRedirectType = redirectType;
5917
5918 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)
5919 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)
;
5920
5921 rv = CreateNewURI(location.get(), getter_AddRefs(mRedirectURI));
5922
5923 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5924 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)
;
5925 return NS_ERROR_CORRUPTED_CONTENT;
5926 }
5927
5928 if (!StaticPrefs::network_allow_redirect_to_data() &&
5929 !mLoadInfo->GetAllowInsecureRedirectToDataURI() &&
5930 mRedirectURI->SchemeIs("data")) {
5931 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)
;
5932 nsContentSecurityManager::ReportBlockedDataURI(mRedirectURI, mLoadInfo,
5933 true);
5934 return NS_ERROR_DOM_BAD_URI;
5935 }
5936
5937 // Perform the URL query string stripping for redirects. We will only strip
5938 // the query string if it is redirecting to a third-party URI in the top
5939 // level.
5940 if (StaticPrefs::privacy_query_stripping_redirect()) {
5941 ThirdPartyUtil* thirdPartyUtil = ThirdPartyUtil::GetInstance();
5942 bool isThirdPartyRedirectURI = true;
5943 thirdPartyUtil->IsThirdPartyURI(mURI, mRedirectURI,
5944 &isThirdPartyRedirectURI);
5945 if (isThirdPartyRedirectURI && mLoadInfo->GetExternalContentPolicyType() ==
5946 ExtContentPolicy::TYPE_DOCUMENT) {
5947 Telemetry::AccumulateCategorical(
5948 Telemetry::LABELS_QUERY_STRIPPING_COUNT::Redirect);
5949
5950 nsCOMPtr<nsIPrincipal> prin;
5951 ContentBlockingAllowList::RecomputePrincipal(
5952 mRedirectURI, mLoadInfo->GetOriginAttributes(), getter_AddRefs(prin));
5953
5954 bool isRedirectURIInAllowList = false;
5955 if (prin) {
5956 ContentBlockingAllowList::Check(prin, mPrivateBrowsing,
5957 isRedirectURIInAllowList);
5958 }
5959
5960 if (!isRedirectURIInAllowList) {
5961 nsCOMPtr<nsIURI> strippedURI;
5962
5963 nsCOMPtr<nsIURLQueryStringStripper> queryStripper;
5964 queryStripper =
5965 mozilla::components::URLQueryStringStripper::Service(&rv);
5966 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"
, 5966); return rv; } } while (false)
;
5967
5968 uint32_t numStripped;
5969
5970 rv = queryStripper->Strip(mRedirectURI, mPrivateBrowsing,
5971 getter_AddRefs(strippedURI), &numStripped);
5972 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"
, 5972); return rv; } } while (false)
;
5973
5974 if (numStripped) {
5975 mUnstrippedRedirectURI = mRedirectURI;
5976 mRedirectURI = strippedURI;
5977
5978 // Record telemetry, but only if we stripped any query params.
5979 Telemetry::AccumulateCategorical(
5980 Telemetry::LABELS_QUERY_STRIPPING_COUNT::StripForRedirect);
5981 Telemetry::Accumulate(Telemetry::QUERY_STRIPPING_PARAM_COUNT,
5982 numStripped);
5983 }
5984 }
5985 }
5986 }
5987
5988 if (NS_WARN_IF(!mRedirectURI)NS_warn_if_impl(!mRedirectURI, "!mRedirectURI", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 5988)
) {
5989 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)
;
5990 return NS_ERROR_FAILURE;
5991 }
5992
5993 return ContinueProcessRedirectionAfterFallback(NS_OK);
5994}
5995
5996nsresult nsHttpChannel::ContinueProcessRedirectionAfterFallback(nsresult rv) {
5997 // Kill the current cache entry if we are redirecting
5998 // back to ourself.
5999 bool redirectingBackToSameURI = false;
6000 if (mCacheEntry && LoadCacheEntryIsWriteOnly() &&
6001 NS_SUCCEEDED(mURI->Equals(mRedirectURI, &redirectingBackToSameURI))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mURI->Equals(mRedirectURI
, &redirectingBackToSameURI))), 1)))
&&
6002 redirectingBackToSameURI) {
6003 mCacheEntry->AsyncDoom(nullptr);
6004 }
6005
6006 // move the reference of the old location to the new one if the new
6007 // one has none.
6008 PropagateReferenceIfNeeded(mURI, mRedirectURI);
6009
6010 bool rewriteToGET =
6011 ShouldRewriteRedirectToGET(mRedirectType, mRequestHead.ParsedMethod());
6012
6013 // prompt if the method is not safe (such as POST, PUT, DELETE, ...)
6014 if (!rewriteToGET && !mRequestHead.IsSafeMethod()) {
6015 rv = PromptTempRedirect();
6016 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
6017 }
6018
6019 uint32_t redirectFlags;
6020 if (nsHttp::IsPermanentRedirect(mRedirectType)) {
6021 redirectFlags = nsIChannelEventSink::REDIRECT_PERMANENT;
6022 } else {
6023 redirectFlags = nsIChannelEventSink::REDIRECT_TEMPORARY;
6024 }
6025
6026 nsCOMPtr<nsIIOService> ioService;
6027 rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
6028 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
6029
6030 nsCOMPtr<nsIChannel> newChannel;
6031 nsCOMPtr<nsILoadInfo> redirectLoadInfo =
6032 CloneLoadInfoForRedirect(mRedirectURI, redirectFlags);
6033
6034 // Propagate the unstripped redirect URI.
6035 redirectLoadInfo->SetUnstrippedURI(mUnstrippedRedirectURI);
6036
6037 rv = NS_NewChannelInternal(getter_AddRefs(newChannel), mRedirectURI,
6038 redirectLoadInfo,
6039 nullptr, // PerformanceStorage
6040 nullptr, // aLoadGroup
6041 nullptr, // aCallbacks
6042 nsIRequest::LOAD_NORMAL, ioService);
6043 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"
, 6043); return rv; } } while (false)
;
6044
6045 rv = SetupReplacementChannel(mRedirectURI, newChannel, !rewriteToGET,
6046 redirectFlags);
6047 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
6048
6049 // verify that this is a legal redirect
6050 mRedirectChannel = newChannel;
6051
6052 PushRedirectAsyncFunc(&nsHttpChannel::ContinueProcessRedirection);
6053 rv = gHttpHandler->AsyncOnChannelRedirect(this, newChannel, redirectFlags);
6054
6055 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = WaitForRedirectCallback();
6056
6057 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6058 AutoRedirectVetoNotifier notifier(this, rv);
6059 PopRedirectAsyncFunc(&nsHttpChannel::ContinueProcessRedirection);
6060 }
6061
6062 return rv;
6063}
6064
6065nsresult nsHttpChannel::ContinueProcessRedirection(nsresult rv) {
6066 AutoRedirectVetoNotifier notifier(this, rv);
6067
6068 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)
6069 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)
;
6070 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
6071
6072 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"
, 6072); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRedirectChannel"
") (" "No redirect channel?" ")"); do { *((volatile int*)__null
) = 6072; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
6073
6074 // Make sure to do this after we received redirect veto answer,
6075 // i.e. after all sinks had been notified
6076 mRedirectChannel->SetOriginalURI(mOriginalURI);
6077
6078 // XXX we used to talk directly with the script security manager, but that
6079 // should really be handled by the event sink implementation.
6080
6081 // begin loading the new channel
6082 rv = mRedirectChannel->AsyncOpen(mListener);
6083 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)
;
6084 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"
, 6084); return rv; } } while (false)
;
6085
6086 // close down this channel
6087 Cancel(NS_BINDING_REDIRECTED);
6088
6089 notifier.RedirectSucceeded();
6090
6091 ReleaseListeners();
6092
6093 return NS_OK;
6094}
6095
6096//-----------------------------------------------------------------------------
6097// nsHttpChannel <auth>
6098//-----------------------------------------------------------------------------
6099
6100NS_IMETHODIMPnsresult nsHttpChannel::OnAuthAvailable() {
6101 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)
;
6102
6103 // setting mAuthRetryPending flag and resuming the transaction
6104 // triggers process of throwing away the unauthenticated data already
6105 // coming from the network
6106 mIsAuthChannel = true;
6107 mAuthRetryPending = true;
6108 StoreProxyAuthPending(false);
6109 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)
;
6110 if (mTransactionPump) {
6111 mTransactionPump->Resume();
6112 }
6113
6114 if (StaticPrefs::network_auth_use_redirect_for_retries()) {
6115 return CallOrWaitForResume(
6116 [](auto* self) { return self->RedirectToNewChannelForAuthRetry(); });
6117 }
6118
6119 return NS_OK;
6120}
6121
6122NS_IMETHODIMPnsresult nsHttpChannel::OnAuthCancelled(bool userCancel) {
6123 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)
;
6124 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"
, 6124); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAuthRetryPending"
") (" "OnAuthCancelled should not be called twice" ")"); do {
*((volatile int*)__null) = 6124; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
6125
6126 if (mTransactionPump) {
6127 // If the channel is trying to authenticate to a proxy and
6128 // that was canceled we cannot show the http response body
6129 // from the 40x as that might mislead the user into thinking
6130 // it was a end host response instead of a proxy reponse.
6131 // This must check explicitly whether a proxy auth was being done
6132 // because we do want to show the content if this is an error from
6133 // the origin server.
6134 if (LoadProxyAuthPending()) Cancel(NS_ERROR_PROXY_CONNECTION_REFUSED);
6135
6136 // Make sure to process security headers before calling CallOnStartRequest.
6137 nsresult rv = ProcessCrossOriginSecurityHeaders();
6138 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6139 mStatus = rv;
6140 HandleAsyncAbort();
6141 return rv;
6142 }
6143
6144 // ensure call of OnStartRequest of the current listener here,
6145 // it would not be called otherwise at all
6146 rv = CallOnStartRequest();
6147
6148 // drop mAuthRetryPending flag and resume the transaction
6149 // this resumes load of the unauthenticated content data (which
6150 // may have been canceled if we don't want to show it)
6151 mAuthRetryPending = false;
6152 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)
;
6153 mTransactionPump->Resume();
6154
6155 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) mTransactionPump->Cancel(rv);
6156 }
6157
6158 StoreProxyAuthPending(false);
6159 return NS_OK;
6160}
6161
6162NS_IMETHODIMPnsresult nsHttpChannel::CloseStickyConnection() {
6163 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)
;
6164
6165 // Require we are between OnStartRequest and OnStopRequest, because
6166 // what we do here takes effect in OnStopRequest (not reusing the
6167 // connection for next authentication round).
6168 if (!LoadIsPending()) {
6169 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)
;
6170 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"
, 6172); MOZ_PretendNoReturn(); } while (0)
6171 "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"
, 6172); MOZ_PretendNoReturn(); } while (0)
6172 "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"
, 6172); MOZ_PretendNoReturn(); } while (0)
;
6173 return NS_ERROR_UNEXPECTED;
6174 }
6175
6176 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"
, 6176); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mTransaction"
")"); do { *((volatile int*)__null) = 6176; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6177 if (!mTransaction) {
6178 return NS_ERROR_UNEXPECTED;
6179 }
6180
6181 if (!(mCaps & NS_HTTP_STICKY_CONNECTION(1 << 2) ||
6182 mTransaction->HasStickyConnection())) {
6183 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)
;
6184 return NS_OK;
6185 }
6186
6187 mTransaction->DontReuseConnection();
6188 return NS_OK;
6189}
6190
6191NS_IMETHODIMPnsresult nsHttpChannel::ConnectionRestartable(bool aRestartable) {
6192 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)
6193 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)
;
6194 StoreAuthConnectionRestartable(aRestartable);
6195 return NS_OK;
6196}
6197
6198//-----------------------------------------------------------------------------
6199// nsHttpChannel::nsISupports
6200//-----------------------------------------------------------------------------
6201
6202NS_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; }
6203NS_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; }
6204
6205NS_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"
, 6205); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
6206 NS_INTERFACE_MAP_ENTRY(nsIRequest)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequest>)) foundInterface = static_cast
<nsIRequest*>(this); else
6207 NS_INTERFACE_MAP_ENTRY(nsIChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIChannel>)) foundInterface = static_cast
<nsIChannel*>(this); else
6208 NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequestObserver>)) foundInterface
= static_cast<nsIRequestObserver*>(this); else
6209 NS_INTERFACE_MAP_ENTRY(nsIStreamListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIStreamListener>)) foundInterface
= static_cast<nsIStreamListener*>(this); else
6210 NS_INTERFACE_MAP_ENTRY(nsIHttpChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIHttpChannel>)) foundInterface =
static_cast<nsIHttpChannel*>(this); else
6211 NS_INTERFACE_MAP_ENTRY(nsICacheInfoChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICacheInfoChannel>)) foundInterface
= static_cast<nsICacheInfoChannel*>(this); else
6212 NS_INTERFACE_MAP_ENTRY(nsICachingChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICachingChannel>)) foundInterface
= static_cast<nsICachingChannel*>(this); else
6213 NS_INTERFACE_MAP_ENTRY(nsIClassOfService)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIClassOfService>)) foundInterface
= static_cast<nsIClassOfService*>(this); else
6214 NS_INTERFACE_MAP_ENTRY(nsIUploadChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIUploadChannel>)) foundInterface
= static_cast<nsIUploadChannel*>(this); else
6215 NS_INTERFACE_MAP_ENTRY(nsIFormPOSTActionChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIFormPOSTActionChannel>)) foundInterface
= static_cast<nsIFormPOSTActionChannel*>(this); else
6216 NS_INTERFACE_MAP_ENTRY(nsIUploadChannel2)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIUploadChannel2>)) foundInterface
= static_cast<nsIUploadChannel2*>(this); else
6217 NS_INTERFACE_MAP_ENTRY(nsICacheEntryOpenCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICacheEntryOpenCallback>)) foundInterface
= static_cast<nsICacheEntryOpenCallback*>(this); else
6218 NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIHttpChannelInternal>)) foundInterface
= static_cast<nsIHttpChannelInternal*>(this); else
6219 NS_INTERFACE_MAP_ENTRY(nsIResumableChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIResumableChannel>)) foundInterface
= static_cast<nsIResumableChannel*>(this); else
6220 NS_INTERFACE_MAP_ENTRY(nsITransportEventSink)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsITransportEventSink>)) foundInterface
= static_cast<nsITransportEventSink*>(this); else
6221 NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsPriority>)) foundInterface
= static_cast<nsISupportsPriority*>(this); else
6222 NS_INTERFACE_MAP_ENTRY(nsIProtocolProxyCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIProtocolProxyCallback>)) foundInterface
= static_cast<nsIProtocolProxyCallback*>(this); else
6223 NS_INTERFACE_MAP_ENTRY(nsIProxiedChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIProxiedChannel>)) foundInterface
= static_cast<nsIProxiedChannel*>(this); else
6224 NS_INTERFACE_MAP_ENTRY(nsIHttpAuthenticableChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIHttpAuthenticableChannel>)) foundInterface
= static_cast<nsIHttpAuthenticableChannel*>(this); else
6225 NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIAsyncVerifyRedirectCallback>))
foundInterface = static_cast<nsIAsyncVerifyRedirectCallback
*>(this); else
6226 NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableRequest)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIThreadRetargetableRequest>)) foundInterface
= static_cast<nsIThreadRetargetableRequest*>(this); else
6227 NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIThreadRetargetableStreamListener>
)) foundInterface = static_cast<nsIThreadRetargetableStreamListener
*>(this); else
6228 NS_INTERFACE_MAP_ENTRY(nsIDNSListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIDNSListener>)) foundInterface =
static_cast<nsIDNSListener*>(this); else
6229 NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsWeakReference>)) foundInterface
= static_cast<nsISupportsWeakReference*>(this); else
6230 NS_INTERFACE_MAP_ENTRY(nsICorsPreflightCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsICorsPreflightCallback>)) foundInterface
= static_cast<nsICorsPreflightCallback*>(this); else
6231 NS_INTERFACE_MAP_ENTRY(nsIRaceCacheWithNetwork)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRaceCacheWithNetwork>)) foundInterface
= static_cast<nsIRaceCacheWithNetwork*>(this); else
6232 NS_INTERFACE_MAP_ENTRY(nsIRequestTailUnblockCallback)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequestTailUnblockCallback>)) foundInterface
= static_cast<nsIRequestTailUnblockCallback*>(this); else
6233 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
6234 NS_INTERFACE_MAP_ENTRY(nsIEarlyHintObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIEarlyHintObserver>)) foundInterface
= static_cast<nsIEarlyHintObserver*>(this); else
6235NS_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; }
6236
6237//-----------------------------------------------------------------------------
6238// nsHttpChannel::nsIRequest
6239//-----------------------------------------------------------------------------
6240
6241NS_IMETHODIMPnsresult nsHttpChannel::SetCanceledReason(const nsACString& aReason) {
6242 return SetCanceledReasonImpl(aReason);
6243}
6244
6245NS_IMETHODIMPnsresult nsHttpChannel::GetCanceledReason(nsACString& aReason) {
6246 return GetCanceledReasonImpl(aReason);
6247}
6248
6249NS_IMETHODIMPnsresult
6250nsHttpChannel::CancelWithReason(nsresult aStatus, const nsACString& aReason) {
6251 return CancelWithReasonImpl(aStatus, aReason);
6252}
6253
6254NS_IMETHODIMPnsresult
6255nsHttpChannel::Cancel(nsresult status) {
6256 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"
, 6256); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 6256; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6257 // We should never have a pump open while a CORS preflight is in progress.
6258 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"
, 6258); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCachePump"
")"); do { *((volatile int*)__null) = 6258; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6259#ifdef DEBUG1
6260 // We want to perform this check only when the chanel is being cancelled the
6261 // first time with a URL classifier blocking error code. If mStatus is
6262 // already set to such an error code then Cancel() may be called for some
6263 // other reason, for example because we've received notification about our
6264 // parent process side channel being canceled, in which case we cannot expect
6265 // that CancelByURLClassifier() would have handled this case.
6266 if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status) &&
6267 !UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(mStatus)) {
6268 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"
, 6270, MOZ_CrashPrintf("" "Blocking classifier error %" "x" " need to be handled by CancelByURLClassifier()"
, static_cast<uint32_t>(status))); } while (false)
6269 " 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"
, 6270, MOZ_CrashPrintf("" "Blocking classifier error %" "x" " need to be handled by CancelByURLClassifier()"
, static_cast<uint32_t>(status))); } while (false)
6270 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"
, 6270, MOZ_CrashPrintf("" "Blocking classifier error %" "x" " need to be handled by CancelByURLClassifier()"
, static_cast<uint32_t>(status))); } while (false)
;
6271 }
6272#endif
6273
6274 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)
6275 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)
;
6276 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"
, 6278); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!AllowedErrorForHTTPSRRFallback(status)"
")"); do { *((volatile int*)__null) = 6278; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
6277 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"
, 6278); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!AllowedErrorForHTTPSRRFallback(status)"
")"); do { *((volatile int*)__null) = 6278; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
6278 !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"
, 6278); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!AllowedErrorForHTTPSRRFallback(status)"
")"); do { *((volatile int*)__null) = 6278; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6279
6280 mEarlyHintObserver = nullptr;
6281 mWebTransportSessionEventListener = nullptr;
6282
6283 if (mCanceled) {
6284 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)
;
6285 return NS_OK;
6286 }
6287
6288 LogCallingScriptLocation(this);
6289
6290 if (LoadWaitingForRedirectCallback()) {
6291 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)
;
6292 }
6293
6294 return CancelInternal(status);
6295}
6296
6297NS_IMETHODIMPnsresult
6298nsHttpChannel::CancelByURLClassifier(nsresult aErrorCode) {
6299 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"
, 6300); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6300; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6300 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"
, 6300); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6300; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6301 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"
, 6301); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 6301; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6302 // We should never have a pump open while a CORS preflight is in progress.
6303 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"
, 6303); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCachePump"
")"); do { *((volatile int*)__null) = 6303; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6304
6305 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)
;
6306
6307 if (mCanceled) {
6308 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)
;
6309 return NS_OK;
6310 }
6311
6312 // We are being canceled by the channel classifier because of tracking
6313 // protection, but we haven't yet had a chance to dispatch the
6314 // "http-on-modify-request" notifications yet (this would normally be
6315 // done in PrepareToConnect()). So do that now, before proceeding to
6316 // cancel.
6317 //
6318 // Note that running these observers can itself result in the channel
6319 // being canceled. In that case, we accept that cancelation code as
6320 // the cause of the cancelation, as if the classification of the channel
6321 // would have occurred past this point!
6322
6323 // notify "http-on-modify-request" observers
6324 CallOnModifyRequestObservers();
6325
6326 // Check if request was cancelled during on-modify-request
6327 if (mCanceled) {
6328 return mStatus;
6329 }
6330
6331 if (mSuspendCount) {
6332 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)
;
6333 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"
, 6333); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
")"); do { *((volatile int*)__null) = 6333; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6334 StoreChannelClassifierCancellationPending(1);
6335 mCallOnResume = [aErrorCode](nsHttpChannel* self) {
6336 self->HandleContinueCancellingByURLClassifier(aErrorCode);
6337 return NS_OK;
6338 };
6339 return NS_OK;
6340 }
6341
6342 // Check to see if we should redirect this channel elsewhere by
6343 // nsIHttpChannel.redirectTo API request
6344 if (mAPIRedirectTo) {
6345 StoreChannelClassifierCancellationPending(1);
6346 return AsyncCall(&nsHttpChannel::HandleAsyncAPIRedirect);
6347 }
6348
6349 return CancelInternal(aErrorCode);
6350}
6351
6352void nsHttpChannel::ContinueCancellingByURLClassifier(nsresult aErrorCode) {
6353 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"
, 6354); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6354; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6354 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"
, 6354); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6354; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6355 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"
, 6355); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 6355; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6356 // We should never have a pump open while a CORS preflight is in progress.
6357 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"
, 6357); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCachePump"
")"); do { *((volatile int*)__null) = 6357; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6358
6359 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)
;
6360 if (mCanceled) {
6361 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)
;
6362 return;
6363 }
6364
6365 // Check to see if we should redirect this channel elsewhere by
6366 // nsIHttpChannel.redirectTo API request
6367 if (mAPIRedirectTo) {
6368 Unused << AsyncCall(&nsHttpChannel::HandleAsyncAPIRedirect);
6369 return;
6370 }
6371
6372 Unused << CancelInternal(aErrorCode);
6373}
6374
6375nsresult nsHttpChannel::CancelInternal(nsresult status) {
6376 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)
;
6377 bool channelClassifierCancellationPending =
6378 !!LoadChannelClassifierCancellationPending();
6379 if (UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(status)) {
6380 StoreChannelClassifierCancellationPending(0);
6381 }
6382
6383 mEarlyHintObserver = nullptr;
6384 mWebTransportSessionEventListener = nullptr;
6385 mCanceled = true;
6386 mStatus = NS_FAILED(status)((bool)(__builtin_expect(!!(NS_FAILED_impl(status)), 0))) ? status : NS_ERROR_ABORT;
6387
6388 if (StaticPrefs::network_http_network_error_logging_enabled() &&
6389 LoadUsedNetwork() && !mReportedNEL) {
6390 if (nsCOMPtr<nsINetworkErrorLogging> nel =
6391 components::NetworkErrorLogging::Service()) {
6392 nel->GenerateNELReport(this);
6393 }
6394 mReportedNEL = true;
6395 }
6396
6397 // We don't want the content process to see any header values
6398 // when the request is blocked by ORB
6399 if (mChannelBlockedByOpaqueResponse && mCachedOpaqueResponseBlockingPref) {
6400 mResponseHead->ClearHeaders();
6401 }
6402
6403 if (mLastStatusReported && !mEndMarkerAdded &&
6404 profiler_thread_is_being_profiled_for_markers()) {
6405 // These do allocations/frees/etc; avoid if not active
6406 // mLastStatusReported can be null if Cancel is called before we added the
6407 // start marker.
6408 mEndMarkerAdded = true;
6409
6410 nsAutoCString requestMethod;
6411 GetRequestMethod(requestMethod);
6412
6413 int32_t priority = PRIORITY_NORMAL;
6414 GetPriority(&priority);
6415
6416 uint64_t size = 0;
6417 GetEncodedBodySize(&size);
6418
6419 profiler_add_network_marker(
6420 mURI, requestMethod, priority, mChannelId, NetworkLoadType::LOAD_CANCEL,
6421 mLastStatusReported, TimeStamp::Now(), size, mCacheDisposition,
6422 mLoadInfo->GetInnerWindowID(),
6423 mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(),
6424 mClassOfService.Flags(), &mTransactionTimings, std::move(mSource));
6425 }
6426
6427 // If we don't have mTransactionPump and mCachePump, we need to call
6428 // AsyncAbort to make sure this channel's listener got notified.
6429 bool needAsyncAbort = !mTransactionPump && !mCachePump;
6430
6431 if (mProxyRequest) mProxyRequest->Cancel(status);
6432 CancelNetworkRequest(status);
6433 mCacheInputStream.CloseAndRelease();
6434 if (mCachePump) mCachePump->Cancel(status);
6435 if (mAuthProvider) mAuthProvider->Cancel(status);
6436 if (mPreflightChannel) mPreflightChannel->Cancel(status);
6437 if (mRequestContext && mOnTailUnblock) {
6438 mOnTailUnblock = nullptr;
6439 mRequestContext->CancelTailedRequest(this);
6440 CloseCacheEntry(false);
6441 needAsyncAbort = false;
6442 Unused << AsyncAbort(status);
6443 } else if (channelClassifierCancellationPending) {
6444 // If mCallOnResume is not null here, it's set in
6445 // nsHttpChannel::CancelByURLClassifier. We can override mCallOnResume since
6446 // mCanceled is true and nsHttpChannel::ContinueCancellingByURLClassifier
6447 // does nothing.
6448 if (mCallOnResume) {
6449 mCallOnResume = nullptr;
6450 }
6451 // If we're coming from an asynchronous path when canceling a channel due
6452 // to safe-browsing protection, we need to AsyncAbort the channel now.
6453 needAsyncAbort = false;
6454 Unused << AsyncAbort(status);
6455 }
6456
6457 // If we already have mCallOnResume, AsyncAbort will be called in
6458 // ResumeInternal.
6459 if (needAsyncAbort && !mCallOnResume && !mSuspendCount) {
6460 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)
;
6461 CloseCacheEntry(false);
6462 Unused << AsyncAbort(status);
6463 }
6464 return NS_OK;
6465}
6466
6467void nsHttpChannel::CancelNetworkRequest(nsresult aStatus) {
6468 if (mTransaction) {
6469 nsresult rv = gHttpHandler->CancelTransaction(mTransaction, aStatus);
6470 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6471 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)
;
6472 }
6473 }
6474 if (mTransactionPump) mTransactionPump->Cancel(aStatus);
6475
6476 mEarlyHintObserver = nullptr;
6477 mWebTransportSessionEventListener = nullptr;
6478}
6479
6480NS_IMETHODIMPnsresult
6481nsHttpChannel::Suspend() {
6482 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"
, 6482); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
6483
6484 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)
;
6485 LogCallingScriptLocation(this);
6486
6487 ++mSuspendCount;
6488
6489 if (mSuspendCount == 1) {
6490 mSuspendTimestamp = TimeStamp::NowLoRes();
6491 }
6492
6493 nsresult rvTransaction = NS_OK;
6494 if (mTransactionPump) {
6495 rvTransaction = mTransactionPump->Suspend();
6496 }
6497 nsresult rvCache = NS_OK;
6498 if (mCachePump) {
6499 rvCache = mCachePump->Suspend();
6500 }
6501
6502 return NS_FAILED(rvTransaction)((bool)(__builtin_expect(!!(NS_FAILED_impl(rvTransaction)), 0
)))
? rvTransaction : rvCache;
6503}
6504
6505NS_IMETHODIMPnsresult
6506nsHttpChannel::Resume() {
6507 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"
, 6507); return NS_ERROR_UNEXPECTED; } } while (false)
;
6508
6509 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)
;
6510 LogCallingScriptLocation(this);
6511
6512 if (--mSuspendCount == 0) {
6513 mSuspendTotalTime += TimeStamp::NowLoRes() - mSuspendTimestamp;
6514
6515 if (mCallOnResume) {
6516 // Resume the interrupted procedure first, then resume
6517 // the pump to continue process the input stream.
6518 // Any newly created pump MUST be suspended to prevent calling
6519 // its OnStartRequest before OnStopRequest of any pre-existing
6520 // pump. AsyncResumePending ensures that.
6521 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"
, 6521); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadAsyncResumePending()"
")"); do { *((volatile int*)__null) = 6521; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6522 StoreAsyncResumePending(1);
6523
6524 std::function<nsresult(nsHttpChannel*)> callOnResume = nullptr;
6525 std::swap(callOnResume, mCallOnResume);
6526
6527 RefPtr<nsHttpChannel> self(this);
6528 nsCOMPtr<nsIRequest> transactionPump = mTransactionPump;
6529 RefPtr<nsInputStreamPump> cachePump = mCachePump;
6530
6531 nsresult rv = NS_DispatchToCurrentThread(NS_NewRunnableFunction(
6532 "nsHttpChannel::CallOnResume",
6533 [callOnResume{std::move(callOnResume)}, self{std::move(self)},
6534 transactionPump{std::move(transactionPump)},
6535 cachePump{std::move(cachePump)}]() {
6536 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"
, 6536); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->LoadAsyncResumePending()"
")"); do { *((volatile int*)__null) = 6536; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6537 nsresult rv = self->CallOrWaitForResume(callOnResume);
6538 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6539 self->CloseCacheEntry(false);
6540 Unused << self->AsyncAbort(rv);
6541 }
6542 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"
, 6542); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->LoadAsyncResumePending()"
")"); do { *((volatile int*)__null) = 6542; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6543
6544 self->StoreAsyncResumePending(0);
6545
6546 // And now actually resume the previously existing pumps.
6547 if (transactionPump) {
6548 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)
6549 ("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)
6550 "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)
6551 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)
;
6552 transactionPump->Resume();
6553 }
6554 if (cachePump) {
6555 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)
6556 ("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)
6557 "%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)
6558 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)
;
6559 cachePump->Resume();
6560 }
6561
6562 // Any newly created pumps were suspended once because of
6563 // AsyncResumePending. Problem is that the stream listener
6564 // notification is already pending in the queue right now, because
6565 // AsyncRead doesn't (regardless if called after Suspend) respect
6566 // the suspend coutner and the right order would not be preserved.
6567 // Hence, we do another dispatch round to actually Resume after
6568 // the notification from the original pump.
6569 if (transactionPump != self->mTransactionPump &&
6570 self->mTransactionPump) {
6571 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)
6572 ("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)
6573 "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)
6574 "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)
6575 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)
;
6576
6577 nsCOMPtr<nsIRequest> pump = self->mTransactionPump;
6578 NS_DispatchToCurrentThread(NS_NewRunnableFunction(
6579 "nsHttpChannel::CallOnResume new transaction",
6580 [pump{std::move(pump)}]() { pump->Resume(); }));
6581 }
6582 if (cachePump != self->mCachePump && self->mCachePump) {
6583 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)
6584 ("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)
6585 "%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)
6586 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)
;
6587
6588 RefPtr<nsInputStreamPump> pump = self->mCachePump;
6589 NS_DispatchToCurrentThread(NS_NewRunnableFunction(
6590 "nsHttpChannel::CallOnResume new pump",
6591 [pump{std::move(pump)}]() { pump->Resume(); }));
6592 }
6593 }));
6594 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"
, 6594); return rv; } } while (false)
;
6595 return rv;
6596 }
6597 }
6598
6599 nsresult rvTransaction = NS_OK;
6600 if (mTransactionPump) {
6601 rvTransaction = mTransactionPump->Resume();
6602 }
6603
6604 nsresult rvCache = NS_OK;
6605 if (mCachePump) {
6606 rvCache = mCachePump->Resume();
6607 }
6608
6609 return NS_FAILED(rvTransaction)((bool)(__builtin_expect(!!(NS_FAILED_impl(rvTransaction)), 0
)))
? rvTransaction : rvCache;
6610}
6611
6612//-----------------------------------------------------------------------------
6613// nsHttpChannel::nsIChannel
6614//-----------------------------------------------------------------------------
6615
6616NS_IMETHODIMPnsresult
6617nsHttpChannel::GetSecurityInfo(nsITransportSecurityInfo** securityInfo) {
6618 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"
, 6618); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6619 *securityInfo = do_AddRef(mSecurityInfo).take();
6620 return NS_OK;
6621}
6622
6623// If any of the functions that AsyncOpen calls returns immediately an error
6624// AsyncAbort(which calls onStart/onStopRequest) does not need to be call.
6625// To be sure that they are not call ReleaseListeners() is called.
6626// If AsyncOpen returns NS_OK, after that point AsyncAbort must be called on
6627// any error.
6628NS_IMETHODIMPnsresult
6629nsHttpChannel::AsyncOpen(nsIStreamListener* aListener) {
6630 nsCOMPtr<nsIStreamListener> listener = aListener;
6631 nsresult rv =
6632 nsContentSecurityManager::doContentSecurityCheck(this, listener);
6633 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"
, 6633)
) {
6634 ReleaseListeners();
6635 return rv;
6636 }
6637
6638 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"
, 6645); 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) = 6645; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6639 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"
, 6645); 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) = 6645; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6640 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"
, 6645); 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) = 6645; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6641 (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"
, 6645); 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) = 6645; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6642 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"
, 6645); 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) = 6645; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6643 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"
, 6645); 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) = 6645; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6644 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"
, 6645); 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) = 6645; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6645 "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"
, 6645); 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) = 6645; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6646
6647 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
)
;
6648 mOpenerCallingScriptLocation = CallingScriptLocationString();
6649 LogCallingScriptLocation(this, mOpenerCallingScriptLocation);
6650 NS_CompareLoadInfoAndLoadContext(this);
6651
6652#ifdef DEBUG1
6653 AssertPrivateBrowsingId();
6654#endif
6655
6656 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"
, 6656); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6657 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"
, 6657); return NS_ERROR_IN_PROGRESS; } } while (false)
;
6658 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"
, 6658); return NS_ERROR_ALREADY_OPENED; } } while (false)
;
6659
6660 if (mCanceled) {
6661 ReleaseListeners();
6662 return NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0))) ? mStatus : NS_ERROR_FAILURE;
6663 }
6664
6665 if (MaybeWaitForUploadStreamNormalization(listener, nullptr)) {
6666 return NS_OK;
6667 }
6668
6669 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"
, 6669); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 6669; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6670
6671 if (!gHttpHandler->Active()) {
6672 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)
;
6673 ReleaseListeners();
6674 return NS_ERROR_NOT_AVAILABLE;
6675 }
6676
6677 rv = NS_CheckPortSafety(mURI);
6678 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6679 ReleaseListeners();
6680 return rv;
6681 }
6682
6683 // If no one called SetLoadGroup or SetNotificationCallbacks, the private
6684 // state has not been updated on PrivateBrowsingChannel (which we derive
6685 // from) Same if the loadinfo has changed since the creation of the channel.
6686 // Hence, we have to call UpdatePrivateBrowsing() here
6687 UpdatePrivateBrowsing();
6688
6689 AntiTrackingUtils::UpdateAntiTrackingInfoForChannel(this);
6690
6691 // Recalculate the default userAgent header after the AntiTrackingInfo gets
6692 // updated because we can only know whether the site is exempted from
6693 // fingerprinting protection after we have the AntiTracking Info.
6694 //
6695 // Note that we don't recalculate the header if it has been modified since the
6696 // channel was created because we want to preserve the modified header.
6697 if (!LoadIsUserAgentHeaderModified()) {
6698 rv = mRequestHead.SetHeader(
6699 nsHttp::User_Agent,
6700 gHttpHandler->UserAgent(nsContentUtils::ShouldResistFingerprinting(
6701 this, RFPTarget::HttpUserAgent)),
6702 false, nsHttpHeaderArray::eVarietyRequestEnforceDefault);
6703 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"
, 6703); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 6703; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6704 }
6705
6706 if (WaitingForTailUnblock()) {
6707 // This channel is marked as Tail and is part of a request context
6708 // that has positive number of non-tailed requestst, hence this channel
6709 // has been put to a queue.
6710 // When tail is unblocked, OnTailUnblock on this channel will be called
6711 // to continue AsyncOpen.
6712 mListener = listener;
6713 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"
, 6713); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mOnTailUnblock"
")"); do { *((volatile int*)__null) = 6713; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6714 mOnTailUnblock = &nsHttpChannel::AsyncOpenOnTailUnblock;
6715
6716 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)
;
6717 return NS_OK;
6718 }
6719
6720 // Remember the cookie header that was set, if any
6721 nsAutoCString cookieHeader;
6722 if (NS_SUCCEEDED(mRequestHead.GetHeader(nsHttp::Cookie, cookieHeader))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mRequestHead.GetHeader
(nsHttp::Cookie, cookieHeader))), 1)))
) {
6723 mUserSetCookieHeader = cookieHeader;
6724 }
6725
6726 // Set user agent override, do so before OnOpeningRequest notification
6727 // since we want to allow consumers of that notification change or remove
6728 // the User-Agent request header.
6729 HttpBaseChannel::SetDocshellUserAgentOverride();
6730
6731 // After we notify any observers (on-opening-request, loadGroup, etc) we
6732 // must return NS_OK and return any errors asynchronously via
6733 // OnStart/OnStopRequest. Observers may add a reference to the channel
6734 // and expect to get OnStopRequest so they know when to drop the reference,
6735 // etc.
6736
6737 // notify "http-on-opening-request" observers, but not if this is a redirect
6738 if (!(mLoadFlags & LOAD_REPLACE)) {
6739 gHttpHandler->OnOpeningRequest(this);
6740 }
6741
6742 StoreIsPending(true);
6743 StoreWasOpened(true);
6744
6745 mListener = listener;
6746
6747 if (nsIOService::UseSocketProcess() &&
6748 !gIOService->IsSocketProcessLaunchComplete()) {
6749 RefPtr<nsHttpChannel> self = this;
6750 gIOService->CallOrWaitForSocketProcess(
6751 [self]() { self->AsyncOpenFinal(TimeStamp::Now()); });
6752 return NS_OK;
6753 }
6754
6755 AsyncOpenFinal(TimeStamp::Now());
6756
6757 return NS_OK;
6758}
6759
6760void nsHttpChannel::AsyncOpenFinal(TimeStamp aTimeStamp) {
6761 // We save this timestamp from outside of the if block in case we enable the
6762 // profiler after AsyncOpen().
6763 mLastStatusReported = TimeStamp::Now();
6764 if (profiler_thread_is_being_profiled_for_markers()) {
6765 nsAutoCString requestMethod;
6766 GetRequestMethod(requestMethod);
6767
6768 profiler_add_network_marker(
6769 mURI, requestMethod, mPriority, mChannelId, NetworkLoadType::LOAD_START,
6770 mChannelCreationTimestamp, mLastStatusReported, 0, mCacheDisposition,
6771 mLoadInfo->GetInnerWindowID(),
6772 mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(),
6773 mClassOfService.Flags());
6774 }
6775
6776 // Added due to PauseTask/DelayHttpChannel
6777 if (mLoadGroup) mLoadGroup->AddRequest(this, nullptr);
6778
6779 // record asyncopen time unconditionally and clear it if we
6780 // don't want it after OnModifyRequest() weighs in. But waiting for
6781 // that to complete would mean we don't include proxy resolution in the
6782 // timing.
6783 if (!LoadAsyncOpenTimeOverriden()) {
6784 mAsyncOpenTime = aTimeStamp;
6785 }
6786
6787 // Remember we have Authorization header set here. We need to check on it
6788 // just once and early, AsyncOpen is the best place.
6789 StoreCustomAuthHeader(mRequestHead.HasHeader(nsHttp::Authorization));
6790
6791 bool willCallback = false;
6792 // We are about to do an async lookup to check if the URI is a tracker. If
6793 // yes, this channel will be canceled by channel classifier. Chances are the
6794 // lookup is not needed so CheckIsTrackerWithLocalTable() will return an
6795 // error and then we can MaybeResolveProxyAndBeginConnect() right away.
6796 // We skip the check in case this is an internal redirected channel
6797 if (!LoadAuthRedirectedChannel() && NS_ShouldClassifyChannel(this)) {
6798 RefPtr<nsHttpChannel> self = this;
6799 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"
, 6803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6803; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6800 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"
, 6803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6803; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6801 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"
, 6803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6803; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6802 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"
, 6803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6803; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6803 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"
, 6803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6803; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6804
6805 // 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"
, 6803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6803; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6806 // 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"
, 6803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6803; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6807 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"
, 6803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6803; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6808
6809 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"
, 6803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6803; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
6810 }))((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"
, 6803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "uri" ")"); do
{ *((volatile int*)__null) = 6803; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false); FinishAntiTrackingRedirectHeuristic
(self, uri); self->MaybeResolveProxyAndBeginConnect(); }))
), 1)))
;
6811 }
6812
6813 if (!willCallback) {
6814 // We can do MaybeResolveProxyAndBeginConnect immediately if
6815 // CheckIsTrackerWithLocalTable is failed. Note that we don't need to
6816 // handle the failure because BeginConnect() will return synchronously and
6817 // the caller will be responsible for handling it.
6818 MaybeResolveProxyAndBeginConnect();
6819 }
6820}
6821
6822void nsHttpChannel::MaybeResolveProxyAndBeginConnect() {
6823 nsresult rv;
6824
6825 // The common case for HTTP channels is to begin proxy resolution and return
6826 // at this point. The only time we know mProxyInfo already is if we're
6827 // proxying a non-http protocol like ftp. We don't need to discover proxy
6828 // settings if we are never going to make a network connection.
6829 if (!mProxyInfo &&
6830 !(mLoadFlags & (LOAD_ONLY_FROM_CACHE | LOAD_NO_NETWORK_IO)) &&
6831 !BypassProxy() && NS_SUCCEEDED(ResolveProxy())((bool)(__builtin_expect(!!(!NS_FAILED_impl(ResolveProxy())),
1)))
) {
6832 return;
6833 }
6834
6835 if (!gHttpHandler->Active()) {
6836 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)
6837 ("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)
6838 "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)
6839 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)
;
6840 rv = NS_ERROR_NOT_AVAILABLE;
6841 } else {
6842 rv = BeginConnect();
6843 }
6844 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6845 CloseCacheEntry(false);
6846 Unused << AsyncAbort(rv);
6847 }
6848}
6849
6850nsresult nsHttpChannel::AsyncOpenOnTailUnblock() {
6851 return AsyncOpen(mListener);
6852}
6853
6854already_AddRefed<nsChannelClassifier>
6855nsHttpChannel::GetOrCreateChannelClassifier() {
6856 if (!mChannelClassifier) {
6857 mChannelClassifier = new nsChannelClassifier(this);
6858 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)
6859 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)
;
6860 }
6861
6862 RefPtr<nsChannelClassifier> classifier = mChannelClassifier;
6863 return classifier.forget();
6864}
6865
6866ProxyDNSStrategy nsHttpChannel::GetProxyDNSStrategy() {
6867 // When network_dns_force_use_https_rr is true, return DNS_PREFETCH_ORIGIN.
6868 // This ensures that we always perform HTTPS RR query.
6869 nsCOMPtr<nsProxyInfo> proxyInfo(static_cast<nsProxyInfo*>(mProxyInfo.get()));
6870 if (!proxyInfo || StaticPrefs::network_dns_force_use_https_rr()) {
6871 return ProxyDNSStrategy::ORIGIN;
6872 }
6873
6874 // If the proxy is not to perform name resolution itself.
6875 return GetProxyDNSStrategyHelper(proxyInfo->Type(), proxyInfo->Flags());
6876}
6877
6878// BeginConnect() SHOULD NOT call AsyncAbort(). AsyncAbort will be called by
6879// functions that called BeginConnect if needed. Only
6880// MaybeResolveProxyAndBeginConnect and OnProxyAvailable ever call
6881// BeginConnect.
6882nsresult nsHttpChannel::BeginConnect() {
6883 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)
;
6884 nsresult rv;
6885
6886 // It is the caller's responsibility to not call us late in shutdown.
6887 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"
, 6887); AnnotateMozCrashReason("MOZ_ASSERT" "(" "gHttpHandler->Active()"
")"); do { *((volatile int*)__null) = 6887; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6888
6889 // Construct connection info object
6890 nsAutoCString host;
6891 nsAutoCString scheme;
6892 int32_t port = -1;
6893 bool isHttps = mURI->SchemeIs("https");
6894
6895 rv = mURI->GetScheme(scheme);
6896 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = mURI->GetAsciiHost(host);
6897 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = mURI->GetPort(&port);
6898 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) rv = mURI->GetAsciiSpec(mSpec);
6899 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6900 return rv;
6901 }
6902
6903 // Just a warning here because some nsIURIs do not implement this method.
6904 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"
, 6904)
;
6905
6906 // Reject the URL if it doesn't specify a host
6907 if (host.IsEmpty()) {
6908 rv = NS_ERROR_MALFORMED_URI;
6909 return rv;
6910 }
6911 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)
;
6912 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)
;
6913
6914 nsCOMPtr<nsProxyInfo> proxyInfo;
6915 if (mProxyInfo) proxyInfo = do_QueryInterface(mProxyInfo);
6916
6917 if (mCaps & NS_HTTP_CONNECT_ONLY(1 << 16)) {
6918 if (!proxyInfo) {
6919 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)
;
6920 return NS_ERROR_FAILURE;
6921 }
6922
6923 if (!proxyInfo->IsHTTP() && !proxyInfo->IsHTTPS()) {
6924 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)
;
6925 return NS_ERROR_FAILURE;
6926 }
6927 }
6928
6929 mRequestHead.SetHTTPS(isHttps);
6930 mRequestHead.SetOrigin(scheme, host, port);
6931
6932 SetOriginHeader();
6933 SetDoNotTrack();
6934 SetGlobalPrivacyControl();
6935
6936 OriginAttributes originAttributes;
6937 // Regular principal in case we have a proxy.
6938 if (proxyInfo &&
6939 !StaticPrefs::privacy_partition_network_state_connection_with_proxy()) {
6940 StoragePrincipalHelper::GetOriginAttributes(
6941 this, originAttributes, StoragePrincipalHelper::eRegularPrincipal);
6942 } else {
6943 StoragePrincipalHelper::GetOriginAttributesForNetworkState(
6944 this, originAttributes);
6945 }
6946
6947 // Adjust mCaps according to our request headers:
6948 // - If "Connection: close" is set as a request header, then do not bother
6949 // trying to establish a keep-alive connection.
6950 if (mRequestHead.HasHeaderValue(nsHttp::Connection, "close")) {
6951 mCaps &= ~(NS_HTTP_ALLOW_KEEPALIVE(1 << 0));
6952 StoreAllowHttp3(false);
6953 }
6954
6955 gHttpHandler->MaybeAddAltSvcForTesting(mURI, mUsername, mPrivateBrowsing,
6956 mCallbacks, originAttributes);
6957
6958 RefPtr<nsHttpConnectionInfo> connInfo;
6959#ifdef FUZZING
6960 if (StaticPrefs::fuzzing_necko_http3()) {
6961 connInfo =
6962 new nsHttpConnectionInfo(host, port, "h3"_ns, mUsername, proxyInfo,
6963 originAttributes, host, port, true);
6964 } else {
6965#endif
6966 if (mWebTransportSessionEventListener) {
6967 connInfo =
6968 new nsHttpConnectionInfo(host, port, "h3"_ns, mUsername, proxyInfo,
6969 originAttributes, isHttps, true, true);
6970 bool dedicated = true;
6971 nsresult rv;
6972 nsCOMPtr<WebTransportConnectionSettings> wtconSettings =
6973 do_QueryInterface(mWebTransportSessionEventListener, &rv);
6974 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"
, 6974); return rv; } } while (false)
;
6975 wtconSettings->GetDedicated(&dedicated);
6976 if (dedicated) {
6977 connInfo->SetWebTransportId(
6978 gHttpHandler->ConnMgr()->GenerateNewWebTransportId());
6979 }
6980 } else {
6981 connInfo = new nsHttpConnectionInfo(host, port, ""_ns, mUsername,
6982 proxyInfo, originAttributes, isHttps);
6983 }
6984#ifdef FUZZING
6985 }
6986#endif
6987
6988 bool http2Allowed = !gHttpHandler->IsHttp2Excluded(connInfo);
6989
6990 bool http3Allowed = Http3Allowed();
6991 if (!http3Allowed) {
6992 mCaps |= NS_HTTP_DISALLOW_HTTP3(1 << 21);
6993 }
6994
6995 RefPtr<AltSvcMapping> mapping;
6996 if (!mConnectionInfo && LoadAllowAltSvc() && // per channel
6997 !mWebTransportSessionEventListener && (http2Allowed || http3Allowed) &&
6998 !(mLoadFlags & LOAD_FRESH_CONNECTION) &&
6999 AltSvcMapping::AcceptableProxy(proxyInfo) &&
7000 (scheme.EqualsLiteral("http") || scheme.EqualsLiteral("https")) &&
7001 (mapping = gHttpHandler->GetAltServiceMapping(
7002 scheme, host, port, mPrivateBrowsing, originAttributes, http2Allowed,
7003 http3Allowed))) {
7004 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)
7005 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)
7006 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)
;
7007
7008 if (!(mLoadFlags & LOAD_ANONYMOUS) && !mPrivateBrowsing) {
7009 nsAutoCString altUsedLine(mapping->AlternateHost());
7010 bool defaultPort =
7011 mapping->AlternatePort() ==
7012 (isHttps ? NS_HTTPS_DEFAULT_PORT443 : NS_HTTP_DEFAULT_PORT80);
7013 if (!defaultPort) {
7014 altUsedLine.AppendLiteral(":");
7015 altUsedLine.AppendInt(mapping->AlternatePort());
7016 }
7017 // Like what we did for 'Authorization' header, we need to do the same for
7018 // 'Alt-Used' for avoiding this header being shown in the ServiceWorker
7019 // FetchEvent.
7020 Unused << mRequestHead.ClearHeader(nsHttp::Alternate_Service_Used);
7021 rv = mRequestHead.SetHeader(nsHttp::Alternate_Service_Used, altUsedLine,
7022 false,
7023 nsHttpHeaderArray::eVarietyRequestDefault);
7024 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"
, 7024); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 7024; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7025 }
7026
7027 nsCOMPtr<nsIConsoleService> consoleService;
7028 consoleService = mozilla::components::Console::Service();
7029 if (consoleService && !host.Equals(mapping->AlternateHost())) {
7030 nsAutoString message(u"Alternate Service Mapping found: "_ns);
7031 AppendASCIItoUTF16(scheme, message);
7032 message.AppendLiteral(u"://");
7033 AppendASCIItoUTF16(host, message);
7034 message.AppendLiteral(u":");
7035 message.AppendInt(port);
7036 message.AppendLiteral(u" to ");
7037 AppendASCIItoUTF16(scheme, message);
7038 message.AppendLiteral(u"://");
7039 AppendASCIItoUTF16(mapping->AlternateHost(), message);
7040 message.AppendLiteral(u":");
7041 message.AppendInt(mapping->AlternatePort());
7042 consoleService->LogStringMessage(message.get());
7043 }
7044
7045 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)
;
7046 mapping->GetConnectionInfo(getter_AddRefs(mConnectionInfo), proxyInfo,
7047 originAttributes);
7048 Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC, true);
7049 if (mConnectionInfo->IsHttp3() &&
7050 StaticPrefs::
7051 network_http_http3_force_use_alt_svc_mapping_for_testing()) {
7052 mCaps |= NS_HTTP_DISALLOW_SPDY(1 << 7);
7053 }
7054 } else if (mConnectionInfo) {
7055 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)
;
7056 Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC, false);
7057 } else {
7058 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)
;
7059
7060 mConnectionInfo = connInfo;
7061 Telemetry::Accumulate(Telemetry::HTTP_TRANSACTION_USE_ALTSVC, false);
7062 }
7063
7064 bool trrEnabled = false;
7065 auto dnsStrategy = GetProxyDNSStrategy();
7066 bool httpsRRAllowed =
7067 !LoadBeConservative() && !(mCaps & NS_HTTP_BE_CONSERVATIVE(1 << 11)) &&
7068 !(mLoadInfo->TriggeringPrincipal()->IsSystemPrincipal() &&
7069 mLoadInfo->GetExternalContentPolicyType() !=
7070 ExtContentPolicy::TYPE_DOCUMENT) &&
7071 dnsStrategy == ProxyDNSStrategy::ORIGIN &&
7072 !mConnectionInfo->UsingConnect() && canUseHTTPSRRonNetwork(trrEnabled) &&
7073 StaticPrefs::network_dns_use_https_rr_as_altsvc();
7074 if (!httpsRRAllowed) {
7075 DisallowHTTPSRR(mCaps);
7076 } else if (trrEnabled) {
7077 if (nsIRequest::GetTRRMode() != nsIRequest::TRR_DISABLED_MODE) {
7078 mCaps |= NS_HTTP_FORCE_WAIT_HTTP_RR(1 << 22);
7079 }
7080 }
7081 // No need to lookup HTTPSSVC record if mHTTPSSVCRecord already contains a
7082 // value.
7083 StoreUseHTTPSSVC(StaticPrefs::network_dns_upgrade_with_https_rr() &&
7084 httpsRRAllowed && mHTTPSSVCRecord.isNothing());
7085
7086 // Need to re-ask the handler, since mConnectionInfo may not be the connInfo
7087 // we used earlier
7088 if (!mConnectionInfo->IsHttp3() &&
7089 gHttpHandler->IsHttp2Excluded(mConnectionInfo)) {
7090 StoreAllowSpdy(0);
7091 mCaps |= NS_HTTP_DISALLOW_SPDY(1 << 7);
7092 mConnectionInfo->SetNoSpdy(true);
7093 }
7094
7095 // We can be passed with the auth provider if this channel was
7096 // a result of redirect due to auth retry
7097 if (!mAuthProvider) {
7098 mAuthProvider = new nsHttpChannelAuthProvider();
7099 }
7100
7101 rv = mAuthProvider->Init(this);
7102 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7103 return rv;
7104 }
7105
7106 // check to see if authorization headers should be included
7107 // CustomAuthHeader is set in AsyncOpen if we find Authorization header
7108 rv = mAuthProvider->AddAuthorizationHeaders(LoadCustomAuthHeader());
7109 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7110 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)
7111 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)
;
7112 }
7113
7114 // if this somehow fails we can go on without it
7115 Unused << gHttpHandler->AddConnectionHeader(&mRequestHead, mCaps);
7116
7117 if (!LoadIsTRRServiceChannel() &&
7118 ((mLoadFlags & LOAD_FRESH_CONNECTION) ||
7119 (!StaticPrefs::network_dns_only_refresh_on_fresh_connection() &&
7120 (mLoadFlags & VALIDATE_ALWAYS ||
7121 BYPASS_LOCAL_CACHE(mLoadFlags, LoadPreferCacheLoadOverBypass())((mLoadFlags) & (nsIRequest::LOAD_BYPASS_CACHE | nsICachingChannel
::LOAD_BYPASS_LOCAL_CACHE) && !(((mLoadFlags) & nsIRequest
::LOAD_FROM_CACHE) && (LoadPreferCacheLoadOverBypass(
))))
)))) {
7122 mCaps |= NS_HTTP_REFRESH_DNS(1 << 3);
7123 }
7124
7125 if (gHttpHandler->CriticalRequestPrioritization()) {
7126 if (mClassOfService.Flags() & nsIClassOfService::Leader) {
7127 mCaps |= NS_HTTP_LOAD_AS_BLOCKING(1 << 6);
7128 }
7129 if (mClassOfService.Flags() & nsIClassOfService::Unblocked) {
7130 mCaps |= NS_HTTP_LOAD_UNBLOCKED(1 << 8);
7131 }
7132 if (mClassOfService.Flags() & nsIClassOfService::UrgentStart &&
7133 gHttpHandler->IsUrgentStartEnabled()) {
7134 mCaps |= NS_HTTP_URGENT_START(1 << 12);
7135 SetPriority(nsISupportsPriority::PRIORITY_HIGHEST);
7136 }
7137 }
7138
7139 // Force-Reload should reset the persistent connection pool for this host
7140 if (mLoadFlags & LOAD_FRESH_CONNECTION) {
7141 // just the initial document resets the whole pool
7142 if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
7143 gHttpHandler->AltServiceCache()->ClearAltServiceMappings();
7144 rv = gHttpHandler->DoShiftReloadConnectionCleanupWithConnInfo(
7145 mConnectionInfo);
7146 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7147 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)
7148 "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)
7149 "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)
7150 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)
;
7151 }
7152 }
7153 }
7154
7155 // We may have been cancelled already, either by on-modify-request
7156 // listeners or load group observers; in that case, we should not send the
7157 // request to the server
7158 if (mCanceled) {
7159 return mStatus;
7160 }
7161 // skip classifier checks if this channel was the result of internal auth
7162 // redirect
7163 bool shouldBeClassified =
7164 !LoadAuthRedirectedChannel() && NS_ShouldClassifyChannel(this);
7165
7166 if (shouldBeClassified) {
7167 if (LoadChannelClassifierCancellationPending()) {
7168 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)
7169 ("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)
7170 "[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)
7171 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)
;
7172 return NS_OK;
7173 }
7174
7175 ReEvaluateReferrerAfterTrackingStatusIsKnown();
7176 }
7177
7178 MaybeStartDNSPrefetch();
7179
7180 // Update whether the channel is on the third-party cookie blocking exception
7181 // list.
7182 CookieService::Update3PCBExceptionInfo(this);
7183
7184 rv = CallOrWaitForResume(
7185 [](nsHttpChannel* self) { return self->PrepareToConnect(); });
7186 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7187 return rv;
7188 }
7189
7190 if (shouldBeClassified) {
7191 // Start nsChannelClassifier to catch phishing and malware URIs.
7192 RefPtr<nsChannelClassifier> channelClassifier =
7193 GetOrCreateChannelClassifier();
7194 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)
7195 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)
;
7196 channelClassifier->Start();
7197 }
7198
7199 return NS_OK;
7200}
7201
7202void nsHttpChannel::MaybeStartDNSPrefetch() {
7203 // Start a DNS lookup very early in case the real open is queued the DNS can
7204 // happen in parallel. Do not do so in the presence of an HTTP proxy as
7205 // all lookups other than for the proxy itself are done by the proxy.
7206 // Also we don't do a lookup if the LOAD_NO_NETWORK_IO or
7207 // LOAD_ONLY_FROM_CACHE flags are set.
7208 //
7209 // We keep the DNS prefetch object around so that we can retrieve
7210 // timing information from it. There is no guarantee that we actually
7211 // use the DNS prefetch data for the real connection, but as we keep
7212 // this data around for 3 minutes by default, this should almost always
7213 // be correct, and even when it isn't, the timing still represents _a_
7214 // valid DNS lookup timing for the site, even if it is not _the_
7215 // timing we used.
7216 if ((mLoadFlags & (LOAD_NO_NETWORK_IO | LOAD_ONLY_FROM_CACHE)) ||
7217 LoadAuthRedirectedChannel()) {
7218 return;
7219 }
7220
7221 auto dnsStrategy = GetProxyDNSStrategy();
7222
7223 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, static_cast<uint32_t>(dnsStrategy
), mCaps & (1 << 3) ? ", refresh requested" : ""); }
} while (0)
7224 ("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, static_cast<uint32_t>(dnsStrategy
), mCaps & (1 << 3) ? ", refresh requested" : ""); }
} while (0)
7225 "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, static_cast<uint32_t>(dnsStrategy
), mCaps & (1 << 3) ? ", refresh requested" : ""); }
} while (0)
7226 this, static_cast<uint32_t>(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, static_cast<uint32_t>(dnsStrategy
), mCaps & (1 << 3) ? ", refresh requested" : ""); }
} while (0)
7227 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, static_cast<uint32_t>(dnsStrategy
), mCaps & (1 << 3) ? ", refresh requested" : ""); }
} while (0)
;
7228
7229 if (dnsStrategy == ProxyDNSStrategy::ORIGIN) {
7230 OriginAttributes originAttributes;
7231 StoragePrincipalHelper::GetOriginAttributesForNetworkState(
7232 this, originAttributes);
7233
7234 mDNSPrefetch = new nsDNSPrefetch(mURI, originAttributes,
7235 nsIRequest::GetTRRMode(), this, true);
7236 nsIDNSService::DNSFlags dnsFlags = nsIDNSService::RESOLVE_DEFAULT_FLAGS;
7237 if (mCaps & NS_HTTP_REFRESH_DNS(1 << 3)) {
7238 dnsFlags |= nsIDNSService::RESOLVE_BYPASS_CACHE;
7239 }
7240
7241 Unused << mDNSPrefetch->PrefetchHigh(dnsFlags);
7242
7243 bool unused;
7244 if (StaticPrefs::network_dns_use_https_rr_as_altsvc() && !mHTTPSSVCRecord &&
7245 !(mCaps & NS_HTTP_DISALLOW_HTTPS_RR(1 << 24)) &&
7246 canUseHTTPSRRonNetwork(unused)) {
7247 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"
, 7247); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mHTTPSSVCRecord"
")"); do { *((volatile int*)__null) = 7247; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7248
7249 OriginAttributes originAttributes;
7250 StoragePrincipalHelper::GetOriginAttributesForHTTPSRR(this,
7251 originAttributes);
7252
7253 RefPtr<nsDNSPrefetch> resolver =
7254 new nsDNSPrefetch(mURI, originAttributes, nsIRequest::GetTRRMode());
7255 Unused << resolver->FetchHTTPSSVC(mCaps & NS_HTTP_REFRESH_DNS(1 << 3), true,
7256 [](nsIDNSHTTPSSVCRecord*) {
7257 // Do nothing. This is a DNS prefetch.
7258 });
7259 }
7260 }
7261}
7262
7263NS_IMETHODIMPnsresult
7264nsHttpChannel::GetEncodedBodySize(uint64_t* aEncodedBodySize) {
7265 if (mCacheEntry && !LoadCacheEntryIsWriteOnly()) {
7266 int64_t dataSize = 0;
7267 mCacheEntry->GetDataSize(&dataSize);
7268 *aEncodedBodySize = dataSize;
7269 } else {
7270 *aEncodedBodySize = mLogicalOffset;
7271 }
7272 return NS_OK;
7273}
7274
7275//-----------------------------------------------------------------------------
7276// nsHttpChannel::nsIHttpChannelInternal
7277//-----------------------------------------------------------------------------
7278
7279NS_IMETHODIMPnsresult
7280nsHttpChannel::GetIsAuthChannel(bool* aIsAuthChannel) {
7281 *aIsAuthChannel = mIsAuthChannel;
7282 return NS_OK;
7283}
7284
7285NS_IMETHODIMPnsresult
7286nsHttpChannel::SetChannelIsForDownload(bool aChannelIsForDownload) {
7287 if (aChannelIsForDownload) {
7288 AddClassFlags(nsIClassOfService::Throttleable);
7289 } else {
7290 ClearClassFlags(nsIClassOfService::Throttleable);
7291 }
7292
7293 return HttpBaseChannel::SetChannelIsForDownload(aChannelIsForDownload);
7294}
7295
7296base::ProcessId nsHttpChannel::ProcessId() {
7297 nsCOMPtr<nsIParentChannel> parentChannel;
7298 NS_QueryNotificationCallbacks(this, parentChannel);
7299 if (RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel)) {
7300 return httpParent->OtherPid();
7301 }
7302 if (RefPtr<DocumentLoadListener> docParent = do_QueryObject(parentChannel)) {
7303 return docParent->OtherPid();
7304 }
7305 return base::GetCurrentProcId();
7306}
7307
7308auto nsHttpChannel::AttachStreamFilter() -> RefPtr<ChildEndpointPromise> {
7309 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)
;
7310 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"
, 7310); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
")"); do { *((volatile int*)__null) = 7310; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7311
7312 if (!ProcessId()) {
7313 return ChildEndpointPromise::CreateAndReject(false, __func__);
7314 }
7315
7316 nsCOMPtr<nsIParentChannel> parentChannel;
7317 NS_QueryNotificationCallbacks(this, parentChannel);
7318
7319 // If our listener is a DocumentLoadListener, then we might handle
7320 // multi-part responses here in the parent process. The current extension
7321 // API doesn't understand the parsed multipart format, so we defer responding
7322 // here until CallOnStartRequest, and attach the StreamFilter before the
7323 // multipart handler (in the parent process!) if applicable.
7324 if (RefPtr<DocumentLoadListener> docParent = do_QueryObject(parentChannel)) {
7325 StreamFilterRequest* request = mStreamFilterRequests.AppendElement();
7326 request->mPromise = new ChildEndpointPromise::Private(__func__);
7327 return request->mPromise;
7328 }
7329
7330 mozilla::ipc::Endpoint<extensions::PStreamFilterParent> parent;
7331 mozilla::ipc::Endpoint<extensions::PStreamFilterChild> child;
7332 nsresult rv = extensions::PStreamFilter::CreateEndpoints(&parent, &child);
7333 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7334 return ChildEndpointPromise::CreateAndReject(false, __func__);
7335 }
7336
7337 if (RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel)) {
7338 return httpParent->AttachStreamFilter(std::move(parent), std::move(child));
7339 }
7340
7341 extensions::StreamFilterParent::Attach(this, std::move(parent));
7342 return ChildEndpointPromise::CreateAndResolve(std::move(child), __func__);
7343}
7344
7345NS_IMETHODIMPnsresult
7346nsHttpChannel::GetNavigationStartTimeStamp(TimeStamp* aTimeStamp) {
7347 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)
;
7348 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"
, 7348); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTimeStamp"
")"); do { *((volatile int*)__null) = 7348; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7349 *aTimeStamp = mNavigationStartTimeStamp;
7350 return NS_OK;
7351}
7352
7353NS_IMETHODIMPnsresult
7354nsHttpChannel::SetNavigationStartTimeStamp(TimeStamp aTimeStamp) {
7355 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)
;
7356 mNavigationStartTimeStamp = aTimeStamp;
7357 return NS_OK;
7358}
7359
7360//-----------------------------------------------------------------------------
7361// nsHttpChannel::nsISupportsPriority
7362//-----------------------------------------------------------------------------
7363
7364NS_IMETHODIMPnsresult
7365nsHttpChannel::SetPriority(int32_t value) {
7366 int16_t newValue = std::clamp<int32_t>(value, INT16_MIN(-32767-1), INT16_MAX(32767));
7367 if (mPriority == newValue) return NS_OK;
7368
7369 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)
;
7370
7371 mPriority = newValue;
7372 if (mTransaction) {
7373 nsresult rv = gHttpHandler->RescheduleTransaction(mTransaction, mPriority);
7374 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7375 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)
7376 ("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)
7377 "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)
7378 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)
;
7379 }
7380 }
7381
7382 // If this channel is the real channel for an e10s channel, notify the
7383 // child side about the priority change as well.
7384 nsCOMPtr<nsIParentChannel> parentChannel;
7385 NS_QueryNotificationCallbacks(this, parentChannel);
7386 RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel);
7387 if (httpParent) {
7388 httpParent->DoSendSetPriority(newValue);
7389 }
7390
7391 return NS_OK;
7392}
7393
7394//-----------------------------------------------------------------------------
7395// HttpChannel::nsIClassOfService
7396//-----------------------------------------------------------------------------
7397
7398void nsHttpChannel::OnClassOfServiceUpdated() {
7399 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)
7400 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)
;
7401
7402 if (mTransaction) {
7403 gHttpHandler->UpdateClassOfServiceOnTransaction(mTransaction,
7404 mClassOfService);
7405 }
7406 if (EligibleForTailing()) {
7407 RemoveAsNonTailRequest();
7408 } else {
7409 AddAsNonTailRequest();
7410 }
7411}
7412
7413NS_IMETHODIMPnsresult
7414nsHttpChannel::SetClassFlags(uint32_t inFlags) {
7415 uint32_t previous = mClassOfService.Flags();
7416 mClassOfService.SetFlags(inFlags);
7417 if (previous != mClassOfService.Flags()) {
7418 OnClassOfServiceUpdated();
7419 }
7420 return NS_OK;
7421}
7422
7423NS_IMETHODIMPnsresult
7424nsHttpChannel::AddClassFlags(uint32_t inFlags) {
7425 uint32_t previous = mClassOfService.Flags();
7426 mClassOfService.SetFlags(inFlags | mClassOfService.Flags());
7427 if (previous != mClassOfService.Flags()) {
7428 OnClassOfServiceUpdated();
7429 }
7430 return NS_OK;
7431}
7432
7433NS_IMETHODIMPnsresult
7434nsHttpChannel::ClearClassFlags(uint32_t inFlags) {
7435 uint32_t previous = mClassOfService.Flags();
7436 mClassOfService.SetFlags(~inFlags & mClassOfService.Flags());
7437 if (previous != mClassOfService.Flags()) {
7438 OnClassOfServiceUpdated();
7439 }
7440 return NS_OK;
7441}
7442
7443NS_IMETHODIMPnsresult
7444nsHttpChannel::SetClassOfService(ClassOfService cos) {
7445 ClassOfService previous = mClassOfService;
7446 mClassOfService = cos;
7447 if (previous != mClassOfService) {
7448 OnClassOfServiceUpdated();
7449 }
7450 return NS_OK;
7451}
7452
7453NS_IMETHODIMPnsresult
7454nsHttpChannel::SetIncremental(bool incremental) {
7455 bool previous = mClassOfService.Incremental();
7456 mClassOfService.SetIncremental(incremental);
7457 if (previous != mClassOfService.Incremental()) {
7458 OnClassOfServiceUpdated();
7459 }
7460 return NS_OK;
7461}
7462
7463//-----------------------------------------------------------------------------
7464// nsHttpChannel::nsIProtocolProxyCallback
7465//-----------------------------------------------------------------------------
7466
7467NS_IMETHODIMPnsresult
7468nsHttpChannel::OnProxyAvailable(nsICancelable* request, nsIChannel* channel,
7469 nsIProxyInfo* pi, nsresult status) {
7470 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)
7471 " 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)
7472 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)
7473 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)
;
7474 mProxyRequest = nullptr;
7475
7476 nsresult rv;
7477
7478 // If status is a failure code, then it means that we failed to resolve
7479 // proxy info. That is a non-fatal error assuming it wasn't because the
7480 // request was canceled. We just failover to DIRECT when proxy resolution
7481 // fails (failure can mean that the PAC URL could not be loaded).
7482
7483 if (NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1)))) {
7484 mProxyInfo = pi;
7485
7486 if (mProxyInfo) {
7487 nsAutoCStringN<8> type;
7488 mProxyInfo->GetType(type);
7489 uint32_t flags = 0;
7490 mProxyInfo->GetFlags(&flags);
7491
7492 if (type.EqualsLiteral("socks")) {
7493 if (flags & nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST) {
7494 glean::networking::proxy_info_type
7495 .EnumGet(glean::networking::ProxyInfoTypeLabel::eSocks5h)
7496 .Add(1);
7497 } else {
7498 glean::networking::proxy_info_type
7499 .EnumGet(glean::networking::ProxyInfoTypeLabel::eSocks5)
7500 .Add(1);
7501 }
7502 } else if (type.EqualsLiteral("socks4")) {
7503 if (flags & nsIProxyInfo::TRANSPARENT_PROXY_RESOLVES_HOST) {
7504 glean::networking::proxy_info_type
7505 .EnumGet(glean::networking::ProxyInfoTypeLabel::eSocks4a)
7506 .Add(1);
7507 } else {
7508 glean::networking::proxy_info_type
7509 .EnumGet(glean::networking::ProxyInfoTypeLabel::eSocks4)
7510 .Add(1);
7511 }
7512 } else if (type.EqualsLiteral("http")) {
7513 glean::networking::proxy_info_type
7514 .EnumGet(glean::networking::ProxyInfoTypeLabel::eHttp)
7515 .Add(1);
7516 } else if (type.EqualsLiteral("https")) {
7517 glean::networking::proxy_info_type
7518 .EnumGet(glean::networking::ProxyInfoTypeLabel::eHttps)
7519 .Add(1);
7520 } else if (type.EqualsLiteral("direct")) {
7521 glean::networking::proxy_info_type
7522 .EnumGet(glean::networking::ProxyInfoTypeLabel::eDirect)
7523 .Add(1);
7524 } else {
7525 glean::networking::proxy_info_type
7526 .EnumGet(glean::networking::ProxyInfoTypeLabel::eUnknown)
7527 .Add(1);
7528 }
7529 }
7530 }
7531
7532 if (!gHttpHandler->Active()) {
7533 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)
7534 ("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)
7535 "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)
7536 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)
;
7537 rv = NS_ERROR_NOT_AVAILABLE;
7538 } else {
7539 rv = BeginConnect();
7540 }
7541
7542 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
7543 CloseCacheEntry(false);
7544 Unused << AsyncAbort(rv);
7545 }
7546 return rv;
7547}
7548
7549//-----------------------------------------------------------------------------
7550// nsHttpChannel::nsIProxiedChannel
7551//-----------------------------------------------------------------------------
7552
7553NS_IMETHODIMPnsresult
7554nsHttpChannel::GetProxyInfo(nsIProxyInfo** result) {
7555 if (!mConnectionInfo) {
7556 *result = do_AddRef(mProxyInfo).take();
7557 } else {
7558 *result = do_AddRef(mConnectionInfo->ProxyInfo()).take();
7559 }
7560 return NS_OK;
7561}
7562
7563//-----------------------------------------------------------------------------
7564// nsHttpChannel::nsITimedChannel
7565//-----------------------------------------------------------------------------
7566
7567NS_IMETHODIMPnsresult
7568nsHttpChannel::GetDomainLookupStart(TimeStamp* _retval) {
7569 if (mTransaction) {
7570 *_retval = mTransaction->GetDomainLookupStart();
7571 } else {
7572 *_retval = mTransactionTimings.domainLookupStart;
7573 }
7574 return NS_OK;
7575}
7576
7577NS_IMETHODIMPnsresult
7578nsHttpChannel::GetDomainLookupEnd(TimeStamp* _retval) {
7579 if (mTransaction) {
7580 *_retval = mTransaction->GetDomainLookupEnd();
7581 } else {
7582 *_retval = mTransactionTimings.domainLookupEnd;
7583 }
7584 return NS_OK;
7585}
7586
7587NS_IMETHODIMPnsresult
7588nsHttpChannel::GetConnectStart(TimeStamp* _retval) {
7589 if (mTransaction) {
7590 *_retval = mTransaction->GetConnectStart();
7591 } else {
7592 *_retval = mTransactionTimings.connectStart;
7593 }
7594 return NS_OK;
7595}
7596
7597NS_IMETHODIMPnsresult
7598nsHttpChannel::GetTcpConnectEnd(TimeStamp* _retval) {
7599 if (mTransaction) {
7600 *_retval = mTransaction->GetTcpConnectEnd();
7601 } else {
7602 *_retval = mTransactionTimings.tcpConnectEnd;
7603 }
7604 return NS_OK;
7605}
7606
7607NS_IMETHODIMPnsresult
7608nsHttpChannel::GetSecureConnectionStart(TimeStamp* _retval) {
7609 if (mTransaction) {
7610 *_retval = mTransaction->GetSecureConnectionStart();
7611 } else {
7612 *_retval = mTransactionTimings.secureConnectionStart;
7613 }
7614 return NS_OK;
7615}
7616
7617NS_IMETHODIMPnsresult
7618nsHttpChannel::GetConnectEnd(TimeStamp* _retval) {
7619 if (mTransaction) {
7620 *_retval = mTransaction->GetConnectEnd();
7621 } else {
7622 *_retval = mTransactionTimings.connectEnd;
7623 }
7624 return NS_OK;
7625}
7626
7627NS_IMETHODIMPnsresult
7628nsHttpChannel::GetRequestStart(TimeStamp* _retval) {
7629 if (mTransaction) {
7630 *_retval = mTransaction->GetRequestStart();
7631 } else {
7632 *_retval = mTransactionTimings.requestStart;
7633 }
7634 return NS_OK;
7635}
7636
7637NS_IMETHODIMPnsresult
7638nsHttpChannel::GetResponseStart(TimeStamp* _retval) {
7639 if (mTransaction) {
7640 *_retval = mTransaction->GetResponseStart();
7641 } else {
7642 *_retval = mTransactionTimings.responseStart;
7643 }
7644 return NS_OK;
7645}
7646
7647NS_IMETHODIMPnsresult
7648nsHttpChannel::GetResponseEnd(TimeStamp* _retval) {
7649 if (mTransaction) {
7650 *_retval = mTransaction->GetResponseEnd();
7651 } else {
7652 *_retval = mTransactionTimings.responseEnd;
7653 }
7654 return NS_OK;
7655}
7656
7657NS_IMETHODIMPnsresult
7658nsHttpChannel::GetTransactionPending(TimeStamp* _retval) {
7659 if (mTransaction) {
7660 *_retval = mTransaction->GetPendingTime();
7661 } else {
7662 *_retval = mTransactionTimings.transactionPending;
7663 }
7664 return NS_OK;
7665}
7666
7667//-----------------------------------------------------------------------------
7668// nsHttpChannel::nsIHttpAuthenticableChannel
7669//-----------------------------------------------------------------------------
7670
7671NS_IMETHODIMPnsresult
7672nsHttpChannel::GetIsSSL(bool* aIsSSL) {
7673 // this attribute is really misnamed - it wants to know if
7674 // https:// is being used. SSL might be used to cover http://
7675 // in some circumstances (proxies, http/2, etc..)
7676 return mURI->SchemeIs("https", aIsSSL);
7677}
7678
7679NS_IMETHODIMPnsresult
7680nsHttpChannel::GetProxyMethodIsConnect(bool* aProxyMethodIsConnect) {
7681 *aProxyMethodIsConnect = mConnectionInfo->UsingConnect();
7682 return NS_OK;
7683}
7684
7685NS_IMETHODIMPnsresult
7686nsHttpChannel::GetServerResponseHeader(nsACString& value) {
7687 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
7688 return mResponseHead->GetHeader(nsHttp::Server, value);
7689}
7690
7691NS_IMETHODIMPnsresult
7692nsHttpChannel::GetProxyChallenges(nsACString& value) {
7693 if (!mResponseHead) return NS_ERROR_UNEXPECTED;
7694 return mResponseHead->GetHeader(nsHttp::Proxy_Authenticate, value);
7695}
7696
7697NS_IMETHODIMPnsresult
7698nsHttpChannel::GetWWWChallenges(nsACString& value) {
7699 if (!mResponseHead) return NS_ERROR_UNEXPECTED;
7700 return mResponseHead->GetHeader(nsHttp::WWW_Authenticate, value);
7701}
7702
7703NS_IMETHODIMPnsresult
7704nsHttpChannel::SetProxyCredentials(const nsACString& value) {
7705 return mRequestHead.SetHeader(nsHttp::Proxy_Authorization, value);
7706}
7707
7708NS_IMETHODIMPnsresult
7709nsHttpChannel::SetWWWCredentials(const nsACString& value) {
7710 // This method is called when various browser initiated authorization
7711 // code sets the credentials. We need to flag this header as the
7712 // "browser default" so it does not show up in the ServiceWorker
7713 // FetchEvent. This may actually get called more than once, though,
7714 // so we clear the header first since "default" headers are not
7715 // allowed to overwrite normally.
7716 Unused << mRequestHead.ClearHeader(nsHttp::Authorization);
7717 return mRequestHead.SetHeader(nsHttp::Authorization, value, false,
7718 nsHttpHeaderArray::eVarietyRequestDefault);
7719}
7720
7721//-----------------------------------------------------------------------------
7722// Methods that nsIHttpAuthenticableChannel dupes from other IDLs, which we
7723// get from HttpBaseChannel, must be explicitly forwarded, because C++ sucks.
7724//-----------------------------------------------------------------------------
7725
7726NS_IMETHODIMPnsresult
7727nsHttpChannel::GetLoadFlags(nsLoadFlags* aLoadFlags) {
7728 return HttpBaseChannel::GetLoadFlags(aLoadFlags);
7729}
7730
7731NS_IMETHODIMPnsresult
7732nsHttpChannel::GetURI(nsIURI** aURI) { return HttpBaseChannel::GetURI(aURI); }
7733
7734NS_IMETHODIMPnsresult
7735nsHttpChannel::GetNotificationCallbacks(nsIInterfaceRequestor** aCallbacks) {
7736 return HttpBaseChannel::GetNotificationCallbacks(aCallbacks);
7737}
7738
7739NS_IMETHODIMPnsresult
7740nsHttpChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) {
7741 return HttpBaseChannel::GetLoadGroup(aLoadGroup);
7742}
7743
7744NS_IMETHODIMPnsresult
7745nsHttpChannel::GetRequestMethod(nsACString& aMethod) {
7746 return HttpBaseChannel::GetRequestMethod(aMethod);
7747}
7748
7749//-----------------------------------------------------------------------------
7750// nsHttpChannel::nsIRequestObserver
7751//-----------------------------------------------------------------------------
7752
7753void nsHttpChannel::RecordOnStartTelemetry(nsresult aStatus,
7754 bool aIsNavigation) {
7755 Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_ONSTART_SUCCESS,
7756 NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1))));
7757
7758 mozilla::glean::networking::http_channel_onstart_status
7759 .Get(NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1))) ? "successful"_ns : "fail"_ns)
7760 .Add(1);
7761
7762 if (mTransaction) {
7763 Telemetry::Accumulate(
7764 Telemetry::HTTP3_CHANNEL_ONSTART_SUCCESS,
7765 (mTransaction->IsHttp3Used()) ? "http3"_ns : "no_http3"_ns,
7766 NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1))));
7767 }
7768
7769 enum class HttpOnStartState : uint32_t {
7770 Success = 0,
7771 DNSError = 1,
7772 Others = 2,
7773 };
7774
7775 if (TRRService::Get() && TRRService::Get()->IsConfirmed()) {
7776 // Note this telemetry probe is not working when DNS resolution is done in
7777 // the socket process.
7778 HttpOnStartState state = HttpOnStartState::Others;
7779 if (NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1)))) {
7780 state = HttpOnStartState::Success;
7781 } else if (aStatus == NS_ERROR_UNKNOWN_HOST ||
7782 aStatus == NS_ERROR_UNKNOWN_PROXY_HOST) {
7783 state = HttpOnStartState::DNSError;
7784 }
7785
7786 if (aIsNavigation) {
7787 Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_PAGE_ONSTART_SUCCESS_TRR3,
7788 TRRService::ProviderKey(),
7789 static_cast<uint32_t>(state));
7790 } else {
7791 Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_SUB_ONSTART_SUCCESS_TRR3,
7792 TRRService::ProviderKey(),
7793 static_cast<uint32_t>(state));
7794 }
7795 }
7796
7797 if (nsIOService::UseSocketProcess() && mTransaction) {
7798 const TimeStamp now = TimeStamp::Now();
7799 TimeStamp responseEnd = mTransaction->GetResponseEnd();
7800 if (!responseEnd.IsNull()) {
7801 PerfStats::RecordMeasurement(PerfStats::Metric::ResponseEndSocketToParent,
7802 now - responseEnd);
7803 }
7804
7805 mOnStartRequestStartTime = mTransaction->GetOnStartRequestStartTime();
7806 if (!mOnStartRequestStartTime.IsNull()) {
7807 PerfStats::RecordMeasurement(
7808 PerfStats::Metric::OnStartRequestSocketToParent,
7809 now - mOnStartRequestStartTime);
7810 }
7811 } else {
7812 mOnStartRequestStartTime = TimeStamp::Now();
7813 }
7814}
7815
7816NS_IMETHODIMPnsresult
7817nsHttpChannel::OnStartRequest(nsIRequest* request) {
7818 nsresult rv;
7819
7820 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"
, 7820); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadRequestObserversCalled()"
")"); do { *((volatile int*)__null) = 7820; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7821
7822 AUTO_PROFILER_LABEL("nsHttpChannel::OnStartRequest", NETWORK)mozilla::AutoProfilerLabel raiiObject7822( "nsHttpChannel::OnStartRequest"
, nullptr, JS::ProfilingCategoryPair::NETWORK)
;
7823
7824 if (!(mCanceled || NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0)))) &&
7825 !WRONG_RACING_RESPONSE_SOURCE(request)(mRaceCacheWithNetwork && (((mFirstResponseSource == RESPONSE_FROM_CACHE
) && ((request) != mCachePump)) || ((mFirstResponseSource
== RESPONSE_FROM_NETWORK) && ((request) != mTransactionPump
))))
) {
7826 // capture the request's status, so our consumers will know ASAP of any
7827 // connection failures, etc - bug 93581
7828 nsresult status;
7829 request->GetStatus(&status);
7830 mStatus = status;
7831 }
7832
7833 if (mStatus == NS_ERROR_NON_LOCAL_CONNECTION_REFUSED) {
7834 MOZ_CRASH_UNSAFE(nsPrintfCString("Attempting to connect to non-local "MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7841, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7835 "address! opener is [%s], uri is "MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7841, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7836 "[%s]",MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7841, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7837 mOpenerCallingScriptLocationMOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7841, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7838 ? mOpenerCallingScriptLocation->get()MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7841, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7839 : "unknown",MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7841, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7840 mURI->GetSpecOrDefault().get())MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7841, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
7841 .get())MOZ_Crash("/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 7841, nsPrintfCString("Attempting to connect to non-local "
"address! opener is [%s], uri is " "[%s]", mOpenerCallingScriptLocation
? mOpenerCallingScriptLocation->get() : "unknown", mURI->
GetSpecOrDefault().get()) .get())
;
7842 }
7843
7844 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)
7845 "]\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)
7846 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)
;
7847
7848 RecordOnStartTelemetry(mStatus, IsNavigation());
7849
7850 if (mRaceCacheWithNetwork) {
7851 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)
7852 (" 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)
7853 "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)
7854 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)
7855 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)
;
7856 if (mFirstResponseSource == RESPONSE_PENDING) {
7857 // When the cache wins mFirstResponseSource is set to
7858 // RESPONSE_FROM_CACHE earlier in ReadFromCache, so this must be a
7859 // response from the network.
7860 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"
, 7860); AnnotateMozCrashReason("MOZ_ASSERT" "(" "request == mTransactionPump"
")"); do { *((volatile int*)__null) = 7860; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7861 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)
;
7862 {
7863 // Race condition with OnCacheEntryCheck, which is not limited
7864 // to main thread.
7865 mozilla::MutexAutoLock lock(mRCWNLock);
7866 mFirstResponseSource = RESPONSE_FROM_NETWORK;
7867 // If we haven't gotten any response from the cache, we've won the
7868 // race. Any response from the case means it's a cache 'win', even if
7869 // the response was "we don't have an entry" or "we have an entry but
7870 // it's expired/invalid".
7871 if (LoadCachedContentIsValid() == CachedContentValidity::Unset) {
7872 StoreNetworkWonRace(1);
7873 }
7874 mOnStartRequestTimestamp = TimeStamp::Now();
7875 PROFILER_MARKER_TEXT(do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won on StartRequest valid=%d for %s - %p"
, LoadCachedContentIsValid(), mSpec.get(), this)); } } while (
false); } while (false)
7876 "RCWN", NETWORK, {},do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won on StartRequest valid=%d for %s - %p"
, LoadCachedContentIsValid(), mSpec.get(), this)); } } while (
false); } while (false)
7877 nsPrintfCString("Network won on StartRequest valid=%d for %s - %p",do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won on StartRequest valid=%d for %s - %p"
, LoadCachedContentIsValid(), mSpec.get(), this)); } } while (
false); } while (false)
7878 LoadCachedContentIsValid(), mSpec.get(), this))do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won on StartRequest valid=%d for %s - %p"
, LoadCachedContentIsValid(), mSpec.get(), this)); } } while (
false); } while (false)
;
7879
7880 // Conditional or byte range header could be added in
7881 // OnCacheEntryCheck. We need to remove them because the
7882 // request might be sent again due to auth retry and we must
7883 // not send these headers without having the entry.
7884 if (mDidReval) {
7885 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)
;
7886 UntieValidationRequest();
7887 mDidReval = false;
7888 }
7889 if (LoadCachedContentIsPartial()) {
7890 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)
;
7891 UntieByteRangeRequest();
7892 StoreCachedContentIsPartial(false);
7893 }
7894 }
7895 mAvailableCachedAltDataType.Truncate();
7896 StoreDeliveringAltData(false);
7897 } else if (WRONG_RACING_RESPONSE_SOURCE(request)(mRaceCacheWithNetwork && (((mFirstResponseSource == RESPONSE_FROM_CACHE
) && ((request) != mCachePump)) || ((mFirstResponseSource
== RESPONSE_FROM_NETWORK) && ((request) != mTransactionPump
))))
) {
7898 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)
;
7899 return NS_OK;
7900 } else {
7901 PROFILER_MARKER_TEXT(do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Cache won on StartRequest valid=%d for %s - %p"
, LoadCachedContentIsValid(), mSpec.get(), this)); } } while (
false); } while (false)
7902 "RCWN", NETWORK, {},do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Cache won on StartRequest valid=%d for %s - %p"
, LoadCachedContentIsValid(), mSpec.get(), this)); } } while (
false); } while (false)
7903 nsPrintfCString("Cache won on StartRequest valid=%d for %s - %p",do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Cache won on StartRequest valid=%d for %s - %p"
, LoadCachedContentIsValid(), mSpec.get(), this)); } } while (
false); } while (false)
7904 LoadCachedContentIsValid(), mSpec.get(), this))do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Cache won on StartRequest valid=%d for %s - %p"
, LoadCachedContentIsValid(), mSpec.get(), this)); } } while (
false); } while (false)
;
7905 }
7906 }
7907
7908 // Make sure things are what we expect them to be...
7909 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"
, 7910); AnnotateMozCrashReason("MOZ_ASSERT" "(" "request == mCachePump || request == mTransactionPump"
") (" "Unexpected request" ")"); do { *((volatile int*)__null
) = 7910; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
7910 "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"
, 7910); AnnotateMozCrashReason("MOZ_ASSERT" "(" "request == mCachePump || request == mTransactionPump"
") (" "Unexpected request" ")"); do { *((volatile int*)__null
) = 7910; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
7911
7912 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"
, 7916); 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) = 7916; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
7913 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"
, 7916); 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) = 7916; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
7914 "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"
, 7916); 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) = 7916; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
7915 " 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"
, 7916); 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) = 7916; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
7916 "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"
, 7916); 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) = 7916; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7917
7918 StoreAfterOnStartRequestBegun(true);
7919 if (mOnStartRequestTimestamp.IsNull()) {
7920 mOnStartRequestTimestamp = TimeStamp::Now();
7921 }
7922
7923 mozilla::glean::networking::http_onstart_suspend_total_time
7924 .AccumulateRawDuration(mSuspendTotalTime);
7925
7926 if (mTransaction) {
7927 mProxyConnectResponseCode = mTransaction->GetProxyConnectResponseCode();
7928 if (request == mTransactionPump) {
7929 StoreDataSentToChildProcess(mTransaction->DataSentToChildProcess());
7930 }
7931
7932 if (!mSecurityInfo && !mCachePump) {
7933 // grab the security info from the connection object; the transaction
7934 // is guaranteed to own a reference to the connection.
7935 mSecurityInfo = mTransaction->SecurityInfo();
7936 }
7937
7938 uint32_t stage = mTransaction->HTTPSSVCReceivedStage();
7939 if (!LoadHTTPSSVCTelemetryReported() && stage != HTTPSSVC_NOT_USED) {
7940 Telemetry::Accumulate(Telemetry::DNS_HTTPSSVC_RECORD_RECEIVING_STAGE,
7941 stage);
7942 }
7943
7944 if (HTTPS_RR_IS_USED(stage)(stage > HTTPSSVC_NOT_PRESENT && stage < HTTPSSVC_WITH_IPHINT_RECEIVED_STAGE_2
)
) {
7945 nsAutoCString suffix(LoadEchConfigUsed() ? "_ech_used" : "");
7946 // Determine the result string based on the status.
7947 nsAutoCString result(NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1))) ? "success" : "failure");
7948 result.Append(suffix);
7949
7950 mozilla::glean::networking::http_channel_onstart_success_https_rr
7951 .Get(result)
7952 .Add(1);
7953 StoreHasHTTPSRR(true);
7954 }
7955
7956 StoreLoadedBySocketProcess(mTransaction->AsHttpTransactionParent() !=
7957 nullptr);
7958
7959 bool isTrr;
7960 bool echConfigUsed;
7961 mTransaction->GetNetworkAddresses(mSelfAddr, mPeerAddr, isTrr,
7962 mEffectiveTRRMode, mTRRSkipReason,
7963 echConfigUsed);
7964 StoreResolvedByTRR(isTrr);
7965 StoreEchConfigUsed(echConfigUsed);
7966 }
7967
7968 // don't enter this block if we're reading from the cache...
7969 if (NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1))) && !mCachePump && mTransaction) {
7970 // mTransactionPump doesn't hit OnInputStreamReady and call this until
7971 // all of the response headers have been acquired, so we can take
7972 // ownership of them from the transaction.
7973 mResponseHead = mTransaction->TakeResponseHead();
7974 mSupportsHTTP3 = mTransaction->GetSupportsHTTP3();
7975 // the response head may be null if the transaction was cancelled. in
7976 // which case we just need to call OnStartRequest/OnStopRequest.
7977 if (mResponseHead) return ProcessResponse();
7978
7979 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"
, 7979)
;
7980 }
7981
7982 // cache file could be deleted on our behalf, it could contain errors or
7983 // it failed to allocate memory, reload from network here.
7984 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)
) {
7985 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)
;
7986 mCacheEntry->AsyncDoom(nullptr);
7987 rv =
7988 StartRedirectChannelToURI(mURI, nsIChannelEventSink::REDIRECT_INTERNAL);
7989 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) return NS_OK;
7990 }
7991
7992 // avoid crashing if mListener happens to be null...
7993 if (!mListener) {
7994 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"
, 7994); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "mListener is null" ")"); do { *(
(volatile int*)__null) = 7994; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
7995 return NS_OK;
7996 }
7997
7998 rv = ProcessCrossOriginSecurityHeaders();
7999 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
8000 mStatus = rv;
8001 HandleAsyncAbort();
8002 return rv;
8003 }
8004
8005 // No process change is needed, so continue on to ContinueOnStartRequest1.
8006 return ContinueOnStartRequest1(rv);
8007}
8008
8009nsresult nsHttpChannel::ContinueOnStartRequest1(nsresult result) {
8010 nsresult rv;
8011
8012 // if process selection failed, cancel this load.
8013 if (NS_FAILED(result)((bool)(__builtin_expect(!!(NS_FAILED_impl(result)), 0))) && !mCanceled) {
8014 Cancel(result);
8015 return CallOnStartRequest();
8016 }
8017
8018 // before we start any content load, check for redirectTo being called
8019 // this code is executed mainly before we start load from the cache
8020 if (mAPIRedirectTo && !mCanceled) {
8021 nsAutoCString redirectToSpec;
8022 mAPIRedirectTo->first()->GetAsciiSpec(redirectToSpec);
8023 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)
;
8024
8025 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"
, 8025); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
")"); do { *((volatile int*)__null) = 8025; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8026 PushRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest2);
8027 rv = StartRedirectChannelToURI(
8028 mAPIRedirectTo->first(),
8029 mAPIRedirectTo->second() ? nsIChannelEventSink::REDIRECT_TEMPORARY |
8030 nsIChannelEventSink::REDIRECT_TRANSPARENT
8031 : nsIChannelEventSink::REDIRECT_TEMPORARY);
8032 mAPIRedirectTo = Nothing();
8033 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
8034 return NS_OK;
8035 }
8036 PopRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest2);
8037 }
8038
8039 // Hack: ContinueOnStartRequest2 uses NS_OK to detect successful redirects,
8040 // so we distinguish this codepath (a non-redirect that's processing
8041 // normally) by passing in a bogus error code.
8042 return ContinueOnStartRequest2(NS_BINDING_FAILED);
8043}
8044
8045nsresult nsHttpChannel::ContinueOnStartRequest2(nsresult result) {
8046 if (NS_SUCCEEDED(result)((bool)(__builtin_expect(!!(!NS_FAILED_impl(result)), 1)))) {
8047 // Redirect has passed through, we don't want to go on with this
8048 // channel. It will now be canceled by the redirect handling code
8049 // that called this function.
8050 return NS_OK;
8051 }
8052
8053 // on proxy errors, try to failover
8054 if (mConnectionInfo->ProxyInfo() &&
8055 (mStatus == NS_ERROR_PROXY_CONNECTION_REFUSED ||
8056 mStatus == NS_ERROR_UNKNOWN_PROXY_HOST ||
8057 mStatus == NS_ERROR_NET_TIMEOUT || mStatus == NS_ERROR_NET_RESET)) {
8058 PushRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest3);
8059 if (NS_SUCCEEDED(ProxyFailover())((bool)(__builtin_expect(!!(!NS_FAILED_impl(ProxyFailover()))
, 1)))
) {
8060 mProxyConnectResponseCode = 0;
8061 return NS_OK;
8062 }
8063 PopRedirectAsyncFunc(&nsHttpChannel::ContinueOnStartRequest3);
8064 }
8065
8066 // Hack: ContinueOnStartRequest3 uses NS_OK to detect successful redirects,
8067 // so we distinguish this codepath (a non-redirect that's processing
8068 // normally) by passing in a bogus error code.
8069 return ContinueOnStartRequest3(NS_BINDING_FAILED);
8070}
8071
8072nsresult nsHttpChannel::ContinueOnStartRequest3(nsresult result) {
8073 if (NS_SUCCEEDED(result)((bool)(__builtin_expect(!!(!NS_FAILED_impl(result)), 1)))) {
8074 // Redirect has passed through, we don't want to go on with this
8075 // channel. It will now be canceled by the redirect handling code
8076 // that called this function.
8077 return NS_OK;
8078 }
8079
8080 return ContinueOnStartRequest4(NS_OK);
8081}
8082
8083nsresult nsHttpChannel::ContinueOnStartRequest4(nsresult result) {
8084 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)
;
8085
8086 if (NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1))) && mResponseHead && mAuthProvider) {
8087 uint32_t httpStatus = mResponseHead->Status();
8088 if (httpStatus != 401 && httpStatus != 407) {
8089 nsresult rv = mAuthProvider->CheckForSuperfluousAuth();
8090 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
8091 mStatus = rv;
8092 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)
8093 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)
;
8094 }
8095 }
8096 }
8097
8098 return CallOnStartRequest();
8099}
8100
8101static void ReportHTTPSRRTelemetry(
8102 const Maybe<nsCOMPtr<nsIDNSHTTPSSVCRecord>>& aMaybeRecord) {
8103 bool hasHTTPSRR = aMaybeRecord && (aMaybeRecord.ref() != nullptr);
8104 if (!hasHTTPSRR) {
8105 mozilla::glean::networking::https_rr_presented.Get("none"_ns).Add(1);
8106 return;
8107 }
8108
8109 const nsCOMPtr<nsIDNSHTTPSSVCRecord>& record = aMaybeRecord.ref();
8110 nsCOMPtr<nsISVCBRecord> svcbRecord;
8111 if (NS_SUCCEEDED(record->GetServiceModeRecord(false, false,((bool)(__builtin_expect(!!(!NS_FAILED_impl(record->GetServiceModeRecord
(false, false, getter_AddRefs(svcbRecord)))), 1)))
8112 getter_AddRefs(svcbRecord)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(record->GetServiceModeRecord
(false, false, getter_AddRefs(svcbRecord)))), 1)))
) {
8113 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"
, 8113); AnnotateMozCrashReason("MOZ_ASSERT" "(" "svcbRecord"
")"); do { *((volatile int*)__null) = 8113; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8114
8115 Maybe<std::tuple<nsCString, SupportedAlpnRank>> alpn =
8116 svcbRecord->GetAlpn();
8117 bool isHttp3 = alpn ? IsHttp3(std::get<1>(*alpn)) : false;
8118 mozilla::glean::networking::https_rr_presented
8119 .Get(isHttp3 ? "presented_with_http3"_ns : "presented"_ns)
8120 .Add(1);
8121 }
8122}
8123
8124static void RecordHttpChanDispositionGlean(ChannelDisposition chanDisposition) {
8125 switch (chanDisposition) {
8126 case kHttpCanceled:
8127 mozilla::glean::networking::http_channel_disposition
8128 .Get("http_cancelled"_ns)
8129 .Add(1);
8130 break;
8131 case kHttpDisk:
8132 mozilla::glean::networking::http_channel_disposition.Get("http_disk"_ns)
8133 .Add(1);
8134 break;
8135 case kHttpNetOK:
8136 mozilla::glean::networking::http_channel_disposition.Get("http_net_ok"_ns)
8137 .Add(1);
8138 break;
8139 case kHttpNetEarlyFail:
8140 mozilla::glean::networking::http_channel_disposition
8141 .Get("http_net_early_fail"_ns)
8142 .Add(1);
8143 break;
8144 case kHttpNetLateFail:
8145 mozilla::glean::networking::http_channel_disposition
8146 .Get("http_net_late_fail"_ns)
8147 .Add(1);
8148 break;
8149 case kHttpsCanceled:
8150 mozilla::glean::networking::http_channel_disposition
8151 .Get("https_cancelled"_ns)
8152 .Add(1);
8153 break;
8154 case kHttpsDisk:
8155 mozilla::glean::networking::http_channel_disposition.Get("http_disk"_ns)
8156 .Add(1);
8157 break;
8158 case kHttpsNetOK:
8159 mozilla::glean::networking::http_channel_disposition
8160 .Get("https_net_ok"_ns)
8161 .Add(1);
8162 break;
8163 case kHttpsNetEarlyFail:
8164 mozilla::glean::networking::http_channel_disposition
8165 .Get("https_net_early_fail"_ns)
8166 .Add(1);
8167 break;
8168 case kHttpsNetLateFail:
8169 mozilla::glean::networking::http_channel_disposition
8170 .Get("https_net_late_fail"_ns)
8171 .Add(1);
8172 break;
8173 default:
8174 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"
, 8174); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unknown value for chanDisposition"
")"); do { *((volatile int*)__null) = 8174; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8175 }
8176}
8177
8178static nsLiteralCString HttpChanDispositionToTelemetryLabel(
8179 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE upgradeChanDisposition) {
8180 if (upgradeChanDisposition ==
8181 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::cancel) {
8182 return "cancel"_ns;
8183 }
8184 if (upgradeChanDisposition ==
8185 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::disk) {
8186 return "disk"_ns;
8187 }
8188 if (upgradeChanDisposition ==
8189 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::netOk) {
8190 return "net_ok"_ns;
8191 }
8192 if (upgradeChanDisposition ==
8193 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::netEarlyFail) {
8194 return "net_early_fail"_ns;
8195 }
8196 if (upgradeChanDisposition ==
8197 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::netLateFail) {
8198 return "net_late_fail"_ns;
8199 }
8200
8201 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"
, 8201); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unknown value for upgradeChanDecomposition"
")"); do { *((volatile int*)__null) = 8201; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8202 return "other"_ns;
8203}
8204
8205nsresult nsHttpChannel::LogConsoleError(const char* aTag) {
8206 nsCOMPtr<nsIConsoleService> console(mozilla::components::Console::Service());
8207 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"
, 8207); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
8208
8209 nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
8210 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"
, 8210); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
8211 uint64_t innerWindowID = loadInfo->GetInnerWindowID();
8212
8213 nsAutoString errorText;
8214 nsresult rv = nsContentUtils::GetLocalizedString(
8215 nsContentUtils::eNECKO_PROPERTIES, aTag, errorText);
8216 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"
, 8216); return rv; } } while (false)
;
8217
8218 nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID"@mozilla.org/scripterror;1"));
8219 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"
, 8219); return NS_ERROR_OUT_OF_MEMORY; } } while (false)
;
8220
8221 rv =
8222 error->InitWithSourceURI(errorText, mURI, 0, 0, nsIScriptError::errorFlag,
8223 "Invalid HTTP Status Lines"_ns, innerWindowID);
8224 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"
, 8224); return rv; } } while (false)
;
8225 console->LogMessage(error);
8226 return NS_OK;
8227}
8228
8229static void RecordHTTPSUpgradeTelemetry(nsIURI* aURI, nsILoadInfo* aLoadInfo) {
8230 // we record https telemetry only for top-level loads
8231 if (aLoadInfo->GetExternalContentPolicyType() !=
8232 ExtContentPolicy::TYPE_DOCUMENT) {
8233 return;
8234 }
8235
8236 // exempt loopback addresses because we only want to record telemetry
8237 // for actual web requests
8238 if (nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackURL(aURI)) {
8239 return;
8240 }
8241
8242 // todo: for now we don't record form submissions, only
8243 // top-level document loads. Once Bug 1720500 is fixed, we can
8244 // consider recording form submissions too.
8245 if (aLoadInfo->GetIsFormSubmission()) {
8246 return;
8247 }
8248
8249 bool isHTTPS = aURI->SchemeIs("https");
8250
8251 nsILoadInfo::HTTPSUpgradeTelemetryType httpsTelemetry =
8252 aLoadInfo->GetHttpsUpgradeTelemetry();
8253 switch (httpsTelemetry) {
8254 case nsILoadInfo::NOT_INITIALIZED: {
8255 if (isHTTPS) {
8256 // Bug 1912222: We should never encounter NOT_INITIALIZED values,
8257 // though we still want to know whether those loads are HTTPS
8258 // or not. Eventually we'll want to remove this if-clause
8259 // again and only report "not_initialized".
8260 mozilla::glean::networking::http_to_https_upgrade_reason
8261 .Get("not_initialized_https"_ns)
8262 .Add(1);
8263 return;
8264 }
8265 mozilla::glean::networking::http_to_https_upgrade_reason
8266 .Get("not_initialized"_ns)
8267 .Add(1);
8268 break;
8269 }
8270 case nsILoadInfo::NO_UPGRADE: {
8271 if (isHTTPS) {
8272 // Bug 1912222: We should rearely encounter NO_UPGRADE values, though
8273 // we still want to ensure those are not HTTPS. Eventually we'll want
8274 // to remove this if-clause again and only report "no_upgrade".
8275 mozilla::glean::networking::http_to_https_upgrade_reason
8276 .Get("no_upgrade_https"_ns)
8277 .Add(1);
8278 return;
8279 }
8280 mozilla::glean::networking::http_to_https_upgrade_reason
8281 .Get("no_upgrade"_ns)
8282 .Add(1);
8283 break;
8284 }
8285 case nsILoadInfo::ALREADY_HTTPS:
8286 mozilla::glean::networking::http_to_https_upgrade_reason
8287 .Get("already_https"_ns)
8288 .Add(1);
8289 break;
8290 case nsILoadInfo::HSTS:
8291 mozilla::glean::networking::http_to_https_upgrade_reason.Get("hsts"_ns)
8292 .Add(1);
8293 break;
8294 case nsILoadInfo::HTTPS_ONLY_UPGRADE:
8295 mozilla::glean::networking::http_to_https_upgrade_reason
8296 .Get("https_only_upgrade"_ns)
8297 .Add(1);
8298 break;
8299 case nsILoadInfo::HTTPS_ONLY_UPGRADE_DOWNGRADE:
8300 mozilla::glean::networking::http_to_https_upgrade_reason
8301 .Get("https_only_upgrade_downgrade"_ns)
8302 .Add(1);
8303 break;
8304 case nsILoadInfo::HTTPS_FIRST_UPGRADE:
8305 mozilla::glean::networking::http_to_https_upgrade_reason
8306 .Get("https_first_upgrade"_ns)
8307 .Add(1);
8308 break;
8309 case nsILoadInfo::HTTPS_FIRST_UPGRADE_DOWNGRADE:
8310 mozilla::glean::networking::http_to_https_upgrade_reason
8311 .Get("https_first_upgrade_downgrade"_ns)
8312 .Add(1);
8313 break;
8314 case nsILoadInfo::HTTPS_FIRST_SCHEMELESS_UPGRADE:
8315 mozilla::glean::networking::http_to_https_upgrade_reason
8316 .Get("https_first_schemeless_upgrade"_ns)
8317 .Add(1);
8318 break;
8319 case nsILoadInfo::HTTPS_FIRST_SCHEMELESS_UPGRADE_DOWNGRADE:
8320 mozilla::glean::networking::http_to_https_upgrade_reason
8321 .Get("https_first_schemeless_upgrade_downgrade"_ns)
8322 .Add(1);
8323 break;
8324 case nsILoadInfo::CSP_UIR:
8325 mozilla::glean::networking::http_to_https_upgrade_reason.Get("csp_uir"_ns)
8326 .Add(1);
8327 break;
8328 case nsILoadInfo::HTTPS_RR:
8329 mozilla::glean::networking::http_to_https_upgrade_reason
8330 .Get("https_rr"_ns)
8331 .Add(1);
8332 break;
8333 case nsILoadInfo::WEB_EXTENSION_UPGRADE:
8334 mozilla::glean::networking::http_to_https_upgrade_reason
8335 .Get("web_extension_upgrade"_ns)
8336 .Add(1);
8337 break;
8338 case nsILoadInfo::UPGRADE_EXCEPTION:
8339 mozilla::glean::networking::http_to_https_upgrade_reason
8340 .Get("upgrade_exception"_ns)
8341 .Add(1);
8342 break;
8343 case nsILoadInfo::SKIP_HTTPS_UPGRADE:
8344 mozilla::glean::networking::http_to_https_upgrade_reason
8345 .Get("skip_upgrade"_ns)
8346 .Add(1);
8347 break;
8348 default:
8349 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"
, 8349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"what telemetry flag is set to end up here?" ")"); do { *((volatile
int*)__null) = 8349; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
8350 }
8351}
8352
8353static void RecordIPAddressSpaceTelemetry(bool aLoadSuccess, nsIURI* aURI,
8354 nsILoadInfo* aLoadInfo,
8355 NetAddr& aPeerAddr) {
8356 bool isIpAddrAny = false;
8357
8358 if (NS_SUCCEEDED(gIOService->HostnameIsIPAddressAny(aURI, &isIpAddrAny))((bool)(__builtin_expect(!!(!NS_FAILED_impl(gIOService->HostnameIsIPAddressAny
(aURI, &isIpAddrAny))), 1)))
&&
8359 isIpAddrAny) {
8360 if (aLoadSuccess) {
8361 mozilla::glean::networking::http_ip_addr_any_hostnames.Get("sucess"_ns)
8362 .Add(1);
8363 } else {
8364 mozilla::glean::networking::http_ip_addr_any_hostnames.Get("failure"_ns)
8365 .Add(1);
8366 }
8367 }
8368
8369 // if the load was not successful, then there is nothing to record here
8370 if (!aLoadSuccess) {
8371 return;
8372 }
8373
8374 // we record https telemetry only for top-level loads
8375 if (aLoadInfo->GetExternalContentPolicyType() !=
8376 ExtContentPolicy::TYPE_DOCUMENT) {
8377 return;
8378 }
8379
8380 if (aURI->SchemeIs("https")) {
8381 mozilla::glean::networking::https_http_or_local.Get("load_is_https"_ns)
8382 .Add(1);
8383 return;
8384 }
8385
8386 if (aURI->SchemeIs("http")) {
8387 if (aPeerAddr.IsIPAddrLocal() || aPeerAddr.IsLoopbackAddr()) {
8388 mozilla::glean::networking::https_http_or_local
8389 .Get("load_is_http_for_local_domain"_ns)
8390 .Add(1);
8391 } else {
8392 mozilla::glean::networking::https_http_or_local.Get("load_is_http"_ns)
8393 .Add(1);
8394 }
8395 return;
8396 }
8397}
8398
8399NS_IMETHODIMPnsresult
8400nsHttpChannel::OnStopRequest(nsIRequest* request, nsresult status) {
8401 MOZ_ASSERT(!mAsyncOpenTime.IsNull())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mAsyncOpenTime.IsNull())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mAsyncOpenTime.IsNull()))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("!mAsyncOpenTime.IsNull()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 8401); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mAsyncOpenTime.IsNull()"
")"); do { *((volatile int*)__null) = 8401; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8402 AUTO_PROFILER_LABEL("nsHttpChannel::OnStopRequest", NETWORK)mozilla::AutoProfilerLabel raiiObject8402( "nsHttpChannel::OnStopRequest"
, nullptr, JS::ProfilingCategoryPair::NETWORK)
;
8403
8404 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)
8405 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)
;
8406
8407 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)
8408 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)
;
8409
8410 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"
, 8411); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "OnStopRequest should only be called from the main thread"
")"); do { *((volatile int*)__null) = 8411; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
8411 "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"
, 8411); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "OnStopRequest should only be called from the main thread"
")"); do { *((volatile int*)__null) = 8411; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8412
8413 if (mStatus == NS_ERROR_PARSING_HTTP_STATUS_LINE) {
8414 Unused << LogConsoleError("InvalidHTTPResponseStatusLine");
8415 }
8416
8417 if (WRONG_RACING_RESPONSE_SOURCE(request)(mRaceCacheWithNetwork && (((mFirstResponseSource == RESPONSE_FROM_CACHE
) && ((request) != mCachePump)) || ((mFirstResponseSource
== RESPONSE_FROM_NETWORK) && ((request) != mTransactionPump
))))
) {
8418 return NS_OK;
8419 }
8420
8421 // It's possible that LoadUseHTTPSSVC() is false, but we already have
8422 // mHTTPSSVCRecord.
8423 if (LoadUseHTTPSSVC() || mHTTPSSVCRecord) {
8424 ReportHTTPSRRTelemetry(mHTTPSSVCRecord);
8425 }
8426
8427 // If this load failed because of a security error, it may be because we
8428 // are in a captive portal - trigger an async check to make sure.
8429 int32_t nsprError = -1 * NS_ERROR_GET_CODE(status);
8430 if (mozilla::psm::IsNSSErrorCode(nsprError) && IsHTTPS()) {
8431 gIOService->RecheckCaptivePortal();
8432 }
8433
8434 if (request == mCachePump) {
8435 mCacheReadEnd = TimeStamp::Now();
8436 }
8437
8438 // allow content to be cached if it was loaded successfully (bug #482935)
8439 bool contentComplete = NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1)));
8440
8441 // honor the cancelation status even if the underlying transaction
8442 // completed.
8443 if (mCanceled || NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0)))) status = mStatus;
8444
8445 if (mLoadInfo->TriggeringPrincipal()->IsSystemPrincipal()) {
8446 ReportSystemChannelTelemetry(status);
8447 }
8448
8449 if (LoadCachedContentIsPartial()) {
8450 if (NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1)))) {
8451 // mTransactionPump should be suspended
8452 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"
, 8453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "request != mTransactionPump"
") (" "byte-range transaction finished prematurely" ")"); do
{ *((volatile int*)__null) = 8453; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
8453 "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"
, 8453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "request != mTransactionPump"
") (" "byte-range transaction finished prematurely" ")"); do
{ *((volatile int*)__null) = 8453; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
8454
8455 if (request == mCachePump) {
8456 bool streamDone;
8457 status = OnDoneReadingPartialCacheEntry(&streamDone);
8458 if (NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1))) && !streamDone) return status;
8459 // otherwise, fall through and fire OnStopRequest...
8460 } else if (request == mTransactionPump) {
8461 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"
, 8461); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadConcurrentCacheAccess()"
")"); do { *((volatile int*)__null) = 8461; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8462 } else {
8463 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"
, 8463); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "unexpected request" ")"); do { *
((volatile int*)__null) = 8463; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
8464 }
8465 }
8466 // Do not to leave the transaction in a suspended state in error cases.
8467 if (NS_FAILED(status)((bool)(__builtin_expect(!!(NS_FAILED_impl(status)), 0))) && mTransaction) {
8468 nsresult rv = gHttpHandler->CancelTransaction(mTransaction, status);
8469 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
8470 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)
;
8471 }
8472 }
8473 }
8474
8475 nsCOMPtr<nsICompressConvStats> conv = do_QueryInterface(mCompressListener);
8476 if (conv) {
8477 conv->GetDecodedDataLength(&mDecodedBodySize);
8478 }
8479
8480 bool isFromNet = request == mTransactionPump;
8481
8482 if (mTransaction) {
8483 // determine if we should call DoAuthRetry
8484 bool authRetry = (mAuthRetryPending && NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1))) &&
8485 // we should only auth retry in this channel if are not
8486 // redirecting a new channel for authentication retries
8487 !StaticPrefs::network_auth_use_redirect_for_retries());
8488
8489 StoreStronglyFramed(mTransaction->ResponseIsComplete());
8490 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)
8491 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)
;
8492
8493 // Save the reference of |mTransaction| to |transactionWithStickyConn|
8494 // when it has a sticky connection.
8495 // In the case we need to retry an authentication request, we need to
8496 // reuse the connection of |transactionWithStickyConn|.
8497 RefPtr<HttpTransactionShell> transactionWithStickyConn;
8498 if (mCaps & NS_HTTP_STICKY_CONNECTION(1 << 2) ||
8499 mTransaction->HasStickyConnection()) {
8500 transactionWithStickyConn = mTransaction;
8501 // Make sure we use the updated caps and connection info from transaction.
8502 // We read these values when the transaction is already closed, so there
8503 // should be no race.
8504 if (mTransaction->Http2Disabled()) {
8505 mCaps |= NS_HTTP_DISALLOW_SPDY(1 << 7);
8506 }
8507 if (mTransaction->Http3Disabled()) {
8508 mCaps |= NS_HTTP_DISALLOW_HTTP3(1 << 21);
8509 }
8510 mConnectionInfo = mTransaction->GetConnInfo();
8511 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)
8512 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)
;
8513 }
8514
8515 // this code relies on the code in nsHttpTransaction::Close, which
8516 // tests for NS_HTTP_STICKY_CONNECTION to determine whether or not to
8517 // keep the connection around after the transaction is finished.
8518 //
8519 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)
8520 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)
8521 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)
;
8522 // We must check caps for stickinness also on the transaction because it
8523 // might have been updated by the transaction itself during inspection of
8524 // the reposnse headers yet on the socket thread (found connection based
8525 // auth schema).
8526
8527 if ((NS_FAILED(status)((bool)(__builtin_expect(!!(NS_FAILED_impl(status)), 0)))) && transactionWithStickyConn) {
8528 // Close (don't reuse) the sticky connection if this channel has been
8529 // cancelled. There are proxy servers known to get confused when we send
8530 // a new request over such a half-stated connection.
8531 if (!LoadAuthConnectionRestartable()) {
8532 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)
;
8533 transactionWithStickyConn->DontReuseConnection();
8534 }
8535 }
8536
8537 if (mCaps & NS_HTTP_STICKY_CONNECTION(1 << 2)) {
8538 mTransaction->SetH2WSConnRefTaken();
8539 }
8540
8541 mTransferSize = mTransaction->GetTransferSize();
8542 mRequestSize = mTransaction->GetRequestSize();
8543
8544 RecordHTTPSUpgradeTelemetry(mURI, mLoadInfo);
8545
8546 RecordIPAddressSpaceTelemetry(NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1))), mURI, mLoadInfo,
8547 mPeerAddr);
8548
8549 // If we are using the transaction to serve content, we also save the
8550 // time since async open in the cache entry so we can compare telemetry
8551 // between cache and net response.
8552 // Do not store the time of conditional requests because even if we
8553 // fetch the data from the server, the time includes loading of the old
8554 // cache entry which would skew the network load time.
8555 if (request == mTransactionPump && mCacheEntry && !mDidReval &&
8556 !LoadCustomConditionalRequest() && !mAsyncOpenTime.IsNull() &&
8557 !mOnStartRequestTimestamp.IsNull()) {
8558 uint64_t onStartTime =
8559 (mOnStartRequestTimestamp - mAsyncOpenTime).ToMilliseconds();
8560 uint64_t onStopTime =
8561 (TimeStamp::Now() - mAsyncOpenTime).ToMilliseconds();
8562 Unused << mCacheEntry->SetNetworkTimes(onStartTime, onStopTime);
8563 }
8564
8565 mResponseTrailers = mTransaction->TakeResponseTrailers();
8566
8567 if (nsIOService::UseSocketProcess() && mTransaction) {
8568 mOnStopRequestStartTime = mTransaction->GetOnStopRequestStartTime();
8569 if (!mOnStopRequestStartTime.IsNull()) {
8570 PerfStats::RecordMeasurement(
8571 PerfStats::Metric::OnStopRequestSocketToParent,
8572 TimeStamp::Now() - mOnStopRequestStartTime);
8573 }
8574 } else {
8575 mOnStopRequestStartTime = TimeStamp::Now();
8576 }
8577
8578 // at this point, we're done with the transaction
8579 mTransactionTimings = mTransaction->Timings();
8580 mTransaction = nullptr;
8581 mTransactionPump = nullptr;
8582
8583 // We no longer need the dns prefetch object
8584 if (mDNSPrefetch && mDNSPrefetch->TimingsValid() &&
8585 !mTransactionTimings.requestStart.IsNull() &&
8586 !mTransactionTimings.connectStart.IsNull() &&
8587 mDNSPrefetch->EndTimestamp() <= mTransactionTimings.connectStart) {
8588 // We only need the domainLookup timestamps when not using a
8589 // persistent connection, meaning if the endTimestamp < connectStart
8590 mTransactionTimings.domainLookupStart = mDNSPrefetch->StartTimestamp();
8591 mTransactionTimings.domainLookupEnd = mDNSPrefetch->EndTimestamp();
8592 }
8593 mDNSPrefetch = nullptr;
8594
8595 // handle auth retry...
8596 if (authRetry) {
8597 mAuthRetryPending = false;
8598 auto continueOSR = [authRetry, isFromNet, contentComplete,
8599 transactionWithStickyConn](auto* self,
8600 nsresult aStatus) {
8601 return self->ContinueOnStopRequestAfterAuthRetry(
8602 aStatus, authRetry, isFromNet, contentComplete,
8603 transactionWithStickyConn);
8604 };
8605 status = DoAuthRetry(transactionWithStickyConn, continueOSR);
8606 if (NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1)))) {
8607 return NS_OK;
8608 }
8609 }
8610 return ContinueOnStopRequestAfterAuthRetry(status, authRetry, isFromNet,
8611 contentComplete,
8612 transactionWithStickyConn);
8613 }
8614
8615 return ContinueOnStopRequest(status, isFromNet, contentComplete);
8616}
8617
8618nsresult nsHttpChannel::ContinueOnStopRequestAfterAuthRetry(
8619 nsresult aStatus, bool aAuthRetry, bool aIsFromNet, bool aContentComplete,
8620 HttpTransactionShell* aTransWithStickyConn) {
8621 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)
8622 ("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)
8623 "[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)
8624 " 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)
8625 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)
8626 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)
;
8627
8628 if (aAuthRetry && NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1)))) {
8629 return NS_OK;
8630 }
8631
8632 // If DoAuthRetry failed, or if we have been cancelled since showing
8633 // the auth. dialog, then we need to send OnStartRequest now
8634 if (aAuthRetry || (mAuthRetryPending && NS_FAILED(aStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus)), 0))))) {
8635 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"
, 8635); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatus)), 0)))"
") (" "should have a failure code here" ")"); do { *((volatile
int*)__null) = 8635; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
8636 // NOTE: since we have a failure status, we can ignore the return
8637 // value from onStartRequest.
8638 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)
8639 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)
;
8640 if (mListener) {
8641 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"
, 8642); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
") (" "We should not call OnStartRequest twice." ")"); do { *
((volatile int*)__null) = 8642; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
8642 "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"
, 8642); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
") (" "We should not call OnStartRequest twice." ")"); do { *
((volatile int*)__null) = 8642; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
8643 if (!LoadOnStartRequestCalled()) {
8644 nsCOMPtr<nsIStreamListener> listener(mListener);
8645 StoreOnStartRequestCalled(true);
8646 listener->OnStartRequest(this);
8647 }
8648 } else {
8649 StoreOnStartRequestCalled(true);
8650 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"
, 8650)
;
8651 }
8652 mAuthRetryPending = false;
8653 }
8654
8655 // if this transaction has been replaced, then bail.
8656 if (LoadTransactionReplaced()) {
8657 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)
;
8658 // This was just the network check for a 304 response.
8659 mFirstResponseSource = RESPONSE_PENDING;
8660 return NS_OK;
8661 }
8662
8663 bool upgradeWebsocket = mUpgradeProtocolCallback && aTransWithStickyConn &&
8664 mResponseHead &&
8665 ((mResponseHead->Status() == 101 &&
8666 mResponseHead->Version() == HttpVersion::v1_1) ||
8667 (mResponseHead->Status() == 200 &&
8668 mResponseHead->Version() == HttpVersion::v2_0));
8669
8670 bool upgradeConnect = mUpgradeProtocolCallback && aTransWithStickyConn &&
8671 (mCaps & NS_HTTP_CONNECT_ONLY(1 << 16)) && mResponseHead &&
8672 mResponseHead->Status() == 200;
8673
8674 if (upgradeWebsocket || upgradeConnect) {
8675 if (nsIOService::UseSocketProcess() && upgradeConnect) {
8676 // TODO: Support connection upgrade for socket process in bug 1632809.
8677 Unused << mUpgradeProtocolCallback->OnUpgradeFailed(
8678 NS_ERROR_NOT_IMPLEMENTED);
8679 return ContinueOnStopRequest(aStatus, aIsFromNet, aContentComplete);
8680 }
8681
8682 nsresult rv = gHttpHandler->CompleteUpgrade(aTransWithStickyConn,
8683 mUpgradeProtocolCallback);
8684 mUpgradeProtocolCallback = nullptr;
8685 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
8686 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)
8687 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)
;
8688
8689 // This ensures that WebSocketChannel::OnStopRequest will be
8690 // called with an error so the session is properly aborted.
8691 aStatus = rv;
8692 }
8693 }
8694
8695 return ContinueOnStopRequest(aStatus, aIsFromNet, aContentComplete);
8696}
8697
8698nsresult nsHttpChannel::ContinueOnStopRequest(nsresult aStatus, bool aIsFromNet,
8699 bool aContentComplete) {
8700 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)
8701 ("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)
8702 "[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)
8703 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)
;
8704
8705 // HTTP_CHANNEL_DISPOSITION TELEMETRY
8706 ChannelDisposition chanDisposition = kHttpCanceled;
8707 // HTTP_CHANNEL_DISPOSITION_UPGRADE TELEMETRY
8708 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE upgradeChanDisposition =
8709 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::cancel;
8710
8711 // HTTP 0.9 is more likely to be an error than really 0.9, so count it that
8712 // way
8713 if (mCanceled) {
8714 chanDisposition = kHttpCanceled;
8715 upgradeChanDisposition =
8716 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::cancel;
8717 } else if (!LoadUsedNetwork() ||
8718 (mRaceCacheWithNetwork &&
8719 mFirstResponseSource == RESPONSE_FROM_CACHE)) {
8720 chanDisposition = kHttpDisk;
8721 upgradeChanDisposition =
8722 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::disk;
8723 } else if (NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1))) && mResponseHead &&
8724 mResponseHead->Version() != HttpVersion::v0_9) {
8725 chanDisposition = kHttpNetOK;
8726 upgradeChanDisposition =
8727 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::netOk;
8728 } else if (!mTransferSize) {
8729 chanDisposition = kHttpNetEarlyFail;
8730 upgradeChanDisposition =
8731 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::netEarlyFail;
8732 } else {
8733 chanDisposition = kHttpNetLateFail;
8734 upgradeChanDisposition =
8735 Telemetry::LABELS_HTTP_CHANNEL_DISPOSITION_UPGRADE::netLateFail;
8736 }
8737 // Browser upgrading only happens on HTTPS pages for mixed passive content
8738 // when upgrading is enabled.
8739 nsCString upgradeKey;
8740 nsLiteralCString upgradeChanDispositionLabel =
8741 HttpChanDispositionToTelemetryLabel(upgradeChanDisposition);
8742 if (IsHTTPS()) {
8743 // Browser upgrading is disabled and the content is already HTTPS
8744 upgradeKey = "disabledNoReason"_ns;
8745 // Checks "security.mixed_content.upgrade_display_content" is true
8746 if (StaticPrefs::security_mixed_content_upgrade_display_content()) {
8747 if (mLoadInfo->GetBrowserUpgradeInsecureRequests()) {
8748 // HTTP content the browser has upgraded to HTTPS
8749 mozilla::glean::networking::http_channel_disposition_enabled_upgrade
8750 .Get(upgradeChanDispositionLabel)
8751 .Add(1);
8752 upgradeKey = "enabledUpgrade"_ns;
8753 } else {
8754 // Content wasn't upgraded but is already HTTPS
8755 mozilla::glean::networking::http_channel_disposition_enabled_no_reason
8756 .Get(upgradeChanDispositionLabel)
8757 .Add(1);
8758 upgradeKey = "enabledNoReason"_ns;
8759 }
8760 } else {
8761 mozilla::glean::networking::http_channel_disposition_disabled_no_reason
8762 .Get(upgradeChanDispositionLabel)
8763 .Add(1);
8764 }
8765 // shift http to https disposition enums
8766 chanDisposition =
8767 static_cast<ChannelDisposition>(chanDisposition + kHttpsCanceled);
8768 } else if (mLoadInfo->GetBrowserWouldUpgradeInsecureRequests()) {
8769 // HTTP content the browser would upgrade to HTTPS if upgrading was
8770 // enabled
8771 mozilla::glean::networking::http_channel_disposition_disabled_upgrade
8772 .Get(upgradeChanDispositionLabel)
8773 .Add(1);
8774 upgradeKey = "disabledUpgrade"_ns;
8775 } else if (StaticPrefs::security_mixed_content_upgrade_display_content()) {
8776 // HTTP content that wouldn't upgrade
8777 mozilla::glean::networking::http_channel_disposition_enabled_wont
8778 .Get(upgradeChanDispositionLabel)
8779 .Add(1);
8780 upgradeKey = "enabledWont"_ns;
8781 } else {
8782 mozilla::glean::networking::http_channel_disposition_disabled_wont
8783 .Get(upgradeChanDispositionLabel)
8784 .Add(1);
8785 upgradeKey = "disabledWont"_ns;
8786 }
8787
8788 Telemetry::AccumulateCategoricalKeyed(upgradeKey, upgradeChanDisposition);
8789
8790 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)
8791 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)
;
8792 Telemetry::Accumulate(Telemetry::HTTP_CHANNEL_DISPOSITION, chanDisposition);
8793 RecordHttpChanDispositionGlean(chanDisposition);
8794
8795 // Collect specific telemetry for measuring image, video, audio
8796 // success/failure rates in regular browsing mode and when auto upgrading of
8797 // subresources is enabled. Note that we only evaluate actual image types, not
8798 // favicons.
8799 nsContentPolicyType internalLoadType;
8800 mLoadInfo->GetInternalContentPolicyType(&internalLoadType);
8801 bool statusIsSuccess = NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1)));
8802 if (internalLoadType == nsIContentPolicy::TYPE_INTERNAL_IMAGE ||
8803 internalLoadType == nsIContentPolicy::TYPE_INTERNAL_IMAGE_PRELOAD) {
8804 if (mLoadInfo->GetBrowserDidUpgradeInsecureRequests()) {
8805 Telemetry::AccumulateCategorical(
8806 statusIsSuccess
8807 ? Telemetry::LABELS_MIXED_CONTENT_IMAGES::ImgUpSuccess
8808 : Telemetry::LABELS_MIXED_CONTENT_IMAGES::ImgUpFailure);
8809 } else {
8810 Telemetry::AccumulateCategorical(
8811 statusIsSuccess
8812 ? Telemetry::LABELS_MIXED_CONTENT_IMAGES::ImgNoUpSuccess
8813 : Telemetry::LABELS_MIXED_CONTENT_IMAGES::ImgNoUpFailure);
8814 }
8815 }
8816 if (internalLoadType == nsIContentPolicy::TYPE_INTERNAL_VIDEO) {
8817 if (mLoadInfo->GetBrowserDidUpgradeInsecureRequests()) {
8818 Telemetry::AccumulateCategorical(
8819 statusIsSuccess
8820 ? Telemetry::LABELS_MIXED_CONTENT_VIDEO::VideoUpSuccess
8821 : Telemetry::LABELS_MIXED_CONTENT_VIDEO::VideoUpFailure);
8822 } else {
8823 Telemetry::AccumulateCategorical(
8824 statusIsSuccess
8825 ? Telemetry::LABELS_MIXED_CONTENT_VIDEO::VideoNoUpSuccess
8826 : Telemetry::LABELS_MIXED_CONTENT_VIDEO::VideoNoUpFailure);
8827 }
8828 }
8829 if (internalLoadType == nsIContentPolicy::TYPE_INTERNAL_AUDIO) {
8830 if (mLoadInfo->GetBrowserDidUpgradeInsecureRequests()) {
8831 Telemetry::AccumulateCategorical(
8832 statusIsSuccess
8833 ? Telemetry::LABELS_MIXED_CONTENT_AUDIO::AudioUpSuccess
8834 : Telemetry::LABELS_MIXED_CONTENT_AUDIO::AudioUpFailure);
8835 } else {
8836 Telemetry::AccumulateCategorical(
8837 statusIsSuccess
8838 ? Telemetry::LABELS_MIXED_CONTENT_AUDIO::AudioNoUpSuccess
8839 : Telemetry::LABELS_MIXED_CONTENT_AUDIO::AudioNoUpFailure);
8840 }
8841 }
8842
8843 // if needed, check cache entry has all data we expect
8844 if (mCacheEntry && mCachePump && LoadConcurrentCacheAccess() &&
8845 aContentComplete) {
8846 int64_t size, contentLength;
8847 nsresult rv = CheckPartial(mCacheEntry, &size, &contentLength);
8848 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
8849 if (size == int64_t(-1)) {
8850 // mayhemer TODO - we have to restart read from cache here at the size
8851 // offset
8852 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"
, 8852); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ")")
; do { *((volatile int*)__null) = 8852; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8853 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)
8854 (" 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)
8855 "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)
;
8856 } else if (contentLength != int64_t(-1) && contentLength != size) {
8857 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)
;
8858 mCachedResponseHead = std::move(mResponseHead);
8859 // Ignore zero partial length because we also want to resume when
8860 // no data at all has been read from the cache.
8861 rv = MaybeSetupByteRangeRequest(size, contentLength, true);
8862 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && LoadIsPartialRequest()) {
8863 // Prevent read from cache again
8864 StoreCachedContentIsValid(CachedContentValidity::Invalid);
8865 StoreCachedContentIsPartial(1);
8866
8867 // We are about to perform a different network request.
8868 // We must set mRaceCacheWithNetwork to false because otherwise
8869 // we would ignore the network response thinking we didn't need it.
8870 mRaceCacheWithNetwork = false;
8871
8872 // Perform the range request
8873 rv = ContinueConnect();
8874 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
8875 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)
;
8876 mCachePump = nullptr;
8877 return NS_OK;
8878 }
8879 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)
8880 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)
;
8881 aStatus = NS_ERROR_NET_INTERRUPT;
8882 } else {
8883 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)
8884 ", 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)
8885 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)
;
8886 }
8887 }
8888 }
8889 }
8890
8891 StoreIsPending(false);
8892 mStatus = aStatus;
8893
8894 // perform any final cache operations before we close the cache entry.
8895 if (mCacheEntry && LoadRequestTimeInitialized()) {
8896 // New implementation just returns value of the !LoadCacheEntryIsReadOnly()
8897 // flag passed in. Old implementation checks on nsICache::ACCESS_WRITE
8898 // flag.
8899
8900 // Assume that write access is granted
8901 if (!LoadCacheEntryIsReadOnly()) {
8902 nsresult rv = FinalizeCacheEntry();
8903 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
8904 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)
;
8905 }
8906 }
8907 }
8908
8909 ReportRcwnStats(aIsFromNet);
8910
8911 // Register entry to the PerformanceStorage resource timing
8912 MaybeReportTimingData();
8913
8914 MaybeFlushConsoleReports();
8915
8916 if (!mEndMarkerAdded && profiler_thread_is_being_profiled_for_markers()) {
8917 // These do allocations/frees/etc; avoid if not active
8918 mEndMarkerAdded = true;
8919
8920 nsAutoCString requestMethod;
8921 GetRequestMethod(requestMethod);
8922
8923 int32_t priority = PRIORITY_NORMAL;
8924 GetPriority(&priority);
8925
8926 uint64_t size = 0;
8927 GetEncodedBodySize(&size);
8928
8929 nsAutoCString contentType;
8930 mozilla::Maybe<mozilla::net::HttpVersion> httpVersion = Nothing();
8931 mozilla::Maybe<uint32_t> responseStatus = Nothing();
8932 if (mResponseHead) {
8933 mResponseHead->ContentType(contentType);
8934 httpVersion = Some(mResponseHead->Version());
8935 responseStatus = Some(mResponseHead->Status());
8936 }
8937
8938 profiler_add_network_marker(
8939 mURI, requestMethod, priority, mChannelId, NetworkLoadType::LOAD_STOP,
8940 mLastStatusReported, TimeStamp::Now(), size, mCacheDisposition,
8941 mLoadInfo->GetInnerWindowID(),
8942 mLoadInfo->GetOriginAttributes().IsPrivateBrowsing(),
8943 mClassOfService.Flags(), &mTransactionTimings, std::move(mSource),
8944 httpVersion, responseStatus,
8945 Some(nsDependentCString(contentType.get())));
8946 }
8947
8948 if (mAuthRetryPending &&
8949 StaticPrefs::network_auth_use_redirect_for_retries()) {
8950 nsresult rv = OpenRedirectChannel(aStatus);
8951 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)
8952 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)
;
8953 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
8954 if (mListener) {
8955 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"
, 8956); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
") (" "We should not call OnStartRequest twice." ")"); do { *
((volatile int*)__null) = 8956; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
8956 "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"
, 8956); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStartRequestCalled()"
") (" "We should not call OnStartRequest twice." ")"); do { *
((volatile int*)__null) = 8956; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
8957 if (!LoadOnStartRequestCalled()) {
8958 nsCOMPtr<nsIStreamListener> listener(mListener);
8959 StoreOnStartRequestCalled(true);
8960 listener->OnStartRequest(this);
8961 }
8962 } else {
8963 StoreOnStartRequestCalled(true);
8964 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"
, 8964)
;
8965 }
8966 }
8967 mAuthRetryPending = false;
8968 }
8969
8970 if (StaticPrefs::network_http_network_error_logging_enabled() &&
8971 LoadUsedNetwork() && !mReportedNEL) {
8972 if (nsCOMPtr<nsINetworkErrorLogging> nel =
8973 components::NetworkErrorLogging::Service()) {
8974 nel->GenerateNELReport(this);
8975 }
8976 mReportedNEL = true;
8977 }
8978
8979 // notify "http-on-before-stop-request" observers
8980 gHttpHandler->OnBeforeStopRequest(this);
8981
8982 if (mListener) {
8983 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)
;
8984 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"
, 8985); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadOnStartRequestCalled()"
") (" "OnStartRequest should be called before OnStopRequest"
")"); do { *((volatile int*)__null) = 8985; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
8985 "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"
, 8985); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadOnStartRequestCalled()"
") (" "OnStartRequest should be called before OnStopRequest"
")"); do { *((volatile int*)__null) = 8985; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8986 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"
, 8987); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStopRequestCalled()"
") (" "We should not call OnStopRequest twice" ")"); do { *(
(volatile int*)__null) = 8987; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
8987 "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"
, 8987); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadOnStopRequestCalled()"
") (" "We should not call OnStopRequest twice" ")"); do { *(
(volatile int*)__null) = 8987; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
8988 StoreOnStopRequestCalled(true);
8989 mListener->OnStopRequest(this, aStatus);
8990 }
8991 StoreOnStopRequestCalled(true);
8992
8993 // The prefetch needs to be released on the main thread
8994 mDNSPrefetch = nullptr;
8995
8996 mRedirectChannel = nullptr;
8997
8998 // notify "http-on-stop-request" observers
8999 gHttpHandler->OnStopRequest(this);
9000
9001 RemoveAsNonTailRequest();
9002
9003 if (mChannelBlockedByOpaqueResponse && mCachedOpaqueResponseBlockingPref) {
9004 mResponseHead->ClearHeaders();
9005 }
9006 // If a preferred alt-data type was set, this signals the consumer is
9007 // interested in reading and/or writing the alt-data representation.
9008 // We need to hold a reference to the cache entry in case the listener calls
9009 // openAlternativeOutputStream() after CloseCacheEntry() clears mCacheEntry.
9010 if (!mPreferredCachedAltDataTypes.IsEmpty()) {
9011 mAltDataCacheEntry = mCacheEntry;
9012 }
9013
9014 CloseCacheEntry(!aContentComplete);
9015
9016 if (mLoadGroup) {
9017 mLoadGroup->RemoveRequest(this, nullptr, aStatus);
9018 }
9019
9020 // We don't need this info anymore
9021 CleanRedirectCacheChainIfNecessary();
9022
9023 ReleaseListeners();
9024
9025 return NS_OK;
9026}
9027
9028//-----------------------------------------------------------------------------
9029// nsHttpChannel::nsIStreamListener
9030//-----------------------------------------------------------------------------
9031
9032class OnTransportStatusAsyncEvent : public Runnable {
9033 public:
9034 OnTransportStatusAsyncEvent(nsITransportEventSink* aEventSink,
9035 nsresult aTransportStatus, int64_t aProgress,
9036 int64_t aProgressMax)
9037 : Runnable("net::OnTransportStatusAsyncEvent"),
9038 mEventSink(aEventSink),
9039 mTransportStatus(aTransportStatus),
9040 mProgress(aProgress),
9041 mProgressMax(aProgressMax) {
9042 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"
, 9042); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!NS_IsMainThread()"
") (" "Shouldn't be created on main thread" ")"); do { *((volatile
int*)__null) = 9042; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9043 }
9044
9045 NS_IMETHODvirtual nsresult Run() override {
9046 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"
, 9046); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should run on main thread" ")"); do { *((volatile int
*)__null) = 9046; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9047 if (mEventSink) {
9048 mEventSink->OnTransportStatus(nullptr, mTransportStatus, mProgress,
9049 mProgressMax);
9050 }
9051 return NS_OK;
9052 }
9053
9054 private:
9055 nsCOMPtr<nsITransportEventSink> mEventSink;
9056 nsresult mTransportStatus;
9057 int64_t mProgress;
9058 int64_t mProgressMax;
9059};
9060
9061NS_IMETHODIMPnsresult
9062nsHttpChannel::OnDataAvailable(nsIRequest* request, nsIInputStream* input,
9063 uint64_t offset, uint32_t count) {
9064 nsresult rv;
9065 AUTO_PROFILER_LABEL("nsHttpChannel::OnDataAvailable", NETWORK)mozilla::AutoProfilerLabel raiiObject9065( "nsHttpChannel::OnDataAvailable"
, nullptr, JS::ProfilingCategoryPair::NETWORK)
;
9066
9067 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)
9068 " 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)
9069 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)
;
9070
9071 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)
9072 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)
;
9073
9074 // don't send out OnDataAvailable notifications if we've been canceled.
9075 if (mCanceled) return mStatus;
9076
9077 if (mAuthRetryPending || WRONG_RACING_RESPONSE_SOURCE(request)(mRaceCacheWithNetwork && (((mFirstResponseSource == RESPONSE_FROM_CACHE
) && ((request) != mCachePump)) || ((mFirstResponseSource
== RESPONSE_FROM_NETWORK) && ((request) != mTransactionPump
))))
||
9078 (request == mTransactionPump && LoadTransactionReplaced())) {
9079 uint32_t n;
9080 return input->ReadSegments(NS_DiscardSegment, nullptr, count, &n);
9081 }
9082
9083 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"
, 9083); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mResponseHead"
") (" "No response head in ODA!!" ")"); do { *((volatile int
*)__null) = 9083; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9084
9085 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"
, 9086); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(LoadCachedContentIsPartial() && (request == mTransactionPump))"
") (" "transaction pump not suspended" ")"); do { *((volatile
int*)__null) = 9086; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
9086 "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"
, 9086); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(LoadCachedContentIsPartial() && (request == mTransactionPump))"
") (" "transaction pump not suspended" ")"); do { *((volatile
int*)__null) = 9086; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9087
9088 mIsReadingFromCache = (request == mCachePump);
9089
9090 if (mListener) {
9091 //
9092 // synthesize transport progress event. we do this here since we want
9093 // to delay OnProgress events until we start streaming data. this is
9094 // crucially important since it impacts the lock icon (see bug 240053).
9095 //
9096 nsresult transportStatus;
9097 if (request == mCachePump) {
9098 transportStatus = NS_NET_STATUS_READING;
9099 } else {
9100 transportStatus = NS_NET_STATUS_RECEIVING_FROM;
9101 }
9102
9103 // mResponseHead may reference new or cached headers, but either way it
9104 // holds our best estimate of the total content length. Even in the case
9105 // of a byte range request, the content length stored in the cached
9106 // response headers is what we want to use here.
9107
9108 int64_t progressMax = -1;
9109 rv = GetContentLength(&progressMax);
9110 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
9111 NS_WARNING("GetContentLength failed")NS_DebugBreak(NS_DEBUG_WARNING, "GetContentLength failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 9111)
;
9112 }
9113 int64_t progress = mLogicalOffset + count;
9114
9115 if ((progress > progressMax) && (progressMax != -1)) {
9116 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"
, 9118)
9117 "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"
, 9118)
9118 "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"
, 9118)
;
9119 }
9120
9121 // make sure params are in range for js
9122 if (!InScriptableRange(progressMax)) {
9123 progressMax = -1;
9124 }
9125
9126 if (!InScriptableRange(progress)) {
9127 progress = -1;
9128 }
9129
9130 if (NS_IsMainThread()) {
9131 OnTransportStatus(nullptr, transportStatus, progress, progressMax);
9132 } else {
9133 rv = NS_DispatchToMainThread(new OnTransportStatusAsyncEvent(
9134 this, transportStatus, progress, progressMax));
9135 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"
, 9135); return rv; } } while (false)
;
9136 }
9137
9138 //
9139 // we have to manually keep the logical offset of the stream up-to-date.
9140 // we cannot depend solely on the offset provided, since we may have
9141 // already streamed some data from another source (see, for example,
9142 // OnDoneReadingPartialCacheEntry).
9143 //
9144 int64_t offsetBefore = 0;
9145 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(input);
9146 if (seekable && NS_FAILED(seekable->Tell(&offsetBefore))((bool)(__builtin_expect(!!(NS_FAILED_impl(seekable->Tell(
&offsetBefore))), 0)))
) {
9147 seekable = nullptr;
9148 }
9149
9150 if (nsIOService::UseSocketProcess() && mTransaction) {
9151 mOnDataAvailableStartTime = mTransaction->GetDataAvailableStartTime();
9152 if (!mOnDataAvailableStartTime.IsNull()) {
9153 PerfStats::RecordMeasurement(
9154 PerfStats::Metric::OnDataAvailableSocketToParent,
9155 TimeStamp::Now() - mOnDataAvailableStartTime);
9156 }
9157 } else {
9158 mOnDataAvailableStartTime = TimeStamp::Now();
9159 }
9160 nsresult rv =
9161 mListener->OnDataAvailable(this, input, mLogicalOffset, count);
9162 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
9163 // by contract mListener must read all of "count" bytes, but
9164 // nsInputStreamPump is tolerant to seekable streams that violate that
9165 // and it will redeliver incompletely read data. So we need to do
9166 // the same thing when updating the progress counter to stay in sync.
9167 int64_t offsetAfter, delta;
9168 if (seekable && NS_SUCCEEDED(seekable->Tell(&offsetAfter))((bool)(__builtin_expect(!!(!NS_FAILED_impl(seekable->Tell
(&offsetAfter))), 1)))
) {
9169 delta = offsetAfter - offsetBefore;
9170 if (delta != count) {
9171 count = delta;
9172
9173 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"
, 9173)
;
9174 nsCOMPtr<nsIConsoleService> consoleService;
9175 consoleService = mozilla::components::Console::Service();
9176 nsAutoString message(nsLiteralString(
9177 u"http channel Listener OnDataAvailable contract violation"));
9178 if (consoleService) {
9179 consoleService->LogStringMessage(message.get());
9180 }
9181 }
9182 }
9183 mLogicalOffset += count;
9184 }
9185
9186 return rv;
9187 }
9188
9189 return NS_ERROR_ABORT;
9190}
9191
9192//-----------------------------------------------------------------------------
9193// nsHttpChannel::nsIThreadRetargetableRequest
9194//-----------------------------------------------------------------------------
9195
9196NS_IMETHODIMPnsresult
9197nsHttpChannel::RetargetDeliveryTo(nsISerialEventTarget* aNewTarget) {
9198 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"
, 9198); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should be called on main thread only" ")"); do { *((volatile
int*)__null) = 9198; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9199
9200 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"
, 9200); return NS_ERROR_INVALID_ARG; } } while (false)
;
9201 if (aNewTarget->IsOnCurrentThread()) {
9202 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"
, 9202)
;
9203 return NS_OK;
9204 }
9205 if (!mTransactionPump && !mCachePump) {
9206 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)
9207 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)
;
9208 return NS_ERROR_NOT_AVAILABLE;
9209 }
9210
9211 nsresult rv = NS_OK;
9212 // If both cache pump and transaction pump exist, we're probably dealing
9213 // with partially cached content. So, we must be able to retarget both.
9214 nsCOMPtr<nsIThreadRetargetableRequest> retargetableCachePump;
9215 nsCOMPtr<nsIThreadRetargetableRequest> retargetableTransactionPump;
9216 if (mCachePump) {
9217 retargetableCachePump = do_QueryObject(mCachePump);
9218 // nsInputStreamPump should implement this interface.
9219 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"
, 9219); AnnotateMozCrashReason("MOZ_ASSERT" "(" "retargetableCachePump"
")"); do { *((volatile int*)__null) = 9219; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9220 rv = retargetableCachePump->RetargetDeliveryTo(aNewTarget);
9221 }
9222 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && mTransactionPump) {
9223 retargetableTransactionPump = do_QueryObject(mTransactionPump);
9224 // nsInputStreamPump should implement this interface.
9225 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"
, 9225); AnnotateMozCrashReason("MOZ_ASSERT" "(" "retargetableTransactionPump"
")"); do { *((volatile int*)__null) = 9225; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9226 rv = retargetableTransactionPump->RetargetDeliveryTo(aNewTarget);
9227
9228 // If retarget fails for transaction pump, we must restore mCachePump.
9229 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && retargetableCachePump) {
9230 nsCOMPtr<nsISerialEventTarget> main = GetMainThreadSerialEventTarget();
9231 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"
, 9231); return NS_ERROR_UNEXPECTED; } } while (false)
;
9232 rv = retargetableCachePump->RetargetDeliveryTo(main);
9233 }
9234 }
9235 return rv;
9236}
9237
9238NS_IMETHODIMPnsresult
9239nsHttpChannel::GetDeliveryTarget(nsISerialEventTarget** aEventTarget) {
9240 if (mCachePump) {
9241 return mCachePump->GetDeliveryTarget(aEventTarget);
9242 }
9243 if (mTransactionPump) {
9244 nsCOMPtr<nsIThreadRetargetableRequest> request =
9245 do_QueryInterface(mTransactionPump);
9246 return request->GetDeliveryTarget(aEventTarget);
9247 }
9248 return NS_ERROR_NOT_AVAILABLE;
9249}
9250
9251//-----------------------------------------------------------------------------
9252// nsHttpChannel::nsThreadRetargetableStreamListener
9253//-----------------------------------------------------------------------------
9254
9255NS_IMETHODIMPnsresult
9256nsHttpChannel::CheckListenerChain() {
9257 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"
, 9257); MOZ_PretendNoReturn(); } } while (0)
;
9258 nsresult rv = NS_OK;
9259 nsCOMPtr<nsIThreadRetargetableStreamListener> retargetableListener =
9260 do_QueryInterface(mListener, &rv);
9261 if (retargetableListener) {
9262 rv = retargetableListener->CheckListenerChain();
9263 }
9264 return rv;
9265}
9266
9267NS_IMETHODIMPnsresult
9268nsHttpChannel::OnDataFinished(nsresult aStatus) {
9269 nsCOMPtr<nsIThreadRetargetableStreamListener> listener =
9270 do_QueryInterface(mListener);
9271
9272 if (listener) {
9273 return listener->OnDataFinished(aStatus);
9274 }
9275
9276 return NS_OK;
9277}
9278
9279//-----------------------------------------------------------------------------
9280// nsHttpChannel::nsITransportEventSink
9281//-----------------------------------------------------------------------------
9282
9283NS_IMETHODIMPnsresult
9284nsHttpChannel::OnTransportStatus(nsITransport* trans, nsresult status,
9285 int64_t progress, int64_t progressMax) {
9286 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"
, 9286); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should be on main thread only" ")"); do { *((volatile
int*)__null) = 9286; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9287 // cache the progress sink so we don't have to query for it each time.
9288 if (!mProgressSink) GetCallback(mProgressSink);
9289
9290 mLastTransportStatus = status;
9291 if (status == NS_NET_STATUS_CONNECTED_TO ||
9292 status == NS_NET_STATUS_WAITING_FOR) {
9293 bool isTrr = false;
9294 bool echConfigUsed = false;
9295 if (mTransaction) {
9296 mTransaction->GetNetworkAddresses(mSelfAddr, mPeerAddr, isTrr,
9297 mEffectiveTRRMode, mTRRSkipReason,
9298 echConfigUsed);
9299
9300 } else {
9301 nsCOMPtr<nsISocketTransport> socketTransport = do_QueryInterface(trans);
9302 if (socketTransport) {
9303 socketTransport->GetPeerAddr(&mPeerAddr);
9304 socketTransport->GetSelfAddr(&mSelfAddr);
9305 socketTransport->ResolvedByTRR(&isTrr);
9306 socketTransport->GetEffectiveTRRMode(&mEffectiveTRRMode);
9307 socketTransport->GetEchConfigUsed(&echConfigUsed);
9308 }
9309 }
9310
9311 StoreResolvedByTRR(isTrr);
9312 StoreEchConfigUsed(echConfigUsed);
9313 }
9314
9315 // block socket status event after Cancel or OnStopRequest has been called.
9316 if (mProgressSink && NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1))) && LoadIsPending()) {
9317 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)
9318 " 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)
9319 (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)
9320 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)
;
9321
9322 nsAutoCString host;
9323 mURI->GetHost(host);
9324 if (!(mLoadFlags & LOAD_BACKGROUND)) {
9325 mProgressSink->OnStatus(this, status, NS_ConvertUTF8toUTF16(host).get());
9326 } else {
9327 nsCOMPtr<nsIParentChannel> parentChannel;
9328 NS_QueryNotificationCallbacks(this, parentChannel);
9329 // If the event sink is |HttpChannelParent|, we have to send status
9330 // events to it even if LOAD_BACKGROUND is set. |HttpChannelParent|
9331 // needs to be aware of whether the status is
9332 // |NS_NET_STATUS_RECEIVING_FROM| or |NS_NET_STATUS_READING|.
9333 // LOAD_BACKGROUND is checked again in |HttpChannelChild|, so the final
9334 // consumer won't get this event.
9335 if (SameCOMIdentity(parentChannel, mProgressSink)) {
9336 mProgressSink->OnStatus(this, status,
9337 NS_ConvertUTF8toUTF16(host).get());
9338 }
9339 }
9340
9341 if (progress > 0) {
9342 if ((progress > progressMax) && (progressMax != -1)) {
9343 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"
, 9343)
;
9344 }
9345
9346 // Try to get mProgressSink if it was nulled out during OnStatus.
9347 if (!mProgressSink) {
9348 GetCallback(mProgressSink);
9349 }
9350 if (mProgressSink) {
9351 mProgressSink->OnProgress(this, progress, progressMax);
9352 }
9353 }
9354 }
9355
9356 return NS_OK;
9357}
9358
9359//-----------------------------------------------------------------------------
9360// nsHttpChannel::nsICacheInfoChannel
9361//-----------------------------------------------------------------------------
9362
9363NS_IMETHODIMPnsresult
9364nsHttpChannel::IsFromCache(bool* value) {
9365 if (!LoadIsPending()) return NS_ERROR_NOT_AVAILABLE;
9366
9367 if (!mRaceCacheWithNetwork) {
9368 // return false if reading a partial cache entry; the data isn't
9369 // entirely from the cache!
9370 *value = (mCachePump || (mLoadFlags & LOAD_ONLY_IF_MODIFIED)) &&
9371 CachedContentIsValid() && !LoadCachedContentIsPartial();
9372 return NS_OK;
9373 }
9374
9375 // If we are racing network and cache (or skipping the cache)
9376 // we just return the first response source.
9377 *value = mFirstResponseSource == RESPONSE_FROM_CACHE;
9378
9379 return NS_OK;
9380}
9381
9382NS_IMETHODIMPnsresult
9383nsHttpChannel::GetCacheEntryId(uint64_t* aCacheEntryId) {
9384 bool fromCache = false;
9385 if (NS_FAILED(IsFromCache(&fromCache))((bool)(__builtin_expect(!!(NS_FAILED_impl(IsFromCache(&fromCache
))), 0)))
|| !fromCache || !mCacheEntry ||
9386 NS_FAILED(mCacheEntry->GetCacheEntryId(aCacheEntryId))((bool)(__builtin_expect(!!(NS_FAILED_impl(mCacheEntry->GetCacheEntryId
(aCacheEntryId))), 0)))
) {
9387 return NS_ERROR_NOT_AVAILABLE;
9388 }
9389
9390 return NS_OK;
9391}
9392
9393NS_IMETHODIMPnsresult
9394nsHttpChannel::GetCacheTokenFetchCount(uint32_t* _retval) {
9395 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"
, 9395); return NS_ERROR_INVALID_POINTER; } } while (false)
;
9396 nsCOMPtr<nsICacheEntry> cacheEntry =
9397 mCacheEntry ? mCacheEntry : mAltDataCacheEntry;
9398 if (!cacheEntry) {
9399 return NS_ERROR_NOT_AVAILABLE;
9400 }
9401
9402 return cacheEntry->GetFetchCount(_retval);
9403}
9404
9405NS_IMETHODIMPnsresult
9406nsHttpChannel::GetCacheTokenExpirationTime(uint32_t* _retval) {
9407 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"
, 9407); return NS_ERROR_INVALID_POINTER; } } while (false)
;
9408 if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
9409
9410 return mCacheEntry->GetExpirationTime(_retval);
9411}
9412
9413NS_IMETHODIMPnsresult
9414nsHttpChannel::SetAllowStaleCacheContent(bool aAllowStaleCacheContent) {
9415 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)
9416 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)
;
9417 StoreAllowStaleCacheContent(aAllowStaleCacheContent);
9418 return NS_OK;
9419}
9420NS_IMETHODIMPnsresult
9421nsHttpChannel::GetAllowStaleCacheContent(bool* aAllowStaleCacheContent) {
9422 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"
, 9422); return NS_ERROR_INVALID_ARG; } } while (false)
;
9423 *aAllowStaleCacheContent = LoadAllowStaleCacheContent();
9424 return NS_OK;
9425}
9426
9427NS_IMETHODIMPnsresult
9428nsHttpChannel::SetForceValidateCacheContent(bool aForceValidateCacheContent) {
9429 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)
9430 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)
;
9431 StoreForceValidateCacheContent(aForceValidateCacheContent);
9432 return NS_OK;
9433}
9434NS_IMETHODIMPnsresult
9435nsHttpChannel::GetForceValidateCacheContent(bool* aForceValidateCacheContent) {
9436 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"
, 9436); return NS_ERROR_INVALID_ARG; } } while (false)
;
9437 *aForceValidateCacheContent = LoadForceValidateCacheContent();
9438 return NS_OK;
9439}
9440
9441NS_IMETHODIMPnsresult
9442nsHttpChannel::SetPreferCacheLoadOverBypass(bool aPreferCacheLoadOverBypass) {
9443 StorePreferCacheLoadOverBypass(aPreferCacheLoadOverBypass);
9444 return NS_OK;
9445}
9446NS_IMETHODIMPnsresult
9447nsHttpChannel::GetPreferCacheLoadOverBypass(bool* aPreferCacheLoadOverBypass) {
9448 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"
, 9448); return NS_ERROR_INVALID_ARG; } } while (false)
;
9449 *aPreferCacheLoadOverBypass = LoadPreferCacheLoadOverBypass();
9450 return NS_OK;
9451}
9452
9453NS_IMETHODIMPnsresult
9454nsHttpChannel::PreferAlternativeDataType(
9455 const nsACString& aType, const nsACString& aContentType,
9456 PreferredAlternativeDataDeliveryType aDeliverAltData) {
9457 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"
, 9457); 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"
, 9457, 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"
, 9457); } } 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"
, 9457); 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"
, 9457); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
9458 mPreferredCachedAltDataTypes.AppendElement(PreferredAlternativeDataTypeParams(
9459 nsCString(aType), nsCString(aContentType), aDeliverAltData));
9460 return NS_OK;
9461}
9462
9463const nsTArray<PreferredAlternativeDataTypeParams>&
9464nsHttpChannel::PreferredAlternativeDataTypes() {
9465 return mPreferredCachedAltDataTypes;
9466}
9467
9468NS_IMETHODIMPnsresult
9469nsHttpChannel::GetAlternativeDataType(nsACString& aType) {
9470 // must be called during or after OnStartRequest
9471 if (!LoadAfterOnStartRequestBegun()) {
9472 return NS_ERROR_NOT_AVAILABLE;
9473 }
9474 aType = mAvailableCachedAltDataType;
9475 return NS_OK;
9476}
9477
9478NS_IMETHODIMPnsresult
9479nsHttpChannel::OpenAlternativeOutputStream(const nsACString& type,
9480 int64_t predictedSize,
9481 nsIAsyncOutputStream** _retval) {
9482 // OnStopRequest will clear mCacheEntry, but we may use mAltDataCacheEntry
9483 // if the consumer called PreferAlternativeDataType()
9484 nsCOMPtr<nsICacheEntry> cacheEntry =
9485 mCacheEntry ? mCacheEntry : mAltDataCacheEntry;
9486 if (!cacheEntry) {
9487 return NS_ERROR_NOT_AVAILABLE;
9488 }
9489 nsresult rv =
9490 cacheEntry->OpenAlternativeOutputStream(type, predictedSize, _retval);
9491 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
9492 // Clear this metadata flag in case it exists.
9493 // The caller of this method may set it again.
9494 cacheEntry->SetMetaDataElement("alt-data-from-child", nullptr);
9495 }
9496 return rv;
9497}
9498
9499NS_IMETHODIMPnsresult
9500nsHttpChannel::GetOriginalInputStream(nsIInputStreamReceiver* aReceiver) {
9501 if (aReceiver == nullptr) {
9502 return NS_ERROR_INVALID_ARG;
9503 }
9504 nsCOMPtr<nsIInputStream> inputStream;
9505
9506 nsCOMPtr<nsICacheEntry> cacheEntry =
9507 mCacheEntry ? mCacheEntry : mAltDataCacheEntry;
9508 if (cacheEntry) {
9509 cacheEntry->OpenInputStream(0, getter_AddRefs(inputStream));
9510 }
9511 aReceiver->OnInputStreamReady(inputStream);
9512 return NS_OK;
9513}
9514
9515NS_IMETHODIMPnsresult
9516nsHttpChannel::GetAlternativeDataInputStream(nsIInputStream** aInputStream) {
9517 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"
, 9517); return NS_ERROR_INVALID_POINTER; } } while (false)
;
9518
9519 *aInputStream = nullptr;
9520
9521 nsCOMPtr<nsICacheEntry> cacheEntry =
9522 mCacheEntry ? mCacheEntry : mAltDataCacheEntry;
9523 if (!mAvailableCachedAltDataType.IsEmpty() && cacheEntry) {
9524 nsresult rv = cacheEntry->OpenAlternativeInputStream(
9525 mAvailableCachedAltDataType, aInputStream);
9526 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"
, 9526); return rv; } } while (false)
;
9527 }
9528 return NS_OK;
9529}
9530
9531//-----------------------------------------------------------------------------
9532// nsHttpChannel::nsICachingChannel
9533//-----------------------------------------------------------------------------
9534
9535NS_IMETHODIMPnsresult
9536nsHttpChannel::IsRacing(bool* aIsRacing) {
9537 if (!LoadAfterOnStartRequestBegun()) {
9538 return NS_ERROR_NOT_AVAILABLE;
9539 }
9540 *aIsRacing = mRaceCacheWithNetwork;
9541 return NS_OK;
9542}
9543
9544NS_IMETHODIMPnsresult
9545nsHttpChannel::GetCacheToken(nsISupports** token) {
9546 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"
, 9546); return NS_ERROR_INVALID_POINTER; } } while (false)
;
9547 if (!mCacheEntry) return NS_ERROR_NOT_AVAILABLE;
9548 return CallQueryInterface(mCacheEntry, token);
9549}
9550
9551NS_IMETHODIMPnsresult
9552nsHttpChannel::SetCacheToken(nsISupports* token) {
9553 return NS_ERROR_NOT_IMPLEMENTED;
9554}
9555
9556NS_IMETHODIMPnsresult
9557nsHttpChannel::GetCacheKey(uint32_t* key) {
9558 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"
, 9558); return NS_ERROR_INVALID_POINTER; } } while (false)
;
9559
9560 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)
;
9561
9562 *key = mPostID;
9563 return NS_OK;
9564}
9565
9566NS_IMETHODIMPnsresult
9567nsHttpChannel::SetCacheKey(uint32_t key) {
9568 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)
;
9569
9570 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"
, 9570); 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"
, 9570, 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"
, 9570); } } 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"
, 9570); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 9570; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
9571
9572 mPostID = key;
9573 return NS_OK;
9574}
9575
9576NS_IMETHODIMPnsresult
9577nsHttpChannel::GetCacheOnlyMetadata(bool* aOnlyMetadata) {
9578 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"
, 9578); return NS_ERROR_INVALID_ARG; } } while (false)
;
9579 *aOnlyMetadata = LoadCacheOnlyMetadata();
9580 return NS_OK;
9581}
9582
9583NS_IMETHODIMPnsresult
9584nsHttpChannel::SetCacheOnlyMetadata(bool aOnlyMetadata) {
9585 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)
9586 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)
;
9587
9588 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"
, 9588); 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"
, 9588, 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"
, 9588); } } 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"
, 9588); 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"
, 9588); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
9589
9590 StoreCacheOnlyMetadata(aOnlyMetadata);
9591 if (aOnlyMetadata) {
9592 mLoadFlags |= LOAD_ONLY_IF_MODIFIED;
9593 }
9594
9595 return NS_OK;
9596}
9597
9598NS_IMETHODIMPnsresult
9599nsHttpChannel::GetPin(bool* aPin) {
9600 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"
, 9600); return NS_ERROR_INVALID_ARG; } } while (false)
;
9601 *aPin = LoadPinCacheContent();
9602 return NS_OK;
9603}
9604
9605NS_IMETHODIMPnsresult
9606nsHttpChannel::SetPin(bool aPin) {
9607 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)
;
9608
9609 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"
, 9609); 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"
, 9609, 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"
, 9609); } } 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"
, 9609); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 9609; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
9610
9611 StorePinCacheContent(aPin);
9612 return NS_OK;
9613}
9614
9615NS_IMETHODIMPnsresult
9616nsHttpChannel::ForceCacheEntryValidFor(uint32_t aSecondsToTheFuture) {
9617 if (!mCacheEntry) {
9618 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)
9619 ("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)
9620 "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)
9621 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)
;
9622 } else {
9623 mCacheEntry->ForceValidFor(aSecondsToTheFuture);
9624
9625 nsAutoCString key;
9626 mCacheEntry->GetKey(key);
9627
9628 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)
9629 ("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)
9630 "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)
9631 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)
;
9632 }
9633
9634 return NS_OK;
9635}
9636
9637//-----------------------------------------------------------------------------
9638// nsHttpChannel::nsIResumableChannel
9639//-----------------------------------------------------------------------------
9640
9641NS_IMETHODIMPnsresult
9642nsHttpChannel::ResumeAt(uint64_t aStartPos, const nsACString& aEntityID) {
9643 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)
9644 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)
;
9645 mEntityID = aEntityID;
9646 mStartPos = aStartPos;
9647 StoreResuming(true);
9648 return NS_OK;
9649}
9650
9651nsresult nsHttpChannel::DoAuthRetry(
9652 HttpTransactionShell* aTransWithStickyConn,
9653 const std::function<nsresult(nsHttpChannel*, nsresult)>&
9654 aContinueOnStopRequestFunc) {
9655 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)
9656 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)
;
9657
9658 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"
, 9658); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mTransaction"
") (" "should not have a transaction" ")"); do { *((volatile
int*)__null) = 9658; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9659
9660 // Note that we don't have to toggle |IsPending| anymore. See the reasons
9661 // below.
9662 // 1. We can't suspend the channel during "http-on-modify-request"
9663 // when |IsPending| is false.
9664 // 2. We don't check |IsPending| in SetRequestHeader now.
9665
9666 // Reset RequestObserversCalled because we've probably called the request
9667 // observers once already.
9668 StoreRequestObserversCalled(false);
9669
9670 // fetch cookies, and add them to the request header.
9671 // the server response could have included cookies that must be sent with
9672 // this authentication attempt (bug 84794).
9673 // TODO: save cookies from auth response and send them here (bug 572151).
9674 AddCookiesToRequest();
9675
9676 // notify "http-on-modify-request" observers
9677 CallOnModifyRequestObservers();
9678
9679 RefPtr<HttpTransactionShell> trans(aTransWithStickyConn);
9680 return CallOrWaitForResume(
9681 [trans{std::move(trans)}, aContinueOnStopRequestFunc](auto* self) {
9682 return self->ContinueDoAuthRetry(trans, aContinueOnStopRequestFunc);
9683 });
9684}
9685
9686nsresult nsHttpChannel::ContinueDoAuthRetry(
9687 HttpTransactionShell* aTransWithStickyConn,
9688 const std::function<nsresult(nsHttpChannel*, nsresult)>&
9689 aContinueOnStopRequestFunc) {
9690 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)
;
9691 StoreIsPending(true);
9692
9693 // get rid of the old response headers
9694 mResponseHead = nullptr;
9695
9696 // rewind the upload stream
9697 if (mUploadStream) {
9698 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
9699 nsresult rv = NS_ERROR_NO_INTERFACE;
9700 if (seekable) {
9701 rv = seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
9702 }
9703
9704 // This should not normally happen, but it's possible that big memory
9705 // blobs originating in the other process can't be rewinded.
9706 // In that case we just fail the request, otherwise the content length
9707 // will not match and this load will never complete.
9708 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"
, 9708); return rv; } } while (false)
;
9709 }
9710
9711 // always set sticky connection flag
9712 mCaps |= NS_HTTP_STICKY_CONNECTION(1 << 2);
9713 // and when needed, allow restart regardless the sticky flag
9714 if (LoadAuthConnectionRestartable()) {
9715 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)
;
9716 mCaps |= NS_HTTP_CONNECTION_RESTARTABLE(1 << 13);
9717 StoreAuthConnectionRestartable(false);
9718 } else {
9719 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)
;
9720 mCaps &= ~NS_HTTP_CONNECTION_RESTARTABLE(1 << 13);
9721 }
9722
9723 // notify "http-on-before-connect" observers
9724 gHttpHandler->OnBeforeConnect(this);
9725
9726 RefPtr<HttpTransactionShell> trans(aTransWithStickyConn);
9727 return CallOrWaitForResume(
9728 [trans{std::move(trans)}, aContinueOnStopRequestFunc](auto* self) {
9729 nsresult rv = self->DoConnect(trans);
9730 return aContinueOnStopRequestFunc(self, rv);
9731 });
9732}
9733
9734//-----------------------------------------------------------------------------
9735// nsHttpChannel::nsIAsyncVerifyRedirectCallback
9736//-----------------------------------------------------------------------------
9737
9738nsresult nsHttpChannel::WaitForRedirectCallback() {
9739 nsresult rv;
9740 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)
;
9741
9742 if (mTransactionPump) {
9743 rv = mTransactionPump->Suspend();
9744 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"
, 9744); return rv; } } while (false)
;
9745 }
9746 if (mCachePump) {
9747 rv = mCachePump->Suspend();
9748 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) && mTransactionPump) {
9749#ifdef DEBUG1
9750 nsresult resume =
9751#endif
9752 mTransactionPump->Resume();
9753 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"
, 9753); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(resume)), 1)))"
") (" "Failed to resume transaction pump" ")"); do { *((volatile
int*)__null) = 9753; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9754 }
9755 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"
, 9755); return rv; } } while (false)
;
9756 }
9757
9758 StoreWaitingForRedirectCallback(true);
9759 return NS_OK;
9760}
9761
9762NS_IMETHODIMPnsresult
9763nsHttpChannel::OnRedirectVerifyCallback(nsresult result) {
9764 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)
9765 ("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)
9766 "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)
9767 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)
9768 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)
;
9769 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"
, 9770); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWaitingForRedirectCallback()"
") (" "Someone forgot to call WaitForRedirectCallback() ?!" ")"
); do { *((volatile int*)__null) = 9770; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9770 "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"
, 9770); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWaitingForRedirectCallback()"
") (" "Someone forgot to call WaitForRedirectCallback() ?!" ")"
); do { *((volatile int*)__null) = 9770; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9771 StoreWaitingForRedirectCallback(false);
9772
9773 if (mCanceled && NS_SUCCEEDED(result)((bool)(__builtin_expect(!!(!NS_FAILED_impl(result)), 1)))) result = NS_BINDING_ABORTED;
9774
9775 for (uint32_t i = mRedirectFuncStack.Length(); i > 0;) {
9776 --i;
9777 // Pop the last function pushed to the stack
9778 nsContinueRedirectionFunc func = mRedirectFuncStack.PopLastElement();
9779
9780 // Call it with the result we got from the callback or the deeper
9781 // function call.
9782 result = (this->*func)(result);
9783
9784 // If a new function has been pushed to the stack and placed us in the
9785 // waiting state, we need to break the chain and wait for the callback
9786 // again.
9787 if (LoadWaitingForRedirectCallback()) break;
9788 }
9789
9790 if (NS_FAILED(result)((bool)(__builtin_expect(!!(NS_FAILED_impl(result)), 0))) && !mCanceled) {
9791 // First, cancel this channel if we are in failure state to set mStatus
9792 // and let it be propagated to pumps.
9793 Cancel(result);
9794 }
9795
9796 if (!LoadWaitingForRedirectCallback()) {
9797 // We are not waiting for the callback. At this moment we must release
9798 // reference to the redirect target channel, otherwise we may leak.
9799 // However, if we are redirecting due to auth retries, we open the
9800 // redirected channel after OnStopRequest. In that case we should not
9801 // release the reference
9802 if (!StaticPrefs::network_auth_use_redirect_for_retries() ||
9803 !mAuthRetryPending) {
9804 mRedirectChannel = nullptr;
9805 }
9806 }
9807
9808 // We always resume the pumps here. If all functions on stack have been
9809 // called we need OnStopRequest to be triggered, and if we broke out of the
9810 // loop above (and are thus waiting for a new callback) the suspension
9811 // count must be balanced in the pumps.
9812 if (mTransactionPump) mTransactionPump->Resume();
9813 if (mCachePump) mCachePump->Resume();
9814
9815 return result;
9816}
9817
9818void nsHttpChannel::PushRedirectAsyncFunc(nsContinueRedirectionFunc func) {
9819 mRedirectFuncStack.AppendElement(func);
9820}
9821
9822void nsHttpChannel::PopRedirectAsyncFunc(nsContinueRedirectionFunc func) {
9823 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"
, 9824); AnnotateMozCrashReason("MOZ_ASSERT" "(" "func == mRedirectFuncStack.LastElement()"
") (" "Trying to pop wrong method from redirect async stack!"
")"); do { *((volatile int*)__null) = 9824; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9824 "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"
, 9824); AnnotateMozCrashReason("MOZ_ASSERT" "(" "func == mRedirectFuncStack.LastElement()"
") (" "Trying to pop wrong method from redirect async stack!"
")"); do { *((volatile int*)__null) = 9824; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9825
9826 mRedirectFuncStack.RemoveLastElement();
9827}
9828
9829//-----------------------------------------------------------------------------
9830// nsIDNSListener functions
9831//-----------------------------------------------------------------------------
9832
9833NS_IMETHODIMPnsresult
9834nsHttpChannel::OnLookupComplete(nsICancelable* request, nsIDNSRecord* rec,
9835 nsresult status) {
9836 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"
, 9836); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Expecting DNS callback on main thread." ")"); do { *(
(volatile int*)__null) = 9836; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
9837
9838 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)
9839 ("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)
9840 "%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)
9841 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)
9842 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)
9843 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)
;
9844
9845 // Unset DNS cache refresh if it was requested,
9846 if (mCaps & NS_HTTP_REFRESH_DNS(1 << 3)) {
9847 mCaps &= ~NS_HTTP_REFRESH_DNS(1 << 3);
9848 if (mTransaction) {
9849 mTransaction->SetDNSWasRefreshed();
9850 }
9851 }
9852
9853 if (!mDNSBlockingPromise.IsEmpty()) {
9854 if (NS_SUCCEEDED(status)((bool)(__builtin_expect(!!(!NS_FAILED_impl(status)), 1)))) {
9855 nsCOMPtr<nsIDNSRecord> record(rec);
9856 mDNSBlockingPromise.Resolve(record, __func__);
9857 } else {
9858 mDNSBlockingPromise.Reject(status, __func__);
9859 }
9860 }
9861
9862 return NS_OK;
9863}
9864
9865void nsHttpChannel::OnHTTPSRRAvailable(nsIDNSHTTPSSVCRecord* aRecord) {
9866 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"
, 9866); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Expecting DNS callback on main thread." ")"); do { *(
(volatile int*)__null) = 9866; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
9867
9868 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)
9869 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)
;
9870
9871 if (mHTTPSSVCRecord) {
9872 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"
, 9872); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"OnHTTPSRRAvailable called twice!" ")"); do { *((volatile int
*)__null) = 9872; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
9873 return;
9874 }
9875
9876 nsCOMPtr<nsIDNSHTTPSSVCRecord> record = aRecord;
9877 mHTTPSSVCRecord.emplace(std::move(record));
9878 const nsCOMPtr<nsIDNSHTTPSSVCRecord>& httprr = mHTTPSSVCRecord.ref();
9879
9880 if (LoadWaitHTTPSSVCRecord()) {
9881 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"
, 9881); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mURI->SchemeIs(\"http\")"
")"); do { *((volatile int*)__null) = 9881; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9882
9883 StoreWaitHTTPSSVCRecord(false);
9884 nsresult rv = ContinueOnBeforeConnect(!!httprr, mStatus, !!httprr);
9885 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
9886 CloseCacheEntry(false);
9887 Unused << AsyncAbort(rv);
9888 }
9889 } else {
9890 // This channel is not canceled and the transaction is not created.
9891 if (httprr && NS_SUCCEEDED(mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mStatus)), 1))) && !mTransaction &&
9892 (mFirstResponseSource != RESPONSE_FROM_CACHE)) {
9893 bool hasIPAddress = false;
9894 Unused << httprr->GetHasIPAddresses(&hasIPAddress);
9895 Telemetry::Accumulate(Telemetry::DNS_HTTPSSVC_RECORD_RECEIVING_STAGE,
9896 hasIPAddress
9897 ? HTTPSSVC_WITH_IPHINT_RECEIVED_STAGE_0
9898 : HTTPSSVC_WITHOUT_IPHINT_RECEIVED_STAGE_0);
9899 StoreHTTPSSVCTelemetryReported(true);
9900 }
9901 }
9902}
9903
9904//-----------------------------------------------------------------------------
9905// nsHttpChannel internal functions
9906//-----------------------------------------------------------------------------
9907
9908// Creates an URI to the given location using current URI for base and charset
9909nsresult nsHttpChannel::CreateNewURI(const char* loc, nsIURI** newURI) {
9910 nsCOMPtr<nsIIOService> ioService;
9911 nsresult rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
9912 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
9913
9914 return ioService->NewURI(nsDependentCString(loc), nullptr, mURI, newURI);
9915}
9916
9917void nsHttpChannel::MaybeInvalidateCacheEntryForSubsequentGet() {
9918 // See RFC 2616 section 5.1.1. These are considered valid
9919 // methods which DO NOT invalidate cache-entries for the
9920 // referred resource. POST, PUT and DELETE as well as any
9921 // other method not listed here will potentially invalidate
9922 // any cached copy of the resource
9923 if (mRequestHead.IsGet() || mRequestHead.IsOptions() ||
9924 mRequestHead.IsHead() || mRequestHead.IsTrace() ||
9925 mRequestHead.IsConnect()) {
9926 return;
9927 }
9928
9929 // Invalidate the request-uri.
9930 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(mozilla::net::
gHttpLog, mozilla::LogLevel::Verbose)), 0))
) {
9931 nsAutoCString key;
9932 mURI->GetAsciiSpec(key);
9933 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)
9934 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)
;
9935 }
9936
9937 DoInvalidateCacheEntry(mURI);
9938
9939 // Invalidate Location-header if set
9940 nsAutoCString location;
9941 Unused << mResponseHead->GetHeader(nsHttp::Location, location);
9942 if (!location.IsEmpty()) {
9943 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)
;
9944 InvalidateCacheEntryForLocation(location.get());
9945 }
9946
9947 // Invalidate Content-Location-header if set
9948 Unused << mResponseHead->GetHeader(nsHttp::Content_Location, location);
9949 if (!location.IsEmpty()) {
9950 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)
;
9951 InvalidateCacheEntryForLocation(location.get());
9952 }
9953}
9954
9955void nsHttpChannel::InvalidateCacheEntryForLocation(const char* location) {
9956 nsAutoCString tmpCacheKey, tmpSpec;
9957 nsCOMPtr<nsIURI> resultingURI;
9958 nsresult rv = CreateNewURI(location, getter_AddRefs(resultingURI));
9959 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && HostPartIsTheSame(resultingURI)) {
9960 DoInvalidateCacheEntry(resultingURI);
9961 } else {
9962 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)
;
9963 }
9964}
9965
9966void nsHttpChannel::DoInvalidateCacheEntry(nsIURI* aURI) {
9967 // NOTE:
9968 // Following comments 24,32 and 33 in bug #327765, we only care about
9969 // the cache in the protocol-handler.
9970 // The logic below deviates from the original logic in OpenCacheEntry on
9971 // one point by using only READ_ONLY access-policy. I think this is safe.
9972
9973 nsresult rv;
9974
9975 nsAutoCString key;
9976 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(mozilla::net::
gHttpLog, mozilla::LogLevel::Verbose)), 0))
) {
9977 aURI->GetAsciiSpec(key);
9978 }
9979
9980 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)
;
9981
9982 nsCOMPtr<nsICacheStorageService> cacheStorageService(
9983 components::CacheStorage::Service());
9984 rv = cacheStorageService ? NS_OK : NS_ERROR_FAILURE;
9985
9986 nsCOMPtr<nsICacheStorage> cacheStorage;
9987 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
9988 RefPtr<LoadContextInfo> info = GetLoadContextInfo(this);
9989 rv = cacheStorageService->DiskCacheStorage(info,
9990 getter_AddRefs(cacheStorage));
9991 }
9992
9993 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
9994 rv = cacheStorage->AsyncDoomURI(aURI, ""_ns, nullptr);
9995 }
9996
9997 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)
9998 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)
;
9999}
10000
10001void nsHttpChannel::AsyncOnExamineCachedResponse() {
10002 gHttpHandler->OnExamineCachedResponse(this);
10003}
10004
10005void nsHttpChannel::UpdateAggregateCallbacks() {
10006 if (!mTransaction) {
10007 return;
10008 }
10009 nsCOMPtr<nsIInterfaceRequestor> callbacks;
10010 NS_NewNotificationCallbacksAggregation(mCallbacks, mLoadGroup,
10011 GetCurrentSerialEventTarget(),
10012 getter_AddRefs(callbacks));
10013 mTransaction->SetSecurityCallbacks(callbacks);
10014}
10015
10016NS_IMETHODIMPnsresult
10017nsHttpChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) {
10018 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"
, 10018); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Wrong thread." ")"); do { *((volatile int*)__null) = 10018
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
10019
10020 nsresult rv = HttpBaseChannel::SetLoadGroup(aLoadGroup);
10021 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
10022 UpdateAggregateCallbacks();
10023 }
10024 return rv;
10025}
10026
10027NS_IMETHODIMPnsresult
10028nsHttpChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks) {
10029 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"
, 10029); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Wrong thread." ")"); do { *((volatile int*)__null) = 10029
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
10030
10031 nsresult rv = HttpBaseChannel::SetNotificationCallbacks(aCallbacks);
10032 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
10033 UpdateAggregateCallbacks();
10034 }
10035 return rv;
10036}
10037
10038bool nsHttpChannel::AwaitingCacheCallbacks() {
10039 return LoadWaitForCacheEntry() != 0;
10040}
10041
10042void nsHttpChannel::SetPushedStreamTransactionAndId(
10043 HttpTransactionShell* aTransWithPushedStream, uint32_t aPushedStreamId) {
10044 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"
, 10044); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mTransWithPushedStream"
")"); do { *((volatile int*)__null) = 10044; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10045 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)
10046 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)
;
10047
10048 mTransWithPushedStream = aTransWithPushedStream;
10049 mPushedStreamId = aPushedStreamId;
10050}
10051
10052nsresult nsHttpChannel::OnPush(uint32_t aPushedStreamId, const nsACString& aUrl,
10053 const nsACString& aRequestString,
10054 HttpTransactionShell* aTransaction) {
10055 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"
, 10055); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 10055; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10056 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"
, 10056); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aTransaction"
")"); do { *((volatile int*)__null) = 10056; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10057 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)
;
10058
10059 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"
, 10059); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCaps & (1 << 9)"
")"); do { *((volatile int*)__null) = 10059; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10060 nsCOMPtr<nsIHttpPushListener> pushListener;
10061 NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
10062 NS_GET_IID(nsIHttpPushListener)(nsIHttpPushListener::COMTypeInfo<nsIHttpPushListener, void
>::kIID)
,
10063 getter_AddRefs(pushListener));
10064
10065 if (!pushListener) {
10066 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)
10067 ("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)
10068 "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)
10069 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)
;
10070 return NS_ERROR_NOT_AVAILABLE;
10071 }
10072
10073 nsCOMPtr<nsIURI> pushResource;
10074 nsresult rv;
10075
10076 // Create a Channel for the Push Resource
10077 rv = NS_NewURI(getter_AddRefs(pushResource), aUrl);
10078 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10079 return NS_ERROR_FAILURE;
10080 }
10081
10082 nsCOMPtr<nsIIOService> ioService;
10083 rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
10084 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"
, 10084); return rv; } } while (false)
;
10085
10086 nsCOMPtr<nsIChannel> pushChannel;
10087 rv = NS_NewChannelInternal(getter_AddRefs(pushChannel), pushResource,
10088 mLoadInfo,
10089 nullptr, // PerformanceStorage
10090 nullptr, // aLoadGroup
10091 nullptr, // aCallbacks
10092 nsIRequest::LOAD_NORMAL, ioService);
10093 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"
, 10093); return rv; } } while (false)
;
10094
10095 nsCOMPtr<nsIHttpChannel> pushHttpChannel = do_QueryInterface(pushChannel);
10096 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"
, 10096); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pushHttpChannel"
")"); do { *((volatile int*)__null) = 10096; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10097 if (!pushHttpChannel) {
10098 return NS_ERROR_UNEXPECTED;
10099 }
10100
10101 RefPtr<nsHttpChannel> channel;
10102 CallQueryInterface(pushHttpChannel, channel.StartAssignment());
10103 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"
, 10103); AnnotateMozCrashReason("MOZ_ASSERT" "(" "channel" ")"
); do { *((volatile int*)__null) = 10103; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
10104 if (!channel) {
10105 return NS_ERROR_UNEXPECTED;
10106 }
10107
10108 // new channel needs mrqeuesthead and headers from pushedStream
10109 channel->mRequestHead.ParseHeaderSet(aRequestString.BeginReading());
10110 channel->mLoadGroup = mLoadGroup;
10111 channel->mLoadInfo = mLoadInfo;
10112 channel->mCallbacks = mCallbacks;
10113
10114 // Link the trans with pushed stream and the new channel and call listener
10115 channel->SetPushedStreamTransactionAndId(aTransaction, aPushedStreamId);
10116 rv = pushListener->OnPush(this, pushHttpChannel);
10117 return rv;
10118}
10119
10120// static
10121bool nsHttpChannel::IsRedirectStatus(uint32_t status) {
10122 // 305 disabled as a security measure (see bug 187996).
10123 return status == 301 || status == 302 || status == 303 || status == 307 ||
10124 status == 308;
10125}
10126
10127void nsHttpChannel::SetCouldBeSynthesized() {
10128 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"
, 10128); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
")"); do { *((volatile int*)__null) = 10128; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10129 StoreResponseCouldBeSynthesized(true);
10130}
10131
10132NS_IMETHODIMPnsresult
10133nsHttpChannel::OnPreflightSucceeded() {
10134 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"
, 10134); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadRequireCORSPreflight()"
") (" "Why did a preflight happen?" ")"); do { *((volatile int
*)__null) = 10134; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10135 StoreIsCorsPreflightDone(1);
10136 mPreflightChannel = nullptr;
10137
10138 return ContinueConnect();
10139}
10140
10141NS_IMETHODIMPnsresult
10142nsHttpChannel::OnPreflightFailed(nsresult aError) {
10143 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"
, 10143); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadRequireCORSPreflight()"
") (" "Why did a preflight happen?" ")"); do { *((volatile int
*)__null) = 10143; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10144 StoreIsCorsPreflightDone(1);
10145 mPreflightChannel = nullptr;
10146
10147 CloseCacheEntry(false);
10148 Unused << AsyncAbort(aError);
10149 return NS_OK;
10150}
10151
10152nsresult nsHttpChannel::CallOrWaitForResume(
10153 const std::function<nsresult(nsHttpChannel*)>& aFunc) {
10154 if (mCanceled) {
10155 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"
, 10155); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0)))"
")"); do { *((volatile int*)__null) = 10155; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10156 return mStatus;
10157 }
10158
10159 if (mSuspendCount) {
10160 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)
;
10161 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"
, 10161); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mCallOnResume"
")"); do { *((volatile int*)__null) = 10161; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10162 mCallOnResume = aFunc;
10163 return NS_OK;
10164 }
10165
10166 return aFunc(this);
10167}
10168
10169// This is loosely based on:
10170// https://fetch.spec.whatwg.org/#serializing-a-request-origin
10171static bool HasNullRequestOrigin(nsHttpChannel* aChannel, nsIURI* aURI,
10172 bool isAddonRequest) {
10173 // Step 1. If request has a redirect-tainted origin, then return "null".
10174 if (aChannel->HasRedirectTaintedOrigin()) {
10175 if (StaticPrefs::network_http_origin_redirectTainted()) {
10176 return true;
10177 }
10178 }
10179
10180 // Non-standard: Only allow HTTP and HTTPS origins.
10181 if (!ReferrerInfo::IsReferrerSchemeAllowed(aURI)) {
10182 // And moz-extension: for add-on initiated requests.
10183 if (!aURI->SchemeIs("moz-extension") || !isAddonRequest) {
10184 return true;
10185 }
10186 }
10187
10188 // Non-standard: Hide onion URLs.
10189 if (StaticPrefs::network_http_referer_hideOnionSource()) {
10190 nsAutoCString host;
10191 if (NS_SUCCEEDED(aURI->GetAsciiHost(host))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aURI->GetAsciiHost
(host))), 1)))
&&
10192 StringEndsWith(host, ".onion"_ns)) {
10193 return ReferrerInfo::IsCrossOriginRequest(aChannel);
10194 }
10195 }
10196
10197 // Step 2. Return request’s origin, serialized.
10198 return false;
10199}
10200
10201// Step 8.12. of HTTP-network-or-cache fetch
10202//
10203// https://fetch.spec.whatwg.org/#append-a-request-origin-header
10204void nsHttpChannel::SetOriginHeader() {
10205 auto* triggeringPrincipal =
10206 BasePrincipal::Cast(mLoadInfo->TriggeringPrincipal());
10207
10208 if (triggeringPrincipal->IsSystemPrincipal()) {
10209 // We can't infer an Origin header from the system principal,
10210 // this means system requests use whatever Origin header was specified.
10211 return;
10212 }
10213 bool isAddonRequest = triggeringPrincipal->AddonPolicy() ||
10214 triggeringPrincipal->ContentScriptAddonPolicy();
10215
10216 // Non-standard: Handle already existing Origin header.
10217 nsAutoCString existingHeader;
10218 Unused << mRequestHead.GetHeader(nsHttp::Origin, existingHeader);
10219 if (!existingHeader.IsEmpty()) {
10220 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)
;
10221 auto const shouldNullifyOriginHeader =
10222 [&existingHeader, isAddonRequest](nsHttpChannel* aChannel) {
10223 nsCOMPtr<nsIURI> uri;
10224 nsresult rv = NS_NewURI(getter_AddRefs(uri), existingHeader);
10225 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10226 return false;
10227 }
10228
10229 if (HasNullRequestOrigin(aChannel, uri, isAddonRequest)) {
10230 return true;
10231 }
10232
10233 nsCOMPtr<nsILoadInfo> info = aChannel->LoadInfo();
10234 if (info->GetTainting() == mozilla::LoadTainting::CORS) {
10235 return false;
10236 }
10237
10238 return ReferrerInfo::ShouldSetNullOriginHeader(aChannel, uri);
10239 };
10240
10241 if (!existingHeader.EqualsLiteral("null") &&
10242 shouldNullifyOriginHeader(this)) {
10243 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)
;
10244 MOZ_ALWAYS_SUCCEEDS(do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mRequestHead.SetHeader(nsHttp::Origin, "null"_ns, false ))),
1)))), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, \"null\"_ns, false ))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10245); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, \"null\"_ns, false ))"
")"); do { *((volatile int*)__null) = 10245; __attribute__((
nomerge)) ::abort(); } while (false); } while (false); } } while
(false)
10245 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 { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, \"null\"_ns, false ))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10245); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, \"null\"_ns, false ))"
")"); do { *((volatile int*)__null) = 10245; __attribute__((
nomerge)) ::abort(); } while (false); } while (false); } } while
(false)
;
10246 }
10247 return;
10248 }
10249
10250 if (StaticPrefs::network_http_sendOriginHeader() == 0) {
10251 // Custom user setting: 0 means never send Origin header.
10252 return;
10253 }
10254
10255 // Step 1. Let serializedOrigin be the result of byte-serializing a request
10256 // origin with request.
10257 nsAutoCString serializedOrigin;
10258 nsCOMPtr<nsIURI> uri;
10259 {
10260 if (NS_FAILED(triggeringPrincipal->GetURI(getter_AddRefs(uri)))((bool)(__builtin_expect(!!(NS_FAILED_impl(triggeringPrincipal
->GetURI(getter_AddRefs(uri)))), 0)))
) {
10261 return;
10262 }
10263
10264 if (!uri) {
10265 if (isAddonRequest) {
10266 // For add-on compatibility prefer sending no header at all
10267 // instead of `Origin: null`.
10268 return;
10269 }
10270
10271 // Otherwise use "null" when the triggeringPrincipal's URI is nullptr.
10272 serializedOrigin.AssignLiteral("null");
10273 } else if (HasNullRequestOrigin(this, uri, isAddonRequest)) {
10274 serializedOrigin.AssignLiteral("null");
10275 } else {
10276 nsContentUtils::GetWebExposedOriginSerialization(uri, serializedOrigin);
10277 }
10278 }
10279
10280 // Step 2. If request’s response tainting is "cors" or request’s mode is
10281 // "websocket", then append (`Origin`, serializedOrigin) to request’s header
10282 // list.
10283 //
10284 // Note: We don't handle "websocket" here (yet?).
10285 if (mLoadInfo->GetTainting() == mozilla::LoadTainting::CORS) {
10286 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 { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10287); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
")"); do { *((volatile int*)__null) = 10287; __attribute__((
nomerge)) ::abort(); } while (false); } while (false); } } while
(false)
10287 false /* merge */))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false
))), 1)))), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10287); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
")"); do { *((volatile int*)__null) = 10287; __attribute__((
nomerge)) ::abort(); } while (false); } while (false); } } while
(false)
;
10288 return;
10289 }
10290
10291 // Step 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then:
10292 if (mRequestHead.IsGet() || mRequestHead.IsHead()) {
10293 return;
10294 }
10295
10296 if (!serializedOrigin.EqualsLiteral("null")) {
10297 // Step 3.1. (Implemented by ReferrerInfo::ShouldSetNullOriginHeader)
10298 if (ReferrerInfo::ShouldSetNullOriginHeader(this, uri)) {
10299 serializedOrigin.AssignLiteral("null");
10300 } else if (StaticPrefs::network_http_sendOriginHeader() == 1) {
10301 // Non-standard: Restrict Origin to same-origin loads if requested by user
10302 nsAutoCString currentOrigin;
10303 nsContentUtils::GetWebExposedOriginSerialization(mURI, currentOrigin);
10304 if (!serializedOrigin.EqualsIgnoreCase(currentOrigin.get())) {
10305 // Origin header suppressed by user setting.
10306 serializedOrigin.AssignLiteral("null");
10307 }
10308 }
10309 }
10310
10311 // Step 3.2. Append (`Origin`, serializedOrigin) to request’s header list.
10312 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 { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10313); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
")"); do { *((volatile int*)__null) = 10313; __attribute__((
nomerge)) ::abort(); } while (false); } while (false); } } while
(false)
10313 false /* merge */))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false
))), 1)))), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10313); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(mRequestHead.SetHeader(nsHttp::Origin, serializedOrigin, false ))"
")"); do { *((volatile int*)__null) = 10313; __attribute__((
nomerge)) ::abort(); } while (false); } while (false); } } while
(false)
;
10314}
10315
10316void nsHttpChannel::SetDoNotTrack() {
10317 /**
10318 * 'DoNotTrack' header should be added if 'privacy.donottrackheader.enabled'
10319 * is true or tracking protection is enabled. See bug 1258033.
10320 */
10321 nsCOMPtr<nsILoadContext> loadContext;
10322 NS_QueryNotificationCallbacks(this, loadContext);
10323
10324 if ((loadContext && loadContext->UseTrackingProtection()) ||
10325 StaticPrefs::privacy_donottrackheader_enabled()) {
10326 DebugOnly<nsresult> rv =
10327 mRequestHead.SetHeader(nsHttp::DoNotTrack, "1"_ns, false);
10328 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"
, 10328); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 10328; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10329 }
10330}
10331
10332void nsHttpChannel::SetGlobalPrivacyControl() {
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 if (StaticPrefs::privacy_globalprivacycontrol_functionality_enabled() &&
10336 (StaticPrefs::privacy_globalprivacycontrol_enabled() ||
10337 (StaticPrefs::privacy_globalprivacycontrol_pbmode_enabled() &&
10338 NS_UsePrivateBrowsing(this)))) {
10339 // Send the header with a value of 1 to indicate opting-out
10340 DebugOnly<nsresult> rv =
10341 mRequestHead.SetHeader(nsHttp::GlobalPrivacyControl, "1"_ns, false);
10342 }
10343}
10344
10345void nsHttpChannel::ReportRcwnStats(bool isFromNet) {
10346 if (!StaticPrefs::network_http_rcwn_enabled()) {
10347 return;
10348 }
10349
10350 if (isFromNet) {
10351 // Race was won by the network if:
10352 // * we hadn't gotten a response from the cache yet when we started pumping
10353 // data from the network, whether or not the cache entry would have
10354 // been valid or not.
10355 // * If we did get a response from the cache first, but it wasn't valid or
10356 // just
10357 // indicated there was no entry, then it's not a network RCWN win
10358 // * Note that we consider it a Network win even if an invalid/expired cache
10359 // response comes in after the network response.
10360
10361 if (mRaceCacheWithNetwork && LoadNetworkWonRace()) {
10362 PROFILER_MARKER_TEXT(do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won valid = %d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
10363 "RCWN", NETWORK, {},do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won valid = %d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
10364 nsPrintfCString("Network won valid = %d, channel %p, URI %s",do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won valid = %d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
10365 LoadCachedContentIsValid(), this, mSpec.get()))do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Network won valid = %d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
;
10366 gIOService->IncrementNetWonRequestNumber();
10367 Telemetry::Accumulate(
10368 Telemetry::NETWORK_RACE_CACHE_BANDWIDTH_RACE_NETWORK_WIN,
10369 mTransferSize);
10370 if (mRaceDelay) {
10371 AccumulateCategorical(
10372 Telemetry::LABELS_NETWORK_RACE_CACHE_WITH_NETWORK_USAGE_2::
10373 NetworkDelayedRace);
10374 } else {
10375 AccumulateCategorical(
10376 Telemetry::LABELS_NETWORK_RACE_CACHE_WITH_NETWORK_USAGE_2::
10377 NetworkRace);
10378 }
10379 } else {
10380 PROFILER_MARKER_TEXT(do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString( "Cache won or was replaced, valid = %d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
10381 "RCWN", NETWORK, {},do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString( "Cache won or was replaced, valid = %d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
10382 nsPrintfCString(do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString( "Cache won or was replaced, valid = %d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
10383 "Cache won or was replaced, valid = %d, channel %p, URI %s",do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString( "Cache won or was replaced, valid = %d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
10384 LoadCachedContentIsValid(), this, mSpec.get()))do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString( "Cache won or was replaced, valid = %d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
;
10385 Telemetry::Accumulate(Telemetry::NETWORK_RACE_CACHE_BANDWIDTH_NOT_RACE,
10386 mTransferSize);
10387 AccumulateCategorical(
10388 Telemetry::LABELS_NETWORK_RACE_CACHE_WITH_NETWORK_USAGE_2::
10389 NetworkNoRace);
10390 }
10391 } else {
10392 if (mRaceCacheWithNetwork || mRaceDelay) {
10393 PROFILER_MARKER_TEXT(do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Cache won valid=%d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
10394 "RCWN", NETWORK, {},do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Cache won valid=%d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
10395 nsPrintfCString("Cache won valid=%d, channel %p, URI %s",do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Cache won valid=%d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
10396 LoadCachedContentIsValid(), this, mSpec.get()))do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("RCWN", ::geckoprofiler::category::NETWORK, {}, ::geckoprofiler
::markers::TextMarker{}, nsPrintfCString("Cache won valid=%d, channel %p, URI %s"
, LoadCachedContentIsValid(), this, mSpec.get())); } } while (
false); } while (false)
;
10397 gIOService->IncrementCacheWonRequestNumber();
10398 Telemetry::Accumulate(
10399 Telemetry::NETWORK_RACE_CACHE_BANDWIDTH_RACE_CACHE_WIN,
10400 mTransferSize);
10401 if (mRaceDelay) {
10402 AccumulateCategorical(
10403 Telemetry::LABELS_NETWORK_RACE_CACHE_WITH_NETWORK_USAGE_2::
10404 CacheDelayedRace);
10405 } else {
10406 AccumulateCategorical(
10407 Telemetry::LABELS_NETWORK_RACE_CACHE_WITH_NETWORK_USAGE_2::
10408 CacheRace);
10409 }
10410 } else {
10411 Telemetry::Accumulate(Telemetry::NETWORK_RACE_CACHE_BANDWIDTH_NOT_RACE,
10412 mTransferSize);
10413 AccumulateCategorical(
10414 Telemetry::LABELS_NETWORK_RACE_CACHE_WITH_NETWORK_USAGE_2::
10415 CacheNoRace);
10416 }
10417 }
10418
10419 gIOService->IncrementRequestNumber();
10420}
10421
10422void nsHttpChannel::ReportSystemChannelTelemetry(nsresult status) {
10423 // Use status and httpStatus to determine
10424 // if it was successful, and if we had connectivity / offline in this time
10425 nsAutoCString domain;
10426 mOriginalURI->GetHost(domain);
10427
10428 if (!LoadUsedNetwork()) {
10429 // We're not really interested in any cached requests.
10430 return;
10431 }
10432
10433 if (!StringEndsWith(domain, ".mozilla.org"_ns) &&
10434 !StringEndsWith(domain, ".mozilla.com"_ns)) {
10435 return;
10436 }
10437
10438 auto hasConnectivity = []() -> bool {
10439 if (RefPtr<NetworkConnectivityService> ncs =
10440 NetworkConnectivityService::GetSingleton()) {
10441 nsINetworkConnectivityService::ConnectivityState state;
10442 if (NS_SUCCEEDED(ncs->GetIPv4(&state))((bool)(__builtin_expect(!!(!NS_FAILED_impl(ncs->GetIPv4(&
state))), 1)))
&&
10443 state == nsINetworkConnectivityService::NOT_AVAILABLE &&
10444 NS_SUCCEEDED(ncs->GetIPv6(&state))((bool)(__builtin_expect(!!(!NS_FAILED_impl(ncs->GetIPv6(&
state))), 1)))
&&
10445 state == nsINetworkConnectivityService::NOT_AVAILABLE) {
10446 return false;
10447 }
10448 }
10449
10450 return true;
10451 };
10452
10453 nsAutoCString label("ok"_ns);
10454 if (NS_FAILED(status)((bool)(__builtin_expect(!!(NS_FAILED_impl(status)), 0)))) {
10455 if (mCanceled) {
10456 // The request was cancelled.
10457 label = "cancel"_ns;
10458 } else if (NS_IsOffline()) {
10459 // The error occured while all interfaces are offline
10460 label = "offline"_ns;
10461 } else if (!hasConnectivity()) {
10462 // The error occured while the browser didn't have connectivity
10463 label = "connectivity"_ns;
10464 } else if (status == NS_ERROR_UNKNOWN_HOST) {
10465 // The failure was a DNS error
10466 label = "dns"_ns;
10467 } else if (NS_ERROR_GET_MODULE(status) == NS_ERROR_MODULE_SECURITY21) {
10468 // The error was due to TLS
10469 label = "tls_fail"_ns;
10470 } else if (status == NS_ERROR_NET_RESET) {
10471 label = "reset"_ns;
10472 } else if (status == NS_ERROR_NET_TIMEOUT) {
10473 label = "timeout"_ns;
10474 } else if (status == NS_ERROR_CONNECTION_REFUSED) {
10475 label = "refused"_ns;
10476 } else if (status == NS_ERROR_NET_PARTIAL_TRANSFER) {
10477 label = "partial"_ns;
10478 } else {
10479 // Unspecified error. If this bucket is too big we might add other labels.
10480 label = "other"_ns;
10481 }
10482 } else if (mResponseHead && mResponseHead->Status() / 100 != 2) {
10483 // There was no channel error, but the server responded with a non-2XX
10484 // status code.
10485 label = "http_status";
10486 }
10487
10488 if (StringEndsWith(domain, ".addons.mozilla.org"_ns)) {
10489 mozilla::glean::network::system_channel_addonversion_status.Get(label).Add(
10490 1);
10491 return;
10492 }
10493
10494 if (domain == "addons.mozilla.org") {
10495 mozilla::glean::network::system_channel_addon_status.Get(label).Add(1);
10496 return;
10497 }
10498
10499 if (domain == "aus5.mozilla.org"_ns) {
10500 mozilla::glean::network::system_channel_update_status.Get(label).Add(1);
10501 return;
10502 }
10503
10504 if (domain == "firefox.settings.services.mozilla.com"_ns) {
10505 mozilla::glean::network::system_channel_remote_settings_status.Get(label)
10506 .Add(1);
10507 return;
10508 }
10509
10510 if (domain == "incoming.telemetry.mozilla.com"_ns) {
10511 mozilla::glean::network::system_channel_telemetry_status.Get(label).Add(1);
10512 return;
10513 }
10514
10515 // Not one of the probes we recorded earlier.
10516 mozilla::glean::network::system_channel_other_status.Get(label).Add(1);
10517}
10518
10519NS_IMETHODIMPnsresult
10520nsHttpChannel::GetAllowRacing(bool* aAllowRacing) {
10521 *aAllowRacing = mAllowRCWN;
10522 return NS_OK;
10523}
10524
10525NS_IMETHODIMPnsresult
10526nsHttpChannel::SetAllowRacing(bool aAllowRacing) {
10527 mAllowRCWN = aAllowRacing;
10528 return NS_OK;
10529}
10530
10531NS_IMETHODIMPnsresult
10532nsHttpChannel::Test_delayCacheEntryOpeningBy(int32_t aTimeout) {
10533 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)
10534 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)
;
10535 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"
, 10535); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Must be called on the main thread" ")"); do { *((volatile
int*)__null) = 10535; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10536 mRaceCacheWithNetwork = true;
10537 mCacheOpenDelay = aTimeout;
10538 if (mCacheOpenTimer) {
10539 mCacheOpenTimer->SetDelay(aTimeout);
10540 }
10541 return NS_OK;
10542}
10543
10544NS_IMETHODIMPnsresult
10545nsHttpChannel::Test_triggerDelayedOpenCacheEntry() {
10546 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)
;
10547 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"
, 10547); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Must be called on the main thread" ")"); do { *((volatile
int*)__null) = 10547; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10548 nsresult rv;
10549 if (!mCacheOpenDelay) {
10550 // No delay was set.
10551 return NS_ERROR_NOT_AVAILABLE;
10552 }
10553 if (!mCacheOpenFunc) {
10554 // There should be a runnable.
10555 return NS_ERROR_FAILURE;
10556 }
10557 if (mCacheOpenTimer) {
10558 rv = mCacheOpenTimer->Cancel();
10559 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10560 return rv;
10561 }
10562 mCacheOpenTimer = nullptr;
10563 }
10564 mCacheOpenDelay = 0;
10565 // Avoid re-entrancy issues by nulling our mCacheOpenFunc before calling it.
10566 std::function<void(nsHttpChannel*)> cacheOpenFunc = nullptr;
10567 std::swap(cacheOpenFunc, mCacheOpenFunc);
10568 cacheOpenFunc(this);
10569
10570 return NS_OK;
10571}
10572
10573nsresult nsHttpChannel::TriggerNetworkWithDelay(uint32_t aDelay) {
10574 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"
, 10574); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Must be called on the main thread" ")"); do { *((volatile
int*)__null) = 10574; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10575
10576 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)
10577 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)
;
10578
10579 if (mCanceled) {
10580 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)
;
10581 return mStatus;
10582 }
10583
10584 // If a network request has already gone out, there is no point in
10585 // doing this again.
10586 if (mNetworkTriggered) {
10587 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)
;
10588 return NS_OK;
10589 }
10590
10591 if (mNetworkTriggerDelay) {
10592 aDelay = mNetworkTriggerDelay;
10593 }
10594
10595 if (!aDelay) {
10596 // We cannot call TriggerNetwork() directly here, because it would
10597 // cause performance regression in tp6 tests, see bug 1398847.
10598 return NS_DispatchToMainThread(
10599 NewRunnableMethod("net::nsHttpChannel::TriggerNetworkWithDelay", this,
10600 &nsHttpChannel::TriggerNetwork),
10601 NS_DISPATCH_NORMALnsIEventTarget::DISPATCH_NORMAL);
10602 }
10603
10604 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"
, 10604); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mNetworkTriggerTimer"
")"); do { *((volatile int*)__null) = 10604; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10605 mNetworkTriggerTimer = NS_NewTimer();
10606 auto callback = MakeRefPtr<TimerCallback>(this);
10607 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
)
;
10608 mNetworkTriggerTimer->InitWithCallback(callback, aDelay,
10609 nsITimer::TYPE_ONE_SHOT);
10610 return NS_OK;
10611}
10612
10613nsresult nsHttpChannel::TriggerNetwork() {
10614 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"
, 10614); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Must be called on the main thread" ")"); do { *((volatile
int*)__null) = 10614; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10615
10616 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)
;
10617
10618 if (mCanceled) {
10619 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)
;
10620 return mStatus;
10621 }
10622
10623 // If a network request has already gone out, there is no point in
10624 // doing this again.
10625 if (mNetworkTriggered) {
10626 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)
;
10627 return NS_OK;
10628 }
10629
10630 mNetworkTriggered = true;
10631 if (mNetworkTriggerTimer) {
10632 mNetworkTriggerTimer->Cancel();
10633 mNetworkTriggerTimer = nullptr;
10634 }
10635
10636 // If we are waiting for a proxy request, that means we can't trigger
10637 // the next step just yet. We need for mConnectionInfo to be non-null
10638 // before we call ContinueConnect. OnProxyAvailable will trigger
10639 // BeginConnect, and Connect will call ContinueConnect even if it's
10640 // for the cache callbacks.
10641 if (mProxyRequest) {
10642 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)
;
10643 mWaitingForProxy = true;
10644 return NS_OK;
10645 }
10646
10647 // If |mCacheOpenFunc| is assigned, we're delaying opening the entry to
10648 // simulate racing. Although cache entry opening hasn't started yet, we're
10649 // actually racing, so we must set mRaceCacheWithNetwork to true now.
10650 mRaceCacheWithNetwork =
10651 AwaitingCacheCallbacks() &&
10652 (mCacheOpenFunc || StaticPrefs::network_http_rcwn_enabled());
10653
10654 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)
;
10655 return ContinueConnect();
10656}
10657
10658void nsHttpChannel::MaybeRaceCacheWithNetwork() {
10659 nsresult rv;
10660
10661 nsCOMPtr<nsINetworkLinkService> netLinkSvc;
10662 netLinkSvc = do_GetService(NS_NETWORK_LINK_SERVICE_CONTRACTID"@mozilla.org/network/network-link-service;1", &rv);
10663 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10664 return;
10665 }
10666
10667 uint32_t linkType;
10668 rv = netLinkSvc->GetLinkType(&linkType);
10669 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10670 return;
10671 }
10672
10673 if (!(linkType == nsINetworkLinkService::LINK_TYPE_ETHERNET ||
10674#ifndef MOZ_WIDGET_ANDROID
10675 // On Android we don't assume an unknown link type is unmetered
10676 linkType == nsINetworkLinkService::LINK_TYPE_UNKNOWN ||
10677#endif
10678 linkType == nsINetworkLinkService::LINK_TYPE_USB ||
10679 linkType == nsINetworkLinkService::LINK_TYPE_WIFI)) {
10680 return;
10681 }
10682
10683 // Don't trigger the network if the load flags say so.
10684 if (mLoadFlags & (LOAD_ONLY_FROM_CACHE | LOAD_NO_NETWORK_IO)) {
10685 return;
10686 }
10687
10688 // We must not race if the channel has a failure status code.
10689 if (NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0)))) {
10690 return;
10691 }
10692
10693 // If a CORS Preflight is required we must not race.
10694 if (LoadRequireCORSPreflight() && !LoadIsCorsPreflightDone()) {
10695 return;
10696 }
10697
10698 if (CacheFileUtils::CachePerfStats::IsCacheSlow()) {
10699 // If the cache is slow, trigger the network request immediately.
10700 mRaceDelay = 0;
10701 } else {
10702 // Give cache a headstart of 3 times the average cache entry open time.
10703 mRaceDelay = CacheFileUtils::CachePerfStats::GetAverage(
10704 CacheFileUtils::CachePerfStats::ENTRY_OPEN, true) *
10705 3;
10706 // We use microseconds in CachePerfStats but we need milliseconds
10707 // for TriggerNetwork.
10708 mRaceDelay /= 1000;
10709 }
10710
10711 mRaceDelay = std::clamp<uint32_t>(
10712 mRaceDelay, StaticPrefs::network_http_rcwn_min_wait_before_racing_ms(),
10713 StaticPrefs::network_http_rcwn_max_wait_before_racing_ms());
10714
10715 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"
, 10716); AnnotateMozCrashReason("MOZ_ASSERT" "(" "StaticPrefs::network_http_rcwn_enabled() || mNetworkTriggerDelay"
") (" "The pref must be turned on." ")"); do { *((volatile int
*)__null) = 10716; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
10716 "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"
, 10716); AnnotateMozCrashReason("MOZ_ASSERT" "(" "StaticPrefs::network_http_rcwn_enabled() || mNetworkTriggerDelay"
") (" "The pref must be turned on." ")"); do { *((volatile int
*)__null) = 10716; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10717 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)
10718 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)
;
10719
10720 TriggerNetworkWithDelay(mRaceDelay);
10721}
10722
10723NS_IMETHODIMPnsresult
10724nsHttpChannel::Test_triggerNetwork(int32_t aTimeout) {
10725 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)
10726 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)
;
10727 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"
, 10727); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Must be called on the main thread" ")"); do { *((volatile
int*)__null) = 10727; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10728
10729 // We set the trigger delay to the specified timeout.
10730 mRaceCacheWithNetwork = true;
10731 mNetworkTriggerDelay = aTimeout;
10732
10733 // If we already have a timer, set the delay/
10734 if (mNetworkTriggerTimer) {
10735 // If the timeout is 0 and there is a timer, we can trigger
10736 // the network immediately.
10737 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"
, 10737); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
") (" "Must have been opened before" ")"); do { *((volatile int
*)__null) = 10737; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
10738 if (!aTimeout) {
10739 return TriggerNetwork();
10740 }
10741 mNetworkTriggerTimer->SetDelay(aTimeout);
10742 }
10743 return NS_OK;
10744}
10745
10746nsHttpChannel::TimerCallback::TimerCallback(nsHttpChannel* aChannel)
10747 : mChannel(aChannel) {}
10748
10749NS_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"
, 10749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
10749; __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"
, 10749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsHttpChannel::TimerCallback\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 10749; __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"
, 10749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 10749
; __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"
, 10749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"nsHttpChannel::TimerCallback\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 10749; __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"
, 10749); 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(
std::size(table) > 1, "need at least 1 interface"); rv = NS_TableDrivenQI
(static_cast<void*>(this), aIID, aInstancePtr, table); return
rv; }
10750
10751NS_IMETHODIMPnsresult
10752nsHttpChannel::TimerCallback::GetName(nsACString& aName) {
10753 aName.AssignLiteral("nsHttpChannel");
10754 return NS_OK;
10755}
10756
10757NS_IMETHODIMPnsresult
10758nsHttpChannel::TimerCallback::Notify(nsITimer* aTimer) {
10759 if (aTimer == mChannel->mCacheOpenTimer) {
10760 return mChannel->Test_triggerDelayedOpenCacheEntry();
10761 }
10762 if (aTimer == mChannel->mNetworkTriggerTimer) {
10763 return mChannel->TriggerNetwork();
10764 }
10765 MOZ_CRASH("Unknown timer")do { do { } while (false); MOZ_ReportCrash("" "Unknown timer"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/nsHttpChannel.cpp"
, 10765); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown timer"
")"); do { *((volatile int*)__null) = 10765; __attribute__((
nomerge)) ::abort(); } while (false); } while (false)
;
10766
10767 return NS_OK;
10768}
10769
10770bool nsHttpChannel::EligibleForTailing() {
10771 if (!(mClassOfService.Flags() & nsIClassOfService::Tail)) {
10772 return false;
10773 }
10774
10775 if (mClassOfService.Flags() &
10776 (nsIClassOfService::UrgentStart | nsIClassOfService::Leader |
10777 nsIClassOfService::TailForbidden)) {
10778 return false;
10779 }
10780
10781 if (mClassOfService.Flags() & nsIClassOfService::Unblocked &&
10782 !(mClassOfService.Flags() & nsIClassOfService::TailAllowed)) {
10783 return false;
10784 }
10785
10786 if (IsNavigation()) {
10787 return false;
10788 }
10789
10790 return true;
10791}
10792
10793bool nsHttpChannel::WaitingForTailUnblock() {
10794 nsresult rv;
10795
10796 if (!gHttpHandler->IsTailBlockingEnabled()) {
10797 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)
;
10798 return false;
10799 }
10800
10801 if (!EligibleForTailing()) {
10802 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)
;
10803 AddAsNonTailRequest();
10804 return false;
10805 }
10806
10807 if (!EnsureRequestContext()) {
10808 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)
;
10809 return false;
10810 }
10811
10812 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)
10813 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)
;
10814
10815 bool blocked;
10816 rv = mRequestContext->IsContextTailBlocked(this, &blocked);
10817 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10818 return false;
10819 }
10820
10821 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)
;
10822
10823 return blocked;
10824}
10825
10826//-----------------------------------------------------------------------------
10827// nsHttpChannel::nsIRequestTailUnblockCallback
10828//-----------------------------------------------------------------------------
10829
10830// Must be implemented in the leaf class because we don't have
10831// AsyncAbort in HttpBaseChannel.
10832NS_IMETHODIMPnsresult
10833nsHttpChannel::OnTailUnblock(nsresult rv) {
10834 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)
10835 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)
;
10836
10837 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"
, 10837); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mOnTailUnblock"
")"); do { *((volatile int*)__null) = 10837; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10838
10839 if (NS_FAILED(mStatus)((bool)(__builtin_expect(!!(NS_FAILED_impl(mStatus)), 0)))) {
10840 rv = mStatus;
10841 }
10842
10843 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
10844 auto callback = mOnTailUnblock;
10845 mOnTailUnblock = nullptr;
10846 rv = (this->*callback)();
10847 }
10848
10849 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
10850 CloseCacheEntry(false);
10851 return AsyncAbort(rv);
10852 }
10853
10854 return NS_OK;
10855}
10856
10857void nsHttpChannel::SetWarningReporter(
10858 HttpChannelSecurityWarningReporter* aReporter) {
10859 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)
;
10860 mWarningReporter = aReporter;
10861}
10862
10863HttpChannelSecurityWarningReporter* nsHttpChannel::GetWarningReporter() {
10864 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)
10865 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)
;
10866 return mWarningReporter.get();
10867}
10868
10869// The specification for ORB is currently being written:
10870// https://whatpr.org/fetch/1442.html#orb-algorithm
10871// The `opaque-response-safelist check` is implemented in:
10872// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff`
10873// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
10874// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
10875// * `OpaqueResponseBlocker::ValidateJavaScript`
10876//
10877// Should only be called by nsMediaSniffer::GetMIMETypeFromContent and
10878// imageLoader::GetMIMETypeFromContent when the content type can be
10879// recognized by these sniffers.
10880void nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck(
10881 SnifferType aType) {
10882 // https://whatpr.org/fetch/1442.html#orb-algorithm
10883 // This method covers steps, 8 and 10.
10884 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"
, 10884); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 10884; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10885
10886 if (NeedOpaqueResponseAllowedCheckAfterSniff()) {
10887 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"
, 10887); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCachedOpaqueResponseBlockingPref"
")"); do { *((volatile int*)__null) = 10887; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10888
10889 // If the sniffer type is media and the request comes from a media element,
10890 // we would like to check:
10891 // - Whether the information provided by the media element shows it's an
10892 // initial request.
10893 // - Whether the response's status is either 200 or 206.
10894 //
10895 // If any of the results is false, then we set
10896 // mBlockOpaqueResponseAfterSniff to true and block the response later.
10897 if (aType == SnifferType::Media) {
10898 // Step 8
10899 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"
, 10899); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo"
")"); do { *((volatile int*)__null) = 10899; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10900
10901 bool isMediaRequest;
10902 mLoadInfo->GetIsMediaRequest(&isMediaRequest);
10903 if (isMediaRequest) {
10904 bool isInitialRequest;
10905 mLoadInfo->GetIsMediaInitialRequest(&isInitialRequest);
10906 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"
, 10906); AnnotateMozCrashReason("MOZ_ASSERT" "(" "isInitialRequest"
")"); do { *((volatile int*)__null) = 10906; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10907
10908 if (!isInitialRequest) {
10909 // Step 8.1
10910 BlockOpaqueResponseAfterSniff(
10911 u"media request after sniffing, but not initial request"_ns,
10912 OpaqueResponseBlockedTelemetryReason::MEDIA_NOT_INITIAL);
10913 return;
10914 }
10915
10916 if (mResponseHead->Status() != 200 && mResponseHead->Status() != 206) {
10917 // Step 8.2
10918 BlockOpaqueResponseAfterSniff(
10919 u"media request's response status is neither 200 nor 206"_ns,
10920 OpaqueResponseBlockedTelemetryReason::MEDIA_INCORRECT_RESP);
10921 return;
10922 }
10923 }
10924 }
10925
10926 // Step 8.3 if `aType == SnifferType::Media`
10927 // Step 9 can be skipped, only `HTMLMediaElement` ever sets isMediaRequest.
10928 // Step 10 if `aType == SnifferType::Image`
10929 AllowOpaqueResponseAfterSniff();
10930 }
10931}
10932
10933namespace {
10934
10935class CopyNonDefaultHeaderVisitor final : public nsIHttpHeaderVisitor {
10936 nsCOMPtr<nsIHttpChannel> mTarget;
10937
10938 ~CopyNonDefaultHeaderVisitor() = default;
10939
10940 NS_IMETHODvirtual nsresult
10941 VisitHeader(const nsACString& aHeader, const nsACString& aValue) override {
10942 if (aValue.IsEmpty()) {
10943 return mTarget->SetEmptyRequestHeader(aHeader);
10944 }
10945 return mTarget->SetRequestHeader(aHeader, aValue, false /* merge */);
10946 }
10947
10948 public:
10949 explicit CopyNonDefaultHeaderVisitor(nsIHttpChannel* aTarget)
10950 : mTarget(aTarget) {
10951 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"
, 10951); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mTarget"
")"); do { *((volatile int*)__null) = 10951; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10952 }
10953
10954 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:
10955};
10956
10957NS_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"
, 10957); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
10957; __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"
, 10957); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"CopyNonDefaultHeaderVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 10957; __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"
, 10957); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 10957
; __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"
, 10957); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"CopyNonDefaultHeaderVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 10957; __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"
, 10957); 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(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
10958
10959} // anonymous namespace
10960
10961nsresult nsHttpChannel::RedirectToInterceptedChannel() {
10962 nsCOMPtr<nsINetworkInterceptController> controller;
10963 GetCallback(controller);
10964
10965 RefPtr<InterceptedHttpChannel> intercepted =
10966 InterceptedHttpChannel::CreateForInterception(
10967 mChannelCreationTime, mChannelCreationTimestamp, mAsyncOpenTime);
10968
10969 ExtContentPolicyType type = mLoadInfo->GetExternalContentPolicyType();
10970
10971 nsCOMPtr<nsILoadInfo> redirectLoadInfo =
10972 CloneLoadInfoForRedirect(mURI, nsIChannelEventSink::REDIRECT_INTERNAL);
10973
10974 nsresult rv = intercepted->Init(
Value stored to 'rv' during its initialization is never read
10975 mURI, mCaps, static_cast<nsProxyInfo*>(mProxyInfo.get()),
10976 mProxyResolveFlags, mProxyURI, mChannelId, type, redirectLoadInfo);
10977
10978 rv = SetupReplacementChannel(mURI, intercepted, true,
10979 nsIChannelEventSink::REDIRECT_INTERNAL);
10980 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"
, 10980); return rv; } } while (false)
;
10981
10982 // Some APIs, like fetch(), allow content to set non-standard headers.
10983 // Normally these APIs are responsible for copying these headers across
10984 // redirects. In the e10s parent-side intercept case, though, we currently
10985 // "hide" the internal redirect to the InterceptedHttpChannel. So the
10986 // fetch() API does not have the opportunity to move headers over.
10987 // Therefore, we do it automatically here.
10988 //
10989 // Once child-side interception is removed and the internal redirect no
10990 // longer needs to be "hidden", then this header copying code can be
10991 // removed.
10992 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
10993 new CopyNonDefaultHeaderVisitor(intercepted);
10994 rv = VisitNonDefaultRequestHeaders(visitor);
10995 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"
, 10995); return rv; } } while (false)
;
10996
10997 mRedirectChannel = intercepted;
10998
10999 PushRedirectAsyncFunc(&nsHttpChannel::ContinueAsyncRedirectChannelToURI);
11000
11001 rv = gHttpHandler->AsyncOnChannelRedirect(
11002 this, intercepted, nsIChannelEventSink::REDIRECT_INTERNAL);
11003
11004 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
11005 rv = WaitForRedirectCallback();
11006 }
11007
11008 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
11009 AutoRedirectVetoNotifier notifier(this, rv);
11010
11011 PopRedirectAsyncFunc(&nsHttpChannel::ContinueAsyncRedirectChannelToURI);
11012 }
11013
11014 return rv;
11015}
11016
11017void nsHttpChannel::ReEvaluateReferrerAfterTrackingStatusIsKnown() {
11018 nsCOMPtr<nsICookieJarSettings> cjs;
11019 if (mLoadInfo) {
11020 Unused << mLoadInfo->GetCookieJarSettings(getter_AddRefs(cjs));
11021 }
11022 if (!cjs) {
11023 cjs = net::CookieJarSettings::Create(mLoadInfo->GetLoadingPrincipal());
11024 }
11025 if (cjs->GetRejectThirdPartyContexts()) {
11026 bool isPrivate = mLoadInfo->GetOriginAttributes().IsPrivateBrowsing();
11027 // If our referrer has been set before, and our referrer policy is unset
11028 // (default policy) if we thought the channel wasn't a third-party
11029 // tracking channel, we may need to set our referrer with referrer policy
11030 // once again to ensure our defaults properly take effect now.
11031 if (mReferrerInfo) {
11032 ReferrerInfo* referrerInfo =
11033 static_cast<ReferrerInfo*>(mReferrerInfo.get());
11034
11035 if (referrerInfo->IsPolicyOverrided() &&
11036 referrerInfo->ReferrerPolicy() ==
11037 ReferrerInfo::GetDefaultReferrerPolicy(nullptr, nullptr,
11038 isPrivate)) {
11039 nsCOMPtr<nsIReferrerInfo> newReferrerInfo =
11040 referrerInfo->CloneWithNewPolicy(
11041 ReferrerInfo::GetDefaultReferrerPolicy(this, mURI, isPrivate));
11042 // The arguments passed to SetReferrerInfoInternal here should mirror
11043 // the arguments passed in
11044 // HttpChannelChild::RecvOverrideReferrerInfoDuringBeginConnect().
11045 SetReferrerInfoInternal(newReferrerInfo, false, true, true);
11046
11047 nsCOMPtr<nsIParentChannel> parentChannel;
11048 NS_QueryNotificationCallbacks(this, parentChannel);
11049 RefPtr<HttpChannelParent> httpParent = do_QueryObject(parentChannel);
11050 if (httpParent) {
11051 httpParent->OverrideReferrerInfoDuringBeginConnect(newReferrerInfo);
11052 }
11053 }
11054 }
11055 }
11056}
11057
11058namespace {
11059
11060class BackgroundRevalidatingListener : public nsIStreamListener {
11061 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:
11062
11063 NS_DECL_NSISTREAMLISTENERvirtual nsresult OnDataAvailable(nsIRequest *aRequest, nsIInputStream
*aInputStream, uint64_t aOffset, uint32_t aCount) override;
11064 NS_DECL_NSIREQUESTOBSERVERvirtual nsresult OnStartRequest(nsIRequest *aRequest) override
; virtual nsresult OnStopRequest(nsIRequest *aRequest, nsresult
aStatusCode) override;
11065
11066 private:
11067 virtual ~BackgroundRevalidatingListener() = default;
11068};
11069
11070NS_IMETHODIMPnsresult
11071BackgroundRevalidatingListener::OnStartRequest(nsIRequest* request) {
11072 return NS_OK;
11073}
11074
11075NS_IMETHODIMPnsresult
11076BackgroundRevalidatingListener::OnDataAvailable(nsIRequest* request,
11077 nsIInputStream* input,
11078 uint64_t offset,
11079 uint32_t count) {
11080 uint32_t bytesRead = 0;
11081 return input->ReadSegments(NS_DiscardSegment, nullptr, count, &bytesRead);
11082}
11083
11084NS_IMETHODIMPnsresult
11085BackgroundRevalidatingListener::OnStopRequest(nsIRequest* request,
11086 nsresult status) {
11087 if (NS_FAILED(status)((bool)(__builtin_expect(!!(NS_FAILED_impl(status)), 0)))) {
11088 return status;
11089 }
11090
11091 nsCOMPtr<nsIHttpChannel> channel(do_QueryInterface(request));
11092 if (gHttpHandler) {
11093 gHttpHandler->OnBackgroundRevalidation(channel);
11094 }
11095 return NS_OK;
11096}
11097
11098NS_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"
, 11099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
11099; __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"
, 11099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"BackgroundRevalidatingListener\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 11099; __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"
, 11099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 11099
; __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"
, 11099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"BackgroundRevalidatingListener\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 11099; __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"
, 11099); 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(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
11099 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"
, 11099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
11099; __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"
, 11099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"BackgroundRevalidatingListener\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 11099; __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"
, 11099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 11099
; __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"
, 11099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"BackgroundRevalidatingListener\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 11099; __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"
, 11099); 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(std::size(table) > 1, "need at least 1 interface"
); rv = NS_TableDrivenQI(static_cast<void*>(this), aIID
, aInstancePtr, table); return rv; }
11100
11101} // namespace
11102
11103void nsHttpChannel::PerformBackgroundCacheRevalidation() {
11104 if (!StaticPrefs::network_http_stale_while_revalidate_enabled()) {
11105 return;
11106 }
11107
11108 // This is a channel doing a revalidation. It shouldn't do it again.
11109 if (mStaleRevalidation) {
11110 return;
11111 }
11112
11113 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)
;
11114
11115 Unused << NS_DispatchToMainThreadQueue(
11116 NewIdleRunnableMethod(
11117 "nsHttpChannel::PerformBackgroundCacheRevalidation", this,
11118 &nsHttpChannel::PerformBackgroundCacheRevalidationNow),
11119 EventQueuePriority::Idle);
11120}
11121
11122void nsHttpChannel::PerformBackgroundCacheRevalidationNow() {
11123 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)
;
11124
11125 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"
, 11125); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 11125; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11126
11127 nsresult rv;
11128
11129 nsLoadFlags loadFlags = mLoadFlags | LOAD_ONLY_IF_MODIFIED | VALIDATE_ALWAYS |
11130 LOAD_BACKGROUND | LOAD_BYPASS_SERVICE_WORKER;
11131
11132 nsCOMPtr<nsIChannel> validatingChannel;
11133 rv = NS_NewChannelInternal(getter_AddRefs(validatingChannel), mURI, mLoadInfo,
11134 nullptr /* performance storage */, mLoadGroup,
11135 mCallbacks, loadFlags);
11136 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
11137 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)
11138 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)
;
11139 return;
11140 }
11141
11142 nsCOMPtr<nsISupportsPriority> priority(do_QueryInterface(validatingChannel));
11143 if (priority) {
11144 priority->SetPriority(nsISupportsPriority::PRIORITY_LOWEST);
11145 }
11146
11147 nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(validatingChannel));
11148 if (cos) {
11149 cos->AddClassFlags(nsIClassOfService::Tail);
11150 }
11151
11152 RefPtr<nsHttpChannel> httpChan = do_QueryObject(validatingChannel);
11153 if (httpChan) {
11154 httpChan->mStaleRevalidation = true;
11155 }
11156
11157 RefPtr<BackgroundRevalidatingListener> listener =
11158 new BackgroundRevalidatingListener();
11159 rv = validatingChannel->AsyncOpen(listener);
11160 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
11161 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)
;
11162 return;
11163 }
11164
11165 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)
11166 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)
;
11167}
11168
11169NS_IMETHODIMPnsresult
11170nsHttpChannel::SetEarlyHintObserver(nsIEarlyHintObserver* aObserver) {
11171 mEarlyHintObserver = aObserver;
11172 return NS_OK;
11173}
11174
11175NS_IMETHODIMPnsresult
11176nsHttpChannel::EarlyHint(const nsACString& aLinkHeader,
11177 const nsACString& aReferrerPolicy,
11178 const nsACString& aCspHeader) {
11179 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)
;
11180
11181 if (mEarlyHintObserver && nsContentUtils::ComputeIsSecureContext(this)) {
11182 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)
;
11183 mEarlyHintObserver->EarlyHint(aLinkHeader, aReferrerPolicy, aCspHeader);
11184 }
11185 return NS_OK;
11186}
11187
11188NS_IMETHODIMPnsresult nsHttpChannel::SetResponseOverride(
11189 nsIReplacedHttpResponse* aReplacedHttpResponse) {
11190 mOverrideResponse = new nsMainThreadPtrHolder<nsIReplacedHttpResponse>(
11191 "nsIReplacedHttpResponse", aReplacedHttpResponse);
11192 return NS_OK;
11193}
11194
11195NS_IMETHODIMPnsresult nsHttpChannel::SetResponseStatus(uint32_t aStatus,
11196 const nsACString& aStatusText) {
11197 if (!mResponseHead) {
11198 return NS_ERROR_NOT_AVAILABLE;
11199 }
11200
11201 nsAutoCString statusText(aStatusText);
11202 nsAutoCString protocolVersion(
11203 nsHttp::GetProtocolVersion(mResponseHead->Version()));
11204 ToUpperCase(protocolVersion);
11205
11206 nsPrintfCString line("%s %u %s", protocolVersion.get(), aStatus,
11207 statusText.get());
11208
11209 return mResponseHead->ParseStatusLine(line);
11210}
11211
11212NS_IMETHODIMPnsresult nsHttpChannel::SetWebTransportSessionEventListener(
11213 WebTransportSessionEventListener* aListener) {
11214 mWebTransportSessionEventListener = aListener;
11215 return NS_OK;
11216}
11217
11218already_AddRefed<WebTransportSessionEventListener>
11219nsHttpChannel::GetWebTransportSessionEventListener() {
11220 RefPtr<WebTransportSessionEventListener> wt =
11221 mWebTransportSessionEventListener;
11222 return wt.forget();
11223}
11224
11225NS_IMETHODIMPnsresult nsHttpChannel::GetLastTransportStatus(
11226 nsresult* aLastTransportStatus) {
11227 *aLastTransportStatus = mLastTransportStatus;
11228 return NS_OK;
11229}
11230
11231} // namespace net
11232} // namespace mozilla