Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Unified_cpp_protocol_http2.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_http2.cpp
1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* vim: set sw=2 ts=8 et tw=80 : */
3
4/* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8// HttpLog.h should generally be included first
9#include "mozilla/net/HttpBaseChannel.h"
10
11#include <algorithm>
12#include <utility>
13
14#include "HttpBaseChannel.h"
15#include "HttpLog.h"
16#include "LoadInfo.h"
17#include "ReferrerInfo.h"
18#include "mozIRemoteLazyInputStream.h"
19#include "mozIThirdPartyUtil.h"
20#include "mozilla/LoadInfo.h"
21#include "mozilla/AntiTrackingUtils.h"
22#include "mozilla/BasePrincipal.h"
23#include "mozilla/BinarySearch.h"
24#include "mozilla/ConsoleReportCollector.h"
25#include "mozilla/DebugOnly.h"
26#include "mozilla/InputStreamLengthHelper.h"
27#include "mozilla/Mutex.h"
28#include "mozilla/NullPrincipal.h"
29#include "mozilla/PermissionManager.h"
30#include "mozilla/Components.h"
31#include "mozilla/StaticPrefs_browser.h"
32#include "mozilla/StaticPrefs_fission.h"
33#include "mozilla/StaticPrefs_network.h"
34#include "mozilla/StaticPrefs_security.h"
35#include "mozilla/glean/GleanMetrics.h"
36#include "mozilla/Telemetry.h"
37#include "mozilla/Tokenizer.h"
38#include "mozilla/browser/NimbusFeatures.h"
39#include "mozilla/dom/BrowsingContext.h"
40#include "mozilla/dom/CanonicalBrowsingContext.h"
41#include "mozilla/dom/Document.h"
42#include "mozilla/dom/FetchPriority.h"
43#include "mozilla/dom/nsHTTPSOnlyUtils.h"
44#include "mozilla/dom/nsMixedContentBlocker.h"
45#include "mozilla/dom/Performance.h"
46#include "mozilla/dom/PerformanceStorage.h"
47#include "mozilla/dom/ProcessIsolation.h"
48#include "mozilla/dom/RequestBinding.h"
49#include "mozilla/dom/WindowGlobalParent.h"
50#include "mozilla/net/OpaqueResponseUtils.h"
51#include "mozilla/net/UrlClassifierCommon.h"
52#include "mozilla/net/UrlClassifierFeatureFactory.h"
53#include "nsBufferedStreams.h"
54#include "nsCOMPtr.h"
55#include "nsCRT.h"
56#include "nsContentSecurityManager.h"
57#include "nsContentSecurityUtils.h"
58#include "nsContentUtils.h"
59#include "nsDebug.h"
60#include "nsEscape.h"
61#include "nsGlobalWindowInner.h"
62#include "nsGlobalWindowOuter.h"
63#include "nsHttpChannel.h"
64#include "nsHTTPCompressConv.h"
65#include "nsHttpHandler.h"
66#include "nsICacheInfoChannel.h"
67#include "nsICachingChannel.h"
68#include "nsIChannelEventSink.h"
69#include "nsIConsoleService.h"
70#include "nsIContentPolicy.h"
71#include "nsICookieService.h"
72#include "nsIDOMWindowUtils.h"
73#include "nsIDocShell.h"
74#include "nsIDNSService.h"
75#include "nsIEncodedChannel.h"
76#include "nsIHttpHeaderVisitor.h"
77#include "nsILoadGroupChild.h"
78#include "nsIMIMEInputStream.h"
79#include "nsIMultiplexInputStream.h"
80#include "nsIMutableArray.h"
81#include "nsINetworkInterceptController.h"
82#include "nsIObserverService.h"
83#include "nsIPrincipal.h"
84#include "nsIProtocolProxyService.h"
85#include "nsIScriptError.h"
86#include "nsIScriptSecurityManager.h"
87#include "nsISecurityConsoleMessage.h"
88#include "nsISeekableStream.h"
89#include "nsIStorageStream.h"
90#include "nsIStreamConverterService.h"
91#include "nsITimedChannel.h"
92#include "nsITransportSecurityInfo.h"
93#include "nsIURIMutator.h"
94#include "nsMimeTypes.h"
95#include "nsNetCID.h"
96#include "nsNetUtil.h"
97#include "nsPIDOMWindow.h"
98#include "nsProxyRelease.h"
99#include "nsReadableUtils.h"
100#include "nsRedirectHistoryEntry.h"
101#include "nsServerTiming.h"
102#include "nsStreamListenerWrapper.h"
103#include "nsStreamUtils.h"
104#include "nsString.h"
105#include "nsThreadUtils.h"
106#include "nsURLHelper.h"
107#include "mozilla/RemoteLazyInputStreamChild.h"
108#include "mozilla/net/SFVService.h"
109#include "mozilla/dom/ContentChild.h"
110#include "nsQueryObject.h"
111
112using mozilla::dom::RequestMode;
113
114#define LOGORB(msg, ...)do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " msg, __func__, this, ...); } } while
(0)
\
115 MOZ_LOG(GetORBLog(), LogLevel::Debug, \do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " msg, __func__, this, ##__VA_ARGS__
); } } while (0)
116 ("%s: %p " msg, __func__, this, ##__VA_ARGS__))do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " msg, __func__, this, ##__VA_ARGS__
); } } while (0)
117
118namespace mozilla {
119namespace net {
120
121static bool IsHeaderBlacklistedForRedirectCopy(nsHttpAtom const& aHeader) {
122 // IMPORTANT: keep this list ASCII-code sorted
123 static nsHttpAtomLiteral const* blackList[] = {
124 &nsHttp::Accept,
125 &nsHttp::Accept_Encoding,
126 &nsHttp::Accept_Language,
127 &nsHttp::Alternate_Service_Used,
128 &nsHttp::Authentication,
129 &nsHttp::Authorization,
130 &nsHttp::Connection,
131 &nsHttp::Content_Length,
132 &nsHttp::Cookie,
133 &nsHttp::Host,
134 &nsHttp::If,
135 &nsHttp::If_Match,
136 &nsHttp::If_Modified_Since,
137 &nsHttp::If_None_Match,
138 &nsHttp::If_None_Match_Any,
139 &nsHttp::If_Range,
140 &nsHttp::If_Unmodified_Since,
141 &nsHttp::Proxy_Authenticate,
142 &nsHttp::Proxy_Authorization,
143 &nsHttp::Range,
144 &nsHttp::TE,
145 &nsHttp::Transfer_Encoding,
146 &nsHttp::Upgrade,
147 &nsHttp::User_Agent,
148 &nsHttp::WWW_Authenticate};
149
150 class HttpAtomComparator {
151 nsHttpAtom const& mTarget;
152
153 public:
154 explicit HttpAtomComparator(nsHttpAtom const& aTarget) : mTarget(aTarget) {}
155 int operator()(nsHttpAtom const* aVal) const {
156 if (mTarget == *aVal) {
157 return 0;
158 }
159 return strcmp(mTarget.get(), aVal->get());
160 }
161 int operator()(nsHttpAtomLiteral const* aVal) const {
162 if (mTarget == *aVal) {
163 return 0;
164 }
165 return strcmp(mTarget.get(), aVal->get());
166 }
167 };
168
169 size_t unused;
170 return BinarySearchIf(blackList, 0, std::size(blackList),
171 HttpAtomComparator(aHeader), &unused);
172}
173
174class AddHeadersToChannelVisitor final : public nsIHttpHeaderVisitor {
175 public:
176 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:
177
178 explicit AddHeadersToChannelVisitor(nsIHttpChannel* aChannel)
179 : mChannel(aChannel) {}
180
181 NS_IMETHODvirtual nsresult VisitHeader(const nsACString& aHeader,
182 const nsACString& aValue) override {
183 nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
184 if (!IsHeaderBlacklistedForRedirectCopy(atom)) {
185 DebugOnly<nsresult> rv =
186 mChannel->SetRequestHeader(aHeader, aValue, false);
187 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/HttpBaseChannel.cpp"
, 187); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 187; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
188 }
189 return NS_OK;
190 }
191
192 private:
193 ~AddHeadersToChannelVisitor() = default;
194
195 nsCOMPtr<nsIHttpChannel> mChannel;
196};
197
198NS_IMPL_ISUPPORTS(AddHeadersToChannelVisitor, nsIHttpHeaderVisitor)MozExternalRefCountType AddHeadersToChannelVisitor::AddRef(void
) { static_assert(!std::is_destructible_v<AddHeadersToChannelVisitor
>, "Reference-counted class " "AddHeadersToChannelVisitor"
" 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/HttpBaseChannel.cpp"
, 198); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
198; __attribute__((nomerge)) ::abort(); } while (false); } }
while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("AddHeadersToChannelVisitor" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("AddHeadersToChannelVisitor" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"AddHeadersToChannelVisitor\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 198); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"AddHeadersToChannelVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 198; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("AddHeadersToChannelVisitor" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"AddHeadersToChannelVisitor"), (uint32_t)(sizeof(*this))); return
count; } MozExternalRefCountType AddHeadersToChannelVisitor::
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/HttpBaseChannel.cpp"
, 198); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 198
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("AddHeadersToChannelVisitor" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("AddHeadersToChannelVisitor" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"AddHeadersToChannelVisitor\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 198); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"AddHeadersToChannelVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 198; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("AddHeadersToChannelVisitor" " not thread-safe"
); const char* const nametmp = "AddHeadersToChannelVisitor"; nsrefcnt
count = --mRefCnt; NS_LogRelease((this), (count), (nametmp))
; if (count == 0) { mRefCnt = 1; delete (this); return 0; } return
count; } nsresult AddHeadersToChannelVisitor::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/HttpBaseChannel.cpp"
, 198); 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<AddHeadersToChannelVisitor, nsIHttpHeaderVisitor
>, int32_t( reinterpret_cast<char*>(static_cast<nsIHttpHeaderVisitor
*>((AddHeadersToChannelVisitor*)0x1000)) - reinterpret_cast
<char*>((AddHeadersToChannelVisitor*)0x1000))}, {&mozilla
::detail::kImplementedIID<AddHeadersToChannelVisitor, nsISupports
>, int32_t(reinterpret_cast<char*>(static_cast<nsISupports
*>( static_cast<nsIHttpHeaderVisitor*>((AddHeadersToChannelVisitor
*)0x1000))) - reinterpret_cast<char*>((AddHeadersToChannelVisitor
*)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; }
199
200static OpaqueResponseFilterFetch ConfiguredFilterFetchResponseBehaviour() {
201 uint32_t pref = StaticPrefs::
202 browser_opaqueResponseBlocking_filterFetchResponse_DoNotUseDirectly();
203 if (NS_WARN_IF(pref >NS_warn_if_impl(pref > static_cast<uint32_t>(OpaqueResponseFilterFetch
::All), "pref > static_cast<uint32_t>(OpaqueResponseFilterFetch::All)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 204)
204 static_cast<uint32_t>(OpaqueResponseFilterFetch::All))NS_warn_if_impl(pref > static_cast<uint32_t>(OpaqueResponseFilterFetch
::All), "pref > static_cast<uint32_t>(OpaqueResponseFilterFetch::All)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 204)
) {
205 return OpaqueResponseFilterFetch::All;
206 }
207
208 return static_cast<OpaqueResponseFilterFetch>(pref);
209}
210
211HttpBaseChannel::HttpBaseChannel()
212 : mReportCollector(new ConsoleReportCollector()),
213 mHttpHandler(gHttpHandler),
214 mChannelCreationTime(0),
215 mComputedCrossOriginOpenerPolicy(nsILoadInfo::OPENER_POLICY_UNSAFE_NONE),
216 mStartPos(UINT64_MAX(18446744073709551615UL)),
217 mTransferSize(0),
218 mRequestSize(0),
219 mDecodedBodySize(0),
220 mSupportsHTTP3(false),
221 mEncodedBodySize(0),
222 mRequestContextID(0),
223 mContentWindowId(0),
224 mBrowserId(0),
225 mAltDataLength(-1),
226 mChannelId(0),
227 mReqContentLength(0U),
228 mStatus(NS_OK),
229 mCanceled(false),
230 mFirstPartyClassificationFlags(0),
231 mThirdPartyClassificationFlags(0),
232 mLoadFlags(LOAD_NORMAL),
233 mCaps(0),
234 mClassOfService(0, false),
235 mTlsFlags(0),
236 mSuspendCount(0),
237 mInitialRwin(0),
238 mProxyResolveFlags(0),
239 mContentDispositionHint(UINT32_MAX(4294967295U)),
240 mRequestMode(RequestMode::No_cors),
241 mRedirectMode(nsIHttpChannelInternal::REDIRECT_MODE_FOLLOW),
242 mLastRedirectFlags(0),
243 mPriority(PRIORITY_NORMAL),
244 mRedirectionLimit(gHttpHandler->RedirectionLimit()),
245 mRedirectCount(0),
246 mInternalRedirectCount(0),
247 mCachedOpaqueResponseBlockingPref(
248 StaticPrefs::browser_opaqueResponseBlocking()),
249 mChannelBlockedByOpaqueResponse(false),
250 mDummyChannelForCachedResource(false),
251 mHasContentDecompressed(false),
252 mRenderBlocking(false) {
253 StoreApplyConversion(true);
254 StoreAllowSTS(true);
255 StoreTracingEnabled(true);
256 StoreReportTiming(true);
257 StoreAllowSpdy(true);
258 StoreAllowHttp3(true);
259 StoreAllowAltSvc(true);
260 StoreResponseTimeoutEnabled(true);
261 StoreAllRedirectsSameOrigin(true);
262 StoreAllRedirectsPassTimingAllowCheck(true);
263 StoreUpgradableToSecure(true);
264 StoreIsUserAgentHeaderModified(false);
265
266 this->mSelfAddr.inet = {};
267 this->mPeerAddr.inet = {};
268 LOG(("Creating HttpBaseChannel @%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 HttpBaseChannel @%p\n", this); } } while (0)
;
269
270 // Subfields of unions cannot be targeted in an initializer list.
271#ifdef MOZ_VALGRIND
272 // Zero the entire unions so that Valgrind doesn't complain when we send them
273 // to another process.
274 memset(&mSelfAddr, 0, sizeof(NetAddr));
275 memset(&mPeerAddr, 0, sizeof(NetAddr));
276#endif
277 mSelfAddr.raw.family = PR_AF_UNSPEC0;
278 mPeerAddr.raw.family = PR_AF_UNSPEC0;
279}
280
281HttpBaseChannel::~HttpBaseChannel() {
282 LOG(("Destroying HttpBaseChannel @%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 HttpBaseChannel @%p\n", this); } } while (0)
;
283
284 // Make sure we don't leak
285 CleanRedirectCacheChainIfNecessary();
286
287 ReleaseMainThreadOnlyReferences();
288}
289
290namespace { // anon
291
292class NonTailRemover : public nsISupports {
293 NS_DECL_THREADSAFE_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::true_type; protected
: ::mozilla::ThreadSafeAutoRefCnt mRefCnt; nsAutoOwningThread
_mOwningThread; public:
294
295 explicit NonTailRemover(nsIRequestContext* rc) : mRequestContext(rc) {}
296
297 private:
298 virtual ~NonTailRemover() {
299 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/HttpBaseChannel.cpp"
, 299); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 299; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
300 mRequestContext->RemoveNonTailRequest();
301 }
302
303 nsCOMPtr<nsIRequestContext> mRequestContext;
304};
305
306NS_IMPL_ISUPPORTS0(NonTailRemover)MozExternalRefCountType NonTailRemover::AddRef(void) { static_assert
(!std::is_destructible_v<NonTailRemover>, "Reference-counted class "
"NonTailRemover" " 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/HttpBaseChannel.cpp"
, 306); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
306; __attribute__((nomerge)) ::abort(); } while (false); } }
while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("NonTailRemover" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("NonTailRemover" != nullptr)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"NonTailRemover\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 306); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"NonTailRemover\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 306; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("NonTailRemover" " not thread-safe"); nsrefcnt
count = ++mRefCnt; NS_LogAddRef((this), (count), ("NonTailRemover"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
NonTailRemover::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/HttpBaseChannel.cpp"
, 306); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 306
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("NonTailRemover" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("NonTailRemover" != nullptr)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("\"NonTailRemover\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 306); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"NonTailRemover\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 306; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("NonTailRemover" " not thread-safe"); const char
* const nametmp = "NonTailRemover"; nsrefcnt count = --mRefCnt
; NS_LogRelease((this), (count), (nametmp)); if (count == 0) {
mRefCnt = 1; delete (this); return 0; } return count; } nsresult
NonTailRemover::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/HttpBaseChannel.cpp"
, 306); MOZ_PretendNoReturn(); } } while (0); nsresult rv = NS_ERROR_FAILURE
; static const QITableEntry table[] = { {&mozilla::detail
::kImplementedIID<NonTailRemover, nsISupports>, int32_t
( reinterpret_cast<char*>(static_cast<nsISupports*>
((NonTailRemover*)0x1000)) - reinterpret_cast<char*>((NonTailRemover
*)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; }
307
308} // namespace
309
310void HttpBaseChannel::ReleaseMainThreadOnlyReferences() {
311 if (NS_IsMainThread()) {
312 // Already on main thread, let dtor to
313 // take care of releasing references
314 RemoveAsNonTailRequest();
315 return;
316 }
317
318 nsTArray<nsCOMPtr<nsISupports>> arrayToRelease;
319 arrayToRelease.AppendElement(mLoadGroup.forget());
320 arrayToRelease.AppendElement(mLoadInfo.forget());
321 arrayToRelease.AppendElement(mCallbacks.forget());
322 arrayToRelease.AppendElement(mProgressSink.forget());
323 arrayToRelease.AppendElement(mPrincipal.forget());
324 arrayToRelease.AppendElement(mListener.forget());
325 arrayToRelease.AppendElement(mCompressListener.forget());
326 arrayToRelease.AppendElement(mORB.forget());
327
328 if (LoadAddedAsNonTailRequest()) {
329 // RemoveNonTailRequest() on our request context must be called on the main
330 // thread
331 MOZ_RELEASE_ASSERT(mRequestContext,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRequestContext)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mRequestContext))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mRequestContext"
" (" "Someone released rc or set flags w/o having it?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 332); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mRequestContext"
") (" "Someone released rc or set flags w/o having it?" ")")
; do { *((volatile int*)__null) = 332; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
332 "Someone released rc or set flags w/o having it?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRequestContext)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mRequestContext))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("mRequestContext"
" (" "Someone released rc or set flags w/o having it?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 332); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "mRequestContext"
") (" "Someone released rc or set flags w/o having it?" ")")
; do { *((volatile int*)__null) = 332; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
333
334 nsCOMPtr<nsISupports> nonTailRemover(new NonTailRemover(mRequestContext));
335 arrayToRelease.AppendElement(nonTailRemover.forget());
336 }
337
338 NS_DispatchToMainThread(new ProxyReleaseRunnable(std::move(arrayToRelease)));
339}
340
341void HttpBaseChannel::AddClassificationFlags(uint32_t aClassificationFlags,
342 bool aIsThirdParty) {
343 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
, "HttpBaseChannel::AddClassificationFlags classificationFlags=%d "
"thirdparty=%d %p", aClassificationFlags, static_cast<int
>(aIsThirdParty), this); } } while (0)
344 ("HttpBaseChannel::AddClassificationFlags classificationFlags=%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
, "HttpBaseChannel::AddClassificationFlags classificationFlags=%d "
"thirdparty=%d %p", aClassificationFlags, static_cast<int
>(aIsThirdParty), this); } } while (0)
345 "thirdparty=%d %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
, "HttpBaseChannel::AddClassificationFlags classificationFlags=%d "
"thirdparty=%d %p", aClassificationFlags, static_cast<int
>(aIsThirdParty), this); } } while (0)
346 aClassificationFlags, static_cast<int>(aIsThirdParty), 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
, "HttpBaseChannel::AddClassificationFlags classificationFlags=%d "
"thirdparty=%d %p", aClassificationFlags, static_cast<int
>(aIsThirdParty), this); } } while (0)
;
347
348 if (aIsThirdParty) {
349 mThirdPartyClassificationFlags |= aClassificationFlags;
350 } else {
351 mFirstPartyClassificationFlags |= aClassificationFlags;
352 }
353}
354
355static bool isSecureOrTrustworthyURL(nsIURI* aURI) {
356 return aURI->SchemeIs("https") ||
357 (StaticPrefs::network_http_encoding_trustworthy_is_https() &&
358 nsMixedContentBlocker::IsPotentiallyTrustworthyLoopbackURL(aURI));
359}
360
361nsresult HttpBaseChannel::Init(nsIURI* aURI, uint32_t aCaps,
362 nsProxyInfo* aProxyInfo,
363 uint32_t aProxyResolveFlags, nsIURI* aProxyURI,
364 uint64_t aChannelId,
365 ExtContentPolicyType aContentPolicyType,
366 nsILoadInfo* aLoadInfo) {
367 LOG1(("HttpBaseChannel::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, "HttpBaseChannel::Init [this=%p]\n"
, this); } } while (0)
;
368
369 MOZ_ASSERT(aURI, "null uri")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aURI)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(aURI))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("aURI" " (" "null uri" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 369); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aURI" ") (" "null uri"
")"); do { *((volatile int*)__null) = 369; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
370
371 mURI = aURI;
372 mOriginalURI = aURI;
373 mDocumentURI = nullptr;
374 mCaps = aCaps;
375 mProxyResolveFlags = aProxyResolveFlags;
376 mProxyURI = aProxyURI;
377 mChannelId = aChannelId;
378 mLoadInfo = aLoadInfo;
379
380 // Construct connection info object
381 nsAutoCString host;
382 int32_t port = -1;
383 bool isHTTPS = isSecureOrTrustworthyURL(mURI);
384
385 nsresult rv = mURI->GetAsciiHost(host);
386 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
387
388 // Reject the URL if it doesn't specify a host
389 if (host.IsEmpty()) return NS_ERROR_MALFORMED_URI;
390
391 rv = mURI->GetPort(&port);
392 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
393
394 LOG1(("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::Error)), 0))) { mozilla::
detail::log_print(moz_real_module, mozilla::LogLevel::Error, "host=%s port=%d\n"
, host.get(), port); } } while (0)
;
395
396 rv = mURI->GetAsciiSpec(mSpec);
397 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
398 LOG1(("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::Error)), 0))) { mozilla::
detail::log_print(moz_real_module, mozilla::LogLevel::Error, "uri=%s\n"
, mSpec.get()); } } while (0)
;
399
400 // Assert default request method
401 MOZ_ASSERT(mRequestHead.EqualsMethod(nsHttpRequestHead::kMethod_Get))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mRequestHead.EqualsMethod(nsHttpRequestHead::kMethod_Get
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mRequestHead.EqualsMethod(nsHttpRequestHead::kMethod_Get
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mRequestHead.EqualsMethod(nsHttpRequestHead::kMethod_Get)",
"/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 401); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mRequestHead.EqualsMethod(nsHttpRequestHead::kMethod_Get)"
")"); do { *((volatile int*)__null) = 401; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
402
403 // Set request headers
404 nsAutoCString hostLine;
405 rv = nsHttpHandler::GenerateHostPort(host, port, hostLine);
406 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
407
408 rv = mRequestHead.SetHeader(nsHttp::Host, hostLine);
409 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
410
411 rv = gHttpHandler->AddStandardRequestHeaders(
412 &mRequestHead, isHTTPS, aContentPolicyType,
413 nsContentUtils::ShouldResistFingerprinting(this,
414 RFPTarget::HttpUserAgent));
415 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) return rv;
416
417 nsAutoCString type;
418 if (aProxyInfo && NS_SUCCEEDED(aProxyInfo->GetType(type))((bool)(__builtin_expect(!!(!NS_FAILED_impl(aProxyInfo->GetType
(type))), 1)))
&&
419 !type.EqualsLiteral("unknown")) {
420 mProxyInfo = aProxyInfo;
421 }
422
423 mCurrentThread = GetCurrentSerialEventTarget();
424 return rv;
425}
426
427//-----------------------------------------------------------------------------
428// HttpBaseChannel::nsISupports
429//-----------------------------------------------------------------------------
430
431NS_IMPL_ADDREF(HttpBaseChannel)MozExternalRefCountType HttpBaseChannel::AddRef(void) { static_assert
(!std::is_destructible_v<HttpBaseChannel>, "Reference-counted class "
"HttpBaseChannel" " 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/HttpBaseChannel.cpp"
, 431); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
431; __attribute__((nomerge)) ::abort(); } while (false); } }
while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("HttpBaseChannel" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("HttpBaseChannel" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"HttpBaseChannel\" != nullptr" " (" "Must specify a name" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 431); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 431; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("HttpBaseChannel" " not thread-safe"); nsrefcnt
count = ++mRefCnt; NS_LogAddRef((this), (count), ("HttpBaseChannel"
), (uint32_t)(sizeof(*this))); return count; }
432NS_IMPL_RELEASE(HttpBaseChannel)MozExternalRefCountType HttpBaseChannel::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/HttpBaseChannel.cpp"
, 432); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 432
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("HttpBaseChannel" != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!("HttpBaseChannel" != nullptr
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"\"HttpBaseChannel\" != nullptr" " (" "Must specify a name" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 432); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 432; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("HttpBaseChannel" " not thread-safe"); const
char* const nametmp = "HttpBaseChannel"; nsrefcnt count = --
mRefCnt; NS_LogRelease((this), (count), (nametmp)); if (count
== 0) { mRefCnt = 1; delete (this); return 0; } return count
; }
433
434NS_INTERFACE_MAP_BEGIN(HttpBaseChannel)nsresult HttpBaseChannel::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/HttpBaseChannel.cpp"
, 434); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
435 NS_INTERFACE_MAP_ENTRY(nsIRequest)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequest>)) foundInterface = static_cast
<nsIRequest*>(this); else
436 NS_INTERFACE_MAP_ENTRY(nsIChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIChannel>)) foundInterface = static_cast
<nsIChannel*>(this); else
437 NS_INTERFACE_MAP_ENTRY(nsIIdentChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIIdentChannel>)) foundInterface
= static_cast<nsIIdentChannel*>(this); else
438 NS_INTERFACE_MAP_ENTRY(nsIEncodedChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIEncodedChannel>)) foundInterface
= static_cast<nsIEncodedChannel*>(this); else
439 NS_INTERFACE_MAP_ENTRY(nsIHttpChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIHttpChannel>)) foundInterface =
static_cast<nsIHttpChannel*>(this); else
440 NS_INTERFACE_MAP_ENTRY(nsIHttpChannelInternal)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIHttpChannelInternal>)) foundInterface
= static_cast<nsIHttpChannelInternal*>(this); else
441 NS_INTERFACE_MAP_ENTRY(nsIForcePendingChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIForcePendingChannel>)) foundInterface
= static_cast<nsIForcePendingChannel*>(this); else
442 NS_INTERFACE_MAP_ENTRY(nsIUploadChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIUploadChannel>)) foundInterface
= static_cast<nsIUploadChannel*>(this); else
443 NS_INTERFACE_MAP_ENTRY(nsIFormPOSTActionChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIFormPOSTActionChannel>)) foundInterface
= static_cast<nsIFormPOSTActionChannel*>(this); else
444 NS_INTERFACE_MAP_ENTRY(nsIUploadChannel2)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIUploadChannel2>)) foundInterface
= static_cast<nsIUploadChannel2*>(this); else
445 NS_INTERFACE_MAP_ENTRY(nsISupportsPriority)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupportsPriority>)) foundInterface
= static_cast<nsISupportsPriority*>(this); else
446 NS_INTERFACE_MAP_ENTRY(nsITraceableChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsITraceableChannel>)) foundInterface
= static_cast<nsITraceableChannel*>(this); else
447 NS_INTERFACE_MAP_ENTRY(nsIPrivateBrowsingChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIPrivateBrowsingChannel>)) foundInterface
= static_cast<nsIPrivateBrowsingChannel*>(this); else
448 NS_INTERFACE_MAP_ENTRY(nsITimedChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsITimedChannel>)) foundInterface
= static_cast<nsITimedChannel*>(this); else
449 NS_INTERFACE_MAP_ENTRY(nsIConsoleReportCollector)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIConsoleReportCollector>)) foundInterface
= static_cast<nsIConsoleReportCollector*>(this); else
450 NS_INTERFACE_MAP_ENTRY(nsIThrottledInputChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIThrottledInputChannel>)) foundInterface
= static_cast<nsIThrottledInputChannel*>(this); else
451 NS_INTERFACE_MAP_ENTRY(nsIClassifiedChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIClassifiedChannel>)) foundInterface
= static_cast<nsIClassifiedChannel*>(this); else
452 NS_INTERFACE_MAP_ENTRY_CONCRETE(HttpBaseChannel)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, HttpBaseChannel>)) { *aInstancePtr
= do_AddRef(static_cast<HttpBaseChannel*>(this)).take(
); return NS_OK; } else
453NS_INTERFACE_MAP_END_INHERITING(nsHashPropertyBag)foundInterface = 0; nsresult status; if (!foundInterface) status
= nsHashPropertyBag::QueryInterface(aIID, (void**)&foundInterface
); else { (foundInterface)->AddRef(); status = NS_OK; } *aInstancePtr
= foundInterface; return status; }
454
455//-----------------------------------------------------------------------------
456// HttpBaseChannel::nsIRequest
457//-----------------------------------------------------------------------------
458
459NS_IMETHODIMPnsresult
460HttpBaseChannel::GetName(nsACString& aName) {
461 aName = mSpec;
462 return NS_OK;
463}
464
465NS_IMETHODIMPnsresult
466HttpBaseChannel::IsPending(bool* aIsPending) {
467 NS_ENSURE_ARG_POINTER(aIsPending)do { if ((__builtin_expect(!!(!(aIsPending)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aIsPending" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 467); return NS_ERROR_INVALID_POINTER; } } while (false)
;
468 *aIsPending = LoadIsPending() || LoadForcePending();
469 return NS_OK;
470}
471
472NS_IMETHODIMPnsresult
473HttpBaseChannel::GetStatus(nsresult* aStatus) {
474 NS_ENSURE_ARG_POINTER(aStatus)do { if ((__builtin_expect(!!(!(aStatus)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aStatus" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 474); return NS_ERROR_INVALID_POINTER; } } while (false)
;
475 *aStatus = mStatus;
476 return NS_OK;
477}
478
479NS_IMETHODIMPnsresult
480HttpBaseChannel::GetLoadGroup(nsILoadGroup** aLoadGroup) {
481 NS_ENSURE_ARG_POINTER(aLoadGroup)do { if ((__builtin_expect(!!(!(aLoadGroup)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aLoadGroup" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 481); return NS_ERROR_INVALID_POINTER; } } while (false)
;
482 *aLoadGroup = do_AddRef(mLoadGroup).take();
483 return NS_OK;
484}
485
486NS_IMETHODIMPnsresult
487HttpBaseChannel::SetLoadGroup(nsILoadGroup* aLoadGroup) {
488 MOZ_ASSERT(NS_IsMainThread(), "Should only 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 only be called on the main thread." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 488); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should only be called on the main thread." ")"); do {
*((volatile int*)__null) = 488; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
489
490 if (!CanSetLoadGroup(aLoadGroup)) {
491 return NS_ERROR_FAILURE;
492 }
493
494 mLoadGroup = aLoadGroup;
495 mProgressSink = nullptr;
496 UpdatePrivateBrowsing();
497 return NS_OK;
498}
499
500NS_IMETHODIMPnsresult
501HttpBaseChannel::GetLoadFlags(nsLoadFlags* aLoadFlags) {
502 NS_ENSURE_ARG_POINTER(aLoadFlags)do { if ((__builtin_expect(!!(!(aLoadFlags)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aLoadFlags" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 502); return NS_ERROR_INVALID_POINTER; } } while (false)
;
503 *aLoadFlags = mLoadFlags;
504 return NS_OK;
505}
506
507NS_IMETHODIMPnsresult
508HttpBaseChannel::SetLoadFlags(nsLoadFlags aLoadFlags) {
509 mLoadFlags = aLoadFlags;
510 return NS_OK;
511}
512
513NS_IMETHODIMPnsresult
514HttpBaseChannel::GetTRRMode(nsIRequest::TRRMode* aTRRMode) {
515 if (!LoadIsOCSP()) {
516 return GetTRRModeImpl(aTRRMode);
517 }
518
519 nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID"@mozilla.org/network/dns-service;1");
520 nsIDNSService::ResolverMode trrMode = nsIDNSService::MODE_NATIVEONLY;
521 // If this is an OCSP channel, and the global TRR mode is TRR_ONLY (3)
522 // then we set the mode for this channel as TRR_DISABLED_MODE.
523 // We do this to prevent a TRR service channel's OCSP validation from
524 // blocking DNS resolution completely.
525 if (dns && NS_SUCCEEDED(dns->GetCurrentTrrMode(&trrMode))((bool)(__builtin_expect(!!(!NS_FAILED_impl(dns->GetCurrentTrrMode
(&trrMode))), 1)))
&&
526 trrMode == nsIDNSService::MODE_TRRONLY) {
527 *aTRRMode = nsIRequest::TRR_DISABLED_MODE;
528 return NS_OK;
529 }
530
531 return GetTRRModeImpl(aTRRMode);
532}
533
534NS_IMETHODIMPnsresult
535HttpBaseChannel::SetTRRMode(nsIRequest::TRRMode aTRRMode) {
536 return SetTRRModeImpl(aTRRMode);
537}
538
539NS_IMETHODIMPnsresult
540HttpBaseChannel::SetDocshellUserAgentOverride() {
541 RefPtr<dom::BrowsingContext> bc;
542 MOZ_ALWAYS_SUCCEEDS(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))), 1)))
), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 542); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
")"); do { *((volatile int*)__null) = 542; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
543 if (!bc) {
544 return NS_OK;
545 }
546
547 nsAutoString customUserAgent;
548 bc->GetCustomUserAgent(customUserAgent);
549 if (customUserAgent.IsEmpty() || customUserAgent.IsVoid()) {
550 return NS_OK;
551 }
552
553 NS_ConvertUTF16toUTF8 utf8CustomUserAgent(customUserAgent);
554 nsresult rv = SetRequestHeaderInternal(
555 "User-Agent"_ns, utf8CustomUserAgent, false,
556 nsHttpHeaderArray::eVarietyRequestEnforceDefault);
557 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
558 return rv;
559 }
560
561 return NS_OK;
562}
563
564//-----------------------------------------------------------------------------
565// HttpBaseChannel::nsIChannel
566//-----------------------------------------------------------------------------
567
568NS_IMETHODIMPnsresult
569HttpBaseChannel::GetOriginalURI(nsIURI** aOriginalURI) {
570 NS_ENSURE_ARG_POINTER(aOriginalURI)do { if ((__builtin_expect(!!(!(aOriginalURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOriginalURI" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 570); return NS_ERROR_INVALID_POINTER; } } while (false)
;
571 *aOriginalURI = do_AddRef(mOriginalURI).take();
572 return NS_OK;
573}
574
575NS_IMETHODIMPnsresult
576HttpBaseChannel::SetOriginalURI(nsIURI* aOriginalURI) {
577 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/HttpBaseChannel.cpp"
, 577); 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/HttpBaseChannel.cpp"
, 577, 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/HttpBaseChannel.cpp"
, 577); } } 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/HttpBaseChannel.cpp"
, 577); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 577; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
578
579 NS_ENSURE_ARG_POINTER(aOriginalURI)do { if ((__builtin_expect(!!(!(aOriginalURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOriginalURI" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 579); return NS_ERROR_INVALID_POINTER; } } while (false)
;
580 mOriginalURI = aOriginalURI;
581 return NS_OK;
582}
583
584NS_IMETHODIMPnsresult
585HttpBaseChannel::GetURI(nsIURI** aURI) {
586 NS_ENSURE_ARG_POINTER(aURI)do { if ((__builtin_expect(!!(!(aURI)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 586); return NS_ERROR_INVALID_POINTER; } } while (false)
;
587 *aURI = do_AddRef(mURI).take();
588 return NS_OK;
589}
590
591NS_IMETHODIMPnsresult
592HttpBaseChannel::GetOwner(nsISupports** aOwner) {
593 NS_ENSURE_ARG_POINTER(aOwner)do { if ((__builtin_expect(!!(!(aOwner)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOwner" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 593); return NS_ERROR_INVALID_POINTER; } } while (false)
;
594 *aOwner = do_AddRef(mOwner).take();
595 return NS_OK;
596}
597
598NS_IMETHODIMPnsresult
599HttpBaseChannel::SetOwner(nsISupports* aOwner) {
600 mOwner = aOwner;
601 return NS_OK;
602}
603
604NS_IMETHODIMPnsresult
605HttpBaseChannel::SetLoadInfo(nsILoadInfo* aLoadInfo) {
606 MOZ_RELEASE_ASSERT(aLoadInfo, "loadinfo can't be null")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aLoadInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aLoadInfo))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aLoadInfo" " (" "loadinfo can't be null"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 606); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aLoadInfo"
") (" "loadinfo can't be null" ")"); do { *((volatile int*)__null
) = 606; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false)
;
607 mLoadInfo = aLoadInfo;
608 return NS_OK;
609}
610
611NS_IMETHODIMPnsresult
612HttpBaseChannel::GetLoadInfo(nsILoadInfo** aLoadInfo) {
613 *aLoadInfo = do_AddRef(mLoadInfo).take();
614 return NS_OK;
615}
616
617NS_IMETHODIMPnsresult
618HttpBaseChannel::GetIsDocument(bool* aIsDocument) {
619 return NS_GetIsDocumentChannel(this, aIsDocument);
620}
621
622NS_IMETHODIMPnsresult
623HttpBaseChannel::GetNotificationCallbacks(nsIInterfaceRequestor** aCallbacks) {
624 *aCallbacks = do_AddRef(mCallbacks).take();
625 return NS_OK;
626}
627
628NS_IMETHODIMPnsresult
629HttpBaseChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks) {
630 MOZ_ASSERT(NS_IsMainThread(), "Should only 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 only be called on the main thread." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 630); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
") (" "Should only be called on the main thread." ")"); do {
*((volatile int*)__null) = 630; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
631
632 if (!CanSetCallbacks(aCallbacks)) {
633 return NS_ERROR_FAILURE;
634 }
635
636 mCallbacks = aCallbacks;
637 mProgressSink = nullptr;
638
639 UpdatePrivateBrowsing();
640 return NS_OK;
641}
642
643NS_IMETHODIMPnsresult
644HttpBaseChannel::GetContentType(nsACString& aContentType) {
645 if (!mResponseHead) {
646 aContentType.Truncate();
647 return NS_ERROR_NOT_AVAILABLE;
648 }
649
650 mResponseHead->ContentType(aContentType);
651 if (!aContentType.IsEmpty()) {
652 return NS_OK;
653 }
654
655 aContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE"application/x-unknown-content-type");
656 return NS_OK;
657}
658
659NS_IMETHODIMPnsresult
660HttpBaseChannel::SetContentType(const nsACString& aContentType) {
661 if (mListener || LoadWasOpened() || mDummyChannelForCachedResource) {
662 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
663
664 nsAutoCString contentTypeBuf, charsetBuf;
665 bool hadCharset;
666 net_ParseContentType(aContentType, contentTypeBuf, charsetBuf, &hadCharset);
667
668 mResponseHead->SetContentType(contentTypeBuf);
669
670 // take care not to stomp on an existing charset
671 if (hadCharset) mResponseHead->SetContentCharset(charsetBuf);
672
673 } else {
674 // We are being given a content-type hint.
675 bool dummy;
676 net_ParseContentType(aContentType, mContentTypeHint, mContentCharsetHint,
677 &dummy);
678 }
679
680 return NS_OK;
681}
682
683NS_IMETHODIMPnsresult
684HttpBaseChannel::GetContentCharset(nsACString& aContentCharset) {
685 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
686
687 mResponseHead->ContentCharset(aContentCharset);
688 return NS_OK;
689}
690
691NS_IMETHODIMPnsresult
692HttpBaseChannel::SetContentCharset(const nsACString& aContentCharset) {
693 if (mListener) {
694 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
695
696 mResponseHead->SetContentCharset(aContentCharset);
697 } else {
698 // Charset hint
699 mContentCharsetHint = aContentCharset;
700 }
701 return NS_OK;
702}
703
704NS_IMETHODIMPnsresult
705HttpBaseChannel::GetContentDisposition(uint32_t* aContentDisposition) {
706 // See bug 1658877. If mContentDispositionHint is already
707 // DISPOSITION_ATTACHMENT, it means this channel is created from a
708 // download attribute. In this case, we should prefer the value from the
709 // download attribute rather than the value in content disposition header.
710 // DISPOSITION_FORCE_INLINE is used to explicitly set inline, used by
711 // the pdf reader when loading a attachment pdf without having to
712 // download it.
713 if (mContentDispositionHint == nsIChannel::DISPOSITION_ATTACHMENT ||
714 mContentDispositionHint == nsIChannel::DISPOSITION_FORCE_INLINE) {
715 *aContentDisposition = mContentDispositionHint;
716 return NS_OK;
717 }
718
719 nsresult rv;
720 nsCString header;
721
722 rv = GetContentDispositionHeader(header);
723 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
724 if (mContentDispositionHint == UINT32_MAX(4294967295U)) return rv;
725
726 *aContentDisposition = mContentDispositionHint;
727 return NS_OK;
728 }
729
730 *aContentDisposition = NS_GetContentDispositionFromHeader(header, this);
731 return NS_OK;
732}
733
734NS_IMETHODIMPnsresult
735HttpBaseChannel::SetContentDisposition(uint32_t aContentDisposition) {
736 mContentDispositionHint = aContentDisposition;
737 return NS_OK;
738}
739
740NS_IMETHODIMPnsresult
741HttpBaseChannel::GetContentDispositionFilename(
742 nsAString& aContentDispositionFilename) {
743 aContentDispositionFilename.Truncate();
744 nsresult rv;
745 nsCString header;
746
747 rv = GetContentDispositionHeader(header);
748 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
749 rv = NS_GetFilenameFromDisposition(aContentDispositionFilename, header);
750 }
751
752 // If we failed to get the filename from header, we should use
753 // mContentDispositionFilename, since mContentDispositionFilename is set from
754 // the download attribute.
755 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
756 if (!mContentDispositionFilename) {
757 return rv;
758 }
759
760 aContentDispositionFilename = *mContentDispositionFilename;
761 return NS_OK;
762 }
763
764 return rv;
765}
766
767NS_IMETHODIMPnsresult
768HttpBaseChannel::SetContentDispositionFilename(
769 const nsAString& aContentDispositionFilename) {
770 mContentDispositionFilename =
771 MakeUnique<nsString>(aContentDispositionFilename);
772
773 // For safety reasons ensure the filename doesn't contain null characters and
774 // replace them with underscores. We may later pass the extension to system
775 // MIME APIs that expect null terminated strings.
776 mContentDispositionFilename->ReplaceChar(char16_t(0), '_');
777
778 return NS_OK;
779}
780
781NS_IMETHODIMPnsresult
782HttpBaseChannel::GetContentDispositionHeader(
783 nsACString& aContentDispositionHeader) {
784 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
785
786 nsresult rv = mResponseHead->GetHeader(nsHttp::Content_Disposition,
787 aContentDispositionHeader);
788 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || aContentDispositionHeader.IsEmpty()) {
789 return NS_ERROR_NOT_AVAILABLE;
790 }
791
792 return NS_OK;
793}
794
795NS_IMETHODIMPnsresult
796HttpBaseChannel::GetContentLength(int64_t* aContentLength) {
797 NS_ENSURE_ARG_POINTER(aContentLength)do { if ((__builtin_expect(!!(!(aContentLength)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aContentLength" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 797); return NS_ERROR_INVALID_POINTER; } } while (false)
;
798
799 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
800
801 if (LoadDeliveringAltData()) {
802 MOZ_ASSERT(!mAvailableCachedAltDataType.IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mAvailableCachedAltDataType.IsEmpty())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mAvailableCachedAltDataType.IsEmpty()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mAvailableCachedAltDataType.IsEmpty()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 802); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mAvailableCachedAltDataType.IsEmpty()"
")"); do { *((volatile int*)__null) = 802; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
803 *aContentLength = mAltDataLength;
804 return NS_OK;
805 }
806
807 *aContentLength = mResponseHead->ContentLength();
808 return NS_OK;
809}
810
811NS_IMETHODIMPnsresult
812HttpBaseChannel::SetContentLength(int64_t value) {
813 if (!mDummyChannelForCachedResource) {
814 MOZ_ASSERT_UNREACHABLE("HttpBaseChannel::SetContentLength")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: "
"HttpBaseChannel::SetContentLength" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 814); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "HttpBaseChannel::SetContentLength"
")"); do { *((volatile int*)__null) = 814; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
815 return NS_ERROR_NOT_IMPLEMENTED;
816 }
817 MOZ_ASSERT(mResponseHead)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mResponseHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mResponseHead))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("mResponseHead",
"/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 817); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mResponseHead"
")"); do { *((volatile int*)__null) = 817; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
818 mResponseHead->SetContentLength(value);
819 return NS_OK;
820}
821
822NS_IMETHODIMPnsresult
823HttpBaseChannel::Open(nsIInputStream** aStream) {
824 if (!gHttpHandler->Active()) {
825 LOG(("HttpBaseChannel::Open 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
, "HttpBaseChannel::Open after HTTP shutdown..."); } } while (
0)
;
826 return NS_ERROR_NOT_AVAILABLE;
827 }
828
829 nsCOMPtr<nsIStreamListener> listener;
830 nsresult rv =
831 nsContentSecurityManager::doContentSecurityCheck(this, listener);
832 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/HttpBaseChannel.cpp"
, 832); return rv; } } while (false)
;
833
834 NS_ENSURE_TRUE(!LoadWasOpened(), NS_ERROR_IN_PROGRESS)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/HttpBaseChannel.cpp"
, 834); return NS_ERROR_IN_PROGRESS; } } while (false)
;
835
836 if (!gHttpHandler->Active()) {
837 LOG(("HttpBaseChannel::Open 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
, "HttpBaseChannel::Open after HTTP shutdown..."); } } while (
0)
;
838 return NS_ERROR_NOT_AVAILABLE;
839 }
840
841 return NS_ImplementChannelOpen(this, aStream);
842}
843
844//-----------------------------------------------------------------------------
845// HttpBaseChannel::nsIUploadChannel
846//-----------------------------------------------------------------------------
847
848NS_IMETHODIMPnsresult
849HttpBaseChannel::GetUploadStream(nsIInputStream** stream) {
850 NS_ENSURE_ARG_POINTER(stream)do { if ((__builtin_expect(!!(!(stream)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "stream" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 850); return NS_ERROR_INVALID_POINTER; } } while (false)
;
851 *stream = do_AddRef(mUploadStream).take();
852 return NS_OK;
853}
854
855NS_IMETHODIMPnsresult
856HttpBaseChannel::SetUploadStream(nsIInputStream* stream,
857 const nsACString& contentTypeArg,
858 int64_t contentLength) {
859 // NOTE: for backwards compatibility and for compatibility with old style
860 // plugins, |stream| may include headers, specifically Content-Type and
861 // Content-Length headers. in this case, |contentType| and |contentLength|
862 // would be unspecified. this is traditionally the case of a POST request,
863 // and so we select POST as the request method if contentType and
864 // contentLength are unspecified.
865
866 if (stream) {
867 nsAutoCString method;
868 bool hasHeaders = false;
869
870 // This method and ExplicitSetUploadStream mean different things by "empty
871 // content type string". This method means "no header", but
872 // ExplicitSetUploadStream means "header with empty value". So we have to
873 // massage the contentType argument into the form ExplicitSetUploadStream
874 // expects.
875 nsCOMPtr<nsIMIMEInputStream> mimeStream;
876 nsCString contentType(contentTypeArg);
877 if (contentType.IsEmpty()) {
878 contentType.SetIsVoid(true);
879 method = "POST"_ns;
880
881 // MIME streams are a special case, and include headers which need to be
882 // copied to the channel.
883 mimeStream = do_QueryInterface(stream);
884 if (mimeStream) {
885 // Copy non-origin related headers to the channel.
886 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
887 new AddHeadersToChannelVisitor(this);
888 mimeStream->VisitHeaders(visitor);
889
890 return ExplicitSetUploadStream(stream, contentType, contentLength,
891 method, hasHeaders);
892 }
893
894 hasHeaders = true;
895 } else {
896 method = "PUT"_ns;
897
898 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface
(stream, getter_AddRefs(mimeStream)))), 0))))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(((bool)(__builtin_expect(!!(
NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream
)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream)))), 0)))"
" (" "nsIMIMEInputStream should not be set with an explicit content type"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream)))), 0)))"
") (" "nsIMIMEInputStream should not be set with an explicit content type"
")"); do { *((volatile int*)__null) = 900; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
899 NS_FAILED(CallQueryInterface(stream, getter_AddRefs(mimeStream))),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface
(stream, getter_AddRefs(mimeStream)))), 0))))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(((bool)(__builtin_expect(!!(
NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream
)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream)))), 0)))"
" (" "nsIMIMEInputStream should not be set with an explicit content type"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream)))), 0)))"
") (" "nsIMIMEInputStream should not be set with an explicit content type"
")"); do { *((volatile int*)__null) = 900; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
900 "nsIMIMEInputStream should not be set with an explicit content type")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface
(stream, getter_AddRefs(mimeStream)))), 0))))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(((bool)(__builtin_expect(!!(
NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream
)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream)))), 0)))"
" (" "nsIMIMEInputStream should not be set with an explicit content type"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface(stream, getter_AddRefs(mimeStream)))), 0)))"
") (" "nsIMIMEInputStream should not be set with an explicit content type"
")"); do { *((volatile int*)__null) = 900; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
901 }
902 return ExplicitSetUploadStream(stream, contentType, contentLength, method,
903 hasHeaders);
904 }
905
906 // if stream is null, ExplicitSetUploadStream returns error.
907 // So we need special case for GET method.
908 StoreUploadStreamHasHeaders(false);
909 SetRequestMethod("GET"_ns); // revert to GET request
910 mUploadStream = nullptr;
911 return NS_OK;
912}
913
914namespace {
915
916class MIMEHeaderCopyVisitor final : public nsIHttpHeaderVisitor {
917 public:
918 explicit MIMEHeaderCopyVisitor(nsIMIMEInputStream* aDest) : mDest(aDest) {}
919
920 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:
921 NS_IMETHODvirtual nsresult VisitHeader(const nsACString& aName,
922 const nsACString& aValue) override {
923 return mDest->AddHeader(PromiseFlatCStringTPromiseFlatString<char>(aName).get(),
924 PromiseFlatCStringTPromiseFlatString<char>(aValue).get());
925 }
926
927 private:
928 ~MIMEHeaderCopyVisitor() = default;
929
930 nsCOMPtr<nsIMIMEInputStream> mDest;
931};
932
933NS_IMPL_ISUPPORTS(MIMEHeaderCopyVisitor, nsIHttpHeaderVisitor)MozExternalRefCountType MIMEHeaderCopyVisitor::AddRef(void) {
static_assert(!std::is_destructible_v<MIMEHeaderCopyVisitor
>, "Reference-counted class " "MIMEHeaderCopyVisitor" " 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/HttpBaseChannel.cpp"
, 933); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
933; __attribute__((nomerge)) ::abort(); } while (false); } }
while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("MIMEHeaderCopyVisitor" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("MIMEHeaderCopyVisitor" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"MIMEHeaderCopyVisitor\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 933); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MIMEHeaderCopyVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 933; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("MIMEHeaderCopyVisitor" " not thread-safe");
nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), ("MIMEHeaderCopyVisitor"
), (uint32_t)(sizeof(*this))); return count; } MozExternalRefCountType
MIMEHeaderCopyVisitor::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/HttpBaseChannel.cpp"
, 933); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 933
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("MIMEHeaderCopyVisitor" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("MIMEHeaderCopyVisitor" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"MIMEHeaderCopyVisitor\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 933); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"MIMEHeaderCopyVisitor\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 933; __attribute__((nomerge)) ::abort(); } while (false);
} } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("MIMEHeaderCopyVisitor" " not thread-safe");
const char* const nametmp = "MIMEHeaderCopyVisitor"; nsrefcnt
count = --mRefCnt; NS_LogRelease((this), (count), (nametmp))
; if (count == 0) { mRefCnt = 1; delete (this); return 0; } return
count; } nsresult MIMEHeaderCopyVisitor::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/HttpBaseChannel.cpp"
, 933); 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<MIMEHeaderCopyVisitor, nsIHttpHeaderVisitor
>, int32_t( reinterpret_cast<char*>(static_cast<nsIHttpHeaderVisitor
*>((MIMEHeaderCopyVisitor*)0x1000)) - reinterpret_cast<
char*>((MIMEHeaderCopyVisitor*)0x1000))}, {&mozilla::detail
::kImplementedIID<MIMEHeaderCopyVisitor, nsISupports>, int32_t
(reinterpret_cast<char*>(static_cast<nsISupports*>
( static_cast<nsIHttpHeaderVisitor*>((MIMEHeaderCopyVisitor
*)0x1000))) - reinterpret_cast<char*>((MIMEHeaderCopyVisitor
*)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; }
934
935static void NormalizeCopyComplete(void* aClosure, nsresult aStatus) {
936#ifdef DEBUG1
937 // Called on the STS thread by NS_AsyncCopy
938 nsCOMPtr<nsIEventTarget> sts =
939 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/stream-transport-service;1");
940 bool result = false;
941 sts->IsOnCurrentThread(&result);
942 MOZ_ASSERT(result, "Should only be called on the STS thread.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(result)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(result))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("result" " (" "Should only be called on the STS thread."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "result" ") ("
"Should only be called on the STS thread." ")"); do { *((volatile
int*)__null) = 942; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
943#endif
944
945 RefPtr<GenericPromise::Private> ready =
946 already_AddRefed(static_cast<GenericPromise::Private*>(aClosure));
947 if (NS_SUCCEEDED(aStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(aStatus)), 1)))) {
948 ready->Resolve(true, __func__);
949 } else {
950 ready->Reject(aStatus, __func__);
951 }
952}
953
954// Normalize the upload stream for a HTTP channel, so that is one of the
955// expected and compatible types. Components like WebExtensions and DevTools
956// expect that upload streams in the parent process are cloneable, seekable, and
957// synchronous to read, which this function helps guarantee somewhat efficiently
958// and without loss of information.
959//
960// If the replacement stream outparameter is not initialized to `nullptr`, the
961// returned stream should be used instead of `aUploadStream` as the upload
962// stream for the HTTP channel, and the previous stream should not be touched
963// again.
964//
965// If aReadyPromise is non-nullptr after the function is called, it is a promise
966// which should be awaited before continuing to `AsyncOpen` the HTTP channel,
967// as the replacement stream will not be ready until it is resolved.
968static nsresult NormalizeUploadStream(nsIInputStream* aUploadStream,
969 nsIInputStream** aReplacementStream,
970 GenericPromise** aReadyPromise) {
971 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/HttpBaseChannel.cpp"
, 971); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 971; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
972
973 *aReplacementStream = nullptr;
974 *aReadyPromise = nullptr;
975
976 // Unwrap RemoteLazyInputStream and normalize the contents as we're in the
977 // parent process.
978 if (nsCOMPtr<mozIRemoteLazyInputStream> lazyStream =
979 do_QueryInterface(aUploadStream)) {
980 nsCOMPtr<nsIInputStream> internal;
981 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(lazyStream->TakeInternalStream
(getter_AddRefs(internal)))), 1)))
982 lazyStream->TakeInternalStream(getter_AddRefs(internal)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(lazyStream->TakeInternalStream
(getter_AddRefs(internal)))), 1)))
) {
983 nsCOMPtr<nsIInputStream> replacement;
984 nsresult rv = NormalizeUploadStream(internal, getter_AddRefs(replacement),
985 aReadyPromise);
986 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/HttpBaseChannel.cpp"
, 986); return rv; } } while (false)
;
987
988 if (replacement) {
989 replacement.forget(aReplacementStream);
990 } else {
991 internal.forget(aReplacementStream);
992 }
993 return NS_OK;
994 }
995 }
996
997 // Preserve MIME information on the stream when normalizing.
998 if (nsCOMPtr<nsIMIMEInputStream> mime = do_QueryInterface(aUploadStream)) {
999 nsCOMPtr<nsIInputStream> data;
1000 nsresult rv = mime->GetData(getter_AddRefs(data));
1001 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/HttpBaseChannel.cpp"
, 1001); return rv; } } while (false)
;
1002
1003 nsCOMPtr<nsIInputStream> replacement;
1004 rv =
1005 NormalizeUploadStream(data, getter_AddRefs(replacement), aReadyPromise);
1006 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/HttpBaseChannel.cpp"
, 1006); return rv; } } while (false)
;
1007
1008 if (replacement) {
1009 nsCOMPtr<nsIMIMEInputStream> replacementMime(
1010 do_CreateInstance("@mozilla.org/network/mime-input-stream;1", &rv));
1011 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/HttpBaseChannel.cpp"
, 1011); return rv; } } while (false)
;
1012
1013 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
1014 new MIMEHeaderCopyVisitor(replacementMime);
1015 rv = mime->VisitHeaders(visitor);
1016 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/HttpBaseChannel.cpp"
, 1016); return rv; } } while (false)
;
1017
1018 rv = replacementMime->SetData(replacement);
1019 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/HttpBaseChannel.cpp"
, 1019); return rv; } } while (false)
;
1020
1021 replacementMime.forget(aReplacementStream);
1022 }
1023 return NS_OK;
1024 }
1025
1026 // Preserve "real" buffered input streams which wrap data (i.e. are backed by
1027 // nsBufferedInputStream), but normalize the wrapped stream.
1028 if (nsCOMPtr<nsIBufferedInputStream> buffered =
1029 do_QueryInterface(aUploadStream)) {
1030 nsCOMPtr<nsIInputStream> data;
1031 if (NS_SUCCEEDED(buffered->GetData(getter_AddRefs(data)))((bool)(__builtin_expect(!!(!NS_FAILED_impl(buffered->GetData
(getter_AddRefs(data)))), 1)))
) {
1032 nsCOMPtr<nsIInputStream> replacement;
1033 nsresult rv = NormalizeUploadStream(data, getter_AddRefs(replacement),
1034 aReadyPromise);
1035 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/HttpBaseChannel.cpp"
, 1035); return rv; } } while (false)
;
1036 if (replacement) {
1037 // This buffer size should be kept in sync with HTMLFormSubmission.
1038 rv = NS_NewBufferedInputStream(aReplacementStream, replacement.forget(),
1039 8192);
1040 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/HttpBaseChannel.cpp"
, 1040); return rv; } } while (false)
;
1041 }
1042 return NS_OK;
1043 }
1044 }
1045
1046 // Preserve multiplex input streams, normalizing each individual inner stream
1047 // to avoid unnecessary copying.
1048 if (nsCOMPtr<nsIMultiplexInputStream> multiplex =
1049 do_QueryInterface(aUploadStream)) {
1050 uint32_t count = multiplex->GetCount();
1051 nsTArray<nsCOMPtr<nsIInputStream>> streams(count);
1052 nsTArray<RefPtr<GenericPromise>> promises(count);
1053 bool replace = false;
1054 for (uint32_t i = 0; i < count; ++i) {
1055 nsCOMPtr<nsIInputStream> inner;
1056 nsresult rv = multiplex->GetStream(i, getter_AddRefs(inner));
1057 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/HttpBaseChannel.cpp"
, 1057); return rv; } } while (false)
;
1058
1059 RefPtr<GenericPromise> promise;
1060 nsCOMPtr<nsIInputStream> replacement;
1061 rv = NormalizeUploadStream(inner, getter_AddRefs(replacement),
1062 getter_AddRefs(promise));
1063 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/HttpBaseChannel.cpp"
, 1063); return rv; } } while (false)
;
1064 if (promise) {
1065 promises.AppendElement(promise);
1066 }
1067 if (replacement) {
1068 streams.AppendElement(replacement);
1069 replace = true;
1070 } else {
1071 streams.AppendElement(inner);
1072 }
1073 }
1074
1075 // If any of the inner streams needed to be replaced, replace the entire
1076 // nsIMultiplexInputStream.
1077 if (replace) {
1078 nsresult rv;
1079 nsCOMPtr<nsIMultiplexInputStream> replacement =
1080 do_CreateInstance("@mozilla.org/io/multiplex-input-stream;1", &rv);
1081 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/HttpBaseChannel.cpp"
, 1081); return rv; } } while (false)
;
1082 for (auto& stream : streams) {
1083 rv = replacement->AppendStream(stream);
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/HttpBaseChannel.cpp"
, 1084); return rv; } } while (false)
;
1085 }
1086
1087 MOZ_ALWAYS_SUCCEEDS(CallQueryInterface(replacement, aReplacementStream))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(CallQueryInterface(replacement, aReplacementStream))), 1))))
, 1))) { } else { do { do { } while (false); MOZ_ReportCrash(
"" "NS_SUCCEEDED(CallQueryInterface(replacement, aReplacementStream))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1087); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(CallQueryInterface(replacement, aReplacementStream))"
")"); do { *((volatile int*)__null) = 1087; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
1088 }
1089
1090 // Wait for all inner promises to settle before resolving the final promise.
1091 if (!promises.IsEmpty()) {
1092 RefPtr<GenericPromise> ready =
1093 GenericPromise::AllSettled(GetCurrentSerialEventTarget(), promises)
1094 ->Then(GetCurrentSerialEventTarget(), __func__,
1095 [](GenericPromise::AllSettledPromiseType::
1096 ResolveOrRejectValue&& aResults)
1097 -> RefPtr<GenericPromise> {
1098 MOZ_ASSERT(aResults.IsResolve(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aResults.IsResolve())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aResults.IsResolve()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("aResults.IsResolve()"
" (" "AllSettled never rejects" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aResults.IsResolve()"
") (" "AllSettled never rejects" ")"); do { *((volatile int*
)__null) = 1099; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
1099 "AllSettled never rejects")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aResults.IsResolve())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aResults.IsResolve()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("aResults.IsResolve()"
" (" "AllSettled never rejects" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aResults.IsResolve()"
") (" "AllSettled never rejects" ")"); do { *((volatile int*
)__null) = 1099; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false)
;
1100 for (auto& result : aResults.ResolveValue()) {
1101 if (result.IsReject()) {
1102 return GenericPromise::CreateAndReject(
1103 result.RejectValue(), __func__);
1104 }
1105 }
1106 return GenericPromise::CreateAndResolve(true, __func__);
1107 });
1108 ready.forget(aReadyPromise);
1109 }
1110 return NS_OK;
1111 }
1112
1113 // If the stream is cloneable, seekable and non-async, we can allow it. Async
1114 // input streams can cause issues, as various consumers of input streams
1115 // expect the payload to be synchronous and `Available()` to be the length of
1116 // the stream, which is not true for asynchronous streams.
1117 nsCOMPtr<nsIAsyncInputStream> async = do_QueryInterface(aUploadStream);
1118 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(aUploadStream);
1119 if (NS_InputStreamIsCloneable(aUploadStream) && seekable && !async) {
1120 return NS_OK;
1121 }
1122
1123 // Asynchronously copy our non-normalized stream into a StorageStream so that
1124 // it is seekable, cloneable, and synchronous once the copy completes.
1125
1126 NS_WARNING("Upload Stream is being copied into StorageStream")NS_DebugBreak(NS_DEBUG_WARNING, "Upload Stream is being copied into StorageStream"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1126)
;
1127
1128 nsCOMPtr<nsIStorageStream> storageStream;
1129 nsresult rv =
1130 NS_NewStorageStream(4096, UINT32_MAX(4294967295U), getter_AddRefs(storageStream));
1131 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/HttpBaseChannel.cpp"
, 1131); return rv; } } while (false)
;
1132
1133 nsCOMPtr<nsIOutputStream> sink;
1134 rv = storageStream->GetOutputStream(0, getter_AddRefs(sink));
1135 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/HttpBaseChannel.cpp"
, 1135); return rv; } } while (false)
;
1136
1137 nsCOMPtr<nsIInputStream> replacementStream;
1138 rv = storageStream->NewInputStream(0, getter_AddRefs(replacementStream));
1139 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/HttpBaseChannel.cpp"
, 1139); return rv; } } while (false)
;
1140
1141 // Ensure the source stream is buffered before starting the copy so we can use
1142 // ReadSegments, as nsStorageStream doesn't implement WriteSegments.
1143 nsCOMPtr<nsIInputStream> source = aUploadStream;
1144 if (!NS_InputStreamIsBuffered(aUploadStream)) {
1145 nsCOMPtr<nsIInputStream> bufferedSource;
1146 rv = NS_NewBufferedInputStream(getter_AddRefs(bufferedSource),
1147 source.forget(), 4096);
1148 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/HttpBaseChannel.cpp"
, 1148); return rv; } } while (false)
;
1149 source = bufferedSource.forget();
1150 }
1151
1152 // Perform an AsyncCopy into the input stream on the STS.
1153 nsCOMPtr<nsIEventTarget> target =
1154 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID"@mozilla.org/network/stream-transport-service;1");
1155 RefPtr<GenericPromise::Private> ready = new GenericPromise::Private(__func__);
1156 rv = NS_AsyncCopy(source, sink, target, NS_ASYNCCOPY_VIA_READSEGMENTS, 4096,
1157 NormalizeCopyComplete, do_AddRef(ready).take());
1158 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/HttpBaseChannel.cpp"
, 1158)
) {
1159 ready.get()->Release();
1160 return rv;
1161 }
1162
1163 replacementStream.forget(aReplacementStream);
1164 ready.forget(aReadyPromise);
1165 return NS_OK;
1166}
1167
1168} // anonymous namespace
1169
1170NS_IMETHODIMPnsresult
1171HttpBaseChannel::CloneUploadStream(int64_t* aContentLength,
1172 nsIInputStream** aClonedStream) {
1173 NS_ENSURE_ARG_POINTER(aContentLength)do { if ((__builtin_expect(!!(!(aContentLength)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aContentLength" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1173); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1174 NS_ENSURE_ARG_POINTER(aClonedStream)do { if ((__builtin_expect(!!(!(aClonedStream)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aClonedStream" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1174); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1175 *aClonedStream = nullptr;
1176
1177 if (!XRE_IsParentProcess()) {
1178 NS_WARNING("CloneUploadStream is only supported in the parent process")NS_DebugBreak(NS_DEBUG_WARNING, "CloneUploadStream is only supported in the parent process"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1178)
;
1179 return NS_ERROR_NOT_AVAILABLE;
1180 }
1181
1182 if (!mUploadStream) {
1183 return NS_OK;
1184 }
1185
1186 nsCOMPtr<nsIInputStream> clonedStream;
1187 nsresult rv =
1188 NS_CloneInputStream(mUploadStream, getter_AddRefs(clonedStream));
1189 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/HttpBaseChannel.cpp"
, 1189); return rv; } } while (false)
;
1190
1191 clonedStream.forget(aClonedStream);
1192
1193 *aContentLength = mReqContentLength;
1194 return NS_OK;
1195}
1196
1197//-----------------------------------------------------------------------------
1198// HttpBaseChannel::nsIUploadChannel2
1199//-----------------------------------------------------------------------------
1200
1201NS_IMETHODIMPnsresult
1202HttpBaseChannel::ExplicitSetUploadStream(nsIInputStream* aStream,
1203 const nsACString& aContentType,
1204 int64_t aContentLength,
1205 const nsACString& aMethod,
1206 bool aStreamHasHeaders) {
1207 // Ensure stream is set and method is valid
1208 NS_ENSURE_TRUE(aStream, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(aStream)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aStream" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1208); return NS_ERROR_FAILURE; } } while (false)
;
1209
1210 {
1211 DebugOnly<nsCOMPtr<nsIMIMEInputStream>> mimeStream;
1212 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl
(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value
)))), 0))))>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(!aStreamHasHeaders || ((bool)(__builtin_expect
(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs
(mimeStream.value)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
" (" "nsIMIMEInputStream should not include headers" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1215); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
") (" "nsIMIMEInputStream should not include headers" ")"); do
{ *((volatile int*)__null) = 1215; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
1213 !aStreamHasHeaders || NS_FAILED(CallQueryInterface(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl
(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value
)))), 0))))>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(!aStreamHasHeaders || ((bool)(__builtin_expect
(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs
(mimeStream.value)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
" (" "nsIMIMEInputStream should not include headers" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1215); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
") (" "nsIMIMEInputStream should not include headers" ")"); do
{ *((volatile int*)__null) = 1215; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
1214 aStream, getter_AddRefs(mimeStream.value))),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl
(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value
)))), 0))))>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(!aStreamHasHeaders || ((bool)(__builtin_expect
(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs
(mimeStream.value)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
" (" "nsIMIMEInputStream should not include headers" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1215); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
") (" "nsIMIMEInputStream should not include headers" ")"); do
{ *((volatile int*)__null) = 1215; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
1215 "nsIMIMEInputStream should not include headers")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl
(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value
)))), 0))))>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(!aStreamHasHeaders || ((bool)(__builtin_expect
(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs
(mimeStream.value)))), 0)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
" (" "nsIMIMEInputStream should not include headers" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1215); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aStreamHasHeaders || ((bool)(__builtin_expect(!!(NS_FAILED_impl(CallQueryInterface( aStream, getter_AddRefs(mimeStream.value)))), 0)))"
") (" "nsIMIMEInputStream should not include headers" ")"); do
{ *((volatile int*)__null) = 1215; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
1216 }
1217
1218 nsresult rv = SetRequestMethod(aMethod);
1219 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/HttpBaseChannel.cpp"
, 1219); return rv; } } while (false)
;
1220
1221 if (!aStreamHasHeaders && !aContentType.IsVoid()) {
1222 if (aContentType.IsEmpty()) {
1223 SetEmptyRequestHeader("Content-Type"_ns);
1224 } else {
1225 SetRequestHeader("Content-Type"_ns, aContentType, false);
1226 }
1227 }
1228
1229 StoreUploadStreamHasHeaders(aStreamHasHeaders);
1230
1231 return InternalSetUploadStream(aStream, aContentLength, !aStreamHasHeaders);
1232}
1233
1234nsresult HttpBaseChannel::InternalSetUploadStream(
1235 nsIInputStream* aUploadStream, int64_t aContentLength,
1236 bool aSetContentLengthHeader) {
1237 // If we're not on the main thread, such as for TRR, the content length must
1238 // be provided, as we can't normalize our upload stream.
1239 if (!NS_IsMainThread()) {
1240 if (aContentLength < 0) {
1241 MOZ_ASSERT_UNREACHABLE(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: "
"Upload content length must be explicit off-main-thread" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1242); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload content length must be explicit off-main-thread"
")"); do { *((volatile int*)__null) = 1242; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1242 "Upload content length must be explicit off-main-thread")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: "
"Upload content length must be explicit off-main-thread" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1242); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload content length must be explicit off-main-thread"
")"); do { *((volatile int*)__null) = 1242; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1243 return NS_ERROR_INVALID_ARG;
1244 }
1245
1246 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(aUploadStream);
1247 if (!NS_InputStreamIsCloneable(aUploadStream) || !seekable) {
1248 MOZ_ASSERT_UNREACHABLE(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: "
"Upload stream must be cloneable & seekable off-main-thread"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1249); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload stream must be cloneable & seekable off-main-thread"
")"); do { *((volatile int*)__null) = 1249; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1249 "Upload stream must be cloneable & seekable off-main-thread")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: "
"Upload stream must be cloneable & seekable off-main-thread"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1249); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Upload stream must be cloneable & seekable off-main-thread"
")"); do { *((volatile int*)__null) = 1249; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1250 return NS_ERROR_INVALID_ARG;
1251 }
1252
1253 mUploadStream = aUploadStream;
1254 ExplicitSetUploadStreamLength(aContentLength, aSetContentLengthHeader);
1255 return NS_OK;
1256 }
1257
1258 // Normalize the upload stream we're provided to ensure that it is cloneable,
1259 // seekable, and synchronous when in the parent process.
1260 //
1261 // This might be an async operation, in which case ready will be returned and
1262 // resolved when the operation is complete.
1263 nsCOMPtr<nsIInputStream> replacement;
1264 RefPtr<GenericPromise> ready;
1265 if (XRE_IsParentProcess()) {
1266 nsresult rv = NormalizeUploadStream(
1267 aUploadStream, getter_AddRefs(replacement), getter_AddRefs(ready));
1268 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/HttpBaseChannel.cpp"
, 1268); return rv; } } while (false)
;
1269 }
1270
1271 mUploadStream = replacement ? replacement.get() : aUploadStream;
1272
1273 // Once the upload stream is ready, fetch its length before proceeding with
1274 // AsyncOpen.
1275 auto onReady = [self = RefPtr{this}, aContentLength, aSetContentLengthHeader,
1276 stream = mUploadStream]() {
1277 auto setLengthAndResume = [self, aSetContentLengthHeader](int64_t aLength) {
1278 self->StorePendingUploadStreamNormalization(false);
1279 self->ExplicitSetUploadStreamLength(aLength >= 0 ? aLength : 0,
1280 aSetContentLengthHeader);
1281 self->MaybeResumeAsyncOpen();
1282 };
1283
1284 if (aContentLength >= 0) {
1285 setLengthAndResume(aContentLength);
1286 return;
1287 }
1288
1289 int64_t length;
1290 if (InputStreamLengthHelper::GetSyncLength(stream, &length)) {
1291 setLengthAndResume(length);
1292 return;
1293 }
1294
1295 InputStreamLengthHelper::GetAsyncLength(stream, setLengthAndResume);
1296 };
1297 StorePendingUploadStreamNormalization(true);
1298
1299 // Resolve onReady synchronously unless a promise is returned.
1300 if (ready) {
1301 ready->Then(GetCurrentSerialEventTarget(), __func__,
1302 [onReady = std::move(onReady)](
1303 GenericPromise::ResolveOrRejectValue&&) { onReady(); });
1304 } else {
1305 onReady();
1306 }
1307 return NS_OK;
1308}
1309
1310void HttpBaseChannel::ExplicitSetUploadStreamLength(
1311 uint64_t aContentLength, bool aSetContentLengthHeader) {
1312 // We already have the content length. We don't need to determinate it.
1313 mReqContentLength = aContentLength;
1314
1315 if (!aSetContentLengthHeader) {
1316 return;
1317 }
1318
1319 nsAutoCString header;
1320 header.AssignLiteral("Content-Length");
1321
1322 // Maybe the content-length header has been already set.
1323 nsAutoCString value;
1324 nsresult rv = GetRequestHeader(header, value);
1325 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !value.IsEmpty()) {
1326 return;
1327 }
1328
1329 nsAutoCString contentLengthStr;
1330 contentLengthStr.AppendInt(aContentLength);
1331 SetRequestHeader(header, contentLengthStr, false);
1332}
1333
1334NS_IMETHODIMPnsresult
1335HttpBaseChannel::GetUploadStreamHasHeaders(bool* hasHeaders) {
1336 NS_ENSURE_ARG(hasHeaders)do { if ((__builtin_expect(!!(!(hasHeaders)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "hasHeaders" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1336); return NS_ERROR_INVALID_ARG; } } while (false)
;
1337
1338 *hasHeaders = LoadUploadStreamHasHeaders();
1339 return NS_OK;
1340}
1341
1342bool HttpBaseChannel::MaybeWaitForUploadStreamNormalization(
1343 nsIStreamListener* aListener, nsISupports* aContext) {
1344 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/HttpBaseChannel.cpp"
, 1344); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1344; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1345 MOZ_ASSERT(!LoadAsyncOpenWaitingForStreamNormalization(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadAsyncOpenWaitingForStreamNormalization())>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!LoadAsyncOpenWaitingForStreamNormalization()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!LoadAsyncOpenWaitingForStreamNormalization()"
" (" "AsyncOpen() called twice?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1346); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadAsyncOpenWaitingForStreamNormalization()"
") (" "AsyncOpen() called twice?" ")"); do { *((volatile int
*)__null) = 1346; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1346 "AsyncOpen() called twice?")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadAsyncOpenWaitingForStreamNormalization())>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!LoadAsyncOpenWaitingForStreamNormalization()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!LoadAsyncOpenWaitingForStreamNormalization()"
" (" "AsyncOpen() called twice?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1346); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadAsyncOpenWaitingForStreamNormalization()"
") (" "AsyncOpen() called twice?" ")"); do { *((volatile int
*)__null) = 1346; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1347
1348 if (!LoadPendingUploadStreamNormalization()) {
1349 return false;
1350 }
1351
1352 mListener = aListener;
1353 StoreAsyncOpenWaitingForStreamNormalization(true);
1354 return true;
1355}
1356
1357void HttpBaseChannel::MaybeResumeAsyncOpen() {
1358 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/HttpBaseChannel.cpp"
, 1358); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 1358; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1359 MOZ_ASSERT(!LoadPendingUploadStreamNormalization())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!LoadPendingUploadStreamNormalization())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!LoadPendingUploadStreamNormalization()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!LoadPendingUploadStreamNormalization()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1359); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!LoadPendingUploadStreamNormalization()"
")"); do { *((volatile int*)__null) = 1359; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1360
1361 if (!LoadAsyncOpenWaitingForStreamNormalization()) {
1362 return;
1363 }
1364
1365 nsCOMPtr<nsIStreamListener> listener;
1366 listener.swap(mListener);
1367
1368 StoreAsyncOpenWaitingForStreamNormalization(false);
1369
1370 nsresult rv = AsyncOpen(listener);
1371 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/HttpBaseChannel.cpp"
, 1371)
) {
1372 DoAsyncAbort(rv);
1373 }
1374}
1375
1376//-----------------------------------------------------------------------------
1377// HttpBaseChannel::nsIEncodedChannel
1378//-----------------------------------------------------------------------------
1379
1380NS_IMETHODIMPnsresult
1381HttpBaseChannel::GetApplyConversion(bool* value) {
1382 *value = LoadApplyConversion();
1383 return NS_OK;
1384}
1385
1386NS_IMETHODIMPnsresult
1387HttpBaseChannel::SetApplyConversion(bool value) {
1388 LOG(("HttpBaseChannel::SetApplyConversion [this=%p value=%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
, "HttpBaseChannel::SetApplyConversion [this=%p value=%d]\n",
this, value); } } while (0)
1389 value))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetApplyConversion [this=%p value=%d]\n",
this, value); } } while (0)
;
1390 StoreApplyConversion(value);
1391 return NS_OK;
1392}
1393
1394nsresult HttpBaseChannel::DoApplyContentConversions(
1395 nsIStreamListener* aNextListener, nsIStreamListener** aNewNextListener) {
1396 return DoApplyContentConversions(aNextListener, aNewNextListener, nullptr);
1397}
1398
1399// create a listener chain that looks like this
1400// http-channel -> decompressor (n times) -> InterceptFailedOnSTop ->
1401// channel-creator-listener
1402//
1403// we need to do this because not every decompressor has fully streamed output
1404// so may need a call to OnStopRequest to identify its completion state.. and if
1405// it creates an error there the channel status code needs to be updated before
1406// calling the terminal listener. Having the decompress do it via cancel() means
1407// channels cannot effectively be used in two contexts (specifically this one
1408// and a peek context for sniffing)
1409//
1410class InterceptFailedOnStop : public nsIThreadRetargetableStreamListener {
1411 virtual ~InterceptFailedOnStop() = default;
1412 nsCOMPtr<nsIStreamListener> mNext;
1413 HttpBaseChannel* mChannel;
1414
1415 public:
1416 InterceptFailedOnStop(nsIStreamListener* arg, HttpBaseChannel* chan)
1417 : mNext(arg), mChannel(chan) {}
1418 NS_DECL_THREADSAFE_ISUPPORTSpublic: virtual nsresult QueryInterface(const nsIID& aIID
, void** aInstancePtr) override; virtual MozExternalRefCountType
AddRef(void) override; virtual MozExternalRefCountType Release
(void) override; using HasThreadSafeRefCnt = std::true_type; protected
: ::mozilla::ThreadSafeAutoRefCnt mRefCnt; nsAutoOwningThread
_mOwningThread; public:
1419 NS_DECL_NSITHREADRETARGETABLESTREAMLISTENERvirtual nsresult CheckListenerChain(void) override; virtual nsresult
OnDataFinished(nsresult aStatusCode) override;
1420
1421 NS_IMETHODvirtual nsresult OnStartRequest(nsIRequest* aRequest) override {
1422 return mNext->OnStartRequest(aRequest);
1423 }
1424
1425 NS_IMETHODvirtual nsresult OnStopRequest(nsIRequest* aRequest,
1426 nsresult aStatusCode) override {
1427 if (NS_FAILED(aStatusCode)((bool)(__builtin_expect(!!(NS_FAILED_impl(aStatusCode)), 0))
)
&& NS_SUCCEEDED(mChannel->mStatus)((bool)(__builtin_expect(!!(!NS_FAILED_impl(mChannel->mStatus
)), 1)))
) {
1428 LOG(("HttpBaseChannel::InterceptFailedOnStop %p seting status %" 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
, "HttpBaseChannel::InterceptFailedOnStop %p seting status %"
"x", mChannel, static_cast<uint32_t>(aStatusCode)); } }
while (0)
1429 mChannel, static_cast<uint32_t>(aStatusCode)))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::InterceptFailedOnStop %p seting status %"
"x", mChannel, static_cast<uint32_t>(aStatusCode)); } }
while (0)
;
1430 mChannel->mStatus = aStatusCode;
1431 }
1432 return mNext->OnStopRequest(aRequest, aStatusCode);
1433 }
1434
1435 NS_IMETHODvirtual nsresult OnDataAvailable(nsIRequest* aRequest, nsIInputStream* aInputStream,
1436 uint64_t aOffset, uint32_t aCount) override {
1437 return mNext->OnDataAvailable(aRequest, aInputStream, aOffset, aCount);
1438 }
1439};
1440
1441NS_IMPL_ADDREF(InterceptFailedOnStop)MozExternalRefCountType InterceptFailedOnStop::AddRef(void) {
static_assert(!std::is_destructible_v<InterceptFailedOnStop
>, "Reference-counted class " "InterceptFailedOnStop" " 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/HttpBaseChannel.cpp"
, 1441); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1441; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("InterceptFailedOnStop" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("InterceptFailedOnStop" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"InterceptFailedOnStop\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1441); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"InterceptFailedOnStop\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1441; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("InterceptFailedOnStop" " not thread-safe");
nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), ("InterceptFailedOnStop"
), (uint32_t)(sizeof(*this))); return count; }
1442NS_IMPL_RELEASE(InterceptFailedOnStop)MozExternalRefCountType InterceptFailedOnStop::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/HttpBaseChannel.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1442
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("InterceptFailedOnStop" != nullptr)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!("InterceptFailedOnStop" != nullptr))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("\"InterceptFailedOnStop\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"InterceptFailedOnStop\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1442; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("InterceptFailedOnStop" " not thread-safe");
const char* const nametmp = "InterceptFailedOnStop"; nsrefcnt
count = --mRefCnt; NS_LogRelease((this), (count), (nametmp))
; if (count == 0) { mRefCnt = 1; delete (this); return 0; } return
count; }
1443
1444NS_INTERFACE_MAP_BEGIN(InterceptFailedOnStop)nsresult InterceptFailedOnStop::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/HttpBaseChannel.cpp"
, 1444); MOZ_PretendNoReturn(); } } while (0); nsISupports* foundInterface
;
1445 NS_INTERFACE_MAP_ENTRY(nsIStreamListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIStreamListener>)) foundInterface
= static_cast<nsIStreamListener*>(this); else
1446 NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIRequestObserver>)) foundInterface
= static_cast<nsIRequestObserver*>(this); else
1447 NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsIThreadRetargetableStreamListener>
)) foundInterface = static_cast<nsIThreadRetargetableStreamListener
*>(this); else
1448 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequestObserver)if (aIID.Equals(mozilla::detail::kImplementedIID<std::remove_reference_t
<decltype(*this)>, nsISupports>)) foundInterface = static_cast
<nsISupports*>(static_cast<nsIRequestObserver*>(this
)); else
1449NS_INTERFACE_MAP_ENDfoundInterface = 0; nsresult status; if (!foundInterface) { do
{ static_assert( mozilla::detail::AssertionConditionType<
decltype(!aIID.Equals((nsISupports::COMTypeInfo<nsISupports
, void>::kIID)))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aIID.Equals((nsISupports::COMTypeInfo
<nsISupports, void>::kIID))))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1449); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!aIID.Equals((nsISupports::COMTypeInfo<nsISupports, void>::kIID))"
")"); do { *((volatile int*)__null) = 1449; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); status = NS_NOINTERFACE
; } else { (foundInterface)->AddRef(); status = NS_OK; } *
aInstancePtr = foundInterface; return status; }
1450
1451NS_IMETHODIMPnsresult
1452InterceptFailedOnStop::CheckListenerChain() {
1453 nsCOMPtr<nsIThreadRetargetableStreamListener> listener =
1454 do_QueryInterface(mNext);
1455 if (!listener) {
1456 return NS_ERROR_NO_INTERFACE;
1457 }
1458
1459 return listener->CheckListenerChain();
1460}
1461
1462NS_IMETHODIMPnsresult
1463InterceptFailedOnStop::OnDataFinished(nsresult aStatus) {
1464 nsCOMPtr<nsIThreadRetargetableStreamListener> listener =
1465 do_QueryInterface(mNext);
1466 if (listener) {
1467 return listener->OnDataFinished(aStatus);
1468 }
1469
1470 return NS_OK;
1471}
1472
1473NS_IMETHODIMPnsresult
1474HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener,
1475 nsIStreamListener** aNewNextListener,
1476 nsISupports* aCtxt) {
1477 *aNewNextListener = nullptr;
1478 if (!mResponseHead || !aNextListener) {
1479 return NS_OK;
1480 }
1481
1482 LOG(("HttpBaseChannel::DoApplyContentConversions [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
, "HttpBaseChannel::DoApplyContentConversions [this=%p]\n", this
); } } while (0)
;
1483
1484 if (!LoadApplyConversion()) {
1485 LOG(("not applying conversion per ApplyConversion\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 applying conversion per ApplyConversion\n"); } } while
(0)
;
1486 return NS_OK;
1487 }
1488
1489 if (LoadHasAppliedConversion()) {
1490 LOG(("not applying conversion because HasAppliedConversion is 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
, "not applying conversion because HasAppliedConversion is true\n"
); } } while (0)
;
1491 return NS_OK;
1492 }
1493
1494 if (LoadDeliveringAltData()) {
1495 MOZ_ASSERT(!mAvailableCachedAltDataType.IsEmpty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mAvailableCachedAltDataType.IsEmpty())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(!mAvailableCachedAltDataType.IsEmpty()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!mAvailableCachedAltDataType.IsEmpty()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1495); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mAvailableCachedAltDataType.IsEmpty()"
")"); do { *((volatile int*)__null) = 1495; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1496 LOG(("not applying conversion because delivering alt-data\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 applying conversion because delivering alt-data\n"); }
} while (0)
;
1497 return NS_OK;
1498 }
1499
1500 nsAutoCString contentEncoding;
1501 nsresult rv =
1502 mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
1503 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || contentEncoding.IsEmpty()) return NS_OK;
1504
1505 nsCOMPtr<nsIStreamListener> nextListener =
1506 new InterceptFailedOnStop(aNextListener, this);
1507
1508 // The encodings are listed in the order they were applied
1509 // (see rfc 2616 section 14.11), so they need to removed in reverse
1510 // order. This is accomplished because the converter chain ends up
1511 // being a stack with the last converter created being the first one
1512 // to accept the raw network data.
1513
1514 char* cePtr = contentEncoding.BeginWriting();
1515 uint32_t count = 0;
1516 while (char* val = nsCRT::strtok(cePtr, HTTP_LWS" \t" ",", &cePtr)) {
1517 if (++count > 16) {
1518 // That's ridiculous. We only understand 2 different ones :)
1519 // but for compatibility with old code, we will just carry on without
1520 // removing the encodings
1521 LOG(("Too many Content-Encodings. Ignoring remainder.\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
, "Too many Content-Encodings. Ignoring remainder.\n"); } } while
(0)
;
1522 break;
1523 }
1524
1525 if (gHttpHandler->IsAcceptableEncoding(val,
1526 isSecureOrTrustworthyURL(mURI))) {
1527 RefPtr<nsHTTPCompressConv> converter = new nsHTTPCompressConv();
1528 nsAutoCString from(val);
1529 ToLowerCase(from);
1530 rv = converter->AsyncConvertData(from.get(), "uncompressed", nextListener,
1531 aCtxt);
1532 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1533 LOG(("Unexpected failure of AsyncConvertData %s\n", val))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; 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 failure of AsyncConvertData %s\n", val); } } while
(0)
;
1534 return rv;
1535 }
1536
1537 LOG(("converter removed '%s' content-encoding\n", val))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "converter removed '%s' content-encoding\n", val); } } while
(0)
;
1538 if (Telemetry::CanRecordPrereleaseData()) {
1539 int mode = 0;
1540 if (from.EqualsLiteral("gzip") || from.EqualsLiteral("x-gzip")) {
1541 mode = 1;
1542 } else if (from.EqualsLiteral("deflate") ||
1543 from.EqualsLiteral("x-deflate")) {
1544 mode = 2;
1545 } else if (from.EqualsLiteral("br")) {
1546 mode = 3;
1547 } else if (from.EqualsLiteral("zstd")) {
1548 mode = 4;
1549 }
1550 Telemetry::Accumulate(Telemetry::HTTP_CONTENT_ENCODING, mode);
1551 }
1552 nextListener = converter;
1553 } else {
1554 if (val) LOG(("Unknown content encoding '%s', ignoring\n", val))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "Unknown content encoding '%s', ignoring\n", val); } } while
(0)
;
1555 }
1556 }
1557 *aNewNextListener = do_AddRef(nextListener).take();
1558 return NS_OK;
1559}
1560
1561NS_IMETHODIMPnsresult
1562HttpBaseChannel::GetContentEncodings(nsIUTF8StringEnumerator** aEncodings) {
1563 if (!mResponseHead) {
1564 *aEncodings = nullptr;
1565 return NS_OK;
1566 }
1567
1568 nsAutoCString encoding;
1569 Unused << mResponseHead->GetHeader(nsHttp::Content_Encoding, encoding);
1570 if (encoding.IsEmpty()) {
1571 *aEncodings = nullptr;
1572 return NS_OK;
1573 }
1574 RefPtr<nsContentEncodings> enumerator =
1575 new nsContentEncodings(this, encoding.get());
1576 enumerator.forget(aEncodings);
1577 return NS_OK;
1578}
1579
1580//-----------------------------------------------------------------------------
1581// HttpBaseChannel::nsContentEncodings <public>
1582//-----------------------------------------------------------------------------
1583
1584HttpBaseChannel::nsContentEncodings::nsContentEncodings(
1585 nsIHttpChannel* aChannel, const char* aEncodingHeader)
1586 : mEncodingHeader(aEncodingHeader), mChannel(aChannel), mReady(false) {
1587 mCurEnd = aEncodingHeader + strlen(aEncodingHeader);
1588 mCurStart = mCurEnd;
1589}
1590
1591//-----------------------------------------------------------------------------
1592// HttpBaseChannel::nsContentEncodings::nsISimpleEnumerator
1593//-----------------------------------------------------------------------------
1594
1595NS_IMETHODIMPnsresult
1596HttpBaseChannel::nsContentEncodings::HasMore(bool* aMoreEncodings) {
1597 if (mReady) {
1598 *aMoreEncodings = true;
1599 return NS_OK;
1600 }
1601
1602 nsresult rv = PrepareForNext();
1603 *aMoreEncodings = NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)));
1604 return NS_OK;
1605}
1606
1607NS_IMETHODIMPnsresult
1608HttpBaseChannel::nsContentEncodings::GetNext(nsACString& aNextEncoding) {
1609 aNextEncoding.Truncate();
1610 if (!mReady) {
1611 nsresult rv = PrepareForNext();
1612 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
1613 return NS_ERROR_FAILURE;
1614 }
1615 }
1616
1617 const nsACString& encoding = Substring(mCurStart, mCurEnd);
1618
1619 nsACString::const_iterator start, end;
1620 encoding.BeginReading(start);
1621 encoding.EndReading(end);
1622
1623 bool haveType = false;
1624 if (CaseInsensitiveFindInReadable("gzip"_ns, start, end)) {
1625 aNextEncoding.AssignLiteral(APPLICATION_GZIP"application/x-gzip");
1626 haveType = true;
1627 }
1628
1629 if (!haveType) {
1630 encoding.BeginReading(start);
1631 if (CaseInsensitiveFindInReadable("compress"_ns, start, end)) {
1632 aNextEncoding.AssignLiteral(APPLICATION_COMPRESS"application/x-compress");
1633 haveType = true;
1634 }
1635 }
1636
1637 if (!haveType) {
1638 encoding.BeginReading(start);
1639 if (CaseInsensitiveFindInReadable("deflate"_ns, start, end)) {
1640 aNextEncoding.AssignLiteral(APPLICATION_ZIP"application/zip");
1641 haveType = true;
1642 }
1643 }
1644
1645 if (!haveType) {
1646 encoding.BeginReading(start);
1647 if (CaseInsensitiveFindInReadable("br"_ns, start, end)) {
1648 aNextEncoding.AssignLiteral(APPLICATION_BROTLI"application/brotli");
1649 haveType = true;
1650 }
1651 }
1652
1653 if (!haveType) {
1654 encoding.BeginReading(start);
1655 if (CaseInsensitiveFindInReadable("zstd"_ns, start, end)) {
1656 aNextEncoding.AssignLiteral(APPLICATION_ZSTD"application/zstd");
1657 haveType = true;
1658 }
1659 }
1660
1661 // Prepare to fetch the next encoding
1662 mCurEnd = mCurStart;
1663 mReady = false;
1664
1665 if (haveType) return NS_OK;
1666
1667 NS_WARNING("Unknown encoding type")NS_DebugBreak(NS_DEBUG_WARNING, "Unknown encoding type", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1667)
;
1668 return NS_ERROR_FAILURE;
1669}
1670
1671//-----------------------------------------------------------------------------
1672// HttpBaseChannel::nsContentEncodings::nsISupports
1673//-----------------------------------------------------------------------------
1674
1675NS_IMPL_ISUPPORTS(HttpBaseChannel::nsContentEncodings, nsIUTF8StringEnumerator,MozExternalRefCountType HttpBaseChannel::nsContentEncodings::
AddRef(void) { static_assert(!std::is_destructible_v<HttpBaseChannel
::nsContentEncodings>, "Reference-counted class " "HttpBaseChannel::nsContentEncodings"
" 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/HttpBaseChannel.cpp"
, 1676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1676; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("HttpBaseChannel::nsContentEncodings" != nullptr
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("HttpBaseChannel::nsContentEncodings" != nullptr))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("\"HttpBaseChannel::nsContentEncodings\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1676; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("HttpBaseChannel::nsContentEncodings" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"HttpBaseChannel::nsContentEncodings"), (uint32_t)(sizeof(*this
))); return count; } MozExternalRefCountType HttpBaseChannel::
nsContentEncodings::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/HttpBaseChannel.cpp"
, 1676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1676
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("HttpBaseChannel::nsContentEncodings" != nullptr
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("HttpBaseChannel::nsContentEncodings" != nullptr))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("\"HttpBaseChannel::nsContentEncodings\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1676; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("HttpBaseChannel::nsContentEncodings" " not thread-safe"
); const char* const nametmp = "HttpBaseChannel::nsContentEncodings"
; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; } nsresult HttpBaseChannel::nsContentEncodings
::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/HttpBaseChannel.cpp"
, 1676); 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<HttpBaseChannel::nsContentEncodings, nsIUTF8StringEnumerator
>, int32_t( reinterpret_cast<char*>(static_cast<nsIUTF8StringEnumerator
*>((HttpBaseChannel::nsContentEncodings*)0x1000)) - reinterpret_cast
<char*>((HttpBaseChannel::nsContentEncodings*)0x1000))}
, {&mozilla::detail::kImplementedIID<HttpBaseChannel::
nsContentEncodings, nsIStringEnumerator>, int32_t( reinterpret_cast
<char*>(static_cast<nsIStringEnumerator*>((HttpBaseChannel
::nsContentEncodings*)0x1000)) - reinterpret_cast<char*>
((HttpBaseChannel::nsContentEncodings*)0x1000))}, {&mozilla
::detail::kImplementedIID<HttpBaseChannel::nsContentEncodings
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIUTF8StringEnumerator*
>((HttpBaseChannel::nsContentEncodings*)0x1000))) - reinterpret_cast
<char*>((HttpBaseChannel::nsContentEncodings*)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; }
1676 nsIStringEnumerator)MozExternalRefCountType HttpBaseChannel::nsContentEncodings::
AddRef(void) { static_assert(!std::is_destructible_v<HttpBaseChannel
::nsContentEncodings>, "Reference-counted class " "HttpBaseChannel::nsContentEncodings"
" 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/HttpBaseChannel.cpp"
, 1676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) >= 0"
") (" "illegal refcnt" ")"); do { *((volatile int*)__null) =
1676; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("HttpBaseChannel::nsContentEncodings" != nullptr
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("HttpBaseChannel::nsContentEncodings" != nullptr))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("\"HttpBaseChannel::nsContentEncodings\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1676; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("HttpBaseChannel::nsContentEncodings" " not thread-safe"
); nsrefcnt count = ++mRefCnt; NS_LogAddRef((this), (count), (
"HttpBaseChannel::nsContentEncodings"), (uint32_t)(sizeof(*this
))); return count; } MozExternalRefCountType HttpBaseChannel::
nsContentEncodings::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/HttpBaseChannel.cpp"
, 1676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "int32_t(mRefCnt) > 0"
") (" "dup release" ")"); do { *((volatile int*)__null) = 1676
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false); do { static_assert( mozilla::detail::AssertionConditionType
<decltype("HttpBaseChannel::nsContentEncodings" != nullptr
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!("HttpBaseChannel::nsContentEncodings" != nullptr))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("\"HttpBaseChannel::nsContentEncodings\" != nullptr"
" (" "Must specify a name" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1676); AnnotateMozCrashReason("MOZ_ASSERT" "(" "\"HttpBaseChannel::nsContentEncodings\" != nullptr"
") (" "Must specify a name" ")"); do { *((volatile int*)__null
) = 1676; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false); if (!mRefCnt.isThreadSafe) _mOwningThread
.AssertOwnership("HttpBaseChannel::nsContentEncodings" " not thread-safe"
); const char* const nametmp = "HttpBaseChannel::nsContentEncodings"
; nsrefcnt count = --mRefCnt; NS_LogRelease((this), (count), (
nametmp)); if (count == 0) { mRefCnt = 1; delete (this); return
0; } return count; } nsresult HttpBaseChannel::nsContentEncodings
::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/HttpBaseChannel.cpp"
, 1676); 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<HttpBaseChannel::nsContentEncodings, nsIUTF8StringEnumerator
>, int32_t( reinterpret_cast<char*>(static_cast<nsIUTF8StringEnumerator
*>((HttpBaseChannel::nsContentEncodings*)0x1000)) - reinterpret_cast
<char*>((HttpBaseChannel::nsContentEncodings*)0x1000))}
, {&mozilla::detail::kImplementedIID<HttpBaseChannel::
nsContentEncodings, nsIStringEnumerator>, int32_t( reinterpret_cast
<char*>(static_cast<nsIStringEnumerator*>((HttpBaseChannel
::nsContentEncodings*)0x1000)) - reinterpret_cast<char*>
((HttpBaseChannel::nsContentEncodings*)0x1000))}, {&mozilla
::detail::kImplementedIID<HttpBaseChannel::nsContentEncodings
, nsISupports>, int32_t(reinterpret_cast<char*>(static_cast
<nsISupports*>( static_cast<nsIUTF8StringEnumerator*
>((HttpBaseChannel::nsContentEncodings*)0x1000))) - reinterpret_cast
<char*>((HttpBaseChannel::nsContentEncodings*)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; }
1677
1678//-----------------------------------------------------------------------------
1679// HttpBaseChannel::nsContentEncodings <private>
1680//-----------------------------------------------------------------------------
1681
1682nsresult HttpBaseChannel::nsContentEncodings::PrepareForNext(void) {
1683 MOZ_ASSERT(mCurStart == mCurEnd, "Indeterminate state")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCurStart == mCurEnd)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mCurStart == mCurEnd))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("mCurStart == mCurEnd"
" (" "Indeterminate state" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1683); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurStart == mCurEnd"
") (" "Indeterminate state" ")"); do { *((volatile int*)__null
) = 1683; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
1684
1685 // At this point both mCurStart and mCurEnd point to somewhere
1686 // past the end of the next thing we want to return
1687
1688 while (mCurEnd != mEncodingHeader) {
1689 --mCurEnd;
1690 if (*mCurEnd != ',' && !nsCRT::IsAsciiSpace(*mCurEnd)) break;
1691 }
1692 if (mCurEnd == mEncodingHeader) {
1693 return NS_ERROR_NOT_AVAILABLE; // no more encodings
1694 }
1695 ++mCurEnd;
1696
1697 // At this point mCurEnd points to the first char _after_ the
1698 // header we want. Furthermore, mCurEnd - 1 != mEncodingHeader
1699
1700 mCurStart = mCurEnd - 1;
1701 while (mCurStart != mEncodingHeader && *mCurStart != ',' &&
1702 !nsCRT::IsAsciiSpace(*mCurStart)) {
1703 --mCurStart;
1704 }
1705 if (*mCurStart == ',' || nsCRT::IsAsciiSpace(*mCurStart)) {
1706 ++mCurStart; // we stopped because of a weird char, so move up one
1707 }
1708
1709 // At this point mCurStart and mCurEnd bracket the encoding string
1710 // we want. Check that it's not "identity"
1711 if (Substring(mCurStart, mCurEnd)
1712 .Equals("identity", nsCaseInsensitiveCStringComparator)) {
1713 mCurEnd = mCurStart;
1714 return PrepareForNext();
1715 }
1716
1717 mReady = true;
1718 return NS_OK;
1719}
1720
1721//-----------------------------------------------------------------------------
1722// HttpBaseChannel::nsIHttpChannel
1723//-----------------------------------------------------------------------------
1724
1725NS_IMETHODIMPnsresult
1726HttpBaseChannel::GetChannelId(uint64_t* aChannelId) {
1727 NS_ENSURE_ARG_POINTER(aChannelId)do { if ((__builtin_expect(!!(!(aChannelId)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aChannelId" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1727); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1728 *aChannelId = mChannelId;
1729 return NS_OK;
1730}
1731
1732NS_IMETHODIMPnsresult
1733HttpBaseChannel::SetChannelId(uint64_t aChannelId) {
1734 mChannelId = aChannelId;
1735 return NS_OK;
1736}
1737
1738NS_IMETHODIMPnsresult HttpBaseChannel::GetTopLevelContentWindowId(uint64_t* aWindowId) {
1739 if (!mContentWindowId) {
1740 nsCOMPtr<nsILoadContext> loadContext;
1741 GetCallback(loadContext);
1742 if (loadContext) {
1743 nsCOMPtr<mozIDOMWindowProxy> topWindow;
1744 loadContext->GetTopWindow(getter_AddRefs(topWindow));
1745 if (topWindow) {
1746 if (nsPIDOMWindowInner* inner =
1747 nsPIDOMWindowOuter::From(topWindow)->GetCurrentInnerWindow()) {
1748 mContentWindowId = inner->WindowID();
1749 }
1750 }
1751 }
1752 }
1753 *aWindowId = mContentWindowId;
1754 return NS_OK;
1755}
1756
1757NS_IMETHODIMPnsresult HttpBaseChannel::SetBrowserId(uint64_t aId) {
1758 mBrowserId = aId;
1759 return NS_OK;
1760}
1761
1762NS_IMETHODIMPnsresult HttpBaseChannel::GetBrowserId(uint64_t* aId) {
1763 EnsureBrowserId();
1764 *aId = mBrowserId;
1765 return NS_OK;
1766}
1767
1768NS_IMETHODIMPnsresult HttpBaseChannel::SetTopLevelContentWindowId(uint64_t aWindowId) {
1769 mContentWindowId = aWindowId;
1770 return NS_OK;
1771}
1772
1773NS_IMETHODIMPnsresult
1774HttpBaseChannel::IsThirdPartyTrackingResource(bool* aIsTrackingResource) {
1775 MOZ_ASSERT(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/HttpBaseChannel.cpp"
, 1776); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags)"
")"); do { *((volatile int*)__null) = 1776; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1776 !(mFirstPartyClassificationFlags && 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/HttpBaseChannel.cpp"
, 1776); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!(mFirstPartyClassificationFlags && mThirdPartyClassificationFlags)"
")"); do { *((volatile int*)__null) = 1776; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1777 *aIsTrackingResource = UrlClassifierCommon::IsTrackingClassificationFlag(
1778 mThirdPartyClassificationFlags,
1779 mLoadInfo->GetOriginAttributes().IsPrivateBrowsing());
1780 return NS_OK;
1781}
1782
1783NS_IMETHODIMPnsresult
1784HttpBaseChannel::IsThirdPartySocialTrackingResource(
1785 bool* aIsThirdPartySocialTrackingResource) {
1786 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/HttpBaseChannel.cpp"
, 1787); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
")"); do { *((volatile int*)__null) = 1787; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
1787 !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/HttpBaseChannel.cpp"
, 1787); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mFirstPartyClassificationFlags || !mThirdPartyClassificationFlags"
")"); do { *((volatile int*)__null) = 1787; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1788 *aIsThirdPartySocialTrackingResource =
1789 UrlClassifierCommon::IsSocialTrackingClassificationFlag(
1790 mThirdPartyClassificationFlags);
1791 return NS_OK;
1792}
1793
1794NS_IMETHODIMPnsresult
1795HttpBaseChannel::GetClassificationFlags(uint32_t* aFlags) {
1796 if (mThirdPartyClassificationFlags) {
1797 *aFlags = mThirdPartyClassificationFlags;
1798 } else {
1799 *aFlags = mFirstPartyClassificationFlags;
1800 }
1801 return NS_OK;
1802}
1803
1804NS_IMETHODIMPnsresult
1805HttpBaseChannel::GetFirstPartyClassificationFlags(uint32_t* aFlags) {
1806 *aFlags = mFirstPartyClassificationFlags;
1807 return NS_OK;
1808}
1809
1810NS_IMETHODIMPnsresult
1811HttpBaseChannel::GetThirdPartyClassificationFlags(uint32_t* aFlags) {
1812 *aFlags = mThirdPartyClassificationFlags;
1813 return NS_OK;
1814}
1815
1816NS_IMETHODIMPnsresult
1817HttpBaseChannel::GetTransferSize(uint64_t* aTransferSize) {
1818 MutexAutoLock lock(mOnDataFinishedMutex);
1819 *aTransferSize = mTransferSize;
1820 return NS_OK;
1821}
1822
1823NS_IMETHODIMPnsresult
1824HttpBaseChannel::GetRequestSize(uint64_t* aRequestSize) {
1825 *aRequestSize = mRequestSize;
1826 return NS_OK;
1827}
1828
1829NS_IMETHODIMPnsresult
1830HttpBaseChannel::GetDecodedBodySize(uint64_t* aDecodedBodySize) {
1831 *aDecodedBodySize = mDecodedBodySize;
1832 return NS_OK;
1833}
1834
1835NS_IMETHODIMPnsresult
1836HttpBaseChannel::GetEncodedBodySize(uint64_t* aEncodedBodySize) {
1837 MutexAutoLock lock(mOnDataFinishedMutex);
1838 *aEncodedBodySize = mEncodedBodySize;
1839 return NS_OK;
1840}
1841
1842NS_IMETHODIMPnsresult
1843HttpBaseChannel::GetSupportsHTTP3(bool* aSupportsHTTP3) {
1844 *aSupportsHTTP3 = mSupportsHTTP3;
1845 return NS_OK;
1846}
1847
1848NS_IMETHODIMPnsresult
1849HttpBaseChannel::GetHasHTTPSRR(bool* aHasHTTPSRR) {
1850 *aHasHTTPSRR = LoadHasHTTPSRR();
1851 return NS_OK;
1852}
1853
1854NS_IMETHODIMPnsresult
1855HttpBaseChannel::GetRequestMethod(nsACString& aMethod) {
1856 mRequestHead.Method(aMethod);
1857 return NS_OK;
1858}
1859
1860NS_IMETHODIMPnsresult
1861HttpBaseChannel::SetRequestMethod(const nsACString& aMethod) {
1862 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/HttpBaseChannel.cpp"
, 1862); 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/HttpBaseChannel.cpp"
, 1862, 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/HttpBaseChannel.cpp"
, 1862); } } 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/HttpBaseChannel.cpp"
, 1862); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 1862; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
1863
1864 mLoadInfo->SetIsGETRequest(aMethod.Equals("GET"));
1865
1866 const nsCString& flatMethod = PromiseFlatCStringTPromiseFlatString<char>(aMethod);
1867
1868 // Method names are restricted to valid HTTP tokens.
1869 if (!nsHttp::IsValidToken(flatMethod)) return NS_ERROR_INVALID_ARG;
1870
1871 mRequestHead.SetMethod(flatMethod);
1872 return NS_OK;
1873}
1874
1875NS_IMETHODIMPnsresult
1876HttpBaseChannel::GetReferrerInfo(nsIReferrerInfo** aReferrerInfo) {
1877 NS_ENSURE_ARG_POINTER(aReferrerInfo)do { if ((__builtin_expect(!!(!(aReferrerInfo)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aReferrerInfo" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1877); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1878 *aReferrerInfo = do_AddRef(mReferrerInfo).take();
1879 return NS_OK;
1880}
1881
1882nsresult HttpBaseChannel::SetReferrerInfoInternal(
1883 nsIReferrerInfo* aReferrerInfo, bool aClone, bool aCompute,
1884 bool aRespectBeforeConnect) {
1885 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
, "HttpBaseChannel::SetReferrerInfoInternal [this=%p aClone(%d) "
"aCompute(%d)]\n", this, aClone, aCompute); } } while (0)
1886 ("HttpBaseChannel::SetReferrerInfoInternal [this=%p aClone(%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
, "HttpBaseChannel::SetReferrerInfoInternal [this=%p aClone(%d) "
"aCompute(%d)]\n", this, aClone, aCompute); } } while (0)
1887 "aCompute(%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
, "HttpBaseChannel::SetReferrerInfoInternal [this=%p aClone(%d) "
"aCompute(%d)]\n", this, aClone, aCompute); } } while (0)
1888 this, aClone, aCompute))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetReferrerInfoInternal [this=%p aClone(%d) "
"aCompute(%d)]\n", this, aClone, aCompute); } } while (0)
;
1889 if (aRespectBeforeConnect) {
1890 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/HttpBaseChannel.cpp"
, 1890); 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/HttpBaseChannel.cpp"
, 1890, 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/HttpBaseChannel.cpp"
, 1890); } } 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/HttpBaseChannel.cpp"
, 1890); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 1890; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
1891 }
1892
1893 mReferrerInfo = aReferrerInfo;
1894
1895 // clear existing referrer, if any
1896 nsresult rv = ClearReferrerHeader();
1897 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/HttpBaseChannel.cpp"
, 1897)
) {
1898 return rv;
1899 }
1900
1901 if (!mReferrerInfo) {
1902 return NS_OK;
1903 }
1904
1905 if (aClone) {
1906 mReferrerInfo = static_cast<dom::ReferrerInfo*>(aReferrerInfo)->Clone();
1907 }
1908
1909 dom::ReferrerInfo* referrerInfo =
1910 static_cast<dom::ReferrerInfo*>(mReferrerInfo.get());
1911
1912 // Don't set referrerInfo if it has not been initialized.
1913 if (!referrerInfo->IsInitialized()) {
1914 mReferrerInfo = nullptr;
1915 return NS_ERROR_NOT_INITIALIZED;
1916 }
1917
1918 if (aClone) {
1919 // Record the telemetry once we set the referrer info to the channel
1920 // successfully.
1921 referrerInfo->RecordTelemetry(this);
1922 }
1923
1924 if (aCompute) {
1925 rv = referrerInfo->ComputeReferrer(this);
1926 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/HttpBaseChannel.cpp"
, 1926)
) {
1927 return rv;
1928 }
1929 }
1930
1931 nsCOMPtr<nsIURI> computedReferrer = mReferrerInfo->GetComputedReferrer();
1932 if (!computedReferrer) {
1933 return NS_OK;
1934 }
1935
1936 nsAutoCString spec;
1937 rv = computedReferrer->GetSpec(spec);
1938 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/HttpBaseChannel.cpp"
, 1938)
) {
1939 return rv;
1940 }
1941
1942 return SetReferrerHeader(spec, aRespectBeforeConnect);
1943}
1944
1945NS_IMETHODIMPnsresult
1946HttpBaseChannel::SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) {
1947 return SetReferrerInfoInternal(aReferrerInfo, true, true, true);
1948}
1949
1950NS_IMETHODIMPnsresult
1951HttpBaseChannel::SetReferrerInfoWithoutClone(nsIReferrerInfo* aReferrerInfo) {
1952 return SetReferrerInfoInternal(aReferrerInfo, false, true, true);
1953}
1954
1955// Return the channel's proxy URI, or if it doesn't exist, the
1956// channel's main URI.
1957NS_IMETHODIMPnsresult
1958HttpBaseChannel::GetProxyURI(nsIURI** aOut) {
1959 NS_ENSURE_ARG_POINTER(aOut)do { if ((__builtin_expect(!!(!(aOut)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOut" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 1959); return NS_ERROR_INVALID_POINTER; } } while (false)
;
1960 nsCOMPtr<nsIURI> result(mProxyURI);
1961 result.forget(aOut);
1962 return NS_OK;
1963}
1964
1965NS_IMETHODIMPnsresult
1966HttpBaseChannel::GetRequestHeader(const nsACString& aHeader,
1967 nsACString& aValue) {
1968 aValue.Truncate();
1969
1970 // XXX might be better to search the header list directly instead of
1971 // hitting the http atom hash table.
1972 nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
1973 if (!atom) return NS_ERROR_NOT_AVAILABLE;
1974
1975 return mRequestHead.GetHeader(atom, aValue);
1976}
1977
1978NS_IMETHODIMPnsresult
1979HttpBaseChannel::SetRequestHeader(const nsACString& aHeader,
1980 const nsACString& aValue, bool aMerge) {
1981 return SetRequestHeaderInternal(aHeader, aValue, aMerge,
1982 nsHttpHeaderArray::eVarietyRequestOverride);
1983}
1984
1985nsresult HttpBaseChannel::SetRequestHeaderInternal(
1986 const nsACString& aHeader, const nsACString& aValue, bool aMerge,
1987 nsHttpHeaderArray::HeaderVariety aVariety) {
1988 const nsCString& flatHeader = PromiseFlatCStringTPromiseFlatString<char>(aHeader);
1989 const nsCString& flatValue = PromiseFlatCStringTPromiseFlatString<char>(aValue);
1990
1991 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
, "HttpBaseChannel::SetRequestHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, flatHeader.get(), flatValue.get(), aMerge
); } } while (0)
1992 ("HttpBaseChannel::SetRequestHeader [this=%p header=\"%s\" 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
, "HttpBaseChannel::SetRequestHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, flatHeader.get(), flatValue.get(), aMerge
); } } while (0)
1993 "merge=%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
, "HttpBaseChannel::SetRequestHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, flatHeader.get(), flatValue.get(), aMerge
); } } while (0)
1994 this, flatHeader.get(), flatValue.get(), aMerge))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetRequestHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, flatHeader.get(), flatValue.get(), aMerge
); } } while (0)
;
1995
1996 // Verify header names are valid HTTP tokens and header values are reasonably
1997 // close to whats allowed in RFC 2616.
1998 if (!nsHttp::IsValidToken(flatHeader) ||
1999 !nsHttp::IsReasonableHeaderValue(flatValue)) {
2000 return NS_ERROR_INVALID_ARG;
2001 }
2002
2003 // Mark that the User-Agent header has been modified.
2004 if (nsHttp::ResolveAtom(aHeader) == nsHttp::User_Agent) {
2005 StoreIsUserAgentHeaderModified(true);
2006 }
2007
2008 return mRequestHead.SetHeader(aHeader, flatValue, aMerge);
2009}
2010
2011NS_IMETHODIMPnsresult
2012HttpBaseChannel::SetNewReferrerInfo(const nsACString& aUrl,
2013 nsIReferrerInfo::ReferrerPolicyIDL aPolicy,
2014 bool aSendReferrer) {
2015 nsresult rv;
2016 // Create URI from string
2017 nsCOMPtr<nsIURI> aURI;
2018 rv = NS_NewURI(getter_AddRefs(aURI), aUrl);
2019 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/HttpBaseChannel.cpp"
, 2019); return rv; } } while (false)
;
2020 // Create new ReferrerInfo and initialize it.
2021 nsCOMPtr<nsIReferrerInfo> referrerInfo = new mozilla::dom::ReferrerInfo();
2022 rv = referrerInfo->Init(aPolicy, aSendReferrer, aURI);
2023 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/HttpBaseChannel.cpp"
, 2023); return rv; } } while (false)
;
2024 // Set ReferrerInfo
2025 return SetReferrerInfo(referrerInfo);
2026}
2027
2028NS_IMETHODIMPnsresult
2029HttpBaseChannel::SetEmptyRequestHeader(const nsACString& aHeader) {
2030 const nsCString& flatHeader = PromiseFlatCStringTPromiseFlatString<char>(aHeader);
2031
2032 LOG(("HttpBaseChannel::SetEmptyRequestHeader [this=%p header=\"%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
, "HttpBaseChannel::SetEmptyRequestHeader [this=%p header=\"%s\"]\n"
, this, flatHeader.get()); } } while (0)
2033 flatHeader.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
, "HttpBaseChannel::SetEmptyRequestHeader [this=%p header=\"%s\"]\n"
, this, flatHeader.get()); } } while (0)
;
2034
2035 // Verify header names are valid HTTP tokens and header values are reasonably
2036 // close to whats allowed in RFC 2616.
2037 if (!nsHttp::IsValidToken(flatHeader)) {
2038 return NS_ERROR_INVALID_ARG;
2039 }
2040
2041 // Mark that the User-Agent header has been modified.
2042 if (nsHttp::ResolveAtom(aHeader) == nsHttp::User_Agent) {
2043 StoreIsUserAgentHeaderModified(true);
2044 }
2045
2046 return mRequestHead.SetEmptyHeader(aHeader);
2047}
2048
2049NS_IMETHODIMPnsresult
2050HttpBaseChannel::VisitRequestHeaders(nsIHttpHeaderVisitor* visitor) {
2051 return mRequestHead.VisitHeaders(visitor);
2052}
2053
2054NS_IMETHODIMPnsresult
2055HttpBaseChannel::VisitNonDefaultRequestHeaders(nsIHttpHeaderVisitor* visitor) {
2056 return mRequestHead.VisitHeaders(visitor,
2057 nsHttpHeaderArray::eFilterSkipDefault);
2058}
2059
2060NS_IMETHODIMPnsresult
2061HttpBaseChannel::GetResponseHeader(const nsACString& header,
2062 nsACString& value) {
2063 value.Truncate();
2064
2065 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2066
2067 nsHttpAtom atom = nsHttp::ResolveAtom(header);
2068 if (!atom) return NS_ERROR_NOT_AVAILABLE;
2069
2070 return mResponseHead->GetHeader(atom, value);
2071}
2072
2073NS_IMETHODIMPnsresult
2074HttpBaseChannel::SetResponseHeader(const nsACString& header,
2075 const nsACString& value, bool merge) {
2076 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
, "HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, TPromiseFlatString<char>(header).
get(), TPromiseFlatString<char>(value).get(), merge); }
} while (0)
2077 ("HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" 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
, "HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, TPromiseFlatString<char>(header).
get(), TPromiseFlatString<char>(value).get(), merge); }
} while (0)
2078 "merge=%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
, "HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, TPromiseFlatString<char>(header).
get(), TPromiseFlatString<char>(value).get(), merge); }
} while (0)
2079 this, PromiseFlatCString(header).get(), PromiseFlatCString(value).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
, "HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, TPromiseFlatString<char>(header).
get(), TPromiseFlatString<char>(value).get(), merge); }
} while (0)
2080 merge))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetResponseHeader [this=%p header=\"%s\" value=\"%s\" "
"merge=%u]\n", this, TPromiseFlatString<char>(header).
get(), TPromiseFlatString<char>(value).get(), merge); }
} while (0)
;
2081
2082 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2083
2084 nsHttpAtom atom = nsHttp::ResolveAtom(header);
2085 if (!atom) return NS_ERROR_NOT_AVAILABLE;
2086
2087 // these response headers must not be changed
2088 if (atom == nsHttp::Content_Type || atom == nsHttp::Content_Length ||
2089 atom == nsHttp::Content_Encoding || atom == nsHttp::Trailer ||
2090 atom == nsHttp::Transfer_Encoding) {
2091 return NS_ERROR_ILLEGAL_VALUE;
2092 }
2093
2094 StoreResponseHeadersModified(true);
2095
2096 return mResponseHead->SetHeader(header, value, merge);
2097}
2098
2099NS_IMETHODIMPnsresult
2100HttpBaseChannel::VisitResponseHeaders(nsIHttpHeaderVisitor* visitor) {
2101 if (!mResponseHead) {
2102 return NS_ERROR_NOT_AVAILABLE;
2103 }
2104 return mResponseHead->VisitHeaders(visitor,
2105 nsHttpHeaderArray::eFilterResponse);
2106}
2107
2108NS_IMETHODIMPnsresult
2109HttpBaseChannel::GetOriginalResponseHeader(const nsACString& aHeader,
2110 nsIHttpHeaderVisitor* aVisitor) {
2111 if (!mResponseHead) {
2112 return NS_ERROR_NOT_AVAILABLE;
2113 }
2114
2115 nsHttpAtom atom = nsHttp::ResolveAtom(aHeader);
2116 if (!atom) {
2117 return NS_ERROR_NOT_AVAILABLE;
2118 }
2119
2120 return mResponseHead->GetOriginalHeader(atom, aVisitor);
2121}
2122
2123NS_IMETHODIMPnsresult
2124HttpBaseChannel::VisitOriginalResponseHeaders(nsIHttpHeaderVisitor* aVisitor) {
2125 if (!mResponseHead) {
2126 return NS_ERROR_NOT_AVAILABLE;
2127 }
2128
2129 return mResponseHead->VisitHeaders(
2130 aVisitor, nsHttpHeaderArray::eFilterResponseOriginal);
2131}
2132
2133NS_IMETHODIMPnsresult
2134HttpBaseChannel::GetAllowSTS(bool* value) {
2135 NS_ENSURE_ARG_POINTER(value)do { if ((__builtin_expect(!!(!(value)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "value" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2135); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2136 *value = LoadAllowSTS();
2137 return NS_OK;
2138}
2139
2140NS_IMETHODIMPnsresult
2141HttpBaseChannel::SetAllowSTS(bool value) {
2142 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/HttpBaseChannel.cpp"
, 2142); 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/HttpBaseChannel.cpp"
, 2142, 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/HttpBaseChannel.cpp"
, 2142); } } 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/HttpBaseChannel.cpp"
, 2142); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 2142; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2143 StoreAllowSTS(value);
2144 return NS_OK;
2145}
2146
2147NS_IMETHODIMPnsresult
2148HttpBaseChannel::GetIsOCSP(bool* value) {
2149 NS_ENSURE_ARG_POINTER(value)do { if ((__builtin_expect(!!(!(value)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "value" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2149); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2150 *value = LoadIsOCSP();
2151 return NS_OK;
2152}
2153
2154NS_IMETHODIMPnsresult
2155HttpBaseChannel::SetIsOCSP(bool value) {
2156 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/HttpBaseChannel.cpp"
, 2156); 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/HttpBaseChannel.cpp"
, 2156, 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/HttpBaseChannel.cpp"
, 2156); } } 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/HttpBaseChannel.cpp"
, 2156); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 2156; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2157 StoreIsOCSP(value);
2158 return NS_OK;
2159}
2160
2161NS_IMETHODIMPnsresult
2162HttpBaseChannel::GetIsUserAgentHeaderModified(bool* value) {
2163 NS_ENSURE_ARG_POINTER(value)do { if ((__builtin_expect(!!(!(value)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "value" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2163); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2164 *value = LoadIsUserAgentHeaderModified();
2165 return NS_OK;
2166}
2167
2168NS_IMETHODIMPnsresult
2169HttpBaseChannel::SetIsUserAgentHeaderModified(bool value) {
2170 StoreIsUserAgentHeaderModified(value);
2171 return NS_OK;
2172}
2173
2174NS_IMETHODIMPnsresult
2175HttpBaseChannel::GetRedirectionLimit(uint32_t* value) {
2176 NS_ENSURE_ARG_POINTER(value)do { if ((__builtin_expect(!!(!(value)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "value" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2176); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2177 *value = mRedirectionLimit;
2178 return NS_OK;
2179}
2180
2181NS_IMETHODIMPnsresult
2182HttpBaseChannel::SetRedirectionLimit(uint32_t value) {
2183 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/HttpBaseChannel.cpp"
, 2183); 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/HttpBaseChannel.cpp"
, 2183, 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/HttpBaseChannel.cpp"
, 2183); } } 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/HttpBaseChannel.cpp"
, 2183); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 2183; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2184
2185 mRedirectionLimit = std::min<uint32_t>(value, 0xff);
2186 return NS_OK;
2187}
2188
2189nsresult HttpBaseChannel::OverrideSecurityInfo(
2190 nsITransportSecurityInfo* aSecurityInfo) {
2191 MOZ_ASSERT(!mSecurityInfo,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mSecurityInfo))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mSecurityInfo"
" (" "This can only be called when we don't have a security info "
"object already" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2193); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSecurityInfo"
") (" "This can only be called when we don't have a security info "
"object already" ")"); do { *((volatile int*)__null) = 2193;
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
2192 "This can only be called when we don't have a security info "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mSecurityInfo))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mSecurityInfo"
" (" "This can only be called when we don't have a security info "
"object already" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2193); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSecurityInfo"
") (" "This can only be called when we don't have a security info "
"object already" ")"); do { *((volatile int*)__null) = 2193;
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
2193 "object already")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mSecurityInfo))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mSecurityInfo"
" (" "This can only be called when we don't have a security info "
"object already" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2193); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mSecurityInfo"
") (" "This can only be called when we don't have a security info "
"object already" ")"); do { *((volatile int*)__null) = 2193;
__attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
2194 MOZ_RELEASE_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aSecurityInfo))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aSecurityInfo" " ("
"This can only be called with a valid security info object" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2196); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aSecurityInfo"
") (" "This can only be called with a valid security info object"
")"); do { *((volatile int*)__null) = 2196; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2195 aSecurityInfo,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aSecurityInfo))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aSecurityInfo" " ("
"This can only be called with a valid security info object" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2196); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aSecurityInfo"
") (" "This can only be called with a valid security info object"
")"); do { *((volatile int*)__null) = 2196; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2196 "This can only be called with a valid security info object")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aSecurityInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aSecurityInfo))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aSecurityInfo" " ("
"This can only be called with a valid security info object" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2196); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "aSecurityInfo"
") (" "This can only be called with a valid security info object"
")"); do { *((volatile int*)__null) = 2196; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2197 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()"
" (" "This can only be called on channels that are not bypassing "
"interception" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2199); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
") (" "This can only be called on channels that are not bypassing "
"interception" ")"); do { *((volatile int*)__null) = 2199; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2198 "This can only be called on channels that are not bypassing "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!BypassServiceWorker())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!BypassServiceWorker()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!BypassServiceWorker()"
" (" "This can only be called on channels that are not bypassing "
"interception" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2199); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
") (" "This can only be called on channels that are not bypassing "
"interception" ")"); do { *((volatile int*)__null) = 2199; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2199 "interception")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!BypassServiceWorker())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!BypassServiceWorker()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("!BypassServiceWorker()"
" (" "This can only be called on channels that are not bypassing "
"interception" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2199); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!BypassServiceWorker()"
") (" "This can only be called on channels that are not bypassing "
"interception" ")"); do { *((volatile int*)__null) = 2199; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
2200 MOZ_ASSERT(LoadResponseCouldBeSynthesized(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadResponseCouldBeSynthesized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadResponseCouldBeSynthesized
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("LoadResponseCouldBeSynthesized()" " (" "This can only be called on channels that can be intercepted"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2201); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadResponseCouldBeSynthesized()"
") (" "This can only be called on channels that can be intercepted"
")"); do { *((volatile int*)__null) = 2201; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2201 "This can only be called on channels that can be intercepted")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(LoadResponseCouldBeSynthesized())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(LoadResponseCouldBeSynthesized
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("LoadResponseCouldBeSynthesized()" " (" "This can only be called on channels that can be intercepted"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2201); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadResponseCouldBeSynthesized()"
") (" "This can only be called on channels that can be intercepted"
")"); do { *((volatile int*)__null) = 2201; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2202 if (mSecurityInfo) {
2203 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
, "HttpBaseChannel::OverrideSecurityInfo mSecurityInfo is null! "
"[this=%p]\n", this); } } while (0)
2204 ("HttpBaseChannel::OverrideSecurityInfo mSecurityInfo is null! "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::OverrideSecurityInfo mSecurityInfo is null! "
"[this=%p]\n", this); } } while (0)
2205 "[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
, "HttpBaseChannel::OverrideSecurityInfo mSecurityInfo is null! "
"[this=%p]\n", this); } } while (0)
2206 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
, "HttpBaseChannel::OverrideSecurityInfo mSecurityInfo is null! "
"[this=%p]\n", this); } } while (0)
;
2207 return NS_ERROR_UNEXPECTED;
2208 }
2209 if (!LoadResponseCouldBeSynthesized()) {
2210 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
, "HttpBaseChannel::OverrideSecurityInfo channel cannot be intercepted! "
"[this=%p]\n", this); } } while (0)
2211 ("HttpBaseChannel::OverrideSecurityInfo channel cannot be intercepted! "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::OverrideSecurityInfo channel cannot be intercepted! "
"[this=%p]\n", this); } } while (0)
2212 "[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
, "HttpBaseChannel::OverrideSecurityInfo channel cannot be intercepted! "
"[this=%p]\n", this); } } while (0)
2213 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
, "HttpBaseChannel::OverrideSecurityInfo channel cannot be intercepted! "
"[this=%p]\n", this); } } while (0)
;
2214 return NS_ERROR_UNEXPECTED;
2215 }
2216
2217 mSecurityInfo = aSecurityInfo;
2218 return NS_OK;
2219}
2220
2221NS_IMETHODIMPnsresult
2222HttpBaseChannel::IsNoStoreResponse(bool* value) {
2223 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2224 *value = mResponseHead->NoStore();
2225 return NS_OK;
2226}
2227
2228NS_IMETHODIMPnsresult
2229HttpBaseChannel::IsNoCacheResponse(bool* value) {
2230 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2231 *value = mResponseHead->NoCache();
2232 if (!*value) *value = mResponseHead->ExpiresInPast();
2233 return NS_OK;
2234}
2235
2236NS_IMETHODIMPnsresult
2237HttpBaseChannel::IsPrivateResponse(bool* value) {
2238 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2239 *value = mResponseHead->Private();
2240 return NS_OK;
2241}
2242
2243NS_IMETHODIMPnsresult
2244HttpBaseChannel::GetResponseStatus(uint32_t* aValue) {
2245 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2246 *aValue = mResponseHead->Status();
2247 return NS_OK;
2248}
2249
2250NS_IMETHODIMPnsresult
2251HttpBaseChannel::GetResponseStatusText(nsACString& aValue) {
2252 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2253 nsAutoCString version;
2254 // https://fetch.spec.whatwg.org :
2255 // Responses over an HTTP/2 connection will always have the empty byte
2256 // sequence as status message as HTTP/2 does not support them.
2257 if (NS_WARN_IF(NS_FAILED(GetProtocolVersion(version)))NS_warn_if_impl(((bool)(__builtin_expect(!!(NS_FAILED_impl(GetProtocolVersion
(version))), 0))), "NS_FAILED(GetProtocolVersion(version))", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2257)
||
2258 !version.EqualsLiteral("h2")) {
2259 mResponseHead->StatusText(aValue);
2260 }
2261 return NS_OK;
2262}
2263
2264NS_IMETHODIMPnsresult
2265HttpBaseChannel::GetRequestSucceeded(bool* aValue) {
2266 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
2267 uint32_t status = mResponseHead->Status();
2268 *aValue = (status / 100 == 2);
2269 return NS_OK;
2270}
2271
2272NS_IMETHODIMPnsresult
2273HttpBaseChannel::RedirectTo(nsIURI* targetURI) {
2274 NS_ENSURE_ARG(targetURI)do { if ((__builtin_expect(!!(!(targetURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "targetURI" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2274); return NS_ERROR_INVALID_ARG; } } while (false)
;
2275
2276 nsAutoCString spec;
2277 targetURI->GetAsciiSpec(spec);
2278 LOG(("HttpBaseChannel::RedirectTo [this=%p, uri=%s]", this, spec.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
, "HttpBaseChannel::RedirectTo [this=%p, uri=%s]", this, spec
.get()); } } while (0)
;
2279 LogCallingScriptLocation(this);
2280
2281 // We cannot redirect after OnStartRequest of the listener
2282 // has been called, since to redirect we have to switch channels
2283 // and the dance with OnStartRequest et al has to start over.
2284 // This would break the nsIStreamListener contract.
2285 NS_ENSURE_FALSE(LoadOnStartRequestCalled(), NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(!(LoadOnStartRequestCalled())
)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!(LoadOnStartRequestCalled())"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2285); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
2286
2287 // The first parameter is the URI we would like to redirect to
2288 // The second parameter should default to false if normal redirect
2289 mAPIRedirectTo =
2290 Some(mozilla::MakeCompactPair(nsCOMPtr<nsIURI>(targetURI), false));
2291
2292 // Only Web Extensions are allowed to redirect a channel to a data:
2293 // URI. To avoid any bypasses after the channel was flagged by
2294 // the WebRequst API, we are dropping the flag here.
2295 mLoadInfo->SetAllowInsecureRedirectToDataURI(false);
2296
2297 // We may want to rewrite origin allowance, hence we need an
2298 // artificial response head.
2299 if (!mResponseHead) {
2300 mResponseHead.reset(new nsHttpResponseHead());
2301 }
2302 return NS_OK;
2303}
2304
2305NS_IMETHODIMPnsresult
2306HttpBaseChannel::TransparentRedirectTo(nsIURI* targetURI) {
2307 LOG(("HttpBaseChannel::TransparentRedirectTo [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
, "HttpBaseChannel::TransparentRedirectTo [this=%p]", this); }
} while (0)
;
2308 RedirectTo(targetURI);
2309 MOZ_ASSERT(mAPIRedirectTo, "How did this 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 this happen?" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2309); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mAPIRedirectTo"
") (" "How did this happen?" ")"); do { *((volatile int*)__null
) = 2309; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
2310 mAPIRedirectTo->second() = true;
2311 return NS_OK;
2312}
2313
2314NS_IMETHODIMPnsresult
2315HttpBaseChannel::UpgradeToSecure() {
2316 // Upgrades are handled internally between http-on-modify-request and
2317 // http-on-before-connect, which means upgrades are only possible during
2318 // on-modify, or WebRequest.onBeforeRequest in Web Extensions. Once we are
2319 // past the code path where upgrades are handled, attempting an upgrade
2320 // will throw an error.
2321 NS_ENSURE_TRUE(LoadUpgradableToSecure(), NS_ERROR_NOT_AVAILABLE)do { if ((__builtin_expect(!!(!(LoadUpgradableToSecure())), 0
))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "LoadUpgradableToSecure()"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2321); return NS_ERROR_NOT_AVAILABLE; } } while (false)
;
2322
2323 StoreUpgradeToSecure(true);
2324 // todo: Currently UpgradeToSecure() is called only by web extensions, if
2325 // that ever changes, we need to update the following telemetry collection
2326 // to reflect any future changes.
2327 mLoadInfo->SetHttpsUpgradeTelemetry(nsILoadInfo::WEB_EXTENSION_UPGRADE);
2328
2329 return NS_OK;
2330}
2331
2332NS_IMETHODIMPnsresult
2333HttpBaseChannel::GetRequestObserversCalled(bool* aCalled) {
2334 NS_ENSURE_ARG_POINTER(aCalled)do { if ((__builtin_expect(!!(!(aCalled)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aCalled" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2334); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2335 *aCalled = LoadRequestObserversCalled();
2336 return NS_OK;
2337}
2338
2339NS_IMETHODIMPnsresult
2340HttpBaseChannel::SetRequestObserversCalled(bool aCalled) {
2341 StoreRequestObserversCalled(aCalled);
2342 return NS_OK;
2343}
2344
2345NS_IMETHODIMPnsresult
2346HttpBaseChannel::GetRequestContextID(uint64_t* aRCID) {
2347 NS_ENSURE_ARG_POINTER(aRCID)do { if ((__builtin_expect(!!(!(aRCID)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aRCID" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2347); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2348 *aRCID = mRequestContextID;
2349 return NS_OK;
2350}
2351
2352NS_IMETHODIMPnsresult
2353HttpBaseChannel::SetRequestContextID(uint64_t aRCID) {
2354 mRequestContextID = aRCID;
2355 return NS_OK;
2356}
2357
2358NS_IMETHODIMPnsresult
2359HttpBaseChannel::GetIsMainDocumentChannel(bool* aValue) {
2360 NS_ENSURE_ARG_POINTER(aValue)do { if ((__builtin_expect(!!(!(aValue)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aValue" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2360); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2361 *aValue = IsNavigation();
2362 return NS_OK;
2363}
2364
2365NS_IMETHODIMPnsresult
2366HttpBaseChannel::SetIsMainDocumentChannel(bool aValue) {
2367 StoreForceMainDocumentChannel(aValue);
2368 return NS_OK;
2369}
2370
2371NS_IMETHODIMPnsresult
2372HttpBaseChannel::GetProtocolVersion(nsACString& aProtocolVersion) {
2373 // Try to use ALPN if available and if it is not for a proxy, i.e if an
2374 // https proxy was not used or if https proxy was used but the connection to
2375 // the origin server is also https. In the case, an https proxy was used and
2376 // the connection to the origin server was http, mSecurityInfo will be from
2377 // the proxy.
2378 if (!mConnectionInfo || !mConnectionInfo->UsingHttpsProxy() ||
2379 mConnectionInfo->EndToEndSSL()) {
2380 nsAutoCString protocol;
2381 if (mSecurityInfo &&
2382 NS_SUCCEEDED(mSecurityInfo->GetNegotiatedNPN(protocol))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mSecurityInfo->
GetNegotiatedNPN(protocol))), 1)))
&&
2383 !protocol.IsEmpty()) {
2384 // The negotiated protocol was not empty so we can use it.
2385 aProtocolVersion = protocol;
2386 return NS_OK;
2387 }
2388 }
2389
2390 if (mResponseHead) {
2391 HttpVersion version = mResponseHead->Version();
2392 aProtocolVersion.Assign(nsHttp::GetProtocolVersion(version));
2393 return NS_OK;
2394 }
2395
2396 return NS_ERROR_NOT_AVAILABLE;
2397}
2398
2399//-----------------------------------------------------------------------------
2400// HttpBaseChannel::nsIHttpChannelInternal
2401//-----------------------------------------------------------------------------
2402
2403NS_IMETHODIMPnsresult
2404HttpBaseChannel::SetTopWindowURIIfUnknown(nsIURI* aTopWindowURI) {
2405 if (!aTopWindowURI) {
2406 return NS_ERROR_INVALID_ARG;
2407 }
2408
2409 if (mTopWindowURI) {
2410 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
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "mTopWindowURI is already set.\n"
, this); } } while (0)
2411 ("HttpChannelBase::SetTopWindowURIIfUnknown [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
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "mTopWindowURI is already set.\n"
, this); } } while (0)
2412 "mTopWindowURI is already set.\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
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "mTopWindowURI is already set.\n"
, this); } } while (0)
2413 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
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "mTopWindowURI is already set.\n"
, this); } } while (0)
;
2414 return NS_ERROR_FAILURE;
2415 }
2416
2417 nsCOMPtr<nsIURI> topWindowURI;
2418 Unused << GetTopWindowURI(getter_AddRefs(topWindowURI));
2419
2420 // Don't modify |mTopWindowURI| if we can get one from GetTopWindowURI().
2421 if (topWindowURI) {
2422 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
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "Return an error since we got a top window uri.\n"
, this); } } while (0)
2423 ("HttpChannelBase::SetTopWindowURIIfUnknown [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
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "Return an error since we got a top window uri.\n"
, this); } } while (0)
2424 "Return an error since we got a top window uri.\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
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "Return an error since we got a top window uri.\n"
, this); } } while (0)
2425 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
, "HttpChannelBase::SetTopWindowURIIfUnknown [this=%p] " "Return an error since we got a top window uri.\n"
, this); } } while (0)
;
2426 return NS_ERROR_FAILURE;
2427 }
2428
2429 mTopWindowURI = aTopWindowURI;
2430 return NS_OK;
2431}
2432
2433NS_IMETHODIMPnsresult
2434HttpBaseChannel::GetTopWindowURI(nsIURI** aTopWindowURI) {
2435 nsCOMPtr<nsIURI> uriBeingLoaded =
2436 AntiTrackingUtils::MaybeGetDocumentURIBeingLoaded(this);
2437 return GetTopWindowURI(uriBeingLoaded, aTopWindowURI);
2438}
2439
2440nsresult HttpBaseChannel::GetTopWindowURI(nsIURI* aURIBeingLoaded,
2441 nsIURI** aTopWindowURI) {
2442 nsresult rv = NS_OK;
2443 nsCOMPtr<mozIThirdPartyUtil> util;
2444 // Only compute the top window URI once. In e10s, this must be computed in the
2445 // child. The parent gets the top window URI through HttpChannelOpenArgs.
2446 if (!mTopWindowURI) {
2447 util = components::ThirdPartyUtil::Service();
2448 if (!util) {
2449 return NS_ERROR_NOT_AVAILABLE;
2450 }
2451 nsCOMPtr<mozIDOMWindowProxy> win;
2452 rv = util->GetTopWindowForChannel(this, aURIBeingLoaded,
2453 getter_AddRefs(win));
2454 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
2455 rv = util->GetURIFromWindow(win, getter_AddRefs(mTopWindowURI));
2456#if DEBUG1
2457 if (mTopWindowURI) {
2458 nsCString spec;
2459 if (NS_SUCCEEDED(mTopWindowURI->GetSpec(spec))((bool)(__builtin_expect(!!(!NS_FAILED_impl(mTopWindowURI->
GetSpec(spec))), 1)))
) {
2460 LOG(("HttpChannelBase::Setting topwindow URI spec %s [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
, "HttpChannelBase::Setting topwindow URI spec %s [this=%p]\n"
, spec.get(), this); } } while (0)
2461 spec.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
, "HttpChannelBase::Setting topwindow URI spec %s [this=%p]\n"
, spec.get(), this); } } while (0)
;
2462 }
2463 }
2464#endif
2465 }
2466 }
2467 *aTopWindowURI = do_AddRef(mTopWindowURI).take();
2468 return rv;
2469}
2470
2471NS_IMETHODIMPnsresult
2472HttpBaseChannel::GetDocumentURI(nsIURI** aDocumentURI) {
2473 NS_ENSURE_ARG_POINTER(aDocumentURI)do { if ((__builtin_expect(!!(!(aDocumentURI)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aDocumentURI" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2473); return NS_ERROR_INVALID_POINTER; } } while (false)
;
2474 *aDocumentURI = do_AddRef(mDocumentURI).take();
2475 return NS_OK;
2476}
2477
2478NS_IMETHODIMPnsresult
2479HttpBaseChannel::SetDocumentURI(nsIURI* aDocumentURI) {
2480 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/HttpBaseChannel.cpp"
, 2480); 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/HttpBaseChannel.cpp"
, 2480, 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/HttpBaseChannel.cpp"
, 2480); } } 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/HttpBaseChannel.cpp"
, 2480); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 2480; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
2481 mDocumentURI = aDocumentURI;
2482 return NS_OK;
2483}
2484
2485NS_IMETHODIMPnsresult
2486HttpBaseChannel::GetRequestVersion(uint32_t* major, uint32_t* minor) {
2487 HttpVersion version = mRequestHead.Version();
2488
2489 if (major) {
2490 *major = static_cast<uint32_t>(version) / 10;
2491 }
2492 if (minor) {
2493 *minor = static_cast<uint32_t>(version) % 10;
2494 }
2495
2496 return NS_OK;
2497}
2498
2499NS_IMETHODIMPnsresult
2500HttpBaseChannel::GetResponseVersion(uint32_t* major, uint32_t* minor) {
2501 if (!mResponseHead) {
2502 *major = *minor = 0; // we should at least be kind about it
2503 return NS_ERROR_NOT_AVAILABLE;
2504 }
2505
2506 HttpVersion version = mResponseHead->Version();
2507
2508 if (major) {
2509 *major = static_cast<uint32_t>(version) / 10;
2510 }
2511 if (minor) {
2512 *minor = static_cast<uint32_t>(version) % 10;
2513 }
2514
2515 return NS_OK;
2516}
2517
2518bool HttpBaseChannel::IsBrowsingContextDiscarded() const {
2519 // If there is no loadGroup attached to the current channel, we check the
2520 // global private browsing state for the private channel instead. For
2521 // non-private channel, we will always return false here.
2522 //
2523 // Note that we can only access the global private browsing state in the
2524 // parent process. So, we will fallback to just return false in the content
2525 // process.
2526 if (!mLoadGroup) {
2527 if (!XRE_IsParentProcess()) {
2528 return false;
2529 }
2530
2531 return mLoadInfo->GetOriginAttributes().IsPrivateBrowsing() &&
2532 !dom::CanonicalBrowsingContext::IsPrivateBrowsingActive();
2533 }
2534
2535 return mLoadGroup->GetIsBrowsingContextDiscarded();
2536}
2537
2538// https://mikewest.github.io/corpp/#process-navigation-response
2539nsresult HttpBaseChannel::ProcessCrossOriginEmbedderPolicyHeader() {
2540 nsresult rv;
2541 if (!StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2542 return NS_OK;
2543 }
2544
2545 // Only consider Cross-Origin-Embedder-Policy for document loads.
2546 if (mLoadInfo->GetExternalContentPolicyType() !=
2547 ExtContentPolicy::TYPE_DOCUMENT &&
2548 mLoadInfo->GetExternalContentPolicyType() !=
2549 ExtContentPolicy::TYPE_SUBDOCUMENT) {
2550 return NS_OK;
2551 }
2552
2553 nsILoadInfo::CrossOriginEmbedderPolicy resultPolicy =
2554 nsILoadInfo::EMBEDDER_POLICY_NULL;
2555 bool isCoepCredentiallessEnabled;
2556 rv = mLoadInfo->GetIsOriginTrialCoepCredentiallessEnabledForTopLevel(
2557 &isCoepCredentiallessEnabled);
2558 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/HttpBaseChannel.cpp"
, 2558); return rv; } } while (false)
;
2559 rv = GetResponseEmbedderPolicy(isCoepCredentiallessEnabled, &resultPolicy);
2560 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2561 return NS_OK;
2562 }
2563
2564 // https://html.spec.whatwg.org/multipage/origin.html#coep
2565 if (mLoadInfo->GetExternalContentPolicyType() ==
2566 ExtContentPolicy::TYPE_SUBDOCUMENT &&
2567 !nsHttpChannel::IsRedirectStatus(mResponseHead->Status()) &&
2568 mLoadInfo->GetLoadingEmbedderPolicy() !=
2569 nsILoadInfo::EMBEDDER_POLICY_NULL &&
2570 resultPolicy != nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP &&
2571 resultPolicy != nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS) {
2572 return NS_ERROR_DOM_COEP_FAILED;
2573 }
2574
2575 return NS_OK;
2576}
2577
2578// https://mikewest.github.io/corpp/#corp-check
2579nsresult HttpBaseChannel::ProcessCrossOriginResourcePolicyHeader() {
2580 // Fetch 4.5.9
2581 dom::RequestMode requestMode;
2582 MOZ_ALWAYS_SUCCEEDS(GetRequestMode(&requestMode))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(GetRequestMode(&requestMode))), 1)))), 1))) { } else { do
{ do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(GetRequestMode(&requestMode))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2582); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(GetRequestMode(&requestMode))"
")"); do { *((volatile int*)__null) = 2582; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
2583 // XXX this seems wrong per spec? What about navigate
2584 if (requestMode != RequestMode::No_cors) {
2585 return NS_OK;
2586 }
2587
2588 // We only apply this for resources.
2589 auto extContentPolicyType = mLoadInfo->GetExternalContentPolicyType();
2590 if (extContentPolicyType == ExtContentPolicy::TYPE_DOCUMENT ||
2591 extContentPolicyType == ExtContentPolicy::TYPE_WEBSOCKET ||
2592 extContentPolicyType == ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
2593 return NS_OK;
2594 }
2595
2596 if (extContentPolicyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
2597 // COEP pref off, skip CORP checking for subdocument.
2598 if (!StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2599 return NS_OK;
2600 }
2601 // COEP 3.2.1.2 when request targets a nested browsing context then embedder
2602 // policy value is "unsafe-none", then return allowed.
2603 if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2604 nsILoadInfo::EMBEDDER_POLICY_NULL) {
2605 return NS_OK;
2606 }
2607 }
2608
2609 MOZ_ASSERT(mLoadInfo->GetLoadingPrincipal(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetLoadingPrincipal())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetLoadingPrincipal
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mLoadInfo->GetLoadingPrincipal()" " (" "Resources should always have a LoadingPrincipal"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetLoadingPrincipal()"
") (" "Resources should always have a LoadingPrincipal" ")")
; do { *((volatile int*)__null) = 2610; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
2610 "Resources should always have a LoadingPrincipal")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetLoadingPrincipal())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetLoadingPrincipal
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mLoadInfo->GetLoadingPrincipal()" " (" "Resources should always have a LoadingPrincipal"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetLoadingPrincipal()"
") (" "Resources should always have a LoadingPrincipal" ")")
; do { *((volatile int*)__null) = 2610; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2611 if (!mResponseHead) {
2612 return NS_OK;
2613 }
2614
2615 if (mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal()) {
2616 return NS_OK;
2617 }
2618
2619 nsAutoCString content;
2620 Unused << mResponseHead->GetHeader(nsHttp::Cross_Origin_Resource_Policy,
2621 content);
2622
2623 if (StaticPrefs::browser_tabs_remote_useCrossOriginEmbedderPolicy()) {
2624 if (content.IsEmpty()) {
2625 if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2626 nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS) {
2627 bool requestIncludesCredentials = false;
2628 nsresult rv = GetCorsIncludeCredentials(&requestIncludesCredentials);
2629 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2630 return NS_OK;
2631 }
2632 // COEP: Set policy to `same-origin` if: response’s
2633 // request-includes-credentials is true, or forNavigation is true.
2634 if (requestIncludesCredentials ||
2635 extContentPolicyType == ExtContentPolicyType::TYPE_SUBDOCUMENT) {
2636 content = "same-origin"_ns;
2637 }
2638 } else if (mLoadInfo->GetLoadingEmbedderPolicy() ==
2639 nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP) {
2640 // COEP 3.2.1.6 If policy is null, and embedder policy is
2641 // "require-corp", set policy to "same-origin". Note that we treat
2642 // invalid value as "cross-origin", which spec indicates. We might want
2643 // to make that stricter.
2644 content = "same-origin"_ns;
2645 }
2646 }
2647 }
2648
2649 if (content.IsEmpty()) {
2650 return NS_OK;
2651 }
2652
2653 nsCOMPtr<nsIPrincipal> channelOrigin;
2654 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
2655 this, getter_AddRefs(channelOrigin));
2656
2657 // Cross-Origin-Resource-Policy = %s"same-origin" / %s"same-site" /
2658 // %s"cross-origin"
2659 if (content.EqualsLiteral("same-origin")) {
2660 if (!channelOrigin->Equals(mLoadInfo->GetLoadingPrincipal())) {
2661 return NS_ERROR_DOM_CORP_FAILED;
2662 }
2663 return NS_OK;
2664 }
2665 if (content.EqualsLiteral("same-site")) {
2666 nsAutoCString documentBaseDomain;
2667 nsAutoCString resourceBaseDomain;
2668 mLoadInfo->GetLoadingPrincipal()->GetBaseDomain(documentBaseDomain);
2669 channelOrigin->GetBaseDomain(resourceBaseDomain);
2670 if (documentBaseDomain != resourceBaseDomain) {
2671 return NS_ERROR_DOM_CORP_FAILED;
2672 }
2673
2674 nsCOMPtr<nsIURI> resourceURI = channelOrigin->GetURI();
2675 if (!mLoadInfo->GetLoadingPrincipal()->SchemeIs("https") &&
2676 resourceURI->SchemeIs("https")) {
2677 return NS_ERROR_DOM_CORP_FAILED;
2678 }
2679
2680 return NS_OK;
2681 }
2682
2683 return NS_OK;
2684}
2685
2686// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
2687// This method runs steps 1-4 of the algorithm to compare
2688// cross-origin-opener policies
2689static bool CompareCrossOriginOpenerPolicies(
2690 nsILoadInfo::CrossOriginOpenerPolicy documentPolicy,
2691 nsIPrincipal* documentOrigin,
2692 nsILoadInfo::CrossOriginOpenerPolicy resultPolicy,
2693 nsIPrincipal* resultOrigin) {
2694 if (documentPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE &&
2695 resultPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2696 return true;
2697 }
2698
2699 if (documentPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE ||
2700 resultPolicy == nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2701 return false;
2702 }
2703
2704 if (documentPolicy == resultPolicy && documentOrigin->Equals(resultOrigin)) {
2705 return true;
2706 }
2707
2708 return false;
2709}
2710
2711// This runs steps 1-5 of the algorithm when navigating a top level document.
2712// See https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
2713nsresult HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch() {
2714 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/HttpBaseChannel.cpp"
, 2714); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 2714; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2715
2716 StoreHasCrossOriginOpenerPolicyMismatch(false);
2717 if (!StaticPrefs::browser_tabs_remote_useCrossOriginOpenerPolicy()) {
2718 return NS_OK;
2719 }
2720
2721 // Only consider Cross-Origin-Opener-Policy for toplevel document loads.
2722 if (mLoadInfo->GetExternalContentPolicyType() !=
2723 ExtContentPolicy::TYPE_DOCUMENT) {
2724 return NS_OK;
2725 }
2726
2727 // Maybe the channel failed and we have no response head?
2728 if (!mResponseHead) {
2729 // Not having a response head is not a hard failure at the point where
2730 // this method is called.
2731 return NS_OK;
2732 }
2733
2734 RefPtr<mozilla::dom::BrowsingContext> ctx;
2735 mLoadInfo->GetBrowsingContext(getter_AddRefs(ctx));
2736
2737 // In xpcshell-tests we don't always have a browsingContext
2738 if (!ctx) {
2739 return NS_OK;
2740 }
2741
2742 nsCOMPtr<nsIPrincipal> resultOrigin;
2743 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
2744 this, getter_AddRefs(resultOrigin));
2745
2746 // Get the policy of the active document, and the policy for the result.
2747 nsILoadInfo::CrossOriginOpenerPolicy documentPolicy = ctx->GetOpenerPolicy();
2748 nsILoadInfo::CrossOriginOpenerPolicy resultPolicy =
2749 nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
2750 Unused << ComputeCrossOriginOpenerPolicy(documentPolicy, &resultPolicy);
2751 mComputedCrossOriginOpenerPolicy = resultPolicy;
2752
2753 // Add a permission to mark this site as high-value into the permission DB.
2754 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2755 mozilla::dom::AddHighValuePermission(
2756 resultOrigin, mozilla::dom::kHighValueCOOPPermission);
2757 }
2758
2759 // If bc's popup sandboxing flag set is not empty and potentialCOOP is
2760 // non-null, then navigate bc to a network error and abort these steps.
2761 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE &&
2762 mLoadInfo->GetSandboxFlags()) {
2763 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
, "HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch network error "
"for non empty sandboxing and non null COOP"); } } while (0)
2764 "HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch network error "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch network error "
"for non empty sandboxing and non null COOP"); } } while (0)
2765 "for non empty sandboxing and non null COOP"))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::ComputeCrossOriginOpenerPolicyMismatch network error "
"for non empty sandboxing and non null COOP"); } } while (0)
;
2766 return NS_ERROR_DOM_COOP_FAILED;
2767 }
2768
2769 // In xpcshell-tests we don't always have a current window global
2770 RefPtr<mozilla::dom::WindowGlobalParent> currentWindowGlobal =
2771 ctx->Canonical()->GetCurrentWindowGlobal();
2772 if (!currentWindowGlobal) {
2773 return NS_OK;
2774 }
2775
2776 // We use the top window principal as the documentOrigin
2777 nsCOMPtr<nsIPrincipal> documentOrigin =
2778 currentWindowGlobal->DocumentPrincipal();
2779
2780 bool compareResult = CompareCrossOriginOpenerPolicies(
2781 documentPolicy, documentOrigin, resultPolicy, resultOrigin);
2782
2783 if (LOG_ENABLED()(__builtin_expect(!!(mozilla::detail::log_test(mozilla::net::
gHttpLog, mozilla::LogLevel::Verbose)), 0))
) {
2784 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
, "HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch - " "doc:%d result:%d - compare:%d\n"
, documentPolicy, resultPolicy, compareResult); } } while (0)
2785 ("HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch - "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch - " "doc:%d result:%d - compare:%d\n"
, documentPolicy, resultPolicy, compareResult); } } while (0)
2786 "doc:%d result:%d - compare:%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
, "HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch - " "doc:%d result:%d - compare:%d\n"
, documentPolicy, resultPolicy, compareResult); } } while (0)
2787 documentPolicy, resultPolicy, compareResult))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch - " "doc:%d result:%d - compare:%d\n"
, documentPolicy, resultPolicy, compareResult); } } while (0)
;
2788 nsAutoCString docOrigin("(null)");
2789 nsCOMPtr<nsIURI> uri = documentOrigin->GetURI();
2790 if (uri) {
2791 uri->GetSpec(docOrigin);
2792 }
2793 nsAutoCString resOrigin("(null)");
2794 uri = resultOrigin->GetURI();
2795 if (uri) {
2796 uri->GetSpec(resOrigin);
2797 }
2798 LOG(("doc origin:%s - res origin: %s\n", docOrigin.get(), resOrigin.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
, "doc origin:%s - res origin: %s\n", docOrigin.get(), resOrigin
.get()); } } while (0)
;
2799 }
2800
2801 if (compareResult) {
2802 return NS_OK;
2803 }
2804
2805 // If one of the following is false:
2806 // - document's policy is same-origin-allow-popups
2807 // - resultPolicy is null
2808 // - doc is the initial about:blank document
2809 // then we have a mismatch.
2810
2811 if (documentPolicy != nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_ALLOW_POPUPS) {
2812 StoreHasCrossOriginOpenerPolicyMismatch(true);
2813 return NS_OK;
2814 }
2815
2816 if (resultPolicy != nsILoadInfo::OPENER_POLICY_UNSAFE_NONE) {
2817 StoreHasCrossOriginOpenerPolicyMismatch(true);
2818 return NS_OK;
2819 }
2820
2821 if (!currentWindowGlobal->IsInitialDocument()) {
2822 StoreHasCrossOriginOpenerPolicyMismatch(true);
2823 return NS_OK;
2824 }
2825
2826 return NS_OK;
2827}
2828
2829nsresult HttpBaseChannel::ProcessCrossOriginSecurityHeaders() {
2830 StoreProcessCrossOriginSecurityHeadersCalled(true);
2831 nsresult rv = ProcessCrossOriginEmbedderPolicyHeader();
2832 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2833 return rv;
2834 }
2835 rv = ProcessCrossOriginResourcePolicyHeader();
2836 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
2837 return rv;
2838 }
2839 return ComputeCrossOriginOpenerPolicyMismatch();
2840}
2841
2842enum class Report { Error, Warning };
2843
2844// Helper Function to report messages to the console when the loaded
2845// script had a wrong MIME type.
2846void ReportMimeTypeMismatch(HttpBaseChannel* aChannel, const char* aMessageName,
2847 nsIURI* aURI, const nsACString& aContentType,
2848 Report report) {
2849 NS_ConvertUTF8toUTF16 spec(aURI->GetSpecOrDefault());
2850 NS_ConvertUTF8toUTF16 contentType(aContentType);
2851
2852 aChannel->LogMimeTypeMismatch(nsCString(aMessageName),
2853 report == Report::Warning, spec, contentType);
2854}
2855
2856// Check and potentially enforce X-Content-Type-Options: nosniff
2857nsresult ProcessXCTO(HttpBaseChannel* aChannel, nsIURI* aURI,
2858 nsHttpResponseHead* aResponseHead,
2859 nsILoadInfo* aLoadInfo) {
2860 if (!aURI || !aResponseHead || !aLoadInfo) {
2861 // if there is no uri, no response head or no loadInfo, then there is
2862 // nothing to do
2863 return NS_OK;
2864 }
2865
2866 // 1) Query the XCTO header and check if 'nosniff' is the first value.
2867 nsAutoCString contentTypeOptionsHeader;
2868 if (!aResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader)) {
2869 // if failed to get XCTO header, then there is nothing to do.
2870 return NS_OK;
2871 }
2872
2873 // let's compare the header (ignoring case)
2874 // e.g. "NoSniFF" -> "nosniff"
2875 // if it's not 'nosniff' then there is nothing to do here
2876 if (!contentTypeOptionsHeader.EqualsIgnoreCase("nosniff")) {
2877 // since we are getting here, the XCTO header was sent;
2878 // a non matching value most likely means a mistake happenend;
2879 // e.g. sending 'nosnif' instead of 'nosniff', let's log a warning.
2880 AutoTArray<nsString, 1> params;
2881 CopyUTF8toUTF16(contentTypeOptionsHeader, *params.AppendElement());
2882 RefPtr<dom::Document> doc;
2883 aLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
2884 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "XCTO"_ns, doc,
2885 nsContentUtils::eSECURITY_PROPERTIES,
2886 "XCTOHeaderValueMissing", params);
2887 return NS_OK;
2888 }
2889
2890 // 2) Query the content type from the channel
2891 nsAutoCString contentType;
2892 aResponseHead->ContentType(contentType);
2893
2894 // 3) Compare the expected MIME type with the actual type
2895 if (aLoadInfo->GetExternalContentPolicyType() ==
2896 ExtContentPolicy::TYPE_STYLESHEET) {
2897 if (contentType.EqualsLiteral(TEXT_CSS"text/css")) {
2898 return NS_OK;
2899 }
2900 ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
2901 Report::Error);
2902 return NS_ERROR_CORRUPTED_CONTENT;
2903 }
2904
2905 if (aLoadInfo->GetExternalContentPolicyType() ==
2906 ExtContentPolicy::TYPE_SCRIPT) {
2907 if (nsContentUtils::IsJavascriptMIMEType(
2908 NS_ConvertUTF8toUTF16(contentType))) {
2909 return NS_OK;
2910 }
2911 ReportMimeTypeMismatch(aChannel, "MimeTypeMismatch2", aURI, contentType,
2912 Report::Error);
2913 return NS_ERROR_CORRUPTED_CONTENT;
2914 }
2915
2916 auto policyType = aLoadInfo->GetExternalContentPolicyType();
2917 if (policyType == ExtContentPolicy::TYPE_DOCUMENT ||
2918 policyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
2919 // If the header XCTO nosniff is set for any browsing context, then
2920 // we set the skipContentSniffing flag on the Loadinfo. Within
2921 // GetMIMETypeFromContent we then bail early and do not do any sniffing.
2922 aLoadInfo->SetSkipContentSniffing(true);
2923 return NS_OK;
2924 }
2925
2926 return NS_OK;
2927}
2928
2929// Ensure that a load of type script has correct MIME type
2930nsresult EnsureMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
2931 nsHttpResponseHead* aResponseHead,
2932 nsILoadInfo* aLoadInfo) {
2933 if (!aURI || !aResponseHead || !aLoadInfo) {
2934 // if there is no uri, no response head or no loadInfo, then there is
2935 // nothing to do
2936 return NS_OK;
2937 }
2938
2939 if (aLoadInfo->GetExternalContentPolicyType() !=
2940 ExtContentPolicy::TYPE_SCRIPT) {
2941 // if this is not a script load, then there is nothing to do
2942 return NS_OK;
2943 }
2944
2945 nsAutoCString contentType;
2946 aResponseHead->ContentType(contentType);
2947 NS_ConvertUTF8toUTF16 typeString(contentType);
2948
2949 if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
2950 // script load has type script
2951 AccumulateCategorical(
2952 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::javaScript);
2953 return NS_OK;
2954 }
2955
2956 nsContentPolicyType internalType = aLoadInfo->InternalContentPolicyType();
2957 bool isModule =
2958 internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE ||
2959 internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD;
2960
2961 if (isModule && nsContentUtils::IsJsonMimeType(typeString)) {
2962 AccumulateCategorical(
2963 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::javaScript);
2964 return NS_OK;
2965 }
2966
2967 switch (aLoadInfo->InternalContentPolicyType()) {
2968 case nsIContentPolicy::TYPE_SCRIPT:
2969 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT:
2970 case nsIContentPolicy::TYPE_INTERNAL_SCRIPT_PRELOAD:
2971 case nsIContentPolicy::TYPE_INTERNAL_MODULE:
2972 case nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD:
2973 case nsIContentPolicy::TYPE_INTERNAL_CHROMEUTILS_COMPILED_SCRIPT:
2974 case nsIContentPolicy::TYPE_INTERNAL_FRAME_MESSAGEMANAGER_SCRIPT:
2975 AccumulateCategorical(
2976 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::script_load);
2977 break;
2978 case nsIContentPolicy::TYPE_INTERNAL_WORKER:
2979 case nsIContentPolicy::TYPE_INTERNAL_WORKER_STATIC_MODULE:
2980 case nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER:
2981 AccumulateCategorical(
2982 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worker_load);
2983 break;
2984 case nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER:
2985 AccumulateCategorical(
2986 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::serviceworker_load);
2987 break;
2988 case nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS:
2989 AccumulateCategorical(
2990 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::importScript_load);
2991 break;
2992 case nsIContentPolicy::TYPE_INTERNAL_AUDIOWORKLET:
2993 case nsIContentPolicy::TYPE_INTERNAL_PAINTWORKLET:
2994 AccumulateCategorical(
2995 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::worklet_load);
2996 break;
2997 default:
2998 MOZ_ASSERT_UNREACHABLE("unexpected script type")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 script type" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 2998); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "unexpected script type" ")"); do
{ *((volatile int*)__null) = 2998; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
2999 break;
3000 }
3001
3002 if (aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(aURI)) {
3003 // same origin
3004 AccumulateCategorical(
3005 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::same_origin);
3006 } else {
3007 bool cors = false;
3008 nsAutoCString corsOrigin;
3009 nsresult rv = aResponseHead->GetHeader(
3010 nsHttp::ResolveAtom("Access-Control-Allow-Origin"_ns), corsOrigin);
3011 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3012 if (corsOrigin.Equals("*")) {
3013 cors = true;
3014 } else {
3015 nsCOMPtr<nsIURI> corsOriginURI;
3016 rv = NS_NewURI(getter_AddRefs(corsOriginURI), corsOrigin);
3017 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
3018 if (aLoadInfo->GetLoadingPrincipal()->IsSameOrigin(corsOriginURI)) {
3019 cors = true;
3020 }
3021 }
3022 }
3023 }
3024 if (cors) {
3025 // cors origin
3026 AccumulateCategorical(
3027 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::CORS_origin);
3028 } else {
3029 // cross origin
3030 AccumulateCategorical(
3031 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::cross_origin);
3032 }
3033 }
3034
3035 bool block = false;
3036 if (StringBeginsWith(contentType, "image/"_ns)) {
3037 // script load has type image
3038 AccumulateCategorical(
3039 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::image);
3040 block = true;
3041 } else if (StringBeginsWith(contentType, "audio/"_ns)) {
3042 // script load has type audio
3043 AccumulateCategorical(
3044 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::audio);
3045 block = true;
3046 } else if (StringBeginsWith(contentType, "video/"_ns)) {
3047 // script load has type video
3048 AccumulateCategorical(
3049 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::video);
3050 block = true;
3051 } else if (StringBeginsWith(contentType, "text/csv"_ns)) {
3052 // script load has type text/csv
3053 AccumulateCategorical(
3054 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_csv);
3055 block = true;
3056 }
3057
3058 if (block) {
3059 ReportMimeTypeMismatch(aChannel, "BlockScriptWithWrongMimeType2", aURI,
3060 contentType, Report::Error);
3061 return NS_ERROR_CORRUPTED_CONTENT;
3062 }
3063
3064 if (StringBeginsWith(contentType, "text/plain"_ns)) {
3065 // script load has type text/plain
3066 AccumulateCategorical(
3067 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_plain);
3068 } else if (StringBeginsWith(contentType, "text/xml"_ns)) {
3069 // script load has type text/xml
3070 AccumulateCategorical(
3071 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_xml);
3072 } else if (StringBeginsWith(contentType, "application/octet-stream"_ns)) {
3073 // script load has type application/octet-stream
3074 AccumulateCategorical(
3075 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_octet_stream);
3076 } else if (StringBeginsWith(contentType, "application/xml"_ns)) {
3077 // script load has type application/xml
3078 AccumulateCategorical(
3079 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_xml);
3080 } else if (StringBeginsWith(contentType, "application/json"_ns)) {
3081 // script load has type application/json
3082 AccumulateCategorical(
3083 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::app_json);
3084 } else if (StringBeginsWith(contentType, "text/json"_ns)) {
3085 // script load has type text/json
3086 AccumulateCategorical(
3087 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_json);
3088 } else if (StringBeginsWith(contentType, "text/html"_ns)) {
3089 // script load has type text/html
3090 AccumulateCategorical(
3091 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::text_html);
3092 } else if (contentType.IsEmpty()) {
3093 // script load has no type
3094 AccumulateCategorical(
3095 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::empty);
3096 } else {
3097 // script load has unknown type
3098 AccumulateCategorical(
3099 Telemetry::LABELS_SCRIPT_BLOCK_INCORRECT_MIME_3::unknown);
3100 }
3101
3102 // We restrict importScripts() in worker code to JavaScript MIME types.
3103 if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_IMPORT_SCRIPTS ||
3104 internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER_STATIC_MODULE) {
3105 ReportMimeTypeMismatch(aChannel, "BlockImportScriptsWithWrongMimeType",
3106 aURI, contentType, Report::Error);
3107 return NS_ERROR_CORRUPTED_CONTENT;
3108 }
3109
3110 if (internalType == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
3111 internalType == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
3112 // Do not block the load if the feature is not enabled.
3113 if (!StaticPrefs::security_block_Worker_with_wrong_mime()) {
3114 return NS_OK;
3115 }
3116
3117 ReportMimeTypeMismatch(aChannel, "BlockWorkerWithWrongMimeType", aURI,
3118 contentType, Report::Error);
3119 return NS_ERROR_CORRUPTED_CONTENT;
3120 }
3121
3122 // ES6 modules require a strict MIME type check.
3123 if (isModule) {
3124 ReportMimeTypeMismatch(aChannel, "BlockModuleWithWrongMimeType", aURI,
3125 contentType, Report::Error);
3126 return NS_ERROR_CORRUPTED_CONTENT;
3127 }
3128
3129 return NS_OK;
3130}
3131
3132// Warn when a load of type script uses a wrong MIME type and
3133// wasn't blocked by EnsureMIMEOfScript or ProcessXCTO.
3134void WarnWrongMIMEOfScript(HttpBaseChannel* aChannel, nsIURI* aURI,
3135 nsHttpResponseHead* aResponseHead,
3136 nsILoadInfo* aLoadInfo) {
3137 if (!aURI || !aResponseHead || !aLoadInfo) {
3138 // If there is no uri, no response head or no loadInfo, then there is
3139 // nothing to do.
3140 return;
3141 }
3142
3143 if (aLoadInfo->GetExternalContentPolicyType() !=
3144 ExtContentPolicy::TYPE_SCRIPT) {
3145 // If this is not a script load, then there is nothing to do.
3146 return;
3147 }
3148
3149 bool succeeded;
3150 MOZ_ALWAYS_SUCCEEDS(aChannel->GetRequestSucceeded(&succeeded))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(aChannel->GetRequestSucceeded(&succeeded))), 1)))), 1
))) { } else { do { do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(aChannel->GetRequestSucceeded(&succeeded))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3150); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(aChannel->GetRequestSucceeded(&succeeded))"
")"); do { *((volatile int*)__null) = 3150; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
3151 if (!succeeded) {
3152 // Do not warn for failed loads: HTTP error pages are usually in HTML.
3153 return;
3154 }
3155
3156 nsAutoCString contentType;
3157 aResponseHead->ContentType(contentType);
3158 NS_ConvertUTF8toUTF16 typeString(contentType);
3159
3160 if (nsContentUtils::IsJavascriptMIMEType(typeString)) {
3161 return;
3162 }
3163
3164 nsContentPolicyType internalType = aLoadInfo->InternalContentPolicyType();
3165 bool isModule =
3166 internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE ||
3167 internalType == nsIContentPolicy::TYPE_INTERNAL_MODULE_PRELOAD;
3168 if (isModule && nsContentUtils::IsJsonMimeType(typeString)) {
3169 return;
3170 }
3171
3172 ReportMimeTypeMismatch(aChannel, "WarnScriptWithWrongMimeType", aURI,
3173 contentType, Report::Warning);
3174}
3175
3176nsresult HttpBaseChannel::ValidateMIMEType() {
3177 nsresult rv = EnsureMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
3178 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3179 return rv;
3180 }
3181
3182 rv = ProcessXCTO(this, mURI, mResponseHead.get(), mLoadInfo);
3183 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
3184 return rv;
3185 }
3186
3187 WarnWrongMIMEOfScript(this, mURI, mResponseHead.get(), mLoadInfo);
3188 return NS_OK;
3189}
3190
3191bool HttpBaseChannel::ShouldFilterOpaqueResponse(
3192 OpaqueResponseFilterFetch aFilterType) const {
3193 MOZ_ASSERT(ShouldBlockOpaqueResponse())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ShouldBlockOpaqueResponse())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(ShouldBlockOpaqueResponse())
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("ShouldBlockOpaqueResponse()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3193); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ShouldBlockOpaqueResponse()"
")"); do { *((volatile int*)__null) = 3193; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3194
3195 if (!mLoadInfo || ConfiguredFilterFetchResponseBehaviour() != aFilterType) {
3196 return false;
3197 }
3198
3199 // We should filter a response in the parent if it is opaque and is the result
3200 // of a fetch() function from the Fetch specification.
3201 return mLoadInfo->InternalContentPolicyType() == nsIContentPolicy::TYPE_FETCH;
3202}
3203
3204bool HttpBaseChannel::ShouldBlockOpaqueResponse() const {
3205 if (!mURI || !mResponseHead || !mLoadInfo) {
3206 // if there is no uri, no response head or no loadInfo, then there is
3207 // nothing to do
3208 LOGORB("No block: no mURI, mResponseHead, or mLoadInfo")do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " "No block: no mURI, mResponseHead, or mLoadInfo"
, __func__, this); } } while (0)
;
3209 return false;
3210 }
3211
3212 nsCOMPtr<nsIPrincipal> principal = mLoadInfo->GetLoadingPrincipal();
3213 if (!principal || principal->IsSystemPrincipal()) {
3214 // If it's a top-level load or a system principal, then there is nothing to
3215 // do.
3216 LOGORB("No block: top-level load or system principal")do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " "No block: top-level load or system principal"
, __func__, this); } } while (0)
;
3217 return false;
3218 }
3219
3220 // Check if the response is a opaque response, which means requestMode should
3221 // be RequestMode::No_cors and responseType should be ResponseType::Opaque.
3222 nsContentPolicyType contentPolicy = mLoadInfo->InternalContentPolicyType();
3223
3224 // Skip the RequestMode would be RequestMode::Navigate
3225 if (contentPolicy == nsIContentPolicy::TYPE_DOCUMENT ||
3226 contentPolicy == nsIContentPolicy::TYPE_SUBDOCUMENT ||
3227 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_FRAME ||
3228 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_IFRAME ||
3229 // Skip the RequestMode would be RequestMode::Same_origin
3230 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_WORKER ||
3231 contentPolicy == nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER) {
3232 return false;
3233 }
3234
3235 uint32_t securityMode = mLoadInfo->GetSecurityMode();
3236 // Skip when RequestMode would not be RequestMode::no_cors
3237 if (securityMode !=
3238 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT &&
3239 securityMode != nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL) {
3240 LOGORB("No block: not no_cors requests")do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " "No block: not no_cors requests"
, __func__, this); } } while (0)
;
3241 return false;
3242 }
3243
3244 // Only continue when ResponseType would be ResponseType::Opaque
3245 if (mLoadInfo->GetTainting() != mozilla::LoadTainting::Opaque) {
3246 LOGORB("No block: not opaque response")do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " "No block: not opaque response",
__func__, this); } } while (0)
;
3247 return false;
3248 }
3249
3250 auto extContentPolicyType = mLoadInfo->GetExternalContentPolicyType();
3251 if (extContentPolicyType == ExtContentPolicy::TYPE_OBJECT ||
3252 extContentPolicyType == ExtContentPolicy::TYPE_OBJECT_SUBREQUEST ||
3253 extContentPolicyType == ExtContentPolicy::TYPE_WEBSOCKET ||
3254 extContentPolicyType == ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD) {
3255 LOGORB("No block: object || websocket request || save as download")do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " "No block: object || websocket request || save as download"
, __func__, this); } } while (0)
;
3256 return false;
3257 }
3258
3259 // Ignore the request from object or embed elements
3260 if (mLoadInfo->GetIsFromObjectOrEmbed()) {
3261 LOGORB("No block: Request From <object> or <embed>")do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " "No block: Request From <object> or <embed>"
, __func__, this); } } while (0)
;
3262 return false;
3263 }
3264
3265 // Exclude no_cors System XHR
3266 if (extContentPolicyType == ExtContentPolicy::TYPE_XMLHTTPREQUEST) {
3267 if (securityMode ==
3268 nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_INHERITS_SEC_CONTEXT) {
3269 LOGORB("No block: System XHR")do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " "No block: System XHR", __func__
, this); } } while (0)
;
3270 return false;
3271 }
3272 }
3273
3274 uint32_t httpsOnlyStatus = mLoadInfo->GetHttpsOnlyStatus();
3275 if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_BYPASS_ORB) {
3276 LOGORB("No block: HTTPS_ONLY_BYPASS_ORB")do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " "No block: HTTPS_ONLY_BYPASS_ORB"
, __func__, this); } } while (0)
;
3277 return false;
3278 }
3279
3280 bool isInDevToolsContext;
3281 mLoadInfo->GetIsInDevToolsContext(&isInDevToolsContext);
3282 if (isInDevToolsContext) {
3283 LOGORB("No block: Request created by devtools")do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " "No block: Request created by devtools"
, __func__, this); } } while (0)
;
3284 return false;
3285 }
3286
3287 return true;
3288}
3289
3290OpaqueResponse HttpBaseChannel::BlockOrFilterOpaqueResponse(
3291 OpaqueResponseBlocker* aORB, const nsAString& aReason,
3292 const OpaqueResponseBlockedTelemetryReason aTelemetryReason,
3293 const char* aFormat, ...) {
3294 NimbusFeatures::RecordExposureEvent("opaqueResponseBlocking"_ns, true);
3295
3296 const bool shouldFilter =
3297 ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::BlockedByORB);
3298
3299 if (MOZ_UNLIKELY(MOZ_LOG_TEST(GetORBLog(), LogLevel::Debug))(__builtin_expect(!!((__builtin_expect(!!(mozilla::detail::log_test
(GetORBLog(), LogLevel::Debug)), 0))), 0))
) {
3300 va_list ap;
3301 va_start(ap, aFormat)__builtin_va_start(ap, aFormat);
3302 nsVprintfCString logString(aFormat, ap);
3303 va_end(ap)__builtin_va_end(ap);
3304
3305 LOGORB("%s: %s", shouldFilter ? "Filtered" : "Blocked", logString.get())do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " "%s: %s", __func__, this, shouldFilter
? "Filtered" : "Blocked", logString.get()); } } while (0)
;
3306 }
3307
3308 if (shouldFilter) {
3309 Telemetry::AccumulateCategorical(
3310 Telemetry::LABELS_ORB_BLOCK_INITIATOR::FILTERED_FETCH);
3311 // The existence of `mORB` depends on `BlockOrFilterOpaqueResponse` being
3312 // called before or after sniffing has completed.
3313 // Another requirement is that `OpaqueResponseFilter` must come after
3314 // `OpaqueResponseBlocker`, which is why in the case of having an
3315 // `OpaqueResponseBlocker` we let it handle creating an
3316 // `OpaqueResponseFilter`.
3317 if (aORB) {
3318 MOZ_DIAGNOSTIC_ASSERT(!mORB || aORB == mORB)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mORB || aORB == mORB)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mORB || aORB == mORB))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!mORB || aORB == mORB"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3318); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!mORB || aORB == mORB"
")"); do { *((volatile int*)__null) = 3318; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3319 aORB->FilterResponse();
3320 } else {
3321 mListener = new OpaqueResponseFilter(mListener);
3322 }
3323 return OpaqueResponse::Allow;
3324 }
3325
3326 LogORBError(aReason, aTelemetryReason);
3327 return OpaqueResponse::Block;
3328}
3329
3330// The specification for ORB is currently being written:
3331// https://whatpr.org/fetch/1442.html#orb-algorithm
3332// The `opaque-response-safelist check` is implemented in:
3333// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff`
3334// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3335// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
3336// * `OpaqueResponseBlocker::ValidateJavaScript`
3337OpaqueResponse
3338HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff() {
3339 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/HttpBaseChannel.cpp"
, 3339); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 3339; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3340
3341 // https://whatpr.org/fetch/1442.html#http-fetch, step 6.4
3342 if (!ShouldBlockOpaqueResponse()) {
3343 return OpaqueResponse::Allow;
3344 }
3345
3346 // Regardless of if ORB is enabled or not, we check if we should filter the
3347 // response in the parent. This way data won't reach a content process that
3348 // will create a filtered `Response` object. This is enabled when
3349 // 'browser.opaqueResponseBlocking.filterFetchResponse' is
3350 // `OpaqueResponseFilterFetch::All`.
3351 // See https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
3352 if (ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::All)) {
3353 mListener = new OpaqueResponseFilter(mListener);
3354
3355 // If we're filtering a response in the parent, there will be no data to
3356 // determine if it should be blocked or not so the only option we have is to
3357 // allow it.
3358 return OpaqueResponse::Allow;
3359 }
3360
3361 if (!mCachedOpaqueResponseBlockingPref) {
3362 return OpaqueResponse::Allow;
3363 }
3364
3365 // If ORB is enabled, we check if we should filter the response in the parent.
3366 // This way data won't reach a content process that will create a filtered
3367 // `Response` object. We allow ORB to determine if the response should be
3368 // blocked or filtered, but regardless no data should reach the content
3369 // process. This is enabled when
3370 // 'browser.opaqueResponseBlocking.filterFetchResponse' is
3371 // `OpaqueResponseFilterFetch::AllowedByORB`.
3372 // See https://fetch.spec.whatwg.org/#concept-filtered-response-opaque
3373 if (ShouldFilterOpaqueResponse(OpaqueResponseFilterFetch::AllowedByORB)) {
3374 mListener = new OpaqueResponseFilter(mListener);
3375 }
3376
3377 glean::opaque_response_blocking::cross_origin_opaque_response_count.Add(1);
3378
3379 PROFILER_MARKER_TEXT("ORB safelist check", NETWORK, {}, "Before sniff"_ns)do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("ORB safelist check", ::geckoprofiler::category::NETWORK, {}
, ::geckoprofiler::markers::TextMarker{}, "Before sniff"_ns);
} } while (false); } while (false)
;
3380
3381 // https://whatpr.org/fetch/1442.html#orb-algorithm
3382 // Step 1
3383 nsAutoCString contentType;
3384 mResponseHead->ContentType(contentType);
3385
3386 // Step 2
3387 nsAutoCString contentTypeOptionsHeader;
3388 bool nosniff =
3389 mResponseHead->GetContentTypeOptionsHeader(contentTypeOptionsHeader) &&
3390 contentTypeOptionsHeader.EqualsIgnoreCase("nosniff");
3391
3392 // Step 3
3393 switch (GetOpaqueResponseBlockedReason(contentType, mResponseHead->Status(),
3394 nosniff)) {
3395 case OpaqueResponseBlockedReason::ALLOWED_SAFE_LISTED:
3396 // Step 3.1
3397 return OpaqueResponse::Allow;
3398 case OpaqueResponseBlockedReason::ALLOWED_SAFE_LISTED_SPEC_BREAKING:
3399 LOGORB("Allowed %s in a spec breaking way", contentType.get())do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " "Allowed %s in a spec breaking way"
, __func__, this, contentType.get()); } } while (0)
;
3400 return OpaqueResponse::Allow;
3401 case OpaqueResponseBlockedReason::BLOCKED_BLOCKLISTED_NEVER_SNIFFED:
3402 return BlockOrFilterOpaqueResponse(
3403 mORB, u"mimeType is an opaque-blocklisted-never-sniffed MIME type"_ns,
3404 OpaqueResponseBlockedTelemetryReason::MIME_NEVER_SNIFFED,
3405 "BLOCKED_BLOCKLISTED_NEVER_SNIFFED");
3406 case OpaqueResponseBlockedReason::BLOCKED_206_AND_BLOCKLISTED:
3407 // Step 3.3
3408 return BlockOrFilterOpaqueResponse(
3409 mORB,
3410 u"response's status is 206 and mimeType is an opaque-blocklisted MIME type"_ns,
3411 OpaqueResponseBlockedTelemetryReason::RESP_206_BLCLISTED,
3412 "BLOCKED_206_AND_BLOCKEDLISTED");
3413 case OpaqueResponseBlockedReason::
3414 BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN:
3415 // Step 3.4
3416 return BlockOrFilterOpaqueResponse(
3417 mORB,
3418 u"nosniff is true and mimeType is an opaque-blocklisted MIME type or its essence is 'text/plain'"_ns,
3419 OpaqueResponseBlockedTelemetryReason::NOSNIFF_BLC_OR_TEXTP,
3420 "BLOCKED_NOSNIFF_AND_EITHER_BLOCKLISTED_OR_TEXTPLAIN");
3421 default:
3422 break;
3423 }
3424
3425 // Step 4
3426 // If it's a media subsequent request, we assume that it will only be made
3427 // after a successful initial request.
3428 bool isMediaRequest;
3429 mLoadInfo->GetIsMediaRequest(&isMediaRequest);
3430 if (isMediaRequest) {
3431 bool isMediaInitialRequest;
3432 mLoadInfo->GetIsMediaInitialRequest(&isMediaInitialRequest);
3433 if (!isMediaInitialRequest) {
3434 return OpaqueResponse::Allow;
3435 }
3436 }
3437
3438 // Step 5
3439 if (mResponseHead->Status() == 206 &&
3440 !IsFirstPartialResponse(*mResponseHead)) {
3441 return BlockOrFilterOpaqueResponse(
3442 mORB, u"response status is 206 and not first partial response"_ns,
3443 OpaqueResponseBlockedTelemetryReason::RESP_206_BLCLISTED,
3444 "Is not a valid partial response given 0");
3445 }
3446
3447 // Setup for steps 6, 7, 8 and 10.
3448 // Steps 6 and 7 are handled by the sniffer framework.
3449 // Steps 8 and 10 by are handled by
3450 // `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3451 if (mLoadFlags & nsIChannel::LOAD_CALL_CONTENT_SNIFFERS) {
3452 mSnifferCategoryType = SnifferCategoryType::All;
3453 } else {
3454 mSnifferCategoryType = SnifferCategoryType::OpaqueResponseBlocking;
3455 }
3456
3457 mLoadFlags |= (nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
3458 nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE);
3459
3460 // Install an input stream listener that performs ORB checks that depend on
3461 // inspecting the incoming data. It is crucial that `OnStartRequest` is called
3462 // on this listener either after sniffing is completed or that we skip
3463 // sniffing, otherwise `OpaqueResponseBlocker` will allow responses that it
3464 // shouldn't.
3465 mORB = new OpaqueResponseBlocker(mListener, this, contentType, nosniff);
3466 mListener = mORB;
3467
3468 nsAutoCString contentEncoding;
3469 nsresult rv =
3470 mResponseHead->GetHeader(nsHttp::Content_Encoding, contentEncoding);
3471
3472 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !contentEncoding.IsEmpty()) {
3473 return OpaqueResponse::SniffCompressed;
3474 }
3475 mLoadFlags |= (nsIChannel::LOAD_CALL_CONTENT_SNIFFERS |
3476 nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE);
3477 return OpaqueResponse::Sniff;
3478}
3479
3480// The specification for ORB is currently being written:
3481// https://whatpr.org/fetch/1442.html#orb-algorithm
3482// The `opaque-response-safelist check` is implemented in:
3483// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckBeforeSniff`
3484// * `nsHttpChannel::DisableIsOpaqueResponseAllowedAfterSniffCheck`
3485// * `HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff`
3486// * `OpaqueResponseBlocker::ValidateJavaScript`
3487OpaqueResponse HttpBaseChannel::PerformOpaqueResponseSafelistCheckAfterSniff(
3488 const nsACString& aContentType, bool aNoSniff) {
3489 PROFILER_MARKER_TEXT("ORB safelist check", NETWORK, {}, "After sniff"_ns)do { ; do { if (profiler_is_collecting_markers()) { ::profiler_add_marker_impl
("ORB safelist check", ::geckoprofiler::category::NETWORK, {}
, ::geckoprofiler::markers::TextMarker{}, "After sniff"_ns); }
} while (false); } while (false)
;
3490
3491 // https://whatpr.org/fetch/1442.html#orb-algorithm
3492 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/HttpBaseChannel.cpp"
, 3492); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 3492; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3493 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/HttpBaseChannel.cpp"
, 3493); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCachedOpaqueResponseBlockingPref"
")"); do { *((volatile int*)__null) = 3493; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3494
3495 // Step 9
3496 bool isMediaRequest;
3497 mLoadInfo->GetIsMediaRequest(&isMediaRequest);
3498 if (isMediaRequest) {
3499 return BlockOrFilterOpaqueResponse(
3500 mORB, u"after sniff: media request"_ns,
3501 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_MEDIA,
3502 "media request");
3503 }
3504
3505 // Step 11
3506 if (aNoSniff) {
3507 return BlockOrFilterOpaqueResponse(
3508 mORB, u"after sniff: nosniff is true"_ns,
3509 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_NOSNIFF, "nosniff");
3510 }
3511
3512 // Step 12
3513 if (mResponseHead &&
3514 (mResponseHead->Status() < 200 || mResponseHead->Status() > 299)) {
3515 return BlockOrFilterOpaqueResponse(
3516 mORB, u"after sniff: status code is not in allowed range"_ns,
3517 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_STA_CODE,
3518 "status code (%d) is not allowed", mResponseHead->Status());
3519 }
3520
3521 // Step 13
3522 if (!mResponseHead || aContentType.IsEmpty()) {
3523 LOGORB("Allowed: mimeType is failure")do { const ::mozilla::LogModule* moz_real_module = GetORBLog(
); if ((__builtin_expect(!!(mozilla::detail::log_test(moz_real_module
, LogLevel::Debug)), 0))) { mozilla::detail::log_print(moz_real_module
, LogLevel::Debug, "%s: %p " "Allowed: mimeType is failure", __func__
, this); } } while (0)
;
3524 return OpaqueResponse::Allow;
3525 }
3526
3527 // Step 14
3528 if (StringBeginsWith(aContentType, "image/"_ns) ||
3529 StringBeginsWith(aContentType, "video/"_ns) ||
3530 StringBeginsWith(aContentType, "audio/"_ns)) {
3531 return BlockOrFilterOpaqueResponse(
3532 mORB,
3533 u"after sniff: content-type declares image/video/audio, but sniffing fails"_ns,
3534 OpaqueResponseBlockedTelemetryReason::AFTER_SNIFF_CT_FAIL,
3535 "ContentType is image/video/audio");
3536 }
3537
3538 return OpaqueResponse::Sniff;
3539}
3540
3541bool HttpBaseChannel::NeedOpaqueResponseAllowedCheckAfterSniff() const {
3542 return mORB ? mORB->IsSniffing() : false;
3543}
3544
3545void HttpBaseChannel::BlockOpaqueResponseAfterSniff(
3546 const nsAString& aReason,
3547 const OpaqueResponseBlockedTelemetryReason aTelemetryReason) {
3548 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/HttpBaseChannel.cpp"
, 3548); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mORB"
")"); do { *((volatile int*)__null) = 3548; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3549 LogORBError(aReason, aTelemetryReason);
3550 mORB->BlockResponse(this, NS_BINDING_ABORTED);
3551}
3552
3553void HttpBaseChannel::AllowOpaqueResponseAfterSniff() {
3554 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/HttpBaseChannel.cpp"
, 3554); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "mORB"
")"); do { *((volatile int*)__null) = 3554; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3555 mORB->AllowResponse();
3556}
3557
3558void HttpBaseChannel::SetChannelBlockedByOpaqueResponse() {
3559 mChannelBlockedByOpaqueResponse = true;
3560
3561 RefPtr<dom::BrowsingContext> browsingContext =
3562 dom::BrowsingContext::GetCurrentTopByBrowserId(mBrowserId);
3563 if (!browsingContext) {
3564 return;
3565 }
3566
3567 dom::WindowContext* windowContext = browsingContext->GetTopWindowContext();
3568 if (windowContext) {
3569 windowContext->Canonical()->SetShouldReportHasBlockedOpaqueResponse(
3570 mLoadInfo->InternalContentPolicyType());
3571 }
3572}
3573
3574NS_IMETHODIMPnsresult
3575HttpBaseChannel::SetCookieHeaders(const nsTArray<nsCString>& aCookieHeaders) {
3576 if (mLoadFlags & LOAD_ANONYMOUS) return NS_OK;
3577
3578 if (IsBrowsingContextDiscarded()) {
3579 return NS_OK;
3580 }
3581
3582 // empty header isn't an error
3583 if (aCookieHeaders.IsEmpty()) {
3584 return NS_OK;
3585 }
3586
3587 nsICookieService* cs = gHttpHandler->GetCookieService();
3588 NS_ENSURE_TRUE(cs, NS_ERROR_FAILURE)do { if ((__builtin_expect(!!(!(cs)), 0))) { NS_DebugBreak(NS_DEBUG_WARNING
, "NS_ENSURE_TRUE(" "cs" ") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3588); return NS_ERROR_FAILURE; } } while (false)
;
3589
3590 for (const nsCString& cookieHeader : aCookieHeaders) {
3591 nsresult rv = cs->SetCookieStringFromHttp(mURI, cookieHeader, this);
3592 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/HttpBaseChannel.cpp"
, 3592); return rv; } } while (false)
;
3593 }
3594
3595 return NS_OK;
3596}
3597
3598NS_IMETHODIMPnsresult
3599HttpBaseChannel::GetThirdPartyFlags(uint32_t* aFlags) {
3600 *aFlags = LoadThirdPartyFlags();
3601 return NS_OK;
3602}
3603
3604NS_IMETHODIMPnsresult
3605HttpBaseChannel::SetThirdPartyFlags(uint32_t aFlags) {
3606 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/HttpBaseChannel.cpp"
, 3606); 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/HttpBaseChannel.cpp"
, 3606, 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/HttpBaseChannel.cpp"
, 3606); } } 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/HttpBaseChannel.cpp"
, 3606); 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/HttpBaseChannel.cpp"
, 3606); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
3607
3608 StoreThirdPartyFlags(aFlags);
3609 return NS_OK;
3610}
3611
3612NS_IMETHODIMPnsresult
3613HttpBaseChannel::GetForceAllowThirdPartyCookie(bool* aForce) {
3614 *aForce = !!(LoadThirdPartyFlags() &
3615 nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3616 return NS_OK;
3617}
3618
3619NS_IMETHODIMPnsresult
3620HttpBaseChannel::SetForceAllowThirdPartyCookie(bool aForce) {
3621 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/HttpBaseChannel.cpp"
, 3621); 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/HttpBaseChannel.cpp"
, 3621, 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/HttpBaseChannel.cpp"
, 3621); } } 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/HttpBaseChannel.cpp"
, 3621); 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/HttpBaseChannel.cpp"
, 3621); return NS_ERROR_ALREADY_OPENED; } } while (false); }
while (0)
;
3622
3623 if (aForce) {
3624 StoreThirdPartyFlags(LoadThirdPartyFlags() |
3625 nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3626 } else {
3627 StoreThirdPartyFlags(LoadThirdPartyFlags() &
3628 ~nsIHttpChannelInternal::THIRD_PARTY_FORCE_ALLOW);
3629 }
3630
3631 return NS_OK;
3632}
3633
3634NS_IMETHODIMPnsresult
3635HttpBaseChannel::GetCanceled(bool* aCanceled) {
3636 *aCanceled = mCanceled;
3637 return NS_OK;
3638}
3639
3640NS_IMETHODIMPnsresult
3641HttpBaseChannel::GetChannelIsForDownload(bool* aChannelIsForDownload) {
3642 *aChannelIsForDownload = LoadChannelIsForDownload();
3643 return NS_OK;
3644}
3645
3646NS_IMETHODIMPnsresult
3647HttpBaseChannel::SetChannelIsForDownload(bool aChannelIsForDownload) {
3648 StoreChannelIsForDownload(aChannelIsForDownload);
3649 return NS_OK;
3650}
3651
3652NS_IMETHODIMPnsresult
3653HttpBaseChannel::SetCacheKeysRedirectChain(nsTArray<nsCString>* cacheKeys) {
3654 auto RedirectedCachekeys = mRedirectedCachekeys.Lock();
3655 auto& ref = RedirectedCachekeys.ref();
3656 ref = WrapUnique(cacheKeys);
3657 return NS_OK;
3658}
3659
3660NS_IMETHODIMPnsresult
3661HttpBaseChannel::GetLocalAddress(nsACString& addr) {
3662 if (mSelfAddr.raw.family == PR_AF_UNSPEC0) return NS_ERROR_NOT_AVAILABLE;
3663
3664 addr.SetLength(kIPv6CStrBufSize);
3665 mSelfAddr.ToStringBuffer(addr.BeginWriting(), kIPv6CStrBufSize);
3666 addr.SetLength(strlen(addr.BeginReading()));
3667
3668 return NS_OK;
3669}
3670
3671NS_IMETHODIMPnsresult
3672HttpBaseChannel::TakeAllSecurityMessages(
3673 nsCOMArray<nsISecurityConsoleMessage>& aMessages) {
3674 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/HttpBaseChannel.cpp"
, 3674); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3674; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3675
3676 aMessages.Clear();
3677 for (const auto& pair : mSecurityConsoleMessages) {
3678 nsresult rv;
3679 nsCOMPtr<nsISecurityConsoleMessage> message =
3680 do_CreateInstance(NS_SECURITY_CONSOLE_MESSAGE_CONTRACTID"@mozilla.org/securityconsole/message;1", &rv);
3681 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/HttpBaseChannel.cpp"
, 3681); return rv; } } while (false)
;
3682
3683 message->SetTag(pair.first);
3684 message->SetCategory(pair.second);
3685 aMessages.AppendElement(message);
3686 }
3687
3688 MOZ_ASSERT(mSecurityConsoleMessages.Length() == aMessages.Length())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mSecurityConsoleMessages.Length() == aMessages.Length
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(mSecurityConsoleMessages.Length() == aMessages.Length
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("mSecurityConsoleMessages.Length() == aMessages.Length()", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3688); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mSecurityConsoleMessages.Length() == aMessages.Length()"
")"); do { *((volatile int*)__null) = 3688; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3689 mSecurityConsoleMessages.Clear();
3690
3691 return NS_OK;
3692}
3693
3694/* Please use this method with care. This can cause the message
3695 * queue to grow large and cause the channel to take up a lot
3696 * of memory. Use only static string messages and do not add
3697 * server side data to the queue, as that can be large.
3698 * Add only a limited number of messages to the queue to keep
3699 * the channel size down and do so only in rare erroneous situations.
3700 * More information can be found here:
3701 * https://bugzilla.mozilla.org/show_bug.cgi?id=846918
3702 */
3703nsresult HttpBaseChannel::AddSecurityMessage(
3704 const nsAString& aMessageTag, const nsAString& aMessageCategory) {
3705 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/HttpBaseChannel.cpp"
, 3705); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 3705; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3706
3707 nsresult rv;
3708
3709 // nsSecurityConsoleMessage is not thread-safe refcounted.
3710 // Delay the object construction until requested.
3711 // See TakeAllSecurityMessages()
3712 std::pair<nsString, nsString> pair(aMessageTag, aMessageCategory);
3713 mSecurityConsoleMessages.AppendElement(std::move(pair));
3714
3715 nsCOMPtr<nsIConsoleService> console(
3716 do_GetService(NS_CONSOLESERVICE_CONTRACTID"@mozilla.org/consoleservice;1"));
3717 if (!console) {
3718 return NS_ERROR_FAILURE;
3719 }
3720
3721 nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
3722
3723 auto innerWindowID = loadInfo->GetInnerWindowID();
3724
3725 nsAutoString errorText;
3726 rv = nsContentUtils::GetLocalizedString(
3727 nsContentUtils::eSECURITY_PROPERTIES,
3728 NS_ConvertUTF16toUTF8(aMessageTag).get(), errorText);
3729 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/HttpBaseChannel.cpp"
, 3729); return rv; } } while (false)
;
3730
3731 nsCOMPtr<nsIScriptError> error(do_CreateInstance(NS_SCRIPTERROR_CONTRACTID"@mozilla.org/scripterror;1"));
3732 error->InitWithSourceURI(errorText, mURI, 0, 0, nsIScriptError::warningFlag,
3733 NS_ConvertUTF16toUTF8(aMessageCategory),
3734 innerWindowID);
3735
3736 console->LogMessage(error);
3737
3738 return NS_OK;
3739}
3740
3741NS_IMETHODIMPnsresult
3742HttpBaseChannel::GetLocalPort(int32_t* port) {
3743 NS_ENSURE_ARG_POINTER(port)do { if ((__builtin_expect(!!(!(port)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "port" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3743); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3744
3745 if (mSelfAddr.raw.family == PR_AF_INET2) {
3746 *port = (int32_t)ntohs(mSelfAddr.inet.port)__bswap_16 (mSelfAddr.inet.port);
3747 } else if (mSelfAddr.raw.family == PR_AF_INET610) {
3748 *port = (int32_t)ntohs(mSelfAddr.inet6.port)__bswap_16 (mSelfAddr.inet6.port);
3749 } else {
3750 return NS_ERROR_NOT_AVAILABLE;
3751 }
3752
3753 return NS_OK;
3754}
3755
3756NS_IMETHODIMPnsresult
3757HttpBaseChannel::GetRemoteAddress(nsACString& addr) {
3758 if (mPeerAddr.raw.family == PR_AF_UNSPEC0) return NS_ERROR_NOT_AVAILABLE;
3759
3760 addr.SetLength(kIPv6CStrBufSize);
3761 mPeerAddr.ToStringBuffer(addr.BeginWriting(), kIPv6CStrBufSize);
3762 addr.SetLength(strlen(addr.BeginReading()));
3763
3764 return NS_OK;
3765}
3766
3767NS_IMETHODIMPnsresult
3768HttpBaseChannel::GetRemotePort(int32_t* port) {
3769 NS_ENSURE_ARG_POINTER(port)do { if ((__builtin_expect(!!(!(port)), 0))) { NS_DebugBreak(
NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "port" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3769); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3770
3771 if (mPeerAddr.raw.family == PR_AF_INET2) {
3772 *port = (int32_t)ntohs(mPeerAddr.inet.port)__bswap_16 (mPeerAddr.inet.port);
3773 } else if (mPeerAddr.raw.family == PR_AF_INET610) {
3774 *port = (int32_t)ntohs(mPeerAddr.inet6.port)__bswap_16 (mPeerAddr.inet6.port);
3775 } else {
3776 return NS_ERROR_NOT_AVAILABLE;
3777 }
3778
3779 return NS_OK;
3780}
3781
3782NS_IMETHODIMPnsresult
3783HttpBaseChannel::HTTPUpgrade(const nsACString& aProtocolName,
3784 nsIHttpUpgradeListener* aListener) {
3785 NS_ENSURE_ARG(!aProtocolName.IsEmpty())do { if ((__builtin_expect(!!(!(!aProtocolName.IsEmpty())), 0
))) { NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!aProtocolName.IsEmpty()"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3785); return NS_ERROR_INVALID_ARG; } } while (false)
;
3786 NS_ENSURE_ARG_POINTER(aListener)do { if ((__builtin_expect(!!(!(aListener)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aListener" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3786); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3787
3788 mUpgradeProtocol = aProtocolName;
3789 mUpgradeProtocolCallback = aListener;
3790 return NS_OK;
3791}
3792
3793NS_IMETHODIMPnsresult
3794HttpBaseChannel::GetOnlyConnect(bool* aOnlyConnect) {
3795 NS_ENSURE_ARG_POINTER(aOnlyConnect)do { if ((__builtin_expect(!!(!(aOnlyConnect)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aOnlyConnect" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3795); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3796
3797 *aOnlyConnect = mCaps & NS_HTTP_CONNECT_ONLY(1 << 16);
3798 return NS_OK;
3799}
3800
3801NS_IMETHODIMPnsresult
3802HttpBaseChannel::SetConnectOnly(bool aTlsTunnel) {
3803 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/HttpBaseChannel.cpp"
, 3803); 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/HttpBaseChannel.cpp"
, 3803, 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/HttpBaseChannel.cpp"
, 3803); } } 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/HttpBaseChannel.cpp"
, 3803); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 3803; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
3804
3805 if (!mUpgradeProtocolCallback) {
3806 return NS_ERROR_FAILURE;
3807 }
3808
3809 mCaps |= NS_HTTP_CONNECT_ONLY(1 << 16);
3810 if (aTlsTunnel) {
3811 mCaps |= NS_HTTP_TLS_TUNNEL(1 << 29);
3812 }
3813 mProxyResolveFlags = nsIProtocolProxyService::RESOLVE_PREFER_HTTPS_PROXY |
3814 nsIProtocolProxyService::RESOLVE_ALWAYS_TUNNEL;
3815 return SetLoadFlags(nsIRequest::INHIBIT_CACHING | nsIChannel::LOAD_ANONYMOUS |
3816 nsIRequest::LOAD_BYPASS_CACHE |
3817 nsIChannel::LOAD_BYPASS_SERVICE_WORKER);
3818}
3819
3820NS_IMETHODIMPnsresult
3821HttpBaseChannel::GetAllowSpdy(bool* aAllowSpdy) {
3822 NS_ENSURE_ARG_POINTER(aAllowSpdy)do { if ((__builtin_expect(!!(!(aAllowSpdy)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aAllowSpdy" ") failed",
nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3822); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3823
3824 *aAllowSpdy = LoadAllowSpdy();
3825 return NS_OK;
3826}
3827
3828NS_IMETHODIMPnsresult
3829HttpBaseChannel::SetAllowSpdy(bool aAllowSpdy) {
3830 StoreAllowSpdy(aAllowSpdy);
3831 return NS_OK;
3832}
3833
3834NS_IMETHODIMPnsresult
3835HttpBaseChannel::GetAllowHttp3(bool* aAllowHttp3) {
3836 NS_ENSURE_ARG_POINTER(aAllowHttp3)do { if ((__builtin_expect(!!(!(aAllowHttp3)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aAllowHttp3" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3836); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3837
3838 *aAllowHttp3 = LoadAllowHttp3();
3839 return NS_OK;
3840}
3841
3842NS_IMETHODIMPnsresult
3843HttpBaseChannel::SetAllowHttp3(bool aAllowHttp3) {
3844 StoreAllowHttp3(aAllowHttp3);
3845 return NS_OK;
3846}
3847
3848NS_IMETHODIMPnsresult
3849HttpBaseChannel::GetAllowAltSvc(bool* aAllowAltSvc) {
3850 NS_ENSURE_ARG_POINTER(aAllowAltSvc)do { if ((__builtin_expect(!!(!(aAllowAltSvc)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aAllowAltSvc" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3850); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3851
3852 *aAllowAltSvc = LoadAllowAltSvc();
3853 return NS_OK;
3854}
3855
3856NS_IMETHODIMPnsresult
3857HttpBaseChannel::SetAllowAltSvc(bool aAllowAltSvc) {
3858 StoreAllowAltSvc(aAllowAltSvc);
3859 return NS_OK;
3860}
3861
3862NS_IMETHODIMPnsresult
3863HttpBaseChannel::GetBeConservative(bool* aBeConservative) {
3864 NS_ENSURE_ARG_POINTER(aBeConservative)do { if ((__builtin_expect(!!(!(aBeConservative)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aBeConservative" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3864); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3865
3866 *aBeConservative = LoadBeConservative();
3867 return NS_OK;
3868}
3869
3870NS_IMETHODIMPnsresult
3871HttpBaseChannel::SetBeConservative(bool aBeConservative) {
3872 StoreBeConservative(aBeConservative);
3873 return NS_OK;
3874}
3875
3876bool HttpBaseChannel::BypassProxy() {
3877 return StaticPrefs::network_proxy_allow_bypass() && LoadBypassProxy();
3878}
3879
3880NS_IMETHODIMPnsresult
3881HttpBaseChannel::GetBypassProxy(bool* aBypassProxy) {
3882 NS_ENSURE_ARG_POINTER(aBypassProxy)do { if ((__builtin_expect(!!(!(aBypassProxy)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aBypassProxy" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3882); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3883
3884 *aBypassProxy = BypassProxy();
3885 return NS_OK;
3886}
3887
3888NS_IMETHODIMPnsresult
3889HttpBaseChannel::SetBypassProxy(bool aBypassProxy) {
3890 if (StaticPrefs::network_proxy_allow_bypass()) {
3891 StoreBypassProxy(aBypassProxy);
3892 } else {
3893 NS_WARNING("bypassProxy set but network.proxy.allow_bypass is disabled")NS_DebugBreak(NS_DEBUG_WARNING, "bypassProxy set but network.proxy.allow_bypass is disabled"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3893)
;
3894 return NS_ERROR_FAILURE;
3895 }
3896 return NS_OK;
3897}
3898
3899NS_IMETHODIMPnsresult
3900HttpBaseChannel::GetIsTRRServiceChannel(bool* aIsTRRServiceChannel) {
3901 NS_ENSURE_ARG_POINTER(aIsTRRServiceChannel)do { if ((__builtin_expect(!!(!(aIsTRRServiceChannel)), 0))) {
NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aIsTRRServiceChannel"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3901); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3902
3903 *aIsTRRServiceChannel = LoadIsTRRServiceChannel();
3904 return NS_OK;
3905}
3906
3907NS_IMETHODIMPnsresult
3908HttpBaseChannel::SetIsTRRServiceChannel(bool aIsTRRServiceChannel) {
3909 StoreIsTRRServiceChannel(aIsTRRServiceChannel);
3910 return NS_OK;
3911}
3912
3913NS_IMETHODIMPnsresult
3914HttpBaseChannel::GetIsResolvedByTRR(bool* aResolvedByTRR) {
3915 NS_ENSURE_ARG_POINTER(aResolvedByTRR)do { if ((__builtin_expect(!!(!(aResolvedByTRR)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResolvedByTRR" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3915); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3916 *aResolvedByTRR = LoadResolvedByTRR();
3917 return NS_OK;
3918}
3919
3920NS_IMETHODIMPnsresult
3921HttpBaseChannel::GetEffectiveTRRMode(nsIRequest::TRRMode* aEffectiveTRRMode) {
3922 *aEffectiveTRRMode = mEffectiveTRRMode;
3923 return NS_OK;
3924}
3925
3926NS_IMETHODIMPnsresult
3927HttpBaseChannel::GetTrrSkipReason(nsITRRSkipReason::value* aTrrSkipReason) {
3928 *aTrrSkipReason = mTRRSkipReason;
3929 return NS_OK;
3930}
3931
3932NS_IMETHODIMPnsresult
3933HttpBaseChannel::GetIsLoadedBySocketProcess(bool* aResult) {
3934 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3934); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3935 *aResult = LoadLoadedBySocketProcess();
3936 return NS_OK;
3937}
3938
3939NS_IMETHODIMPnsresult
3940HttpBaseChannel::GetTlsFlags(uint32_t* aTlsFlags) {
3941 NS_ENSURE_ARG_POINTER(aTlsFlags)do { if ((__builtin_expect(!!(!(aTlsFlags)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aTlsFlags" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3941); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3942
3943 *aTlsFlags = mTlsFlags;
3944 return NS_OK;
3945}
3946
3947NS_IMETHODIMPnsresult
3948HttpBaseChannel::SetTlsFlags(uint32_t aTlsFlags) {
3949 mTlsFlags = aTlsFlags;
3950 return NS_OK;
3951}
3952
3953NS_IMETHODIMPnsresult
3954HttpBaseChannel::GetApiRedirectToURI(nsIURI** aResult) {
3955 if (!mAPIRedirectTo) {
3956 return NS_ERROR_NOT_AVAILABLE;
3957 }
3958 NS_ENSURE_ARG_POINTER(aResult)do { if ((__builtin_expect(!!(!(aResult)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aResult" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3958); return NS_ERROR_INVALID_POINTER; } } while (false)
;
3959 *aResult = do_AddRef(mAPIRedirectTo->first()).take();
3960 return NS_OK;
3961}
3962
3963NS_IMETHODIMPnsresult
3964HttpBaseChannel::GetResponseTimeoutEnabled(bool* aEnable) {
3965 if (NS_WARN_IF(!aEnable)NS_warn_if_impl(!aEnable, "!aEnable", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3965)
) {
3966 return NS_ERROR_NULL_POINTER;
3967 }
3968 *aEnable = LoadResponseTimeoutEnabled();
3969 return NS_OK;
3970}
3971
3972NS_IMETHODIMPnsresult
3973HttpBaseChannel::SetResponseTimeoutEnabled(bool aEnable) {
3974 StoreResponseTimeoutEnabled(aEnable);
3975 return NS_OK;
3976}
3977
3978NS_IMETHODIMPnsresult
3979HttpBaseChannel::GetInitialRwin(uint32_t* aRwin) {
3980 if (NS_WARN_IF(!aRwin)NS_warn_if_impl(!aRwin, "!aRwin", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 3980)
) {
3981 return NS_ERROR_NULL_POINTER;
3982 }
3983 *aRwin = mInitialRwin;
3984 return NS_OK;
3985}
3986
3987NS_IMETHODIMPnsresult
3988HttpBaseChannel::SetInitialRwin(uint32_t aRwin) {
3989 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/HttpBaseChannel.cpp"
, 3989); 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/HttpBaseChannel.cpp"
, 3989, 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/HttpBaseChannel.cpp"
, 3989); } } 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/HttpBaseChannel.cpp"
, 3989); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 3989; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
3990 mInitialRwin = aRwin;
3991 return NS_OK;
3992}
3993
3994NS_IMETHODIMPnsresult
3995HttpBaseChannel::ForcePending(bool aForcePending) {
3996 StoreForcePending(aForcePending);
3997 return NS_OK;
3998}
3999
4000NS_IMETHODIMPnsresult
4001HttpBaseChannel::GetLastModifiedTime(PRTime* lastModifiedTime) {
4002 if (!mResponseHead) return NS_ERROR_NOT_AVAILABLE;
4003 uint32_t lastMod;
4004 nsresult rv = mResponseHead->GetLastModifiedValue(&lastMod);
4005 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/HttpBaseChannel.cpp"
, 4005); return rv; } } while (false)
;
4006 *lastModifiedTime = lastMod;
4007 return NS_OK;
4008}
4009
4010NS_IMETHODIMPnsresult
4011HttpBaseChannel::GetCorsIncludeCredentials(bool* aInclude) {
4012 *aInclude = LoadCorsIncludeCredentials();
4013 return NS_OK;
4014}
4015
4016NS_IMETHODIMPnsresult
4017HttpBaseChannel::SetCorsIncludeCredentials(bool aInclude) {
4018 StoreCorsIncludeCredentials(aInclude);
4019 return NS_OK;
4020}
4021
4022NS_IMETHODIMPnsresult
4023HttpBaseChannel::GetRequestMode(RequestMode* aMode) {
4024 *aMode = mRequestMode;
4025 return NS_OK;
4026}
4027
4028NS_IMETHODIMPnsresult
4029HttpBaseChannel::SetRequestMode(RequestMode aMode) {
4030 mRequestMode = aMode;
4031 return NS_OK;
4032}
4033
4034NS_IMETHODIMPnsresult
4035HttpBaseChannel::GetRedirectMode(uint32_t* aMode) {
4036 *aMode = mRedirectMode;
4037 return NS_OK;
4038}
4039
4040NS_IMETHODIMPnsresult
4041HttpBaseChannel::SetRedirectMode(uint32_t aMode) {
4042 mRedirectMode = aMode;
4043 return NS_OK;
4044}
4045
4046namespace {
4047
4048bool ContainsAllFlags(uint32_t aLoadFlags, uint32_t aMask) {
4049 return (aLoadFlags & aMask) == aMask;
4050}
4051
4052} // anonymous namespace
4053
4054NS_IMETHODIMPnsresult
4055HttpBaseChannel::GetFetchCacheMode(uint32_t* aFetchCacheMode) {
4056 NS_ENSURE_ARG_POINTER(aFetchCacheMode)do { if ((__builtin_expect(!!(!(aFetchCacheMode)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aFetchCacheMode" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4056); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4057
4058 // Otherwise try to guess an appropriate cache mode from the load flags.
4059 if (ContainsAllFlags(mLoadFlags, INHIBIT_CACHING | LOAD_BYPASS_CACHE)) {
4060 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_STORE;
4061 } else if (ContainsAllFlags(mLoadFlags, LOAD_BYPASS_CACHE)) {
4062 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_RELOAD;
4063 } else if (ContainsAllFlags(mLoadFlags, VALIDATE_ALWAYS) ||
4064 LoadForceValidateCacheContent()) {
4065 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_CACHE;
4066 } else if (ContainsAllFlags(
4067 mLoadFlags,
4068 VALIDATE_NEVER | nsICachingChannel::LOAD_ONLY_FROM_CACHE)) {
4069 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED;
4070 } else if (ContainsAllFlags(mLoadFlags, VALIDATE_NEVER)) {
4071 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE;
4072 } else {
4073 *aFetchCacheMode = nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT;
4074 }
4075
4076 return NS_OK;
4077}
4078
4079namespace {
4080
4081void SetCacheFlags(uint32_t& aLoadFlags, uint32_t aFlags) {
4082 // First, clear any possible cache related flags.
4083 uint32_t allPossibleFlags =
4084 nsIRequest::INHIBIT_CACHING | nsIRequest::LOAD_BYPASS_CACHE |
4085 nsIRequest::VALIDATE_ALWAYS | nsIRequest::LOAD_FROM_CACHE |
4086 nsICachingChannel::LOAD_ONLY_FROM_CACHE;
4087 aLoadFlags &= ~allPossibleFlags;
4088
4089 // Then set the new flags.
4090 aLoadFlags |= aFlags;
4091}
4092
4093} // anonymous namespace
4094
4095NS_IMETHODIMPnsresult
4096HttpBaseChannel::SetFetchCacheMode(uint32_t aFetchCacheMode) {
4097 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/HttpBaseChannel.cpp"
, 4097); 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/HttpBaseChannel.cpp"
, 4097, 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/HttpBaseChannel.cpp"
, 4097); } } 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/HttpBaseChannel.cpp"
, 4097); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 4097; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
4098
4099 // Now, set the load flags that implement each cache mode.
4100 switch (aFetchCacheMode) {
4101 case nsIHttpChannelInternal::FETCH_CACHE_MODE_DEFAULT:
4102 // The "default" mode means to use the http cache normally and
4103 // respect any http cache-control headers. We effectively want
4104 // to clear our cache related load flags.
4105 SetCacheFlags(mLoadFlags, 0);
4106 break;
4107 case nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_STORE:
4108 // no-store means don't consult the cache on the way to the network, and
4109 // don't store the response in the cache even if it's cacheable.
4110 SetCacheFlags(mLoadFlags, INHIBIT_CACHING | LOAD_BYPASS_CACHE);
4111 break;
4112 case nsIHttpChannelInternal::FETCH_CACHE_MODE_RELOAD:
4113 // reload means don't consult the cache on the way to the network, but
4114 // do store the response in the cache if possible.
4115 SetCacheFlags(mLoadFlags, LOAD_BYPASS_CACHE);
4116 break;
4117 case nsIHttpChannelInternal::FETCH_CACHE_MODE_NO_CACHE:
4118 // no-cache means always validate what's in the cache.
4119 SetCacheFlags(mLoadFlags, VALIDATE_ALWAYS);
4120 break;
4121 case nsIHttpChannelInternal::FETCH_CACHE_MODE_FORCE_CACHE:
4122 // force-cache means don't validate unless if the response would vary.
4123 SetCacheFlags(mLoadFlags, VALIDATE_NEVER);
4124 break;
4125 case nsIHttpChannelInternal::FETCH_CACHE_MODE_ONLY_IF_CACHED:
4126 // only-if-cached means only from cache, no network, no validation,
4127 // generate a network error if the document was't in the cache. The
4128 // privacy implications of these flags (making it fast/easy to check if
4129 // the user has things in their cache without any network traffic side
4130 // effects) are addressed in the Request constructor which
4131 // enforces/requires same-origin request mode.
4132 SetCacheFlags(mLoadFlags,
4133 VALIDATE_NEVER | nsICachingChannel::LOAD_ONLY_FROM_CACHE);
4134 break;
4135 }
4136
4137#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED1
4138 uint32_t finalMode = 0;
4139 MOZ_ALWAYS_SUCCEEDS(GetFetchCacheMode(&finalMode))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(GetFetchCacheMode(&finalMode))), 1)))), 1))) { } else { do
{ do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(GetFetchCacheMode(&finalMode))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4139); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(GetFetchCacheMode(&finalMode))"
")"); do { *((volatile int*)__null) = 4139; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
4140 MOZ_DIAGNOSTIC_ASSERT(finalMode == aFetchCacheMode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(finalMode == aFetchCacheMode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(finalMode == aFetchCacheMode
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"finalMode == aFetchCacheMode", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4140); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "finalMode == aFetchCacheMode"
")"); do { *((volatile int*)__null) = 4140; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4141#endif // MOZ_DIAGNOSTIC_ASSERT_ENABLED
4142
4143 return NS_OK;
4144}
4145
4146NS_IMETHODIMPnsresult
4147HttpBaseChannel::SetIntegrityMetadata(const nsAString& aIntegrityMetadata) {
4148 mIntegrityMetadata = aIntegrityMetadata;
4149 return NS_OK;
4150}
4151
4152NS_IMETHODIMPnsresult
4153HttpBaseChannel::GetIntegrityMetadata(nsAString& aIntegrityMetadata) {
4154 aIntegrityMetadata = mIntegrityMetadata;
4155 return NS_OK;
4156}
4157
4158//-----------------------------------------------------------------------------
4159// HttpBaseChannel::nsISupportsPriority
4160//-----------------------------------------------------------------------------
4161
4162NS_IMETHODIMPnsresult
4163HttpBaseChannel::GetPriority(int32_t* value) {
4164 *value = mPriority;
4165 return NS_OK;
4166}
4167
4168NS_IMETHODIMPnsresult
4169HttpBaseChannel::AdjustPriority(int32_t delta) {
4170 return SetPriority(mPriority + delta);
4171}
4172
4173//-----------------------------------------------------------------------------
4174// HttpBaseChannel::nsIResumableChannel
4175//-----------------------------------------------------------------------------
4176
4177NS_IMETHODIMPnsresult
4178HttpBaseChannel::GetEntityID(nsACString& aEntityID) {
4179 // Don't return an entity ID for Non-GET requests which require
4180 // additional data
4181 if (!mRequestHead.IsGet()) {
4182 return NS_ERROR_NOT_RESUMABLE;
4183 }
4184
4185 uint64_t size = UINT64_MAX(18446744073709551615UL);
4186 nsAutoCString etag, lastmod;
4187 if (mResponseHead) {
4188 // Don't return an entity if the server sent the following header:
4189 // Accept-Ranges: none
4190 // Not sending the Accept-Ranges header means we can still try
4191 // sending range requests.
4192 nsAutoCString acceptRanges;
4193 Unused << mResponseHead->GetHeader(nsHttp::Accept_Ranges, acceptRanges);
4194 if (!acceptRanges.IsEmpty() &&
4195 !nsHttp::FindToken(acceptRanges.get(), "bytes",
4196 HTTP_HEADER_VALUE_SEPS" \t" ",")) {
4197 return NS_ERROR_NOT_RESUMABLE;
4198 }
4199
4200 size = mResponseHead->TotalEntitySize();
4201 Unused << mResponseHead->GetHeader(nsHttp::Last_Modified, lastmod);
4202 Unused << mResponseHead->GetHeader(nsHttp::ETag, etag);
4203 }
4204 nsCString entityID;
4205 NS_EscapeURL(etag.BeginReading(), etag.Length(),
4206 esc_AlwaysCopy | esc_FileBaseName | esc_Forced, entityID);
4207 entityID.Append('/');
4208 entityID.AppendInt(int64_t(size));
4209 entityID.Append('/');
4210 entityID.Append(lastmod);
4211 // NOTE: Appending lastmod as the last part avoids having to escape it
4212
4213 aEntityID = entityID;
4214
4215 return NS_OK;
4216}
4217
4218//-----------------------------------------------------------------------------
4219// HttpBaseChannel::nsIConsoleReportCollector
4220//-----------------------------------------------------------------------------
4221
4222void HttpBaseChannel::AddConsoleReport(
4223 uint32_t aErrorFlags, const nsACString& aCategory,
4224 nsContentUtils::PropertiesFile aPropertiesFile,
4225 const nsACString& aSourceFileURI, uint32_t aLineNumber,
4226 uint32_t aColumnNumber, const nsACString& aMessageName,
4227 const nsTArray<nsString>& aStringParams) {
4228 mReportCollector->AddConsoleReport(aErrorFlags, aCategory, aPropertiesFile,
4229 aSourceFileURI, aLineNumber, aColumnNumber,
4230 aMessageName, aStringParams);
4231
4232 // If this channel is already part of a loadGroup, we can flush this console
4233 // report immediately.
4234 HttpBaseChannel::MaybeFlushConsoleReports();
4235}
4236
4237void HttpBaseChannel::FlushReportsToConsole(uint64_t aInnerWindowID,
4238 ReportAction aAction) {
4239 mReportCollector->FlushReportsToConsole(aInnerWindowID, aAction);
4240}
4241
4242void HttpBaseChannel::FlushReportsToConsoleForServiceWorkerScope(
4243 const nsACString& aScope, ReportAction aAction) {
4244 mReportCollector->FlushReportsToConsoleForServiceWorkerScope(aScope, aAction);
4245}
4246
4247void HttpBaseChannel::FlushConsoleReports(dom::Document* aDocument,
4248 ReportAction aAction) {
4249 mReportCollector->FlushConsoleReports(aDocument, aAction);
4250}
4251
4252void HttpBaseChannel::FlushConsoleReports(nsILoadGroup* aLoadGroup,
4253 ReportAction aAction) {
4254 mReportCollector->FlushConsoleReports(aLoadGroup, aAction);
4255}
4256
4257void HttpBaseChannel::FlushConsoleReports(
4258 nsIConsoleReportCollector* aCollector) {
4259 mReportCollector->FlushConsoleReports(aCollector);
4260}
4261
4262void HttpBaseChannel::StealConsoleReports(
4263 nsTArray<net::ConsoleReportCollected>& aReports) {
4264 mReportCollector->StealConsoleReports(aReports);
4265}
4266
4267void HttpBaseChannel::ClearConsoleReports() {
4268 mReportCollector->ClearConsoleReports();
4269}
4270
4271bool HttpBaseChannel::IsNavigation() {
4272 return LoadForceMainDocumentChannel() || (mLoadFlags & LOAD_DOCUMENT_URI);
4273}
4274
4275bool HttpBaseChannel::BypassServiceWorker() const {
4276 return mLoadFlags & LOAD_BYPASS_SERVICE_WORKER;
4277}
4278
4279bool HttpBaseChannel::ShouldIntercept(nsIURI* aURI) {
4280 nsCOMPtr<nsINetworkInterceptController> controller;
4281 GetCallback(controller);
4282 bool shouldIntercept = false;
4283
4284 if (!StaticPrefs::dom_serviceWorkers_enabled()) {
4285 return false;
4286 }
4287
4288 // We should never intercept internal redirects. The ServiceWorker code
4289 // can trigger interntal redirects as the result of a FetchEvent. If
4290 // we re-intercept then an infinite loop can occur.
4291 //
4292 // Its also important that we do not set the LOAD_BYPASS_SERVICE_WORKER
4293 // flag because an internal redirect occurs. Its possible that another
4294 // interception should occur after the internal redirect. For example,
4295 // if the ServiceWorker chooses not to call respondWith() the channel
4296 // will be reset with an internal redirect. If the request is a navigation
4297 // and the network then triggers a redirect its possible the new URL
4298 // should be intercepted again.
4299 //
4300 // Note, HSTS upgrade redirects are often treated the same as internal
4301 // redirects. In this case, however, we intentionally allow interception
4302 // of HSTS upgrade redirects. This matches the expected spec behavior and
4303 // does not run the risk of infinite loops as described above.
4304 bool internalRedirect =
4305 mLastRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL;
4306
4307 if (controller && mLoadInfo && !BypassServiceWorker() && !internalRedirect) {
4308 nsresult rv = controller->ShouldPrepareForIntercept(
4309 aURI ? aURI : mURI.get(), this, &shouldIntercept);
4310 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
4311 return false;
4312 }
4313 }
4314 return shouldIntercept;
4315}
4316
4317void HttpBaseChannel::AddAsNonTailRequest() {
4318 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/HttpBaseChannel.cpp"
, 4318); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4318; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4319
4320 if (EnsureRequestContext()) {
4321 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
, "HttpBaseChannel::AddAsNonTailRequest this=%p, rc=%p, already added=%d"
, this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
4322 "HttpBaseChannel::AddAsNonTailRequest this=%p, rc=%p, already added=%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
, "HttpBaseChannel::AddAsNonTailRequest this=%p, rc=%p, already added=%d"
, this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
4323 this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::AddAsNonTailRequest this=%p, rc=%p, already added=%d"
, this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
;
4324
4325 if (!LoadAddedAsNonTailRequest()) {
4326 mRequestContext->AddNonTailRequest();
4327 StoreAddedAsNonTailRequest(true);
4328 }
4329 }
4330}
4331
4332void HttpBaseChannel::RemoveAsNonTailRequest() {
4333 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/HttpBaseChannel.cpp"
, 4333); AnnotateMozCrashReason("MOZ_ASSERT" "(" "NS_IsMainThread()"
")"); do { *((volatile int*)__null) = 4333; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4334
4335 if (mRequestContext) {
4336 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
, "HttpBaseChannel::RemoveAsNonTailRequest this=%p, rc=%p, already "
"added=%d", this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
4337 ("HttpBaseChannel::RemoveAsNonTailRequest this=%p, rc=%p, already "do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::RemoveAsNonTailRequest this=%p, rc=%p, already "
"added=%d", this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
4338 "added=%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
, "HttpBaseChannel::RemoveAsNonTailRequest this=%p, rc=%p, already "
"added=%d", this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
4339 this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest()))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::RemoveAsNonTailRequest this=%p, rc=%p, already "
"added=%d", this, mRequestContext.get(), (bool)LoadAddedAsNonTailRequest
()); } } while (0)
;
4340
4341 if (LoadAddedAsNonTailRequest()) {
4342 mRequestContext->RemoveNonTailRequest();
4343 StoreAddedAsNonTailRequest(false);
4344 }
4345 }
4346}
4347
4348#ifdef DEBUG1
4349void HttpBaseChannel::AssertPrivateBrowsingId() {
4350 nsCOMPtr<nsILoadContext> loadContext;
4351 NS_QueryNotificationCallbacks(this, loadContext);
4352
4353 if (!loadContext) {
4354 return;
4355 }
4356
4357 // We skip testing of favicon loading here since it could be triggered by XUL
4358 // image which uses SystemPrincipal. The SystemPrincpal doesn't have
4359 // mPrivateBrowsingId.
4360 if (mLoadInfo->GetLoadingPrincipal() &&
4361 mLoadInfo->GetLoadingPrincipal()->IsSystemPrincipal() &&
4362 mLoadInfo->InternalContentPolicyType() ==
4363 nsIContentPolicy::TYPE_INTERNAL_IMAGE_FAVICON) {
4364 return;
4365 }
4366
4367 OriginAttributes docShellAttrs;
4368 loadContext->GetOriginAttributes(docShellAttrs);
4369 MOZ_ASSERT(mLoadInfo->GetOriginAttributes().mPrivateBrowsingId ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetOriginAttributes().mPrivateBrowsingId
== docShellAttrs.mPrivateBrowsingId)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetOriginAttributes
().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
" (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4372); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4372; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4370 docShellAttrs.mPrivateBrowsingId,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetOriginAttributes().mPrivateBrowsingId
== docShellAttrs.mPrivateBrowsingId)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetOriginAttributes
().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
" (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4372); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4372; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4371 "PrivateBrowsingId values are not the same between LoadInfo and "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetOriginAttributes().mPrivateBrowsingId
== docShellAttrs.mPrivateBrowsingId)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetOriginAttributes
().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
" (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4372); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4372; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
4372 "LoadContext.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mLoadInfo->GetOriginAttributes().mPrivateBrowsingId
== docShellAttrs.mPrivateBrowsingId)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(mLoadInfo->GetOriginAttributes
().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
" (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4372); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mLoadInfo->GetOriginAttributes().mPrivateBrowsingId == docShellAttrs.mPrivateBrowsingId"
") (" "PrivateBrowsingId values are not the same between LoadInfo and "
"LoadContext." ")"); do { *((volatile int*)__null) = 4372; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
4373}
4374#endif
4375
4376already_AddRefed<nsILoadInfo> HttpBaseChannel::CloneLoadInfoForRedirect(
4377 nsIURI* aNewURI, uint32_t aRedirectFlags) {
4378 // make a copy of the loadinfo, append to the redirectchain
4379 // this will be set on the newly created channel for the redirect target.
4380 nsCOMPtr<nsILoadInfo> newLoadInfo =
4381 static_cast<mozilla::net::LoadInfo*>(mLoadInfo.get())->Clone();
4382
4383 ExtContentPolicyType contentPolicyType =
4384 mLoadInfo->GetExternalContentPolicyType();
4385 if (contentPolicyType == ExtContentPolicy::TYPE_DOCUMENT ||
4386 contentPolicyType == ExtContentPolicy::TYPE_SUBDOCUMENT) {
4387 // Reset PrincipalToInherit to a null principal. We'll credit the the
4388 // redirecting resource's result principal as the new principal's precursor.
4389 // This means that a data: URI will end up loading in a process based on the
4390 // redirected-from URI.
4391 nsCOMPtr<nsIPrincipal> redirectPrincipal;
4392 nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
4393 this, getter_AddRefs(redirectPrincipal));
4394 nsCOMPtr<nsIPrincipal> nullPrincipalToInherit =
4395 NullPrincipal::CreateWithInheritedAttributes(redirectPrincipal);
4396 newLoadInfo->SetPrincipalToInherit(nullPrincipalToInherit);
4397 }
4398
4399 bool isTopLevelDoc = newLoadInfo->GetExternalContentPolicyType() ==
4400 ExtContentPolicy::TYPE_DOCUMENT;
4401
4402 if (isTopLevelDoc) {
4403 // re-compute the origin attributes of the loadInfo if it's top-level load.
4404 nsCOMPtr<nsILoadContext> loadContext;
4405 NS_QueryNotificationCallbacks(this, loadContext);
4406 OriginAttributes docShellAttrs;
4407 if (loadContext) {
4408 loadContext->GetOriginAttributes(docShellAttrs);
4409 }
4410
4411 OriginAttributes attrs = newLoadInfo->GetOriginAttributes();
4412
4413 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mUserContextId == attrs.mUserContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mUserContextId == attrs.mUserContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mUserContextId == attrs.mUserContextId" " (" "docshell and necko should have the same userContextId attribute."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mUserContextId == attrs.mUserContextId"
") (" "docshell and necko should have the same userContextId attribute."
")"); do { *((volatile int*)__null) = 4415; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4414 docShellAttrs.mUserContextId == attrs.mUserContextId,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mUserContextId == attrs.mUserContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mUserContextId == attrs.mUserContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mUserContextId == attrs.mUserContextId" " (" "docshell and necko should have the same userContextId attribute."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mUserContextId == attrs.mUserContextId"
") (" "docshell and necko should have the same userContextId attribute."
")"); do { *((volatile int*)__null) = 4415; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4415 "docshell and necko should have the same userContextId attribute.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mUserContextId == attrs.mUserContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mUserContextId == attrs.mUserContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mUserContextId == attrs.mUserContextId" " (" "docshell and necko should have the same userContextId attribute."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4415); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mUserContextId == attrs.mUserContextId"
") (" "docshell and necko should have the same userContextId attribute."
")"); do { *((volatile int*)__null) = 4415; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4416 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
" (" "docshell and necko should have the same privateBrowsingId attribute."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4418); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { *((volatile int*)__null) = 4418; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4417 docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
" (" "docshell and necko should have the same privateBrowsingId attribute."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4418); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { *((volatile int*)__null) = 4418; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4418 "docshell and necko should have the same privateBrowsingId attribute.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
" (" "docshell and necko should have the same privateBrowsingId attribute."
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4418); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mPrivateBrowsingId == attrs.mPrivateBrowsingId"
") (" "docshell and necko should have the same privateBrowsingId attribute."
")"); do { *((volatile int*)__null) = 4418; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4419 MOZ_ASSERT(docShellAttrs.mGeckoViewSessionContextId ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
" (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4422); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4422; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4420 attrs.mGeckoViewSessionContextId,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
" (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4422); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4422; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4421 "docshell and necko should have the same "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
" (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4422); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4422; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4422 "geckoViewSessionContextId attribute")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
" (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4422); AnnotateMozCrashReason("MOZ_ASSERT" "(" "docShellAttrs.mGeckoViewSessionContextId == attrs.mGeckoViewSessionContextId"
") (" "docshell and necko should have the same " "geckoViewSessionContextId attribute"
")"); do { *((volatile int*)__null) = 4422; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4423
4424 attrs = docShellAttrs;
4425 attrs.SetFirstPartyDomain(true, aNewURI);
4426 newLoadInfo->SetOriginAttributes(attrs);
4427
4428 // re-compute the upgrade insecure requests bit for document navigations
4429 // since it should only apply to same-origin navigations (redirects).
4430 // we only do this if the CSP of the triggering element (the cspToInherit)
4431 // uses 'upgrade-insecure-requests', otherwise UIR does not apply.
4432 nsCOMPtr<nsIContentSecurityPolicy> csp = newLoadInfo->GetCspToInherit();
4433 if (csp) {
4434 bool upgradeInsecureRequests = false;
4435 csp->GetUpgradeInsecureRequests(&upgradeInsecureRequests);
4436 if (upgradeInsecureRequests) {
4437 nsCOMPtr<nsIPrincipal> resultPrincipal =
4438 BasePrincipal::CreateContentPrincipal(
4439 aNewURI, newLoadInfo->GetOriginAttributes());
4440 bool isConsideredSameOriginforUIR =
4441 nsContentSecurityUtils::IsConsideredSameOriginForUIR(
4442 newLoadInfo->TriggeringPrincipal(), resultPrincipal);
4443 static_cast<mozilla::net::LoadInfo*>(newLoadInfo.get())
4444 ->SetUpgradeInsecureRequests(isConsideredSameOriginforUIR);
4445 }
4446 }
4447 }
4448
4449 // Leave empty, we want a 'clean ground' when creating the new channel.
4450 // This will be ensured to be either set by the protocol handler or set
4451 // to the redirect target URI properly after the channel creation.
4452 newLoadInfo->SetResultPrincipalURI(nullptr);
4453
4454 bool isInternalRedirect =
4455 (aRedirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
4456 nsIChannelEventSink::REDIRECT_STS_UPGRADE));
4457
4458 // Reset our sandboxed null principal ID when cloning loadInfo for an
4459 // externally visible redirect.
4460 if (!isInternalRedirect) {
4461 // If we've redirected from http to something that isn't, clear
4462 // the "external" flag, as loads that now go to other apps should be
4463 // allowed to go ahead and not trip infinite-loop protection
4464 // (see bug 1717314 for context).
4465 if (!aNewURI->SchemeIs("http") && !aNewURI->SchemeIs("https")) {
4466 newLoadInfo->SetLoadTriggeredFromExternal(false);
4467 }
4468 newLoadInfo->ResetSandboxedNullPrincipalID();
4469
4470 // Reset HTTPS-first and -only status on http redirect. To not unexpectedly
4471 // downgrade requests that weren't upgraded via HTTPS-First (Bug 1904238).
4472 if (isTopLevelDoc) {
4473 Unused << newLoadInfo->SetHttpsOnlyStatus(
4474 nsILoadInfo::HTTPS_ONLY_UNINITIALIZED);
4475 }
4476 }
4477
4478 newLoadInfo->AppendRedirectHistoryEntry(this, isInternalRedirect);
4479
4480 return newLoadInfo.forget();
4481}
4482
4483//-----------------------------------------------------------------------------
4484// nsHttpChannel::nsITraceableChannel
4485//-----------------------------------------------------------------------------
4486
4487NS_IMETHODIMPnsresult
4488HttpBaseChannel::SetNewListener(nsIStreamListener* aListener,
4489 bool aMustApplyContentConversion,
4490 nsIStreamListener** _retval) {
4491 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
, "HttpBaseChannel::SetNewListener [this=%p, mListener=%p, newListener=%p]"
, this, mListener.get(), aListener); } } while (0)
4492 "HttpBaseChannel::SetNewListener [this=%p, mListener=%p, newListener=%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
, "HttpBaseChannel::SetNewListener [this=%p, mListener=%p, newListener=%p]"
, this, mListener.get(), aListener); } } while (0)
4493 this, mListener.get(), aListener))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetNewListener [this=%p, mListener=%p, newListener=%p]"
, this, mListener.get(), aListener); } } while (0)
;
4494
4495 if (!LoadTracingEnabled()) return NS_ERROR_FAILURE;
4496
4497 NS_ENSURE_STATE(mListener)do { if ((__builtin_expect(!!(!(mListener)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "mListener" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4497); return NS_ERROR_UNEXPECTED; } } while (false)
;
4498 NS_ENSURE_ARG_POINTER(aListener)do { if ((__builtin_expect(!!(!(aListener)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aListener" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4498); return NS_ERROR_INVALID_POINTER; } } while (false)
;
4499
4500 nsCOMPtr<nsIStreamListener> wrapper = new nsStreamListenerWrapper(mListener);
4501
4502 wrapper.forget(_retval);
4503 mListener = aListener;
4504 if (aMustApplyContentConversion) {
4505 StoreListenerRequiresContentConversion(true);
4506 }
4507 return NS_OK;
4508}
4509
4510//-----------------------------------------------------------------------------
4511// HttpBaseChannel helpers
4512//-----------------------------------------------------------------------------
4513
4514void HttpBaseChannel::ReleaseListeners() {
4515 MOZ_ASSERT(mCurrentThread->IsOnCurrentThread(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCurrentThread->IsOnCurrentThread())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mCurrentThread->IsOnCurrentThread()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mCurrentThread->IsOnCurrentThread()"
" (" "Should only be called on the current thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4516); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurrentThread->IsOnCurrentThread()"
") (" "Should only be called on the current thread" ")"); do
{ *((volatile int*)__null) = 4516; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
4516 "Should only be called on the current thread")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(mCurrentThread->IsOnCurrentThread())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(mCurrentThread->IsOnCurrentThread()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("mCurrentThread->IsOnCurrentThread()"
" (" "Should only be called on the current thread" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4516); AnnotateMozCrashReason("MOZ_ASSERT" "(" "mCurrentThread->IsOnCurrentThread()"
") (" "Should only be called on the current thread" ")"); do
{ *((volatile int*)__null) = 4516; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
4517
4518 mListener = nullptr;
4519 mCallbacks = nullptr;
4520 mProgressSink = nullptr;
4521 mCompressListener = nullptr;
4522 mORB = nullptr;
4523}
4524
4525void HttpBaseChannel::DoNotifyListener() {
4526 LOG(("HttpBaseChannel::DoNotifyListener 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
, "HttpBaseChannel::DoNotifyListener this=%p", this); } } while
(0)
;
4527
4528 // In case nsHttpChannel::OnStartRequest wasn't called (e.g. due to flag
4529 // LOAD_ONLY_IF_MODIFIED) we want to set AfterOnStartRequestBegun to true
4530 // before notifying listener.
4531 if (!LoadAfterOnStartRequestBegun()) {
4532 StoreAfterOnStartRequestBegun(true);
4533 }
4534
4535 if (mListener && !LoadOnStartRequestCalled()) {
4536 nsCOMPtr<nsIStreamListener> listener = mListener;
4537 StoreOnStartRequestCalled(true);
4538 listener->OnStartRequest(this);
4539 }
4540 StoreOnStartRequestCalled(true);
4541
4542 // Make sure IsPending is set to false. At this moment we are done from
4543 // the point of view of our consumer and we have to report our self
4544 // as not-pending.
4545 StoreIsPending(false);
4546
4547 // notify "http-on-before-stop-request" observers
4548 gHttpHandler->OnBeforeStopRequest(this);
4549
4550 if (mListener && !LoadOnStopRequestCalled()) {
4551 nsCOMPtr<nsIStreamListener> listener = mListener;
4552 StoreOnStopRequestCalled(true);
4553 listener->OnStopRequest(this, mStatus);
4554 }
4555 StoreOnStopRequestCalled(true);
4556
4557 // notify "http-on-stop-request" observers
4558 gHttpHandler->OnStopRequest(this);
4559
4560 // This channel has finished its job, potentially release any tail-blocked
4561 // requests with this.
4562 RemoveAsNonTailRequest();
4563
4564 // We have to make sure to drop the references to listeners and callbacks
4565 // no longer needed.
4566 ReleaseListeners();
4567
4568 DoNotifyListenerCleanup();
4569
4570 // If this is a navigation, then we must let the docshell flush the reports
4571 // to the console later. The LoadDocument() is pointing at the detached
4572 // document that started the navigation. We want to show the reports on the
4573 // new document. Otherwise the console is wiped and the user never sees
4574 // the information.
4575 if (!IsNavigation()) {
4576 if (mLoadGroup) {
4577 FlushConsoleReports(mLoadGroup);
4578 } else {
4579 RefPtr<dom::Document> doc;
4580 mLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
4581 FlushConsoleReports(doc);
4582 }
4583 }
4584}
4585
4586void HttpBaseChannel::AddCookiesToRequest() {
4587 if (mLoadFlags & LOAD_ANONYMOUS) {
4588 return;
4589 }
4590
4591 bool useCookieService = (XRE_IsParentProcess());
4592 nsAutoCString cookie;
4593 if (useCookieService) {
4594 nsICookieService* cs = gHttpHandler->GetCookieService();
4595 if (cs) {
4596 cs->GetCookieStringFromHttp(mURI, this, cookie);
4597 }
4598
4599 if (cookie.IsEmpty()) {
4600 cookie = mUserSetCookieHeader;
4601 } else if (!mUserSetCookieHeader.IsEmpty()) {
4602 cookie.AppendLiteral("; ");
4603 cookie.Append(mUserSetCookieHeader);
4604 }
4605 } else {
4606 cookie = mUserSetCookieHeader;
4607 }
4608
4609 // If we are in the child process, we want the parent seeing any
4610 // cookie headers that might have been set by SetRequestHeader()
4611 SetRequestHeader(nsHttp::Cookie.val(), cookie, false);
4612}
4613
4614/* static */
4615void HttpBaseChannel::PropagateReferenceIfNeeded(
4616 nsIURI* aURI, nsCOMPtr<nsIURI>& aRedirectURI) {
4617 bool hasRef = false;
4618 nsresult rv = aRedirectURI->GetHasRef(&hasRef);
4619 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && !hasRef) {
4620 nsAutoCString ref;
4621 aURI->GetRef(ref);
4622 if (!ref.IsEmpty()) {
4623 // NOTE: SetRef will fail if mRedirectURI is immutable
4624 // (e.g. an about: URI)... Oh well.
4625 Unused << NS_MutateURI(aRedirectURI).SetRef(ref).Finalize(aRedirectURI);
4626 }
4627 }
4628}
4629
4630bool HttpBaseChannel::ShouldRewriteRedirectToGET(
4631 uint32_t httpStatus, nsHttpRequestHead::ParsedMethodType method) {
4632 // for 301 and 302, only rewrite POST
4633 if (httpStatus == 301 || httpStatus == 302) {
4634 return method == nsHttpRequestHead::kMethod_Post;
4635 }
4636
4637 // rewrite for 303 unless it was HEAD
4638 if (httpStatus == 303) return method != nsHttpRequestHead::kMethod_Head;
4639
4640 // otherwise, such as for 307, do not rewrite
4641 return false;
4642}
4643
4644NS_IMETHODIMPnsresult
4645HttpBaseChannel::ShouldStripRequestBodyHeader(const nsACString& aMethod,
4646 bool* aResult) {
4647 *aResult = false;
4648 uint32_t httpStatus = 0;
4649 if (NS_FAILED(GetResponseStatus(&httpStatus))((bool)(__builtin_expect(!!(NS_FAILED_impl(GetResponseStatus(
&httpStatus))), 0)))
) {
4650 return NS_OK;
4651 }
4652
4653 nsAutoCString method(aMethod);
4654 nsHttpRequestHead::ParsedMethodType parsedMethod;
4655 nsHttpRequestHead::ParseMethod(method, parsedMethod);
4656 // Fetch 4.4.11, which is slightly different than the perserved method
4657 // algrorithm: strip request-body-header for GET->GET redirection for 303.
4658 *aResult =
4659 ShouldRewriteRedirectToGET(httpStatus, parsedMethod) &&
4660 !(httpStatus == 303 && parsedMethod == nsHttpRequestHead::kMethod_Get);
4661
4662 return NS_OK;
4663}
4664
4665HttpBaseChannel::ReplacementChannelConfig
4666HttpBaseChannel::CloneReplacementChannelConfig(bool aPreserveMethod,
4667 uint32_t aRedirectFlags,
4668 ReplacementReason aReason) {
4669 ReplacementChannelConfig config;
4670 config.redirectFlags = aRedirectFlags;
4671 config.classOfService = mClassOfService;
4672
4673 if (mPrivateBrowsingOverriden) {
4674 config.privateBrowsing = Some(mPrivateBrowsing);
4675 }
4676
4677 if (mReferrerInfo) {
4678 // When cloning for a document channel replacement (parent process
4679 // copying values for a new content process channel), this happens after
4680 // OnStartRequest so we have the headers for the response available.
4681 // We don't want to apply them to the referrer for the channel though,
4682 // since that is the referrer for the current document, and the header
4683 // should only apply to navigations from the current document.
4684 if (aReason == ReplacementReason::DocumentChannel) {
4685 config.referrerInfo = mReferrerInfo;
4686 } else {
4687 dom::ReferrerPolicy referrerPolicy = dom::ReferrerPolicy::_empty;
4688 nsAutoCString tRPHeaderCValue;
4689 Unused << GetResponseHeader("referrer-policy"_ns, tRPHeaderCValue);
4690 NS_ConvertUTF8toUTF16 tRPHeaderValue(tRPHeaderCValue);
4691
4692 if (!tRPHeaderValue.IsEmpty()) {
4693 referrerPolicy =
4694 dom::ReferrerInfo::ReferrerPolicyFromHeaderString(tRPHeaderValue);
4695 }
4696
4697 // In case we are here because an upgrade happened through mixed content
4698 // upgrading, CSP upgrade-insecure-requests, HTTPS-Only or HTTPS-First, we
4699 // have to recalculate the referrer based on the original referrer to
4700 // account for the different scheme. This does NOT apply to HSTS.
4701 // See Bug 1857894 and order of https://fetch.spec.whatwg.org/#main-fetch.
4702 // Otherwise, if we have a new referrer policy, we want to recalculate the
4703 // referrer based on the old computed referrer (Bug 1678545).
4704 bool wasNonHSTSUpgrade =
4705 (aRedirectFlags & nsIChannelEventSink::REDIRECT_STS_UPGRADE) &&
4706 (!mLoadInfo->GetHstsStatus());
4707 if (wasNonHSTSUpgrade) {
4708 nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetOriginalReferrer();
4709 config.referrerInfo =
4710 new dom::ReferrerInfo(referrer, mReferrerInfo->ReferrerPolicy(),
4711 mReferrerInfo->GetSendReferrer());
4712 } else if (referrerPolicy != dom::ReferrerPolicy::_empty) {
4713 nsCOMPtr<nsIURI> referrer = mReferrerInfo->GetComputedReferrer();
4714 config.referrerInfo = new dom::ReferrerInfo(
4715 referrer, referrerPolicy, mReferrerInfo->GetSendReferrer());
4716 } else {
4717 config.referrerInfo = mReferrerInfo;
4718 }
4719 }
4720 }
4721
4722 nsCOMPtr<nsITimedChannel> oldTimedChannel(
4723 do_QueryInterface(static_cast<nsIHttpChannel*>(this)));
4724 if (oldTimedChannel) {
4725 config.timedChannelInfo = Some(dom::TimedChannelInfo());
4726 config.timedChannelInfo->redirectCount() = mRedirectCount;
4727 config.timedChannelInfo->internalRedirectCount() = mInternalRedirectCount;
4728 config.timedChannelInfo->asyncOpen() = mAsyncOpenTime;
4729 config.timedChannelInfo->channelCreation() = mChannelCreationTimestamp;
4730 config.timedChannelInfo->redirectStart() = mRedirectStartTimeStamp;
4731 config.timedChannelInfo->redirectEnd() = mRedirectEndTimeStamp;
4732 config.timedChannelInfo->initiatorType() = mInitiatorType;
4733 config.timedChannelInfo->allRedirectsSameOrigin() =
4734 LoadAllRedirectsSameOrigin();
4735 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() =
4736 LoadAllRedirectsPassTimingAllowCheck();
4737 // Execute the timing allow check to determine whether
4738 // to report the redirect timing info
4739 nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
4740 // TYPE_DOCUMENT loads don't have a loadingPrincipal, so we can't set
4741 // AllRedirectsPassTimingAllowCheck on them.
4742 if (loadInfo->GetExternalContentPolicyType() !=
4743 ExtContentPolicy::TYPE_DOCUMENT) {
4744 nsCOMPtr<nsIPrincipal> principal = loadInfo->GetLoadingPrincipal();
4745 config.timedChannelInfo->timingAllowCheckForPrincipal() =
4746 Some(oldTimedChannel->TimingAllowCheck(principal));
4747 }
4748
4749 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() =
4750 LoadAllRedirectsPassTimingAllowCheck();
4751 config.timedChannelInfo->launchServiceWorkerStart() =
4752 mLaunchServiceWorkerStart;
4753 config.timedChannelInfo->launchServiceWorkerEnd() = mLaunchServiceWorkerEnd;
4754 config.timedChannelInfo->dispatchFetchEventStart() =
4755 mDispatchFetchEventStart;
4756 config.timedChannelInfo->dispatchFetchEventEnd() = mDispatchFetchEventEnd;
4757 config.timedChannelInfo->handleFetchEventStart() = mHandleFetchEventStart;
4758 config.timedChannelInfo->handleFetchEventEnd() = mHandleFetchEventEnd;
4759 config.timedChannelInfo->responseStart() =
4760 mTransactionTimings.responseStart;
4761 config.timedChannelInfo->responseEnd() = mTransactionTimings.responseEnd;
4762 }
4763
4764 if (aPreserveMethod) {
4765 // since preserveMethod is true, we need to ensure that the appropriate
4766 // request method gets set on the channel, regardless of whether or not
4767 // we set the upload stream above. This means SetRequestMethod() will
4768 // be called twice if ExplicitSetUploadStream() gets called above.
4769
4770 nsAutoCString method;
4771 mRequestHead.Method(method);
4772 config.method = Some(method);
4773
4774 if (mUploadStream) {
4775 // rewind upload stream
4776 nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
4777 if (seekable) {
4778 seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
4779 }
4780 config.uploadStream = mUploadStream;
4781 }
4782 config.uploadStreamLength = mReqContentLength;
4783 config.uploadStreamHasHeaders = LoadUploadStreamHasHeaders();
4784
4785 nsAutoCString contentType;
4786 nsresult rv = mRequestHead.GetHeader(nsHttp::Content_Type, contentType);
4787 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4788 config.contentType = Some(contentType);
4789 }
4790
4791 nsAutoCString contentLength;
4792 rv = mRequestHead.GetHeader(nsHttp::Content_Length, contentLength);
4793 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
4794 config.contentLength = Some(contentLength);
4795 }
4796 }
4797
4798 return config;
4799}
4800
4801/* static */ void HttpBaseChannel::ConfigureReplacementChannel(
4802 nsIChannel* newChannel, const ReplacementChannelConfig& config,
4803 ReplacementReason aReason) {
4804 nsCOMPtr<nsIClassOfService> cos(do_QueryInterface(newChannel));
4805 if (cos) {
4806 cos->SetClassOfService(config.classOfService);
4807 }
4808
4809 // Try to preserve the privacy bit if it has been overridden
4810 if (config.privateBrowsing) {
4811 nsCOMPtr<nsIPrivateBrowsingChannel> newPBChannel =
4812 do_QueryInterface(newChannel);
4813 if (newPBChannel) {
4814 newPBChannel->SetPrivate(*config.privateBrowsing);
4815 }
4816 }
4817
4818 // Transfer the timing data (if we are dealing with an nsITimedChannel).
4819 nsCOMPtr<nsITimedChannel> newTimedChannel(do_QueryInterface(newChannel));
4820 if (config.timedChannelInfo && newTimedChannel) {
4821 // If we're an internal redirect, or a document channel replacement,
4822 // then we shouldn't record any new timing for this and just copy
4823 // over the existing values.
4824 bool shouldHideTiming = aReason != ReplacementReason::Redirect;
4825 if (shouldHideTiming) {
4826 newTimedChannel->SetRedirectCount(
4827 config.timedChannelInfo->redirectCount());
4828 int32_t newCount = config.timedChannelInfo->internalRedirectCount() + 1;
4829 newTimedChannel->SetInternalRedirectCount(std::max(
4830 newCount, static_cast<int32_t>(
4831 config.timedChannelInfo->internalRedirectCount())));
4832 } else {
4833 int32_t newCount = config.timedChannelInfo->redirectCount() + 1;
4834 newTimedChannel->SetRedirectCount(std::max(
4835 newCount,
4836 static_cast<int32_t>(config.timedChannelInfo->redirectCount())));
4837 newTimedChannel->SetInternalRedirectCount(
4838 config.timedChannelInfo->internalRedirectCount());
4839 }
4840
4841 if (shouldHideTiming) {
4842 if (!config.timedChannelInfo->channelCreation().IsNull()) {
4843 newTimedChannel->SetChannelCreation(
4844 config.timedChannelInfo->channelCreation());
4845 }
4846
4847 if (!config.timedChannelInfo->asyncOpen().IsNull()) {
4848 newTimedChannel->SetAsyncOpen(config.timedChannelInfo->asyncOpen());
4849 }
4850 }
4851
4852 // If the RedirectStart is null, we will use the AsyncOpen value of the
4853 // previous channel (this is the first redirect in the redirects chain).
4854 if (config.timedChannelInfo->redirectStart().IsNull()) {
4855 // Only do this for real redirects. Internal redirects should be hidden.
4856 if (!shouldHideTiming) {
4857 newTimedChannel->SetRedirectStart(config.timedChannelInfo->asyncOpen());
4858 }
4859 } else {
4860 newTimedChannel->SetRedirectStart(
4861 config.timedChannelInfo->redirectStart());
4862 }
4863
4864 // For internal redirects just propagate the last redirect end time
4865 // forward. Otherwise the new redirect end time is the last response
4866 // end time.
4867 TimeStamp newRedirectEnd;
4868 if (shouldHideTiming) {
4869 newRedirectEnd = config.timedChannelInfo->redirectEnd();
4870 } else if (!config.timedChannelInfo->responseEnd().IsNull()) {
4871 newRedirectEnd = config.timedChannelInfo->responseEnd();
4872 } else {
4873 newRedirectEnd = TimeStamp::Now();
4874 }
4875 newTimedChannel->SetRedirectEnd(newRedirectEnd);
4876
4877 newTimedChannel->SetInitiatorType(config.timedChannelInfo->initiatorType());
4878
4879 nsCOMPtr<nsILoadInfo> loadInfo = newChannel->LoadInfo();
4880 MOZ_ASSERT(loadInfo)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(loadInfo)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(loadInfo))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("loadInfo", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4880); AnnotateMozCrashReason("MOZ_ASSERT" "(" "loadInfo" ")"
); do { *((volatile int*)__null) = 4880; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4881
4882 newTimedChannel->SetAllRedirectsSameOrigin(
4883 config.timedChannelInfo->allRedirectsSameOrigin());
4884
4885 if (config.timedChannelInfo->timingAllowCheckForPrincipal()) {
4886 newTimedChannel->SetAllRedirectsPassTimingAllowCheck(
4887 config.timedChannelInfo->allRedirectsPassTimingAllowCheck() &&
4888 *config.timedChannelInfo->timingAllowCheckForPrincipal());
4889 }
4890
4891 // Propagate service worker measurements across redirects. The
4892 // PeformanceResourceTiming.workerStart API expects to see the
4893 // worker start time after a redirect.
4894 newTimedChannel->SetLaunchServiceWorkerStart(
4895 config.timedChannelInfo->launchServiceWorkerStart());
4896 newTimedChannel->SetLaunchServiceWorkerEnd(
4897 config.timedChannelInfo->launchServiceWorkerEnd());
4898 newTimedChannel->SetDispatchFetchEventStart(
4899 config.timedChannelInfo->dispatchFetchEventStart());
4900 newTimedChannel->SetDispatchFetchEventEnd(
4901 config.timedChannelInfo->dispatchFetchEventEnd());
4902 newTimedChannel->SetHandleFetchEventStart(
4903 config.timedChannelInfo->handleFetchEventStart());
4904 newTimedChannel->SetHandleFetchEventEnd(
4905 config.timedChannelInfo->handleFetchEventEnd());
4906 }
4907
4908 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
4909 if (!httpChannel) {
4910 return; // no other options to set
4911 }
4912
4913 if (config.uploadStream) {
4914 nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(httpChannel);
4915 nsCOMPtr<nsIUploadChannel2> uploadChannel2 = do_QueryInterface(httpChannel);
4916 if (uploadChannel2 || uploadChannel) {
4917 // replicate original call to SetUploadStream...
4918 if (uploadChannel2) {
4919 const nsACString& ctype =
4920 config.contentType ? *config.contentType : VoidCString();
4921 // If header is not present mRequestHead.HasHeaderValue will truncated
4922 // it. But we want to end up with a void string, not an empty string,
4923 // because ExplicitSetUploadStream treats the former as "no header" and
4924 // the latter as "header with empty string value".
4925
4926 const nsACString& method =
4927 config.method ? *config.method : VoidCString();
4928
4929 uploadChannel2->ExplicitSetUploadStream(
4930 config.uploadStream, ctype, config.uploadStreamLength, method,
4931 config.uploadStreamHasHeaders);
4932 } else {
4933 if (config.uploadStreamHasHeaders) {
4934 uploadChannel->SetUploadStream(config.uploadStream, ""_ns,
4935 config.uploadStreamLength);
4936 } else {
4937 nsAutoCString ctype;
4938 if (config.contentType) {
4939 ctype = *config.contentType;
4940 } else {
4941 ctype = "application/octet-stream"_ns;
4942 }
4943 if (config.contentLength && !config.contentLength->IsEmpty()) {
4944 uploadChannel->SetUploadStream(
4945 config.uploadStream, ctype,
4946 nsCRT::atoll(config.contentLength->get()));
4947 }
4948 }
4949 }
4950 }
4951 }
4952
4953 if (config.referrerInfo) {
4954 DebugOnly<nsresult> success{};
4955 success = httpChannel->SetReferrerInfo(config.referrerInfo);
4956 MOZ_ASSERT(NS_SUCCEEDED(success))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(((bool)(__builtin_expect(!!(!NS_FAILED_impl(success)
), 1))))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl(success)
), 1)))))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("((bool)(__builtin_expect(!!(!NS_FAILED_impl(success)), 1)))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 4956); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(success)), 1)))"
")"); do { *((volatile int*)__null) = 4956; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4957 }
4958
4959 if (config.method) {
4960 DebugOnly<nsresult> rv = httpChannel->SetRequestMethod(*config.method);
4961 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/HttpBaseChannel.cpp"
, 4961); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 4961; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4962 }
4963}
4964
4965HttpBaseChannel::ReplacementChannelConfig::ReplacementChannelConfig(
4966 const dom::ReplacementChannelConfigInit& aInit) {
4967 redirectFlags = aInit.redirectFlags();
4968 classOfService = aInit.classOfService();
4969 privateBrowsing = aInit.privateBrowsing();
4970 method = aInit.method();
4971 referrerInfo = aInit.referrerInfo();
4972 timedChannelInfo = aInit.timedChannelInfo();
4973 uploadStream = aInit.uploadStream();
4974 uploadStreamLength = aInit.uploadStreamLength();
4975 uploadStreamHasHeaders = aInit.uploadStreamHasHeaders();
4976 contentType = aInit.contentType();
4977 contentLength = aInit.contentLength();
4978}
4979
4980dom::ReplacementChannelConfigInit
4981HttpBaseChannel::ReplacementChannelConfig::Serialize() {
4982 dom::ReplacementChannelConfigInit config;
4983 config.redirectFlags() = redirectFlags;
4984 config.classOfService() = classOfService;
4985 config.privateBrowsing() = privateBrowsing;
4986 config.method() = method;
4987 config.referrerInfo() = referrerInfo;
4988 config.timedChannelInfo() = timedChannelInfo;
4989 config.uploadStream() =
4990 uploadStream ? RemoteLazyInputStream::WrapStream(uploadStream) : nullptr;
4991 config.uploadStreamLength() = uploadStreamLength;
4992 config.uploadStreamHasHeaders() = uploadStreamHasHeaders;
4993 config.contentType() = contentType;
4994 config.contentLength() = contentLength;
4995
4996 return config;
4997}
4998
4999nsresult HttpBaseChannel::SetupReplacementChannel(nsIURI* newURI,
5000 nsIChannel* newChannel,
5001 bool preserveMethod,
5002 uint32_t redirectFlags) {
5003 nsresult rv;
5004
5005 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
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d]"
, this, newChannel, preserveMethod); } } while (0)
5006 ("HttpBaseChannel::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
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d]"
, this, newChannel, preserveMethod); } } while (0)
5007 "[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
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d]"
, this, newChannel, preserveMethod); } } while (0)
5008 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
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p newChannel=%p preserveMethod=%d]"
, this, newChannel, preserveMethod); } } while (0)
;
5009
5010 // Ensure the channel's loadInfo's result principal URI so that it's
5011 // either non-null or updated to the redirect target URI.
5012 // We must do this because in case the loadInfo's result principal URI
5013 // is null, it would be taken from OriginalURI of the channel. But we
5014 // overwrite it with the whole redirect chain first URI before opening
5015 // the target channel, hence the information would be lost.
5016 // If the protocol handler that created the channel wants to use
5017 // the originalURI of the channel as the principal URI, this fulfills
5018 // that request - newURI is the original URI of the channel.
5019 nsCOMPtr<nsILoadInfo> newLoadInfo = newChannel->LoadInfo();
5020 nsCOMPtr<nsIURI> resultPrincipalURI;
5021 rv = newLoadInfo->GetResultPrincipalURI(getter_AddRefs(resultPrincipalURI));
5022 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/HttpBaseChannel.cpp"
, 5022); return rv; } } while (false)
;
5023 if (!resultPrincipalURI) {
5024 rv = newLoadInfo->SetResultPrincipalURI(newURI);
5025 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/HttpBaseChannel.cpp"
, 5025); return rv; } } while (false)
;
5026 }
5027
5028 nsLoadFlags loadFlags = mLoadFlags;
5029 loadFlags |= LOAD_REPLACE;
5030
5031 // if the original channel was using SSL and this channel is not using
5032 // SSL, then no need to inhibit persistent caching. however, if the
5033 // original channel was not using SSL and has INHIBIT_PERSISTENT_CACHING
5034 // set, then allow the flag to apply to the redirected channel as well.
5035 // since we force set INHIBIT_PERSISTENT_CACHING on all HTTPS channels,
5036 // we only need to check if the original channel was using SSL.
5037 if (mURI->SchemeIs("https")) {
5038 loadFlags &= ~INHIBIT_PERSISTENT_CACHING;
5039 }
5040
5041 newChannel->SetLoadFlags(loadFlags);
5042
5043 nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(newChannel);
5044
5045 ReplacementReason redirectType =
5046 redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
5047 nsIChannelEventSink::REDIRECT_TRANSPARENT)
5048 ? ReplacementReason::InternalRedirect
5049 : ReplacementReason::Redirect;
5050 ReplacementChannelConfig config = CloneReplacementChannelConfig(
5051 preserveMethod, redirectFlags, redirectType);
5052 ConfigureReplacementChannel(newChannel, config, redirectType);
5053
5054 // Check whether or not this was a cross-domain redirect.
5055 nsCOMPtr<nsITimedChannel> newTimedChannel(do_QueryInterface(newChannel));
5056 bool sameOriginWithOriginalUri = SameOriginWithOriginalUri(newURI);
5057 if (config.timedChannelInfo && newTimedChannel) {
5058 newTimedChannel->SetAllRedirectsSameOrigin(
5059 config.timedChannelInfo->allRedirectsSameOrigin() &&
5060 sameOriginWithOriginalUri);
5061 }
5062
5063 newChannel->SetLoadGroup(mLoadGroup);
5064 newChannel->SetNotificationCallbacks(mCallbacks);
5065 // TODO: create tests for cross-origin redirect in bug 1662896.
5066 if (sameOriginWithOriginalUri) {
5067 newChannel->SetContentDisposition(mContentDispositionHint);
5068 if (mContentDispositionFilename) {
5069 newChannel->SetContentDispositionFilename(*mContentDispositionFilename);
5070 }
5071 }
5072
5073 if (!httpChannel) return NS_OK; // no other options to set
5074
5075 // Preserve the CORS preflight information.
5076 nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(newChannel);
5077 if (httpInternal) {
5078 httpInternal->SetLastRedirectFlags(redirectFlags);
5079
5080 if (LoadRequireCORSPreflight()) {
5081 httpInternal->SetCorsPreflightParameters(mUnsafeHeaders, false, false);
5082 }
5083 }
5084
5085 // convey the LoadAllowSTS() flags
5086 rv = httpChannel->SetAllowSTS(LoadAllowSTS());
5087 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/HttpBaseChannel.cpp"
, 5087); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5087; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5088
5089 // convey the Accept header value
5090 {
5091 nsAutoCString oldAcceptValue;
5092 nsresult hasHeader = mRequestHead.GetHeader(nsHttp::Accept, oldAcceptValue);
5093 if (NS_SUCCEEDED(hasHeader)((bool)(__builtin_expect(!!(!NS_FAILED_impl(hasHeader)), 1)))) {
5094 rv = httpChannel->SetRequestHeader("Accept"_ns, oldAcceptValue, false);
5095 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/HttpBaseChannel.cpp"
, 5095); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5095; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5096 }
5097 }
5098
5099 // convey the User-Agent header value
5100 // since we might be setting custom user agent from DevTools.
5101 if (httpInternal && mRequestMode == RequestMode::No_cors &&
5102 redirectType == ReplacementReason::Redirect) {
5103 nsAutoCString oldUserAgent;
5104 nsresult hasHeader =
5105 mRequestHead.GetHeader(nsHttp::User_Agent, oldUserAgent);
5106 if (NS_SUCCEEDED(hasHeader)((bool)(__builtin_expect(!!(!NS_FAILED_impl(hasHeader)), 1)))) {
5107 rv = httpChannel->SetRequestHeader("User-Agent"_ns, oldUserAgent, false);
5108 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/HttpBaseChannel.cpp"
, 5108); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5108; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5109 }
5110 }
5111
5112 // convery the IsUserAgentHeaderModified value.
5113 if (httpInternal) {
5114 rv = httpInternal->SetIsUserAgentHeaderModified(
5115 LoadIsUserAgentHeaderModified());
5116 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/HttpBaseChannel.cpp"
, 5116); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5116; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5117 }
5118
5119 // share the request context - see bug 1236650
5120 rv = httpChannel->SetRequestContextID(mRequestContextID);
5121 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/HttpBaseChannel.cpp"
, 5121); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5121; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5122
5123 // When on the parent process, the channel can't attempt to get it itself.
5124 // When on the child process, it would be waste to query it again.
5125 rv = httpChannel->SetBrowserId(mBrowserId);
5126 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/HttpBaseChannel.cpp"
, 5126); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5126; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5127
5128 // Not setting this flag would break carrying permissions down to the child
5129 // process when the channel is artificially forced to be a main document load.
5130 rv = httpChannel->SetIsMainDocumentChannel(LoadForceMainDocumentChannel());
5131 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/HttpBaseChannel.cpp"
, 5131); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5131; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5132
5133 // Preserve the loading order
5134 nsCOMPtr<nsISupportsPriority> p = do_QueryInterface(newChannel);
5135 if (p) {
5136 p->SetPriority(mPriority);
5137 }
5138
5139 if (httpInternal) {
5140 // Convey third party cookie, conservative, and spdy flags.
5141 rv = httpInternal->SetThirdPartyFlags(LoadThirdPartyFlags());
5142 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/HttpBaseChannel.cpp"
, 5142); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5142; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5143 rv = httpInternal->SetAllowSpdy(LoadAllowSpdy());
5144 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/HttpBaseChannel.cpp"
, 5144); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5144; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5145 rv = httpInternal->SetAllowHttp3(LoadAllowHttp3());
5146 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/HttpBaseChannel.cpp"
, 5146); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5146; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5147 rv = httpInternal->SetAllowAltSvc(LoadAllowAltSvc());
5148 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/HttpBaseChannel.cpp"
, 5148); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5148; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5149 rv = httpInternal->SetBeConservative(LoadBeConservative());
5150 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/HttpBaseChannel.cpp"
, 5150); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5150; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5151 rv = httpInternal->SetIsTRRServiceChannel(LoadIsTRRServiceChannel());
5152 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/HttpBaseChannel.cpp"
, 5152); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5152; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5153 rv = httpInternal->SetTlsFlags(mTlsFlags);
5154 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/HttpBaseChannel.cpp"
, 5154); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5154; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5155
5156 // Ensure the type of realChannel involves all types it may redirect to.
5157 // Such as nsHttpChannel and InterceptedChannel.
5158 // Even thought InterceptedChannel itself doesn't require these information,
5159 // it may still be necessary for the following redirections.
5160 // E.g. nsHttpChannel -> InterceptedChannel -> nsHttpChannel
5161 RefPtr<HttpBaseChannel> realChannel;
5162 CallQueryInterface(newChannel, realChannel.StartAssignment());
5163 if (realChannel) {
5164 realChannel->SetTopWindowURI(mTopWindowURI);
5165
5166 realChannel->StoreTaintedOriginFlag(
5167 ShouldTaintReplacementChannelOrigin(newChannel, redirectFlags));
5168 }
5169
5170 // update the DocumentURI indicator since we are being redirected.
5171 // if this was a top-level document channel, then the new channel
5172 // should have its mDocumentURI point to newURI; otherwise, we
5173 // just need to pass along our mDocumentURI to the new channel.
5174 if (newURI && (mURI == mDocumentURI)) {
5175 rv = httpInternal->SetDocumentURI(newURI);
5176 } else {
5177 rv = httpInternal->SetDocumentURI(mDocumentURI);
5178 }
5179 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/HttpBaseChannel.cpp"
, 5179); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5179; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5180
5181 // if there is a chain of keys for redirect-responses we transfer it to
5182 // the new channel (see bug #561276)
5183 {
5184 auto redirectedCachekeys = mRedirectedCachekeys.Lock();
5185 auto& ref = redirectedCachekeys.ref();
5186 if (ref) {
5187 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
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p] transferring chain of redirect cache-keys"
, this); } } while (0)
5188 ("HttpBaseChannel::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
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p] transferring chain of redirect cache-keys"
, this); } } while (0)
5189 "[this=%p] transferring chain of redirect cache-keys",do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p] transferring chain of redirect cache-keys"
, this); } } while (0)
5190 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
, "HttpBaseChannel::SetupReplacementChannel " "[this=%p] transferring chain of redirect cache-keys"
, this); } } while (0)
;
5191 rv = httpInternal->SetCacheKeysRedirectChain(ref.release());
5192 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/HttpBaseChannel.cpp"
, 5192); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5192; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5193 }
5194 }
5195
5196 // Preserve Request mode.
5197 rv = httpInternal->SetRequestMode(mRequestMode);
5198 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/HttpBaseChannel.cpp"
, 5198); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5198; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5199
5200 // Preserve Redirect mode flag.
5201 rv = httpInternal->SetRedirectMode(mRedirectMode);
5202 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/HttpBaseChannel.cpp"
, 5202); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5202; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5203
5204 // Preserve Integrity metadata.
5205 rv = httpInternal->SetIntegrityMetadata(mIntegrityMetadata);
5206 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/HttpBaseChannel.cpp"
, 5206); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5206; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5207
5208 httpInternal->SetAltDataForChild(LoadAltDataForChild());
5209 if (LoadDisableAltDataCache()) {
5210 httpInternal->DisableAltDataCache();
5211 }
5212 }
5213
5214 // transfer any properties
5215 nsCOMPtr<nsIWritablePropertyBag> bag(do_QueryInterface(newChannel));
5216 if (bag) {
5217 for (const auto& entry : mPropertyHash) {
5218 bag->SetProperty(entry.GetKey(), entry.GetWeak());
5219 }
5220 }
5221
5222 // Pass the preferred alt-data type on to the new channel.
5223 nsCOMPtr<nsICacheInfoChannel> cacheInfoChan(do_QueryInterface(newChannel));
5224 if (cacheInfoChan) {
5225 for (auto& data : mPreferredCachedAltDataTypes) {
5226 cacheInfoChan->PreferAlternativeDataType(data.type(), data.contentType(),
5227 data.deliverAltData());
5228 }
5229
5230 if (LoadForceValidateCacheContent()) {
5231 Unused << cacheInfoChan->SetForceValidateCacheContent(true);
5232 }
5233 }
5234
5235 if (redirectFlags & (nsIChannelEventSink::REDIRECT_INTERNAL |
5236 nsIChannelEventSink::REDIRECT_STS_UPGRADE)) {
5237 // Copy non-origin related headers to the new channel.
5238 nsCOMPtr<nsIHttpHeaderVisitor> visitor =
5239 new AddHeadersToChannelVisitor(httpChannel);
5240 rv = mRequestHead.VisitHeaders(visitor);
5241 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/HttpBaseChannel.cpp"
, 5241); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5241; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5242 }
5243
5244 // we need to strip Authentication headers for cross-origin requests
5245 // Ref: https://fetch.spec.whatwg.org/#http-redirect-fetch
5246 nsAutoCString authHeader;
5247 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->GetRequestHeader
("Authorization"_ns, authHeader))), 1)))
5248 httpChannel->GetRequestHeader("Authorization"_ns, authHeader))((bool)(__builtin_expect(!!(!NS_FAILED_impl(httpChannel->GetRequestHeader
("Authorization"_ns, authHeader))), 1)))
&&
5249 NS_ShouldRemoveAuthHeaderOnRedirect(static_cast<nsIChannel*>(this),
5250 newChannel, redirectFlags)) {
5251 rv = httpChannel->SetRequestHeader("Authorization"_ns, ""_ns, false);
5252 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/HttpBaseChannel.cpp"
, 5252); AnnotateMozCrashReason("MOZ_ASSERT" "(" "((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))"
")"); do { *((volatile int*)__null) = 5252; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5253 }
5254
5255 return NS_OK;
5256}
5257
5258// check whether the new channel is of same origin as the current channel
5259bool HttpBaseChannel::IsNewChannelSameOrigin(nsIChannel* aNewChannel) {
5260 bool isSameOrigin = false;
5261 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5262
5263 if (!ssm) {
5264 return false;
5265 }
5266
5267 nsCOMPtr<nsIURI> newURI;
5268 NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI));
5269
5270 nsresult rv = ssm->CheckSameOriginURI(newURI, mURI, false, false);
5271 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1)))) {
5272 isSameOrigin = true;
5273 }
5274
5275 return isSameOrigin;
5276}
5277
5278bool HttpBaseChannel::ShouldTaintReplacementChannelOrigin(
5279 nsIChannel* aNewChannel, uint32_t aRedirectFlags) {
5280 if (LoadTaintedOriginFlag()) {
5281 return true;
5282 }
5283
5284 if (NS_IsInternalSameURIRedirect(this, aNewChannel, aRedirectFlags) ||
5285 NS_IsHSTSUpgradeRedirect(this, aNewChannel, aRedirectFlags)) {
5286 return false;
5287 }
5288
5289 // If new channel is not of same origin we need to taint unless
5290 // mURI <-> mOriginalURI/LoadingPrincipal are same origin.
5291 if (IsNewChannelSameOrigin(aNewChannel)) {
5292 return false;
5293 }
5294
5295 nsresult rv;
5296
5297 if (mLoadInfo->GetLoadingPrincipal()) {
5298 bool sameOrigin = false;
5299 rv = mLoadInfo->GetLoadingPrincipal()->IsSameOrigin(mURI, &sameOrigin);
5300 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5301 return true;
5302 }
5303 return !sameOrigin;
5304 }
5305 if (!mOriginalURI) {
5306 return true;
5307 }
5308
5309 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5310 if (!ssm) {
5311 return true;
5312 }
5313
5314 rv = ssm->CheckSameOriginURI(mOriginalURI, mURI, false, false);
5315 return NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)));
5316}
5317
5318// Redirect Tracking
5319bool HttpBaseChannel::SameOriginWithOriginalUri(nsIURI* aURI) {
5320 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5321 bool isPrivateWin = mLoadInfo->GetOriginAttributes().IsPrivateBrowsing();
5322 nsresult rv =
5323 ssm->CheckSameOriginURI(aURI, mOriginalURI, false, isPrivateWin);
5324 return (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))));
5325}
5326
5327//-----------------------------------------------------------------------------
5328// HttpBaseChannel::nsIClassifiedChannel
5329
5330NS_IMETHODIMPnsresult
5331HttpBaseChannel::GetMatchedList(nsACString& aList) {
5332 aList = mMatchedList;
5333 return NS_OK;
5334}
5335
5336NS_IMETHODIMPnsresult
5337HttpBaseChannel::GetMatchedProvider(nsACString& aProvider) {
5338 aProvider = mMatchedProvider;
5339 return NS_OK;
5340}
5341
5342NS_IMETHODIMPnsresult
5343HttpBaseChannel::GetMatchedFullHash(nsACString& aFullHash) {
5344 aFullHash = mMatchedFullHash;
5345 return NS_OK;
5346}
5347
5348NS_IMETHODIMPnsresult
5349HttpBaseChannel::SetMatchedInfo(const nsACString& aList,
5350 const nsACString& aProvider,
5351 const nsACString& aFullHash) {
5352 NS_ENSURE_ARG(!aList.IsEmpty())do { if ((__builtin_expect(!!(!(!aList.IsEmpty())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!aList.IsEmpty()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5352); return NS_ERROR_INVALID_ARG; } } while (false)
;
5353
5354 mMatchedList = aList;
5355 mMatchedProvider = aProvider;
5356 mMatchedFullHash = aFullHash;
5357 return NS_OK;
5358}
5359
5360NS_IMETHODIMPnsresult
5361HttpBaseChannel::GetMatchedTrackingLists(nsTArray<nsCString>& aLists) {
5362 aLists = mMatchedTrackingLists.Clone();
5363 return NS_OK;
5364}
5365
5366NS_IMETHODIMPnsresult
5367HttpBaseChannel::GetMatchedTrackingFullHashes(
5368 nsTArray<nsCString>& aFullHashes) {
5369 aFullHashes = mMatchedTrackingFullHashes.Clone();
5370 return NS_OK;
5371}
5372
5373NS_IMETHODIMPnsresult
5374HttpBaseChannel::SetMatchedTrackingInfo(
5375 const nsTArray<nsCString>& aLists, const nsTArray<nsCString>& aFullHashes) {
5376 NS_ENSURE_ARG(!aLists.IsEmpty())do { if ((__builtin_expect(!!(!(!aLists.IsEmpty())), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "!aLists.IsEmpty()" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5376); return NS_ERROR_INVALID_ARG; } } while (false)
;
5377 // aFullHashes can be empty for non hash-matching algorithm, for example,
5378 // host based test entries in preference.
5379
5380 mMatchedTrackingLists = aLists.Clone();
5381 mMatchedTrackingFullHashes = aFullHashes.Clone();
5382 return NS_OK;
5383}
5384//-----------------------------------------------------------------------------
5385// HttpBaseChannel::nsITimedChannel
5386//-----------------------------------------------------------------------------
5387
5388NS_IMETHODIMPnsresult
5389HttpBaseChannel::GetChannelCreation(TimeStamp* _retval) {
5390 *_retval = mChannelCreationTimestamp;
5391 return NS_OK;
5392}
5393
5394NS_IMETHODIMPnsresult
5395HttpBaseChannel::SetChannelCreation(TimeStamp aValue) {
5396 MOZ_DIAGNOSTIC_ASSERT(!aValue.IsNull())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aValue.IsNull())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aValue.IsNull()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!aValue.IsNull()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5396); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!aValue.IsNull()"
")"); do { *((volatile int*)__null) = 5396; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5397 TimeDuration adjust = aValue - mChannelCreationTimestamp;
5398 mChannelCreationTimestamp = aValue;
5399 mChannelCreationTime += (PRTime)adjust.ToMicroseconds();
5400 return NS_OK;
5401}
5402
5403NS_IMETHODIMPnsresult
5404HttpBaseChannel::GetAsyncOpen(TimeStamp* _retval) {
5405 *_retval = mAsyncOpenTime;
5406 return NS_OK;
5407}
5408
5409NS_IMETHODIMPnsresult
5410HttpBaseChannel::SetAsyncOpen(TimeStamp aValue) {
5411 MOZ_DIAGNOSTIC_ASSERT(!aValue.IsNull())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!aValue.IsNull())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!aValue.IsNull()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!aValue.IsNull()"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5411); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "!aValue.IsNull()"
")"); do { *((volatile int*)__null) = 5411; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5412 mAsyncOpenTime = aValue;
5413 StoreAsyncOpenTimeOverriden(true);
5414 return NS_OK;
5415}
5416
5417/**
5418 * @return the number of redirects. There is no check for cross-domain
5419 * redirects. This check must be done by the consumers.
5420 */
5421NS_IMETHODIMPnsresult
5422HttpBaseChannel::GetRedirectCount(uint8_t* aRedirectCount) {
5423 *aRedirectCount = mRedirectCount;
5424 return NS_OK;
5425}
5426
5427NS_IMETHODIMPnsresult
5428HttpBaseChannel::SetRedirectCount(uint8_t aRedirectCount) {
5429 mRedirectCount = aRedirectCount;
5430 return NS_OK;
5431}
5432
5433NS_IMETHODIMPnsresult
5434HttpBaseChannel::GetInternalRedirectCount(uint8_t* aRedirectCount) {
5435 *aRedirectCount = mInternalRedirectCount;
5436 return NS_OK;
5437}
5438
5439NS_IMETHODIMPnsresult
5440HttpBaseChannel::SetInternalRedirectCount(uint8_t aRedirectCount) {
5441 mInternalRedirectCount = aRedirectCount;
5442 return NS_OK;
5443}
5444
5445NS_IMETHODIMPnsresult
5446HttpBaseChannel::GetRedirectStart(TimeStamp* _retval) {
5447 *_retval = mRedirectStartTimeStamp;
5448 return NS_OK;
5449}
5450
5451NS_IMETHODIMPnsresult
5452HttpBaseChannel::SetRedirectStart(TimeStamp aRedirectStart) {
5453 mRedirectStartTimeStamp = aRedirectStart;
5454 return NS_OK;
5455}
5456
5457NS_IMETHODIMPnsresult
5458HttpBaseChannel::GetRedirectEnd(TimeStamp* _retval) {
5459 *_retval = mRedirectEndTimeStamp;
5460 return NS_OK;
5461}
5462
5463NS_IMETHODIMPnsresult
5464HttpBaseChannel::SetRedirectEnd(TimeStamp aRedirectEnd) {
5465 mRedirectEndTimeStamp = aRedirectEnd;
5466 return NS_OK;
5467}
5468
5469NS_IMETHODIMPnsresult
5470HttpBaseChannel::GetAllRedirectsSameOrigin(bool* aAllRedirectsSameOrigin) {
5471 *aAllRedirectsSameOrigin = LoadAllRedirectsSameOrigin();
5472 return NS_OK;
5473}
5474
5475NS_IMETHODIMPnsresult
5476HttpBaseChannel::SetAllRedirectsSameOrigin(bool aAllRedirectsSameOrigin) {
5477 StoreAllRedirectsSameOrigin(aAllRedirectsSameOrigin);
5478 return NS_OK;
5479}
5480
5481NS_IMETHODIMPnsresult
5482HttpBaseChannel::GetAllRedirectsPassTimingAllowCheck(bool* aPassesCheck) {
5483 *aPassesCheck = LoadAllRedirectsPassTimingAllowCheck();
5484 return NS_OK;
5485}
5486
5487NS_IMETHODIMPnsresult
5488HttpBaseChannel::SetAllRedirectsPassTimingAllowCheck(bool aPassesCheck) {
5489 StoreAllRedirectsPassTimingAllowCheck(aPassesCheck);
5490 return NS_OK;
5491}
5492
5493// https://fetch.spec.whatwg.org/#cors-check
5494bool HttpBaseChannel::PerformCORSCheck() {
5495 // Step 1
5496 // Let origin be the result of getting `Access-Control-Allow-Origin`
5497 // from response’s header list.
5498 nsAutoCString origin;
5499 nsresult rv = GetResponseHeader("Access-Control-Allow-Origin"_ns, origin);
5500
5501 // Step 2
5502 // If origin is null, then return failure. (Note: null, not 'null').
5503 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || origin.IsVoid()) {
5504 return false;
5505 }
5506
5507 // Step 3
5508 // If request’s credentials mode is not "include"
5509 // and origin is `*`, then return success.
5510 uint32_t cookiePolicy = mLoadInfo->GetCookiePolicy();
5511 if (cookiePolicy != nsILoadInfo::SEC_COOKIES_INCLUDE &&
5512 origin.EqualsLiteral("*")) {
5513 return true;
5514 }
5515
5516 // Step 4
5517 // If the result of byte-serializing a request origin
5518 // with request is not origin, then return failure.
5519 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5520 nsCOMPtr<nsIPrincipal> resourcePrincipal;
5521 rv = ssm->GetChannelURIPrincipal(this, getter_AddRefs(resourcePrincipal));
5522 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !resourcePrincipal) {
5523 return false;
5524 }
5525 nsAutoCString serializedOrigin;
5526 nsContentSecurityManager::GetSerializedOrigin(
5527 mLoadInfo->TriggeringPrincipal(), resourcePrincipal, serializedOrigin,
5528 mLoadInfo);
5529 if (!serializedOrigin.Equals(origin)) {
5530 return false;
5531 }
5532
5533 // Step 5
5534 // If request’s credentials mode is not "include", then return success.
5535 if (cookiePolicy != nsILoadInfo::SEC_COOKIES_INCLUDE) {
5536 return true;
5537 }
5538
5539 // Step 6
5540 // Let credentials be the result of getting
5541 // `Access-Control-Allow-Credentials` from response’s header list.
5542 nsAutoCString credentials;
5543 rv = GetResponseHeader("Access-Control-Allow-Credentials"_ns, credentials);
5544
5545 // Step 7 and 8
5546 // If credentials is `true`, then return success.
5547 // (else) return failure.
5548 return NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && credentials.EqualsLiteral("true");
5549}
5550
5551NS_IMETHODIMPnsresult
5552HttpBaseChannel::BodyInfoAccessAllowedCheck(nsIPrincipal* aOrigin,
5553 BodyInfoAccess* _retval) {
5554 // Per the Fetch spec, https://fetch.spec.whatwg.org/#response-body-info,
5555 // the bodyInfo for Resource Timing and Navigation Timing info consists of
5556 // encoded size, decoded size, and content type. It is however made opaque
5557 // whenever the response is turned into a network error, which sets its
5558 // bodyInfo to its default values (sizes=0, content-type="").
5559
5560 // Case 1:
5561 // "no-cors" -> Upon success, fetch will return an opaque filtered response.
5562 // An opaque(-redirect) filtered response is a filtered response
5563 // whose ... body info is a new response body info.
5564 auto tainting = mLoadInfo->GetTainting();
5565 if (tainting == mozilla::LoadTainting::Opaque) {
5566 *_retval = BodyInfoAccess::DISALLOWED;
5567 return NS_OK;
5568 }
5569
5570 // Case 2:
5571 // If request’s response tainting is "cors" and a CORS check for request
5572 // and response returns failure, then return a network error.
5573 if (tainting == mozilla::LoadTainting::CORS && !PerformCORSCheck()) {
5574 *_retval = BodyInfoAccess::DISALLOWED;
5575 return NS_OK;
5576 }
5577
5578 // Otherwise:
5579 // The fetch response handover, given a fetch params fetchParams
5580 // and a response response, run these steps:
5581 // processResponseEndOfBody:
5582 // - If fetchParams’s request’s mode is not "navigate" or response’s
5583 // has-cross-origin-redirects is false:
5584 // - Let mimeType be the result of extracting a MIME type from
5585 // response’s header list.
5586 // - If mimeType is not failure, then set bodyInfo’s content type to the
5587 // result of minimizing a supported MIME type given mimeType.
5588 dom::RequestMode requestMode;
5589 MOZ_ALWAYS_SUCCEEDS(GetRequestMode(&requestMode))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(GetRequestMode(&requestMode))), 1)))), 1))) { } else { do
{ do { } while (false); MOZ_ReportCrash("" "NS_SUCCEEDED(GetRequestMode(&requestMode))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5589); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(GetRequestMode(&requestMode))"
")"); do { *((volatile int*)__null) = 5589; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5590 if (requestMode != RequestMode::Navigate || LoadAllRedirectsSameOrigin()) {
5591 *_retval = BodyInfoAccess::ALLOW_ALL;
5592 return NS_OK;
5593 }
5594
5595 *_retval = BodyInfoAccess::ALLOW_SIZES;
5596 return NS_OK;
5597}
5598
5599// https://fetch.spec.whatwg.org/#tao-check
5600NS_IMETHODIMPnsresult
5601HttpBaseChannel::TimingAllowCheck(nsIPrincipal* aOrigin, bool* _retval) {
5602 nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
5603 nsCOMPtr<nsIPrincipal> resourcePrincipal;
5604 nsresult rv =
5605 ssm->GetChannelURIPrincipal(this, getter_AddRefs(resourcePrincipal));
5606 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0))) || !resourcePrincipal || !aOrigin) {
5607 *_retval = false;
5608 return NS_OK;
5609 }
5610
5611 bool sameOrigin = false;
5612 rv = resourcePrincipal->Equals(aOrigin, &sameOrigin);
Value stored to 'rv' is never read
5613
5614 nsAutoCString serializedOrigin;
5615 nsContentSecurityManager::GetSerializedOrigin(aOrigin, resourcePrincipal,
5616 serializedOrigin, mLoadInfo);
5617
5618 // All redirects are same origin
5619 if (sameOrigin && (!serializedOrigin.IsEmpty() &&
5620 !serializedOrigin.EqualsLiteral("null"))) {
5621 *_retval = true;
5622 return NS_OK;
5623 }
5624
5625 nsAutoCString headerValue;
5626 rv = GetResponseHeader("Timing-Allow-Origin"_ns, headerValue);
5627 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
5628 *_retval = false;
5629 return NS_OK;
5630 }
5631
5632 Tokenizer p(headerValue);
5633 Tokenizer::Token t;
5634
5635 p.Record();
5636 nsAutoCString headerItem;
5637 while (p.Next(t)) {
5638 if (t.Type() == Tokenizer::TOKEN_EOF ||
5639 t.Equals(Tokenizer::Token::Char(','))) {
5640 p.Claim(headerItem);
5641 nsHttp::TrimHTTPWhitespace(headerItem, headerItem);
5642 // If the list item contains a case-sensitive match for the value of the
5643 // origin, or a wildcard, return pass
5644 if (headerItem == serializedOrigin || headerItem == "*") {
5645 *_retval = true;
5646 return NS_OK;
5647 }
5648 // We start recording again for the following items in the list
5649 p.Record();
5650 }
5651 }
5652
5653 *_retval = false;
5654 return NS_OK;
5655}
5656
5657NS_IMETHODIMPnsresult
5658HttpBaseChannel::GetLaunchServiceWorkerStart(TimeStamp* _retval) {
5659 MOZ_ASSERT(_retval)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_retval)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_retval))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("_retval", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5659); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5659; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5660 *_retval = mLaunchServiceWorkerStart;
5661 return NS_OK;
5662}
5663
5664NS_IMETHODIMPnsresult
5665HttpBaseChannel::SetLaunchServiceWorkerStart(TimeStamp aTimeStamp) {
5666 mLaunchServiceWorkerStart = aTimeStamp;
5667 return NS_OK;
5668}
5669
5670NS_IMETHODIMPnsresult
5671HttpBaseChannel::GetLaunchServiceWorkerEnd(TimeStamp* _retval) {
5672 MOZ_ASSERT(_retval)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_retval)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_retval))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("_retval", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5672); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5672; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5673 *_retval = mLaunchServiceWorkerEnd;
5674 return NS_OK;
5675}
5676
5677NS_IMETHODIMPnsresult
5678HttpBaseChannel::SetLaunchServiceWorkerEnd(TimeStamp aTimeStamp) {
5679 mLaunchServiceWorkerEnd = aTimeStamp;
5680 return NS_OK;
5681}
5682
5683NS_IMETHODIMPnsresult
5684HttpBaseChannel::GetDispatchFetchEventStart(TimeStamp* _retval) {
5685 MOZ_ASSERT(_retval)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_retval)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_retval))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("_retval", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5685); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5685; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5686 *_retval = mDispatchFetchEventStart;
5687 return NS_OK;
5688}
5689
5690NS_IMETHODIMPnsresult
5691HttpBaseChannel::SetDispatchFetchEventStart(TimeStamp aTimeStamp) {
5692 mDispatchFetchEventStart = aTimeStamp;
5693 return NS_OK;
5694}
5695
5696NS_IMETHODIMPnsresult
5697HttpBaseChannel::GetDispatchFetchEventEnd(TimeStamp* _retval) {
5698 MOZ_ASSERT(_retval)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_retval)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_retval))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("_retval", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5698); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5698; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5699 *_retval = mDispatchFetchEventEnd;
5700 return NS_OK;
5701}
5702
5703NS_IMETHODIMPnsresult
5704HttpBaseChannel::SetDispatchFetchEventEnd(TimeStamp aTimeStamp) {
5705 mDispatchFetchEventEnd = aTimeStamp;
5706 return NS_OK;
5707}
5708
5709NS_IMETHODIMPnsresult
5710HttpBaseChannel::GetHandleFetchEventStart(TimeStamp* _retval) {
5711 MOZ_ASSERT(_retval)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_retval)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_retval))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("_retval", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5711); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5711; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5712 *_retval = mHandleFetchEventStart;
5713 return NS_OK;
5714}
5715
5716NS_IMETHODIMPnsresult
5717HttpBaseChannel::SetHandleFetchEventStart(TimeStamp aTimeStamp) {
5718 mHandleFetchEventStart = aTimeStamp;
5719 return NS_OK;
5720}
5721
5722NS_IMETHODIMPnsresult
5723HttpBaseChannel::GetHandleFetchEventEnd(TimeStamp* _retval) {
5724 MOZ_ASSERT(_retval)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(_retval)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(_retval))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("_retval", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5724); AnnotateMozCrashReason("MOZ_ASSERT" "(" "_retval" ")"
); do { *((volatile int*)__null) = 5724; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5725 *_retval = mHandleFetchEventEnd;
5726 return NS_OK;
5727}
5728
5729NS_IMETHODIMPnsresult
5730HttpBaseChannel::SetHandleFetchEventEnd(TimeStamp aTimeStamp) {
5731 mHandleFetchEventEnd = aTimeStamp;
5732 return NS_OK;
5733}
5734
5735NS_IMETHODIMPnsresult
5736HttpBaseChannel::GetDomainLookupStart(TimeStamp* _retval) {
5737 *_retval = mTransactionTimings.domainLookupStart;
5738 return NS_OK;
5739}
5740
5741NS_IMETHODIMPnsresult
5742HttpBaseChannel::GetDomainLookupEnd(TimeStamp* _retval) {
5743 *_retval = mTransactionTimings.domainLookupEnd;
5744 return NS_OK;
5745}
5746
5747NS_IMETHODIMPnsresult
5748HttpBaseChannel::GetConnectStart(TimeStamp* _retval) {
5749 *_retval = mTransactionTimings.connectStart;
5750 return NS_OK;
5751}
5752
5753NS_IMETHODIMPnsresult
5754HttpBaseChannel::GetTcpConnectEnd(TimeStamp* _retval) {
5755 *_retval = mTransactionTimings.tcpConnectEnd;
5756 return NS_OK;
5757}
5758
5759NS_IMETHODIMPnsresult
5760HttpBaseChannel::GetSecureConnectionStart(TimeStamp* _retval) {
5761 *_retval = mTransactionTimings.secureConnectionStart;
5762 return NS_OK;
5763}
5764
5765NS_IMETHODIMPnsresult
5766HttpBaseChannel::GetConnectEnd(TimeStamp* _retval) {
5767 *_retval = mTransactionTimings.connectEnd;
5768 return NS_OK;
5769}
5770
5771NS_IMETHODIMPnsresult
5772HttpBaseChannel::GetRequestStart(TimeStamp* _retval) {
5773 *_retval = mTransactionTimings.requestStart;
5774 return NS_OK;
5775}
5776
5777NS_IMETHODIMPnsresult
5778HttpBaseChannel::GetResponseStart(TimeStamp* _retval) {
5779 *_retval = mTransactionTimings.responseStart;
5780 return NS_OK;
5781}
5782
5783NS_IMETHODIMPnsresult
5784HttpBaseChannel::GetResponseEnd(TimeStamp* _retval) {
5785 *_retval = mTransactionTimings.responseEnd;
5786 return NS_OK;
5787}
5788
5789NS_IMETHODIMPnsresult
5790HttpBaseChannel::GetCacheReadStart(TimeStamp* _retval) {
5791 *_retval = mCacheReadStart;
5792 return NS_OK;
5793}
5794
5795NS_IMETHODIMPnsresult
5796HttpBaseChannel::GetCacheReadEnd(TimeStamp* _retval) {
5797 *_retval = mCacheReadEnd;
5798 return NS_OK;
5799}
5800
5801NS_IMETHODIMPnsresult
5802HttpBaseChannel::GetTransactionPending(TimeStamp* _retval) {
5803 *_retval = mTransactionTimings.transactionPending;
5804 return NS_OK;
5805}
5806
5807NS_IMETHODIMPnsresult
5808HttpBaseChannel::GetInitiatorType(nsAString& aInitiatorType) {
5809 aInitiatorType = mInitiatorType;
5810 return NS_OK;
5811}
5812
5813NS_IMETHODIMPnsresult
5814HttpBaseChannel::SetInitiatorType(const nsAString& aInitiatorType) {
5815 mInitiatorType = aInitiatorType;
5816 return NS_OK;
5817}
5818
5819#define IMPL_TIMING_ATTR(name) \
5820 NS_IMETHODIMPnsresult \
5821 HttpBaseChannel::Get##name##Time(PRTime* _retval) { \
5822 TimeStamp stamp; \
5823 Get##name(&stamp); \
5824 if (stamp.IsNull()) { \
5825 *_retval = 0; \
5826 return NS_OK; \
5827 } \
5828 *_retval = \
5829 mChannelCreationTime + \
5830 (PRTime)((stamp - mChannelCreationTimestamp).ToSeconds() * 1e6); \
5831 return NS_OK; \
5832 }
5833
5834IMPL_TIMING_ATTR(ChannelCreation)
5835IMPL_TIMING_ATTR(AsyncOpen)
5836IMPL_TIMING_ATTR(LaunchServiceWorkerStart)
5837IMPL_TIMING_ATTR(LaunchServiceWorkerEnd)
5838IMPL_TIMING_ATTR(DispatchFetchEventStart)
5839IMPL_TIMING_ATTR(DispatchFetchEventEnd)
5840IMPL_TIMING_ATTR(HandleFetchEventStart)
5841IMPL_TIMING_ATTR(HandleFetchEventEnd)
5842IMPL_TIMING_ATTR(DomainLookupStart)
5843IMPL_TIMING_ATTR(DomainLookupEnd)
5844IMPL_TIMING_ATTR(ConnectStart)
5845IMPL_TIMING_ATTR(TcpConnectEnd)
5846IMPL_TIMING_ATTR(SecureConnectionStart)
5847IMPL_TIMING_ATTR(ConnectEnd)
5848IMPL_TIMING_ATTR(RequestStart)
5849IMPL_TIMING_ATTR(ResponseStart)
5850IMPL_TIMING_ATTR(ResponseEnd)
5851IMPL_TIMING_ATTR(CacheReadStart)
5852IMPL_TIMING_ATTR(CacheReadEnd)
5853IMPL_TIMING_ATTR(RedirectStart)
5854IMPL_TIMING_ATTR(RedirectEnd)
5855IMPL_TIMING_ATTR(TransactionPending)
5856
5857#undef IMPL_TIMING_ATTR
5858
5859void HttpBaseChannel::MaybeReportTimingData() {
5860 // There is no point in continuing, since the performance object in the parent
5861 // isn't the same as the one in the child which will be reporting resource
5862 // performance.
5863 if (XRE_IsE10sParentProcess()) {
5864 return;
5865 }
5866
5867 // Devtools can create fetch requests on behalf the content document.
5868 // If we don't exclude these requests, they'd also be reported
5869 // to the content document.
5870 bool isInDevToolsContext;
5871 mLoadInfo->GetIsInDevToolsContext(&isInDevToolsContext);
5872 if (isInDevToolsContext) {
5873 return;
5874 }
5875
5876 mozilla::dom::PerformanceStorage* documentPerformance =
5877 mLoadInfo->GetPerformanceStorage();
5878 if (documentPerformance) {
5879 documentPerformance->AddEntry(this, this);
5880 return;
5881 }
5882
5883 if (!nsGlobalWindowInner::GetInnerWindowWithId(
5884 mLoadInfo->GetInnerWindowID())) {
5885 // The inner window is in a different process.
5886 dom::ContentChild* child = dom::ContentChild::GetSingleton();
5887
5888 if (!child) {
5889 return;
5890 }
5891 nsAutoString initiatorType;
5892 nsAutoString entryName;
5893
5894 UniquePtr<dom::PerformanceTimingData> performanceTimingData(
5895 dom::PerformanceTimingData::Create(this, this, 0, initiatorType,
5896 entryName));
5897 if (!performanceTimingData) {
5898 return;
5899 }
5900
5901 LoadInfoArgs loadInfoArgs;
5902 mozilla::ipc::LoadInfoToLoadInfoArgs(mLoadInfo, &loadInfoArgs);
5903 child->SendReportFrameTimingData(loadInfoArgs, entryName, initiatorType,
5904 std::move(performanceTimingData));
5905 }
5906}
5907
5908NS_IMETHODIMPnsresult
5909HttpBaseChannel::SetReportResourceTiming(bool enabled) {
5910 StoreReportTiming(enabled);
5911 return NS_OK;
5912}
5913
5914NS_IMETHODIMPnsresult
5915HttpBaseChannel::GetReportResourceTiming(bool* _retval) {
5916 *_retval = LoadReportTiming();
5917 return NS_OK;
5918}
5919
5920nsIURI* HttpBaseChannel::GetReferringPage() {
5921 nsCOMPtr<nsPIDOMWindowInner> pDomWindow = GetInnerDOMWindow();
5922 if (!pDomWindow) {
5923 return nullptr;
5924 }
5925 return pDomWindow->GetDocumentURI();
5926}
5927
5928nsPIDOMWindowInner* HttpBaseChannel::GetInnerDOMWindow() {
5929 nsCOMPtr<nsILoadContext> loadContext;
5930 NS_QueryNotificationCallbacks(this, loadContext);
5931 if (!loadContext) {
5932 return nullptr;
5933 }
5934 nsCOMPtr<mozIDOMWindowProxy> domWindow;
5935 loadContext->GetAssociatedWindow(getter_AddRefs(domWindow));
5936 if (!domWindow) {
5937 return nullptr;
5938 }
5939 auto* pDomWindow = nsPIDOMWindowOuter::From(domWindow);
5940 if (!pDomWindow) {
5941 return nullptr;
5942 }
5943 nsCOMPtr<nsPIDOMWindowInner> innerWindow =
5944 pDomWindow->GetCurrentInnerWindow();
5945 if (!innerWindow) {
5946 return nullptr;
5947 }
5948
5949 return innerWindow;
5950}
5951
5952//-----------------------------------------------------------------------------
5953// HttpBaseChannel::nsIThrottledInputChannel
5954//-----------------------------------------------------------------------------
5955
5956NS_IMETHODIMPnsresult
5957HttpBaseChannel::SetThrottleQueue(nsIInputChannelThrottleQueue* aQueue) {
5958 if (!XRE_IsParentProcess()) {
5959 return NS_ERROR_FAILURE;
5960 }
5961
5962 mThrottleQueue = aQueue;
5963 return NS_OK;
5964}
5965
5966NS_IMETHODIMPnsresult
5967HttpBaseChannel::GetThrottleQueue(nsIInputChannelThrottleQueue** aQueue) {
5968 NS_ENSURE_ARG_POINTER(aQueue)do { if ((__builtin_expect(!!(!(aQueue)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aQueue" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 5968); return NS_ERROR_INVALID_POINTER; } } while (false)
;
5969 nsCOMPtr<nsIInputChannelThrottleQueue> queue = mThrottleQueue;
5970 queue.forget(aQueue);
5971 return NS_OK;
5972}
5973
5974//------------------------------------------------------------------------------
5975
5976bool HttpBaseChannel::EnsureRequestContextID() {
5977 if (mRequestContextID) {
5978 // Already have a request context ID, no need to do the rest of this work
5979 LOG(("HttpBaseChannel::EnsureRequestContextID this=%p id=%" PRIx64, 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
, "HttpBaseChannel::EnsureRequestContextID this=%p id=%" "l" "x"
, this, mRequestContextID); } } while (0)
5980 mRequestContextID))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::EnsureRequestContextID this=%p id=%" "l" "x"
, this, mRequestContextID); } } while (0)
;
5981 return true;
5982 }
5983
5984 // Find the loadgroup at the end of the chain in order
5985 // to make sure all channels derived from the load group
5986 // use the same connection scope.
5987 nsCOMPtr<nsILoadGroupChild> childLoadGroup = do_QueryInterface(mLoadGroup);
5988 if (!childLoadGroup) {
5989 return false;
5990 }
5991
5992 nsCOMPtr<nsILoadGroup> rootLoadGroup;
5993 childLoadGroup->GetRootLoadGroup(getter_AddRefs(rootLoadGroup));
5994 if (!rootLoadGroup) {
5995 return false;
5996 }
5997
5998 // Set the load group connection scope on this channel and its transaction
5999 rootLoadGroup->GetRequestContextID(&mRequestContextID);
6000
6001 LOG(("HttpBaseChannel::EnsureRequestContextID this=%p id=%" PRIx64, 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
, "HttpBaseChannel::EnsureRequestContextID this=%p id=%" "l" "x"
, this, mRequestContextID); } } while (0)
6002 mRequestContextID))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::EnsureRequestContextID this=%p id=%" "l" "x"
, this, mRequestContextID); } } while (0)
;
6003
6004 return true;
6005}
6006
6007bool HttpBaseChannel::EnsureRequestContext() {
6008 if (mRequestContext) {
6009 // Already have a request context, no need to do the rest of this work
6010 return true;
6011 }
6012
6013 if (!EnsureRequestContextID()) {
6014 return false;
6015 }
6016
6017 nsIRequestContextService* rcsvc = gHttpHandler->GetRequestContextService();
6018 if (!rcsvc) {
6019 return false;
6020 }
6021
6022 rcsvc->GetRequestContext(mRequestContextID, getter_AddRefs(mRequestContext));
6023 return static_cast<bool>(mRequestContext);
6024}
6025
6026void HttpBaseChannel::EnsureBrowserId() {
6027 if (mBrowserId) {
6028 return;
6029 }
6030
6031 RefPtr<dom::BrowsingContext> bc;
6032 MOZ_ALWAYS_SUCCEEDS(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))do { if ((__builtin_expect(!!(((bool)(__builtin_expect(!!(!NS_FAILED_impl
(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))), 1)))
), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6032); AnnotateMozCrashReason("MOZ_CRASH(" "NS_SUCCEEDED(mLoadInfo->GetBrowsingContext(getter_AddRefs(bc)))"
")"); do { *((volatile int*)__null) = 6032; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
6033
6034 if (bc) {
6035 mBrowserId = bc->GetBrowserId();
6036 }
6037}
6038
6039void HttpBaseChannel::SetCorsPreflightParameters(
6040 const nsTArray<nsCString>& aUnsafeHeaders,
6041 bool aShouldStripRequestBodyHeader, bool aShouldStripAuthHeader) {
6042 MOZ_RELEASE_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/HttpBaseChannel.cpp"
, 6042); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!LoadRequestObserversCalled()"
")"); do { *((volatile int*)__null) = 6042; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6043
6044 StoreRequireCORSPreflight(true);
6045 mUnsafeHeaders = aUnsafeHeaders.Clone();
6046 if (aShouldStripRequestBodyHeader || aShouldStripAuthHeader) {
6047 mUnsafeHeaders.RemoveElementsBy([&](const nsCString& aHeader) {
6048 return (aShouldStripRequestBodyHeader &&
6049 (aHeader.LowerCaseEqualsASCII("content-type") ||
6050 aHeader.LowerCaseEqualsASCII("content-encoding") ||
6051 aHeader.LowerCaseEqualsASCII("content-language") ||
6052 aHeader.LowerCaseEqualsASCII("content-location"))) ||
6053 (aShouldStripAuthHeader &&
6054 aHeader.LowerCaseEqualsASCII("authorization"));
6055 });
6056 }
6057}
6058
6059void HttpBaseChannel::SetAltDataForChild(bool aIsForChild) {
6060 StoreAltDataForChild(aIsForChild);
6061}
6062
6063NS_IMETHODIMPnsresult
6064HttpBaseChannel::GetBlockAuthPrompt(bool* aValue) {
6065 if (!aValue) {
6066 return NS_ERROR_FAILURE;
6067 }
6068
6069 *aValue = LoadBlockAuthPrompt();
6070 return NS_OK;
6071}
6072
6073NS_IMETHODIMPnsresult
6074HttpBaseChannel::SetBlockAuthPrompt(bool aValue) {
6075 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/HttpBaseChannel.cpp"
, 6075); 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/HttpBaseChannel.cpp"
, 6075, 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/HttpBaseChannel.cpp"
, 6075); } } 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/HttpBaseChannel.cpp"
, 6075); AnnotateMozCrashReason("MOZ_ASSERT" "(" "LoadWasOpened()"
")"); do { *((volatile int*)__null) = 6075; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); return NS_ERROR_ALREADY_OPENED
; } } while (0)
;
6076
6077 StoreBlockAuthPrompt(aValue);
6078 return NS_OK;
6079}
6080
6081NS_IMETHODIMPnsresult
6082HttpBaseChannel::GetConnectionInfoHashKey(nsACString& aConnectionInfoHashKey) {
6083 if (!mConnectionInfo) {
6084 return NS_ERROR_FAILURE;
6085 }
6086 aConnectionInfoHashKey.Assign(mConnectionInfo->HashKey());
6087 return NS_OK;
6088}
6089
6090NS_IMETHODIMPnsresult
6091HttpBaseChannel::GetLastRedirectFlags(uint32_t* aValue) {
6092 NS_ENSURE_ARG(aValue)do { if ((__builtin_expect(!!(!(aValue)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aValue" ") failed", nullptr
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6092); return NS_ERROR_INVALID_ARG; } } while (false)
;
6093 *aValue = mLastRedirectFlags;
6094 return NS_OK;
6095}
6096
6097NS_IMETHODIMPnsresult
6098HttpBaseChannel::SetLastRedirectFlags(uint32_t aValue) {
6099 mLastRedirectFlags = aValue;
6100 return NS_OK;
6101}
6102
6103NS_IMETHODIMPnsresult
6104HttpBaseChannel::GetNavigationStartTimeStamp(TimeStamp* aTimeStamp) {
6105 return NS_ERROR_NOT_IMPLEMENTED;
6106}
6107
6108NS_IMETHODIMPnsresult
6109HttpBaseChannel::SetNavigationStartTimeStamp(TimeStamp aTimeStamp) {
6110 return NS_ERROR_NOT_IMPLEMENTED;
6111}
6112
6113nsresult HttpBaseChannel::CheckRedirectLimit(nsIURI* aNewURI,
6114 uint32_t aRedirectFlags) const {
6115 if (aRedirectFlags & nsIChannelEventSink::REDIRECT_INTERNAL) {
6116 // for internal redirect due to auth retry we do not have any limit
6117 // as we might restrict the number of times a user might retry
6118 // authentication
6119 if (aRedirectFlags & nsIChannelEventSink::REDIRECT_AUTH_RETRY) {
6120 return NS_OK;
6121 }
6122 // Some platform features, like Service Workers, depend on internal
6123 // redirects. We should allow some number of internal redirects above
6124 // and beyond the normal redirect limit so these features continue
6125 // to work.
6126 static const int8_t kMinInternalRedirects = 5;
6127
6128 if (mInternalRedirectCount >= (mRedirectionLimit + kMinInternalRedirects)) {
6129 LOG(("internal redirection limit reached!\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
, "internal redirection limit reached!\n"); } } while (0)
;
6130 return NS_ERROR_REDIRECT_LOOP;
6131 }
6132 return NS_OK;
6133 }
6134
6135 MOZ_ASSERT(aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY |do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY
| nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink
::REDIRECT_STS_UPGRADE))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aRedirectFlags & (nsIChannelEventSink
::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT
| nsIChannelEventSink::REDIRECT_STS_UPGRADE)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6137); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
")"); do { *((volatile int*)__null) = 6137; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6136 nsIChannelEventSink::REDIRECT_PERMANENT |do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY
| nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink
::REDIRECT_STS_UPGRADE))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aRedirectFlags & (nsIChannelEventSink
::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT
| nsIChannelEventSink::REDIRECT_STS_UPGRADE)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6137); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
")"); do { *((volatile int*)__null) = 6137; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6137 nsIChannelEventSink::REDIRECT_STS_UPGRADE))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY
| nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink
::REDIRECT_STS_UPGRADE))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aRedirectFlags & (nsIChannelEventSink
::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT
| nsIChannelEventSink::REDIRECT_STS_UPGRADE)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6137); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aRedirectFlags & (nsIChannelEventSink::REDIRECT_TEMPORARY | nsIChannelEventSink::REDIRECT_PERMANENT | nsIChannelEventSink::REDIRECT_STS_UPGRADE)"
")"); do { *((volatile int*)__null) = 6137; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6138
6139 if (mRedirectCount >= mRedirectionLimit) {
6140 LOG(("redirection limit reached!\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 limit reached!\n"); } } while (0)
;
6141 return NS_ERROR_REDIRECT_LOOP;
6142 }
6143
6144 // in case https-only mode is enabled which upgrades top-level requests to
6145 // https and the page answers with a redirect (meta, 302, win.location, ...)
6146 // then this method can break the cycle which causes the https-only exception
6147 // page to appear. Note that https-first mode breaks upgrade downgrade endless
6148 // loops within ShouldUpgradeHttpsFirstRequest because https-first does not
6149 // display an exception page but needs a soft fallback/downgrade.
6150 if (nsHTTPSOnlyUtils::IsUpgradeDowngradeEndlessLoop(
6151 mURI, aNewURI, mLoadInfo,
6152 {nsHTTPSOnlyUtils::UpgradeDowngradeEndlessLoopOptions::
6153 EnforceForHTTPSOnlyMode})) {
6154 // Mark that we didn't upgrade to https due to loop detection in https-only
6155 // mode to show https-only error page. We know that we are in https-only
6156 // mode, because we passed `EnforceForHTTPSOnlyMode` to
6157 // `IsUpgradeDowngradeEndlessLoop`. In other words we upgrade the request
6158 // with https-only mode, but then immediately cancel the request.
6159 uint32_t httpsOnlyStatus = mLoadInfo->GetHttpsOnlyStatus();
6160 if (httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_UNINITIALIZED) {
6161 httpsOnlyStatus ^= nsILoadInfo::HTTPS_ONLY_UNINITIALIZED;
6162 httpsOnlyStatus |=
6163 nsILoadInfo::HTTPS_ONLY_UPGRADED_LISTENER_NOT_REGISTERED;
6164 mLoadInfo->SetHttpsOnlyStatus(httpsOnlyStatus);
6165 }
6166
6167 LOG(("upgrade downgrade redirect loop!\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
, "upgrade downgrade redirect loop!\n"); } } while (0)
;
6168 return NS_ERROR_REDIRECT_LOOP;
6169 }
6170 // in case of http-first mode we want to add an exception to disable the
6171 // upgrade behavior if we have upgrade-downgrade loop to break the loop and
6172 // load the http request next
6173 if (mozilla::StaticPrefs::
6174 dom_security_https_first_add_exception_on_failure() &&
6175 nsHTTPSOnlyUtils::IsUpgradeDowngradeEndlessLoop(
6176 mURI, aNewURI, mLoadInfo,
6177 {nsHTTPSOnlyUtils::UpgradeDowngradeEndlessLoopOptions::
6178 EnforceForHTTPSFirstMode})) {
6179 nsHTTPSOnlyUtils::AddHTTPSFirstException(mURI, mLoadInfo);
6180 }
6181
6182 return NS_OK;
6183}
6184
6185// NOTE: This function duplicates code from nsBaseChannel. This will go away
6186// once HTTP uses nsBaseChannel (part of bug 312760)
6187/* static */
6188void HttpBaseChannel::CallTypeSniffers(void* aClosure, const uint8_t* aData,
6189 uint32_t aCount) {
6190 nsIChannel* chan = static_cast<nsIChannel*>(aClosure);
6191 const char* snifferType = [chan]() {
6192 if (RefPtr<nsHttpChannel> httpChannel = do_QueryObject(chan)) {
6193 switch (httpChannel->GetSnifferCategoryType()) {
6194 case SnifferCategoryType::NetContent:
6195 return NS_CONTENT_SNIFFER_CATEGORY"net-content-sniffers";
6196 case SnifferCategoryType::OpaqueResponseBlocking:
6197 return NS_ORB_SNIFFER_CATEGORY"orb-content-sniffers";
6198 case SnifferCategoryType::All:
6199 return NS_CONTENT_AND_ORB_SNIFFER_CATEGORY"net-and-orb-content-sniffers";
6200 default:
6201 MOZ_ASSERT_UNREACHABLE("Unexpected SnifferCategoryType!")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 SnifferCategoryType!" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6201); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected SnifferCategoryType!"
")"); do { *((volatile int*)__null) = 6201; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6202 }
6203 }
6204
6205 return NS_CONTENT_SNIFFER_CATEGORY"net-content-sniffers";
6206 }();
6207
6208 nsAutoCString newType;
6209 NS_SniffContent(snifferType, chan, aData, aCount, newType);
6210 if (!newType.IsEmpty()) {
6211 chan->SetContentType(newType);
6212 }
6213}
6214
6215template <class T>
6216static void ParseServerTimingHeader(
6217 const UniquePtr<T>& aHeader, nsTArray<nsCOMPtr<nsIServerTiming>>& aOutput) {
6218 if (!aHeader) {
6219 return;
6220 }
6221
6222 nsAutoCString serverTimingHeader;
6223 Unused << aHeader->GetHeader(nsHttp::Server_Timing, serverTimingHeader);
6224 if (serverTimingHeader.IsEmpty()) {
6225 return;
6226 }
6227
6228 ServerTimingParser parser(serverTimingHeader);
6229 parser.Parse();
6230
6231 nsTArray<nsCOMPtr<nsIServerTiming>> array = parser.TakeServerTimingHeaders();
6232 aOutput.AppendElements(array);
6233}
6234
6235NS_IMETHODIMPnsresult
6236HttpBaseChannel::GetServerTiming(nsIArray** aServerTiming) {
6237 nsresult rv;
6238 NS_ENSURE_ARG_POINTER(aServerTiming)do { if ((__builtin_expect(!!(!(aServerTiming)), 0))) { NS_DebugBreak
(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aServerTiming" ") failed"
, nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6238); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6239
6240 nsCOMPtr<nsIMutableArray> array = do_CreateInstance(NS_ARRAY_CONTRACTID"@mozilla.org/array;1", &rv);
6241 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/HttpBaseChannel.cpp"
, 6241); return rv; } } while (false)
;
6242
6243 nsTArray<nsCOMPtr<nsIServerTiming>> data;
6244 rv = GetNativeServerTiming(data);
6245 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/HttpBaseChannel.cpp"
, 6245); return rv; } } while (false)
;
6246
6247 for (const auto& entry : data) {
6248 array->AppendElement(entry);
6249 }
6250
6251 array.forget(aServerTiming);
6252 return NS_OK;
6253}
6254
6255NS_IMETHODIMPnsresult
6256HttpBaseChannel::GetNativeServerTiming(
6257 nsTArray<nsCOMPtr<nsIServerTiming>>& aServerTiming) {
6258 aServerTiming.Clear();
6259
6260 if (nsContentUtils::ComputeIsSecureContext(this)) {
6261 ParseServerTimingHeader(mResponseHead, aServerTiming);
6262 ParseServerTimingHeader(mResponseTrailers, aServerTiming);
6263 }
6264
6265 return NS_OK;
6266}
6267
6268NS_IMETHODIMPnsresult
6269HttpBaseChannel::CancelByURLClassifier(nsresult aErrorCode) {
6270 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/HttpBaseChannel.cpp"
, 6271); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6271; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6271 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/HttpBaseChannel.cpp"
, 6271); AnnotateMozCrashReason("MOZ_ASSERT" "(" "UrlClassifierFeatureFactory::IsClassifierBlockingErrorCode(aErrorCode)"
")"); do { *((volatile int*)__null) = 6271; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6272 return Cancel(aErrorCode);
6273}
6274
6275NS_IMETHODIMPnsresult HttpBaseChannel::SetIPv4Disabled() {
6276 mCaps |= NS_HTTP_DISABLE_IPV4(1 << 17);
6277 return NS_OK;
6278}
6279
6280NS_IMETHODIMPnsresult HttpBaseChannel::SetIPv6Disabled() {
6281 mCaps |= NS_HTTP_DISABLE_IPV6(1 << 18);
6282 return NS_OK;
6283}
6284
6285NS_IMETHODIMPnsresult HttpBaseChannel::GetResponseEmbedderPolicy(
6286 bool aIsOriginTrialCoepCredentiallessEnabled,
6287 nsILoadInfo::CrossOriginEmbedderPolicy* aOutPolicy) {
6288 *aOutPolicy = nsILoadInfo::EMBEDDER_POLICY_NULL;
6289 if (!mResponseHead) {
6290 return NS_ERROR_NOT_AVAILABLE;
6291 }
6292
6293 if (!nsContentUtils::ComputeIsSecureContext(this)) {
6294 // Feature is only available for secure contexts.
6295 return NS_OK;
6296 }
6297
6298 nsAutoCString content;
6299 Unused << mResponseHead->GetHeader(nsHttp::Cross_Origin_Embedder_Policy,
6300 content);
6301 *aOutPolicy = NS_GetCrossOriginEmbedderPolicyFromHeader(
6302 content, aIsOriginTrialCoepCredentiallessEnabled);
6303 return NS_OK;
6304}
6305
6306// Obtain a cross-origin opener-policy from a response response and a
6307// cross-origin opener policy initiator.
6308// https://gist.github.com/annevk/6f2dd8c79c77123f39797f6bdac43f3e
6309NS_IMETHODIMPnsresult HttpBaseChannel::ComputeCrossOriginOpenerPolicy(
6310 nsILoadInfo::CrossOriginOpenerPolicy aInitiatorPolicy,
6311 nsILoadInfo::CrossOriginOpenerPolicy* aOutPolicy) {
6312 MOZ_ASSERT(aOutPolicy)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aOutPolicy)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aOutPolicy))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("aOutPolicy", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6312); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aOutPolicy"
")"); do { *((volatile int*)__null) = 6312; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6313 *aOutPolicy = nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
6314
6315 if (!mResponseHead) {
6316 return NS_ERROR_NOT_AVAILABLE;
6317 }
6318
6319 // COOP headers are ignored for insecure-context loads.
6320 if (!nsContentUtils::ComputeIsSecureContext(this)) {
6321 return NS_OK;
6322 }
6323
6324 nsAutoCString openerPolicy;
6325 Unused << mResponseHead->GetHeader(nsHttp::Cross_Origin_Opener_Policy,
6326 openerPolicy);
6327
6328 // Cross-Origin-Opener-Policy = %s"same-origin" /
6329 // %s"same-origin-allow-popups" /
6330 // %s"unsafe-none"; case-sensitive
6331
6332 nsCOMPtr<nsISFVService> sfv = GetSFVService();
6333
6334 nsCOMPtr<nsISFVItem> item;
6335 nsresult rv = sfv->ParseItem(openerPolicy, getter_AddRefs(item));
6336 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6337 return rv;
6338 }
6339
6340 nsCOMPtr<nsISFVBareItem> value;
6341 rv = item->GetValue(getter_AddRefs(value));
6342 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6343 return rv;
6344 }
6345
6346 nsCOMPtr<nsISFVToken> token = do_QueryInterface(value);
6347 if (!token) {
6348 return NS_ERROR_UNEXPECTED;
6349 }
6350
6351 rv = token->GetValue(openerPolicy);
6352 if (NS_FAILED(rv)((bool)(__builtin_expect(!!(NS_FAILED_impl(rv)), 0)))) {
6353 return rv;
6354 }
6355
6356 nsILoadInfo::CrossOriginOpenerPolicy policy =
6357 nsILoadInfo::OPENER_POLICY_UNSAFE_NONE;
6358
6359 if (openerPolicy.EqualsLiteral("same-origin")) {
6360 policy = nsILoadInfo::OPENER_POLICY_SAME_ORIGIN;
6361 } else if (openerPolicy.EqualsLiteral("same-origin-allow-popups")) {
6362 policy = nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_ALLOW_POPUPS;
6363 }
6364 if (policy == nsILoadInfo::OPENER_POLICY_SAME_ORIGIN) {
6365 nsILoadInfo::CrossOriginEmbedderPolicy coep =
6366 nsILoadInfo::EMBEDDER_POLICY_NULL;
6367 bool isCoepCredentiallessEnabled;
6368 rv = mLoadInfo->GetIsOriginTrialCoepCredentiallessEnabledForTopLevel(
6369 &isCoepCredentiallessEnabled);
6370 if (!isCoepCredentiallessEnabled) {
6371 nsAutoCString originTrialToken;
6372 Unused << mResponseHead->GetHeader(nsHttp::OriginTrial, originTrialToken);
6373 if (!originTrialToken.IsEmpty()) {
6374 nsCOMPtr<nsIPrincipal> resultPrincipal;
6375 rv = nsContentUtils::GetSecurityManager()->GetChannelResultPrincipal(
6376 this, getter_AddRefs(resultPrincipal));
6377 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/HttpBaseChannel.cpp"
, 6377)
) {
6378 OriginTrials trials;
6379 trials.UpdateFromToken(NS_ConvertASCIItoUTF16(originTrialToken),
6380 resultPrincipal);
6381 if (trials.IsEnabled(OriginTrial::CoepCredentialless)) {
6382 isCoepCredentiallessEnabled = true;
6383 }
6384 }
6385 }
6386 }
6387
6388 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/HttpBaseChannel.cpp"
, 6388); return rv; } } while (false)
;
6389 if (NS_SUCCEEDED(((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetResponseEmbedderPolicy
(isCoepCredentiallessEnabled, &coep))), 1)))
6390 GetResponseEmbedderPolicy(isCoepCredentiallessEnabled, &coep))((bool)(__builtin_expect(!!(!NS_FAILED_impl(GetResponseEmbedderPolicy
(isCoepCredentiallessEnabled, &coep))), 1)))
&&
6391 (coep == nsILoadInfo::EMBEDDER_POLICY_REQUIRE_CORP ||
6392 coep == nsILoadInfo::EMBEDDER_POLICY_CREDENTIALLESS)) {
6393 policy =
6394 nsILoadInfo::OPENER_POLICY_SAME_ORIGIN_EMBEDDER_POLICY_REQUIRE_CORP;
6395 }
6396 }
6397
6398 *aOutPolicy = policy;
6399 return NS_OK;
6400}
6401
6402NS_IMETHODIMPnsresult
6403HttpBaseChannel::GetCrossOriginOpenerPolicy(
6404 nsILoadInfo::CrossOriginOpenerPolicy* aPolicy) {
6405 MOZ_ASSERT(aPolicy)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(aPolicy)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(aPolicy))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("aPolicy", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6405); AnnotateMozCrashReason("MOZ_ASSERT" "(" "aPolicy" ")"
); do { *((volatile int*)__null) = 6405; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6406 if (!aPolicy) {
6407 return NS_ERROR_INVALID_ARG;
6408 }
6409 // If this method is called before OnStartRequest (ie. before we call
6410 // ComputeCrossOriginOpenerPolicy) or if we were unable to compute the
6411 // policy we'll throw an error.
6412 if (!LoadOnStartRequestCalled()) {
6413 return NS_ERROR_NOT_AVAILABLE;
6414 }
6415 *aPolicy = mComputedCrossOriginOpenerPolicy;
6416 return NS_OK;
6417}
6418
6419NS_IMETHODIMPnsresult
6420HttpBaseChannel::HasCrossOriginOpenerPolicyMismatch(bool* aIsMismatch) {
6421 // This should only be called in parent process.
6422 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/HttpBaseChannel.cpp"
, 6422); AnnotateMozCrashReason("MOZ_ASSERT" "(" "XRE_IsParentProcess()"
")"); do { *((volatile int*)__null) = 6422; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6423 *aIsMismatch = LoadHasCrossOriginOpenerPolicyMismatch();
6424 return NS_OK;
6425}
6426
6427void HttpBaseChannel::MaybeFlushConsoleReports() {
6428 // Flush if we have a known window ID.
6429 if (mLoadInfo->GetInnerWindowID() > 0) {
6430 FlushReportsToConsole(mLoadInfo->GetInnerWindowID());
6431 return;
6432 }
6433
6434 // If this channel is part of a loadGroup, we can flush the console reports
6435 // immediately.
6436 nsCOMPtr<nsILoadGroup> loadGroup;
6437 nsresult rv = GetLoadGroup(getter_AddRefs(loadGroup));
6438 if (NS_SUCCEEDED(rv)((bool)(__builtin_expect(!!(!NS_FAILED_impl(rv)), 1))) && loadGroup) {
6439 FlushConsoleReports(loadGroup);
6440 }
6441}
6442
6443void HttpBaseChannel::DoDiagnosticAssertWhenOnStopNotCalledOnDestroy() {}
6444
6445bool HttpBaseChannel::Http3Allowed() const {
6446 bool isDirectOrNoProxy =
6447 mProxyInfo ? static_cast<nsProxyInfo*>(mProxyInfo.get())->IsDirect()
6448 : true;
6449 return !mUpgradeProtocolCallback && isDirectOrNoProxy &&
6450 !(mCaps & NS_HTTP_BE_CONSERVATIVE(1 << 11)) && !LoadBeConservative() &&
6451 LoadAllowHttp3();
6452}
6453
6454UniquePtr<nsHttpResponseHead>
6455HttpBaseChannel::MaybeCloneResponseHeadForCachedResource() {
6456 if (!mResponseHead) {
6457 return nullptr;
6458 }
6459
6460 return MakeUnique<nsHttpResponseHead>(*mResponseHead);
6461}
6462
6463void HttpBaseChannel::SetDummyChannelForCachedResource(
6464 const nsHttpResponseHead* aMaybeResponseHead /* = nullptr */) {
6465 mDummyChannelForCachedResource = true;
6466 MOZ_ASSERT(!mResponseHead,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mResponseHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mResponseHead))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mResponseHead"
" (" "SetDummyChannelForCachedResource should only be called once"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6467); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mResponseHead"
") (" "SetDummyChannelForCachedResource should only be called once"
")"); do { *((volatile int*)__null) = 6467; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6467 "SetDummyChannelForCachedResource should only be called once")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!mResponseHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!mResponseHead))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!mResponseHead"
" (" "SetDummyChannelForCachedResource should only be called once"
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6467); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!mResponseHead"
") (" "SetDummyChannelForCachedResource should only be called once"
")"); do { *((volatile int*)__null) = 6467; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6468 if (aMaybeResponseHead) {
6469 mResponseHead = MakeUnique<nsHttpResponseHead>(*aMaybeResponseHead);
6470 } else {
6471 mResponseHead = MakeUnique<nsHttpResponseHead>();
6472 }
6473}
6474
6475void HttpBaseChannel::SetEarlyHints(
6476 nsTArray<EarlyHintConnectArgs>&& aEarlyHints) {
6477 mEarlyHints = std::move(aEarlyHints);
6478}
6479
6480nsTArray<EarlyHintConnectArgs>&& HttpBaseChannel::TakeEarlyHints() {
6481 return std::move(mEarlyHints);
6482}
6483
6484NS_IMETHODIMPnsresult
6485HttpBaseChannel::SetEarlyHintPreloaderId(uint64_t aEarlyHintPreloaderId) {
6486 mEarlyHintPreloaderId = aEarlyHintPreloaderId;
6487 return NS_OK;
6488}
6489
6490NS_IMETHODIMPnsresult
6491HttpBaseChannel::GetEarlyHintPreloaderId(uint64_t* aEarlyHintPreloaderId) {
6492 NS_ENSURE_ARG_POINTER(aEarlyHintPreloaderId)do { if ((__builtin_expect(!!(!(aEarlyHintPreloaderId)), 0)))
{ NS_DebugBreak(NS_DEBUG_WARNING, "NS_ENSURE_TRUE(" "aEarlyHintPreloaderId"
") failed", nullptr, "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6492); return NS_ERROR_INVALID_POINTER; } } while (false)
;
6493 *aEarlyHintPreloaderId = mEarlyHintPreloaderId;
6494 return NS_OK;
6495}
6496
6497NS_IMETHODIMPnsresult
6498HttpBaseChannel::SetClassicScriptHintCharset(
6499 const nsAString& aClassicScriptHintCharset) {
6500 mClassicScriptHintCharset = aClassicScriptHintCharset;
6501 return NS_OK;
6502}
6503
6504NS_IMETHODIMPnsresult HttpBaseChannel::GetClassicScriptHintCharset(
6505 nsAString& aClassicScriptHintCharset) {
6506 aClassicScriptHintCharset = mClassicScriptHintCharset;
6507 return NS_OK;
6508}
6509
6510NS_IMETHODIMPnsresult HttpBaseChannel::SetDocumentCharacterSet(
6511 const nsAString& aDocumentCharacterSet) {
6512 mDocumentCharacterSet = aDocumentCharacterSet;
6513 return NS_OK;
6514}
6515
6516NS_IMETHODIMPnsresult HttpBaseChannel::GetDocumentCharacterSet(
6517 nsAString& aDocumentCharacterSet) {
6518 aDocumentCharacterSet = mDocumentCharacterSet;
6519 return NS_OK;
6520}
6521
6522void HttpBaseChannel::SetConnectionInfo(nsHttpConnectionInfo* aCI) {
6523 mConnectionInfo = aCI ? aCI->Clone() : nullptr;
6524}
6525
6526NS_IMETHODIMPnsresult
6527HttpBaseChannel::GetIsProxyUsed(bool* aIsProxyUsed) {
6528 if (mProxyInfo) {
6529 if (!static_cast<nsProxyInfo*>(mProxyInfo.get())->IsDirect()) {
6530 StoreIsProxyUsed(true);
6531 }
6532 }
6533 *aIsProxyUsed = LoadIsProxyUsed();
6534 return NS_OK;
6535}
6536
6537static void CollectORBBlockTelemetry(
6538 const OpaqueResponseBlockedTelemetryReason aTelemetryReason,
6539 ExtContentPolicy aPolicy) {
6540 Telemetry::LABELS_ORB_BLOCK_REASON label{
6541 static_cast<uint32_t>(aTelemetryReason)};
6542 Telemetry::AccumulateCategorical(label);
6543
6544 switch (aPolicy) {
6545 case ExtContentPolicy::TYPE_INVALID:
6546 Telemetry::AccumulateCategorical(
6547 Telemetry::LABELS_ORB_BLOCK_INITIATOR::INVALID);
6548 break;
6549 case ExtContentPolicy::TYPE_OTHER:
6550 Telemetry::AccumulateCategorical(
6551 Telemetry::LABELS_ORB_BLOCK_INITIATOR::OTHER);
6552 break;
6553 case ExtContentPolicy::TYPE_FETCH:
6554 Telemetry::AccumulateCategorical(
6555 Telemetry::LABELS_ORB_BLOCK_INITIATOR::BLOCKED_FETCH);
6556 break;
6557 case ExtContentPolicy::TYPE_SCRIPT:
6558 Telemetry::AccumulateCategorical(
6559 Telemetry::LABELS_ORB_BLOCK_INITIATOR::SCRIPT);
6560 break;
6561 case ExtContentPolicy::TYPE_JSON:
6562 Telemetry::AccumulateCategorical(
6563 Telemetry::LABELS_ORB_BLOCK_INITIATOR::JSON);
6564 break;
6565 case ExtContentPolicy::TYPE_IMAGE:
6566 Telemetry::AccumulateCategorical(
6567 Telemetry::LABELS_ORB_BLOCK_INITIATOR::IMAGE);
6568 break;
6569 case ExtContentPolicy::TYPE_STYLESHEET:
6570 Telemetry::AccumulateCategorical(
6571 Telemetry::LABELS_ORB_BLOCK_INITIATOR::STYLESHEET);
6572 break;
6573 case ExtContentPolicy::TYPE_XMLHTTPREQUEST:
6574 Telemetry::AccumulateCategorical(
6575 Telemetry::LABELS_ORB_BLOCK_INITIATOR::XMLHTTPREQUEST);
6576 break;
6577 case ExtContentPolicy::TYPE_DTD:
6578 Telemetry::AccumulateCategorical(
6579 Telemetry::LABELS_ORB_BLOCK_INITIATOR::DTD);
6580 break;
6581 case ExtContentPolicy::TYPE_FONT:
6582 Telemetry::AccumulateCategorical(
6583 Telemetry::LABELS_ORB_BLOCK_INITIATOR::FONT);
6584 break;
6585 case ExtContentPolicy::TYPE_MEDIA:
6586 Telemetry::AccumulateCategorical(
6587 Telemetry::LABELS_ORB_BLOCK_INITIATOR::MEDIA);
6588 break;
6589 case ExtContentPolicy::TYPE_CSP_REPORT:
6590 Telemetry::AccumulateCategorical(
6591 Telemetry::LABELS_ORB_BLOCK_INITIATOR::CSP_REPORT);
6592 break;
6593 case ExtContentPolicy::TYPE_XSLT:
6594 Telemetry::AccumulateCategorical(
6595 Telemetry::LABELS_ORB_BLOCK_INITIATOR::XSLT);
6596 break;
6597 case ExtContentPolicy::TYPE_IMAGESET:
6598 Telemetry::AccumulateCategorical(
6599 Telemetry::LABELS_ORB_BLOCK_INITIATOR::IMAGESET);
6600 break;
6601 case ExtContentPolicy::TYPE_WEB_MANIFEST:
6602 Telemetry::AccumulateCategorical(
6603 Telemetry::LABELS_ORB_BLOCK_INITIATOR::WEB_MANIFEST);
6604 break;
6605 case ExtContentPolicy::TYPE_SPECULATIVE:
6606 Telemetry::AccumulateCategorical(
6607 Telemetry::LABELS_ORB_BLOCK_INITIATOR::SPECULATIVE);
6608 break;
6609 case ExtContentPolicy::TYPE_UA_FONT:
6610 Telemetry::AccumulateCategorical(
6611 Telemetry::LABELS_ORB_BLOCK_INITIATOR::UA_FONT);
6612 break;
6613 case ExtContentPolicy::TYPE_PROXIED_WEBRTC_MEDIA:
6614 Telemetry::AccumulateCategorical(
6615 Telemetry::LABELS_ORB_BLOCK_INITIATOR::PROXIED_WEBRTC_MEDIA);
6616 break;
6617 case ExtContentPolicy::TYPE_PING:
6618 Telemetry::AccumulateCategorical(
6619 Telemetry::LABELS_ORB_BLOCK_INITIATOR::PING);
6620 break;
6621 case ExtContentPolicy::TYPE_BEACON:
6622 Telemetry::AccumulateCategorical(
6623 Telemetry::LABELS_ORB_BLOCK_INITIATOR::BEACON);
6624 break;
6625 case ExtContentPolicy::TYPE_WEB_TRANSPORT:
6626 Telemetry::AccumulateCategorical(
6627 Telemetry::LABELS_ORB_BLOCK_INITIATOR::WEB_TRANSPORT);
6628 break;
6629 case ExtContentPolicy::TYPE_WEB_IDENTITY:
6630 // Don't bother extending the telemetry for this.
6631 Telemetry::AccumulateCategorical(
6632 Telemetry::LABELS_ORB_BLOCK_INITIATOR::OTHER);
6633 break;
6634 case ExtContentPolicy::TYPE_DOCUMENT:
6635 case ExtContentPolicy::TYPE_SUBDOCUMENT:
6636 case ExtContentPolicy::TYPE_OBJECT:
6637 case ExtContentPolicy::TYPE_OBJECT_SUBREQUEST:
6638 case ExtContentPolicy::TYPE_WEBSOCKET:
6639 case ExtContentPolicy::TYPE_SAVEAS_DOWNLOAD:
6640 MOZ_ASSERT_UNREACHABLE("Shouldn't block this type")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: "
"Shouldn't block this type" ")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6640); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Shouldn't block this type" ")");
do { *((volatile int*)__null) = 6640; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6641 // DOCUMENT, SUBDOCUMENT, OBJECT, OBJECT_SUBREQUEST,
6642 // WEBSOCKET and SAVEAS_DOWNLOAD are excluded from ORB
6643 Telemetry::AccumulateCategorical(
6644 Telemetry::LABELS_ORB_BLOCK_INITIATOR::EXCLUDED);
6645 break;
6646 // Do not add default: so that compilers can catch the missing case.
6647 }
6648}
6649
6650void HttpBaseChannel::LogORBError(
6651 const nsAString& aReason,
6652 const OpaqueResponseBlockedTelemetryReason aTelemetryReason) {
6653 auto policy = mLoadInfo->GetExternalContentPolicyType();
6654 CollectORBBlockTelemetry(aTelemetryReason, policy);
6655
6656 // Blocking `ExtContentPolicy::TYPE_BEACON` isn't web observable, so keep
6657 // quiet in the console about blocking it.
6658 if (policy == ExtContentPolicy::TYPE_BEACON) {
6659 return;
6660 }
6661
6662 RefPtr<dom::Document> doc;
6663 mLoadInfo->GetLoadingDocument(getter_AddRefs(doc));
6664
6665 nsAutoCString uri;
6666 nsresult rv = nsContentUtils::AnonymizeURI(mURI, uri);
6667 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/HttpBaseChannel.cpp"
, 6667)
) {
6668 return;
6669 }
6670
6671 uint64_t contentWindowId;
6672 GetTopLevelContentWindowId(&contentWindowId);
6673 if (contentWindowId) {
6674 nsContentUtils::ReportToConsoleByWindowID(
6675 u"A resource is blocked by OpaqueResponseBlocking, please check browser console for details."_ns,
6676 nsIScriptError::warningFlag, "ORB"_ns, contentWindowId,
6677 SourceLocation(mURI.get()));
6678 }
6679
6680 AutoTArray<nsString, 2> params;
6681 params.AppendElement(NS_ConvertUTF8toUTF16(uri));
6682 params.AppendElement(aReason);
6683 nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "ORB"_ns, doc,
6684 nsContentUtils::eNECKO_PROPERTIES,
6685 "ResourceBlockedORB", params);
6686}
6687
6688NS_IMETHODIMPnsresult HttpBaseChannel::SetEarlyHintLinkType(
6689 uint32_t aEarlyHintLinkType) {
6690 mEarlyHintLinkType = aEarlyHintLinkType;
6691 return NS_OK;
6692}
6693
6694NS_IMETHODIMPnsresult HttpBaseChannel::GetEarlyHintLinkType(
6695 uint32_t* aEarlyHintLinkType) {
6696 *aEarlyHintLinkType = mEarlyHintLinkType;
6697 return NS_OK;
6698}
6699
6700NS_IMETHODIMPnsresult
6701HttpBaseChannel::SetHasContentDecompressed(bool aValue) {
6702 LOG(("HttpBaseChannel::SetHasContentDecompressed [this=%p value=%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
, "HttpBaseChannel::SetHasContentDecompressed [this=%p value=%d]\n"
, this, aValue); } } while (0)
6703 aValue))do { const ::mozilla::LogModule* moz_real_module = mozilla::net
::gHttpLog; if ((__builtin_expect(!!(mozilla::detail::log_test
(moz_real_module, mozilla::LogLevel::Verbose)), 0))) { mozilla
::detail::log_print(moz_real_module, mozilla::LogLevel::Verbose
, "HttpBaseChannel::SetHasContentDecompressed [this=%p value=%d]\n"
, this, aValue); } } while (0)
;
6704 mHasContentDecompressed = aValue;
6705 return NS_OK;
6706}
6707NS_IMETHODIMPnsresult
6708HttpBaseChannel::GetHasContentDecompressed(bool* value) {
6709 *value = mHasContentDecompressed;
6710 return NS_OK;
6711}
6712
6713NS_IMETHODIMPnsresult
6714HttpBaseChannel::SetRenderBlocking(bool aRenderBlocking) {
6715 mRenderBlocking = aRenderBlocking;
6716 return NS_OK;
6717}
6718
6719NS_IMETHODIMPnsresult
6720HttpBaseChannel::GetRenderBlocking(bool* aRenderBlocking) {
6721 *aRenderBlocking = mRenderBlocking;
6722 return NS_OK;
6723}
6724
6725NS_IMETHODIMPnsresult HttpBaseChannel::GetLastTransportStatus(
6726 nsresult* aLastTransportStatus) {
6727 return NS_ERROR_NOT_IMPLEMENTED;
6728}
6729
6730void HttpBaseChannel::SetFetchPriorityDOM(
6731 mozilla::dom::FetchPriority aPriority) {
6732 switch (aPriority) {
6733 case mozilla::dom::FetchPriority::Auto:
6734 SetFetchPriority(nsIClassOfService::FETCHPRIORITY_AUTO);
6735 return;
6736 case mozilla::dom::FetchPriority::High:
6737 SetFetchPriority(nsIClassOfService::FETCHPRIORITY_HIGH);
6738 return;
6739 case mozilla::dom::FetchPriority::Low:
6740 SetFetchPriority(nsIClassOfService::FETCHPRIORITY_LOW);
6741 return;
6742 default:
6743 MOZ_ASSERT_UNREACHABLE()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: "
")", "/var/lib/jenkins/workspace/firefox-scan-build/netwerk/protocol/http/HttpBaseChannel.cpp"
, 6743); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " ")"); do { *((volatile int*)__null
) = 6743; __attribute__((nomerge)) ::abort(); } while (false)
; } } while (false)
;
6744 }
6745}
6746
6747} // namespace net
6748} // namespace mozilla