diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:35:49 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:35:49 +0000 |
commit | d8bbc7858622b6d9c278469aab701ca0b609cddf (patch) | |
tree | eff41dc61d9f714852212739e6b3738b82a2af87 /netwerk | |
parent | Releasing progress-linux version 125.0.3-1~progress7.99u1. (diff) | |
download | firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.tar.xz firefox-d8bbc7858622b6d9c278469aab701ca0b609cddf.zip |
Merging upstream version 126.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'netwerk')
118 files changed, 1621 insertions, 507 deletions
diff --git a/netwerk/base/LoadInfo.cpp b/netwerk/base/LoadInfo.cpp index eb90324c37..6be031113f 100644 --- a/netwerk/base/LoadInfo.cpp +++ b/netwerk/base/LoadInfo.cpp @@ -20,6 +20,7 @@ #include "mozilla/dom/ToJSValue.h" #include "mozilla/dom/BrowsingContext.h" #include "mozilla/dom/WindowGlobalParent.h" +#include "mozilla/dom/nsHTTPSOnlyUtils.h" #include "mozilla/net/CookieJarSettings.h" #include "mozilla/NullPrincipal.h" #include "mozilla/StaticPrefs_network.h" @@ -216,8 +217,9 @@ LoadInfo::LoadInfo( mDocumentHasUserInteracted = aLoadingContext->OwnerDoc()->UserHasInteracted(); - // Inherit HTTPS-Only Mode flags from parent document - mHttpsOnlyStatus |= aLoadingContext->OwnerDoc()->HttpsOnlyStatus(); + // Inherit HTTPS-Only Mode flags from parent document. + mHttpsOnlyStatus |= nsHTTPSOnlyUtils::GetStatusForSubresourceLoad( + aLoadingContext->OwnerDoc()->HttpsOnlyStatus()); // When the element being loaded is a frame, we choose the frame's window // for the window ID and the frame element's window as the parent @@ -528,7 +530,9 @@ LoadInfo::LoadInfo(dom::WindowGlobalParent* aParentWGP, parentBC->UsePrivateBrowsing()); } - mHttpsOnlyStatus |= aParentWGP->HttpsOnlyStatus(); + // Inherit HTTPS-Only Mode flags from embedder document. + mHttpsOnlyStatus |= nsHTTPSOnlyUtils::GetStatusForSubresourceLoad( + aParentWGP->HttpsOnlyStatus()); // For chrome BC, the mPrivateBrowsingId remains 0 even its // UsePrivateBrowsing() is true, so we only update the mPrivateBrowsingId in diff --git a/netwerk/base/http-sfv/nsIStructuredFieldValues.idl b/netwerk/base/http-sfv/nsIStructuredFieldValues.idl index 3f02b33953..20b0392ac9 100644 --- a/netwerk/base/http-sfv/nsIStructuredFieldValues.idl +++ b/netwerk/base/http-sfv/nsIStructuredFieldValues.idl @@ -256,7 +256,7 @@ interface nsISFVService: nsISupports * The following functions create bare item of specific type. */ nsISFVInteger newInteger(in long long value); - nsISFVBool newBool(in bool value); + nsISFVBool newBool(in boolean value); nsISFVDecimal newDecimal(in double value); nsISFVString newString(in ACString value); nsISFVByteSeq newByteSequence(in ACString value); diff --git a/netwerk/base/mozurl/src/lib.rs b/netwerk/base/mozurl/src/lib.rs index 21be5f7e8b..ac33f0f8a8 100644 --- a/netwerk/base/mozurl/src/lib.rs +++ b/netwerk/base/mozurl/src/lib.rs @@ -214,7 +214,10 @@ pub extern "C" fn mozurl_real_port(url: &MozURL) -> i32 { #[no_mangle] pub extern "C" fn mozurl_host_port(url: &MozURL) -> SpecSlice { - (&url[Position::BeforeHost..Position::BeforePath]).into() + if url.port().is_some() { + return (&url[Position::BeforeHost..Position::BeforePath]).into(); + } + url.host_str().unwrap_or("").into() } #[no_mangle] @@ -436,6 +439,11 @@ pub extern "C" fn mozurl_set_hostname(url: &mut MozURL, host: &nsACString) -> ns #[no_mangle] pub extern "C" fn mozurl_set_port_no(url: &mut MozURL, new_port: i32) -> nsresult { debug_assert_mut!(url); + + if new_port > u16::MAX as i32 { + return NS_ERROR_UNEXPECTED; + } + if url.cannot_be_a_base() { return NS_ERROR_MALFORMED_URI; } diff --git a/netwerk/base/nsIBackgroundFileSaver.idl b/netwerk/base/nsIBackgroundFileSaver.idl index 0b26852c28..d9a5ba20a5 100644 --- a/netwerk/base/nsIBackgroundFileSaver.idl +++ b/netwerk/base/nsIBackgroundFileSaver.idl @@ -130,7 +130,7 @@ interface nsIBackgroundFileSaver : nsISupports * rather than deleted, if the operation fails or is canceled. This is * generally set for downloads that use temporary ".part" files. */ - void setTarget(in nsIFile aTarget, in bool aKeepPartial); + void setTarget(in nsIFile aTarget, in boolean aKeepPartial); /** * Terminates access to the output file, then notifies the observer with the diff --git a/netwerk/base/nsICaptivePortalService.idl b/netwerk/base/nsICaptivePortalService.idl index e4867765d7..0814ecb665 100644 --- a/netwerk/base/nsICaptivePortalService.idl +++ b/netwerk/base/nsICaptivePortalService.idl @@ -10,7 +10,7 @@ interface nsICaptivePortalServiceCallback : nsISupports /** * Invoke callbacks after captive portal detection finished. */ - void complete(in bool success, in nsresult error); + void complete(in boolean success, in nsresult error); }; /** diff --git a/netwerk/base/nsIChannel.idl b/netwerk/base/nsIChannel.idl index 2269c4faa8..a29bd1a463 100644 --- a/netwerk/base/nsIChannel.idl +++ b/netwerk/base/nsIChannel.idl @@ -359,7 +359,7 @@ interface nsIChannel : nsIRequest * Note: May have the wrong value if called before OnStartRequest as we * don't know the MIME type yet. */ - readonly attribute bool isDocument; + readonly attribute boolean isDocument; %{ C++ inline bool IsDocument() diff --git a/netwerk/base/nsIClassOfService.idl b/netwerk/base/nsIClassOfService.idl index 5426eabbcc..7b133107de 100644 --- a/netwerk/base/nsIClassOfService.idl +++ b/netwerk/base/nsIClassOfService.idl @@ -26,7 +26,7 @@ native ClassOfService(mozilla::net::ClassOfService); interface nsIClassOfService : nsISupports { attribute unsigned long classFlags; - attribute bool incremental; + attribute boolean incremental; void clearClassFlags(in unsigned long flags); void addClassFlags(in unsigned long flags); diff --git a/netwerk/base/nsIInterceptionInfo.idl b/netwerk/base/nsIInterceptionInfo.idl index d3c1b030ac..ca2549adbd 100644 --- a/netwerk/base/nsIInterceptionInfo.idl +++ b/netwerk/base/nsIInterceptionInfo.idl @@ -66,8 +66,8 @@ interface nsIInterceptionInfo : nsISupports * The InterceptedHttpChannel is a third party channel or not. */ [noscript, notxpcom, nostdcall, binaryname(FromThirdParty)] - bool binaryFromThirdParty(); + boolean binaryFromThirdParty(); [noscript, notxpcom, nostdcall, binaryname(SetFromThirdParty)] - void binarySetFromThirdParty(in bool aFromThirdParty); + void binarySetFromThirdParty(in boolean aFromThirdParty); }; diff --git a/netwerk/base/nsINetworkInterceptController.idl b/netwerk/base/nsINetworkInterceptController.idl index 155daa5cd5..946cc95a88 100644 --- a/netwerk/base/nsINetworkInterceptController.idl +++ b/netwerk/base/nsINetworkInterceptController.idl @@ -97,7 +97,7 @@ interface nsIInterceptedChannel : nsISupports in nsIInterceptedBodyCallback callback, in nsICacheInfoChannel channel, in ACString finalURLSpec, - in bool responseRedirected); + in boolean responseRedirected); /** * Instruct a channel that has been intercepted that response synthesis @@ -155,7 +155,7 @@ interface nsIInterceptedChannel : nsISupports * network or not. */ [noscript] - bool GetIsReset(); + boolean GetIsReset(); %{C++ already_AddRefed<nsIConsoleReportCollector> @@ -239,7 +239,7 @@ interface nsINetworkInterceptController : nsISupports * @param aChannel The channel that may be intercepted. It will * be in the state prior to calling OnStartRequest(). */ - bool shouldPrepareForIntercept(in nsIURI aURI, in nsIChannel aChannel); + boolean shouldPrepareForIntercept(in nsIURI aURI, in nsIChannel aChannel); /** * Notification when a given intercepted channel is prepared to accept a synthesized diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp index 8450a59b4a..998c389ace 100644 --- a/netwerk/base/nsIOService.cpp +++ b/netwerk/base/nsIOService.cpp @@ -87,6 +87,7 @@ using mozilla::dom::ServiceWorkerDescriptor; #define WEBRTC_PREF_PREFIX "media.peerconnection." #define NETWORK_DNS_PREF "network.dns." #define FORCE_EXTERNAL_PREF_PREFIX "network.protocol-handler.external." +#define SIMPLE_URI_SCHEMES_PREF "network.url.simple_uri_schemes" nsIOService* gIOService; static bool gHasWarnedUploadChannel2; @@ -171,6 +172,7 @@ int16_t gBadPortList[] = { 2049, // nfs 3659, // apple-sasl 4045, // lockd + 4160, // sieve 5060, // sip 5061, // sips 6000, // x11 @@ -180,6 +182,7 @@ int16_t gBadPortList[] = { 6667, // irc (default) 6668, // irc (alternate) 6669, // irc (alternate) + 6679, // osaut 6697, // irc+tls 10080, // amanda 0, // Sentinel value: This MUST be zero @@ -211,6 +214,7 @@ static const char* gCallbackPrefs[] = { NECKO_BUFFER_CACHE_SIZE_PREF, NETWORK_CAPTIVE_PORTAL_PREF, FORCE_EXTERNAL_PREF_PREFIX, + SIMPLE_URI_SCHEMES_PREF, nullptr, }; @@ -1528,6 +1532,15 @@ void nsIOService::PrefsChanged(const char* pref) { AutoWriteLock lock(mLock); mForceExternalSchemes = std::move(forceExternalSchemes); } + + if (!pref || strncmp(pref, SIMPLE_URI_SCHEMES_PREF, + strlen(SIMPLE_URI_SCHEMES_PREF)) == 0) { + LOG(( + "simple_uri_schemes pref change observed, updating the scheme list\n")); + nsAutoCString schemeList; + Preferences::GetCString(SIMPLE_URI_SCHEMES_PREF, schemeList); + mozilla::net::ParseSimpleURISchemes(schemeList); + } } void nsIOService::ParsePortList(const char* pref, bool remove) { diff --git a/netwerk/base/nsIParentChannel.idl b/netwerk/base/nsIParentChannel.idl index a351019d7d..92af600493 100644 --- a/netwerk/base/nsIParentChannel.idl +++ b/netwerk/base/nsIParentChannel.idl @@ -62,7 +62,7 @@ interface nsIParentChannel : nsIStreamListener * with the URI of the window. */ [noscript] void notifyClassificationFlags(in uint32_t aClassificationFlags, - in bool aIsThirdParty); + in boolean aIsThirdParty); /** * Called to invoke deletion of the IPC protocol. diff --git a/netwerk/base/nsIParentRedirectingChannel.idl b/netwerk/base/nsIParentRedirectingChannel.idl index 6302775c51..4dacaf70b6 100644 --- a/netwerk/base/nsIParentRedirectingChannel.idl +++ b/netwerk/base/nsIParentRedirectingChannel.idl @@ -26,7 +26,7 @@ interface nsIAsyncVerifyRedirectReadyCallback : nsISupports * Implemented by chrome side of IPC protocols that support redirect responses. */ -[scriptable, uuid(3ed1d288-5324-46ee-8a98-33ac37d1080b)] +[uuid(3ed1d288-5324-46ee-8a98-33ac37d1080b)] interface nsIParentRedirectingChannel : nsIParentChannel { /** diff --git a/netwerk/base/nsIPermissionManager.idl b/netwerk/base/nsIPermissionManager.idl index f234958010..e9b990c019 100644 --- a/netwerk/base/nsIPermissionManager.idl +++ b/netwerk/base/nsIPermissionManager.idl @@ -117,6 +117,14 @@ interface nsIPermissionManager : nsISupports [optional] in int64_t expireTime); /** + * Test method to add a permission for a given principal with custom modification time. + */ + void testAddFromPrincipalByTime(in nsIPrincipal principal, in ACString type, + in uint32_t permission, + in int64_t modificationTime + ); + + /** * Add permanent permission information for a given principal in private * browsing. * diff --git a/netwerk/base/nsISecureBrowserUI.idl b/netwerk/base/nsISecureBrowserUI.idl index 6197a9adff..b0e9c9e32d 100644 --- a/netwerk/base/nsISecureBrowserUI.idl +++ b/netwerk/base/nsISecureBrowserUI.idl @@ -12,6 +12,6 @@ interface nsITransportSecurityInfo; interface nsISecureBrowserUI : nsISupports { readonly attribute unsigned long state; - readonly attribute bool isSecureContext; + readonly attribute boolean isSecureContext; readonly attribute nsITransportSecurityInfo secInfo; }; diff --git a/netwerk/base/nsISocketFilter.idl b/netwerk/base/nsISocketFilter.idl index 0846fa2eda..40d58d086a 100644 --- a/netwerk/base/nsISocketFilter.idl +++ b/netwerk/base/nsISocketFilter.idl @@ -22,10 +22,10 @@ interface nsISocketFilter : nsISupports const long SF_INCOMING = 0; const long SF_OUTGOING = 1; - bool filterPacket([const]in NetAddrPtr remote_addr, - [const, array, size_is(len)]in uint8_t data, - in unsigned long len, - in long direction); + boolean filterPacket([const]in NetAddrPtr remote_addr, + [const, array, size_is(len)]in uint8_t data, + in unsigned long len, + in long direction); }; /** diff --git a/netwerk/base/nsISocketTransport.idl b/netwerk/base/nsISocketTransport.idl index 58b869203e..c0f26f5c66 100644 --- a/netwerk/base/nsISocketTransport.idl +++ b/netwerk/base/nsISocketTransport.idl @@ -132,7 +132,7 @@ interface nsISocketTransport : nsITransport /** * True to set addr and port reuse socket options. */ - void setReuseAddrPort(in bool reuseAddrPort); + void setReuseAddrPort(in boolean reuseAddrPort); /** * Values for the aType parameter passed to get/setTimeout. @@ -349,7 +349,7 @@ interface nsISocketTransport : nsITransport /** * IP address resolved using TRR. */ - bool resolvedByTRR(); + boolean resolvedByTRR(); /** * Returns the effectiveTRRMode used for the DNS resolution. diff --git a/netwerk/base/nsIStreamTransportService.idl b/netwerk/base/nsIStreamTransportService.idl index 3a1c5a4239..3df8d4c127 100644 --- a/netwerk/base/nsIStreamTransportService.idl +++ b/netwerk/base/nsIStreamTransportService.idl @@ -36,14 +36,4 @@ interface nsIStreamTransportService : nsISupports */ nsITransport createInputTransport(in nsIInputStream aStream, in boolean aCloseWhenDone); - - void InputAvailable(in nsIInputStream aStream, - in nsIInputAvailableCallback aCallback); -}; - -[uuid(ff2da731-44d0-4dd9-8236-c99387fec721)] -interface nsIInputAvailableCallback : nsISupports -{ - void onInputAvailableComplete(in unsigned long long available, - in nsresult available_return_code); }; diff --git a/netwerk/base/nsISystemProxySettings.idl b/netwerk/base/nsISystemProxySettings.idl index 935da146af..0b24b0a83a 100644 --- a/netwerk/base/nsISystemProxySettings.idl +++ b/netwerk/base/nsISystemProxySettings.idl @@ -22,7 +22,7 @@ interface nsISystemProxySettings : nsISupports * provided for implementations that do not block but use other main thread only * functions such as dbus. */ - readonly attribute bool mainThreadOnly; + readonly attribute boolean mainThreadOnly; /** * If non-empty, use this PAC file. If empty, call getProxyForURI instead. @@ -43,5 +43,5 @@ interface nsISystemProxySettings : nsISupports /** * Check if system settings are configured to use WPAD */ - readonly attribute bool systemWPADSetting; + readonly attribute boolean systemWPADSetting; }; diff --git a/netwerk/base/nsIUDPSocket.idl b/netwerk/base/nsIUDPSocket.idl index 41bd0ebc17..5c23c1bb6f 100644 --- a/netwerk/base/nsIUDPSocket.idl +++ b/netwerk/base/nsIUDPSocket.idl @@ -116,7 +116,7 @@ interface nsIUDPSocket : nsISupports * If it is used off the socket thread there is a risk of triggering a bug * in OS thatcan cause a crash. */ - void syncListen(in nsIUDPSocketSyncListener aListener); + [noscript] void syncListen(in nsIUDPSocketSyncListener aListener); /** * connect diff --git a/netwerk/base/nsIncrementalStreamLoader.cpp b/netwerk/base/nsIncrementalStreamLoader.cpp index f4437b5269..1b74000871 100644 --- a/netwerk/base/nsIncrementalStreamLoader.cpp +++ b/netwerk/base/nsIncrementalStreamLoader.cpp @@ -182,7 +182,9 @@ nsIncrementalStreamLoader::OnDataAvailable(nsIRequest* request, void nsIncrementalStreamLoader::ReleaseData() { mData.clearAndFree(); } NS_IMETHODIMP -nsIncrementalStreamLoader::CheckListenerChain() { return NS_OK; } +nsIncrementalStreamLoader::CheckListenerChain() { + return NS_ERROR_NO_INTERFACE; +} NS_IMETHODIMP nsIncrementalStreamLoader::OnDataFinished(nsresult aStatus) { return NS_OK; } diff --git a/netwerk/base/nsNetUtil.cpp b/netwerk/base/nsNetUtil.cpp index ac86d8fa32..413fbd3ed6 100644 --- a/netwerk/base/nsNetUtil.cpp +++ b/netwerk/base/nsNetUtil.cpp @@ -693,17 +693,6 @@ int32_t NS_GetDefaultPort(const char* scheme, return NS_SUCCEEDED(rv) ? port : -1; } -/** - * This function is a helper function to apply the ToAscii conversion - * to a string - */ -bool NS_StringToACE(const nsACString& idn, nsACString& result) { - nsCOMPtr<nsIIDNService> idnSrv = do_GetService(NS_IDNSERVICE_CONTRACTID); - if (!idnSrv) return false; - nsresult rv = idnSrv->ConvertUTF8toACE(idn, result); - return NS_SUCCEEDED(rv); -} - int32_t NS_GetRealPort(nsIURI* aURI) { int32_t port; nsresult rv = aURI->GetPort(&port); @@ -721,6 +710,20 @@ int32_t NS_GetRealPort(nsIURI* aURI) { return NS_GetDefaultPort(scheme.get()); } +nsresult NS_DomainToASCII(const nsACString& aHost, nsACString& aASCII) { + return nsStandardURL::GetIDNService()->ConvertUTF8toACE(aHost, aASCII); +} + +nsresult NS_DomainToDisplay(const nsACString& aHost, nsACString& aDisplay) { + bool ignored; + return nsStandardURL::GetIDNService()->ConvertToDisplayIDN(aHost, &ignored, + aDisplay); +} + +nsresult NS_DomainToUnicode(const nsACString& aHost, nsACString& aUnicode) { + return nsStandardURL::GetIDNService()->ConvertACEtoUTF8(aHost, aUnicode); +} + nsresult NS_NewInputStreamChannelInternal( nsIChannel** outChannel, nsIURI* aUri, already_AddRefed<nsIInputStream> aStream, const nsACString& aContentType, @@ -1813,6 +1816,26 @@ class TlsAutoIncrement { T& mVar; }; +static nsTHashSet<nsCString> sSimpleURISchemes; +static StaticRWLock sSchemeLock; + +namespace mozilla::net { + +void ParseSimpleURISchemes(const nsACString& schemeList) { + StaticAutoWriteLock lock(sSchemeLock); + + sSimpleURISchemes.Clear(); + for (const auto& scheme : schemeList.Split(',')) { + nsAutoCString s(scheme); + s.CompressWhitespace(); + if (!s.IsEmpty()) { + sSimpleURISchemes.Insert(s); + } + } +} + +} // namespace mozilla::net + nsresult NS_NewURI(nsIURI** aURI, const nsACString& aSpec, const char* aCharset /* = nullptr */, nsIURI* aBaseURI /* = nullptr */) { @@ -2000,6 +2023,14 @@ nsresult NS_NewURI(nsIURI** aURI, const nsACString& aSpec, } #endif + auto mustUseSimpleURI = [](const nsCString& scheme) -> bool { + if (!StaticPrefs::network_url_some_schemes_bypass_defaultURI_fallback()) { + return false; + } + StaticAutoReadLock lock(sSchemeLock); + return sSimpleURISchemes.Contains(scheme); + }; + if (aBaseURI) { nsAutoCString newSpec; rv = aBaseURI->Resolve(aSpec, newSpec); @@ -2013,6 +2044,12 @@ nsresult NS_NewURI(nsIURI** aURI, const nsACString& aSpec, } if (StaticPrefs::network_url_useDefaultURI()) { + if (mustUseSimpleURI(scheme)) { + return NS_MutateURI(new nsSimpleURI::Mutator()) + .SetSpec(newSpec) + .Finalize(aURI); + } + return NS_MutateURI(new DefaultURI::Mutator()) .SetSpec(newSpec) .Finalize(aURI); @@ -2024,6 +2061,11 @@ nsresult NS_NewURI(nsIURI** aURI, const nsACString& aSpec, } if (StaticPrefs::network_url_useDefaultURI()) { + if (mustUseSimpleURI(scheme)) { + return NS_MutateURI(new nsSimpleURI::Mutator()) + .SetSpec(aSpec) + .Finalize(aURI); + } return NS_MutateURI(new DefaultURI::Mutator()) .SetSpec(aSpec) .Finalize(aURI); @@ -3409,25 +3451,24 @@ bool IsSchemeChangePermitted(nsIURI* aOldURI, const nsACString& newScheme) { } already_AddRefed<nsIURI> TryChangeProtocol(nsIURI* aURI, - const nsAString& aProtocol) { + const nsACString& aProtocol) { MOZ_ASSERT(aURI); - nsAString::const_iterator start; + nsACString::const_iterator start; aProtocol.BeginReading(start); - nsAString::const_iterator end; + nsACString::const_iterator end; aProtocol.EndReading(end); - nsAString::const_iterator iter(start); + nsACString::const_iterator iter(start); FindCharInReadable(':', iter, end); // Changing the protocol of a URL, changes the "nature" of the URI // implementation. In order to do this properly, we have to serialize the // existing URL and reparse it in a new object. nsCOMPtr<nsIURI> clone; - nsresult rv = NS_MutateURI(aURI) - .SetScheme(NS_ConvertUTF16toUTF8(Substring(start, iter))) - .Finalize(clone); + nsresult rv = + NS_MutateURI(aURI).SetScheme(Substring(start, iter)).Finalize(clone); if (NS_WARN_IF(NS_FAILED(rv))) { return nullptr; } diff --git a/netwerk/base/nsNetUtil.h b/netwerk/base/nsNetUtil.h index c1f30a56ed..8058ae89d9 100644 --- a/netwerk/base/nsNetUtil.h +++ b/netwerk/base/nsNetUtil.h @@ -294,10 +294,28 @@ int32_t NS_GetDefaultPort(const char* scheme, nsIIOService* ioService = nullptr); /** - * This function is a helper function to apply the ToAscii conversion - * to a string + * The UTS #46 ToASCII operation as parametrized by the WHATWG URL Standard. + * + * Use this function to prepare a host name for network protocols. + */ +nsresult NS_DomainToASCII(const nsACString& aHost, nsACString& aASCII); + +/** + * The UTS #46 ToUnicode operation as parametrized by the WHATWG URL Standard, + * except potentially misleading labels are treated according to ToASCII + * instead. + * + * Use this function to prepare a host name for display to the user. */ -bool NS_StringToACE(const nsACString& idn, nsACString& result); +nsresult NS_DomainToDisplay(const nsACString& aHost, nsACString& aDisplay); + +/** + * The UTS #46 ToUnicode operation as parametrized by the WHATWG URL Standard. + * + * It's most likely incorrect to call this function, and `NS_DomainToDisplay` + * should typically be called instead. + */ +nsresult NS_DomainToUnicode(const nsACString& aHost, nsACString& aUnicode); /** * This function is a helper function to get a protocol's default port if the @@ -1020,7 +1038,7 @@ bool SchemeIsFTP(nsIURI* aURI); // step 2.1 in https://url.spec.whatwg.org/#scheme-state bool SchemeIsSpecial(const nsACString&); bool IsSchemeChangePermitted(nsIURI*, const nsACString&); -already_AddRefed<nsIURI> TryChangeProtocol(nsIURI*, const nsAString&); +already_AddRefed<nsIURI> TryChangeProtocol(nsIURI*, const nsACString&); struct LinkHeader { nsString mHref; @@ -1099,6 +1117,8 @@ void CheckForBrokenChromeURL(nsILoadInfo* aLoadInfo, nsIURI* aURI); bool IsCoepCredentiallessEnabled(bool aIsOriginTrialCoepCredentiallessEnabled); +void ParseSimpleURISchemes(const nsACString& schemeList); + } // namespace net } // namespace mozilla diff --git a/netwerk/base/nsPACMan.cpp b/netwerk/base/nsPACMan.cpp index d4c6c4bd79..28d8aa7df4 100644 --- a/netwerk/base/nsPACMan.cpp +++ b/netwerk/base/nsPACMan.cpp @@ -713,6 +713,7 @@ void nsPACMan::ContinueLoadingAfterPACUriKnown() { channel->SetLoadFlags(nsIRequest::LOAD_BYPASS_CACHE); channel->SetNotificationCallbacks(this); + channel->SetTRRMode(nsIRequest::TRR_DISABLED_MODE); if (NS_SUCCEEDED(channel->AsyncOpen(loader))) return; } } diff --git a/netwerk/base/nsPISocketTransportService.idl b/netwerk/base/nsPISocketTransportService.idl index e7c8ac5a60..8ea8d7ba55 100644 --- a/netwerk/base/nsPISocketTransportService.idl +++ b/netwerk/base/nsPISocketTransportService.idl @@ -17,7 +17,7 @@ interface nsPISocketTransportService : nsIRoutedSocketTransportService * init/shutdown routines. */ void init(); - void shutdown(in bool aXpcomShutdown); + void shutdown(in boolean aXpcomShutdown); /** * controls the TCP sender window clamp diff --git a/netwerk/base/nsStandardURL.cpp b/netwerk/base/nsStandardURL.cpp index d9b0c23ead..fac8e4ca7f 100644 --- a/netwerk/base/nsStandardURL.cpp +++ b/netwerk/base/nsStandardURL.cpp @@ -622,6 +622,8 @@ nsresult nsStandardURL::NormalizeIPv4(const nsACString& host, return NS_OK; } +nsIIDNService* nsStandardURL::GetIDNService() { return gIDN.get(); } + nsresult nsStandardURL::NormalizeIDN(const nsCString& host, nsCString& result) { result.Truncate(); mDisplayHost.Truncate(); @@ -1104,7 +1106,7 @@ nsresult nsStandardURL::BuildNormalizedSpec(const char* spec, } } - if (mDirectory.mLen > 1) { + if (mDirectory.mLen > 0) { netCoalesceFlags coalesceFlag = NET_COALESCE_NORMAL; if (SegmentIs(buf, mScheme, "ftp")) { coalesceFlag = diff --git a/netwerk/base/nsStandardURL.h b/netwerk/base/nsStandardURL.h index a4f644e722..5e49088fbc 100644 --- a/netwerk/base/nsStandardURL.h +++ b/netwerk/base/nsStandardURL.h @@ -198,6 +198,8 @@ class nsStandardURL : public nsIFileURL, static nsresult NormalizeIPv4(const nsACString& host, nsCString& result); + static nsIIDNService* GetIDNService(); + protected: // enum used in a few places to specify how .ref attribute should be handled enum RefHandlingEnum { eIgnoreRef, eHonorRef, eReplaceRef }; diff --git a/netwerk/base/nsStreamTransportService.cpp b/netwerk/base/nsStreamTransportService.cpp index e1369bbcb5..19776b2ac2 100644 --- a/netwerk/base/nsStreamTransportService.cpp +++ b/netwerk/base/nsStreamTransportService.cpp @@ -369,61 +369,5 @@ nsStreamTransportService::Observe(nsISupports* subject, const char* topic, return NS_OK; } -class AvailableEvent final : public Runnable { - public: - AvailableEvent(nsIInputStream* stream, nsIInputAvailableCallback* callback) - : Runnable("net::AvailableEvent"), - mStream(stream), - mCallback(callback), - mDoingCallback(false), - mSize(0), - mResultForCallback(NS_OK) { - mCallbackTarget = GetCurrentSerialEventTarget(); - } - - NS_IMETHOD Run() override { - if (mDoingCallback) { - // pong - mCallback->OnInputAvailableComplete(mSize, mResultForCallback); - mCallback = nullptr; - } else { - // ping - mResultForCallback = mStream->Available(&mSize); - mStream = nullptr; - mDoingCallback = true; - - nsCOMPtr<nsIRunnable> event(this); // overly cute - mCallbackTarget->Dispatch(event.forget(), NS_DISPATCH_NORMAL); - mCallbackTarget = nullptr; - } - return NS_OK; - } - - private: - virtual ~AvailableEvent() = default; - - nsCOMPtr<nsIInputStream> mStream; - nsCOMPtr<nsIInputAvailableCallback> mCallback; - nsCOMPtr<nsIEventTarget> mCallbackTarget; - bool mDoingCallback; - uint64_t mSize; - nsresult mResultForCallback; -}; - -NS_IMETHODIMP -nsStreamTransportService::InputAvailable(nsIInputStream* stream, - nsIInputAvailableCallback* callback) { - nsCOMPtr<nsIThreadPool> pool; - { - mozilla::MutexAutoLock lock(mShutdownLock); - if (mIsShutdown) { - return NS_ERROR_NOT_INITIALIZED; - } - pool = mPool; - } - nsCOMPtr<nsIRunnable> event = new AvailableEvent(stream, callback); - return pool->Dispatch(event.forget(), NS_DISPATCH_NORMAL); -} - } // namespace net } // namespace mozilla diff --git a/netwerk/base/nsURLHelper.cpp b/netwerk/base/nsURLHelper.cpp index ca82b0cd00..109df8f6d1 100644 --- a/netwerk/base/nsURLHelper.cpp +++ b/netwerk/base/nsURLHelper.cpp @@ -219,6 +219,11 @@ void net_CoalesceDirs(netCoalesceFlags flags, char* path) { uint32_t traversal = 0; uint32_t special_ftp_len = 0; + MOZ_ASSERT(*path == '/', "We expect the path to begin with /"); + if (*path != '/') { + return; + } + /* Remember if this url is a special ftp one: */ if (flags & NET_COALESCE_DOUBLE_SLASH_IS_ROOT) { /* some schemes (for example ftp) have the speciality that @@ -249,7 +254,7 @@ void net_CoalesceDirs(netCoalesceFlags flags, char* path) { fwdPtr = path; /* replace all %2E or %2e with . in the path */ - /* but stop at lastchar if non null */ + /* but stop at lastslash if non null */ for (; (*fwdPtr != '\0') && (*fwdPtr != '?') && (*fwdPtr != '#') && (*lastslash == '\0' || fwdPtr != lastslash); ++fwdPtr) { @@ -346,6 +351,14 @@ void net_CoalesceDirs(netCoalesceFlags flags, char* path) { urlPtr--; } + // Before we start copying past ?#, we must make sure we don't overwrite + // the first / character. If fwdPtr is also unchanged, just copy everything + // (this shouldn't happen unless we could get in here without a leading + // slash). + if (urlPtr == path && fwdPtr != path) { + urlPtr++; + } + // Copy remaining stuff past the #?; for (; *fwdPtr != '\0'; ++fwdPtr) { *urlPtr++ = *fwdPtr; @@ -1097,24 +1110,32 @@ bool net_GetDefaultStatusTextForCode(uint16_t aCode, nsACString& aOutText) { return true; } -namespace mozilla { -static auto MakeNameMatcher(const nsAString& aName) { +static auto MakeNameMatcher(const nsACString& aName) { return [&aName](const auto& param) { return param.mKey.Equals(aName); }; } -bool URLParams::Has(const nsAString& aName) { +static void AssignMaybeInvalidUTF8String(const nsACString& aSource, + nsACString& aDest) { + if (NS_FAILED(UTF_8_ENCODING->DecodeWithoutBOMHandling(aSource, aDest))) { + MOZ_CRASH("Out of memory when converting URL params."); + } +} + +namespace mozilla { + +bool URLParams::Has(const nsACString& aName) { return std::any_of(mParams.cbegin(), mParams.cend(), MakeNameMatcher(aName)); } -bool URLParams::Has(const nsAString& aName, const nsAString& aValue) { +bool URLParams::Has(const nsACString& aName, const nsACString& aValue) { return std::any_of( mParams.cbegin(), mParams.cend(), [&aName, &aValue](const auto& param) { return param.mKey.Equals(aName) && param.mValue.Equals(aValue); }); } -void URLParams::Get(const nsAString& aName, nsString& aRetval) { - SetDOMStringToNull(aRetval); +void URLParams::Get(const nsACString& aName, nsACString& aRetval) { + aRetval.SetIsVoid(true); const auto end = mParams.cend(); const auto it = std::find_if(mParams.cbegin(), end, MakeNameMatcher(aName)); @@ -1123,7 +1144,7 @@ void URLParams::Get(const nsAString& aName, nsString& aRetval) { } } -void URLParams::GetAll(const nsAString& aName, nsTArray<nsString>& aRetval) { +void URLParams::GetAll(const nsACString& aName, nsTArray<nsCString>& aRetval) { aRetval.Clear(); for (uint32_t i = 0, len = mParams.Length(); i < len; ++i) { @@ -1133,13 +1154,13 @@ void URLParams::GetAll(const nsAString& aName, nsTArray<nsString>& aRetval) { } } -void URLParams::Append(const nsAString& aName, const nsAString& aValue) { +void URLParams::Append(const nsACString& aName, const nsACString& aValue) { Param* param = mParams.AppendElement(); param->mKey = aName; param->mValue = aValue; } -void URLParams::Set(const nsAString& aName, const nsAString& aValue) { +void URLParams::Set(const nsACString& aName, const nsACString& aValue) { Param* param = nullptr; for (uint32_t i = 0, len = mParams.Length(); i < len;) { if (!mParams[i].mKey.Equals(aName)) { @@ -1164,34 +1185,24 @@ void URLParams::Set(const nsAString& aName, const nsAString& aValue) { param->mValue = aValue; } -void URLParams::Delete(const nsAString& aName) { +void URLParams::Delete(const nsACString& aName) { mParams.RemoveElementsBy( [&aName](const auto& param) { return param.mKey.Equals(aName); }); } -void URLParams::Delete(const nsAString& aName, const nsAString& aValue) { +void URLParams::Delete(const nsACString& aName, const nsACString& aValue) { mParams.RemoveElementsBy([&aName, &aValue](const auto& param) { return param.mKey.Equals(aName) && param.mValue.Equals(aValue); }); } /* static */ -void URLParams::ConvertString(const nsACString& aInput, nsAString& aOutput) { - if (NS_FAILED(UTF_8_ENCODING->DecodeWithoutBOMHandling(aInput, aOutput))) { - MOZ_CRASH("Out of memory when converting URL params."); - } -} - -/* static */ -void URLParams::DecodeString(const nsACString& aInput, nsAString& aOutput) { +void URLParams::DecodeString(const nsACString& aInput, nsACString& aOutput) { const char* const end = aInput.EndReading(); - - nsAutoCString unescaped; - for (const char* iter = aInput.BeginReading(); iter != end;) { // replace '+' with U+0020 if (*iter == '+') { - unescaped.Append(' '); + aOutput.Append(' '); ++iter; continue; } @@ -1214,30 +1225,26 @@ void URLParams::DecodeString(const nsACString& aInput, nsAString& aOutput) { if (first != end && second != end && asciiHexDigit(*first) && asciiHexDigit(*second)) { - unescaped.Append(hexDigit(*first) * 16 + hexDigit(*second)); + aOutput.Append(hexDigit(*first) * 16 + hexDigit(*second)); iter = second + 1; } else { - unescaped.Append('%'); + aOutput.Append('%'); ++iter; } continue; } - unescaped.Append(*iter); + aOutput.Append(*iter); ++iter; } - - // XXX It seems rather wasteful to first decode into a UTF-8 nsCString and - // then convert the whole string to UTF-16, at least if we exceed the inline - // storage size. - ConvertString(unescaped, aOutput); + AssignMaybeInvalidUTF8String(aOutput, aOutput); } /* static */ bool URLParams::ParseNextInternal(const char*& aStart, const char* const aEnd, - bool aShouldDecode, nsAString* aOutputName, - nsAString* aOutputValue) { + bool aShouldDecode, nsACString* aOutputName, + nsACString* aOutputValue) { nsDependentCSubstring string; const char* const iter = std::find(aStart, aEnd, '&'); @@ -1273,17 +1280,18 @@ bool URLParams::ParseNextInternal(const char*& aStart, const char* const aEnd, return true; } - ConvertString(name, *aOutputName); - ConvertString(value, *aOutputValue); + AssignMaybeInvalidUTF8String(name, *aOutputName); + AssignMaybeInvalidUTF8String(value, *aOutputValue); return true; } /* static */ -bool URLParams::Extract(const nsACString& aInput, const nsAString& aName, - nsAString& aValue) { +bool URLParams::Extract(const nsACString& aInput, const nsACString& aName, + nsACString& aValue) { aValue.SetIsVoid(true); return !URLParams::Parse( - aInput, true, [&aName, &aValue](const nsAString& name, nsString&& value) { + aInput, true, + [&aName, &aValue](const nsACString& name, nsCString&& value) { if (aName == name) { aValue = std::move(value); return false; @@ -1296,16 +1304,14 @@ void URLParams::ParseInput(const nsACString& aInput) { // Remove all the existing data before parsing a new input. DeleteAll(); - URLParams::Parse(aInput, true, [this](nsString&& name, nsString&& value) { + URLParams::Parse(aInput, true, [this](nsCString&& name, nsCString&& value) { mParams.AppendElement(Param{std::move(name), std::move(value)}); return true; }); } -namespace { - -void SerializeString(const nsCString& aInput, nsAString& aValue) { - const unsigned char* p = (const unsigned char*)aInput.get(); +void URLParams::SerializeString(const nsACString& aInput, nsACString& aValue) { + const unsigned char* p = (const unsigned char*)aInput.BeginReading(); const unsigned char* end = p + aInput.Length(); while (p != end) { @@ -1325,9 +1331,7 @@ void SerializeString(const nsCString& aInput, nsAString& aValue) { } } -} // namespace - -void URLParams::Serialize(nsAString& aValue, bool aEncode) const { +void URLParams::Serialize(nsACString& aValue, bool aEncode) const { aValue.Truncate(); bool first = true; @@ -1341,9 +1345,9 @@ void URLParams::Serialize(nsAString& aValue, bool aEncode) const { // XXX Actually, it's not necessary to build a new string object. Generally, // such cases could just convert each codepoint one-by-one. if (aEncode) { - SerializeString(NS_ConvertUTF16toUTF8(mParams[i].mKey), aValue); + SerializeString(mParams[i].mKey, aValue); aValue.Append('='); - SerializeString(NS_ConvertUTF16toUTF8(mParams[i].mValue), aValue); + SerializeString(mParams[i].mValue, aValue); } else { aValue.Append(mParams[i].mKey); aValue.Append('='); @@ -1354,7 +1358,11 @@ void URLParams::Serialize(nsAString& aValue, bool aEncode) const { void URLParams::Sort() { mParams.StableSort([](const Param& lhs, const Param& rhs) { - return Compare(lhs.mKey, rhs.mKey); + // FIXME(emilio, bug 1888901): The URLSearchParams.sort() spec requires + // comparing by utf-16 code points... That's a bit unfortunate, maybe we + // can optimize the string conversions here? + return Compare(NS_ConvertUTF8toUTF16(lhs.mKey), + NS_ConvertUTF8toUTF16(rhs.mKey)); }); } diff --git a/netwerk/base/nsURLHelper.h b/netwerk/base/nsURLHelper.h index 36844e6e4b..b9b81a8eb0 100644 --- a/netwerk/base/nsURLHelper.h +++ b/netwerk/base/nsURLHelper.h @@ -251,7 +251,7 @@ class URLParams final { * \param aInput the query string to parse * \param aParamHandler the parameter handler as desribed above * \tparam ParamHandler a function type compatible with signature - * bool(nsString, nsString) + * bool(nsCString, nsCString) * * \return false if the parameter handler returned false for any parameter, * true otherwise @@ -263,8 +263,8 @@ class URLParams final { const char* const end = aInput.EndReading(); while (start != end) { - nsAutoString name; - nsAutoString value; + nsAutoCString name; + nsAutoCString value; if (!ParseNextInternal(start, end, aShouldDecode, &name, &value)) { continue; @@ -290,8 +290,8 @@ class URLParams final { * there is no match \return true iff there was a parameter with with name * \paramref aName */ - static bool Extract(const nsACString& aInput, const nsAString& aName, - nsAString& aValue); + static bool Extract(const nsACString& aInput, const nsACString& aName, + nsACString& aValue); /** * \brief Resets the state of this instance and parses a new query string. @@ -306,11 +306,12 @@ class URLParams final { * \param[out] aValue will be assigned the result of the serialization * \param aEncode If this is true, the serialization will encode the string. */ - void Serialize(nsAString& aValue, bool aEncode) const; + void Serialize(nsACString& aValue, bool aEncode) const; - void Get(const nsAString& aName, nsString& aRetval); + static void SerializeString(const nsACString& aInput, nsACString& aValue); + void Get(const nsACString& aName, nsACString& aRetval); - void GetAll(const nsAString& aName, nsTArray<nsString>& aRetval); + void GetAll(const nsACString& aName, nsTArray<nsCString>& aRetval); /** * \brief Sets the value of a given parameter. @@ -319,31 +320,32 @@ class URLParams final { * replaced, and all further parameters of the name are deleted. Otherwise, * the behaviour is the same as \ref Append. */ - void Set(const nsAString& aName, const nsAString& aValue); + void Set(const nsACString& aName, const nsACString& aValue); - void Append(const nsAString& aName, const nsAString& aValue); + void Append(const nsACString& aName, const nsACString& aValue); - bool Has(const nsAString& aName); + bool Has(const nsACString& aName); - bool Has(const nsAString& aName, const nsAString& aValue); + bool Has(const nsACString& aName, const nsACString& aValue); /** * \brief Deletes all parameters with the given name. */ - void Delete(const nsAString& aName); + void Delete(const nsACString& aName); - void Delete(const nsAString& aName, const nsAString& aValue); + void Delete(const nsACString& aName, const nsACString& aValue); void DeleteAll() { mParams.Clear(); } uint32_t Length() const { return mParams.Length(); } - const nsAString& GetKeyAtIndex(uint32_t aIndex) const { + static void DecodeString(const nsACString& aInput, nsACString& aOutput); + const nsACString& GetKeyAtIndex(uint32_t aIndex) const { MOZ_ASSERT(aIndex < mParams.Length()); return mParams[aIndex].mKey; } - const nsAString& GetValueAtIndex(uint32_t aIndex) const { + const nsACString& GetValueAtIndex(uint32_t aIndex) const { MOZ_ASSERT(aIndex < mParams.Length()); return mParams[aIndex].mValue; } @@ -355,15 +357,13 @@ class URLParams final { void Sort(); private: - 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, - bool aShouldDecode, nsAString* aOutputName, - nsAString* aOutputValue); + bool aShouldDecode, nsACString* aOutputName, + nsACString* aOutputValue); struct Param { - nsString mKey; - nsString mValue; + nsCString mKey; + nsCString mValue; }; nsTArray<Param> mParams; diff --git a/netwerk/cache2/nsICachePurgeLock.idl b/netwerk/cache2/nsICachePurgeLock.idl index a0937a8922..35d2e5457c 100644 --- a/netwerk/cache2/nsICachePurgeLock.idl +++ b/netwerk/cache2/nsICachePurgeLock.idl @@ -23,7 +23,7 @@ interface nsICachePurgeLock : nsISupports { * Returns true if another instance also holds the lock. * Throws if called before lock was called, or after unlock was called. */ - bool isOtherInstanceRunning(); + boolean isOtherInstanceRunning(); /** * Releases the lock. diff --git a/netwerk/cache2/nsICacheStorage.idl b/netwerk/cache2/nsICacheStorage.idl index 8169c9b730..ddc73313cb 100644 --- a/netwerk/cache2/nsICacheStorage.idl +++ b/netwerk/cache2/nsICacheStorage.idl @@ -121,7 +121,7 @@ interface nsICacheStorage : nsISupports */ void getCacheIndexEntryAttrs(in nsIURI aURI, in ACString aIdExtension, - out bool aHasAltData, + out boolean aHasAltData, out uint32_t aSizeInKB); /** * Asynchronously removes an entry belonging to the URI from the cache. diff --git a/netwerk/cookie/Cookie.cpp b/netwerk/cookie/Cookie.cpp index e9de561f88..e78c11e50d 100644 --- a/netwerk/cookie/Cookie.cpp +++ b/netwerk/cookie/Cookie.cpp @@ -100,8 +100,8 @@ already_AddRefed<Cookie> Cookie::CreateValidated( if (cookie->mData.creationTime() > currentTimeInUsec) { uint64_t diffInSeconds = (cookie->mData.creationTime() - currentTimeInUsec) / PR_USEC_PER_SEC; - mozilla::glean::networking::cookie_creation_fixup_diff.AccumulateSamples( - {diffInSeconds}); + mozilla::glean::networking::cookie_creation_fixup_diff + .AccumulateSingleSample(diffInSeconds); glean::networking::cookie_timestamp_fixed_count.Get("creationTime"_ns) .Add(1); @@ -112,8 +112,8 @@ already_AddRefed<Cookie> Cookie::CreateValidated( if (cookie->mData.lastAccessed() > currentTimeInUsec) { uint64_t diffInSeconds = (cookie->mData.lastAccessed() - currentTimeInUsec) / PR_USEC_PER_SEC; - mozilla::glean::networking::cookie_access_fixup_diff.AccumulateSamples( - {diffInSeconds}); + mozilla::glean::networking::cookie_access_fixup_diff.AccumulateSingleSample( + diffInSeconds); glean::networking::cookie_timestamp_fixed_count.Get("lastAccessed"_ns) .Add(1); diff --git a/netwerk/cookie/CookieJarSettings.cpp b/netwerk/cookie/CookieJarSettings.cpp index 09a4789d85..9e598c296f 100644 --- a/netwerk/cookie/CookieJarSettings.cpp +++ b/netwerk/cookie/CookieJarSettings.cpp @@ -4,9 +4,11 @@ * 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 "mozIThirdPartyUtil.h" #include "mozilla/AntiTrackingUtils.h" #include "mozilla/BasePrincipal.h" #include "mozilla/ClearOnShutdown.h" +#include "mozilla/Components.h" #include "mozilla/ContentBlockingAllowList.h" #include "mozilla/dom/BrowsingContext.h" #include "mozilla/net/CookieJarSettings.h" @@ -15,6 +17,7 @@ #include "mozilla/PermissionManager.h" #include "mozilla/SchedulerGroup.h" #include "mozilla/StaticPrefs_network.h" +#include "mozilla/StoragePrincipalHelper.h" #include "mozilla/Unused.h" #include "nsIPrincipal.h" #if defined(MOZ_THUNDERBIRD) || defined(MOZ_SUITE) @@ -172,7 +175,8 @@ CookieJarSettings::CookieJarSettings(uint32_t aCookieBehavior, mIsOnContentBlockingAllowListUpdated(false), mState(aState), mToBeMerged(false), - mShouldResistFingerprinting(aShouldResistFingerprinting) { + mShouldResistFingerprinting(aShouldResistFingerprinting), + mTopLevelWindowContextId(0) { MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT_IF( mIsFirstPartyIsolated, @@ -195,7 +199,7 @@ CookieJarSettings::InitWithURI(nsIURI* aURI, bool aIsPrivate) { mCookieBehavior = nsICookieManager::GetCookieBehavior(aIsPrivate); - SetPartitionKey(aURI); + SetPartitionKey(aURI, false); return NS_OK; } @@ -408,6 +412,8 @@ void CookieJarSettings::Serialize(CookieJarSettingsArgs& aData) { CookiePermissionData(principalInfo, cookiePermission)); } + aData.topLevelWindowContextId() = mTopLevelWindowContextId; + mToBeMerged = false; } @@ -451,6 +457,8 @@ void CookieJarSettings::Serialize(CookieJarSettingsArgs& aData) { aData.fingerprintingRandomizationKey().Clone()); } + cookieJarSettings->mTopLevelWindowContextId = aData.topLevelWindowContextId(); + cookieJarSettings.forget(aCookieJarSettings); } @@ -521,14 +529,25 @@ void CookieJarSettings::Merge(const CookieJarSettingsArgs& aData) { } } -void CookieJarSettings::SetPartitionKey(nsIURI* aURI) { +void CookieJarSettings::SetPartitionKey(nsIURI* aURI, + bool aForeignByAncestorContext) { MOZ_ASSERT(aURI); OriginAttributes attrs; - attrs.SetPartitionKey(aURI); + attrs.SetPartitionKey(aURI, aForeignByAncestorContext); mPartitionKey = std::move(attrs.mPartitionKey); } +void CookieJarSettings::UpdatePartitionKeyForDocumentLoadedByChannel( + nsIChannel* aChannel) { + nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo(); + bool thirdParty = AntiTrackingUtils::IsThirdPartyChannel(aChannel); + bool foreignByAncestorContext = + thirdParty && !loadInfo->GetIsThirdPartyContextToTopWindow(); + StoragePrincipalHelper::UpdatePartitionKeyWithForeignAncestorBit( + mPartitionKey, foreignByAncestorContext); +} + void CookieJarSettings::UpdateIsOnContentBlockingAllowList( nsIChannel* aChannel) { MOZ_DIAGNOSTIC_ASSERT(XRE_IsParentProcess()); diff --git a/netwerk/cookie/CookieJarSettings.h b/netwerk/cookie/CookieJarSettings.h index 97f8528a55..cf3c9ff418 100644 --- a/netwerk/cookie/CookieJarSettings.h +++ b/netwerk/cookie/CookieJarSettings.h @@ -161,12 +161,14 @@ class CookieJarSettings final : public nsICookieJarSettings { void UpdateIsOnContentBlockingAllowList(nsIChannel* aChannel); - void SetPartitionKey(nsIURI* aURI); + void SetPartitionKey(nsIURI* aURI, bool aForeignByAncestorContext); void SetPartitionKey(const nsAString& aPartitionKey) { mPartitionKey = aPartitionKey; } const nsAString& GetPartitionKey() { return mPartitionKey; }; + void UpdatePartitionKeyForDocumentLoadedByChannel(nsIChannel* aChannel); + void SetFingerprintingRandomizationKey(const nsTArray<uint8_t>& aKey) { mFingerprintingRandomKey.reset(); @@ -179,6 +181,11 @@ class CookieJarSettings final : public nsICookieJarSettings { // network.cookie.rejectForeignWithExceptions.enabled pref is set to true. static bool IsRejectThirdPartyContexts(uint32_t aCookieBehavior); + void SetTopLevelWindowContextId(uint64_t aId) { + mTopLevelWindowContextId = aId; + } + uint64_t GetTopLevelWindowContextId() { return mTopLevelWindowContextId; } + private: enum State { // No cookie permissions are allowed to be stored in this object. @@ -259,6 +266,10 @@ class CookieJarSettings final : public nsICookieJarSettings { // browsing session changes. This can prevent trackers to identify individuals // by using browser fingerprints. Maybe<nsTArray<uint8_t>> mFingerprintingRandomKey; + + // This field caches the top level window context id when loading the top + // level document. + uint64_t mTopLevelWindowContextId; }; } // namespace net diff --git a/netwerk/cookie/CookiePersistentStorage.cpp b/netwerk/cookie/CookiePersistentStorage.cpp index 6358b39e3a..57727ad4fc 100644 --- a/netwerk/cookie/CookiePersistentStorage.cpp +++ b/netwerk/cookie/CookiePersistentStorage.cpp @@ -2105,22 +2105,22 @@ void CookiePersistentStorage::CollectCookieJarSizeData() { if (cookieEntry.IsPartitioned()) { uint16_t cePartitioned = cookieEntry.GetCookies().Length(); sumPartitioned += cePartitioned; - mozilla::glean::networking::cookie_count_part_by_key.AccumulateSamples( - {cePartitioned}); + mozilla::glean::networking::cookie_count_part_by_key + .AccumulateSingleSample(cePartitioned); } else { uint16_t ceUnpartitioned = cookieEntry.GetCookies().Length(); sumUnpartitioned += ceUnpartitioned; - mozilla::glean::networking::cookie_count_unpart_by_key.AccumulateSamples( - {ceUnpartitioned}); + mozilla::glean::networking::cookie_count_unpart_by_key + .AccumulateSingleSample(ceUnpartitioned); } } - mozilla::glean::networking::cookie_count_total.AccumulateSamples( - {mCookieCount}); - mozilla::glean::networking::cookie_count_partitioned.AccumulateSamples( - {sumPartitioned}); - mozilla::glean::networking::cookie_count_unpartitioned.AccumulateSamples( - {sumUnpartitioned}); + mozilla::glean::networking::cookie_count_total.AccumulateSingleSample( + mCookieCount); + mozilla::glean::networking::cookie_count_partitioned.AccumulateSingleSample( + sumPartitioned); + mozilla::glean::networking::cookie_count_unpartitioned.AccumulateSingleSample( + sumUnpartitioned); } } // namespace net diff --git a/netwerk/cookie/CookieStorage.cpp b/netwerk/cookie/CookieStorage.cpp index fd0af6129b..ef4af82b64 100644 --- a/netwerk/cookie/CookieStorage.cpp +++ b/netwerk/cookie/CookieStorage.cpp @@ -669,8 +669,8 @@ void CookieStorage::AddCookie(nsIConsoleReportCollector* aCRC, } uint32_t purgedLength = 0; purgedList->GetLength(&purgedLength); - mozilla::glean::networking::cookie_purge_entry_max.AccumulateSamples( - {purgedLength}); + mozilla::glean::networking::cookie_purge_entry_max.AccumulateSingleSample( + purgedLength); } else if (mCookieCount >= ADD_TEN_PERCENT(mMaxNumberOfCookies)) { int64_t maxAge = aCurrentTimeInUsec - mCookieOldestTime; @@ -687,8 +687,8 @@ void CookieStorage::AddCookie(nsIConsoleReportCollector* aCRC, mCookiePurgeAge); uint32_t purgedLength = 0; purgedList->GetLength(&purgedLength); - mozilla::glean::networking::cookie_purge_max.AccumulateSamples( - {purgedLength}); + mozilla::glean::networking::cookie_purge_max.AccumulateSingleSample( + purgedLength); } } } diff --git a/netwerk/dns/DNS.h b/netwerk/dns/DNS.h index a0dbbaa17d..64dd7a7336 100644 --- a/netwerk/dns/DNS.h +++ b/netwerk/dns/DNS.h @@ -216,6 +216,11 @@ class AddrInfo { mInfo->mAddresses = std::move(addresses); } + template <class Comparator> + void SortAddresses(const Comparator& aComp) { + mInfo->mAddresses.Sort(aComp); + } + void SetCanonicalHostname(const nsACString& aCname) { mInfo->mCanonicalName = aCname; } diff --git a/netwerk/dns/HostRecordQueue.cpp b/netwerk/dns/HostRecordQueue.cpp index 6e8fd5488f..c4ec4bc585 100644 --- a/netwerk/dns/HostRecordQueue.cpp +++ b/netwerk/dns/HostRecordQueue.cpp @@ -166,6 +166,10 @@ void HostRecordQueue::MoveToAnotherPendingQ(nsHostRecord* aRec, } aRec->remove(); + // We just removed from pending queue. Insert record will + // increment this value again. + mPendingCount--; + InsertRecord(aRec, aFlags, aProofOfLock); } diff --git a/netwerk/dns/effective_tld_names.dat b/netwerk/dns/effective_tld_names.dat index 21df77442b..fdcaca41d5 100644 --- a/netwerk/dns/effective_tld_names.dat +++ b/netwerk/dns/effective_tld_names.dat @@ -6710,7 +6710,7 @@ org.zw // newGTLDs -// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2024-03-28T15:13:37Z +// List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2024-05-04T15:12:50Z // This list is auto-generated, don't edit it manually. // aaa : American Automobile Association, Inc. // https://www.iana.org/domains/root/db/aaa.html @@ -6896,7 +6896,7 @@ anquan // https://www.iana.org/domains/root/db/anz.html anz -// aol : Oath Inc. +// aol : Yahoo Inc. // https://www.iana.org/domains/root/db/aol.html aol @@ -11120,7 +11120,7 @@ xyz // https://www.iana.org/domains/root/db/yachts.html yachts -// yahoo : Oath Inc. +// yahoo : Yahoo Inc. // https://www.iana.org/domains/root/db/yahoo.html yahoo @@ -11200,6 +11200,10 @@ ltd.ua // 611coin : https://611project.org/ 611.to +// AAA workspace : https://aaa.vodka +// Submitted by Kirill Rezraf <admin@aaa.vodka> +aaa.vodka + // A2 Hosting // Submitted by Tyler Hall <sysadmin@a2hosting.com> a2hosted.com @@ -11346,23 +11350,28 @@ cloudfront.net // Amazon Cognito // Submitted by AWS Security <psl-maintainers@amazon.com> -// Reference: 7bee1013-f456-47df-bfe8-03c78d946d61 +// Reference: 09588633-91fe-49d8-b4e7-ec36496d11f3 auth.af-south-1.amazoncognito.com auth.ap-northeast-1.amazoncognito.com auth.ap-northeast-2.amazoncognito.com auth.ap-northeast-3.amazoncognito.com auth.ap-south-1.amazoncognito.com +auth.ap-south-2.amazoncognito.com auth.ap-southeast-1.amazoncognito.com auth.ap-southeast-2.amazoncognito.com auth.ap-southeast-3.amazoncognito.com +auth.ap-southeast-4.amazoncognito.com auth.ca-central-1.amazoncognito.com auth.eu-central-1.amazoncognito.com +auth.eu-central-2.amazoncognito.com auth.eu-north-1.amazoncognito.com auth.eu-south-1.amazoncognito.com +auth.eu-south-2.amazoncognito.com auth.eu-west-1.amazoncognito.com auth.eu-west-2.amazoncognito.com auth.eu-west-3.amazoncognito.com auth.il-central-1.amazoncognito.com +auth.me-central-1.amazoncognito.com auth.me-south-1.amazoncognito.com auth.sa-east-1.amazoncognito.com auth.us-east-1.amazoncognito.com @@ -11385,7 +11394,7 @@ us-east-1.amazonaws.com // Amazon EMR // Submitted by AWS Security <psl-maintainers@amazon.com> -// Reference: 597f3f8e-9283-4e48-8e32-7ee25a1ff6ab +// Reference: 82f43f9f-bbb8-400e-8349-854f5a62f20d emrappui-prod.cn-north-1.amazonaws.com.cn emrnotebooks-prod.cn-north-1.amazonaws.com.cn emrstudio-prod.cn-north-1.amazonaws.com.cn @@ -11410,6 +11419,9 @@ emrstudio-prod.ap-northeast-3.amazonaws.com emrappui-prod.ap-south-1.amazonaws.com emrnotebooks-prod.ap-south-1.amazonaws.com emrstudio-prod.ap-south-1.amazonaws.com +emrappui-prod.ap-south-2.amazonaws.com +emrnotebooks-prod.ap-south-2.amazonaws.com +emrstudio-prod.ap-south-2.amazonaws.com emrappui-prod.ap-southeast-1.amazonaws.com emrnotebooks-prod.ap-southeast-1.amazonaws.com emrstudio-prod.ap-southeast-1.amazonaws.com @@ -11419,18 +11431,30 @@ emrstudio-prod.ap-southeast-2.amazonaws.com emrappui-prod.ap-southeast-3.amazonaws.com emrnotebooks-prod.ap-southeast-3.amazonaws.com emrstudio-prod.ap-southeast-3.amazonaws.com +emrappui-prod.ap-southeast-4.amazonaws.com +emrnotebooks-prod.ap-southeast-4.amazonaws.com +emrstudio-prod.ap-southeast-4.amazonaws.com emrappui-prod.ca-central-1.amazonaws.com emrnotebooks-prod.ca-central-1.amazonaws.com emrstudio-prod.ca-central-1.amazonaws.com +emrappui-prod.ca-west-1.amazonaws.com +emrnotebooks-prod.ca-west-1.amazonaws.com +emrstudio-prod.ca-west-1.amazonaws.com emrappui-prod.eu-central-1.amazonaws.com emrnotebooks-prod.eu-central-1.amazonaws.com emrstudio-prod.eu-central-1.amazonaws.com +emrappui-prod.eu-central-2.amazonaws.com +emrnotebooks-prod.eu-central-2.amazonaws.com +emrstudio-prod.eu-central-2.amazonaws.com emrappui-prod.eu-north-1.amazonaws.com emrnotebooks-prod.eu-north-1.amazonaws.com emrstudio-prod.eu-north-1.amazonaws.com emrappui-prod.eu-south-1.amazonaws.com emrnotebooks-prod.eu-south-1.amazonaws.com emrstudio-prod.eu-south-1.amazonaws.com +emrappui-prod.eu-south-2.amazonaws.com +emrnotebooks-prod.eu-south-2.amazonaws.com +emrstudio-prod.eu-south-2.amazonaws.com emrappui-prod.eu-west-1.amazonaws.com emrnotebooks-prod.eu-west-1.amazonaws.com emrstudio-prod.eu-west-1.amazonaws.com @@ -11440,6 +11464,9 @@ emrstudio-prod.eu-west-2.amazonaws.com emrappui-prod.eu-west-3.amazonaws.com emrnotebooks-prod.eu-west-3.amazonaws.com emrstudio-prod.eu-west-3.amazonaws.com +emrappui-prod.il-central-1.amazonaws.com +emrnotebooks-prod.il-central-1.amazonaws.com +emrstudio-prod.il-central-1.amazonaws.com emrappui-prod.me-central-1.amazonaws.com emrnotebooks-prod.me-central-1.amazonaws.com emrstudio-prod.me-central-1.amazonaws.com @@ -11470,9 +11497,11 @@ emrstudio-prod.us-west-2.amazonaws.com // Amazon Managed Workflows for Apache Airflow // Submitted by AWS Security <psl-maintainers@amazon.com> -// Reference: 4ab55e6f-90c0-4a8d-b6a0-52ca5dbb1c2e +// Reference: 87f24ece-a77e-40e8-bb4a-f6b74fe9f975 *.cn-north-1.airflow.amazonaws.com.cn *.cn-northwest-1.airflow.amazonaws.com.cn +*.af-south-1.airflow.amazonaws.com +*.ap-east-1.airflow.amazonaws.com *.ap-northeast-1.airflow.amazonaws.com *.ap-northeast-2.airflow.amazonaws.com *.ap-south-1.airflow.amazonaws.com @@ -11481,12 +11510,15 @@ emrstudio-prod.us-west-2.amazonaws.com *.ca-central-1.airflow.amazonaws.com *.eu-central-1.airflow.amazonaws.com *.eu-north-1.airflow.amazonaws.com +*.eu-south-1.airflow.amazonaws.com *.eu-west-1.airflow.amazonaws.com *.eu-west-2.airflow.amazonaws.com *.eu-west-3.airflow.amazonaws.com +*.me-south-1.airflow.amazonaws.com *.sa-east-1.airflow.amazonaws.com *.us-east-1.airflow.amazonaws.com *.us-east-2.airflow.amazonaws.com +*.us-west-1.airflow.amazonaws.com *.us-west-2.airflow.amazonaws.com // Amazon S3 @@ -11780,9 +11812,25 @@ s3-fips.us-west-2.amazonaws.com s3-object-lambda.us-west-2.amazonaws.com s3-website.us-west-2.amazonaws.com +// Amazon SageMaker Ground Truth +// Submitted by AWS Security <psl-maintainers@amazon.com> +// Reference: 98dbfde4-7802-48c3-8751-b60f204e0d9c +labeling.ap-northeast-1.sagemaker.aws +labeling.ap-northeast-2.sagemaker.aws +labeling.ap-south-1.sagemaker.aws +labeling.ap-southeast-1.sagemaker.aws +labeling.ap-southeast-2.sagemaker.aws +labeling.ca-central-1.sagemaker.aws +labeling.eu-central-1.sagemaker.aws +labeling.eu-west-1.sagemaker.aws +labeling.eu-west-2.sagemaker.aws +labeling.us-east-1.sagemaker.aws +labeling.us-east-2.sagemaker.aws +labeling.us-west-2.sagemaker.aws + // Amazon SageMaker Notebook Instances // Submitted by AWS Security <psl-maintainers@amazon.com> -// Reference: ce8ae0b1-0070-496d-be88-37c31837af9d +// Reference: b5ea56df-669e-43cc-9537-14aa172f5dfc notebook.af-south-1.sagemaker.aws notebook.ap-east-1.sagemaker.aws notebook.ap-northeast-1.sagemaker.aws @@ -11819,6 +11867,7 @@ notebook-fips.us-gov-east-1.sagemaker.aws notebook.us-gov-west-1.sagemaker.aws notebook-fips.us-gov-west-1.sagemaker.aws notebook.us-west-1.sagemaker.aws +notebook-fips.us-west-1.sagemaker.aws notebook.us-west-2.sagemaker.aws notebook-fips.us-west-2.sagemaker.aws notebook.cn-north-1.sagemaker.com.cn @@ -11826,7 +11875,7 @@ notebook.cn-northwest-1.sagemaker.com.cn // Amazon SageMaker Studio // Submitted by AWS Security <psl-maintainers@amazon.com> -// Reference: 057ee397-6bf8-4f20-b807-d7bc145ac980 +// Reference: 69c723d9-6e1a-4bff-a203-48eecd203183 studio.af-south-1.sagemaker.aws studio.ap-east-1.sagemaker.aws studio.ap-northeast-1.sagemaker.aws @@ -11840,6 +11889,7 @@ studio.ca-central-1.sagemaker.aws studio.eu-central-1.sagemaker.aws studio.eu-north-1.sagemaker.aws studio.eu-south-1.sagemaker.aws +studio.eu-south-2.sagemaker.aws studio.eu-west-1.sagemaker.aws studio.eu-west-2.sagemaker.aws studio.eu-west-3.sagemaker.aws @@ -11951,6 +12001,11 @@ webview-assets.aws-cloud9.us-west-2.amazonaws.com vfs.cloud9.us-west-2.amazonaws.com webview-assets.cloud9.us-west-2.amazonaws.com +// AWS Directory Service +// Submitted by AWS Security <psl-maintainers@amazon.com> +// Reference: a13203e8-42dc-4045-a0d2-2ee67bed1068 +awsapps.com + // AWS Elastic Beanstalk // Submitted by AWS Security <psl-maintainers@amazon.com> // Reference: bb5a965c-dec3-4967-aa22-e306ad064797 @@ -12076,6 +12131,7 @@ autocode.dev // AVM : https://avm.de // Submitted by Andreas Weise <a.weise@avm.de> +myfritz.link myfritz.net // AVStack Pte. Ltd. : https://avstack.io @@ -12143,6 +12199,10 @@ pages.gay // Submitted by Adrian <adrian@betainabox.com> betainabox.com +// University of Bielsko-Biala regional domain: http://dns.bielsko.pl/ +// Submitted by Marcin <dns@ath.bielsko.pl> +bielsko.pl + // BinaryLane : http://www.binarylane.com // Submitted by Nathan O'Sullivan <nathan@mammoth.com.au> bnr.la @@ -12189,7 +12249,8 @@ square7.net *.s.brave.io // Brendly : https://brendly.rs -// Submitted by Dusan Radovanovic <dusan.radovanovic@brendly.rs> +// Submitted by Dusan Radovanovic <administracija@brendly.rs> +shop.brendly.hr shop.brendly.rs // BrowserSafetyMark @@ -12353,6 +12414,12 @@ pages.dev r2.dev workers.dev +// cloudscale.ch AG : https://www.cloudscale.ch/ +// Submitted by Gaudenz Steinlin <support@cloudscale.ch> +cust.cloudscale.ch +objects.lpg.cloudscale.ch +objects.rma.cloudscale.ch + // Clovyr : https://clovyr.io // Submitted by Patrick Nielsen <patrick@clovyr.io> wnext.app @@ -12370,22 +12437,33 @@ co.cz // CDN77.com : http://www.cdn77.com // Submitted by Jan Krpes <jan.krpes@cdn77.com> -c.cdn77.org +cdn77-storage.com +rsc.contentproxy9.cz cdn77-ssl.net r.cdn77.net -rsc.cdn77.org ssl.origin.cdn77-secure.org +c.cdn77.org +rsc.cdn77.org // Cloud DNS Ltd : http://www.cloudns.net -// Submitted by Aleksander Hristov <noc@cloudns.net> +// Submitted by Aleksander Hristov <noc@cloudns.net> & Boyan Peychev <boyan@cloudns.net> cloudns.asia +cloudns.be cloudns.biz -cloudns.club cloudns.cc +cloudns.ch +cloudns.cl +cloudns.club +dnsabr.com +cloudns.cx cloudns.eu cloudns.in cloudns.info +dns-cloud.net +dns-dynamic.net +cloudns.nz cloudns.org +cloudns.ph cloudns.pro cloudns.pw cloudns.us @@ -12398,6 +12476,11 @@ cnpy.gdn // Submitted by Moritz Marquardt <git@momar.de> codeberg.page +// CodeSandbox B.V. : https://codesandbox.io +// Submitted by Ives van Hoorne <abuse@codesandbox.io> +csb.app +preview.csb.app + // CoDNS B.V. co.nl co.no @@ -12516,6 +12599,7 @@ dyndns.dappnode.io // Dark, Inc. : https://darklang.com // Submitted by Paul Biggar <ops@darklang.com> builtwithdark.com +darklang.io // DataDetect, LLC. : https://datadetect.com // Submitted by Andrew Banchich <abanchich@sceven.com> @@ -12914,6 +12998,10 @@ ondigitalocean.app // Submitted by Robin H. Johnson <psl-maintainers@digitalocean.com> *.digitaloceanspaces.com +// DigitalPlat : https://www.digitalplat.org/ +// Submitted by Edward Hsing <contact@digitalplat.org> +us.kg + // dnstrace.pro : https://dnstrace.pro/ // Submitted by Chris Partridge <chris@partridge.tech> bci.dnstrace.pro @@ -12955,6 +13043,14 @@ easypanel.host // Submitted by <infracloudteam@namecheap.com> *.ewp.live +// Electromagnetic Field : https://www.emfcamp.org +// Submitted by <noc@emfcamp.org> +at.emf.camp + +// Elefunc, Inc. : https://elefunc.com +// Submitted by Cetin Sert <domains@elefunc.com> +rt.ht + // Elementor : Elementor Ltd. // Submitted by Anton Barkan <antonb@elementor.com> elementor.cloud @@ -13246,7 +13342,8 @@ forgeblocks.com id.forgerock.io // Framer : https://www.framer.com -// Submitted by Koen Rouwhorst <koenrh@framer.com> +// Submitted by Koen Rouwhorst <security@framer.com> +framer.ai framer.app framercanvas.com framer.media @@ -13287,6 +13384,24 @@ freemyip.com // Submitted by Daniel A. Maierhofer <vorstand@funkfeuer.at> wien.funkfeuer.at +// Future Versatile Group. :https://www.fvg-on.net/ +// T.Kabu <webmaster@fvg-on.net> +daemon.asia +dix.asia +mydns.bz +0am.jp +0g0.jp +0j0.jp +0t0.jp +mydns.jp +pgw.jp +wjg.jp +keyword-on.net +live-on.net +server-on.net +mydns.tw +mydns.vc + // Futureweb GmbH : https://www.futureweb.at // Submitted by Andreas Schnederle-Wagner <schnederle@futureweb.at> *.futurecms.at @@ -13330,9 +13445,11 @@ gentlentapis.com lab.ms cdn-edges.net -// Ghost Foundation : https://ghost.org -// Submitted by Matt Hanley <security@ghost.org> -ghost.io +// Getlocalcert: https://www.getlocalcert.net +// Submitted by Robert Alexander <support@getlocalcert.net> +localcert.net +localhostcert.net +corpnet.work // GignoSystemJapan: http://gsj.bz // Submitted by GignoSystemJapan <kakutou-ec@gsj.bz> @@ -13599,6 +13716,10 @@ goupile.fr // Submitted by <domeinnaam@minaz.nl> gov.nl +// GrayJay Web Solutions Inc. : https://grayjaysports.ca +// Submitted by Matt Yamkowy <info@grayjaysports.ca> +grayjayleagues.com + // Group 53, LLC : https://www.group53.com // Submitted by Tyler Todd <noc@nova53.net> awsmppl.com @@ -13633,6 +13754,11 @@ hasura-app.io // Submitted by Richard Zowalla <mi-admin@hs-heilbronn.de> pages.it.hs-heilbronn.de +// Helio Networks : https://heliohost.org +// Submitted by Ben Frede <admin@heliohost.org> +helioho.st +heliohost.us + // Hepforge : https://www.hepforge.org // Submitted by David Grellscheid <admin@hepforge.org> hepforge.org @@ -13646,7 +13772,6 @@ herokussl.com // Submitted by Oren Eini <oren@ravendb.net> ravendb.cloud ravendb.community -ravendb.me development.run ravendb.run @@ -13786,6 +13911,10 @@ iopsys.se // Submitted by Matthew Hardeman <mhardeman@ipifony.com> ipifony.net +// is-a.dev : https://www.is-a.dev +// Submitted by William Harrison <admin@maintainers.is-a.dev> +is-a.dev + // ir.md : https://nic.ir.md // Submitted by Ali Soizi <info@nic.ir.md> ir.md @@ -13898,6 +14027,11 @@ myjino.ru // Submitted by Daniel Fariña <ingenieria@jotelulu.com> jotelulu.cloud +// JouwWeb B.V. : https://www.jouwweb.nl +// Submitted by Camilo Sperberg <tech@webador.com> +jouwweb.site +webadorsite.com + // Joyent : https://www.joyent.com/ // Submitted by Brian Bennett <brian.bennett@joyent.com> *.triton.zone @@ -13971,6 +14105,10 @@ lpusercontent.com // Submitted by Lelux Admin <publisuffix@lelux.site> lelux.site +// Libre IT Ltd : https://libre.nz +// Submitted by Tomas Maggio <support@libre.nz> +runcontainers.dev + // Lifetime Hosting : https://Lifetime.Hosting/ // Submitted by Mike Fillator <support@lifetime.hosting> co.business @@ -13981,10 +14119,6 @@ co.network co.place co.technology -// Lightmaker Property Manager, Inc. : https://app.lmpm.com/ -// Submitted by Greg Holland <greg.holland@lmpm.com> -app.lmpm.com - // linkyard ldt: https://www.linkyard.ch/ // Submitted by Mario Siegenthaler <mario.siegenthaler@linkyard.ch> linkyard.cloud @@ -14145,7 +14279,6 @@ co.pl // Managed by Corporate Domains // Microsoft Azure : https://home.azure *.azurecontainer.io -cloudapp.azure.com azure-api.net azureedge.net azurefd.net @@ -14231,6 +14364,10 @@ netlify.app // Submitted by Trung Tran <Trung.Tran@neustar.biz> 4u.com +// NGO.US Registry : https://nic.ngo.us +// Submitted by Alstra Solutions Ltd. Networking Team <admin@alstra.org> +ngo.us + // ngrok : https://ngrok.com/ // Submitted by Alan Shreve <alan@ngrok.com> ngrok.app @@ -14252,8 +14389,9 @@ ngrok.pro torun.pl // Nimbus Hosting Ltd. : https://www.nimbushosting.co.uk/ -// Submitted by Nicholas Ford <nick@nimbushosting.co.uk> +// Submitted by Nicholas Ford <dev@nimbushosting.co.uk> nh-serv.co.uk +nimsite.uk // NFSN, Inc. : https://www.NearlyFreeSpeech.NET/ // Submitted by Jeff Wheelhouse <support@nearlyfreespeech.net> @@ -14413,6 +14551,10 @@ pcloud.host // Submitted by Matthew Brown <mattbrown@nyc.mn> nyc.mn +// O3O.Foundation : https://o3o.foundation/ +// Submitted by the prvcy.page Registry Team <psl@registry.prvcy.page> +prvcy.page + // Observable, Inc. : https://observablehq.com // Submitted by Mike Bostock <dns@observablehq.com> static.observableusercontent.com @@ -14442,7 +14584,6 @@ omniwe.site 123minsida.se 123miweb.es 123paginaweb.pt -123sait.ru 123siteweb.fr 123webseite.at 123webseite.de @@ -14460,6 +14601,13 @@ simplesite.pl // Submitted by Eddie Jones <eddie@onefoldmedia.com> nid.io +// Open Domains : https://open-domains.net +// Submitted by William Harrison <admin@open-domains.net> +is-cool.dev +is-not-a.dev +localplayer.dev +is-local.org + // Open Social : https://www.getopensocial.com/ // Submitted by Alexander Varwijk <security@getopensocial.com> opensocial.site @@ -14480,6 +14628,11 @@ operaunite.com // Submitted by Alexandre Linte <alexandre.linte@orange.com> tech.orange +// OsSav Technology Ltd. : https://ossav.com/ +// TLD Nic: http://nic.can.re - TLD Whois Server: whois.can.re +// Submitted by OsSav Technology Ltd. <support@ossav.com> +can.re + // Oursky Limited : https://authgear.com/, https://skygear.io/ // Submitted by Authgear Team <hello@authgear.com>, Skygear Developer <hello@skygear.io> authgear-staging.com @@ -14530,10 +14683,11 @@ pagexl.com // pcarrier.ca Software Inc: https://pcarrier.ca/ // Submitted by Pierre Carrier <pc@rrier.ca> -bar0.net -bar1.net -bar2.net -rdv.to +*.xmit.co +xmit.dev +srv.us +gh.srv.us +gl.srv.us // .pl domains (grandfathered) art.pl @@ -14621,10 +14775,6 @@ xen.prgmr.com // Submitted by registry <lendl@nic.at> priv.at -// privacytools.io : https://www.privacytools.io/ -// Submitted by Jonah Aragon <jonah@privacytools.io> -prvcy.page - // Protocol Labs : https://protocol.ai/ // Submitted by Michael Burns <noc@protocol.ai> *.dweb.link @@ -14691,9 +14841,12 @@ qcx.io *.sys.qcx.io // QNAP System Inc : https://www.qnap.com -// Submitted by Nick Chang <nickchang@qnap.com> -dev-myqnapcloud.com +// Submitted by Nick Chang <cloudadmin@qnap.com> +myqnapcloud.cn alpha-myqnapcloud.com +dev-myqnapcloud.com +mycloudnas.com +mynascloud.com myqnapcloud.com // Quip : https://quip.com @@ -14923,6 +15076,10 @@ service.gov.scot // Submitted by Shante Adam <shante@skyhat.io> scrysec.com +// Scrypted : https://scrypted.app +// Submitted by Koushik Dutta <public-suffix-list@scrypted.app> +client.scrypted.io + // Securepoint GmbH : https://www.securepoint.de // Submitted by Erik Anders <erik.anders@securepoint.de> firewall-gateway.com @@ -15032,9 +15189,9 @@ small-web.org vp4.me // Snowflake Inc : https://www.snowflake.com/ -// Submitted by Faith Olapade <faith.olapade@snowflake.com> -snowflake.app -privatelink.snowflake.app +// Submitted by Sam Haar <psl@snowflake.com> +*.snowflake.app +*.privatelink.snowflake.app streamlit.app streamlitapp.com @@ -15046,6 +15203,12 @@ try-snowplow.com // Submitted by Drew DeVault <sir@cmpwn.com> srht.site +// StackBlitz : https://stackblitz.com +// Submitted by Dominic Elm <hello@stackblitz.com> +w-corp-staticblitz.com +w-credentialless-staticblitz.com +w-staticblitz.com + // Stackhero : https://www.stackhero.io // Submitted by Adrien Gillon <adrien+public-suffix-list@stackhero.io> stackhero-network.com @@ -15347,6 +15510,10 @@ inc.hk // Submitted by ITComdomains <to@it.com> it.com +// Unison Computing, PBC : https://unison.cloud +// Submitted by Simon Højberg <security@unison.cloud> +unison-services.cloud + // UNIVERSAL DOMAIN REGISTRY : https://www.udr.org.yt/ // see also: whois -h whois.udr.org.yt help // Submitted by Atanunu Igbunuroghene <publicsuffixlist@udr.org.yt> @@ -15396,47 +15563,6 @@ v-info.info // Submitted by Nathan van Bakel <info@voorloper.com> voorloper.cloud -// Voxel.sh DNS : https://voxel.sh/dns/ -// Submitted by Mia Rehlinger <dns@voxel.sh> -neko.am -nyaa.am -be.ax -cat.ax -es.ax -eu.ax -gg.ax -mc.ax -us.ax -xy.ax -nl.ci -xx.gl -app.gp -blog.gt -de.gt -to.gt -be.gy -cc.hn -io.kg -jp.kg -tv.kg -uk.kg -us.kg -de.ls -at.md -de.md -jp.md -to.md -indie.porn -vxl.sh -ch.tc -me.tc -we.tc -nyan.to -at.vg -blog.vu -dev.vu -me.vu - // V.UA Domain Administrator : https://domain.v.ua/ // Submitted by Serhii Rostilo <sergey@rostilo.kiev.ua> v.ua @@ -15465,6 +15591,10 @@ reserve-online.com bookonline.app hotelwithflight.com +// WebWaddle Ltd: https://webwaddle.com/ +// Submitted by Merlin Glander <hostmaster@webwaddle.com> +*.wadl.top + // WeDeploy by Liferay, Inc. : https://www.wedeploy.com // Submitted by Henrique Vicente <security@wedeploy.com> wedeploy.io diff --git a/netwerk/dns/nsHostResolver.cpp b/netwerk/dns/nsHostResolver.cpp index ad28cbb284..b74b974041 100644 --- a/netwerk/dns/nsHostResolver.cpp +++ b/netwerk/dns/nsHostResolver.cpp @@ -1490,6 +1490,18 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookup( aReason, aTRRRequest, lock); } +namespace { +class NetAddrIPv6FirstComparator { + public: + static bool Equals(const NetAddr& aLhs, const NetAddr& aRhs) { + return aLhs.raw.family == aRhs.raw.family; + } + static bool LessThan(const NetAddr& aLhs, const NetAddr& aRhs) { + return aLhs.raw.family > aRhs.raw.family; + } +}; +} // namespace + nsHostResolver::LookupStatus nsHostResolver::CompleteLookupLocked( nsHostRecord* rec, nsresult status, AddrInfo* aNewRRSet, bool pb, const nsACString& aOriginsuffix, TRRSkippedReason aReason, @@ -1601,6 +1613,16 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookupLocked( old_addr_info = std::move(newRRSet); } addrRec->negative = !addrRec->addr_info; + + if (addrRec->addr_info && StaticPrefs::network_dns_preferIPv6() && + addrRec->addr_info->Addresses().Length() > 1 && + addrRec->addr_info->Addresses()[0].IsIPAddrV4()) { + // Sort IPv6 addresses first. + auto builder = addrRec->addr_info->Build(); + builder.SortAddresses(NetAddrIPv6FirstComparator()); + addrRec->addr_info = builder.Finish(); + } + PrepareRecordExpirationAddrRecord(addrRec); } @@ -1673,6 +1695,15 @@ nsHostResolver::LookupStatus nsHostResolver::CompleteLookupByTypeLocked( MOZ_ASSERT(rec->pb == pb); MOZ_ASSERT(!rec->IsAddrRecord()); + if (rec->LoadNative()) { + // If this was resolved using the native resolver + // we also need to update the global count. + if (rec->LoadUsingAnyThread()) { + mActiveAnyThreadCount--; + rec->StoreUsingAnyThread(false); + } + } + RefPtr<TypeHostRecord> typeRec = do_QueryObject(rec); MOZ_ASSERT(typeRec); diff --git a/netwerk/dns/nsIDNSByTypeRecord.idl b/netwerk/dns/nsIDNSByTypeRecord.idl index 1d11325af8..13290e260e 100644 --- a/netwerk/dns/nsIDNSByTypeRecord.idl +++ b/netwerk/dns/nsIDNSByTypeRecord.idl @@ -102,7 +102,7 @@ interface nsISVCBRecord : nsISupports { readonly attribute ACString selectedAlpn; readonly attribute ACString echConfig; readonly attribute ACString ODoHConfig; - readonly attribute bool hasIPHintAddress; + readonly attribute boolean hasIPHintAddress; readonly attribute Array<nsISVCParam> values; }; diff --git a/netwerk/dns/nsIDNSRecord.idl b/netwerk/dns/nsIDNSRecord.idl index 82682bd900..27df2e28be 100644 --- a/netwerk/dns/nsIDNSRecord.idl +++ b/netwerk/dns/nsIDNSRecord.idl @@ -111,12 +111,12 @@ interface nsIDNSAddrRecord : nsIDNSRecord /** * Record retreived with TRR. */ - bool IsTRR(); + boolean IsTRR(); /** * Record is resolved in socket process. */ - bool resolvedInSocketProcess(); + boolean resolvedInSocketProcess(); /** * This attribute is only set if TRR is used and it measures time between diff --git a/netwerk/dns/nsIEffectiveTLDService.idl b/netwerk/dns/nsIEffectiveTLDService.idl index abf786e5ed..383a6daeb5 100644 --- a/netwerk/dns/nsIEffectiveTLDService.idl +++ b/netwerk/dns/nsIEffectiveTLDService.idl @@ -201,5 +201,5 @@ interface nsIEffectiveTLDService : nsISupports * @param aInput The host to be analyzed. * @param aHost The host to compare to. */ - bool hasRootDomain(in AUTF8String aInput, in AUTF8String aHost); + boolean hasRootDomain(in AUTF8String aInput, in AUTF8String aHost); }; diff --git a/netwerk/ipc/DocumentLoadListener.cpp b/netwerk/ipc/DocumentLoadListener.cpp index d849eab750..32d7036ff1 100644 --- a/netwerk/ipc/DocumentLoadListener.cpp +++ b/netwerk/ipc/DocumentLoadListener.cpp @@ -1997,12 +1997,6 @@ bool DocumentLoadListener::MaybeTriggerProcessSwitch( return false; } - if (!StaticPrefs::fission_remoteObjectEmbed()) { - MOZ_LOG(gProcessIsolationLog, LogLevel::Verbose, - ("Process Switch Abort: remote <object>/<embed> disabled")); - return false; - } - mObjectUpgradeHandler->UpgradeObjectLoad()->Then( GetMainThreadSerialEventTarget(), __func__, [self = RefPtr{this}, options, parentWindow]( diff --git a/netwerk/ipc/NeckoChannelParams.ipdlh b/netwerk/ipc/NeckoChannelParams.ipdlh index c2948c7766..62b272e99c 100644 --- a/netwerk/ipc/NeckoChannelParams.ipdlh +++ b/netwerk/ipc/NeckoChannelParams.ipdlh @@ -63,6 +63,7 @@ struct CookieJarSettingsArgs nsString partitionKey; bool hasFingerprintingRandomizationKey; uint8_t[] fingerprintingRandomizationKey; + uint64_t topLevelWindowContextId; }; //----------------------------------------------------------------------------- diff --git a/netwerk/metrics.yaml b/netwerk/metrics.yaml index 641c1500a6..648dced01e 100644 --- a/netwerk/metrics.yaml +++ b/netwerk/metrics.yaml @@ -452,22 +452,6 @@ networking: - rjesup@mozilla.com expires: 130 - http_content_ondatafinished_to_onstop_delay_negative: - type: timing_distribution - time_unit: millisecond - description: > - The time between processing OnStopRequest and processing OnDataFinished (if OnStopRequest comes first) - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1857615 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1857615#c - data_sensitivity: - - technical - notification_emails: - - necko@mozilla.com - - rjesup@mozilla.com - expires: 130 - http_content_html5parser_ondatafinished_to_onstop_delay: type: timing_distribution time_unit: millisecond @@ -484,22 +468,6 @@ networking: - rjesup@mozilla.com expires: 130 - http_content_html5parser_ondatafinished_to_onstop_delay_negative: - type: timing_distribution - time_unit: millisecond - description: > - The time between processing OnStopRequest and processing OnDataFinished (if OnStopRequest comes first) - bugs: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1857926 - data_reviews: - - https://bugzilla.mozilla.org/show_bug.cgi?id=1857926 - data_sensitivity: - - technical - notification_emails: - - necko@mozilla.com - - rjesup@mozilla.com - expires: 130 - http_content_cssloader_ondatafinished_to_onstop_delay: type: timing_distribution time_unit: millisecond diff --git a/netwerk/mime/nsIMIMEInfo.idl b/netwerk/mime/nsIMIMEInfo.idl index a7ffcfe513..97d7660932 100644 --- a/netwerk/mime/nsIMIMEInfo.idl +++ b/netwerk/mime/nsIMIMEInfo.idl @@ -53,19 +53,24 @@ interface nsIHandlerInfo : nsISupports { readonly attribute nsIMutableArray possibleApplicationHandlers; /** - * Indicates whether a default application handler exists, + * Indicates whether a default OS application handler exists, * i.e. whether launchWithFile with action = useSystemDefault is possible * and defaultDescription will contain usable information. */ readonly attribute boolean hasDefaultHandler; /** - * A pretty name description of the associated default application. Only + * A pretty name description of the associated default OS application. Only * usable if hasDefaultHandler is true. */ readonly attribute AString defaultDescription; /** + * The default OS application. Only usable if hasDefaultHandler is true. + */ + readonly attribute nsIFile defaultExecutable; + + /** * Launches the application with the specified URI, in a way that * depends on the value of preferredAction. preferredAction must be * useHelperApp or useSystemDefault. @@ -281,6 +286,24 @@ interface nsILocalHandlerApp : nsIHandlerApp { readonly attribute unsigned long parameterCount; /** + * Asynchronously returns the pretty (user friendly) name of the + * executable. + * + * On Linux and Mac, this is the same as the name + * property. On Mac, that happens to be a nicer name than + * the executable's name without the file extension. + * + * On Windows, this name will be nicer, looked up from the + * registry when it exists and falling back to the FileDescription + * getVersionFieldInfo when the registry data doesn't exist. + * This has the side effect that the prettyName returned + * generally will match the text returned by defaultDescription in + * nsIHandlerInfo. + */ + [implicit_jscontext] + Promise prettyNameAsync(); + + /** * Clears the current list of command line parameters. */ void clearParameters(); diff --git a/netwerk/mime/nsMimeTypes.h b/netwerk/mime/nsMimeTypes.h index 86934d44fd..66034c7b2c 100644 --- a/netwerk/mime/nsMimeTypes.h +++ b/netwerk/mime/nsMimeTypes.h @@ -31,6 +31,7 @@ #define APPLICATION_GZIP2 "application/gzip" #define APPLICATION_GZIP3 "application/x-gunzip" #define APPLICATION_BROTLI "application/brotli" +#define APPLICATION_ZSTD "application/zstd" #define APPLICATION_ZIP "application/zip" #define APPLICATION_HTTP_INDEX_FORMAT "application/http-index-format" #define APPLICATION_ECMASCRIPT "application/ecmascript" @@ -245,6 +246,7 @@ #define ENCODING_UUENCODE3 "uuencode" #define ENCODING_UUENCODE4 "uue" #define ENCODING_YENCODE "x-yencode" +#define ENCODING_ZSTD "zstd" /* Some names of parameters that various MIME headers include. */ diff --git a/netwerk/protocol/http/ConnectionEntry.cpp b/netwerk/protocol/http/ConnectionEntry.cpp index 7b59011cd3..dc0dfd103c 100644 --- a/netwerk/protocol/http/ConnectionEntry.cpp +++ b/netwerk/protocol/http/ConnectionEntry.cpp @@ -124,6 +124,7 @@ void ConnectionEntry::DisallowHttp2() { // Can't coalesce if we're not using spdy mCoalescingKeys.Clear(); + mAddresses.Clear(); } void ConnectionEntry::DontReuseHttp3Conn() { @@ -137,6 +138,7 @@ void ConnectionEntry::DontReuseHttp3Conn() { // Can't coalesce if we're not using http3 mCoalescingKeys.Clear(); + mAddresses.Clear(); } void ConnectionEntry::RecordIPFamilyPreference(uint16_t family) { @@ -447,6 +449,7 @@ void ConnectionEntry::ClosePersistentConnections() { } mCoalescingKeys.Clear(); + mAddresses.Clear(); } uint32_t ConnectionEntry::PruneDeadConnections() { @@ -969,18 +972,16 @@ bool ConnectionEntry::MaybeProcessCoalescingKeys(nsIDNSAddrRecord* dnsRecord, return false; } - nsTArray<NetAddr> addressSet; - nsresult rv = dnsRecord->GetAddresses(addressSet); - - if (NS_FAILED(rv) || addressSet.IsEmpty()) { + nsresult rv = dnsRecord->GetAddresses(mAddresses); + if (NS_FAILED(rv) || mAddresses.IsEmpty()) { return false; } - for (uint32_t i = 0; i < addressSet.Length(); ++i) { - if ((addressSet[i].raw.family == AF_INET && addressSet[i].inet.ip == 0) || - (addressSet[i].raw.family == AF_INET6 && - addressSet[i].inet6.ip.u64[0] == 0 && - addressSet[i].inet6.ip.u64[1] == 0)) { + for (uint32_t i = 0; i < mAddresses.Length(); ++i) { + if ((mAddresses[i].raw.family == AF_INET && mAddresses[i].inet.ip == 0) || + (mAddresses[i].raw.family == AF_INET6 && + mAddresses[i].inet6.ip.u64[0] == 0 && + mAddresses[i].inet6.ip.u64[1] == 0)) { // Bug 1680249 - Don't create the coalescing key if the ip address is // `0.0.0.0` or `::`. LOG( @@ -991,7 +992,7 @@ bool ConnectionEntry::MaybeProcessCoalescingKeys(nsIDNSAddrRecord* dnsRecord, } nsCString* newKey = mCoalescingKeys.AppendElement(nsCString()); newKey->SetLength(kIPv6CStrBufSize + 26); - addressSet[i].ToStringBuffer(newKey->BeginWriting(), kIPv6CStrBufSize); + mAddresses[i].ToStringBuffer(newKey->BeginWriting(), kIPv6CStrBufSize); newKey->SetLength(strlen(newKey->BeginReading())); if (mConnInfo->GetAnonymous()) { newKey->AppendLiteral("~A:"); diff --git a/netwerk/protocol/http/ConnectionEntry.h b/netwerk/protocol/http/ConnectionEntry.h index 8ccc126503..6a265e58fc 100644 --- a/netwerk/protocol/http/ConnectionEntry.h +++ b/netwerk/protocol/http/ConnectionEntry.h @@ -121,8 +121,14 @@ class ConnectionEntry { // combined with the Anonymous flag and OA from the connection information // to build the hash key for hosts in the same ip pool. // + nsTArray<nsCString> mCoalescingKeys; + // This is a list of addresses matching the coalescing keys. + // This is necessary to check if the origin's DNS entries + // contain the IP address of the active connection. + nsTArray<NetAddr> mAddresses; + // To have the UsingSpdy flag means some host with the same connection // entry has done NPN=spdy/* at some point. It does not mean every // connection is currently using spdy. diff --git a/netwerk/protocol/http/EarlyHintPreloader.cpp b/netwerk/protocol/http/EarlyHintPreloader.cpp index 920fea7fcd..3c8fd5a882 100644 --- a/netwerk/protocol/http/EarlyHintPreloader.cpp +++ b/netwerk/protocol/http/EarlyHintPreloader.cpp @@ -330,7 +330,7 @@ void EarlyHintPreloader::MaybeCreateAndInsertPreload( // directives to it nsCOMPtr<nsIContentSecurityPolicy> csp = new nsCSPContext(); nsresult rv = csp->SetRequestContextWithPrincipal( - aPrincipal, aBaseURI, u""_ns, 0 /* aInnerWindowId */); + aPrincipal, aBaseURI, ""_ns, 0 /* aInnerWindowId */); NS_ENSURE_SUCCESS_VOID(rv); rv = CSP_AppendCSPFromHeader(csp, NS_ConvertUTF8toUTF16(aCSPHeader), false /* report only */); diff --git a/netwerk/protocol/http/Http3Stream.cpp b/netwerk/protocol/http/Http3Stream.cpp index 4f33ca07e2..4bb6b30925 100644 --- a/netwerk/protocol/http/Http3Stream.cpp +++ b/netwerk/protocol/http/Http3Stream.cpp @@ -42,7 +42,7 @@ Http3Stream::Http3Stream(nsAHttpTransaction* httpTransaction, mTransactionBrowserId = trans->BrowserId(); } - SetPriority(cos.Flags()); + mPriorityUrgency = nsHttpHandler::UrgencyFromCoSFlags(cos.Flags()); SetIncremental(cos.Incremental()); } @@ -80,31 +80,6 @@ bool Http3Stream::GetHeadersString(const char* buf, uint32_t avail, return true; } -void Http3Stream::SetPriority(uint32_t aCos) { - if (aCos & nsIClassOfService::UrgentStart) { - // coming from an user interaction => response should be the highest - // priority - mPriorityUrgency = 1; - } else if (aCos & nsIClassOfService::Leader) { - // main html document normal priority - mPriorityUrgency = 2; - } else if (aCos & nsIClassOfService::Unblocked) { - mPriorityUrgency = 3; - } else if (aCos & nsIClassOfService::Follower) { - mPriorityUrgency = 4; - } else if (aCos & nsIClassOfService::Speculative) { - mPriorityUrgency = 6; - } else if (aCos & nsIClassOfService::Background) { - // background tasks can be deprioritzed to the lowest priority - mPriorityUrgency = 6; - } else if (aCos & nsIClassOfService::Tail) { - mPriorityUrgency = 6; - } else { - // all others get a lower priority than the main html document - mPriorityUrgency = 4; - } -} - void Http3Stream::SetIncremental(bool incremental) { mPriorityIncremental = incremental; } diff --git a/netwerk/protocol/http/Http3Stream.h b/netwerk/protocol/http/Http3Stream.h index 1048b20ef5..fbfd567cbf 100644 --- a/netwerk/protocol/http/Http3Stream.h +++ b/netwerk/protocol/http/Http3Stream.h @@ -67,7 +67,6 @@ class Http3Stream final : public nsAHttpSegmentReader, bool GetHeadersString(const char* buf, uint32_t avail, uint32_t* countUsed); nsresult StartRequest(); - void SetPriority(uint32_t aCos); void SetIncremental(bool incremental); /** diff --git a/netwerk/protocol/http/HttpBaseChannel.cpp b/netwerk/protocol/http/HttpBaseChannel.cpp index 9008d758fc..ff88b02753 100644 --- a/netwerk/protocol/http/HttpBaseChannel.cpp +++ b/netwerk/protocol/http/HttpBaseChannel.cpp @@ -1402,7 +1402,7 @@ nsresult HttpBaseChannel::DoApplyContentConversions( // channels cannot effectively be used in two contexts (specifically this one // and a peek context for sniffing) // -class InterceptFailedOnStop : public nsIStreamListener { +class InterceptFailedOnStop : public nsIThreadRetargetableStreamListener { virtual ~InterceptFailedOnStop() = default; nsCOMPtr<nsIStreamListener> mNext; HttpBaseChannel* mChannel; @@ -1411,6 +1411,7 @@ class InterceptFailedOnStop : public nsIStreamListener { InterceptFailedOnStop(nsIStreamListener* arg, HttpBaseChannel* chan) : mNext(arg), mChannel(chan) {} NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER NS_IMETHOD OnStartRequest(nsIRequest* aRequest) override { return mNext->OnStartRequest(aRequest); @@ -1432,7 +1433,37 @@ class InterceptFailedOnStop : public nsIStreamListener { } }; -NS_IMPL_ISUPPORTS(InterceptFailedOnStop, nsIStreamListener, nsIRequestObserver) +NS_IMPL_ADDREF(InterceptFailedOnStop) +NS_IMPL_RELEASE(InterceptFailedOnStop) + +NS_INTERFACE_MAP_BEGIN(InterceptFailedOnStop) + NS_INTERFACE_MAP_ENTRY(nsIStreamListener) + NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) + NS_INTERFACE_MAP_ENTRY(nsIThreadRetargetableStreamListener) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRequestObserver) +NS_INTERFACE_MAP_END + +NS_IMETHODIMP +InterceptFailedOnStop::CheckListenerChain() { + nsCOMPtr<nsIThreadRetargetableStreamListener> listener = + do_QueryInterface(mNext); + if (!listener) { + return NS_ERROR_NO_INTERFACE; + } + + return listener->CheckListenerChain(); +} + +NS_IMETHODIMP +InterceptFailedOnStop::OnDataFinished(nsresult aStatus) { + nsCOMPtr<nsIThreadRetargetableStreamListener> listener = + do_QueryInterface(mNext); + if (listener) { + return listener->OnDataFinished(aStatus); + } + + return NS_OK; +} NS_IMETHODIMP HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener, @@ -1508,6 +1539,8 @@ HttpBaseChannel::DoApplyContentConversions(nsIStreamListener* aNextListener, mode = 2; } else if (from.EqualsLiteral("br")) { mode = 3; + } else if (from.EqualsLiteral("zstd")) { + mode = 4; } Telemetry::Accumulate(Telemetry::HTTP_CONTENT_ENCODING, mode); } @@ -1612,6 +1645,14 @@ HttpBaseChannel::nsContentEncodings::GetNext(nsACString& aNextEncoding) { } } + if (!haveType) { + encoding.BeginReading(start); + if (CaseInsensitiveFindInReadable("zstd"_ns, start, end)) { + aNextEncoding.AssignLiteral(APPLICATION_ZSTD); + haveType = true; + } + } + // Prepare to fetch the next encoding mCurEnd = mCurStart; mReady = false; @@ -2392,7 +2433,6 @@ HttpBaseChannel::GetDocumentURI(nsIURI** aDocumentURI) { NS_IMETHODIMP HttpBaseChannel::SetDocumentURI(nsIURI* aDocumentURI) { ENSURE_CALLED_BEFORE_CONNECT(); - mDocumentURI = aDocumentURI; return NS_OK; } @@ -4973,7 +5013,7 @@ nsresult HttpBaseChannel::SetupReplacementChannel(nsIURI* newURI, httpInternal->SetLastRedirectFlags(redirectFlags); if (LoadRequireCORSPreflight()) { - httpInternal->SetCorsPreflightParameters(mUnsafeHeaders, false); + httpInternal->SetCorsPreflightParameters(mUnsafeHeaders, false, false); } } @@ -5847,17 +5887,20 @@ void HttpBaseChannel::EnsureBrowserId() { void HttpBaseChannel::SetCorsPreflightParameters( const nsTArray<nsCString>& aUnsafeHeaders, - bool aShouldStripRequestBodyHeader) { + bool aShouldStripRequestBodyHeader, bool aShouldStripAuthHeader) { MOZ_RELEASE_ASSERT(!LoadRequestObserversCalled()); StoreRequireCORSPreflight(true); mUnsafeHeaders = aUnsafeHeaders.Clone(); - if (aShouldStripRequestBodyHeader) { + if (aShouldStripRequestBodyHeader || aShouldStripAuthHeader) { mUnsafeHeaders.RemoveElementsBy([&](const nsCString& aHeader) { - return aHeader.LowerCaseEqualsASCII("content-type") || - aHeader.LowerCaseEqualsASCII("content-encoding") || - aHeader.LowerCaseEqualsASCII("content-language") || - aHeader.LowerCaseEqualsASCII("content-location"); + return (aShouldStripRequestBodyHeader && + (aHeader.LowerCaseEqualsASCII("content-type") || + aHeader.LowerCaseEqualsASCII("content-encoding") || + aHeader.LowerCaseEqualsASCII("content-language") || + aHeader.LowerCaseEqualsASCII("content-location"))) || + (aShouldStripAuthHeader && + aHeader.LowerCaseEqualsASCII("authorization")); }); } } diff --git a/netwerk/protocol/http/HttpBaseChannel.h b/netwerk/protocol/http/HttpBaseChannel.h index f3678bb0c9..d6d693212b 100644 --- a/netwerk/protocol/http/HttpBaseChannel.h +++ b/netwerk/protocol/http/HttpBaseChannel.h @@ -319,7 +319,7 @@ class HttpBaseChannel : public nsHashPropertyBag, NS_IMETHOD GetProxyURI(nsIURI** proxyURI) override; virtual void SetCorsPreflightParameters( const nsTArray<nsCString>& unsafeHeaders, - bool aShouldStripRequestBodyHeader) override; + bool aShouldStripRequestBodyHeader, bool aShouldStripAuthHeader) override; virtual void SetAltDataForChild(bool aIsForChild) override; virtual void DisableAltDataCache() override { StoreDisableAltDataCache(true); diff --git a/netwerk/protocol/http/HttpChannelChild.cpp b/netwerk/protocol/http/HttpChannelChild.cpp index c7009f34d3..8b581b070e 100644 --- a/netwerk/protocol/http/HttpChannelChild.cpp +++ b/netwerk/protocol/http/HttpChannelChild.cpp @@ -8,7 +8,7 @@ // HttpLog.h should generally be included first #include "HttpLog.h" -#include "mozilla/net/PBackgroundDataBridge.h" +#include "nsError.h" #include "nsHttp.h" #include "nsICacheEntry.h" #include "mozilla/BasePrincipal.h" @@ -23,6 +23,7 @@ #include "mozilla/ipc/IPCStreamUtils.h" #include "mozilla/net/NeckoChild.h" #include "mozilla/net/HttpChannelChild.h" +#include "mozilla/net/PBackgroundDataBridge.h" #include "mozilla/net/UrlClassifierCommon.h" #include "mozilla/net/UrlClassifierFeatureFactory.h" @@ -34,6 +35,7 @@ #include "nsContentPolicyUtils.h" #include "nsDOMNavigationTiming.h" #include "nsIThreadRetargetableStreamListener.h" +#include "nsIStreamTransportService.h" #include "nsStringStream.h" #include "nsHttpChannel.h" #include "nsHttpHandler.h" @@ -598,6 +600,17 @@ void HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest) { } else if (listener) { mListener = listener; mCompressListener = listener; + + // We call MaybeRetarget here to allow the stream converter + // the option to request data on another thread, even if the + // final listener might not support it + if (nsCOMPtr<nsIStreamConverter> conv = + do_QueryInterface((mCompressListener))) { + rv = conv->MaybeRetarget(this); + if (NS_SUCCEEDED(rv)) { + mOMTResult = LABELS_HTTP_CHILD_OMT_STATS_2::successOnlyDecomp; + } + } } } @@ -852,15 +865,10 @@ class RecordStopRequestDelta final { } TimeDuration delta = (mOnStopRequestTime - mOnDataFinishedTime); - if (delta.ToMilliseconds() < 0) { - // Because Telemetry can't handle negatives - delta = -delta; - glean::networking::http_content_ondatafinished_to_onstop_delay_negative - .AccumulateRawDuration(delta); - } else { - glean::networking::http_content_ondatafinished_to_onstop_delay - .AccumulateRawDuration(delta); - } + MOZ_ASSERT((delta.ToMilliseconds() >= 0), + "OnDataFinished after OnStopRequest"); + glean::networking::http_content_ondatafinished_to_onstop_delay + .AccumulateRawDuration(delta); } }; @@ -1157,7 +1165,7 @@ void HttpChannelChild::CollectOMTTelemetry() { NS_CP_ContentTypeName(mLoadInfo->InternalContentPolicyType())); Telemetry::AccumulateCategoricalKeyed( - key, static_cast<LABELS_HTTP_CHILD_OMT_STATS>(mOMTResult)); + key, static_cast<LABELS_HTTP_CHILD_OMT_STATS_2>(mOMTResult)); } // We want to inspect all upgradable mixed content loads @@ -3055,7 +3063,7 @@ HttpChannelChild::RetargetDeliveryTo(nsISerialEventTarget* aNewTarget) { NS_ENSURE_ARG(aNewTarget); if (aNewTarget->IsOnCurrentThread()) { NS_WARNING("Retargeting delivery to same thread"); - mOMTResult = LABELS_HTTP_CHILD_OMT_STATS::successMainThread; + mOMTResult = LABELS_HTTP_CHILD_OMT_STATS_2::successMainThread; return NS_OK; } @@ -3063,7 +3071,7 @@ HttpChannelChild::RetargetDeliveryTo(nsISerialEventTarget* aNewTarget) { // TODO: Maybe add a new label for this? Maybe it doesn't // matter though, since we also blocked QI, so we shouldn't // ever get here. - mOMTResult = LABELS_HTTP_CHILD_OMT_STATS::failListener; + mOMTResult = LABELS_HTTP_CHILD_OMT_STATS_2::failListener; return NS_ERROR_NO_INTERFACE; } @@ -3074,27 +3082,34 @@ HttpChannelChild::RetargetDeliveryTo(nsISerialEventTarget* aNewTarget) { do_QueryInterface(mListener, &rv); if (!retargetableListener || NS_FAILED(rv)) { NS_WARNING("Listener is not retargetable"); - mOMTResult = LABELS_HTTP_CHILD_OMT_STATS::failListener; + mOMTResult = LABELS_HTTP_CHILD_OMT_STATS_2::failListener; return NS_ERROR_NO_INTERFACE; } rv = retargetableListener->CheckListenerChain(); if (NS_FAILED(rv)) { NS_WARNING("Subsequent listeners are not retargetable"); - mOMTResult = LABELS_HTTP_CHILD_OMT_STATS::failListenerChain; + mOMTResult = LABELS_HTTP_CHILD_OMT_STATS_2::failListenerChain; return rv; } { MutexAutoLock lock(mEventTargetMutex); MOZ_ASSERT(!mODATarget); - mODATarget = aNewTarget; + RetargetDeliveryToImpl(aNewTarget, lock); } - mOMTResult = LABELS_HTTP_CHILD_OMT_STATS::success; + mOMTResult = LABELS_HTTP_CHILD_OMT_STATS_2::success; return NS_OK; } +void HttpChannelChild::RetargetDeliveryToImpl(nsISerialEventTarget* aNewTarget, + MutexAutoLock& aLockRef) { + aLockRef.AssertOwns(mEventTargetMutex); + + mODATarget = aNewTarget; +} + NS_IMETHODIMP HttpChannelChild::GetDeliveryTarget(nsISerialEventTarget** aEventTarget) { MutexAutoLock lock(mEventTargetMutex); diff --git a/netwerk/protocol/http/HttpChannelChild.h b/netwerk/protocol/http/HttpChannelChild.h index 38895a0555..8cfc820a23 100644 --- a/netwerk/protocol/http/HttpChannelChild.h +++ b/netwerk/protocol/http/HttpChannelChild.h @@ -33,7 +33,7 @@ #include "nsIThreadRetargetableRequest.h" #include "mozilla/net/DNS.h" -using mozilla::Telemetry::LABELS_HTTP_CHILD_OMT_STATS; +using mozilla::Telemetry::LABELS_HTTP_CHILD_OMT_STATS_2; class nsIEventTarget; class nsIInterceptedBodyCallback; @@ -271,6 +271,9 @@ class HttpChannelChild final : public PHttpChannelChild, nsresult MaybeLogCOEPError(nsresult aStatus); + void RetargetDeliveryToImpl(nsISerialEventTarget* aNewTarget, + MutexAutoLock& aLockRef); + private: // this section is for main-thread-only object // all the references need to be proxy released on main thread. @@ -312,8 +315,8 @@ class HttpChannelChild final : public PHttpChannelChild, // The result of RetargetDeliveryTo for this channel. // |notRequested| represents OMT is not requested by the channel owner. - Atomic<LABELS_HTTP_CHILD_OMT_STATS, mozilla::Relaxed> mOMTResult{ - LABELS_HTTP_CHILD_OMT_STATS::notRequested}; + Atomic<LABELS_HTTP_CHILD_OMT_STATS_2, mozilla::Relaxed> mOMTResult{ + LABELS_HTTP_CHILD_OMT_STATS_2::notRequested}; uint32_t mCacheKey{0}; int32_t mCacheFetchCount{0}; diff --git a/netwerk/protocol/http/HttpChannelParent.cpp b/netwerk/protocol/http/HttpChannelParent.cpp index e734d15a7d..b8634512ce 100644 --- a/netwerk/protocol/http/HttpChannelParent.cpp +++ b/netwerk/protocol/http/HttpChannelParent.cpp @@ -587,7 +587,7 @@ bool HttpChannelParent::DoAsyncOpen( if (aCorsPreflightArgs.isSome()) { const CorsPreflightArgs& args = aCorsPreflightArgs.ref(); - httpChannel->SetCorsPreflightParameters(args.unsafeHeaders(), false); + httpChannel->SetCorsPreflightParameters(args.unsafeHeaders(), false, false); } nsCOMPtr<nsIInputStream> stream = DeserializeIPCStream(uploadStream); @@ -896,7 +896,7 @@ mozilla::ipc::IPCResult HttpChannelParent::RecvRedirect2Verify( MOZ_RELEASE_ASSERT(newInternalChannel); const CorsPreflightArgs& args = aCorsPreflightArgs.ref(); newInternalChannel->SetCorsPreflightParameters(args.unsafeHeaders(), - false); + false, false); } if (aReferrerInfo) { @@ -1180,7 +1180,7 @@ HttpChannelParent::OnStartRequest(nsIRequest* aRequest) { PContentParent* pcp = Manager()->Manager(); MOZ_ASSERT(pcp, "We should have a manager if our IPC isn't closed"); DebugOnly<nsresult> rv = - static_cast<ContentParent*>(pcp)->AboutToLoadHttpFtpDocumentForChild( + static_cast<ContentParent*>(pcp)->AboutToLoadHttpDocumentForChild( chan, &args.shouldWaitForOnStartRequestSent()); MOZ_ASSERT(NS_SUCCEEDED(rv)); } diff --git a/netwerk/protocol/http/ObliviousHttpChannel.cpp b/netwerk/protocol/http/ObliviousHttpChannel.cpp index fafbf84b0b..1b4449f004 100644 --- a/netwerk/protocol/http/ObliviousHttpChannel.cpp +++ b/netwerk/protocol/http/ObliviousHttpChannel.cpp @@ -419,10 +419,10 @@ void ObliviousHttpChannel::SetAltDataForChild(bool aIsForChild) { void ObliviousHttpChannel::SetCorsPreflightParameters( nsTArray<nsTString<char>> const& aUnsafeHeaders, - bool aShouldStripRequestBodyHeader) { + bool aShouldStripRequestBodyHeader, bool aShouldStripAuthHeader) { if (mInnerChannelInternal) { mInnerChannelInternal->SetCorsPreflightParameters( - aUnsafeHeaders, aShouldStripRequestBodyHeader); + aUnsafeHeaders, aShouldStripRequestBodyHeader, aShouldStripAuthHeader); } } diff --git a/netwerk/protocol/http/nsCORSListenerProxy.cpp b/netwerk/protocol/http/nsCORSListenerProxy.cpp index 90ac6a4ddc..2846b852ca 100644 --- a/netwerk/protocol/http/nsCORSListenerProxy.cpp +++ b/netwerk/protocol/http/nsCORSListenerProxy.cpp @@ -441,7 +441,8 @@ nsresult nsCORSListenerProxy::Init(nsIChannel* aChannel, getter_AddRefs(mOuterNotificationCallbacks)); aChannel->SetNotificationCallbacks(this); - nsresult rv = UpdateChannel(aChannel, aAllowDataURI, UpdateType::Default); + nsresult rv = + UpdateChannel(aChannel, aAllowDataURI, UpdateType::Default, false); if (NS_FAILED(rv)) { { MutexAutoLock lock(mMutex); @@ -765,7 +766,7 @@ nsCORSListenerProxy::AsyncOnChannelRedirect( // data URIs should have been blocked before we got to the internal // redirect. rv = UpdateChannel(aNewChannel, DataURIHandling::Allow, - UpdateType::InternalOrHSTSRedirect); + UpdateType::InternalOrHSTSRedirect, false); if (NS_FAILED(rv)) { NS_WARNING( "nsCORSListenerProxy::AsyncOnChannelRedirect: " @@ -835,6 +836,13 @@ nsCORSListenerProxy::AsyncOnChannelRedirect( } bool rewriteToGET = false; + // We need to strip auth header from preflight request for + // cross-origin redirects. + // See Bug 1874132 + bool stripAuthHeader = + StaticPrefs::network_fetch_redirect_stripAuthHeader() && + NS_ShouldRemoveAuthHeaderOnRedirect(aOldChannel, aNewChannel, aFlags); + nsCOMPtr<nsIHttpChannel> oldHttpChannel = do_QueryInterface(aOldChannel); if (oldHttpChannel) { nsAutoCString method; @@ -843,9 +851,10 @@ nsCORSListenerProxy::AsyncOnChannelRedirect( &rewriteToGET); } - rv = UpdateChannel(aNewChannel, DataURIHandling::Disallow, - rewriteToGET ? UpdateType::StripRequestBodyHeader - : UpdateType::Default); + rv = UpdateChannel( + aNewChannel, DataURIHandling::Disallow, + rewriteToGET ? UpdateType::StripRequestBodyHeader : UpdateType::Default, + stripAuthHeader); if (NS_FAILED(rv)) { NS_WARNING( "nsCORSListenerProxy::AsyncOnChannelRedirect: " @@ -930,7 +939,10 @@ bool CheckInsecureUpgradePreventsCORS(nsIPrincipal* aRequestingPrincipal, nsresult nsCORSListenerProxy::UpdateChannel(nsIChannel* aChannel, DataURIHandling aAllowDataURI, - UpdateType aUpdateType) { + UpdateType aUpdateType, + bool aStripAuthHeader) { + MOZ_ASSERT_IF(aUpdateType == UpdateType::InternalOrHSTSRedirect, + !aStripAuthHeader); nsCOMPtr<nsIURI> uri, originalURI; nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); NS_ENSURE_SUCCESS(rv, rv); @@ -1020,7 +1032,7 @@ nsresult nsCORSListenerProxy::UpdateChannel(nsIChannel* aChannel, // Check if we need to do a preflight, and if so set one up. This must be // called once we know that the request is going, or has gone, cross-origin. - rv = CheckPreflightNeeded(aChannel, aUpdateType); + rv = CheckPreflightNeeded(aChannel, aUpdateType, aStripAuthHeader); NS_ENSURE_SUCCESS(rv, rv); // It's a cross site load @@ -1087,7 +1099,8 @@ nsresult nsCORSListenerProxy::UpdateChannel(nsIChannel* aChannel, } nsresult nsCORSListenerProxy::CheckPreflightNeeded(nsIChannel* aChannel, - UpdateType aUpdateType) { + UpdateType aUpdateType, + bool aStripAuthHeader) { // If this caller isn't using AsyncOpen, or if this *is* a preflight channel, // then we shouldn't initiate preflight for this channel. nsCOMPtr<nsILoadInfo> loadInfo = aChannel->LoadInfo(); @@ -1154,7 +1167,7 @@ nsresult nsCORSListenerProxy::CheckPreflightNeeded(nsIChannel* aChannel, internal->SetCorsPreflightParameters( headers.IsEmpty() ? loadInfoHeaders : headers, - aUpdateType == UpdateType::StripRequestBodyHeader); + aUpdateType == UpdateType::StripRequestBodyHeader, aStripAuthHeader); return NS_OK; } diff --git a/netwerk/protocol/http/nsCORSListenerProxy.h b/netwerk/protocol/http/nsCORSListenerProxy.h index e96b0a8aca..cdc3272fe0 100644 --- a/netwerk/protocol/http/nsCORSListenerProxy.h +++ b/netwerk/protocol/http/nsCORSListenerProxy.h @@ -92,10 +92,12 @@ class nsCORSListenerProxy final : public nsIInterfaceRequestor, [[nodiscard]] nsresult UpdateChannel(nsIChannel* aChannel, DataURIHandling aAllowDataURI, - UpdateType aUpdateType); + UpdateType aUpdateType, + bool aStripAuthHeader); [[nodiscard]] nsresult CheckRequestApproved(nsIRequest* aRequest); [[nodiscard]] nsresult CheckPreflightNeeded(nsIChannel* aChannel, - UpdateType aUpdateType); + UpdateType aUpdateType, + bool aStripAuthHeader); nsCOMPtr<nsIStreamListener> mOuterListener; // The principal that originally kicked off the request diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index 96e61e4fb8..4428b72426 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -15,11 +15,13 @@ #include "mozilla/glean/GleanMetrics.h" #include "mozilla/StoragePrincipalHelper.h" +#include "nsCOMPtr.h" #include "nsContentSecurityUtils.h" #include "nsHttp.h" #include "nsHttpChannel.h" #include "nsHttpChannelAuthProvider.h" #include "nsHttpHandler.h" +#include "nsIStreamConverter.h" #include "nsString.h" #include "nsICacheStorageService.h" #include "nsICacheStorage.h" @@ -483,6 +485,25 @@ void nsHttpChannel::HandleContinueCancellingByURLClassifier( ContinueCancellingByURLClassifier(aErrorCode); } +void nsHttpChannel::SetPriorityHeader() { + uint8_t urgency = nsHttpHandler::UrgencyFromCoSFlags(mClassOfService.Flags()); + bool incremental = mClassOfService.Incremental(); + + nsPrintfCString value( + "%s", urgency != 3 ? nsPrintfCString("u=%d", urgency).get() : ""); + + if (incremental) { + if (!value.IsEmpty()) { + value.Append(", "); + } + value.Append("i"); + } + + if (!value.IsEmpty()) { + SetRequestHeader("Priority"_ns, value, false); + } +} + nsresult nsHttpChannel::OnBeforeConnect() { nsresult rv = NS_OK; @@ -1202,6 +1223,10 @@ nsresult nsHttpChannel::SetupTransaction() { mozilla::MutexAutoLock lock(mRCWNLock); + if (StaticPrefs::network_http_priority_header_enabled()) { + SetPriorityHeader(); + } + // If we're racing cache with network, conditional or byte range header // could be added in OnCacheEntryCheck. We cannot send conditional request // without having the entry, so we need to remove the headers here and @@ -1810,6 +1835,7 @@ nsresult nsHttpChannel::CallOnStartRequest() { "converter in this case."); mListener = listener; mCompressListener = listener; + StoreHasAppliedConversion(true); } } @@ -7664,6 +7690,7 @@ static nsLiteralCString ContentTypeToTelemetryLabel(nsHttpChannel* aChannel) { return "proxy"_ns; } if (contentType.EqualsLiteral(APPLICATION_BROTLI) || + contentType.EqualsLiteral(APPLICATION_ZSTD) || contentType.Find("zip") != kNotFound || contentType.Find("compress") != kNotFound) { return "compressed"_ns; diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index dede167f87..e2fb5abde9 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -566,6 +566,8 @@ class nsHttpChannel final : public HttpBaseChannel, // This method can only be called on the main thread. void PerformBackgroundCacheRevalidationNow(); + void SetPriorityHeader(); + private: nsCOMPtr<nsICancelable> mProxyRequest; diff --git a/netwerk/protocol/http/nsHttpConnectionMgr.cpp b/netwerk/protocol/http/nsHttpConnectionMgr.cpp index c7c385a42a..dbbd8fe0ca 100644 --- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp +++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp @@ -817,10 +817,35 @@ HttpConnectionBase* nsHttpConnectionMgr::FindCoalescableConnection( for (uint32_t i = 0; i < keyLen; ++i) { conn = FindCoalescableConnectionByHashKey(ent, ent->mCoalescingKeys[i], justKidding, aNoHttp2, aNoHttp3); + + auto usableEntry = [&](HttpConnectionBase* conn) { + // This is allowed by the spec, but other browsers don't coalesce + // so agressively, which surprises developers. See bug 1420777. + if (StaticPrefs::network_http_http2_aggressive_coalescing()) { + return true; + } + + // Make sure that the connection's IP address is one that is in + // the set of IP addresses in the entry's DNS response. + NetAddr addr; + nsresult rv = conn->GetPeerAddr(&addr); + if (NS_FAILED(rv)) { + // Err on the side of not coalescing + return false; + } + // We don't care about remote port when matching entries. + addr.inet.port = 0; + return ent->mAddresses.Contains(addr); + }; + if (conn) { - LOG(("FindCoalescableConnection(%s) match conn %p on dns key %s\n", - ci->HashKey().get(), conn, ent->mCoalescingKeys[i].get())); - return conn; + LOG(("Found connection with matching hash")); + if (usableEntry(conn)) { + LOG(("> coalescing")); + return conn; + } else { + LOG(("> not coalescing as remote address not present in DNS records")); + } } } diff --git a/netwerk/protocol/http/nsHttpDigestAuth.cpp b/netwerk/protocol/http/nsHttpDigestAuth.cpp index 2a98301942..809cf7993b 100644 --- a/netwerk/protocol/http/nsHttpDigestAuth.cpp +++ b/netwerk/protocol/http/nsHttpDigestAuth.cpp @@ -9,6 +9,7 @@ #include "mozilla/ClearOnShutdown.h" #include "mozilla/Sprintf.h" +#include "mozilla/StaticPrefs_network.h" #include "mozilla/Unused.h" #include "nsHttp.h" @@ -22,6 +23,7 @@ #include "nsCRT.h" #include "nsICryptoHash.h" #include "nsComponentManagerUtils.h" +#include "pk11pub.h" constexpr uint16_t DigestLength(uint16_t aAlgorithm) { if (aAlgorithm & (ALGO_SHA256 | ALGO_SHA256_SESS)) { @@ -321,9 +323,13 @@ nsHttpDigestAuth::GenerateCredentials( // returned Authentication-Info header). also used for session info. // nsAutoCString cnonce; - static const char hexChar[] = "0123456789abcdef"; - for (int i = 0; i < 16; ++i) { - cnonce.Append(hexChar[(int)(15.0 * rand() / (RAND_MAX + 1.0))]); + nsTArray<uint8_t> cnonceBuf; + cnonceBuf.SetLength(StaticPrefs::network_http_digest_auth_cnonce_length() / + 2); + PK11_GenerateRandom(reinterpret_cast<unsigned char*>(cnonceBuf.Elements()), + cnonceBuf.Length()); + for (auto byte : cnonceBuf) { + cnonce.AppendPrintf("%02x", byte); } LOG((" cnonce=%s\n", cnonce.get())); diff --git a/netwerk/protocol/http/nsHttpHandler.cpp b/netwerk/protocol/http/nsHttpHandler.cpp index 4861b45466..b6440c88b5 100644 --- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -714,6 +714,34 @@ nsresult nsHttpHandler::GenerateHostPort(const nsCString& host, int32_t port, return NS_GenerateHostPort(host, port, hostLine); } +// static +uint8_t nsHttpHandler::UrgencyFromCoSFlags(uint32_t cos) { + uint8_t urgency; + if (cos & nsIClassOfService::UrgentStart) { + // coming from an user interaction => response should be the highest + // priority + urgency = 1; + } else if (cos & nsIClassOfService::Leader) { + // main html document normal priority + urgency = 2; + } else if (cos & nsIClassOfService::Unblocked) { + urgency = 3; + } else if (cos & nsIClassOfService::Follower) { + urgency = 4; + } else if (cos & nsIClassOfService::Speculative) { + urgency = 6; + } else if (cos & nsIClassOfService::Background) { + // background tasks can be deprioritzed to the lowest priority + urgency = 6; + } else if (cos & nsIClassOfService::Tail) { + urgency = 6; + } else { + // all others get a lower priority than the main html document + urgency = 4; + } + return urgency; +} + //----------------------------------------------------------------------------- // nsHttpHandler <private> //----------------------------------------------------------------------------- diff --git a/netwerk/protocol/http/nsHttpHandler.h b/netwerk/protocol/http/nsHttpHandler.h index 2562d0c833..65ce5d6d12 100644 --- a/netwerk/protocol/http/nsHttpHandler.h +++ b/netwerk/protocol/http/nsHttpHandler.h @@ -429,6 +429,8 @@ class nsHttpHandler final : public nsIHttpProtocolHandler, int32_t port, nsACString& hostLine); + static uint8_t UrgencyFromCoSFlags(uint32_t cos); + SpdyInformation* SpdyInfo() { return &mSpdyInfo; } bool IsH2MandatorySuiteEnabled() { return mH2MandatorySuiteEnabled; } diff --git a/netwerk/protocol/http/nsHttpTransaction.cpp b/netwerk/protocol/http/nsHttpTransaction.cpp index 558de8e6ea..24ef50fb85 100644 --- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -1684,16 +1684,16 @@ void nsHttpTransaction::Close(nsresult reason) { switch (mHttpVersion) { case HttpVersion::v1_0: case HttpVersion::v1_1: - glean::networking::http_1_download_throughput.AccumulateSamples( - {mpbs}); + glean::networking::http_1_download_throughput.AccumulateSingleSample( + mpbs); break; case HttpVersion::v2_0: - glean::networking::http_2_download_throughput.AccumulateSamples( - {mpbs}); + glean::networking::http_2_download_throughput.AccumulateSingleSample( + mpbs); break; case HttpVersion::v3_0: - glean::networking::http_3_download_throughput.AccumulateSamples( - {mpbs}); + glean::networking::http_3_download_throughput.AccumulateSingleSample( + mpbs); break; default: break; @@ -3574,42 +3574,42 @@ void nsHttpTransaction::CollectTelemetryForUploads() { switch (mHttpVersion) { case HttpVersion::v1_0: case HttpVersion::v1_1: - glean::networking::http_1_upload_throughput.AccumulateSamples({mpbs}); + glean::networking::http_1_upload_throughput.AccumulateSingleSample(mpbs); if (mRequestSize <= TELEMETRY_REQUEST_SIZE_50M) { - glean::networking::http_1_upload_throughput_10_50.AccumulateSamples( - {mpbs}); + glean::networking::http_1_upload_throughput_10_50 + .AccumulateSingleSample(mpbs); } else if (mRequestSize <= TELEMETRY_REQUEST_SIZE_100M) { - glean::networking::http_1_upload_throughput_50_100.AccumulateSamples( - {mpbs}); + glean::networking::http_1_upload_throughput_50_100 + .AccumulateSingleSample(mpbs); } else { - glean::networking::http_1_upload_throughput_100.AccumulateSamples( - {mpbs}); + glean::networking::http_1_upload_throughput_100.AccumulateSingleSample( + mpbs); } break; case HttpVersion::v2_0: - glean::networking::http_2_upload_throughput.AccumulateSamples({mpbs}); + glean::networking::http_2_upload_throughput.AccumulateSingleSample(mpbs); if (mRequestSize <= TELEMETRY_REQUEST_SIZE_50M) { - glean::networking::http_2_upload_throughput_10_50.AccumulateSamples( - {mpbs}); + glean::networking::http_2_upload_throughput_10_50 + .AccumulateSingleSample(mpbs); } else if (mRequestSize <= TELEMETRY_REQUEST_SIZE_100M) { - glean::networking::http_2_upload_throughput_50_100.AccumulateSamples( - {mpbs}); + glean::networking::http_2_upload_throughput_50_100 + .AccumulateSingleSample(mpbs); } else { - glean::networking::http_2_upload_throughput_100.AccumulateSamples( - {mpbs}); + glean::networking::http_2_upload_throughput_100.AccumulateSingleSample( + mpbs); } break; case HttpVersion::v3_0: - glean::networking::http_3_upload_throughput.AccumulateSamples({mpbs}); + glean::networking::http_3_upload_throughput.AccumulateSingleSample(mpbs); if (mRequestSize <= TELEMETRY_REQUEST_SIZE_50M) { - glean::networking::http_3_upload_throughput_10_50.AccumulateSamples( - {mpbs}); + glean::networking::http_3_upload_throughput_10_50 + .AccumulateSingleSample(mpbs); } else if (mRequestSize <= TELEMETRY_REQUEST_SIZE_100M) { - glean::networking::http_3_upload_throughput_50_100.AccumulateSamples( - {mpbs}); + glean::networking::http_3_upload_throughput_50_100 + .AccumulateSingleSample(mpbs); } else { - glean::networking::http_3_upload_throughput_100.AccumulateSamples( - {mpbs}); + glean::networking::http_3_upload_throughput_100.AccumulateSingleSample( + mpbs); } break; default: diff --git a/netwerk/protocol/http/nsIHttpActivityObserver.idl b/netwerk/protocol/http/nsIHttpActivityObserver.idl index 533e6af135..1a2cea84ba 100644 --- a/netwerk/protocol/http/nsIHttpActivityObserver.idl +++ b/netwerk/protocol/http/nsIHttpActivityObserver.idl @@ -196,9 +196,9 @@ interface nsIHttpActivityDistributor : nsIHttpActivityObserver /** * C++ friendly getter */ - [noscript, notxpcom] bool Activated(); - [noscript, notxpcom] bool ObserveProxyResponseEnabled(); - [noscript, notxpcom] bool ObserveConnectionEnabled(); + [noscript, notxpcom] boolean Activated(); + [noscript, notxpcom] boolean ObserveProxyResponseEnabled(); + [noscript, notxpcom] boolean ObserveConnectionEnabled(); /** * When true, the ACTIVITY_SUBTYPE_PROXY_RESPONSE_HEADER will be sent to diff --git a/netwerk/protocol/http/nsIHttpAuthManager.idl b/netwerk/protocol/http/nsIHttpAuthManager.idl index 5acd652942..cf39a03e34 100644 --- a/netwerk/protocol/http/nsIHttpAuthManager.idl +++ b/netwerk/protocol/http/nsIHttpAuthManager.idl @@ -63,7 +63,7 @@ interface nsIHttpAuthManager : nsISupports out AString aUserDomain, out AString aUserName, out AString aUserPassword, - [optional] in bool aIsPrivate, + [optional] in boolean aIsPrivate, [optional] in nsIPrincipal aPrincipal); /** diff --git a/netwerk/protocol/http/nsIHttpChannel.idl b/netwerk/protocol/http/nsIHttpChannel.idl index 7ed707eacf..1bd7aeba37 100644 --- a/netwerk/protocol/http/nsIHttpChannel.idl +++ b/netwerk/protocol/http/nsIHttpChannel.idl @@ -204,7 +204,7 @@ interface nsIHttpChannel : nsIIdentChannel * Call this method to see if we need to strip the request body headers * for the new http channel. This should be called during redirection. */ - [must_use] bool ShouldStripRequestBodyHeader(in ACString aMethod); + [must_use] boolean ShouldStripRequestBodyHeader(in ACString aMethod); /** * This attribute of the channel indicates whether or not diff --git a/netwerk/protocol/http/nsIHttpChannelInternal.idl b/netwerk/protocol/http/nsIHttpChannelInternal.idl index 1650b8f35c..64f41be28b 100644 --- a/netwerk/protocol/http/nsIHttpChannelInternal.idl +++ b/netwerk/protocol/http/nsIHttpChannelInternal.idl @@ -105,7 +105,7 @@ interface nsIHttpChannelInternal : nsISupports * Returns true in case this channel is used for auth; * (the response header includes 'www-authenticate'). */ - [noscript, must_use] readonly attribute bool isAuthChannel; + [noscript, must_use] readonly attribute boolean isAuthChannel; /** * This flag is set to force relevant cookies to be sent with this load @@ -381,7 +381,8 @@ interface nsIHttpChannelInternal : nsISupports */ [noscript, notxpcom, nostdcall] void setCorsPreflightParameters(in CStringArrayRef unsafeHeaders, - in boolean shouldStripRequestBodyHeader); + in boolean shouldStripRequestBodyHeader, + in boolean shouldStripAuthHeader); [noscript, notxpcom, nostdcall] void setAltDataForChild(in boolean aIsForChild); @@ -457,7 +458,7 @@ interface nsIHttpChannelInternal : nsISupports in nsILoadInfo_CrossOriginOpenerPolicy aInitiatorPolicy); [noscript] - bool hasCrossOriginOpenerPolicyMismatch(); + boolean hasCrossOriginOpenerPolicyMismatch(); [noscript] nsILoadInfo_CrossOriginEmbedderPolicy getResponseEmbedderPolicy(in boolean aIsOriginTrialCoepCredentiallessEnabled); diff --git a/netwerk/protocol/http/nsIWellKnownOpportunisticUtils.idl b/netwerk/protocol/http/nsIWellKnownOpportunisticUtils.idl index fa90891172..366b17fdd4 100644 --- a/netwerk/protocol/http/nsIWellKnownOpportunisticUtils.idl +++ b/netwerk/protocol/http/nsIWellKnownOpportunisticUtils.idl @@ -19,5 +19,5 @@ interface nsIWellKnownOpportunisticUtils : nsISupports [must_use] void verify(in ACString aJSON, in ACString aOrigin); - [must_use] readonly attribute bool valid; + [must_use] readonly attribute boolean valid; }; diff --git a/netwerk/protocol/res/PageThumbProtocolHandler.cpp b/netwerk/protocol/res/PageThumbProtocolHandler.cpp index 2d9777da7b..ece55aa54c 100644 --- a/netwerk/protocol/res/PageThumbProtocolHandler.cpp +++ b/netwerk/protocol/res/PageThumbProtocolHandler.cpp @@ -304,9 +304,9 @@ nsresult PageThumbProtocolHandler::GetThumbnailPath(const nsACString& aPath, } // Extract URL from query string. - nsAutoString url; + nsAutoCString url; bool found = - URLParams::Extract(Substring(aPath, queryIndex + 1), u"url"_ns, url); + URLParams::Extract(Substring(aPath, queryIndex + 1), "url"_ns, url); if (!found || url.IsVoid()) { return NS_ERROR_NOT_AVAILABLE; } @@ -320,7 +320,8 @@ nsresult PageThumbProtocolHandler::GetThumbnailPath(const nsACString& aPath, } // Use PageThumbsStorageService to get the local file path of the screenshot // for the given URL. - rv = pageThumbsStorage->GetFilePathForURL(url, aThumbnailPath); + rv = pageThumbsStorage->GetFilePathForURL(NS_ConvertUTF8toUTF16(url), + aThumbnailPath); #ifdef MOZ_PLACES } else if (aHost.EqualsLiteral(PLACES_PREVIEWS_HOST)) { nsCOMPtr<nsIPlacesPreviewsHelperService> helper = @@ -328,7 +329,7 @@ nsresult PageThumbProtocolHandler::GetThumbnailPath(const nsACString& aPath, if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } - rv = helper->GetFilePathForURL(url, aThumbnailPath); + rv = helper->GetFilePathForURL(NS_ConvertUTF8toUTF16(url), aThumbnailPath); #endif } else { MOZ_ASSERT_UNREACHABLE("Unknown thumbnail host"); diff --git a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp index f2428a5744..3b5f95d5f3 100644 --- a/netwerk/protocol/viewsource/nsViewSourceChannel.cpp +++ b/netwerk/protocol/viewsource/nsViewSourceChannel.cpp @@ -1048,9 +1048,9 @@ NS_IMETHODIMP nsViewSourceChannel::GetDocumentCharacterSet( // Have to manually forward SetCorsPreflightParameters since it's [notxpcom] void nsViewSourceChannel::SetCorsPreflightParameters( const nsTArray<nsCString>& aUnsafeHeaders, - bool aShouldStripRequestBodyHeader) { + bool aShouldStripRequestBodyHeader, bool aShouldStripAuthHeader) { mHttpChannelInternal->SetCorsPreflightParameters( - aUnsafeHeaders, aShouldStripRequestBodyHeader); + aUnsafeHeaders, aShouldStripRequestBodyHeader, aShouldStripAuthHeader); } void nsViewSourceChannel::SetAltDataForChild(bool aIsForChild) { diff --git a/netwerk/protocol/websocket/nsIWebSocketEventService.idl b/netwerk/protocol/websocket/nsIWebSocketEventService.idl index 9763850609..b97e06a72b 100644 --- a/netwerk/protocol/websocket/nsIWebSocketEventService.idl +++ b/netwerk/protocol/websocket/nsIWebSocketEventService.idl @@ -83,5 +83,5 @@ interface nsIWebSocketEventService : nsISupports [must_use] void removeListener(in unsigned long long aInnerWindowID, in nsIWebSocketEventListener aListener); - [must_use] bool hasListenerFor(in unsigned long long aInnerWindowID); + [must_use] boolean hasListenerFor(in unsigned long long aInnerWindowID); }; diff --git a/netwerk/protocol/webtransport/nsIWebTransport.idl b/netwerk/protocol/webtransport/nsIWebTransport.idl index 2283c42977..5ed4e96517 100644 --- a/netwerk/protocol/webtransport/nsIWebTransport.idl +++ b/netwerk/protocol/webtransport/nsIWebTransport.idl @@ -82,7 +82,7 @@ interface WebTransportSessionEventListener : nsISupports { // This is used internally to pass the reference of WebTransportSession // object to WebTransportSessionProxy. void onSessionReadyInternal(in Http3WebTransportSessionPtr aSession); - void onSessionClosed(in bool aCleanly, + void onSessionClosed(in boolean aCleanly, in uint32_t aErrorCode, in ACString aReason); @@ -121,7 +121,7 @@ interface WebTransportSessionEventListener : nsISupports { [uuid(faad75bd-83c6-420b-9fdb-a70bd70be449)] interface WebTransportConnectionSettings : nsISupports { // WebTransport specific connection information - readonly attribute bool dedicated; + readonly attribute boolean dedicated; void getServerCertificateHashes(out Array<nsIWebTransportHash> aServerCertHashes); }; diff --git a/netwerk/sctp/src/moz.yaml b/netwerk/sctp/src/moz.yaml index 14b840547d..9ed76d5d96 100644 --- a/netwerk/sctp/src/moz.yaml +++ b/netwerk/sctp/src/moz.yaml @@ -10,8 +10,8 @@ origin: url: https://github.com/sctplab/usrsctp/blob/master/Manual.md - release: a0cbf4681474fab1e89d9e9e2d5c3694fce50359 (2023-09-13T13:37:16Z). - revision: a0cbf4681474fab1e89d9e9e2d5c3694fce50359 + release: 2952e9324299c5729ba9f03a87924f787868e494 (2023-11-05T13:52:04Z). + revision: 2952e9324299c5729ba9f03a87924f787868e494 license: BSD-3-Clause diff --git a/netwerk/sctp/src/netinet/sctp_output.c b/netwerk/sctp/src/netinet/sctp_output.c index 61fa3a5fe8..85b7886404 100644 --- a/netwerk/sctp/src/netinet/sctp_output.c +++ b/netwerk/sctp/src/netinet/sctp_output.c @@ -5023,7 +5023,9 @@ sctp_lowlevel_chunk_output(struct sctp_inpcb *inp, sctphdr->dest_port = dest_port; sctphdr->v_tag = v_tag; sctphdr->checksum = 0; - if (SCTP_BASE_VAR(crc32c_offloaded) == 0) { + if (use_zero_crc) { + SCTP_STAT_INCR(sctps_sendzerocrc); + } else if (SCTP_BASE_VAR(crc32c_offloaded) == 0) { sctphdr->checksum = sctp_calculate_cksum(m, 0); SCTP_STAT_INCR(sctps_sendswcrc); } else { diff --git a/netwerk/sctp/src/user_environment.c b/netwerk/sctp/src/user_environment.c index 3deb3ef0d4..ea52f0ada7 100644 --- a/netwerk/sctp/src/user_environment.c +++ b/netwerk/sctp/src/user_environment.c @@ -367,7 +367,7 @@ read_random(void *buf, size_t size) position = 0; while (position < size) { - if (nacl_secure_random((char *)buf + position, size - position, &n) == 0) + if (nacl_secure_random((char *)buf + position, size - position, &n) == 0) { position += n; } } diff --git a/netwerk/sctp/src/user_socket.c b/netwerk/sctp/src/user_socket.c index 6658390420..cde6ecc417 100644 --- a/netwerk/sctp/src/user_socket.c +++ b/netwerk/sctp/src/user_socket.c @@ -3479,6 +3479,7 @@ USRSCTP_SYSCTL_SET_DEF(sctp_steady_step, SCTPCTL_RTTVAR_STEADYS) USRSCTP_SYSCTL_SET_DEF(sctp_use_dccc_ecn, SCTPCTL_RTTVAR_DCCCECN) USRSCTP_SYSCTL_SET_DEF(sctp_buffer_splitting, SCTPCTL_BUFFER_SPLITTING) USRSCTP_SYSCTL_SET_DEF(sctp_initial_cwnd, SCTPCTL_INITIAL_CWND) +USRSCTP_SYSCTL_SET_DEF(sctp_ootb_with_zero_cksum, SCTPCTL_OOTB_WITH_ZERO_CKSUM) #ifdef SCTP_DEBUG USRSCTP_SYSCTL_SET_DEF(sctp_debug_on, SCTPCTL_DEBUG) #endif @@ -3561,6 +3562,7 @@ USRSCTP_SYSCTL_GET_DEF(sctp_steady_step) USRSCTP_SYSCTL_GET_DEF(sctp_use_dccc_ecn) USRSCTP_SYSCTL_GET_DEF(sctp_buffer_splitting) USRSCTP_SYSCTL_GET_DEF(sctp_initial_cwnd) +USRSCTP_SYSCTL_GET_DEF(sctp_ootb_with_zero_cksum) #ifdef SCTP_DEBUG USRSCTP_SYSCTL_GET_DEF(sctp_debug_on) #endif diff --git a/netwerk/socket/neqo_glue/Cargo.toml b/netwerk/socket/neqo_glue/Cargo.toml index 2d7f0d9a5f..8355c54c19 100644 --- a/netwerk/socket/neqo_glue/Cargo.toml +++ b/netwerk/socket/neqo_glue/Cargo.toml @@ -9,10 +9,10 @@ license = "MPL-2.0" name = "neqo_glue" [dependencies] -neqo-http3 = { tag = "v0.7.2", git = "https://github.com/mozilla/neqo" } -neqo-transport = { tag = "v0.7.2", git = "https://github.com/mozilla/neqo" } -neqo-common = { tag = "v0.7.2", git = "https://github.com/mozilla/neqo" } -neqo-qpack = { tag = "v0.7.2", git = "https://github.com/mozilla/neqo" } +neqo-http3 = { tag = "v0.7.5", git = "https://github.com/mozilla/neqo" } +neqo-transport = { tag = "v0.7.5", git = "https://github.com/mozilla/neqo" } +neqo-common = { tag = "v0.7.5", git = "https://github.com/mozilla/neqo" } +neqo-qpack = { tag = "v0.7.5", git = "https://github.com/mozilla/neqo" } nserror = { path = "../../../xpcom/rust/nserror" } nsstring = { path = "../../../xpcom/rust/nsstring" } xpcom = { path = "../../../xpcom/rust/xpcom" } @@ -27,10 +27,10 @@ uuid = { version = "1.0", features = ["v4"] } winapi = {version = "0.3", features = ["ws2def"] } [dependencies.neqo-crypto] -tag = "v0.7.2" +tag = "v0.7.5" git = "https://github.com/mozilla/neqo" default-features = false features = ["gecko"] [features] -fuzzing = ["neqo-http3/fuzzing"] +fuzzing = ["neqo-http3/disable-encryption"] diff --git a/netwerk/socket/neqo_glue/src/lib.rs b/netwerk/socket/neqo_glue/src/lib.rs index 6c86211ed5..fd527a7fb9 100644 --- a/netwerk/socket/neqo_glue/src/lib.rs +++ b/netwerk/socket/neqo_glue/src/lib.rs @@ -121,7 +121,7 @@ impl NeqoHttp3Conn { max_accumlated_time_ms: u32, ) -> Result<RefPtr<NeqoHttp3Conn>, nsresult> { // Nss init. - init(); + init().map_err(|_| NS_ERROR_UNEXPECTED)?; let origin_conv = str::from_utf8(origin).map_err(|_| NS_ERROR_INVALID_ARG)?; diff --git a/netwerk/streamconv/converters/moz.build b/netwerk/streamconv/converters/moz.build index d985eb363a..2629a7e59a 100644 --- a/netwerk/streamconv/converters/moz.build +++ b/netwerk/streamconv/converters/moz.build @@ -29,3 +29,7 @@ LOCAL_INCLUDES += [ "/modules/brotli/dec", "/netwerk/base", ] + +DIRS += [ + "/third_party/zstd", +] diff --git a/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp b/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp index a9f1d5183f..de99273862 100644 --- a/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp +++ b/netwerk/streamconv/converters/mozTXTToHTMLConv.cpp @@ -1263,6 +1263,11 @@ NS_IMETHODIMP mozTXTToHTMLConv::CheckListenerChain() { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHODIMP +mozTXTToHTMLConv::MaybeRetarget(nsIRequest* request) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP mozTXTToHTMLConv::OnStartRequest(nsIRequest* request) { return NS_ERROR_NOT_IMPLEMENTED; } diff --git a/netwerk/streamconv/converters/nsHTTPCompressConv.cpp b/netwerk/streamconv/converters/nsHTTPCompressConv.cpp index e06c72222b..7c7404f110 100644 --- a/netwerk/streamconv/converters/nsHTTPCompressConv.cpp +++ b/netwerk/streamconv/converters/nsHTTPCompressConv.cpp @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsHTTPCompressConv.h" +#include "ErrorList.h" #include "nsCOMPtr.h" #include "nsCRT.h" #include "nsError.h" @@ -19,6 +20,8 @@ #include "nsIForcePendingChannel.h" #include "nsIRequest.h" #include "mozilla/UniquePtrExtensions.h" +#include "nsIThreadRetargetableRequest.h" +#include "nsIChannel.h" // brotli headers #undef assert @@ -26,6 +29,8 @@ #include "state.h" #include "brotli/decode.h" +#include "zstd/zstd.h" + namespace mozilla { namespace net { @@ -50,6 +55,26 @@ class BrotliWrapper { uint64_t mSourceOffset{0}; }; +class ZstdWrapper { + public: + ZstdWrapper() { + mDStream = ZSTD_createDStream(); + ZSTD_DCtx_setParameter(mDStream, ZSTD_d_windowLogMax, 23 /*8*1024*1024*/); + } + ~ZstdWrapper() { + if (mDStream) { + ZSTD_freeDStream(mDStream); + } + } + + UniquePtr<uint8_t[]> mOutBuffer; + nsresult mStatus = NS_OK; + nsIRequest* mRequest{nullptr}; + nsISupports* mContext{nullptr}; + uint64_t mSourceOffset{0}; + ZSTD_DStream* mDStream{nullptr}; +}; + // nsISupports implementation NS_IMPL_ISUPPORTS(nsHTTPCompressConv, nsIStreamConverter, nsIStreamListener, nsIRequestObserver, nsICompressConvStats, @@ -109,6 +134,12 @@ nsHTTPCompressConv::AsyncConvertData(const char* aFromType, const char* aToType, } else if (!nsCRT::strncasecmp(aFromType, HTTP_BROTLI_TYPE, sizeof(HTTP_BROTLI_TYPE) - 1)) { mMode = HTTP_COMPRESS_BROTLI; + } else if (!nsCRT::strncasecmp(aFromType, HTTP_ZSTD_TYPE, + sizeof(HTTP_ZSTD_TYPE) - 1)) { + mMode = HTTP_COMPRESS_ZSTD; + } else if (!nsCRT::strncasecmp(aFromType, HTTP_ZST_TYPE, + sizeof(HTTP_ZST_TYPE) - 1)) { + mMode = HTTP_COMPRESS_ZSTD; } LOG(("nsHttpCompresssConv %p AsyncConvertData %s %s mode %d\n", this, aFromType, aToType, (CompressMode)mMode)); @@ -128,6 +159,54 @@ nsHTTPCompressConv::GetConvertedType(const nsACString& aFromType, } NS_IMETHODIMP +nsHTTPCompressConv::MaybeRetarget(nsIRequest* request) { + MOZ_ASSERT(NS_IsMainThread()); + nsresult rv; + nsCOMPtr<nsIThreadRetargetableRequest> req = do_QueryInterface(request); + if (!req) { + return NS_ERROR_NO_INTERFACE; + } + if (!StaticPrefs::network_decompression_off_mainthread()) { + return NS_OK; + } + nsCOMPtr<nsISerialEventTarget> target; + rv = req->GetDeliveryTarget(getter_AddRefs(target)); + if (NS_FAILED(rv) || !target || target->IsOnCurrentThread()) { + nsCOMPtr<nsIChannel> channel(do_QueryInterface(request)); + int64_t length = -1; + if (channel) { + channel->GetContentLength(&length); + // If this fails we'll retarget + } + if (length <= 0 || + length >= + StaticPrefs::network_decompression_off_mainthread_min_size()) { + LOG(("MaybeRetarget: Retargeting to background thread: Length %" PRId64, + length)); + // No retargetting was performed. Decompress off MainThread, + // and dispatch results back to MainThread. + // Don't do this if the input is small, if we know the length. + // If the length is 0 (unknown), always use OMT. + nsCOMPtr<nsISerialEventTarget> backgroundThread; + rv = NS_CreateBackgroundTaskQueue("nsHTTPCompressConv", + getter_AddRefs(backgroundThread)); + NS_ENSURE_SUCCESS(rv, rv); + rv = req->RetargetDeliveryTo(backgroundThread); + NS_ENSURE_SUCCESS(rv, rv); + if (NS_SUCCEEDED(rv)) { + mDispatchToMainThread = true; + } + } else { + LOG(("MaybeRetarget: Not retargeting: Length %" PRId64, length)); + } + } else { + LOG(("MaybeRetarget: Don't need to retarget")); + } + + return NS_OK; +} + +NS_IMETHODIMP nsHTTPCompressConv::OnStartRequest(nsIRequest* request) { LOG(("nsHttpCompresssConv %p onstart\n", this)); nsCOMPtr<nsIStreamListener> listener; @@ -135,14 +214,33 @@ nsHTTPCompressConv::OnStartRequest(nsIRequest* request) { MutexAutoLock lock(mMutex); listener = mListener; } - return listener->OnStartRequest(request); + nsresult rv = listener->OnStartRequest(request); + if (NS_SUCCEEDED(rv)) { + if (XRE_IsContentProcess()) { + nsCOMPtr<nsIThreadRetargetableStreamListener> retargetlistener = + do_QueryInterface(listener); + // |nsHTTPCompressConv| should *always* be dispatched off of the main + // thread from a content process, even if its listeners don't support it. + // + // If its listener chain does not support being retargeted off of the + // main thread, it will be dispatched back to the main thread in + // |do_OnDataAvailable| and |OnStopRequest|. + if (!retargetlistener || + NS_FAILED(retargetlistener->CheckListenerChain())) { + mDispatchToMainThread = true; + } + } + } + return rv; } NS_IMETHODIMP nsHTTPCompressConv::OnStopRequest(nsIRequest* request, nsresult aStatus) { nsresult status = aStatus; - LOG(("nsHttpCompresssConv %p onstop %" PRIx32 "\n", this, - static_cast<uint32_t>(aStatus))); + // Bug 1886237 : TRRServiceChannel calls OnStopRequest OMT + // MOZ_ASSERT(NS_IsMainThread()); + LOG(("nsHttpCompresssConv %p onstop %" PRIx32 " mDispatchToMainThread %d\n", + this, static_cast<uint32_t>(aStatus), mDispatchToMainThread)); // Framing integrity is enforced for content-encoding: gzip, but not for // content-encoding: deflate. Note that gzip vs deflate is NOT determined @@ -181,6 +279,7 @@ nsHTTPCompressConv::OnStopRequest(nsIRequest* request, nsresult aStatus) { MutexAutoLock lock(mMutex); listener = mListener; } + return listener->OnStopRequest(request, status); } @@ -292,6 +391,71 @@ nsresult nsHTTPCompressConv::BrotliHandler(nsIInputStream* stream, return self->mBrotli->mStatus; } +/* static */ +nsresult nsHTTPCompressConv::ZstdHandler(nsIInputStream* stream, void* closure, + const char* dataIn, uint32_t, + uint32_t aAvail, uint32_t* countRead) { + MOZ_ASSERT(stream); + nsHTTPCompressConv* self = static_cast<nsHTTPCompressConv*>(closure); + *countRead = 0; + + const size_t kOutSize = ZSTD_DStreamOutSize(); // normally 128K + uint8_t* outPtr; + size_t avail = aAvail; + + // Stop decompressing after an error + if (self->mZstd->mStatus != NS_OK) { + *countRead = aAvail; + return NS_OK; + } + + if (!self->mZstd->mOutBuffer) { + self->mZstd->mOutBuffer = MakeUniqueFallible<uint8_t[]>(kOutSize); + if (!self->mZstd->mOutBuffer) { + self->mZstd->mStatus = NS_ERROR_OUT_OF_MEMORY; + return self->mZstd->mStatus; + } + } + ZSTD_inBuffer inBuffer = {.src = dataIn, .size = aAvail, .pos = 0}; + uint32_t last_pos = 0; + while (inBuffer.pos < inBuffer.size) { + outPtr = self->mZstd->mOutBuffer.get(); + + LOG(("nsHttpCompresssConv %p zstdhandler decompress %zu\n", self, avail)); + // Use ZSTD_(de)compressStream to (de)compress the input buffer into the + // output buffer, and fill aReadCount with the number of bytes consumed. + ZSTD_outBuffer outBuffer{.dst = outPtr, .size = kOutSize}; + size_t result; + bool output_full; + do { + outBuffer.pos = 0; + result = + ZSTD_decompressStream(self->mZstd->mDStream, &outBuffer, &inBuffer); + + // If we errored when writing, flag this and abort writing. + if (ZSTD_isError(result)) { + self->mZstd->mStatus = NS_ERROR_INVALID_CONTENT_ENCODING; + return self->mZstd->mStatus; + } + + nsresult rv = self->do_OnDataAvailable( + self->mZstd->mRequest, self->mZstd->mSourceOffset, + reinterpret_cast<const char*>(outPtr), outBuffer.pos); + if (NS_FAILED(rv)) { + self->mZstd->mStatus = rv; + return rv; + } + self->mZstd->mSourceOffset += inBuffer.pos - last_pos; + last_pos = inBuffer.pos; + output_full = outBuffer.pos == outBuffer.size; + // in the unlikely case that the output buffer was full, loop to + // drain it before processing more input + } while (output_full); + } + *countRead = inBuffer.pos; + return NS_OK; +} + NS_IMETHODIMP nsHTTPCompressConv::OnDataAvailable(nsIRequest* request, nsIInputStream* iStr, uint64_t aSourceOffset, uint32_t aCount) { @@ -525,6 +689,25 @@ nsHTTPCompressConv::OnDataAvailable(nsIRequest* request, nsIInputStream* iStr, } } break; + case HTTP_COMPRESS_ZSTD: { + if (!mZstd) { + mZstd = MakeUnique<ZstdWrapper>(); + } + + mZstd->mRequest = request; + mZstd->mContext = nullptr; + mZstd->mSourceOffset = aSourceOffset; + + uint32_t countRead; + rv = iStr->ReadSegments(ZstdHandler, this, streamLen, &countRead); + if (NS_SUCCEEDED(rv)) { + rv = mZstd->mStatus; + } + if (NS_FAILED(rv)) { + return rv; + } + } break; + default: nsCOMPtr<nsIStreamListener> listener; { @@ -553,6 +736,35 @@ nsresult nsHTTPCompressConv::do_OnDataAvailable(nsIRequest* request, uint64_t offset, const char* buffer, uint32_t count) { + LOG(("nsHttpCompressConv %p do_OnDataAvailable mDispatchToMainThread %d", + this, mDispatchToMainThread)); + if (mDispatchToMainThread && !NS_IsMainThread()) { + nsCOMPtr<nsIInputStream> stream; + MOZ_TRY(NS_NewByteInputStream(getter_AddRefs(stream), Span(buffer, count), + nsAssignmentType::NS_ASSIGNMENT_COPY)); + + nsCOMPtr<nsIStreamListener> listener; + { + MutexAutoLock lock(mMutex); + listener = mListener; + } + + // This is safe and will always run before OnStopRequest, because + // ChanneleventQueue means that we can't enqueue OnStopRequest until after + // the OMT OnDataAvailable call has completed. So Dispatching here will + // ensure it's in the MainThread event queue before OnStopRequest + nsCOMPtr<nsIRunnable> handler = NS_NewRunnableFunction( + "nsHTTPCompressConv::do_OnDataAvailable", + [request{RefPtr<nsIRequest>(request)}, stream{std::move(stream)}, + listener{std::move(listener)}, offset, count]() { + LOG(("nsHttpCompressConv Calling OnDataAvailable on Mainthread")); + Unused << listener->OnDataAvailable(request, stream, offset, count); + }); + + mDecodedDataLength += count; + return NS_DispatchToMainThread(handler); + } + if (!mStream) { mStream = do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID); NS_ENSURE_STATE(mStream); @@ -725,12 +937,16 @@ uint32_t nsHTTPCompressConv::check_header(nsIInputStream* iStr, NS_IMETHODIMP nsHTTPCompressConv::CheckListenerChain() { + if (XRE_IsContentProcess()) { + // handle decompression OMT always. If the chain needs to be MT, + // we'll determine that in OnStartRequest and dispatch to MT + return NS_OK; + } nsCOMPtr<nsIThreadRetargetableStreamListener> listener; { MutexAutoLock lock(mMutex); listener = do_QueryInterface(mListener); } - if (!listener) { return NS_ERROR_NO_INTERFACE; } @@ -748,6 +964,15 @@ nsHTTPCompressConv::OnDataFinished(nsresult aStatus) { } if (listener) { + if (mDispatchToMainThread && !NS_IsMainThread()) { + nsCOMPtr<nsIRunnable> handler = NS_NewRunnableFunction( + "dispatch", [listener{std::move(listener)}, aStatus]() { + Unused << listener->OnDataFinished(aStatus); + }); + + return NS_DispatchToMainThread(handler); + } + return listener->OnDataFinished(aStatus); } diff --git a/netwerk/streamconv/converters/nsHTTPCompressConv.h b/netwerk/streamconv/converters/nsHTTPCompressConv.h index 4ba2d9819c..1008edcf27 100644 --- a/netwerk/streamconv/converters/nsHTTPCompressConv.h +++ b/netwerk/streamconv/converters/nsHTTPCompressConv.h @@ -34,11 +34,14 @@ class nsIStringInputStream; # define HTTP_BROTLI_TYPE "br" # define HTTP_IDENTITY_TYPE "identity" # define HTTP_UNCOMPRESSED_TYPE "uncompressed" +# define HTTP_ZSTD_TYPE "zstd" +# define HTTP_ZST_TYPE "zst" namespace mozilla { namespace net { class BrotliWrapper; +class ZstdWrapper; class nsHTTPCompressConv : public nsIStreamConverter, public nsICompressConvStats { @@ -60,7 +63,8 @@ class nsHTTPCompressConv : public nsIStreamConverter, HTTP_COMPRESS_DEFLATE, HTTP_COMPRESS_COMPRESS, HTTP_COMPRESS_BROTLI, - HTTP_COMPRESS_IDENTITY + HTTP_COMPRESS_IDENTITY, + HTTP_COMPRESS_ZSTD, }; private: @@ -77,6 +81,7 @@ class nsHTTPCompressConv : public nsIStreamConverter, uint32_t mInpBufferLen{0}; UniquePtr<BrotliWrapper> mBrotli; + UniquePtr<ZstdWrapper> mZstd; nsCOMPtr<nsIStringInputStream> mStream; @@ -84,6 +89,10 @@ class nsHTTPCompressConv : public nsIStreamConverter, const char* dataIn, uint32_t, uint32_t avail, uint32_t* countRead); + static nsresult ZstdHandler(nsIInputStream* stream, void* closure, + const char* dataIn, uint32_t, uint32_t avail, + uint32_t* countRead); + nsresult do_OnDataAvailable(nsIRequest* request, uint64_t aSourceOffset, const char* buffer, uint32_t aCount); @@ -92,6 +101,7 @@ class nsHTTPCompressConv : public nsIStreamConverter, bool mStreamInitialized{false}; bool mDummyStreamInitialised{false}; bool mFailUncleanStops; + bool mDispatchToMainThread{false}; z_stream d_stream{}; unsigned mLen{0}, hMode{0}, mSkipCount{0}, mFlags{0}; diff --git a/netwerk/streamconv/converters/nsIndexedToHTML.cpp b/netwerk/streamconv/converters/nsIndexedToHTML.cpp index efc8962459..40650d9fce 100644 --- a/netwerk/streamconv/converters/nsIndexedToHTML.cpp +++ b/netwerk/streamconv/converters/nsIndexedToHTML.cpp @@ -98,6 +98,11 @@ nsIndexedToHTML::GetConvertedType(const nsACString& aFromType, } NS_IMETHODIMP +nsIndexedToHTML::MaybeRetarget(nsIRequest* request) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsIndexedToHTML::OnStartRequest(nsIRequest* request) { nsCString buffer; nsresult rv = DoOnStartRequest(request, buffer); diff --git a/netwerk/streamconv/converters/nsMultiMixedConv.cpp b/netwerk/streamconv/converters/nsMultiMixedConv.cpp index fb21d6673f..df7294acf9 100644 --- a/netwerk/streamconv/converters/nsMultiMixedConv.cpp +++ b/netwerk/streamconv/converters/nsMultiMixedConv.cpp @@ -442,6 +442,11 @@ nsMultiMixedConv::GetConvertedType(const nsACString& aFromType, return NS_ERROR_NOT_IMPLEMENTED; } +NS_IMETHODIMP +nsMultiMixedConv::MaybeRetarget(nsIRequest* request) { + return NS_ERROR_NOT_IMPLEMENTED; +} + // nsIRequestObserver implementation NS_IMETHODIMP nsMultiMixedConv::OnStartRequest(nsIRequest* request) { diff --git a/netwerk/streamconv/converters/nsUnknownDecoder.cpp b/netwerk/streamconv/converters/nsUnknownDecoder.cpp index b572b1c276..33c6ea4f1d 100644 --- a/netwerk/streamconv/converters/nsUnknownDecoder.cpp +++ b/netwerk/streamconv/converters/nsUnknownDecoder.cpp @@ -223,6 +223,11 @@ nsUnknownDecoder::OnDataAvailable(nsIRequest* request, nsIInputStream* aStream, return rv; } +NS_IMETHODIMP +nsUnknownDecoder::MaybeRetarget(nsIRequest* request) { + return NS_ERROR_NOT_IMPLEMENTED; +} + // ---- // // nsIRequestObserver methods... diff --git a/netwerk/streamconv/nsIStreamConverter.idl b/netwerk/streamconv/nsIStreamConverter.idl index 68f341b328..b2fc32ebcf 100644 --- a/netwerk/streamconv/nsIStreamConverter.idl +++ b/netwerk/streamconv/nsIStreamConverter.idl @@ -96,6 +96,12 @@ interface nsIStreamConverter : nsIThreadRetargetableStreamListener { in nsISupports aCtxt); /** + * This is called after the request has installed the stream converter as its listener + * giving the stream converter the option to request retargetting of onDataAvailable. + */ + void maybeRetarget(in nsIRequest request); + + /** * Returns the content type that the stream listener passed to asyncConvertData will * see on the channel if the conversion is being done from aFromType to * /*. * diff --git a/netwerk/test/browser/browser.toml b/netwerk/test/browser/browser.toml index 9a470d8c59..002bd2769d 100644 --- a/netwerk/test/browser/browser.toml +++ b/netwerk/test/browser/browser.toml @@ -74,6 +74,10 @@ support-files = [ "file_link_header.sjs", ] +prefs = [ + "network.fetch.systemDefaultsToOmittingCredentials=false" +] + ["browser_103_assets.js"] ["browser_103_assets_extension.js"] diff --git a/netwerk/test/browser/browser_bug1629307.js b/netwerk/test/browser/browser_bug1629307.js index 03ea2476e2..1cab7bc101 100644 --- a/netwerk/test/browser/browser_bug1629307.js +++ b/netwerk/test/browser/browser_bug1629307.js @@ -24,7 +24,7 @@ add_task(async function () { PromptTestUtils.handleNextPrompt( window, { - modalType: Services.prefs.getIntPref("prompts.modalType.httpAuth"), + modalType: Ci.nsIPrompt.MODAL_TYPE_TAB, promptType: "promptUserAndPass", }, { buttonNumClick: 1 } @@ -59,7 +59,7 @@ add_task(async function () { PromptTestUtils.handleNextPrompt( window, { - modalType: Services.prefs.getIntPref("prompts.modalType.httpAuth"), + modalType: Ci.nsIPrompt.MODAL_TYPE_TAB, promptType: "promptUserAndPass", }, { buttonNumClick: 1 } diff --git a/netwerk/test/browser/browser_cookie_filtering_insecure.js b/netwerk/test/browser/browser_cookie_filtering_insecure.js index 679bfc5a56..4f46773675 100644 --- a/netwerk/test/browser/browser_cookie_filtering_insecure.js +++ b/netwerk/test/browser/browser_cookie_filtering_insecure.js @@ -4,6 +4,14 @@ */ "use strict"; +// performing http and https testing within this file, +// and we do not want https-first to interfere with that test +Services.prefs.setBoolPref("dom.security.https_first", false); + +registerCleanupFunction(function () { + Services.prefs.clearUserPref("dom.security.https_first"); +}); + const { HTTPS_EXAMPLE_ORG, HTTPS_EXAMPLE_COM, diff --git a/netwerk/test/browser/browser_cookie_filtering_subdomain.js b/netwerk/test/browser/browser_cookie_filtering_subdomain.js index 78fcdb07dd..4a27eea1e8 100644 --- a/netwerk/test/browser/browser_cookie_filtering_subdomain.js +++ b/netwerk/test/browser/browser_cookie_filtering_subdomain.js @@ -5,6 +5,14 @@ "use strict"; +// performing http and https testing within this file, +// and we do not want https-first to interfere with that test +Services.prefs.setBoolPref("dom.security.https_first", false); + +registerCleanupFunction(function () { + Services.prefs.clearUserPref("dom.security.https_first"); +}); + const { HTTPS_EXAMPLE_ORG, HTTPS_EXAMPLE_COM, diff --git a/netwerk/test/browser/browser_post_auth.js b/netwerk/test/browser/browser_post_auth.js index 24104f96d6..1168cdabb1 100644 --- a/netwerk/test/browser/browser_post_auth.js +++ b/netwerk/test/browser/browser_post_auth.js @@ -43,7 +43,7 @@ add_task(async function () { let promptPromise = PromptTestUtils.handleNextPrompt( tab.linkedBrowser, { - modalType: Services.prefs.getIntPref("prompts.modalType.httpAuth"), + modalType: Ci.nsIPrompt.MODAL_TYPE_TAB, promptType: "promptUserAndPass", }, { buttonNumClick: 0, loginInput: "user", passwordInput: "pass" } diff --git a/netwerk/test/gtest/TestIDNA.cpp b/netwerk/test/gtest/TestIDNA.cpp new file mode 100644 index 0000000000..544debbd43 --- /dev/null +++ b/netwerk/test/gtest/TestIDNA.cpp @@ -0,0 +1,77 @@ +#include "gtest/gtest.h" +#include "gtest/MozGTestBench.h" // For MOZ_GTEST_BENCH +#include "gtest/BlackBox.h" + +#include "nsNetUtil.h" + +#define TEST_COUNT 10000 + +class TestIDNA : public ::testing::Test { + protected: + void SetUp() override { + // Intentionally Assign and not AssignLiteral + // to simulate the usual heap case. + mPlainASCII.Assign("example.com"); + mLeadingDigitASCII.Assign("1test.example"); + mUnicodeMixed.Assign("مثال.example"); + mPunycodeMixed.Assign("xn--mgbh0fb.example"); + mUnicodeLTR.Assign("නම.උදාහරණ"); + mPunycodeLTR.Assign("xn--r0co.xn--ozc8dl2c3bxd"); + mUnicodeRTL.Assign("الاسم.مثال"); + mPunycodeRTL.Assign("xn--mgba0b1dh.xn--mgbh0fb"); + // Intentionally not assigning to mEmpty + } + + public: + nsCString mPlainASCII; + nsCString mLeadingDigitASCII; + nsCString mUnicodeMixed; + nsCString mPunycodeMixed; + nsCString mUnicodeLTR; + nsCString mPunycodeLTR; + nsCString mUnicodeRTL; + nsCString mPunycodeRTL; + nsCString mEmpty; // Extremely suspicious measurement! +}; + +#define IDNA_ITERATIONS 50000 + +#define IDNA_BENCH(name, func, src) \ + MOZ_GTEST_BENCH_F(TestIDNA, name, [this] { \ + for (int i = 0; i < IDNA_ITERATIONS; i++) { \ + nsCString dst; \ + func(*mozilla::BlackBox(&src), *mozilla::BlackBox(&dst)); \ + } \ + }); + +IDNA_BENCH(BenchToASCIIPlainASCII, NS_DomainToASCII, mPlainASCII); +IDNA_BENCH(BenchToASCIILeadingDigitASCII, NS_DomainToASCII, mLeadingDigitASCII); +IDNA_BENCH(BenchToASCIIUnicodeMixed, NS_DomainToASCII, mUnicodeMixed); +IDNA_BENCH(BenchToASCIIPunycodeMixed, NS_DomainToASCII, mPunycodeMixed); +IDNA_BENCH(BenchToASCIIUnicodeLTR, NS_DomainToASCII, mUnicodeLTR); +IDNA_BENCH(BenchToASCIIPunycodeLTR, NS_DomainToASCII, mPunycodeLTR); +IDNA_BENCH(BenchToASCIIUnicodeRTL, NS_DomainToASCII, mUnicodeRTL); +IDNA_BENCH(BenchToASCIIPunycodeRTL, NS_DomainToASCII, mPunycodeRTL); +IDNA_BENCH(BenchToASCIIEmpty, NS_DomainToASCII, mEmpty); + +IDNA_BENCH(BenchToDisplayPlainASCII, NS_DomainToDisplay, mPlainASCII); +IDNA_BENCH(BenchToDisplayLeadingDigitASCII, NS_DomainToDisplay, + mLeadingDigitASCII); +IDNA_BENCH(BenchToDisplayUnicodeMixed, NS_DomainToDisplay, mUnicodeMixed); +IDNA_BENCH(BenchToDisplayPunycodeMixed, NS_DomainToDisplay, mPunycodeMixed); +IDNA_BENCH(BenchToDisplayUnicodeLTR, NS_DomainToDisplay, mUnicodeLTR); +IDNA_BENCH(BenchToDisplayPunycodeLTR, NS_DomainToDisplay, mPunycodeLTR); +IDNA_BENCH(BenchToDisplayUnicodeRTL, NS_DomainToDisplay, mUnicodeRTL); +IDNA_BENCH(BenchToDisplayPunycodeRTL, NS_DomainToDisplay, mPunycodeRTL); +IDNA_BENCH(BenchToDisplayEmpty, NS_DomainToDisplay, mEmpty); + +IDNA_BENCH(BenchToUnicodePlainASCII, NS_DomainToUnicode, mPlainASCII); +IDNA_BENCH(BenchToUnicodeLeadingDigitASCII, NS_DomainToUnicode, + mLeadingDigitASCII); +IDNA_BENCH(BenchToUnicodeUnicodeMixed, NS_DomainToUnicode, mUnicodeMixed); +IDNA_BENCH(BenchToUnicodePunycodeMixed, NS_DomainToUnicode, mPunycodeMixed); +IDNA_BENCH(BenchToUnicodeUnicodeLTR, NS_DomainToUnicode, mUnicodeLTR); +IDNA_BENCH(BenchToUnicodePunycodeLTR, NS_DomainToUnicode, mPunycodeLTR); +IDNA_BENCH(BenchToUnicodeUnicodeRTL, NS_DomainToUnicode, mUnicodeRTL); +IDNA_BENCH(BenchToUnicodePunycodeRTL, NS_DomainToUnicode, mPunycodeRTL); +IDNA_BENCH(BenchToUnicodeEmpty, NS_DomainToUnicode, mEmpty); diff --git a/netwerk/test/gtest/TestStandardURL.cpp b/netwerk/test/gtest/TestStandardURL.cpp index 035c92fcc2..64a57ed7fb 100644 --- a/netwerk/test/gtest/TestStandardURL.cpp +++ b/netwerk/test/gtest/TestStandardURL.cpp @@ -14,6 +14,7 @@ #include "nsSerializationHelper.h" #include "mozilla/Base64.h" #include "nsEscape.h" +#include "nsURLHelper.h" using namespace mozilla; @@ -439,3 +440,30 @@ TEST(TestStandardURL, ParseIPv4Num) Test_ParseIPv4Number("0x10"_ns, 16, number, 255); ASSERT_EQ(number, (uint32_t)16); } + +TEST(TestStandardURL, CoalescePath) +{ + auto testCoalescing = [](const char* input, const char* expected) { + nsAutoCString buf(input); + net_CoalesceDirs(NET_COALESCE_NORMAL, buf.BeginWriting()); + ASSERT_EQ(nsCString(buf.get()), nsCString(expected)); + }; + + testCoalescing("/.", "/"); + testCoalescing("/..", "/"); + testCoalescing("/foo/foo1/.", "/foo/foo1/"); + testCoalescing("/foo/../foo1", "/foo1"); + testCoalescing("/foo/./foo1", "/foo/foo1"); + testCoalescing("/foo/foo1/..", "/foo/"); + + // Bug 1890346 + testCoalescing("/..?/..", "/?/.."); + + testCoalescing("/.?/..", "/?/.."); + testCoalescing("/./../?", "/?"); + testCoalescing("/.abc", "/.abc"); + testCoalescing("//", "//"); + testCoalescing("/../", "/"); + testCoalescing("/./", "/"); + testCoalescing("/.../", "/.../"); +} diff --git a/netwerk/test/gtest/moz.build b/netwerk/test/gtest/moz.build index 571c908707..8e0d66f4e2 100644 --- a/netwerk/test/gtest/moz.build +++ b/netwerk/test/gtest/moz.build @@ -17,6 +17,7 @@ UNIFIED_SOURCES += [ "TestHttpAuthUtils.cpp", "TestHttpChannel.cpp", "TestHttpResponseHead.cpp", + "TestIDNA.cpp", "TestInputStreamTransport.cpp", "TestIsValidIp.cpp", "TestLinkHeader.cpp", diff --git a/netwerk/test/http3server/Cargo.toml b/netwerk/test/http3server/Cargo.toml index 60ff22c530..4905760d3d 100644 --- a/netwerk/test/http3server/Cargo.toml +++ b/netwerk/test/http3server/Cargo.toml @@ -6,10 +6,10 @@ edition = "2018" license = "MPL-2.0" [dependencies] -neqo-transport = { tag = "v0.7.2", git = "https://github.com/mozilla/neqo" } -neqo-common = { tag = "v0.7.2", git = "https://github.com/mozilla/neqo" } -neqo-http3 = { tag = "v0.7.2", git = "https://github.com/mozilla/neqo" } -neqo-qpack = { tag = "v0.7.2", git = "https://github.com/mozilla/neqo" } +neqo-transport = { tag = "v0.7.5", git = "https://github.com/mozilla/neqo" } +neqo-common = { tag = "v0.7.5", git = "https://github.com/mozilla/neqo" } +neqo-http3 = { tag = "v0.7.5", git = "https://github.com/mozilla/neqo" } +neqo-qpack = { tag = "v0.7.5", git = "https://github.com/mozilla/neqo" } mio = "0.6.17" mio-extras = "2.0.5" log = "0.4.0" @@ -21,7 +21,7 @@ tokio = { version = "1", features = ["rt-multi-thread"] } mozilla-central-workspace-hack = { version = "0.1", features = ["http3server"], optional = true } [dependencies.neqo-crypto] -tag = "v0.7.2" +tag = "v0.7.5" git = "https://github.com/mozilla/neqo" default-features = false features = ["gecko"] diff --git a/netwerk/test/http3server/src/main.rs b/netwerk/test/http3server/src/main.rs index a308f56442..1543e3aeb3 100644 --- a/netwerk/test/http3server/src/main.rs +++ b/netwerk/test/http3server/src/main.rs @@ -1378,7 +1378,7 @@ fn main() -> Result<(), io::Error> { } }); - init_db(PathBuf::from(args[1].clone())); + init_db(PathBuf::from(args[1].clone())).unwrap(); let mut servers_runner = ServersRunner::new()?; servers_runner.init(); diff --git a/netwerk/test/mochitests/test_different_domain_in_hierarchy.html b/netwerk/test/mochitests/test_different_domain_in_hierarchy.html index 0ec6d35d4d..1a4abad676 100644 --- a/netwerk/test/mochitests/test_different_domain_in_hierarchy.html +++ b/netwerk/test/mochitests/test_different_domain_in_hierarchy.html @@ -5,7 +5,7 @@ <script src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> -<body onload="setupTest('https://example.org/tests/netwerk/test/mochitests/file_domain_hierarchy_inner.html', 4, 3)"> +<body onload="setupTest('https://example.org/tests/netwerk/test/mochitests/file_domain_hierarchy_inner.html', 3, 3)"> <p id="display"></p> <pre id="test"> <script class="testbody" type="text/javascript" src="file_testcommon.js"> diff --git a/netwerk/test/mochitests/test_rel_preconnect.html b/netwerk/test/mochitests/test_rel_preconnect.html index a0c3309954..fd3d0cf311 100644 --- a/netwerk/test/mochitests/test_rel_preconnect.html +++ b/netwerk/test/mochitests/test_rel_preconnect.html @@ -19,12 +19,15 @@ async function doTest() { await SpecialPowers.setBoolPref("network.http.debug-observations", true); + SimpleTest.registerCleanupFunction(async () => { + await SpecialPowers.setBoolPref("network.http.debug-observations", false); + }); + observer = SpecialPowers.wrapCallback(function() { remainder--; ok(true, "observed remainder = " + remainder); if (!remainder) { SpecialPowers.removeObserver(observer, "speculative-connect-request"); - SpecialPowers.setBoolPref("network.http.debug-observations", false); SimpleTest.finish(); } }); diff --git a/netwerk/test/unit/test_NetUtil.js b/netwerk/test/unit/test_NetUtil.js index 624e35f30e..211f60ac6a 100644 --- a/netwerk/test/unit/test_NetUtil.js +++ b/netwerk/test/unit/test_NetUtil.js @@ -5,7 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** - * This file tests the methods on NetUtil.jsm. + * This file tests the methods on NetUtil.sys.mjs. */ "use strict"; diff --git a/netwerk/test/unit/test_brotli_http.js b/netwerk/test/unit/test_brotli_http.js index 1207c95012..adf5915b76 100644 --- a/netwerk/test/unit/test_brotli_http.js +++ b/netwerk/test/unit/test_brotli_http.js @@ -100,7 +100,7 @@ add_task( }); equal( Services.prefs.getCharPref("network.http.accept-encoding.secure"), - "gzip, deflate, br" + "gzip, deflate, br, zstd" ); let { req, buff } = await new Promise(resolve => { let chan = NetUtil.newChannel({ diff --git a/netwerk/test/unit/test_bug526789.js b/netwerk/test/unit/test_bug526789.js index ec80249a3c..ba0714801f 100644 --- a/netwerk/test/unit/test_bug526789.js +++ b/netwerk/test/unit/test_bug526789.js @@ -239,6 +239,7 @@ add_task(async () => { await testTrailingDotCookie("http://foo.com/", "foo.com"); cm.removeAll(); + Services.prefs.clearUserPref("dom.security.https_first"); }); function getCookieCount() { @@ -285,5 +286,4 @@ async function testTrailingDotCookie(uriString, domain) { Assert.equal(cm.countCookiesFromHost(domain), 0); Assert.equal(cm.countCookiesFromHost(domain + "."), 0); cm.removeAll(); - Services.prefs.clearUserPref("dom.security.https_first"); } diff --git a/netwerk/test/unit/test_connection_coalescing.js b/netwerk/test/unit/test_connection_coalescing.js new file mode 100644 index 0000000000..a61098e73e --- /dev/null +++ b/netwerk/test/unit/test_connection_coalescing.js @@ -0,0 +1,194 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */ + +"use strict"; + +const override = Cc["@mozilla.org/network/native-dns-override;1"].getService( + Ci.nsINativeDNSResolverOverride +); + +let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); +addCertFromFile(certdb, "http2-ca.pem", "CTu,u,u"); + +async function createServer() { + let server = new NodeHTTP2Server(); + await server.start(); + registerCleanupFunction(async () => { + await server.stop(); + }); + await server.registerPathHandler("/", (req, resp) => { + let content = `hello from ${req.authority} | ${req.socket.remotePort}`; + resp.writeHead(200, { + "Content-Type": "text/plain", + "Content-Length": `${content.length}`, + }); + resp.end(content); + }); + return server; +} + +let IP1 = "127.0.0.1"; +let IP2 = "127.0.0.2"; +if (AppConstants.platform == "macosx") { + // OSX doesn't use 127.0.0.2 as a local interface + IP2 = "::1"; +} else if (AppConstants.platform == "android") { + IP2 = "10.0.2.2"; +} + +async function openChan(uri) { + let chan = NetUtil.newChannel({ + uri, + loadUsingSystemPrincipal: true, + }).QueryInterface(Ci.nsIHttpChannel); + chan.loadFlags = Ci.nsIChannel.LOAD_INITIAL_DOCUMENT_URI; + + let { req, buffer } = await new Promise(resolve => { + function finish(r, b) { + resolve({ req: r, buffer: b }); + } + chan.asyncOpen(new ChannelListener(finish, null, CL_ALLOW_UNKNOWN_CL)); + }); + + return { + buffer, + port: buffer.split("|")[1], + addr: req.QueryInterface(Ci.nsIHttpChannelInternal).remoteAddress, + status: req.QueryInterface(Ci.nsIHttpChannel).responseStatus, + }; +} + +add_task(async function test_dontCoalesce() { + let server = await createServer(); + Services.prefs.setBoolPref("network.http.http2.aggressive_coalescing", false); + override.clearOverrides(); + Services.dns.clearCache(true); + + override.addIPOverride("foo.example.com", IP1); + override.addIPOverride("foo.example.com", IP2); + override.addIPOverride("alt1.example.com", IP2); + + let { addr: addr1 } = await openChan( + `https://foo.example.com:${server.port()}/` + ); + let { addr: addr2 } = await openChan( + `https://alt1.example.com:${server.port()}/` + ); + + Assert.notEqual(addr1, addr2); + await server.stop(); +}); + +add_task(async function test_doCoalesce() { + let server = await createServer(); + Services.prefs.setBoolPref("network.http.http2.aggressive_coalescing", false); + override.clearOverrides(); + Services.dns.clearCache(true); + + override.addIPOverride("foo.example.com", IP1); + override.addIPOverride("foo.example.com", IP2); + override.addIPOverride("alt2.example.com", IP1); + override.addIPOverride("alt2.example.com", IP2); + + let { port: port1, addr: addr1 } = await openChan( + `https://foo.example.com:${server.port()}/` + ); + let { port: port2, addr: addr2 } = await openChan( + `https://alt2.example.com:${server.port()}/` + ); + + Assert.equal(addr1, addr2); + Assert.equal(port1, port2); + await server.stop(); +}); + +add_task(async function test_doCoalesceAggresive() { + let server = await createServer(); + + Services.prefs.setBoolPref("network.http.http2.aggressive_coalescing", true); + override.clearOverrides(); + Services.dns.clearCache(true); + + override.addIPOverride("foo.example.com", IP1); + override.addIPOverride("foo.example.com", IP2); + override.addIPOverride("alt1.example.com", IP2); + + let { port: port1, addr: addr1 } = await openChan( + `https://foo.example.com:${server.port()}/` + ); + let { port: port2, addr: addr2 } = await openChan( + `https://alt1.example.com:${server.port()}/` + ); + + Assert.equal(addr1, addr2); + Assert.equal(port1, port2); + await server.stop(); +}); + +// On android because of the way networking is set up the +// localAddress is always ::ffff:127.0.0.1 so it can't be +// used to make a decision. +add_task( + { skip_if: () => AppConstants.platform == "android" }, + async function test_doCoalesceAggresive421() { + let server = await createServer(); + + await server.execute(`global.rightIP = "${IP2}"`); + + await server.registerPathHandler("/", (req, resp) => { + let content = `hello from ${req.authority} | ${req.socket.remotePort}`; + // Check that returning 421 when aggresively coalescing + // makes Firefox not coalesce the connections. + if ( + req.authority.startsWith("alt1.example.com") && + req.socket.localAddress != global.rightIP && + req.socket.localAddress != `::ffff:${global.rightIP}` + ) { + resp.writeHead(421, { + "Content-Type": "text/plain", + "Content-Length": `${content.length}`, + }); + resp.end(content); + return; + } + resp.writeHead(200, { + "Content-Type": "text/plain", + "Content-Length": `${content.length}`, + }); + resp.end(content); + }); + + Services.prefs.setBoolPref( + "network.http.http2.aggressive_coalescing", + true + ); + override.clearOverrides(); + Services.dns.clearCache(true); + + override.addIPOverride("foo.example.com", IP1); + override.addIPOverride("foo.example.com", IP2); + override.addIPOverride("alt1.example.com", IP2); + + let { + addr: addr1, + status: status1, + port: port1, + } = await openChan(`https://foo.example.com:${server.port()}/`); + Assert.equal(status1, 200); + Assert.equal(addr1, IP1); + let { + addr: addr2, + status: status2, + port: port2, + } = await openChan(`https://alt1.example.com:${server.port()}/`); + + Assert.equal(status2, 200); + Assert.equal(addr2, IP2); + Assert.notEqual(port1, port2); + await server.stop(); + } +); diff --git a/netwerk/test/unit/test_default_uri_bypass.js b/netwerk/test/unit/test_default_uri_bypass.js new file mode 100644 index 0000000000..d3ceac5d8c --- /dev/null +++ b/netwerk/test/unit/test_default_uri_bypass.js @@ -0,0 +1,67 @@ +/* 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/. */ + +/* + * Test that default uri is bypassable by an unknown protocol that is + * present in the bypass list (and the pref is enabled) + */ +"use strict"; + +function inChildProcess() { + return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; +} + +function run_test() { + // In-Parent-only process pref setup + if (!inChildProcess()) { + Services.prefs.setBoolPref("network.url.useDefaultURI", true); + Services.prefs.setBoolPref( + "network.url.some_schemes_bypass_defaultURI_fallback", + true + ); + + Services.prefs.setCharPref( + "network.url.simple_uri_schemes", + "simpleprotocol,otherproto" + ); + } + + // check valid url is fine + let uri = NetUtil.newURI("https://example.com/"); + Assert.equal(uri.spec, "https://example.com/"); // same + + // nsStandardURL removes second colon when nesting protocols + let uri1 = NetUtil.newURI("https://https://example.com/"); + Assert.equal(uri1.spec, "https://https//example.com/"); + + // defaultUri removes second colon + // no-bypass protocol uses defaultURI + let uri2 = NetUtil.newURI("nonsimpleprotocol://https://example.com"); + Assert.equal(uri2.spec, "nonsimpleprotocol://https//example.com"); + + // simpleURI keeps the second colon + // an unknown protocol in the bypass list will use simpleURI + // despite network.url.useDefaultURI being enabled + let same = "simpleprotocol://https://example.com"; + let uri3 = NetUtil.newURI(same); + Assert.equal(uri3.spec, same); // simple uri keeps second colon + + // setCharPref not accessible from child process + if (!inChildProcess()) { + // check that pref update removes simpleprotocol from bypass list + Services.prefs.setCharPref("network.url.simple_uri_schemes", "otherproto"); + let uri4 = NetUtil.newURI("simpleprotocol://https://example.com"); + Assert.equal(uri4.spec, "simpleprotocol://https//example.com"); // default uri removes second colon + + // check that spaces are parsed out + Services.prefs.setCharPref( + "network.url.simple_uri_schemes", + " simpleprotocol , otherproto " + ); + let uri5 = NetUtil.newURI("simpleprotocol://https://example.com"); + Assert.equal(uri5.spec, "simpleprotocol://https://example.com"); // simple uri keeps second colon + let uri6 = NetUtil.newURI("otherproto://https://example.com"); + Assert.equal(uri6.spec, "otherproto://https://example.com"); // simple uri keeps second colon + } +} diff --git a/netwerk/test/unit/test_dns_service.js b/netwerk/test/unit/test_dns_service.js index da404c1e7d..a4c167a6c3 100644 --- a/netwerk/test/unit/test_dns_service.js +++ b/netwerk/test/unit/test_dns_service.js @@ -121,3 +121,36 @@ add_task( } } ); + +add_task( + { + skip_if: () => + Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT, + }, + async function test_sort_family() { + Services.prefs.setBoolPref("network.dns.preferIPv6", true); + overrideService.clearOverrides(); + overrideService.addIPOverride("example.com", "1.2.3.4"); + overrideService.addIPOverride("example.com", "3.4.5.6"); + overrideService.addIPOverride("example.com", "::1"); + overrideService.addIPOverride("example.com", "::2"); + + let listener = new Listener(); + Services.dns.asyncResolve( + "example.com", + Ci.nsIDNSService.RESOLVE_TYPE_DEFAULT, + Ci.nsIDNSService.RESOLVE_CANONICAL_NAME, + null, // resolverInfo + listener, + mainThread, + defaultOriginAttributes + ); + + let [, inRecord] = await listener; + inRecord.QueryInterface(Ci.nsIDNSAddrRecord); + Assert.equal(inRecord.getNextAddrAsString(), "::1"); + Assert.equal(inRecord.getNextAddrAsString(), "::2"); + Assert.equal(inRecord.getNextAddrAsString(), "1.2.3.4"); + Assert.equal(inRecord.getNextAddrAsString(), "3.4.5.6"); + } +); diff --git a/netwerk/test/unit/test_http3_prio_disabled.js b/netwerk/test/unit/test_http3_prio_disabled.js index b73ca98709..44c7a20833 100644 --- a/netwerk/test/unit/test_http3_prio_disabled.js +++ b/netwerk/test/unit/test_http3_prio_disabled.js @@ -16,6 +16,7 @@ load("../unit/test_http3_prio_helpers.js"); if (!inChildProcess()) { registerCleanupFunction(async () => { Services.prefs.clearUserPref("network.http.http3.priority"); + Services.prefs.clearUserPref("network.http.priority_header.enabled"); http3_clear_prefs(); }); } @@ -75,7 +76,7 @@ async function test_http3_prio_disabled(incremental) { null ); await test_flag_priority( - "disabled (background)", + "disabled (tail)", Ci.nsIClassOfService.Tail, null, incremental, @@ -91,6 +92,7 @@ add_task(async function test_http3_prio_disabled_inc_true() { // wrapper handles when testing as content process for pref change if (!inChildProcess()) { Services.prefs.setBoolPref("network.http.http3.priority", false); + Services.prefs.setBoolPref("network.http.priority_header.enabled", false); } await test_http3_prio_disabled(true); }); @@ -101,6 +103,7 @@ add_task(async function test_http3_prio_disabled_inc_false() { // wrapper handles when testing as content process for pref change if (!inChildProcess()) { Services.prefs.setBoolPref("network.http.http3.priority", false); + Services.prefs.setBoolPref("network.http.priority_header.enabled", false); } await test_http3_prio_disabled(false); }); diff --git a/netwerk/test/unit/test_http3_prio_enabled.js b/netwerk/test/unit/test_http3_prio_enabled.js index 6dd30c590a..0dcb4aba6f 100644 --- a/netwerk/test/unit/test_http3_prio_enabled.js +++ b/netwerk/test/unit/test_http3_prio_enabled.js @@ -16,6 +16,7 @@ load("../unit/test_http3_prio_helpers.js"); if (!inChildProcess()) { registerCleanupFunction(async () => { Services.prefs.clearUserPref("network.http.http3.priority"); + Services.prefs.clearUserPref("network.http.priority_header.enabled"); http3_clear_prefs(); }); } @@ -82,7 +83,7 @@ async function test_http3_prio_enabled(incremental) { incremental ); await test_flag_priority( - "enabled (background)", + "enabled (tail)", Ci.nsIClassOfService.Tail, "u=6", incremental, @@ -95,6 +96,7 @@ add_task(async function test_http3_prio_enabled_incremental_true() { // wrapper handles when testing as content process for pref change if (!inChildProcess()) { Services.prefs.setBoolPref("network.http.http3.priority", true); + Services.prefs.setBoolPref("network.http.priority_header.enabled", true); } await test_http3_prio_enabled(true); }); @@ -103,6 +105,7 @@ add_task(async function test_http3_prio_enabled_incremental_false() { // wrapper handles when testing as content process for pref change if (!inChildProcess()) { Services.prefs.setBoolPref("network.http.http3.priority", true); + Services.prefs.setBoolPref("network.http.priority_header.enabled", true); } await test_http3_prio_enabled(false); }); diff --git a/netwerk/test/unit/test_multipart_set_cookie.js b/netwerk/test/unit/test_multipart_set_cookie.js index c8943cf3cc..e7ea715355 100644 --- a/netwerk/test/unit/test_multipart_set_cookie.js +++ b/netwerk/test/unit/test_multipart_set_cookie.js @@ -63,7 +63,7 @@ var multipartListener = { "nsIRequestObserver", ]), - onStartRequest(request) { + onStartRequest() { this._buffer = ""; }, @@ -76,7 +76,7 @@ var multipartListener = { } }, - onStopRequest(request, status) { + onStopRequest(request) { try { responseHandler(request, this._buffer); } catch (ex) { diff --git a/netwerk/test/unit/test_standardurl.js b/netwerk/test/unit/test_standardurl.js index cf3f736929..b44289f2e6 100644 --- a/netwerk/test/unit/test_standardurl.js +++ b/netwerk/test/unit/test_standardurl.js @@ -1051,3 +1051,13 @@ add_task(async function test_bug1648493() { equal(url.spec, "t://%C3%83%C2%A7:%C3%83%C2%AA@example.com/"); equal(url.username, "%C3%83%C2%A7"); }); + +add_task(async function test_bug1873976() { + let url = Services.io.newURI("file:."); + equal(url.spec, "file:///"); +}); + +add_task(async function test_bug1890346() { + let url = Services.io.newURI("file:..?/.."); + equal(url.spec, "file:///?/.."); +}); diff --git a/netwerk/test/unit/xpcshell.toml b/netwerk/test/unit/xpcshell.toml index fb3791963d..c86a1759e7 100644 --- a/netwerk/test/unit/xpcshell.toml +++ b/netwerk/test/unit/xpcshell.toml @@ -484,6 +484,7 @@ skip-if = ["os == 'linux' && bits == 64 && !debug"] #Bug 1553353 ["test_cookies_partition_counting.js"] ["test_cookies_privatebrowsing.js"] +skip-if = ["os == 'android' && fission"] # Bug 1888227 ["test_cookies_profile_close.js"] skip-if = ["os == 'android'"] # Bug 1700483 @@ -1275,3 +1276,7 @@ skip-if = [ ] ["test_xmlhttprequest.js"] + +["test_connection_coalescing.js"] + +["test_default_uri_bypass.js"] diff --git a/netwerk/test/unit_ipc/test_default_uri_bypass_wrap.js b/netwerk/test/unit_ipc/test_default_uri_bypass_wrap.js new file mode 100644 index 0000000000..82c8e730f8 --- /dev/null +++ b/netwerk/test/unit_ipc/test_default_uri_bypass_wrap.js @@ -0,0 +1,13 @@ +function run_test() { + Services.prefs.setBoolPref("network.url.useDefaultURI", true); + Services.prefs.setBoolPref( + "network.url.some_schemes_bypass_defaultURI_fallback", + true + ); + Services.prefs.setCharPref( + "network.url.simple_uri_schemes", + "simpleprotocol,otherproto" + ); + + run_test_in_child("../unit/test_default_uri_bypass.js"); +} diff --git a/netwerk/test/unit_ipc/test_http3_prio_disabled_wrap.js b/netwerk/test/unit_ipc/test_http3_prio_disabled_wrap.js index 38988cd450..8704484d13 100644 --- a/netwerk/test/unit_ipc/test_http3_prio_disabled_wrap.js +++ b/netwerk/test/unit_ipc/test_http3_prio_disabled_wrap.js @@ -4,6 +4,7 @@ registerCleanupFunction(async () => { Services.prefs.clearUserPref("network.http.http3.priority"); + Services.prefs.clearUserPref("network.http.priority_header.enabled"); http3_clear_prefs(); }); @@ -15,6 +16,7 @@ add_task(async function setup() { async function run_test() { // test priority urgency and incremental with priority disabled Services.prefs.setBoolPref("network.http.http3.priority", false); + Services.prefs.setBoolPref("network.http.priority_header.enabled", false); run_test_in_child("../unit/test_http3_prio_disabled.js"); run_next_test(); // only pumps next async task from this file } diff --git a/netwerk/test/unit_ipc/test_http3_prio_enabled_wrap.js b/netwerk/test/unit_ipc/test_http3_prio_enabled_wrap.js index dcff09fcba..664869f2f5 100644 --- a/netwerk/test/unit_ipc/test_http3_prio_enabled_wrap.js +++ b/netwerk/test/unit_ipc/test_http3_prio_enabled_wrap.js @@ -4,6 +4,7 @@ registerCleanupFunction(async () => { Services.prefs.clearUserPref("network.http.http3.priority"); + Services.prefs.clearUserPref("network.http.priority_header.enabled"); http3_clear_prefs(); }); @@ -15,6 +16,7 @@ add_task(async function setup() { async function run_test() { // test priority urgency and incremental with priority enabled Services.prefs.setBoolPref("network.http.http3.priority", true); + Services.prefs.setBoolPref("network.http.priority_header.enabled", true); run_test_in_child("../unit/test_http3_prio_enabled.js"); run_next_test(); // only pumps next async task from this file } diff --git a/netwerk/test/unit_ipc/xpcshell.toml b/netwerk/test/unit_ipc/xpcshell.toml index 24c84d745d..bc53e4ce74 100644 --- a/netwerk/test/unit_ipc/xpcshell.toml +++ b/netwerk/test/unit_ipc/xpcshell.toml @@ -70,6 +70,7 @@ support-files = [ "!/netwerk/test/unit/test_http3_prio_helpers.js", "!/netwerk/test/unit/http2-ca.pem", "!/netwerk/test/unit/test_orb_empty_header.js", + "!/netwerk/test/unit/test_default_uri_bypass.js", "child_is_proxy_used.js", "child_cookie_header.js", "child_dns_by_type_resolve.js", @@ -239,3 +240,6 @@ skip-if = ["os == 'android'"] ["test_xmlhttprequest_wrap.js"] prefs = ["network.allow_raw_sockets_in_content_processes=true"] + +["test_default_uri_bypass_wrap.js"] +prefs = ["network.allow_raw_sockets_in_content_processes=true"] |