From fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:14:29 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- netwerk/base/ContentRange.cpp | 64 +++++++++++++++++++++++ netwerk/base/ContentRange.h | 45 ++++++++++++++++ netwerk/base/NetUtil.sys.mjs | 4 +- netwerk/base/Predictor.cpp | 12 +++-- netwerk/base/moz.build | 3 ++ netwerk/base/nsBaseChannel.cpp | 68 +++++++----------------- netwerk/base/nsBaseChannel.h | 46 +++-------------- netwerk/base/nsIBaseChannel.idl | 63 ++++++++++++++++++++++ netwerk/base/nsISecureBrowserUI.idl | 4 -- netwerk/base/nsISystemProxySettings.idl | 5 ++ netwerk/base/nsIURLParser.idl | 6 --- netwerk/base/nsLoadGroup.cpp | 6 --- netwerk/base/nsNetUtil.cpp | 6 ++- netwerk/base/nsPACMan.cpp | 11 +++- netwerk/base/nsProtocolProxyService.cpp | 92 +++++++++++++++++++++------------ netwerk/base/nsProtocolProxyService.h | 10 ++-- netwerk/base/nsStandardURL.cpp | 4 +- netwerk/base/nsTransportUtils.cpp | 16 +++--- netwerk/base/nsURLHelper.cpp | 17 +++--- netwerk/base/nsURLHelper.h | 15 +++--- 20 files changed, 326 insertions(+), 171 deletions(-) create mode 100644 netwerk/base/ContentRange.cpp create mode 100644 netwerk/base/ContentRange.h create mode 100644 netwerk/base/nsIBaseChannel.idl (limited to 'netwerk/base') diff --git a/netwerk/base/ContentRange.cpp b/netwerk/base/ContentRange.cpp new file mode 100644 index 0000000000..dfae132550 --- /dev/null +++ b/netwerk/base/ContentRange.cpp @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ContentRange.h" +#include "nsContentUtils.h" + +mozilla::net::ContentRange::ContentRange(const nsACString& aRangeHeader, + uint64_t aSize) + : mStart(0), mEnd(0), mSize(0) { + auto parsed = nsContentUtils::ParseSingleRangeRequest(aRangeHeader, true); + // https://fetch.spec.whatwg.org/#ref-for-simple-range-header-value%E2%91%A1 + // If rangeValue is failure, then return a network error. + if (!parsed) { + return; + } + + // Sanity check: ParseSingleRangeRequest should handle these two cases. + // If rangeEndValue and rangeStartValue are null, then return failure. + MOZ_ASSERT(parsed->Start().isSome() || parsed->End().isSome()); + // If rangeStartValue and rangeEndValue are numbers, and rangeStartValue + // is greater than rangeEndValue, then return failure. + MOZ_ASSERT(parsed->Start().isNothing() || parsed->End().isNothing() || + *parsed->Start() <= *parsed->End()); + + // https://fetch.spec.whatwg.org/#ref-for-simple-range-header-value%E2%91%A1 + // If rangeStart is null: + if (parsed->Start().isNothing()) { + // Set rangeStart to fullLength − rangeEnd. + mStart = aSize - *parsed->End(); + + // Set rangeEnd to rangeStart + rangeEnd − 1. + mEnd = mStart + *parsed->End() - 1; + + // Otherwise: + } else { + // If rangeStart is greater than or equal to fullLength, then return a + // network error. + if (*parsed->Start() >= aSize) { + return; + } + mStart = *parsed->Start(); + + // If rangeEnd is null or rangeEnd is greater than or equal to fullLength, + // then set rangeEnd to fullLength − 1. + if (parsed->End().isNothing() || *parsed->End() >= aSize) { + mEnd = aSize - 1; + } else { + mEnd = *parsed->End(); + } + } + mSize = aSize; +} + +void mozilla::net::ContentRange::AsHeader(nsACString& aOutString) const { + aOutString.Assign("bytes "_ns); + aOutString.AppendInt(mStart); + aOutString.AppendLiteral("-"); + aOutString.AppendInt(mEnd); + aOutString.AppendLiteral("/"); + aOutString.AppendInt(mSize); +} diff --git a/netwerk/base/ContentRange.h b/netwerk/base/ContentRange.h new file mode 100644 index 0000000000..36b15214eb --- /dev/null +++ b/netwerk/base/ContentRange.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set et cin ts=4 sw=2 sts=2: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef ContentRange_h__ +#define ContentRange_h__ + +#include "mozilla/Maybe.h" +#include "nsString.h" +#include "nsISupportsImpl.h" + +// nsIBaseChannel subclasses may support range headers when accessed via +// Fetch or XMLHTTPRequest, even if they are not HTTP assets and so do not +// normally have access to headers (such as the blob URLs). The ContentRange +// class helps to encapsulate much of the common logic involved in parsing, +// storing, validating, and writing out Content-Range headers. + +namespace mozilla::net { + +class ContentRange { + private: + ~ContentRange() = default; + + uint64_t mStart{0}; + uint64_t mEnd{0}; + uint64_t mSize{0}; + + public: + uint64_t Start() const { return mStart; } + uint64_t End() const { return mEnd; } + uint64_t Size() const { return mSize; } + bool IsValid() const { return mStart < mSize; } + ContentRange(uint64_t aStart, uint64_t aEnd, uint64_t aSize) + : mStart(aStart), mEnd(aEnd), mSize(aSize) {} + ContentRange(const nsACString& aRangeHeader, uint64_t aSize); + void AsHeader(nsACString& aOutString) const; + + NS_INLINE_DECL_REFCOUNTING(ContentRange) +}; + +} // namespace mozilla::net + +#endif // ContentRange_h__ diff --git a/netwerk/base/NetUtil.sys.mjs b/netwerk/base/NetUtil.sys.mjs index 679c9979a7..c952fdeb33 100644 --- a/netwerk/base/NetUtil.sys.mjs +++ b/netwerk/base/NetUtil.sys.mjs @@ -66,7 +66,7 @@ export var NetUtil = { var observer; if (aCallback) { observer = { - onStartRequest(aRequest) {}, + onStartRequest() {}, onStopRequest(aRequest, aStatusCode) { aCallback(aStatusCode); }, @@ -118,7 +118,7 @@ export var NetUtil = { "@mozilla.org/network/simple-stream-listener;1" ].createInstance(Ci.nsISimpleStreamListener); listener.init(pipe.outputStream, { - onStartRequest(aRequest) {}, + onStartRequest() {}, onStopRequest(aRequest, aStatusCode) { pipe.outputStream.close(); aCallback(pipe.inputStream, aStatusCode, aRequest); diff --git a/netwerk/base/Predictor.cpp b/netwerk/base/Predictor.cpp index de19d0e06e..0c604d9d9a 100644 --- a/netwerk/base/Predictor.cpp +++ b/netwerk/base/Predictor.cpp @@ -487,7 +487,9 @@ Predictor::PredictNative(nsIURI* targetURI, nsIURI* sourceURI, PREDICTOR_LOG(("Predictor::Predict")); if (IsNeckoChild()) { - MOZ_DIAGNOSTIC_ASSERT(gNeckoChild); + if (!gNeckoChild) { + return NS_ERROR_FAILURE; + } PREDICTOR_LOG((" called on child process")); // If two different threads are predicting concurently, this will be @@ -1237,7 +1239,9 @@ Predictor::LearnNative(nsIURI* targetURI, nsIURI* sourceURI, PREDICTOR_LOG(("Predictor::Learn")); if (IsNeckoChild()) { - MOZ_DIAGNOSTIC_ASSERT(gNeckoChild); + if (!gNeckoChild) { + return NS_ERROR_FAILURE; + } PREDICTOR_LOG((" called on child process")); @@ -1715,7 +1719,9 @@ Predictor::Reset() { PREDICTOR_LOG(("Predictor::Reset")); if (IsNeckoChild()) { - MOZ_DIAGNOSTIC_ASSERT(gNeckoChild); + if (!gNeckoChild) { + return NS_ERROR_FAILURE; + } PREDICTOR_LOG((" forwarding to parent process")); gNeckoChild->SendPredReset(); diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build index e069a5f296..adeac62cd8 100644 --- a/netwerk/base/moz.build +++ b/netwerk/base/moz.build @@ -18,6 +18,7 @@ XPIDL_SOURCES += [ "nsIAuthPromptCallback.idl", "nsIAuthPromptProvider.idl", "nsIBackgroundFileSaver.idl", + "nsIBaseChannel.idl", "nsIBufferedStreams.idl", "nsIByteRangeRequest.idl", "nsICacheInfoChannel.idl", @@ -157,6 +158,7 @@ EXPORTS.mozilla += [ EXPORTS.mozilla.net += [ "CacheInfoIPCTypes.h", "CaptivePortalService.h", + "ContentRange.h", "Dashboard.h", "DashboardTypes.h", "DefaultURI.h", @@ -178,6 +180,7 @@ UNIFIED_SOURCES += [ "ArrayBufferInputStream.cpp", "BackgroundFileSaver.cpp", "CaptivePortalService.cpp", + "ContentRange.cpp", "Dashboard.cpp", "DefaultURI.cpp", "EventTokenBucket.cpp", diff --git a/netwerk/base/nsBaseChannel.cpp b/netwerk/base/nsBaseChannel.cpp index df8aa23db4..2671b5886a 100644 --- a/netwerk/base/nsBaseChannel.cpp +++ b/netwerk/base/nsBaseChannel.cpp @@ -8,7 +8,6 @@ #include "nsContentUtils.h" #include "nsURLHelper.h" #include "nsNetCID.h" -#include "nsMimeTypes.h" #include "nsUnknownDecoder.h" #include "nsIScriptSecurityManager.h" #include "nsMimeTypes.h" @@ -302,6 +301,7 @@ NS_IMPL_RELEASE(nsBaseChannel) NS_INTERFACE_MAP_BEGIN(nsBaseChannel) NS_INTERFACE_MAP_ENTRY(nsIRequest) NS_INTERFACE_MAP_ENTRY(nsIChannel) + NS_INTERFACE_MAP_ENTRY(nsIBaseChannel) NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableRequest) NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) NS_INTERFACE_MAP_ENTRY(nsITransportEventSink) @@ -967,58 +967,28 @@ void nsBaseChannel::SetupNeckoTarget() { mNeckoTarget = GetMainThreadSerialEventTarget(); } -nsBaseChannel::ContentRange::ContentRange(const nsACString& aRangeHeader, - uint64_t aSize) - : mStart(0), mEnd(0), mSize(0) { - auto parsed = nsContentUtils::ParseSingleRangeRequest(aRangeHeader, true); - // https://fetch.spec.whatwg.org/#ref-for-simple-range-header-value%E2%91%A1 - // If rangeValue is failure, then return a network error. - if (!parsed) { - return; +NS_IMETHODIMP nsBaseChannel::GetContentRange( + RefPtr* aRange) { + if (aRange) { + *aRange = mContentRange; } + return NS_OK; +} - // Sanity check: ParseSingleRangeRequest should handle these two cases. - // If rangeEndValue and rangeStartValue are null, then return failure. - MOZ_ASSERT(parsed->Start().isSome() || parsed->End().isSome()); - // If rangeStartValue and rangeEndValue are numbers, and rangeStartValue - // is greater than rangeEndValue, then return failure. - MOZ_ASSERT(parsed->Start().isNothing() || parsed->End().isNothing() || - *parsed->Start() <= *parsed->End()); - - // https://fetch.spec.whatwg.org/#ref-for-simple-range-header-value%E2%91%A1 - // If rangeStart is null: - if (parsed->Start().isNothing()) { - // Set rangeStart to fullLength − rangeEnd. - mStart = aSize - *parsed->End(); - - // Set rangeEnd to rangeStart + rangeEnd − 1. - mEnd = mStart + *parsed->End() - 1; - - // Otherwise: - } else { - // If rangeStart is greater than or equal to fullLength, then return a - // network error. - if (*parsed->Start() >= aSize) { - return; - } - mStart = *parsed->Start(); +NS_IMETHODIMP nsBaseChannel::SetContentRange( + RefPtr aRange) { + mContentRange = aRange; + return NS_OK; +} - // If rangeEnd is null or rangeEnd is greater than or equal to fullLength, - // then set rangeEnd to fullLength − 1. - if (parsed->End().isNothing() || *parsed->End() >= aSize) { - mEnd = aSize - 1; - } else { - mEnd = *parsed->End(); - } +NS_IMETHODIMP nsBaseChannel::GetFullMimeType(RefPtr>* aOut) { + if (aOut) { + *aOut = mFullMimeType; } - mSize = aSize; + return NS_OK; } -void nsBaseChannel::ContentRange::AsHeader(nsACString& aOutString) const { - aOutString.Assign("bytes "_ns); - aOutString.AppendInt(mStart); - aOutString.AppendLiteral("-"); - aOutString.AppendInt(mEnd); - aOutString.AppendLiteral("/"); - aOutString.AppendInt(mSize); +NS_IMETHODIMP nsBaseChannel::SetFullMimeType(RefPtr> aType) { + mFullMimeType = aType; + return NS_OK; } diff --git a/netwerk/base/nsBaseChannel.h b/netwerk/base/nsBaseChannel.h index 179a24bf45..c0db8e2500 100644 --- a/netwerk/base/nsBaseChannel.h +++ b/netwerk/base/nsBaseChannel.h @@ -6,13 +6,16 @@ #ifndef nsBaseChannel_h__ #define nsBaseChannel_h__ +#include "mozilla/dom/MimeType.h" #include "mozilla/Maybe.h" #include "mozilla/MozPromise.h" #include "mozilla/UniquePtr.h" +#include "mozilla/net/ContentRange.h" #include "mozilla/net/NeckoTargetHolder.h" #include "mozilla/net/PrivateBrowsingChannel.h" #include "nsHashPropertyBag.h" #include "nsIAsyncVerifyRedirectCallback.h" +#include "nsIBaseChannel.h" #include "nsIChannel.h" #include "nsIInterfaceRequestor.h" #include "nsILoadGroup.h" @@ -46,6 +49,7 @@ class nsICancelable; class nsBaseChannel : public nsHashPropertyBag, + public nsIBaseChannel, public nsIChannel, public nsIThreadRetargetableRequest, public nsIInterfaceRequestor, @@ -58,6 +62,7 @@ class nsBaseChannel NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIREQUEST NS_DECL_NSICHANNEL + NS_DECL_NSIBASECHANNEL NS_DECL_NSIINTERFACEREQUESTOR NS_DECL_NSITRANSPORTEVENTSINK NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK @@ -197,44 +202,6 @@ class nsBaseChannel return mPumpingData || mWaitingOnAsyncRedirect; } - // Blob requests may specify a range header. We must parse, validate, and - // store that info in a place where BlobURLInputStream::StoreBlobImplStream - // can access it. This class helps to encapsulate that logic. - class ContentRange { - private: - uint64_t mStart; - uint64_t mEnd; - uint64_t mSize; - - public: - uint64_t Start() const { return mStart; } - uint64_t End() const { return mEnd; } - uint64_t Size() const { return mSize; } - bool IsValid() const { return mStart < mSize; } - ContentRange() : mStart(0), mEnd(0), mSize(0) {} - ContentRange(uint64_t aStart, uint64_t aEnd, uint64_t aSize) - : mStart(aStart), mEnd(aEnd), mSize(aSize) {} - ContentRange(const nsACString& aRangeHeader, uint64_t aSize); - void AsHeader(nsACString& aOutString) const; - }; - - const mozilla::Maybe& GetContentRange() const { - return mContentRange; - } - - void SetContentRange(uint64_t aStart, uint64_t aEnd, uint64_t aSize) { - mContentRange.emplace(ContentRange(aStart, aEnd, aSize)); - } - - bool SetContentRange(const nsACString& aRangeHeader, uint64_t aSize) { - auto range = ContentRange(aRangeHeader, aSize); - if (!range.IsValid()) { - return false; - } - mContentRange.emplace(range); - return true; - } - // Helper function for querying the channel's notification callbacks. template void GetCallback(nsCOMPtr& result) { @@ -325,7 +292,8 @@ class nsBaseChannel bool mWaitingOnAsyncRedirect{false}; bool mOpenRedirectChannel{false}; uint32_t mRedirectFlags{0}; - mozilla::Maybe mContentRange; + RefPtr mContentRange; + RefPtr mFullMimeType; protected: nsCString mContentType; diff --git a/netwerk/base/nsIBaseChannel.idl b/netwerk/base/nsIBaseChannel.idl new file mode 100644 index 0000000000..5f2fe1517d --- /dev/null +++ b/netwerk/base/nsIBaseChannel.idl @@ -0,0 +1,63 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +%{C++ +#include "mozilla/dom/MimeType.h" +#include "mozilla/net/ContentRange.h" +%} + +/** + * The nsIBaseChannel interface allows C++ code to query the interface + * of channels safely to gain access to content range functionality. + * This allows subclasses to optionally handle range-requests on their + * types using fetch/XMLHttpRequest even if they are not accessed via + * HTTP and therefore normally do not have support for headers. + */ + +native ContentRangeRef(RefPtr); +native MimeTypeRef(RefPtr>); + +[uuid(036d5cd7-9a53-40e3-9c72-c2ffaa15aa2b)] +interface nsIBaseChannel : nsISupports { + + /** + * Used by fetch and XMLHttpRequest to get only the range specified in the + * Range request header (if given) for the response body (e.g, for blob URLs) + */ + attribute ContentRangeRef contentRange; + + /** + * Used by fetch and XMLHttpRequest to get the standards-compliant value they + * should set for the Content-Type header on response (if nullptr, they will + * use Firefox-specific values from nsIChannel::GetContentType and GetCharset). + */ + attribute MimeTypeRef fullMimeType; + +%{C++ + RefPtr ContentRange() { + RefPtr range; + mozilla::Unused << GetContentRange(&range); + return range; + } + + bool SetContentRangeFromHeader(const nsACString& aHeader, uint64_t aSize) { + RefPtr range = + new mozilla::net::ContentRange(aHeader, aSize); + if (!range->IsValid()) { + return false; + } + SetContentRange(range); + return true; + } + + RefPtr FullMimeType() { + RefPtr type; + mozilla::Unused << GetFullMimeType(&type); + return type; + } +%} + +}; diff --git a/netwerk/base/nsISecureBrowserUI.idl b/netwerk/base/nsISecureBrowserUI.idl index 3984310d93..6197a9adff 100644 --- a/netwerk/base/nsISecureBrowserUI.idl +++ b/netwerk/base/nsISecureBrowserUI.idl @@ -15,7 +15,3 @@ interface nsISecureBrowserUI : nsISupports readonly attribute bool isSecureContext; readonly attribute nsITransportSecurityInfo secInfo; }; - -%{C++ -#define NS_SECURE_BROWSER_UI_CONTRACTID "@mozilla.org/secure_browser_ui;1" -%} diff --git a/netwerk/base/nsISystemProxySettings.idl b/netwerk/base/nsISystemProxySettings.idl index 9cd561fb64..935da146af 100644 --- a/netwerk/base/nsISystemProxySettings.idl +++ b/netwerk/base/nsISystemProxySettings.idl @@ -39,4 +39,9 @@ interface nsISystemProxySettings : nsISupports in AUTF8String testScheme, in AUTF8String testHost, in int32_t testPort); + + /** + * Check if system settings are configured to use WPAD + */ + readonly attribute bool systemWPADSetting; }; diff --git a/netwerk/base/nsIURLParser.idl b/netwerk/base/nsIURLParser.idl index 3d6ac19b8c..209c04d888 100644 --- a/netwerk/base/nsIURLParser.idl +++ b/netwerk/base/nsIURLParser.idl @@ -90,9 +90,3 @@ interface nsIURLParser : nsISupports out unsigned long basenamePos, out long basenameLen, out unsigned long extensionPos, out long extensionLen); }; - -%{C++ -// url parser key for use with the category manager -// mapping from scheme to url parser. -#define NS_IURLPARSER_KEY "@mozilla.org/urlparser;1" -%} diff --git a/netwerk/base/nsLoadGroup.cpp b/netwerk/base/nsLoadGroup.cpp index 3e2445b6ae..0122e13ad2 100644 --- a/netwerk/base/nsLoadGroup.cpp +++ b/netwerk/base/nsLoadGroup.cpp @@ -1021,12 +1021,6 @@ void nsLoadGroup::TelemetryReportChannel(nsITimedChannel* aTimedChannel, if (httpChannel && NS_SUCCEEDED(httpChannel->GetHasHTTPSRR(&hasHTTPSRR)) && cacheReadStart.IsNull() && cacheReadEnd.IsNull() && !requestStart.IsNull()) { - nsCString key = (hasHTTPSRR) ? ((aDefaultRequest) ? "uses_https_rr_page"_ns - : "uses_https_rr_sub"_ns) - : ((aDefaultRequest) ? "no_https_rr_page"_ns - : "no_https_rr_sub"_ns); - Telemetry::AccumulateTimeDelta(Telemetry::HTTPS_RR_OPEN_TO_FIRST_SENT, key, - asyncOpen, requestStart); TimeDuration elapsed = requestStart - asyncOpen; if (hasHTTPSRR) { if (aDefaultRequest) { diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp index 4c03cf63c3..ac86d8fa32 100644 --- a/netwerk/base/nsNetUtil.cpp +++ b/netwerk/base/nsNetUtil.cpp @@ -96,7 +96,9 @@ #include "nsSocketTransportService2.h" #include "nsViewSourceHandler.h" #include "nsJARURI.h" -#include "nsIconURI.h" +#ifndef XP_IOS +# include "nsIconURI.h" +#endif #include "nsAboutProtocolHandler.h" #include "nsResProtocolHandler.h" #include "mozilla/net/ExtensionProtocolHandler.h" @@ -1951,11 +1953,13 @@ nsresult NS_NewURI(nsIURI** aURI, const nsACString& aSpec, .Finalize(aURI); } +#ifndef XP_IOS if (scheme.EqualsLiteral("moz-icon")) { return NS_MutateURI(new nsMozIconURI::Mutator()) .SetSpec(aSpec) .Finalize(aURI); } +#endif #ifdef MOZ_WIDGET_GTK if (scheme.EqualsLiteral("smb") || scheme.EqualsLiteral("sftp")) { diff --git a/netwerk/base/nsPACMan.cpp b/netwerk/base/nsPACMan.cpp index 0cf66c8ee6..d4c6c4bd79 100644 --- a/netwerk/base/nsPACMan.cpp +++ b/netwerk/base/nsPACMan.cpp @@ -502,6 +502,13 @@ nsresult nsPACMan::PostQuery(PendingPACQuery* query) { return NS_OK; } +// check if proxy settings are configured for WPAD +bool IsProxyConfigValidForWPAD(int proxyConfigType, bool wpadSystemSettings) { + return proxyConfigType == nsIProtocolProxyService::PROXYCONFIG_WPAD || + (proxyConfigType == nsIProtocolProxyService::PROXYCONFIG_SYSTEM && + wpadSystemSettings); +} + nsresult nsPACMan::LoadPACFromURI(const nsACString& aSpec) { return LoadPACFromURI(aSpec, true); } @@ -541,7 +548,7 @@ nsresult nsPACMan::LoadPACFromURI(const nsACString& aSpec, if (NS_FAILED(rv)) { return rv; } - if (mProxyConfigType != nsIProtocolProxyService::PROXYCONFIG_WPAD) { + if (!IsProxyConfigValidForWPAD(mProxyConfigType, mAutoDetect)) { LOG( ("LoadPACFromURI - Aborting WPAD autodetection because the pref " "doesn't match anymore")); @@ -595,7 +602,7 @@ nsresult nsPACMan::GetPACFromDHCP(nsACString& aSpec) { nsresult nsPACMan::ConfigureWPAD(nsACString& aSpec) { MOZ_ASSERT(!NS_IsMainThread(), "wrong thread"); - if (mProxyConfigType != nsIProtocolProxyService::PROXYCONFIG_WPAD) { + if (!IsProxyConfigValidForWPAD(mProxyConfigType, mAutoDetect)) { LOG( ("ConfigureWPAD - Aborting WPAD autodetection because the pref " "doesn't match anymore")); diff --git a/netwerk/base/nsProtocolProxyService.cpp b/netwerk/base/nsProtocolProxyService.cpp index 9f721f94e8..7ccfc9363a 100644 --- a/netwerk/base/nsProtocolProxyService.cpp +++ b/netwerk/base/nsProtocolProxyService.cpp @@ -621,28 +621,29 @@ nsAsyncResolveRequest::AsyncApplyFilters::Cancel(nsresult reason) { return NS_OK; } -// Bug 1366133: make GetPACURI off-main-thread since it may hang on Windows -// platform -class AsyncGetPACURIRequest final : public nsIRunnable { +// Bug 1366133: make GetPACURI and GetSystemWPADSetting off-main-thread since it +// may hang on Windows platform +class AsyncGetPACURIRequestOrSystemWPADSetting final : public nsIRunnable { public: NS_DECL_THREADSAFE_ISUPPORTS using CallbackFunc = nsresult (nsProtocolProxyService::*)(bool, bool, nsresult, - const nsACString&); + const nsACString&, + bool); - AsyncGetPACURIRequest(nsProtocolProxyService* aService, - CallbackFunc aCallback, - nsISystemProxySettings* aSystemProxySettings, - bool aMainThreadOnly, bool aForceReload, - bool aResetPACThread) + AsyncGetPACURIRequestOrSystemWPADSetting( + nsProtocolProxyService* aService, CallbackFunc aCallback, + nsISystemProxySettings* aSystemProxySettings, bool aMainThreadOnly, + bool aForceReload, bool aResetPACThread, bool aSystemWPADAllowed) : mIsMainThreadOnly(aMainThreadOnly), mService(aService), mServiceHolder(do_QueryObject(aService)), mCallback(aCallback), mSystemProxySettings(aSystemProxySettings), mForceReload(aForceReload), - mResetPACThread(aResetPACThread) { + mResetPACThread(aResetPACThread), + mSystemWPADAllowed(aSystemWPADAllowed) { MOZ_ASSERT(NS_IsMainThread()); Unused << mIsMainThreadOnly; } @@ -650,21 +651,30 @@ class AsyncGetPACURIRequest final : public nsIRunnable { NS_IMETHOD Run() override { MOZ_ASSERT(NS_IsMainThread() == mIsMainThreadOnly); + nsresult rv; nsCString pacUri; - nsresult rv = mSystemProxySettings->GetPACURI(pacUri); + bool systemWPADSetting = false; + if (mSystemWPADAllowed) { + mSystemProxySettings->GetSystemWPADSetting(&systemWPADSetting); + } + + rv = mSystemProxySettings->GetPACURI(pacUri); nsCOMPtr event = - NewNonOwningCancelableRunnableMethod( - "AsyncGetPACURIRequestCallback", mService, mCallback, mForceReload, - mResetPACThread, rv, pacUri); + NewNonOwningCancelableRunnableMethod( + "AsyncGetPACURIRequestOrSystemWPADSettingCallback", mService, + mCallback, mForceReload, mResetPACThread, rv, pacUri, + systemWPADSetting); return NS_DispatchToMainThread(event); } private: - ~AsyncGetPACURIRequest() { - NS_ReleaseOnMainThread("AsyncGetPACURIRequest::mServiceHolder", - mServiceHolder.forget()); + ~AsyncGetPACURIRequestOrSystemWPADSetting() { + NS_ReleaseOnMainThread( + "AsyncGetPACURIRequestOrSystemWPADSetting::mServiceHolder", + mServiceHolder.forget()); } bool mIsMainThreadOnly; @@ -676,9 +686,10 @@ class AsyncGetPACURIRequest final : public nsIRunnable { bool mForceReload; bool mResetPACThread; + bool mSystemWPADAllowed; }; -NS_IMPL_ISUPPORTS(AsyncGetPACURIRequest, nsIRunnable) +NS_IMPL_ISUPPORTS(AsyncGetPACURIRequestOrSystemWPADSetting, nsIRunnable) //---------------------------------------------------------------------------- @@ -847,8 +858,8 @@ nsresult nsProtocolProxyService::ReloadNetworkPAC() { return NS_OK; } -nsresult nsProtocolProxyService::AsyncConfigureFromPAC(bool aForceReload, - bool aResetPACThread) { +nsresult nsProtocolProxyService::AsyncConfigureWPADOrFromPAC( + bool aForceReload, bool aResetPACThread, bool aSystemWPADAllowed) { MOZ_ASSERT(NS_IsMainThread()); bool mainThreadOnly; @@ -857,9 +868,10 @@ nsresult nsProtocolProxyService::AsyncConfigureFromPAC(bool aForceReload, return rv; } - nsCOMPtr req = new AsyncGetPACURIRequest( - this, &nsProtocolProxyService::OnAsyncGetPACURI, mSystemProxySettings, - mainThreadOnly, aForceReload, aResetPACThread); + nsCOMPtr req = new AsyncGetPACURIRequestOrSystemWPADSetting( + this, &nsProtocolProxyService::OnAsyncGetPACURIOrSystemWPADSetting, + mSystemProxySettings, mainThreadOnly, aForceReload, aResetPACThread, + aSystemWPADAllowed); if (mainThreadOnly) { return req->Run(); @@ -869,17 +881,24 @@ nsresult nsProtocolProxyService::AsyncConfigureFromPAC(bool aForceReload, nsIEventTarget::DISPATCH_NORMAL); } -nsresult nsProtocolProxyService::OnAsyncGetPACURI(bool aForceReload, - bool aResetPACThread, - nsresult aResult, - const nsACString& aUri) { +nsresult nsProtocolProxyService::OnAsyncGetPACURIOrSystemWPADSetting( + bool aForceReload, bool aResetPACThread, nsresult aResult, + const nsACString& aUri, bool aSystemWPADSetting) { MOZ_ASSERT(NS_IsMainThread()); if (aResetPACThread) { ResetPACThread(); } - if (NS_SUCCEEDED(aResult) && !aUri.IsEmpty()) { + if (aSystemWPADSetting) { + if (mSystemProxySettings || !mPACMan) { + mSystemProxySettings = nullptr; + ResetPACThread(); + } + + nsAutoCString tempString; + ConfigureFromPAC(EmptyCString(), false); + } else if (NS_SUCCEEDED(aResult) && !aUri.IsEmpty()) { ConfigureFromPAC(PromiseFlatCString(aUri), aForceReload); } @@ -960,7 +979,8 @@ void nsProtocolProxyService::PrefsChanged(nsIPrefBranch* prefBranch, auto invokeCallback = MakeScopeExit([&] { NotifyProxyConfigChangedInternal(); }); - if (!pref || !strcmp(pref, PROXY_PREF("type"))) { + if (!pref || !strcmp(pref, PROXY_PREF("type")) || + !strcmp(pref, PROXY_PREF("system_wpad"))) { int32_t type = -1; rv = prefBranch->GetIntPref(PROXY_PREF("type"), &type); if (NS_SUCCEEDED(rv)) { @@ -1076,9 +1096,12 @@ void nsProtocolProxyService::PrefsChanged(nsIPrefBranch* prefBranch, } else if (mProxyConfig == PROXYCONFIG_WPAD) { LOG(("Auto-detecting proxy - Reset Pac Thread")); ResetPACThread(); + } else if (mSystemProxySettings && mProxyConfig == PROXYCONFIG_SYSTEM && + StaticPrefs::network_proxy_system_wpad()) { + AsyncConfigureWPADOrFromPAC(false, false, true); } else if (mSystemProxySettings) { // Get System Proxy settings if available - AsyncConfigureFromPAC(false, false); + AsyncConfigureWPADOrFromPAC(false, false, false); } if (!tempString.IsEmpty() || mProxyConfig == PROXYCONFIG_WPAD) { ConfigureFromPAC(tempString, false); @@ -1478,7 +1501,8 @@ nsProtocolProxyService::ReloadPAC() { prefs->GetCharPref(PROXY_PREF("autoconfig_url"), pacSpec); } else if (type == PROXYCONFIG_SYSTEM) { if (mSystemProxySettings) { - AsyncConfigureFromPAC(true, true); + AsyncConfigureWPADOrFromPAC(true, true, + StaticPrefs::network_proxy_system_wpad()); } else { ResetPACThread(); } @@ -1555,7 +1579,8 @@ nsresult nsProtocolProxyService::AsyncResolveInternal( bool usePACThread; // adapt to realtime changes in the system proxy service - if (mProxyConfig == PROXYCONFIG_SYSTEM) { + if (mProxyConfig == PROXYCONFIG_SYSTEM && + !StaticPrefs::network_proxy_system_wpad()) { nsCOMPtr sp2 = do_GetService(NS_SYSTEMPROXYSETTINGS_CONTRACTID); if (sp2 != mSystemProxySettings) { @@ -2190,7 +2215,8 @@ nsresult nsProtocolProxyService::Resolve_Internal(nsIChannel* channel, } // Proxy auto config magic... - if (mProxyConfig == PROXYCONFIG_PAC || mProxyConfig == PROXYCONFIG_WPAD) { + if (mProxyConfig == PROXYCONFIG_PAC || mProxyConfig == PROXYCONFIG_WPAD || + StaticPrefs::network_proxy_system_wpad()) { // Do not query PAC now. *usePACThread = true; return NS_OK; diff --git a/netwerk/base/nsProtocolProxyService.h b/netwerk/base/nsProtocolProxyService.h index 394450ca6e..2c102a808e 100644 --- a/netwerk/base/nsProtocolProxyService.h +++ b/netwerk/base/nsProtocolProxyService.h @@ -320,9 +320,13 @@ class nsProtocolProxyService final : public nsIProtocolProxyService2, nsresult ResetPACThread(); nsresult ReloadNetworkPAC(); - nsresult AsyncConfigureFromPAC(bool aForceReload, bool aResetPACThread); - nsresult OnAsyncGetPACURI(bool aForceReload, bool aResetPACThread, - nsresult aResult, const nsACString& aUri); + nsresult AsyncConfigureWPADOrFromPAC(bool aForceReload, bool aResetPACThread, + bool aSystemWPADAllowed); + nsresult OnAsyncGetPACURIOrSystemWPADSetting(bool aForceReload, + bool aResetPACThread, + nsresult aResult, + const nsACString& aUri, + bool aSystemWPADSetting); public: // The Sun Forte compiler and others implement older versions of the diff --git a/netwerk/base/nsStandardURL.cpp b/netwerk/base/nsStandardURL.cpp index de3578c439..d9b0c23ead 100644 --- a/netwerk/base/nsStandardURL.cpp +++ b/netwerk/base/nsStandardURL.cpp @@ -292,8 +292,8 @@ void nsStandardURL::SanityCheck() { (uint32_t)mExtension.mPos, (int32_t)mExtension.mLen, (uint32_t)mQuery.mPos, (int32_t)mQuery.mLen, (uint32_t)mRef.mPos, (int32_t)mRef.mLen); - CrashReporter::AnnotateCrashReport(CrashReporter::Annotation::URLSegments, - msg); + CrashReporter::RecordAnnotationNSCString( + CrashReporter::Annotation::URLSegments, msg); MOZ_CRASH("nsStandardURL::SanityCheck failed"); } diff --git a/netwerk/base/nsTransportUtils.cpp b/netwerk/base/nsTransportUtils.cpp index df53ead198..242907da08 100644 --- a/netwerk/base/nsTransportUtils.cpp +++ b/netwerk/base/nsTransportUtils.cpp @@ -24,24 +24,21 @@ class nsTransportEventSinkProxy : public nsITransportEventSink { nsTransportEventSinkProxy(nsITransportEventSink* sink, nsIEventTarget* target) : mSink(sink), mTarget(target), - mLock("nsTransportEventSinkProxy.mLock"), - mLastEvent(nullptr) { - NS_ADDREF(mSink); - } + mLock("nsTransportEventSinkProxy.mLock") {} private: virtual ~nsTransportEventSinkProxy() { // our reference to mSink could be the last, so be sure to release // it on the target thread. otherwise, we could get into trouble. NS_ProxyRelease("nsTransportEventSinkProxy::mSink", mTarget, - dont_AddRef(mSink)); + mSink.forget()); } public: - nsITransportEventSink* mSink; + nsCOMPtr mSink; nsCOMPtr mTarget; Mutex mLock MOZ_UNANNOTATED; - nsTransportStatusEvent* mLastEvent; + RefPtr mLastEvent; }; class nsTransportStatusEvent : public Runnable { @@ -69,11 +66,14 @@ class nsTransportStatusEvent : public Runnable { // if not coalescing all, then last event may not equal self! { MutexAutoLock lock(mProxy->mLock); - if (mProxy->mLastEvent == this) mProxy->mLastEvent = nullptr; + if (mProxy->mLastEvent == this) { + mProxy->mLastEvent = nullptr; + } } mProxy->mSink->OnTransportStatus(mTransport, mStatus, mProgress, mProgressMax); + mProxy = nullptr; return NS_OK; } diff --git a/netwerk/base/nsURLHelper.cpp b/netwerk/base/nsURLHelper.cpp index 3850c6865a..ca82b0cd00 100644 --- a/netwerk/base/nsURLHelper.cpp +++ b/netwerk/base/nsURLHelper.cpp @@ -1236,8 +1236,8 @@ void URLParams::DecodeString(const nsACString& aInput, nsAString& aOutput) { /* static */ bool URLParams::ParseNextInternal(const char*& aStart, const char* const aEnd, - nsAString* aOutDecodedName, - nsAString* aOutDecodedValue) { + bool aShouldDecode, nsAString* aOutputName, + nsAString* aOutputValue) { nsDependentCSubstring string; const char* const iter = std::find(aStart, aEnd, '&'); @@ -1267,9 +1267,14 @@ bool URLParams::ParseNextInternal(const char*& aStart, const char* const aEnd, name.Rebind(string, 0); } - DecodeString(name, *aOutDecodedName); - DecodeString(value, *aOutDecodedValue); + if (aShouldDecode) { + DecodeString(name, *aOutputName); + DecodeString(value, *aOutputValue); + return true; + } + ConvertString(name, *aOutputName); + ConvertString(value, *aOutputValue); return true; } @@ -1278,7 +1283,7 @@ bool URLParams::Extract(const nsACString& aInput, const nsAString& aName, nsAString& aValue) { aValue.SetIsVoid(true); return !URLParams::Parse( - aInput, [&aName, &aValue](const nsAString& name, nsString&& value) { + aInput, true, [&aName, &aValue](const nsAString& name, nsString&& value) { if (aName == name) { aValue = std::move(value); return false; @@ -1291,7 +1296,7 @@ void URLParams::ParseInput(const nsACString& aInput) { // Remove all the existing data before parsing a new input. DeleteAll(); - URLParams::Parse(aInput, [this](nsString&& name, nsString&& value) { + URLParams::Parse(aInput, true, [this](nsString&& name, nsString&& value) { mParams.AppendElement(Param{std::move(name), std::move(value)}); return true; }); diff --git a/netwerk/base/nsURLHelper.h b/netwerk/base/nsURLHelper.h index f5ccc8bac6..36844e6e4b 100644 --- a/netwerk/base/nsURLHelper.h +++ b/netwerk/base/nsURLHelper.h @@ -257,19 +257,20 @@ class URLParams final { * true otherwise */ template - static bool Parse(const nsACString& aInput, ParamHandler aParamHandler) { + static bool Parse(const nsACString& aInput, bool aShouldDecode, + ParamHandler aParamHandler) { const char* start = aInput.BeginReading(); const char* const end = aInput.EndReading(); while (start != end) { - nsAutoString decodedName; - nsAutoString decodedValue; + nsAutoString name; + nsAutoString value; - if (!ParseNextInternal(start, end, &decodedName, &decodedValue)) { + if (!ParseNextInternal(start, end, aShouldDecode, &name, &value)) { continue; } - if (!aParamHandler(std::move(decodedName), std::move(decodedValue))) { + if (!aParamHandler(std::move(name), std::move(value))) { return false; } } @@ -357,8 +358,8 @@ class URLParams final { static void DecodeString(const nsACString& aInput, nsAString& aOutput); static void ConvertString(const nsACString& aInput, nsAString& aOutput); static bool ParseNextInternal(const char*& aStart, const char* aEnd, - nsAString* aOutDecodedName, - nsAString* aOutDecodedValue); + bool aShouldDecode, nsAString* aOutputName, + nsAString* aOutputValue); struct Param { nsString mKey; -- cgit v1.2.3