зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1624318 - Serialize replacement config input stream as a blob. r=baku,necko-reviewers,valentin
Differential Revision: https://phabricator.services.mozilla.com/D71872
This commit is contained in:
Родитель
753c84b4a5
Коммит
20f213591b
|
@ -78,7 +78,8 @@ already_AddRefed<BlobImpl> Deserialize(const IPCBlob& aIPCBlob) {
|
|||
template <typename M>
|
||||
nsresult SerializeInputStreamParent(nsIInputStream* aInputStream,
|
||||
uint64_t aSize, uint64_t aChildID,
|
||||
IPCBlob& aIPCBlob, M* aManager) {
|
||||
PIPCBlobInputStreamParent*& aActorParent,
|
||||
M* aManager) {
|
||||
// Parent to Child we always send a IPCBlobInputStream.
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
|
||||
|
@ -111,60 +112,58 @@ nsresult SerializeInputStreamParent(nsIInputStream* aInputStream,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aIPCBlob.inputStream() = parentActor;
|
||||
aActorParent = parentActor;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
template <typename M>
|
||||
nsresult SerializeInputStreamChild(nsIInputStream* aInputStream,
|
||||
IPCBlob& aIPCBlob, M* aManager) {
|
||||
IPCBlobStream& aIPCBlob, M* aManager) {
|
||||
AutoIPCStream ipcStream(true /* delayed start */);
|
||||
if (!ipcStream.Serialize(aInputStream, aManager)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
aIPCBlob.inputStream() = ipcStream.TakeValue();
|
||||
aIPCBlob = ipcStream.TakeValue();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||
uint64_t aChildID, IPCBlob& aIPCBlob,
|
||||
PIPCBlobInputStreamParent*& aActorParent,
|
||||
ContentParent* aManager) {
|
||||
return SerializeInputStreamParent(aInputStream, aSize, aChildID, aIPCBlob,
|
||||
return SerializeInputStreamParent(aInputStream, aSize, aManager->ChildID(),
|
||||
aActorParent, aManager);
|
||||
}
|
||||
|
||||
nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||
IPCBlobStream& aIPCBlob,
|
||||
ContentParent* aManager) {
|
||||
aIPCBlob = (PIPCBlobInputStreamParent*)nullptr;
|
||||
return SerializeInputStreamParent(aInputStream, aSize, aManager->ChildID(),
|
||||
aIPCBlob.get_PIPCBlobInputStreamParent(),
|
||||
aManager);
|
||||
}
|
||||
|
||||
nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||
uint64_t aChildID, IPCBlob& aIPCBlob,
|
||||
IPCBlobStream& aIPCBlob,
|
||||
PBackgroundParent* aManager) {
|
||||
return SerializeInputStreamParent(aInputStream, aSize, aChildID, aIPCBlob,
|
||||
aManager);
|
||||
aIPCBlob = (PIPCBlobInputStreamParent*)nullptr;
|
||||
return SerializeInputStreamParent(
|
||||
aInputStream, aSize, BackgroundParent::GetChildID(aManager),
|
||||
aIPCBlob.get_PIPCBlobInputStreamParent(), aManager);
|
||||
}
|
||||
|
||||
nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||
uint64_t aChildID, IPCBlob& aIPCBlob,
|
||||
ContentChild* aManager) {
|
||||
IPCBlobStream& aIPCBlob, ContentChild* aManager) {
|
||||
return SerializeInputStreamChild(aInputStream, aIPCBlob, aManager);
|
||||
}
|
||||
|
||||
nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||
uint64_t aChildID, IPCBlob& aIPCBlob,
|
||||
IPCBlobStream& aIPCBlob,
|
||||
PBackgroundChild* aManager) {
|
||||
return SerializeInputStreamChild(aInputStream, aIPCBlob, aManager);
|
||||
}
|
||||
|
||||
uint64_t ChildIDFromManager(ContentParent* aManager) {
|
||||
return aManager->ChildID();
|
||||
}
|
||||
|
||||
uint64_t ChildIDFromManager(PBackgroundParent* aManager) {
|
||||
return BackgroundParent::GetChildID(aManager);
|
||||
}
|
||||
|
||||
uint64_t ChildIDFromManager(ContentChild* aManager) { return 0; }
|
||||
|
||||
uint64_t ChildIDFromManager(PBackgroundChild* aManager) { return 0; }
|
||||
|
||||
template <typename M>
|
||||
nsresult SerializeInternal(BlobImpl* aBlobImpl, M* aManager,
|
||||
IPCBlob& aIPCBlob) {
|
||||
|
@ -219,7 +218,7 @@ nsresult SerializeInternal(BlobImpl* aBlobImpl, M* aManager,
|
|||
}
|
||||
|
||||
rv = SerializeInputStream(inputStream, aIPCBlob.size(),
|
||||
ChildIDFromManager(aManager), aIPCBlob, aManager);
|
||||
aIPCBlob.inputStream(), aManager);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
|
|
@ -47,6 +47,12 @@
|
|||
* parent process and sent to content (a FilePicker creates Blobs and it runs on
|
||||
* the parent process).
|
||||
*
|
||||
* DocumentLoadListener uses blobs to serialize the POST data back to the
|
||||
* content process (for insertion into session history). This lets it correclty
|
||||
* handle OS files by reference, and avoid copying the underlying buffer data
|
||||
* unless it is read. This can hopefully be removed once SessionHistory is
|
||||
* handled in the parent process.
|
||||
*
|
||||
* Child to Parent Blob Serialization
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
|
@ -224,6 +230,7 @@ namespace dom {
|
|||
class IPCBlob;
|
||||
class ContentChild;
|
||||
class ContentParent;
|
||||
class PIPCBlobInputStreamParent;
|
||||
|
||||
namespace IPCBlobUtils {
|
||||
|
||||
|
@ -244,6 +251,10 @@ nsresult Serialize(BlobImpl* aBlobImpl,
|
|||
mozilla::ipc::PBackgroundParent* aManager,
|
||||
IPCBlob& aIPCBlob);
|
||||
|
||||
nsresult SerializeInputStream(nsIInputStream* aInputStream, uint64_t aSize,
|
||||
PIPCBlobInputStreamParent*& aActorParent,
|
||||
ContentParent* aManager);
|
||||
|
||||
// WARNING: If you pass any actor which does not have P{Content,Background} as
|
||||
// its toplevel protocol, this method will MOZ_CRASH.
|
||||
nsresult SerializeUntyped(BlobImpl* aBlobImpl, mozilla::ipc::IProtocol* aActor,
|
||||
|
|
|
@ -11,6 +11,7 @@ include "mozilla/layers/LayersMessageUtils.h";
|
|||
|
||||
include IPCBlob;
|
||||
include IPCStream;
|
||||
include protocol PIPCBlobInputStream;
|
||||
include ProtocolTypes;
|
||||
include protocol PSHEntry;
|
||||
|
||||
|
@ -320,7 +321,7 @@ struct ReplacementChannelConfigInit
|
|||
nsCString? method;
|
||||
nsIReferrerInfo referrerInfo;
|
||||
TimedChannelInfo? timedChannel;
|
||||
nsIInputStream uploadStream;
|
||||
nullable PIPCBlobInputStream uploadStream;
|
||||
bool uploadStreamHasHeaders;
|
||||
nsCString? contentType;
|
||||
nsCString? contentLength;
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "mozilla/dom/BrowserParent.h"
|
||||
#include "mozilla/dom/CanonicalBrowsingContext.h"
|
||||
#include "mozilla/dom/ClientInfo.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
|
||||
extern mozilla::LazyLogModule gDocumentChannelLog;
|
||||
#define LOG(fmt) MOZ_LOG(gDocumentChannelLog, mozilla::LogLevel::Verbose, fmt)
|
||||
|
@ -68,7 +69,9 @@ DocumentChannelParent::RedirectToRealChannel(
|
|||
CreateAndReject(ResponseRejectReason::ChannelClosed, __func__);
|
||||
}
|
||||
RedirectToRealChannelArgs args;
|
||||
mParent->SerializeRedirectData(args, false, aRedirectFlags, aLoadFlags);
|
||||
mParent->SerializeRedirectData(
|
||||
args, false, aRedirectFlags, aLoadFlags,
|
||||
static_cast<ContentParent*>(Manager()->Manager()));
|
||||
return SendRedirectToRealChannel(args, std::move(aStreamFilterEndpoints));
|
||||
}
|
||||
|
||||
|
|
|
@ -1046,7 +1046,8 @@ bool DocumentLoadListener::ResumeSuspendedChannel(
|
|||
|
||||
void DocumentLoadListener::SerializeRedirectData(
|
||||
RedirectToRealChannelArgs& aArgs, bool aIsCrossProcess,
|
||||
uint32_t aRedirectFlags, uint32_t aLoadFlags) const {
|
||||
uint32_t aRedirectFlags, uint32_t aLoadFlags,
|
||||
ContentParent* aParent) const {
|
||||
// Use the original URI of the current channel, as this is what
|
||||
// we'll use to construct the channel in the content process.
|
||||
aArgs.uri() = mChannelCreationURI;
|
||||
|
@ -1132,7 +1133,7 @@ void DocumentLoadListener::SerializeRedirectData(
|
|||
->CloneReplacementChannelConfig(
|
||||
true, aRedirectFlags,
|
||||
HttpBaseChannel::ReplacementReason::DocumentChannel)
|
||||
.Serialize());
|
||||
.Serialize(aParent));
|
||||
}
|
||||
|
||||
uint32_t contentDispositionTemp;
|
||||
|
@ -1389,7 +1390,7 @@ DocumentLoadListener::RedirectToRealChannel(
|
|||
|
||||
RedirectToRealChannelArgs args;
|
||||
SerializeRedirectData(args, !!aDestinationProcess, aRedirectFlags,
|
||||
aLoadFlags);
|
||||
aLoadFlags, cp);
|
||||
if (mTiming) {
|
||||
mTiming->Anonymize(args.uri());
|
||||
args.timing() = Some(std::move(mTiming));
|
||||
|
|
|
@ -200,7 +200,8 @@ class DocumentLoadListener : public nsIInterfaceRequestor,
|
|||
// in the content process into the RedirectToRealChannelArgs struct.
|
||||
void SerializeRedirectData(RedirectToRealChannelArgs& aArgs,
|
||||
bool aIsCrossProcess, uint32_t aRedirectFlags,
|
||||
uint32_t aLoadFlags) const;
|
||||
uint32_t aLoadFlags,
|
||||
dom::ContentParent* aParent) const;
|
||||
|
||||
const nsTArray<DocumentChannelRedirect>& Redirects() const {
|
||||
return mRedirects;
|
||||
|
|
|
@ -77,6 +77,8 @@
|
|||
#include "nsStreamUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsURLHelper.h"
|
||||
#include "mozilla/dom/IPCBlobUtils.h"
|
||||
#include "mozilla/dom/IPCBlobInputStreamChild.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
@ -3181,7 +3183,15 @@ HttpBaseChannel::CloneReplacementChannelConfig(bool aPreserveMethod,
|
|||
mRequestHead.Method(method);
|
||||
config.method = Some(method);
|
||||
|
||||
config.uploadStream = mUploadStream;
|
||||
if (mUploadStream) {
|
||||
// rewind upload stream
|
||||
nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
|
||||
if (seekable) {
|
||||
seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
||||
}
|
||||
config.uploadStream = mUploadStream;
|
||||
}
|
||||
config.uploadStreamLength = mReqContentLength;
|
||||
config.uploadStreamHasHeaders = mUploadStreamHasHeaders;
|
||||
|
||||
nsAutoCString contentType;
|
||||
|
@ -3312,13 +3322,6 @@ HttpBaseChannel::CloneReplacementChannelConfig(bool aPreserveMethod,
|
|||
nsCOMPtr<nsIUploadChannel> uploadChannel = do_QueryInterface(httpChannel);
|
||||
nsCOMPtr<nsIUploadChannel2> uploadChannel2 = do_QueryInterface(httpChannel);
|
||||
if (uploadChannel2 || uploadChannel) {
|
||||
// rewind upload stream
|
||||
nsCOMPtr<nsISeekableStream> seekable =
|
||||
do_QueryInterface(config.uploadStream);
|
||||
if (seekable) {
|
||||
seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
|
||||
}
|
||||
|
||||
// replicate original call to SetUploadStream...
|
||||
if (uploadChannel2) {
|
||||
const nsACString& ctype =
|
||||
|
@ -3331,16 +3334,13 @@ HttpBaseChannel::CloneReplacementChannelConfig(bool aPreserveMethod,
|
|||
const nsACString& method =
|
||||
config.method ? *config.method : VoidCString();
|
||||
|
||||
int64_t len = (!config.contentLength || config.contentLength->IsEmpty())
|
||||
? -1
|
||||
: nsCRT::atoll(config.contentLength->get());
|
||||
uploadChannel2->ExplicitSetUploadStream(config.uploadStream, ctype, len,
|
||||
method,
|
||||
config.uploadStreamHasHeaders);
|
||||
uploadChannel2->ExplicitSetUploadStream(
|
||||
config.uploadStream, ctype, config.uploadStreamLength, method,
|
||||
config.uploadStreamHasHeaders);
|
||||
} else {
|
||||
if (config.uploadStreamHasHeaders) {
|
||||
uploadChannel->SetUploadStream(config.uploadStream, EmptyCString(),
|
||||
-1);
|
||||
config.uploadStreamLength);
|
||||
} else {
|
||||
nsAutoCString ctype;
|
||||
if (config.contentType) {
|
||||
|
@ -3378,14 +3378,24 @@ HttpBaseChannel::ReplacementChannelConfig::ReplacementChannelConfig(
|
|||
method = aInit.method();
|
||||
referrerInfo = aInit.referrerInfo();
|
||||
timedChannel = aInit.timedChannel();
|
||||
uploadStream = aInit.uploadStream();
|
||||
if (dom::IPCBlobInputStreamChild* actor =
|
||||
static_cast<dom::IPCBlobInputStreamChild*>(
|
||||
aInit.uploadStreamChild())) {
|
||||
uploadStreamLength = actor->Size();
|
||||
uploadStream = actor->CreateStream();
|
||||
// actor can be deleted by CreateStream, so don't touch it
|
||||
// after this.
|
||||
} else {
|
||||
uploadStreamLength = 0;
|
||||
}
|
||||
uploadStreamHasHeaders = aInit.uploadStreamHasHeaders();
|
||||
contentType = aInit.contentType();
|
||||
contentLength = aInit.contentLength();
|
||||
}
|
||||
|
||||
dom::ReplacementChannelConfigInit
|
||||
HttpBaseChannel::ReplacementChannelConfig::Serialize() {
|
||||
HttpBaseChannel::ReplacementChannelConfig::Serialize(
|
||||
dom::ContentParent* aParent) {
|
||||
dom::ReplacementChannelConfigInit config;
|
||||
config.redirectFlags() = redirectFlags;
|
||||
config.classOfService() = classOfService;
|
||||
|
@ -3393,7 +3403,10 @@ HttpBaseChannel::ReplacementChannelConfig::Serialize() {
|
|||
config.method() = method;
|
||||
config.referrerInfo() = referrerInfo;
|
||||
config.timedChannel() = timedChannel;
|
||||
config.uploadStream() = uploadStream;
|
||||
if (uploadStream) {
|
||||
dom::IPCBlobUtils::SerializeInputStream(
|
||||
uploadStream, uploadStreamLength, config.uploadStreamParent(), aParent);
|
||||
}
|
||||
config.uploadStreamHasHeaders() = uploadStreamHasHeaders;
|
||||
config.contentType() = contentType;
|
||||
config.contentLength() = contentLength;
|
||||
|
|
|
@ -66,7 +66,8 @@ namespace mozilla {
|
|||
|
||||
namespace dom {
|
||||
class PerformanceStorage;
|
||||
}
|
||||
class ContentParent;
|
||||
} // namespace dom
|
||||
|
||||
class LogCollector;
|
||||
|
||||
|
@ -491,11 +492,12 @@ class HttpBaseChannel : public nsHashPropertyBag,
|
|||
nsCOMPtr<nsIReferrerInfo> referrerInfo;
|
||||
Maybe<dom::TimedChannelInfo> timedChannel;
|
||||
nsCOMPtr<nsIInputStream> uploadStream;
|
||||
uint64_t uploadStreamLength;
|
||||
bool uploadStreamHasHeaders;
|
||||
Maybe<nsCString> contentType;
|
||||
Maybe<nsCString> contentLength;
|
||||
|
||||
dom::ReplacementChannelConfigInit Serialize();
|
||||
dom::ReplacementChannelConfigInit Serialize(dom::ContentParent* aParent);
|
||||
};
|
||||
|
||||
enum class ReplacementReason {
|
||||
|
|
Загрузка…
Ссылка в новой задаче