icecat: add release icecat-140.10.1-1gnu1 for ecne

This commit is contained in:
Ark74 2026-05-04 16:58:41 -06:00
parent a5f93cb214
commit ff85d7c623
1256 changed files with 63469 additions and 24141 deletions

View file

@ -34,7 +34,7 @@ BackgroundChannelRegistrar::~BackgroundChannelRegistrar() {
}
// static
already_AddRefed<nsIBackgroundChannelRegistrar>
already_AddRefed<BackgroundChannelRegistrar>
BackgroundChannelRegistrar::GetOrCreate() {
if (!gSingleton) {
gSingleton = new BackgroundChannelRegistrar();
@ -57,8 +57,22 @@ void BackgroundChannelRegistrar::NotifyChannelLinked(
void BackgroundChannelRegistrar::DeleteChannel(uint64_t aKey) {
MOZ_ASSERT(NS_IsMainThread());
mChannels.Remove(aKey);
mBgChannels.Remove(aKey);
RefPtr<HttpChannelParent> channel;
mChannels.Remove(aKey, getter_AddRefs(channel));
RefPtr<HttpBackgroundChannelParent> bgChannel;
mBgChannels.Remove(aKey, getter_AddRefs(bgChannel));
}
void BackgroundChannelRegistrar::DeleteChannelIfMatches(
uint64_t aKey, HttpChannelParent* aExpected) {
MOZ_ASSERT(NS_IsMainThread());
RefPtr<HttpChannelParent> channel;
if (mChannels.GetWeak(aKey) == aExpected) {
mChannels.Remove(aKey, getter_AddRefs(channel));
}
RefPtr<HttpBackgroundChannelParent> bgChannel;
mBgChannels.Remove(aKey, getter_AddRefs(bgChannel));
}
void BackgroundChannelRegistrar::LinkHttpChannel(uint64_t aKey,

View file

@ -29,12 +29,19 @@ class BackgroundChannelRegistrar final : public nsIBackgroundChannelRegistrar {
explicit BackgroundChannelRegistrar();
// Singleton accessor
static already_AddRefed<nsIBackgroundChannelRegistrar> GetOrCreate();
// Singleton accessors
static already_AddRefed<BackgroundChannelRegistrar> GetOrCreate();
private:
virtual ~BackgroundChannelRegistrar();
// Like DeleteChannel, but only removes the mChannels entry if it matches
// aExpected. Use this in preference to DeleteChannel when the caller knows
// which HttpChannelParent it registered, to avoid accidentally removing an
// entry belonging to a different object that shares the same channel Id.
void DeleteChannelIfMatches(uint64_t aKey, HttpChannelParent* aExpected);
friend class HttpChannelParent;
// A helper function for BackgroundChannelRegistrar itself to callback
// HttpChannelParent and HttpBackgroundChannelParent when both objects are
// ready. aChannelParent and aBgParent is the pair of HttpChannelParent and

View file

@ -10,11 +10,7 @@ namespace mozilla {
namespace net {
BackgroundDataBridgeParent::BackgroundDataBridgeParent(uint64_t aChannelID)
: mChannelID(aChannelID), mBackgroundThread(GetCurrentSerialEventTarget()) {
if (SocketProcessChild* child = SocketProcessChild::GetSingleton()) {
child->AddDataBridgeToMap(aChannelID, this);
}
}
: mChannelID(aChannelID), mBackgroundThread(GetCurrentSerialEventTarget()) {}
void BackgroundDataBridgeParent::ActorDestroy(ActorDestroyReason aWhy) {
if (SocketProcessChild* child = SocketProcessChild::GetSingleton()) {
@ -22,6 +18,16 @@ void BackgroundDataBridgeParent::ActorDestroy(ActorDestroyReason aWhy) {
}
}
already_AddRefed<BackgroundDataBridgeParent>
BackgroundDataBridgeParent::Create(uint64_t aChannelID) {
RefPtr<BackgroundDataBridgeParent> actor =
new BackgroundDataBridgeParent(aChannelID);
if (SocketProcessChild* child = SocketProcessChild::GetSingleton()) {
child->AddDataBridgeToMap(aChannelID, actor);
}
return actor.forget();
}
already_AddRefed<nsISerialEventTarget>
BackgroundDataBridgeParent::GetBackgroundThread() {
return do_AddRef(mBackgroundThread);

View file

@ -14,7 +14,7 @@ class BackgroundDataBridgeParent final : public PBackgroundDataBridgeParent {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(BackgroundDataBridgeParent, override)
explicit BackgroundDataBridgeParent(uint64_t aChannelID);
static already_AddRefed<BackgroundDataBridgeParent> Create(uint64_t aChannelID);
void ActorDestroy(ActorDestroyReason aWhy) override;
already_AddRefed<nsISerialEventTarget> GetBackgroundThread();
void Destroy();
@ -24,6 +24,7 @@ class BackgroundDataBridgeParent final : public PBackgroundDataBridgeParent {
const TimeStamp& aOnStopRequestStart);
private:
explicit BackgroundDataBridgeParent(uint64_t aChannelID);
virtual ~BackgroundDataBridgeParent() = default;
uint64_t mChannelID;

View file

@ -271,12 +271,15 @@ void HttpChannelParent::CleanupBackgroundChannel() {
}
// This HttpChannelParent might still have a reference from
// BackgroundChannelRegistrar.
nsCOMPtr<nsIBackgroundChannelRegistrar> registrar =
// BackgroundChannelRegistrar. Only remove our own entry; another
// HttpChannelParent may have been registered under the same channel Id
// (e.g. after a redirect), and we must not remove that entry.
RefPtr<BackgroundChannelRegistrar> registrar =
BackgroundChannelRegistrar::GetOrCreate();
MOZ_ASSERT(registrar);
registrar->DeleteChannel(mChannel->ChannelId());
if (registrar) {
registrar->DeleteChannelIfMatches(mChannel->ChannelId(), this);
}
// If mAsyncOpenBarrier is greater than zero, it means AsyncOpen procedure
// is still on going. we need to abort AsyncOpen with failure to destroy
@ -980,6 +983,11 @@ HttpChannelParent::ContinueVerification(
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aCallback);
if (mIPCClosed) {
aCallback->ReadyToVerify(NS_ERROR_FAILURE);
return NS_OK;
}
// Continue the verification procedure if background channel is ready.
if (mBgParent) {
aCallback->ReadyToVerify(NS_OK);

View file

@ -18,6 +18,7 @@
#include "nsIThreadRetargetableStreamListener.h"
#include "nsITransportSecurityInfo.h"
#include "nsNetUtil.h"
#include "nsProxyRelease.h"
#include "nsQueryObject.h"
#include "nsSerializationHelper.h"
#include "nsStreamUtils.h"
@ -36,11 +37,31 @@ NS_INTERFACE_MAP_END
NS_IMETHODIMP_(MozExternalRefCountType) HttpTransactionParent::Release(void) {
MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release");
if (!NS_IsMainThread()) {
// Use DecrementWithLimit to atomically decrement only while count > 2.
// This ensures a background thread never drops the count to 1 or 0,
// avoiding the race where the main thread frees the object (via
// ActorDisconnected) between our decrement and the count==1 handling.
auto [success, count] = mRefCnt.DecrementWithLimit<2>();
if (success) {
NS_LOG_RELEASE(this, count, "HttpTransactionParent");
return count;
}
// mRefCnt <= 2: the next decrement could trigger Send__delete__ or
// deletion, both of which must happen on the main thread. Transfer
// our reference there without decrementing.
NS_ProxyRelease("HttpTransactionParent::Release",
GetMainThreadSerialEventTarget(),
dont_AddRef(static_cast<nsIRequest*>(this)));
return 1;
}
nsrefcnt count = --mRefCnt;
NS_LOG_RELEASE(this, count, "HttpTransactionParent");
if (count == 0) {
mRefCnt = 1; /* stabilize */
delete (this);
delete this;
return 0;
}
@ -48,17 +69,7 @@ NS_IMETHODIMP_(MozExternalRefCountType) HttpTransactionParent::Release(void) {
// we are done with this transaction. We should send a delete message
// to delete the transaction child in socket process.
if (count == 1 && CanSend()) {
if (!NS_IsMainThread()) {
RefPtr<HttpTransactionParent> self = this;
MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(
NS_NewRunnableFunction("HttpTransactionParent::Release", [self]() {
mozilla::Unused << self->Send__delete__(self);
// Make sure we can not send IPC after Send__delete__().
MOZ_ASSERT(!self->CanSend());
})));
} else {
mozilla::Unused << Send__delete__(this);
}
mozilla::Unused << Send__delete__(this);
return 1;
}
return count;

View file

@ -525,6 +525,9 @@ NS_IMETHODIMP
ObliviousHttpChannel::AsyncOpen(nsIStreamListener* aListener) {
LOG(("ObliviousHttpChannel::AsyncOpen [this=%p, listener=%p]", this,
aListener));
if (mStreamListener) {
return NS_ERROR_ALREADY_OPENED;
}
mStreamListener = aListener;
nsresult rv = mInnerChannel->SetRequestMethod("POST"_ns);
if (NS_FAILED(rv)) {
@ -728,7 +731,8 @@ nsresult ObliviousHttpChannel::ProcessOnStopRequest() {
getter_AddRefs(mBinaryHttpResponse));
}
void ObliviousHttpChannel::EmitOnDataAvailable() {
void ObliviousHttpChannel::EmitOnDataAvailable(
nsIStreamListener* aStreamListener) {
if (!mBinaryHttpResponse) {
return;
}
@ -749,7 +753,7 @@ void ObliviousHttpChannel::EmitOnDataAvailable() {
if (NS_FAILED(rv)) {
return;
}
rv = mStreamListener->OnDataAvailable(this, contentStream, 0, contentLength);
rv = aStreamListener->OnDataAvailable(this, contentStream, 0, contentLength);
Unused << rv;
}
@ -759,8 +763,7 @@ ObliviousHttpChannel::OnStopRequest(nsIRequest* aRequest,
LOG(("ObliviousHttpChannel::OnStopRequest [this=%p, request=%p, status=%u]",
this, aRequest, (uint32_t)aStatusCode));
auto releaseStreamListener = MakeScopeExit(
[self = RefPtr{this}]() mutable { self->mStreamListener = nullptr; });
nsCOMPtr<nsIStreamListener> listener = std::move(mStreamListener);
if (NS_SUCCEEDED(aStatusCode)) {
bool requestSucceeded;
@ -769,11 +772,11 @@ ObliviousHttpChannel::OnStopRequest(nsIRequest* aRequest,
aStatusCode = ProcessOnStopRequest();
}
}
Unused << mStreamListener->OnStartRequest(this);
Unused << listener->OnStartRequest(this);
if (NS_SUCCEEDED(aStatusCode)) {
EmitOnDataAvailable();
EmitOnDataAvailable(listener);
}
Unused << mStreamListener->OnStopRequest(this, aStatusCode);
Unused << listener->OnStopRequest(this, aStatusCode);
return NS_OK;
}

View file

@ -47,7 +47,7 @@ class ObliviousHttpChannel final : public nsIObliviousHttpChannel,
~ObliviousHttpChannel();
nsresult ProcessOnStopRequest();
void EmitOnDataAvailable();
void EmitOnDataAvailable(nsIStreamListener*);
nsCOMPtr<nsIURI> mTargetURI;
nsTArray<uint8_t> mEncodedConfig;

View file

@ -53,12 +53,18 @@ ReplacedHttpResponse::SetResponseBody(const nsACString& aResponseBody) {
NS_IMETHODIMP
ReplacedHttpResponse::SetResponseHeader(const nsACString& header,
const nsACString& value, bool merge) {
if (mInVisitHeaders) {
return NS_ERROR_FAILURE;
}
return mResponseHeaders.SetHeader(header, value, merge,
nsHttpHeaderArray::eVarietyResponse);
}
NS_IMETHODIMP
ReplacedHttpResponse::VisitResponseHeaders(nsIHttpHeaderVisitor* visitor) {
return mResponseHeaders.VisitHeaders(visitor);
mInVisitHeaders = true;
nsresult rv = mResponseHeaders.VisitHeaders(visitor);
mInVisitHeaders = false;
return rv;
}
} // namespace mozilla::net

View file

@ -7,6 +7,7 @@
#include "nsString.h"
#include "nsHttpHeaderArray.h"
#include "nsIReplacedHttpResponse.h"
#include "mozilla/Atomics.h"
namespace mozilla::net {
@ -24,6 +25,7 @@ class ReplacedHttpResponse : nsIReplacedHttpResponse {
nsCString mResponseStatusText;
nsCString mResponseBody;
nsHttpHeaderArray mResponseHeaders;
Atomic<bool> mInVisitHeaders{false};
};
} // namespace mozilla::net

View file

@ -508,8 +508,16 @@ TLSTransportLayer::OpenOutputStream(uint32_t aFlags, uint32_t aSegmentSize,
NS_IMETHODIMP
TLSTransportLayer::Close(nsresult aReason) {
LOG(("TLSTransportLayer::Close [this=%p reason=%" PRIx32 "]\n", this,
static_cast<uint32_t>(aReason)));
bool onSocketThread = OnSocketThread();
LOG(("TLSTransportLayer::Close [this=%p reason=%" PRIx32 "] sts=%d", this,
static_cast<uint32_t>(aReason), onSocketThread));
if (!onSocketThread) {
gSocketTransportService->Dispatch(NS_NewRunnableFunction(
"TLSTransportLayer::Close",
[self = RefPtr{this}, aReason] { self->Close(aReason); }));
return NS_OK;
}
mInputCallback = nullptr;
mOutputCallback = nullptr;

View file

@ -33,6 +33,7 @@ nsHttpActivityDistributor::ObserveActivity(nsISupports* aHttpChannel,
uint64_t aExtraSizeData,
const nsACString& aExtraStringData) {
MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
RefPtr<nsHttpActivityDistributor> self(this);
for (size_t i = 0; i < mObservers.Length(); i++) {
Unused << mObservers[i]->ObserveActivity(aHttpChannel, aActivityType,
@ -48,6 +49,7 @@ nsHttpActivityDistributor::ObserveConnectionActivity(
bool aIsHttp3, uint32_t aActivityType, uint32_t aActivitySubtype,
PRTime aTimestamp, const nsACString& aExtraStringData) {
MOZ_ASSERT(XRE_IsParentProcess() && NS_IsMainThread());
RefPtr<nsHttpActivityDistributor> self(this);
for (size_t i = 0; i < mObservers.Length(); i++) {
Unused << mObservers[i]->ObserveConnectionActivity(

View file

@ -354,6 +354,7 @@ nsHttpChannel::nsHttpChannel() : HttpAsyncAborter<nsHttpChannel>(this) {
}
nsHttpChannel::~nsHttpChannel() {
MOZ_ASSERT(NS_IsMainThread(), "Must be released on main thread");
PROFILER_MARKER("~nsHttpChannel", NETWORK, {}, TerminatingFlowMarker,
Flow::FromPointer(this));
LOG(("Destroying nsHttpChannel [this=%p, nsIChannel=%p]\n", this,
@ -373,42 +374,11 @@ nsHttpChannel::~nsHttpChannel() {
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
ReleaseMainThreadOnlyReferences();
if (gHttpHandler) {
gHttpHandler->RemoveHttpChannel(mChannelId);
}
}
void nsHttpChannel::ReleaseMainThreadOnlyReferences() {
if (NS_IsMainThread()) {
// Already on main thread, let dtor to
// take care of releasing references
return;
}
nsTArray<nsCOMPtr<nsISupports>> arrayToRelease;
arrayToRelease.AppendElement(mAuthProvider.forget());
arrayToRelease.AppendElement(mRedirectChannel.forget());
arrayToRelease.AppendElement(mPreflightChannel.forget());
arrayToRelease.AppendElement(mDNSPrefetch.forget());
MOZ_DIAGNOSTIC_ASSERT(
!mEarlyHintObserver,
"Early hint observer should have been released in ReleaseListeners()");
arrayToRelease.AppendElement(mEarlyHintObserver.forget());
MOZ_DIAGNOSTIC_ASSERT(
!mChannelClassifier,
"Channel classifier should have been released in ReleaseListeners()");
arrayToRelease.AppendElement(
mChannelClassifier.forget().downcast<nsIURIClassifierCallback>());
MOZ_DIAGNOSTIC_ASSERT(
!mWarningReporter,
"Warning reporter should have been released in ReleaseListeners()");
arrayToRelease.AppendElement(mWarningReporter.forget());
NS_DispatchToMainThread(new ProxyReleaseRunnable(std::move(arrayToRelease)));
}
nsresult nsHttpChannel::Init(nsIURI* uri, uint32_t caps, nsProxyInfo* proxyInfo,
uint32_t proxyResolveFlags, nsIURI* proxyURI,
uint64_t channelId,
@ -6229,7 +6199,29 @@ NS_IMETHODIMP nsHttpChannel::ConnectionRestartable(bool aRestartable) {
//-----------------------------------------------------------------------------
NS_IMPL_ADDREF_INHERITED(nsHttpChannel, HttpBaseChannel)
NS_IMPL_RELEASE_INHERITED(nsHttpChannel, HttpBaseChannel)
bool nsHttpChannel::DispatchRelease() {
if (NS_IsMainThread()) {
return false;
}
NS_DispatchToMainThread(
NewNonOwningRunnableMethod("net::nsHttpChannel::Release", this,
&nsHttpChannel::Release),
NS_DISPATCH_NORMAL);
return true;
}
NS_IMETHODIMP_(MozExternalRefCountType)
nsHttpChannel::Release() {
nsrefcnt count = mRefCnt - 1;
if (DispatchRelease()) {
// Redispatched to the main thread.
return count;
}
NS_IMPL_RELEASE_INHERITED_GUTS(nsHttpChannel, HttpBaseChannel);
}
NS_INTERFACE_MAP_BEGIN(nsHttpChannel)
NS_INTERFACE_MAP_ENTRY(nsIRequest)
@ -6661,6 +6653,10 @@ nsHttpChannel::GetSecurityInfo(nsITransportSecurityInfo** securityInfo) {
// any error.
NS_IMETHODIMP
nsHttpChannel::AsyncOpen(nsIStreamListener* aListener) {
// doContentSecurityCheck and OnOpeningRequest fire observers that may
// spin nested event loops; hold a strong ref to this.
RefPtr<nsHttpChannel> self(this);
AUTO_PROFILER_FLOW_MARKER("nsHttpChannel::AsyncOpen", NETWORK,
Flow::FromPointer(this));
nsCOMPtr<nsIStreamListener> listener = aListener;
@ -11322,9 +11318,11 @@ nsHttpChannel::EarlyHint(const nsACString& aLinkHeader,
const nsACString& aCspHeader) {
LOG(("nsHttpChannel::EarlyHint.\n"));
if (mEarlyHintObserver && nsContentUtils::ComputeIsSecureContext(this)) {
LOG(("nsHttpChannel::EarlyHint propagated.\n"));
mEarlyHintObserver->EarlyHint(aLinkHeader, aReferrerPolicy, aCspHeader);
if (nsCOMPtr<nsIEarlyHintObserver> obs = mEarlyHintObserver) {
if (nsContentUtils::ComputeIsSecureContext(this)) {
LOG(("nsHttpChannel::EarlyHint propagated.\n"));
obs->EarlyHint(aLinkHeader, aReferrerPolicy, aCspHeader);
}
}
return NS_OK;
}

View file

@ -306,6 +306,7 @@ class nsHttpChannel final : public HttpBaseChannel,
// Based on the proxy configuration determine the strategy for resolving the
// end server host name.
ProxyDNSStrategy GetProxyDNSStrategy();
bool DispatchRelease();
// We might synchronously or asynchronously call BeginConnect,
// which includes DNS prefetch and speculative connection, according to
@ -521,8 +522,9 @@ class nsHttpChannel final : public HttpBaseChannel,
void SetCachedContentType();
private:
// this section is for main-thread-only object
// all the references need to be proxy released on main thread.
// --- MAIN THREAD ONLY OBJECTS ---
// this section is for main-thread-only objects
// all the references need to be released on main thread.
// auth specific data
nsCOMPtr<nsIHttpChannelAuthProvider> mAuthProvider;
nsCOMPtr<nsIURI> mRedirectURI;
@ -537,8 +539,7 @@ class nsHttpChannel final : public HttpBaseChannel,
// state of whether tracking protection is enabled or not.
RefPtr<nsChannelClassifier> mChannelClassifier;
// Proxy release all members above on main thread.
void ReleaseMainThreadOnlyReferences();
// --- END OF MAIN THREAD ONLY OBJECTS SECTION ---
// Called after the channel is made aware of its tracking status in order
// to readjust the referrer if needed according to the referrer default
@ -851,7 +852,7 @@ class nsHttpChannel final : public HttpBaseChannel,
private: // cache telemetry
bool mDidReval{false};
RefPtr<nsIEarlyHintObserver> mEarlyHintObserver;
nsCOMPtr<nsIEarlyHintObserver> mEarlyHintObserver;
Maybe<nsCString> mOpenerCallingScriptLocation;
RefPtr<WebTransportSessionEventListener> mWebTransportSessionEventListener;
nsMainThreadPtrHandle<nsIReplacedHttpResponse> mOverrideResponse;

View file

@ -616,7 +616,8 @@ nsresult nsHttpConnection::Activate(nsAHttpTransaction* trans, uint32_t caps,
rv = OnOutputStreamReady(mSocketOut);
if (NS_SUCCEEDED(rv) && mContinueHandshakeDone) {
mContinueHandshakeDone();
auto continuation = std::move(mContinueHandshakeDone);
continuation();
}
mContinueHandshakeDone = nullptr;

View file

@ -2688,13 +2688,13 @@ void nsHttpHandler::ExcludeHttp2OrHttp3Internal(
MOZ_ASSERT_IF(!nsIOService::UseSocketProcess(), OnSocketThread());
if (ci->IsHttp3()) {
if (!mExcludedHttp3Origins.Contains(ci->GetRoutedHost())) {
{
MutexAutoLock lock(mHttpExclusionLock);
mExcludedHttp3Origins.Insert(ci->GetRoutedHost());
}
mConnMgr->ExcludeHttp3(ci);
} else {
if (!mExcludedHttp2Origins.Contains(ci->GetOrigin())) {
{
MutexAutoLock lock(mHttpExclusionLock);
mExcludedHttp2Origins.Insert(ci->GetOrigin());
}

View file

@ -803,7 +803,7 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
"nsHttpConnectionMgr::LastActiveTabLoadOptimization"};
TimeStamp mLastActiveTabLoadOptimizationHit;
Mutex mHttpExclusionLock MOZ_UNANNOTATED{"nsHttpHandler::HttpExclusion"};
Mutex mHttpExclusionLock{"nsHttpHandler::HttpExclusion"};
public:
[[nodiscard]] nsresult NewChannelId(uint64_t& channelId);
@ -826,8 +826,10 @@ class nsHttpHandler final : public nsIHttpProtocolHandler,
#endif
private:
nsTHashSet<nsCString> mExcludedHttp2Origins;
nsTHashSet<nsCString> mExcludedHttp3Origins;
nsTHashSet<nsCString> mExcludedHttp2Origins
MOZ_GUARDED_BY(mHttpExclusionLock);
nsTHashSet<nsCString> mExcludedHttp3Origins
MOZ_GUARDED_BY(mHttpExclusionLock);
nsTHashSet<nsCString> mExcluded0RttTcpOrigins;
// A set of hosts that we should not upgrade to HTTPS with HTTPS RR.
nsTHashSet<nsCString> mExcludedHostsForHTTPSRRUpgrade;

View file

@ -208,8 +208,8 @@ nsresult nsHttpTransaction::Init(
if (NS_FAILED(rv)) return rv;
mConnInfo = cinfo;
mFinalizedConnInfo = cinfo;
mConnInfo = cinfo->Clone();
mFinalizedConnInfo = mConnInfo;
mCallbacks = callbacks;
mConsumerTarget = target;
mCaps = caps;