icecat: add release icecat-140.10.1-1gnu1 for ecne
This commit is contained in:
parent
a5f93cb214
commit
ff85d7c623
1256 changed files with 63469 additions and 24141 deletions
|
|
@ -1,457 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=4 sw=2 sts=2 et tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "GIOChannelChild.h"
|
||||
#include "nsGIOProtocolHandler.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/BrowserChild.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIBrowserChild.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "mozilla/ipc/IPCStreamUtils.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
#include "SerializedLoadContext.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "nsIURIMutator.h"
|
||||
#include "nsContentSecurityManager.h"
|
||||
#include "SerializedLoadContext.h"
|
||||
#include "mozilla/Logging.h"
|
||||
|
||||
using mozilla::dom::ContentChild;
|
||||
|
||||
namespace mozilla {
|
||||
#undef LOG
|
||||
#define LOG(args) MOZ_LOG(gGIOLog, mozilla::LogLevel::Debug, args)
|
||||
namespace net {
|
||||
|
||||
GIOChannelChild::GIOChannelChild(nsIURI* aUri)
|
||||
: mEventQ(new ChannelEventQueue(static_cast<nsIChildChannel*>(this))) {
|
||||
SetURI(aUri);
|
||||
// We could support thread retargeting, but as long as we're being driven by
|
||||
// IPDL on the main thread it doesn't buy us anything.
|
||||
DisallowThreadRetargeting();
|
||||
}
|
||||
|
||||
void GIOChannelChild::AddIPDLReference() {
|
||||
MOZ_ASSERT(!mIPCOpen, "Attempt to retain more than one IPDL reference");
|
||||
mIPCOpen = true;
|
||||
AddRef();
|
||||
}
|
||||
|
||||
void GIOChannelChild::ReleaseIPDLReference() {
|
||||
MOZ_ASSERT(mIPCOpen, "Attempt to release nonexistent IPDL reference");
|
||||
mIPCOpen = false;
|
||||
Release();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GIOChannelChild::nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(GIOChannelChild, nsBaseChannel, nsIChildChannel)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelChild::AsyncOpen(nsIStreamListener* aListener) {
|
||||
nsCOMPtr<nsIStreamListener> listener = aListener;
|
||||
nsresult rv =
|
||||
nsContentSecurityManager::doContentSecurityCheck(this, listener);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
LOG(("GIOChannelChild::AsyncOpen [this=%p]\n", this));
|
||||
|
||||
NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(
|
||||
!static_cast<ContentChild*>(gNeckoChild->Manager())->IsShuttingDown(),
|
||||
NS_ERROR_FAILURE);
|
||||
NS_ENSURE_ARG_POINTER(listener);
|
||||
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
||||
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
|
||||
|
||||
// Port checked in parent, but duplicate here so we can return with error
|
||||
// immediately, as we've done since before e10s.
|
||||
rv = NS_CheckPortSafety(nsBaseChannel::URI()); // Need to disambiguate,
|
||||
// because in the child ipdl,
|
||||
// a typedef URI is defined...
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mozilla::dom::BrowserChild* browserChild = nullptr;
|
||||
nsCOMPtr<nsIBrowserChild> iBrowserChild;
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
|
||||
NS_GET_IID(nsIBrowserChild),
|
||||
getter_AddRefs(iBrowserChild));
|
||||
GetCallback(iBrowserChild);
|
||||
if (iBrowserChild) {
|
||||
browserChild =
|
||||
static_cast<mozilla::dom::BrowserChild*>(iBrowserChild.get());
|
||||
}
|
||||
|
||||
mListener = listener;
|
||||
|
||||
// add ourselves to the load group.
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->AddRequest(this, nullptr);
|
||||
}
|
||||
|
||||
Maybe<mozilla::ipc::IPCStream> ipcStream;
|
||||
mozilla::ipc::SerializeIPCStream(do_AddRef(mUploadStream), ipcStream,
|
||||
/* aAllowLazy */ false);
|
||||
|
||||
uint32_t loadFlags = 0;
|
||||
GetLoadFlags(&loadFlags);
|
||||
|
||||
GIOChannelOpenArgs openArgs;
|
||||
SerializeURI(nsBaseChannel::URI(), openArgs.uri());
|
||||
openArgs.startPos() = mStartPos;
|
||||
openArgs.entityID() = mEntityID;
|
||||
openArgs.uploadStream() = ipcStream;
|
||||
openArgs.loadFlags() = loadFlags;
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo = LoadInfo();
|
||||
rv = mozilla::ipc::LoadInfoToLoadInfoArgs(loadInfo, &openArgs.loadInfo());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// This must happen before the constructor message is sent.
|
||||
SetupNeckoTarget();
|
||||
|
||||
// The socket transport layer in the chrome process now has a logical ref to
|
||||
// us until OnStopRequest is called.
|
||||
AddIPDLReference();
|
||||
|
||||
if (!gNeckoChild->SendPGIOChannelConstructor(
|
||||
this, browserChild, IPC::SerializedLoadContext(this), openArgs)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mIsPending = true;
|
||||
mWasOpened = true;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelChild::IsPending(bool* aResult) {
|
||||
*aResult = mIsPending;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult GIOChannelChild::OpenContentStream(bool aAsync,
|
||||
nsIInputStream** aStream,
|
||||
nsIChannel** aChannel) {
|
||||
MOZ_CRASH("GIOChannel*Child* should never have OpenContentStream called!");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult GIOChannelChild::RecvOnStartRequest(
|
||||
const nsresult& aChannelStatus, const int64_t& aContentLength,
|
||||
const nsACString& aContentType, const nsACString& aEntityID,
|
||||
const URIParams& aURI) {
|
||||
LOG(("GIOChannelChild::RecvOnStartRequest [this=%p]\n", this));
|
||||
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
||||
this, [self = UnsafePtr<GIOChannelChild>(this), aChannelStatus,
|
||||
aContentLength, aContentType = nsCString(aContentType),
|
||||
aEntityID = nsCString(aEntityID), aURI]() {
|
||||
self->DoOnStartRequest(aChannelStatus, aContentLength, aContentType,
|
||||
aEntityID, aURI);
|
||||
}));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void GIOChannelChild::DoOnStartRequest(const nsresult& aChannelStatus,
|
||||
const int64_t& aContentLength,
|
||||
const nsACString& aContentType,
|
||||
const nsACString& aEntityID,
|
||||
const URIParams& aURI) {
|
||||
LOG(("GIOChannelChild::DoOnStartRequest [this=%p]\n", this));
|
||||
if (!mCanceled && NS_SUCCEEDED(mStatus)) {
|
||||
mStatus = aChannelStatus;
|
||||
}
|
||||
|
||||
mContentLength = aContentLength;
|
||||
SetContentType(aContentType);
|
||||
mEntityID = aEntityID;
|
||||
|
||||
nsCString spec;
|
||||
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
|
||||
nsresult rv = uri->GetSpec(spec);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Changes nsBaseChannel::URI()
|
||||
rv = NS_MutateURI(mURI).SetSpec(spec).Finalize(mURI);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
}
|
||||
|
||||
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
||||
rv = mListener->OnStartRequest(this);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult GIOChannelChild::RecvOnDataAvailable(
|
||||
const nsresult& aChannelStatus, const nsACString& aData,
|
||||
const uint64_t& aOffset, const uint32_t& aCount) {
|
||||
LOG(("GIOChannelChild::RecvOnDataAvailable [this=%p]\n", this));
|
||||
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
||||
this, [self = UnsafePtr<GIOChannelChild>(this), aChannelStatus,
|
||||
aData = nsCString(aData), aOffset, aCount]() {
|
||||
self->DoOnDataAvailable(aChannelStatus, aData, aOffset, aCount);
|
||||
}));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void GIOChannelChild::DoOnDataAvailable(const nsresult& aChannelStatus,
|
||||
const nsACString& aData,
|
||||
const uint64_t& aOffset,
|
||||
const uint32_t& aCount) {
|
||||
LOG(("GIOChannelChild::DoOnDataAvailable [this=%p]\n", this));
|
||||
|
||||
if (!mCanceled && NS_SUCCEEDED(mStatus)) {
|
||||
mStatus = aChannelStatus;
|
||||
}
|
||||
|
||||
if (mCanceled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// NOTE: the OnDataAvailable contract requires the client to read all the data
|
||||
// in the inputstream. This code relies on that ('data' will go away after
|
||||
// this function). Apparently the previous, non-e10s behavior was to actually
|
||||
// support only reading part of the data, allowing later calls to read the
|
||||
// rest.
|
||||
nsCOMPtr<nsIInputStream> stringStream;
|
||||
nsresult rv =
|
||||
NS_NewByteInputStream(getter_AddRefs(stringStream),
|
||||
Span(aData).To(aCount), NS_ASSIGNMENT_DEPEND);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
return;
|
||||
}
|
||||
|
||||
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
||||
rv = mListener->OnDataAvailable(this, stringStream, aOffset, aCount);
|
||||
if (NS_FAILED(rv)) {
|
||||
Cancel(rv);
|
||||
}
|
||||
stringStream->Close();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult GIOChannelChild::RecvOnStopRequest(
|
||||
const nsresult& aChannelStatus) {
|
||||
LOG(("GIOChannelChild::RecvOnStopRequest [this=%p status=%" PRIx32 "]\n",
|
||||
this, static_cast<uint32_t>(aChannelStatus)));
|
||||
|
||||
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
||||
this, [self = UnsafePtr<GIOChannelChild>(this), aChannelStatus]() {
|
||||
self->DoOnStopRequest(aChannelStatus);
|
||||
}));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void GIOChannelChild::DoOnStopRequest(const nsresult& aChannelStatus) {
|
||||
LOG(("GIOChannelChild::DoOnStopRequest [this=%p status=%" PRIx32 "]\n", this,
|
||||
static_cast<uint32_t>(aChannelStatus)));
|
||||
|
||||
if (!mCanceled) {
|
||||
mStatus = aChannelStatus;
|
||||
}
|
||||
|
||||
{ // Ensure that all queued ipdl events are dispatched before
|
||||
// we initiate protocol deletion below.
|
||||
mIsPending = false;
|
||||
AutoEventEnqueuer ensureSerialDispatch(mEventQ);
|
||||
(void)mListener->OnStopRequest(this, aChannelStatus);
|
||||
|
||||
mListener = nullptr;
|
||||
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->RemoveRequest(this, nullptr, aChannelStatus);
|
||||
}
|
||||
}
|
||||
|
||||
// This calls NeckoChild::DeallocPGIOChannelChild(), which deletes |this| if
|
||||
// IPDL holds the last reference. Don't rely on |this| existing after here!
|
||||
Send__delete__(this);
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult GIOChannelChild::RecvFailedAsyncOpen(
|
||||
const nsresult& aStatusCode) {
|
||||
LOG(("GIOChannelChild::RecvFailedAsyncOpen [this=%p status=%" PRIx32 "]\n",
|
||||
this, static_cast<uint32_t>(aStatusCode)));
|
||||
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
||||
this, [self = UnsafePtr<GIOChannelChild>(this), aStatusCode]() {
|
||||
self->DoFailedAsyncOpen(aStatusCode);
|
||||
}));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void GIOChannelChild::DoFailedAsyncOpen(const nsresult& aStatusCode) {
|
||||
LOG(("GIOChannelChild::DoFailedAsyncOpen [this=%p status=%" PRIx32 "]\n",
|
||||
this, static_cast<uint32_t>(aStatusCode)));
|
||||
mStatus = aStatusCode;
|
||||
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->RemoveRequest(this, nullptr, aStatusCode);
|
||||
}
|
||||
|
||||
if (mListener) {
|
||||
mListener->OnStartRequest(this);
|
||||
mIsPending = false;
|
||||
mListener->OnStopRequest(this, aStatusCode);
|
||||
} else {
|
||||
mIsPending = false;
|
||||
}
|
||||
|
||||
mListener = nullptr;
|
||||
|
||||
if (mIPCOpen) {
|
||||
Send__delete__(this);
|
||||
}
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult GIOChannelChild::RecvDeleteSelf() {
|
||||
mEventQ->RunOrEnqueue(new NeckoTargetChannelFunctionEvent(
|
||||
this,
|
||||
[self = UnsafePtr<GIOChannelChild>(this)]() { self->DoDeleteSelf(); }));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
void GIOChannelChild::DoDeleteSelf() {
|
||||
if (mIPCOpen) {
|
||||
Send__delete__(this);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GIOChannelChild::nsIResumableChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelChild::Cancel(nsresult aStatus) {
|
||||
LOG(("GIOChannelChild::Cancel [this=%p]\n", this));
|
||||
|
||||
if (mCanceled) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mCanceled = true;
|
||||
mStatus = aStatus;
|
||||
if (mIPCOpen) {
|
||||
SendCancel(aStatus);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelChild::Suspend() {
|
||||
NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
LOG(("GIOChannelChild::Suspend [this=%p]\n", this));
|
||||
|
||||
// SendSuspend only once, when suspend goes from 0 to 1.
|
||||
if (!mSuspendCount++) {
|
||||
SendSuspend();
|
||||
mSuspendSent = true;
|
||||
}
|
||||
mEventQ->Suspend();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelChild::Resume() {
|
||||
NS_ENSURE_TRUE(mIPCOpen, NS_ERROR_NOT_AVAILABLE);
|
||||
|
||||
LOG(("GIOChannelChild::Resume [this=%p]\n", this));
|
||||
|
||||
// SendResume only once, when suspend count drops to 0.
|
||||
if (!--mSuspendCount && mSuspendSent) {
|
||||
SendResume();
|
||||
}
|
||||
mEventQ->Resume();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GIOChannelChild::nsIChildChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelChild::ConnectParent(uint32_t aId) {
|
||||
NS_ENSURE_TRUE((gNeckoChild), NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(
|
||||
!static_cast<ContentChild*>(gNeckoChild->Manager())->IsShuttingDown(),
|
||||
NS_ERROR_FAILURE);
|
||||
|
||||
LOG(("GIOChannelChild::ConnectParent [this=%p]\n", this));
|
||||
|
||||
mozilla::dom::BrowserChild* browserChild = nullptr;
|
||||
nsCOMPtr<nsIBrowserChild> iBrowserChild;
|
||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
|
||||
NS_GET_IID(nsIBrowserChild),
|
||||
getter_AddRefs(iBrowserChild));
|
||||
GetCallback(iBrowserChild);
|
||||
if (iBrowserChild) {
|
||||
browserChild =
|
||||
static_cast<mozilla::dom::BrowserChild*>(iBrowserChild.get());
|
||||
}
|
||||
|
||||
// This must happen before the constructor message is sent.
|
||||
SetupNeckoTarget();
|
||||
|
||||
// The socket transport in the chrome process now holds a logical ref to us
|
||||
// until OnStopRequest, or we do a redirect, or we hit an IPDL error.
|
||||
AddIPDLReference();
|
||||
|
||||
GIOChannelConnectArgs connectArgs(aId);
|
||||
|
||||
if (!gNeckoChild->SendPGIOChannelConstructor(
|
||||
this, browserChild, IPC::SerializedLoadContext(this), connectArgs)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelChild::CompleteRedirectSetup(nsIStreamListener* aListener) {
|
||||
LOG(("GIOChannelChild::CompleteRedirectSetup [this=%p]\n", this));
|
||||
NS_ENSURE_TRUE(!mIsPending, NS_ERROR_IN_PROGRESS);
|
||||
NS_ENSURE_TRUE(!mWasOpened, NS_ERROR_ALREADY_OPENED);
|
||||
|
||||
mIsPending = true;
|
||||
mWasOpened = true;
|
||||
mListener = aListener;
|
||||
|
||||
// add ourselves to the load group.
|
||||
if (mLoadGroup) {
|
||||
mLoadGroup->AddRequest(this, nullptr);
|
||||
}
|
||||
|
||||
// We already have an open IPDL connection to the parent. If on-modify-request
|
||||
// listeners or load group observers canceled us, let the parent handle it
|
||||
// and send it back to us naturally.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void GIOChannelChild::SetupNeckoTarget() {
|
||||
if (mNeckoTarget) {
|
||||
return;
|
||||
}
|
||||
mNeckoTarget = GetMainThreadSerialEventTarget();
|
||||
}
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,111 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=4 sw=2 sts=2 et tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef NS_GIOCHANNELCHILD_H
|
||||
#define NS_GIOCHANNELCHILD_H
|
||||
|
||||
#include "mozilla/net/PGIOChannelChild.h"
|
||||
#include "mozilla/net/ChannelEventQueue.h"
|
||||
#include "nsBaseChannel.h"
|
||||
#include "nsIUploadChannel.h"
|
||||
#include "nsIProxiedChannel.h"
|
||||
#include "nsIResumableChannel.h"
|
||||
#include "nsIChildChannel.h"
|
||||
#include "nsIEventTarget.h"
|
||||
#include "nsIStreamListener.h"
|
||||
|
||||
class nsIEventTarget;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class GIOChannelChild final : public PGIOChannelChild,
|
||||
public nsBaseChannel,
|
||||
public nsIChildChannel {
|
||||
public:
|
||||
using nsIStreamListener = ::nsIStreamListener;
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSICHILDCHANNEL
|
||||
|
||||
NS_IMETHOD Cancel(nsresult aStatus) override;
|
||||
NS_IMETHOD Suspend() override;
|
||||
NS_IMETHOD Resume() override;
|
||||
|
||||
explicit GIOChannelChild(nsIURI* uri);
|
||||
|
||||
void AddIPDLReference();
|
||||
void ReleaseIPDLReference();
|
||||
|
||||
NS_IMETHOD AsyncOpen(nsIStreamListener* aListener) override;
|
||||
|
||||
// Note that we handle this ourselves, overriding the nsBaseChannel
|
||||
// default behavior, in order to be e10s-friendly.
|
||||
NS_IMETHOD IsPending(bool* aResult) override;
|
||||
|
||||
nsresult OpenContentStream(bool aAsync, nsIInputStream** aStream,
|
||||
nsIChannel** aChannel) override;
|
||||
|
||||
bool IsSuspended() const;
|
||||
|
||||
protected:
|
||||
virtual ~GIOChannelChild() = default;
|
||||
|
||||
mozilla::ipc::IPCResult RecvOnStartRequest(const nsresult& aChannelStatus,
|
||||
const int64_t& aContentLength,
|
||||
const nsACString& aContentType,
|
||||
const nsACString& aEntityID,
|
||||
const URIParams& aURI) override;
|
||||
mozilla::ipc::IPCResult RecvOnDataAvailable(const nsresult& aChannelStatus,
|
||||
const nsACString& aData,
|
||||
const uint64_t& aOffset,
|
||||
const uint32_t& aCount) override;
|
||||
mozilla::ipc::IPCResult RecvOnStopRequest(
|
||||
const nsresult& aChannelStatus) override;
|
||||
mozilla::ipc::IPCResult RecvFailedAsyncOpen(
|
||||
const nsresult& aStatusCode) override;
|
||||
mozilla::ipc::IPCResult RecvDeleteSelf() override;
|
||||
|
||||
void DoOnStartRequest(const nsresult& aChannelStatus,
|
||||
const int64_t& aContentLength,
|
||||
const nsACString& aContentType,
|
||||
const nsACString& aEntityID, const URIParams& aURI);
|
||||
void DoOnDataAvailable(const nsresult& aChannelStatus,
|
||||
const nsACString& aData, const uint64_t& aOffset,
|
||||
const uint32_t& aCount);
|
||||
void DoOnStopRequest(const nsresult& aChannelStatus);
|
||||
void DoFailedAsyncOpen(const nsresult& aStatusCode);
|
||||
void DoDeleteSelf();
|
||||
|
||||
void SetupNeckoTarget() override;
|
||||
|
||||
friend class NeckoTargetChannelFunctionEvent;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIInputStream> mUploadStream;
|
||||
|
||||
bool mIPCOpen = false;
|
||||
const RefPtr<ChannelEventQueue> mEventQ;
|
||||
|
||||
bool mCanceled = false;
|
||||
uint32_t mSuspendCount = 0;
|
||||
;
|
||||
bool mIsPending = false;
|
||||
|
||||
uint64_t mStartPos = 0;
|
||||
nsCString mEntityID;
|
||||
|
||||
// Set if SendSuspend is called. Determines if SendResume is needed when
|
||||
// diverting callbacks to parent.
|
||||
bool mSuspendSent = false;
|
||||
};
|
||||
|
||||
inline bool GIOChannelChild::IsSuspended() const { return mSuspendCount != 0; }
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* NS_GIOCHANNELCHILD_H */
|
||||
|
|
@ -1,324 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=4 sw=2 sts=2 et tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "GIOChannelParent.h"
|
||||
#include "nsGIOProtocolHandler.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/BrowserParent.h"
|
||||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "mozilla/net/NeckoChannelParams.h"
|
||||
#include "nsIAuthPrompt.h"
|
||||
#include "nsIAuthPromptProvider.h"
|
||||
#include "nsISecureBrowserUI.h"
|
||||
#include "nsQueryObject.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/net/ChannelEventQueue.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace mozilla {
|
||||
#undef LOG
|
||||
#define LOG(args) MOZ_LOG(gGIOLog, mozilla::LogLevel::Debug, args)
|
||||
namespace net {
|
||||
|
||||
GIOChannelParent::GIOChannelParent(dom::BrowserParent* aIframeEmbedding,
|
||||
nsILoadContext* aLoadContext,
|
||||
PBOverrideStatus aOverrideStatus)
|
||||
: mLoadContext(aLoadContext),
|
||||
mPBOverride(aOverrideStatus),
|
||||
mBrowserParent(aIframeEmbedding) {
|
||||
mEventQ = new ChannelEventQueue(static_cast<nsIParentChannel*>(this));
|
||||
}
|
||||
|
||||
void GIOChannelParent::ActorDestroy(ActorDestroyReason why) {
|
||||
// We may still have refcount>0 if the channel hasn't called OnStopRequest
|
||||
// yet, but we must not send any more msgs to child.
|
||||
mIPCClosed = true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GIOChannelParent::nsISupports
|
||||
//-----------------------------------------------------------------------------
|
||||
NS_IMPL_ISUPPORTS(GIOChannelParent, nsIStreamListener, nsIParentChannel,
|
||||
nsIInterfaceRequestor, nsIRequestObserver)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GIOChannelParent methods
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool GIOChannelParent::Init(const GIOChannelCreationArgs& aOpenArgs) {
|
||||
switch (aOpenArgs.type()) {
|
||||
case GIOChannelCreationArgs::TGIOChannelOpenArgs: {
|
||||
const GIOChannelOpenArgs& a = aOpenArgs.get_GIOChannelOpenArgs();
|
||||
return DoAsyncOpen(a.uri(), a.startPos(), a.entityID(), a.uploadStream(),
|
||||
a.loadInfo(), a.loadFlags());
|
||||
}
|
||||
case GIOChannelCreationArgs::TGIOChannelConnectArgs: {
|
||||
const GIOChannelConnectArgs& cArgs =
|
||||
aOpenArgs.get_GIOChannelConnectArgs();
|
||||
return ConnectChannel(cArgs.channelId());
|
||||
}
|
||||
default:
|
||||
MOZ_ASSERT_UNREACHABLE("unknown open type");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool GIOChannelParent::DoAsyncOpen(const URIParams& aURI,
|
||||
const uint64_t& aStartPos,
|
||||
const nsCString& aEntityID,
|
||||
const Maybe<IPCStream>& aUploadStream,
|
||||
const LoadInfoArgs& aLoadInfoArgs,
|
||||
const uint32_t& aLoadFlags) {
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIURI> uri = DeserializeURI(aURI);
|
||||
if (!uri) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
LOG(("GIOChannelParent DoAsyncOpen [this=%p uri=%s]\n", this,
|
||||
uri->GetSpecOrDefault().get()));
|
||||
#endif
|
||||
|
||||
nsCOMPtr<nsIIOService> ios(do_GetIOService(&rv));
|
||||
if (NS_FAILED(rv)) {
|
||||
return SendFailedAsyncOpen(rv);
|
||||
}
|
||||
|
||||
nsAutoCString remoteType;
|
||||
rv = GetRemoteType(remoteType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return SendFailedAsyncOpen(rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsILoadInfo> loadInfo;
|
||||
rv = mozilla::ipc::LoadInfoArgsToLoadInfo(aLoadInfoArgs, remoteType,
|
||||
getter_AddRefs(loadInfo));
|
||||
if (NS_FAILED(rv)) {
|
||||
return SendFailedAsyncOpen(rv);
|
||||
}
|
||||
|
||||
OriginAttributes attrs;
|
||||
rv = loadInfo->GetOriginAttributes(&attrs);
|
||||
if (NS_FAILED(rv)) {
|
||||
return SendFailedAsyncOpen(rv);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> chan;
|
||||
rv = NS_NewChannelInternal(getter_AddRefs(chan), uri, loadInfo, nullptr,
|
||||
nullptr, nullptr, aLoadFlags, ios);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return SendFailedAsyncOpen(rv);
|
||||
}
|
||||
|
||||
mChannel = chan;
|
||||
|
||||
nsIChannel* gioChan = static_cast<nsIChannel*>(mChannel.get());
|
||||
|
||||
rv = gioChan->AsyncOpen(this);
|
||||
if (NS_FAILED(rv)) {
|
||||
return SendFailedAsyncOpen(rv);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GIOChannelParent::ConnectChannel(const uint64_t& channelId) {
|
||||
nsresult rv;
|
||||
|
||||
LOG(("Looking for a registered channel [this=%p, id=%" PRIx64 "]", this,
|
||||
channelId));
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
rv = NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mChannel = channel;
|
||||
}
|
||||
|
||||
LOG((" found channel %p, rv=%08" PRIx32, mChannel.get(),
|
||||
static_cast<uint32_t>(rv)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult GIOChannelParent::RecvCancel(const nsresult& status) {
|
||||
if (mChannel) {
|
||||
mChannel->Cancel(status);
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult GIOChannelParent::RecvSuspend() {
|
||||
if (mChannel) {
|
||||
mChannel->Suspend();
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult GIOChannelParent::RecvResume() {
|
||||
if (mChannel) {
|
||||
mChannel->Resume();
|
||||
}
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GIOChannelParent::nsIRequestObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelParent::OnStartRequest(nsIRequest* aRequest) {
|
||||
LOG(("GIOChannelParent::OnStartRequest [this=%p]\n", this));
|
||||
nsCOMPtr<nsIChannel> chan = do_QueryInterface(aRequest);
|
||||
MOZ_ASSERT(chan);
|
||||
NS_ENSURE_TRUE(chan, NS_ERROR_UNEXPECTED);
|
||||
|
||||
int64_t contentLength;
|
||||
chan->GetContentLength(&contentLength);
|
||||
nsCString contentType;
|
||||
chan->GetContentType(contentType);
|
||||
nsresult channelStatus = NS_OK;
|
||||
chan->GetStatus(&channelStatus);
|
||||
|
||||
nsCString entityID;
|
||||
URIParams uriparam;
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
chan->GetURI(getter_AddRefs(uri));
|
||||
SerializeURI(uri, uriparam);
|
||||
|
||||
if (mIPCClosed || !SendOnStartRequest(channelStatus, contentLength,
|
||||
contentType, entityID, uriparam)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelParent::OnStopRequest(nsIRequest* aRequest, nsresult aStatusCode) {
|
||||
LOG(("GIOChannelParent::OnStopRequest: [this=%p status=%" PRIu32 "]\n", this,
|
||||
static_cast<uint32_t>(aStatusCode)));
|
||||
|
||||
if (mIPCClosed || !SendOnStopRequest(aStatusCode)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GIOChannelParent::nsIStreamListener
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelParent::OnDataAvailable(nsIRequest* aRequest,
|
||||
nsIInputStream* aInputStream,
|
||||
uint64_t aOffset, uint32_t aCount) {
|
||||
LOG(("GIOChannelParent::OnDataAvailable [this=%p]\n", this));
|
||||
|
||||
nsCString data;
|
||||
nsresult rv = NS_ReadInputStreamToString(aInputStream, data, aCount);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult channelStatus = NS_OK;
|
||||
mChannel->GetStatus(&channelStatus);
|
||||
|
||||
if (mIPCClosed ||
|
||||
!SendOnDataAvailable(channelStatus, data, aOffset, aCount)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GIOChannelParent::nsIParentChannel
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelParent::SetParentListener(ParentChannelListener* aListener) {
|
||||
// Do not need ptr to ParentChannelListener.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelParent::NotifyClassificationFlags(uint32_t aClassificationFlags,
|
||||
bool aIsThirdParty) {
|
||||
// Nothing to do.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelParent::SetClassifierMatchedInfo(const nsACString& aList,
|
||||
const nsACString& aProvider,
|
||||
const nsACString& aFullHash) {
|
||||
// nothing to do
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelParent::SetClassifierMatchedTrackingInfo(
|
||||
const nsACString& aLists, const nsACString& aFullHashes) {
|
||||
// nothing to do
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelParent::Delete() {
|
||||
if (mIPCClosed || !SendDeleteSelf()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelParent::GetRemoteType(nsACString& aRemoteType) {
|
||||
if (!CanSend()) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
dom::PContentParent* pcp = Manager()->Manager();
|
||||
aRemoteType = static_cast<dom::ContentParent*>(pcp)->GetRemoteType();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GIOChannelParent::nsIInterfaceRequestor
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
GIOChannelParent::GetInterface(const nsIID& uuid, void** result) {
|
||||
if (uuid.Equals(NS_GET_IID(nsIAuthPromptProvider)) ||
|
||||
uuid.Equals(NS_GET_IID(nsISecureBrowserUI))) {
|
||||
if (mBrowserParent) {
|
||||
return mBrowserParent->QueryInterface(uuid, result);
|
||||
}
|
||||
}
|
||||
|
||||
// Only support nsILoadContext if child channel's callbacks did too
|
||||
if (uuid.Equals(NS_GET_IID(nsILoadContext)) && mLoadContext) {
|
||||
nsCOMPtr<nsILoadContext> copy = mLoadContext;
|
||||
copy.forget(result);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return QueryInterface(uuid, result);
|
||||
}
|
||||
|
||||
//---------------------
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=4 sw=2 sts=2 et tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef NS_GIOCHANNELPARENT_H
|
||||
#define NS_GIOCHANNELPARENT_H
|
||||
|
||||
#include "mozilla/net/PGIOChannelParent.h"
|
||||
#include "mozilla/net/NeckoParent.h"
|
||||
#include "nsIParentChannel.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
|
||||
class nsILoadContext;
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class BrowserParent;
|
||||
} // namespace dom
|
||||
|
||||
namespace net {
|
||||
class ChannelEventQueue;
|
||||
|
||||
class GIOChannelParent final : public PGIOChannelParent,
|
||||
public nsIParentChannel,
|
||||
public nsIInterfaceRequestor {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
NS_DECL_NSIPARENTCHANNEL
|
||||
NS_DECL_NSIINTERFACEREQUESTOR
|
||||
|
||||
GIOChannelParent(dom::BrowserParent* aIframeEmbedding,
|
||||
nsILoadContext* aLoadContext,
|
||||
PBOverrideStatus aOverrideStatus);
|
||||
|
||||
bool Init(const GIOChannelCreationArgs& aOpenArgs);
|
||||
|
||||
protected:
|
||||
virtual ~GIOChannelParent() = default;
|
||||
|
||||
bool DoAsyncOpen(const URIParams& aURI, const uint64_t& aStartPos,
|
||||
const nsCString& aEntityID,
|
||||
const Maybe<mozilla::ipc::IPCStream>& aUploadStream,
|
||||
const LoadInfoArgs& aLoadInfoArgs,
|
||||
const uint32_t& aLoadFlags);
|
||||
|
||||
// used to connect redirected-to channel in parent with just created
|
||||
// ChildChannel. Used during HTTP->FTP redirects.
|
||||
bool ConnectChannel(const uint64_t& channelId);
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvCancel(const nsresult& status) override;
|
||||
virtual mozilla::ipc::IPCResult RecvSuspend() override;
|
||||
virtual mozilla::ipc::IPCResult RecvResume() override;
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
|
||||
bool mIPCClosed = false;
|
||||
|
||||
nsCOMPtr<nsILoadContext> mLoadContext;
|
||||
|
||||
PBOverrideStatus mPBOverride;
|
||||
|
||||
// Set to the canceled status value if the main channel was canceled.
|
||||
nsresult mStatus = NS_OK;
|
||||
|
||||
RefPtr<mozilla::dom::BrowserParent> mBrowserParent;
|
||||
|
||||
RefPtr<ChannelEventQueue> mEventQ;
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* NS_GIOCHANNELPARENT_H */
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PNecko;
|
||||
include URIParams;
|
||||
|
||||
//FIXME: bug #792908 (NeckoChannelParams already included by PNecko)
|
||||
include NeckoChannelParams;
|
||||
|
||||
using PRTime from "prtime.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
[ManualDealloc, ChildImpl=virtual, ParentImpl=virtual]
|
||||
async protocol PGIOChannel
|
||||
{
|
||||
manager PNecko;
|
||||
|
||||
parent:
|
||||
// Note: channels are opened during construction, so no open method here:
|
||||
// see PNecko.ipdl
|
||||
|
||||
async __delete__();
|
||||
|
||||
async Cancel(nsresult status);
|
||||
async Suspend();
|
||||
async Resume();
|
||||
|
||||
child:
|
||||
async OnStartRequest(nsresult aChannelStatus,
|
||||
int64_t aContentLength,
|
||||
nsCString aContentType,
|
||||
nsCString aEntityID,
|
||||
URIParams aURI);
|
||||
async OnDataAvailable(nsresult channelStatus,
|
||||
nsCString data,
|
||||
uint64_t offset,
|
||||
uint32_t count);
|
||||
async OnStopRequest(nsresult channelStatus);
|
||||
async FailedAsyncOpen(nsresult statusCode);
|
||||
|
||||
async DeleteSelf();
|
||||
};
|
||||
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
Classes = [
|
||||
{
|
||||
'cid': '{ee706783-3af8-4d19-9e84-e2ebfe213480}',
|
||||
'contract_ids': ['@mozilla.org/network/protocol;1?name=moz-gio'],
|
||||
'singleton': True,
|
||||
'type': 'nsGIOProtocolHandler',
|
||||
'headers': ['nsGIOProtocolHandler.h'],
|
||||
'constructor': 'nsGIOProtocolHandler::GetSingleton',
|
||||
'categories': { 'xpcom-startup': 'nsGIOProtocolHandler' },
|
||||
'protocol_config': {
|
||||
'scheme': 'moz-gio',
|
||||
'flags': [
|
||||
'URI_STD',
|
||||
'URI_DANGEROUS_TO_LOAD',
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
XPCOM_MANIFESTS += [
|
||||
"components.conf",
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
"nsGIOProtocolHandler.h",
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.net += [
|
||||
"GIOChannelChild.h",
|
||||
"GIOChannelParent.h",
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
"GIOChannelChild.cpp",
|
||||
"GIOChannelParent.cpp",
|
||||
"nsGIOProtocolHandler.cpp",
|
||||
]
|
||||
|
||||
IPDL_SOURCES = [
|
||||
"PGIOChannel.ipdl",
|
||||
]
|
||||
|
||||
include("/ipc/chromium/chromium-config.mozbuild")
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
"/netwerk/base",
|
||||
]
|
||||
|
||||
FINAL_LIBRARY = "xul"
|
||||
|
||||
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
|
||||
CXXFLAGS += CONFIG["MOZ_GTK3_CFLAGS"]
|
||||
|
||||
with Files("**"):
|
||||
BUG_COMPONENT = ("Core", "Widget: Gtk")
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,38 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsGIOProtocolHandler_h___
|
||||
#define nsGIOProtocolHandler_h___
|
||||
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsStringFwd.h"
|
||||
|
||||
#include "mozilla/Logging.h"
|
||||
extern mozilla::LazyLogModule gGIOLog;
|
||||
|
||||
class nsGIOProtocolHandler final : public nsIProtocolHandler,
|
||||
public nsIObserver {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROTOCOLHANDLER
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
static already_AddRefed<nsGIOProtocolHandler> GetSingleton();
|
||||
bool IsSupportedProtocol(const nsCString& aScheme);
|
||||
|
||||
protected:
|
||||
~nsGIOProtocolHandler() = default;
|
||||
|
||||
private:
|
||||
nsresult Init();
|
||||
|
||||
void InitSupportedProtocolsPref(nsIPrefBranch* prefs);
|
||||
|
||||
static mozilla::StaticRefPtr<nsGIOProtocolHandler> sSingleton;
|
||||
nsTArray<nsCString> mSupportedProtocols;
|
||||
};
|
||||
|
||||
#endif // nsGIOProtocolHandler_h___
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class ObliviousHttpChannel final : public nsIObliviousHttpChannel,
|
|||
~ObliviousHttpChannel();
|
||||
|
||||
nsresult ProcessOnStopRequest();
|
||||
void EmitOnDataAvailable();
|
||||
void EmitOnDataAvailable(nsIStreamListener*);
|
||||
|
||||
nsCOMPtr<nsIURI> mTargetURI;
|
||||
nsTArray<uint8_t> mEncodedConfig;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,13 @@
|
|||
# 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/.
|
||||
|
||||
DIRS += ["about", "data", "file"]
|
||||
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
|
||||
DIRS += ["gio"]
|
||||
DIRS += ["http", "res", "viewsource", "websocket", "webtransport"]
|
||||
DIRS += [
|
||||
"about",
|
||||
"data",
|
||||
"file",
|
||||
"http",
|
||||
"res",
|
||||
"viewsource",
|
||||
"websocket",
|
||||
"webtransport",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@
|
|||
#include "mozilla/BinarySearch.h"
|
||||
#include "mozilla/Components.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/Promise-inl.h"
|
||||
#include "mozilla/ExtensionPolicyService.h"
|
||||
|
|
@ -20,6 +22,7 @@
|
|||
#include "mozilla/Omnijar.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
#include "mozilla/SyncRunnable.h"
|
||||
#include "mozilla/Try.h"
|
||||
|
||||
#include "FileDescriptorFile.h"
|
||||
|
|
@ -385,9 +388,24 @@ NS_IMPL_RELEASE_INHERITED(ExtensionProtocolHandler, SubstitutingProtocolHandler)
|
|||
|
||||
already_AddRefed<ExtensionProtocolHandler>
|
||||
ExtensionProtocolHandler::GetSingleton() {
|
||||
static StaticMutex sMutex;
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (!sSingleton) {
|
||||
sSingleton = new ExtensionProtocolHandler();
|
||||
ClearOnShutdown(&sSingleton);
|
||||
if (NS_IsMainThread()) {
|
||||
sSingleton = new ExtensionProtocolHandler();
|
||||
ClearOnShutdown(&sSingleton);
|
||||
} else {
|
||||
StaticMutexAutoUnlock unlock(sMutex);
|
||||
RefPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
"ExtensionProtocolHandler::GetSingleton", []() {
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (!sSingleton) {
|
||||
sSingleton = new ExtensionProtocolHandler();
|
||||
ClearOnShutdown(&sSingleton);
|
||||
}
|
||||
});
|
||||
SyncRunnable::DispatchToThread(GetMainThreadSerialEventTarget(), r);
|
||||
}
|
||||
}
|
||||
return do_AddRef(sSingleton);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "mozilla/ModuleUtils.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/Omnijar.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#include "MozSrcProtocolHandler.h"
|
||||
|
||||
|
|
@ -19,16 +20,31 @@ NS_IMPL_QUERY_INTERFACE(MozSrcProtocolHandler, nsISubstitutingProtocolHandler,
|
|||
NS_IMPL_ADDREF_INHERITED(MozSrcProtocolHandler, SubstitutingProtocolHandler)
|
||||
NS_IMPL_RELEASE_INHERITED(MozSrcProtocolHandler, SubstitutingProtocolHandler)
|
||||
|
||||
mozilla::StaticMutex MozSrcProtocolHandler::sMutex;
|
||||
mozilla::StaticRefPtr<MozSrcProtocolHandler> MozSrcProtocolHandler::sSingleton;
|
||||
|
||||
already_AddRefed<MozSrcProtocolHandler> MozSrcProtocolHandler::GetSingleton() {
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (!sSingleton) {
|
||||
RefPtr<MozSrcProtocolHandler> handler = new MozSrcProtocolHandler();
|
||||
if (NS_WARN_IF(NS_FAILED(handler->Init()))) {
|
||||
return nullptr;
|
||||
}
|
||||
sSingleton = handler;
|
||||
ClearOnShutdown(&sSingleton);
|
||||
auto prevent_shutdown_race = [] {
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
sSingleton = nullptr;
|
||||
};
|
||||
if (NS_IsMainThread()) {
|
||||
RunOnShutdown(std::move(prevent_shutdown_race));
|
||||
} else {
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(
|
||||
"MozSrcProtocolHandler::RunOnShutdown",
|
||||
[prevent_shutdown_race =
|
||||
std::move(prevent_shutdown_race)]() mutable {
|
||||
RunOnShutdown(std::move(prevent_shutdown_race));
|
||||
}));
|
||||
}
|
||||
}
|
||||
return do_AddRef(sSingleton);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsISubstitutingProtocolHandler.h"
|
||||
#include "mozilla/StaticMutex.h"
|
||||
#include "SubstitutingProtocolHandler.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
|
@ -37,7 +38,9 @@ class MozSrcProtocolHandler final : public nsISubstitutingProtocolHandler,
|
|||
nsIURI** aResult) override;
|
||||
|
||||
private:
|
||||
static mozilla::StaticRefPtr<MozSrcProtocolHandler> sSingleton;
|
||||
static mozilla::StaticMutex sMutex;
|
||||
static mozilla::StaticRefPtr<MozSrcProtocolHandler> sSingleton
|
||||
MOZ_GUARDED_BY(sMutex);
|
||||
nsresult Init();
|
||||
|
||||
nsCString mGREURI;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ using mozilla::dom::ContentParent;
|
|||
mozilla::StaticRefPtr<nsResProtocolHandler> nsResProtocolHandler::sSingleton;
|
||||
|
||||
already_AddRefed<nsResProtocolHandler> nsResProtocolHandler::GetSingleton() {
|
||||
MOZ_ASSERT(NS_IsMainThread() || sSingleton);
|
||||
if (!sSingleton) {
|
||||
RefPtr<nsResProtocolHandler> handler = new nsResProtocolHandler();
|
||||
if (NS_WARN_IF(NS_FAILED(handler->Init()))) {
|
||||
|
|
|
|||
|
|
@ -29,20 +29,20 @@ NS_IMPL_ADDREF(WebSocketChannelChild)
|
|||
|
||||
NS_IMETHODIMP_(MozExternalRefCountType) WebSocketChannelChild::Release() {
|
||||
MOZ_ASSERT(0 != mRefCnt, "dup release");
|
||||
--mRefCnt;
|
||||
nsrefcnt count = --mRefCnt;
|
||||
NS_LOG_RELEASE(this, mRefCnt, "WebSocketChannelChild");
|
||||
|
||||
if (mRefCnt == 1) {
|
||||
if (count == 1) {
|
||||
MaybeReleaseIPCObject();
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
if (mRefCnt == 0) {
|
||||
if (count == 0) {
|
||||
mRefCnt = 1; /* stabilize */
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
return mRefCnt;
|
||||
return count;
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(WebSocketChannelChild)
|
||||
|
|
@ -95,15 +95,6 @@ void WebSocketChannelChild::ReleaseIPDLReference() {
|
|||
}
|
||||
|
||||
void WebSocketChannelChild::MaybeReleaseIPCObject() {
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (mIPCState != Opened) {
|
||||
return;
|
||||
}
|
||||
|
||||
mIPCState = Closing;
|
||||
}
|
||||
|
||||
if (!NS_IsMainThread()) {
|
||||
nsCOMPtr<nsIEventTarget> target = GetNeckoTarget();
|
||||
MOZ_ALWAYS_SUCCEEDS(target->Dispatch(
|
||||
|
|
@ -113,6 +104,15 @@ void WebSocketChannelChild::MaybeReleaseIPCObject() {
|
|||
return;
|
||||
}
|
||||
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
if (mIPCState != Opened) {
|
||||
return;
|
||||
}
|
||||
|
||||
mIPCState = Closing;
|
||||
}
|
||||
|
||||
SendDeleteSelf();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,17 +220,29 @@ WebTransportSessionProxy::CloseSession(uint32_t status,
|
|||
case WebTransportSessionProxyState::INIT:
|
||||
case WebTransportSessionProxyState::DONE:
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
case WebTransportSessionProxyState::NEGOTIATING:
|
||||
mChannel->Cancel(NS_ERROR_ABORT);
|
||||
case WebTransportSessionProxyState::NEGOTIATING: {
|
||||
nsCOMPtr<nsIChannel> channel = mChannel;
|
||||
mChannel = nullptr;
|
||||
ChangeState(WebTransportSessionProxyState::DONE);
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(
|
||||
"WebTransportSessionProxy::CancelChannel",
|
||||
[channel = std::move(channel)]() {
|
||||
channel->Cancel(NS_ERROR_ABORT);
|
||||
}));
|
||||
break;
|
||||
case WebTransportSessionProxyState::NEGOTIATING_SUCCEEDED:
|
||||
mChannel->Cancel(NS_ERROR_ABORT);
|
||||
}
|
||||
case WebTransportSessionProxyState::NEGOTIATING_SUCCEEDED: {
|
||||
nsCOMPtr<nsIChannel> channel = mChannel;
|
||||
mChannel = nullptr;
|
||||
ChangeState(WebTransportSessionProxyState::SESSION_CLOSE_PENDING);
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction(
|
||||
"WebTransportSessionProxy::CancelChannel",
|
||||
[channel = std::move(channel)]() {
|
||||
channel->Cancel(NS_ERROR_ABORT);
|
||||
}));
|
||||
CloseSessionInternal();
|
||||
break;
|
||||
}
|
||||
case WebTransportSessionProxyState::ACTIVE:
|
||||
ChangeState(WebTransportSessionProxyState::SESSION_CLOSE_PENDING);
|
||||
CloseSessionInternal();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue