зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1354248 - Part 2: Abstract out the IPC message that RemoteStreamGetter uses. r=necko-reviewers,kershaw
This will allow the PageIconProtocolHandler to also use RemoteStreamGetter, using its own IPC message. Differential Revision: https://phabricator.services.mozilla.com/D147181
This commit is contained in:
Родитель
2ff2484102
Коммит
9162e50177
|
@ -564,5 +564,11 @@ union GIOChannelCreationArgs
|
|||
GIOChannelOpenArgs; // For AsyncOpen: the common case.
|
||||
GIOChannelConnectArgs; // Used for redirected-to channels
|
||||
};
|
||||
|
||||
struct RemoteStreamInfo {
|
||||
nsIInputStream inputStream;
|
||||
nsCString contentType;
|
||||
int64_t contentLength;
|
||||
};
|
||||
} // namespace net
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "mozilla/net/DNSRequestParent.h"
|
||||
#include "mozilla/net/ClassifierDummyChannelParent.h"
|
||||
#include "mozilla/net/IPCTransportProvider.h"
|
||||
#include "mozilla/net/RemoteStreamGetter.h"
|
||||
#include "mozilla/net/RequestContextService.h"
|
||||
#include "mozilla/net/SocketProcessParent.h"
|
||||
#include "mozilla/net/PSocketProcessBridgeParent.h"
|
||||
|
@ -860,15 +861,13 @@ mozilla::ipc::IPCResult NeckoParent::RecvGetPageThumbStream(
|
|||
|
||||
inputStreamPromise->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[aResolver](const nsCOMPtr<nsIInputStream>& aStream) {
|
||||
aResolver(aStream);
|
||||
},
|
||||
[aResolver](const RemoteStreamInfo& aInfo) { aResolver(Some(aInfo)); },
|
||||
[aResolver](nsresult aRv) {
|
||||
// If NewStream failed, we send back an invalid stream to the child so
|
||||
// it can handle the error. MozPromise rejection is reserved for channel
|
||||
// errors/disconnects.
|
||||
Unused << NS_WARN_IF(NS_FAILED(aRv));
|
||||
aResolver(nullptr);
|
||||
aResolver(Nothing());
|
||||
});
|
||||
|
||||
return IPC_OK();
|
||||
|
|
|
@ -149,7 +149,7 @@ parent:
|
|||
/**
|
||||
* Page thumbnails remote resource loading
|
||||
*/
|
||||
async GetPageThumbStream(nsIURI uri) returns (nsIInputStream stream);
|
||||
async GetPageThumbStream(nsIURI uri) returns (RemoteStreamInfo? info);
|
||||
|
||||
child:
|
||||
/* Predictor Methods */
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "mozilla/ipc/URIParams.h"
|
||||
#include "mozilla/ipc/URIUtils.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/net/RemoteStreamGetter.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
|
||||
|
@ -79,18 +78,16 @@ nsresult PageThumbProtocolHandler::GetFlagsForURI(nsIURI* aURI,
|
|||
// process.
|
||||
*aFlags = URI_STD | URI_IS_UI_RESOURCE | URI_IS_LOCAL_RESOURCE |
|
||||
URI_NORELATIVE | URI_NOAUTH;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
RefPtr<PageThumbStreamPromise> PageThumbProtocolHandler::NewStream(
|
||||
RefPtr<RemoteStreamPromise> PageThumbProtocolHandler::NewStream(
|
||||
nsIURI* aChildURI, bool* aTerminateSender) {
|
||||
MOZ_ASSERT(!IsNeckoChild());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!aChildURI || !aTerminateSender) {
|
||||
return PageThumbStreamPromise::CreateAndReject(NS_ERROR_INVALID_ARG,
|
||||
__func__);
|
||||
return RemoteStreamPromise::CreateAndReject(NS_ERROR_INVALID_ARG, __func__);
|
||||
}
|
||||
|
||||
*aTerminateSender = true;
|
||||
|
@ -103,8 +100,8 @@ RefPtr<PageThumbStreamPromise> PageThumbProtocolHandler::NewStream(
|
|||
bool isPageThumbScheme = false;
|
||||
if (NS_FAILED(aChildURI->SchemeIs(PAGE_THUMB_SCHEME, &isPageThumbScheme)) ||
|
||||
!isPageThumbScheme) {
|
||||
return PageThumbStreamPromise::CreateAndReject(NS_ERROR_UNKNOWN_PROTOCOL,
|
||||
__func__);
|
||||
return RemoteStreamPromise::CreateAndReject(NS_ERROR_UNKNOWN_PROTOCOL,
|
||||
__func__);
|
||||
}
|
||||
|
||||
// We should never receive a URI that does not have "thumbnails" as the host.
|
||||
|
@ -112,8 +109,7 @@ RefPtr<PageThumbStreamPromise> PageThumbProtocolHandler::NewStream(
|
|||
if (NS_FAILED(aChildURI->GetAsciiHost(host)) ||
|
||||
!(host.EqualsLiteral(PAGE_THUMB_HOST) ||
|
||||
host.EqualsLiteral(PLACES_PREVIEWS_HOST))) {
|
||||
return PageThumbStreamPromise::CreateAndReject(NS_ERROR_UNEXPECTED,
|
||||
__func__);
|
||||
return RemoteStreamPromise::CreateAndReject(NS_ERROR_UNEXPECTED, __func__);
|
||||
}
|
||||
|
||||
// For errors after this point, we want to propagate the error to
|
||||
|
@ -127,26 +123,25 @@ RefPtr<PageThumbStreamPromise> PageThumbProtocolHandler::NewStream(
|
|||
nsAutoCString resolvedSpec;
|
||||
rv = ResolveURI(aChildURI, resolvedSpec);
|
||||
if (NS_FAILED(rv)) {
|
||||
return PageThumbStreamPromise::CreateAndReject(rv, __func__);
|
||||
return RemoteStreamPromise::CreateAndReject(rv, __func__);
|
||||
}
|
||||
|
||||
nsAutoCString resolvedScheme;
|
||||
rv = net_ExtractURLScheme(resolvedSpec, resolvedScheme);
|
||||
if (NS_FAILED(rv) || !resolvedScheme.EqualsLiteral("file")) {
|
||||
return PageThumbStreamPromise::CreateAndReject(NS_ERROR_UNEXPECTED,
|
||||
__func__);
|
||||
return RemoteStreamPromise::CreateAndReject(NS_ERROR_UNEXPECTED, __func__);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIIOService> ioService = do_GetIOService(&rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return PageThumbStreamPromise::CreateAndReject(rv, __func__);
|
||||
return RemoteStreamPromise::CreateAndReject(rv, __func__);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> resolvedURI;
|
||||
rv = ioService->NewURI(resolvedSpec, nullptr, nullptr,
|
||||
getter_AddRefs(resolvedURI));
|
||||
if (NS_FAILED(rv)) {
|
||||
return PageThumbStreamPromise::CreateAndReject(rv, __func__);
|
||||
return RemoteStreamPromise::CreateAndReject(rv, __func__);
|
||||
}
|
||||
|
||||
// We use the system principal to get a file channel for the request,
|
||||
|
@ -158,22 +153,34 @@ RefPtr<PageThumbStreamPromise> PageThumbProtocolHandler::NewStream(
|
|||
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
|
||||
nsIContentPolicy::TYPE_OTHER);
|
||||
if (NS_FAILED(rv)) {
|
||||
return PageThumbStreamPromise::CreateAndReject(rv, __func__);
|
||||
return RemoteStreamPromise::CreateAndReject(rv, __func__);
|
||||
}
|
||||
|
||||
auto promiseHolder = MakeUnique<MozPromiseHolder<PageThumbStreamPromise>>();
|
||||
RefPtr<PageThumbStreamPromise> promise = promiseHolder->Ensure(__func__);
|
||||
auto promiseHolder = MakeUnique<MozPromiseHolder<RemoteStreamPromise>>();
|
||||
RefPtr<RemoteStreamPromise> promise = promiseHolder->Ensure(__func__);
|
||||
|
||||
nsCOMPtr<nsIMIMEService> mime = do_GetService("@mozilla.org/mime;1", &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return RemoteStreamPromise::CreateAndReject(rv, __func__);
|
||||
}
|
||||
|
||||
nsAutoCString contentType;
|
||||
rv = mime->GetTypeFromURI(aChildURI, contentType);
|
||||
if (NS_FAILED(rv)) {
|
||||
return RemoteStreamPromise::CreateAndReject(rv, __func__);
|
||||
}
|
||||
|
||||
rv = NS_DispatchBackgroundTask(
|
||||
NS_NewRunnableFunction(
|
||||
"PageThumbProtocolHandler::NewStream",
|
||||
[channel, holder = std::move(promiseHolder)]() {
|
||||
[contentType, channel, holder = std::move(promiseHolder)]() {
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIFileChannel> fileChannel =
|
||||
do_QueryInterface(channel, &rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
holder->Reject(rv, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> requestedFile;
|
||||
|
@ -191,12 +198,14 @@ RefPtr<PageThumbStreamPromise> PageThumbProtocolHandler::NewStream(
|
|||
return;
|
||||
}
|
||||
|
||||
holder->Resolve(inputStream, __func__);
|
||||
RemoteStreamInfo info(inputStream, contentType, -1);
|
||||
|
||||
holder->Resolve(std::move(info), __func__);
|
||||
}),
|
||||
NS_DISPATCH_EVENT_MAY_BLOCK);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return PageThumbStreamPromise::CreateAndReject(rv, __func__);
|
||||
return RemoteStreamPromise::CreateAndReject(rv, __func__);
|
||||
}
|
||||
|
||||
return promise;
|
||||
|
@ -339,20 +348,6 @@ nsresult PageThumbProtocolHandler::GetThumbnailPath(const nsACString& aPath,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// static
|
||||
void PageThumbProtocolHandler::SetContentType(nsIURI* aURI,
|
||||
nsIChannel* aChannel) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMIMEService> mime = do_GetService("@mozilla.org/mime;1", &rv);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsAutoCString contentType;
|
||||
rv = mime->GetTypeFromURI(aURI, contentType);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
Unused << aChannel->SetContentType(contentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void PageThumbProtocolHandler::NewSimpleChannel(
|
||||
nsIURI* aURI, nsILoadInfo* aLoadinfo, RemoteStreamGetter* aStreamGetter,
|
||||
|
@ -361,10 +356,10 @@ void PageThumbProtocolHandler::NewSimpleChannel(
|
|||
aURI, aLoadinfo, aStreamGetter,
|
||||
[](nsIStreamListener* listener, nsIChannel* simpleChannel,
|
||||
RemoteStreamGetter* getter) -> RequestOrReason {
|
||||
return getter->GetAsync(listener, simpleChannel);
|
||||
return getter->GetAsync(listener, simpleChannel,
|
||||
&NeckoChild::SendGetPageThumbStream);
|
||||
});
|
||||
|
||||
SetContentType(aURI, channel);
|
||||
channel.swap(*aRetVal);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "mozilla/Result.h"
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/net/RemoteStreamGetter.h"
|
||||
#include "SubstitutingProtocolHandler.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsWeakReference.h"
|
||||
|
@ -15,9 +16,6 @@
|
|||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
using PageThumbStreamPromise =
|
||||
mozilla::MozPromise<nsCOMPtr<nsIInputStream>, nsresult, false>;
|
||||
|
||||
class RemoteStreamGetter;
|
||||
|
||||
class PageThumbProtocolHandler final
|
||||
|
@ -43,12 +41,12 @@ class PageThumbProtocolHandler final
|
|||
* not a moz-page-thumb URI, the child is in an invalid state and
|
||||
* should be terminated. This outparam will be set synchronously.
|
||||
*
|
||||
* @return PageThumbStreamPromise
|
||||
* The PageThumbStreamPromise will resolve with an nsIInputStream on
|
||||
* @return RemoteStreamPromise
|
||||
* The RemoteStreamPromise will resolve with an RemoteStreamInfo on
|
||||
* success, and reject with an nsresult on failure.
|
||||
*/
|
||||
RefPtr<PageThumbStreamPromise> NewStream(nsIURI* aChildURI,
|
||||
bool* aTerminateSender);
|
||||
RefPtr<RemoteStreamPromise> NewStream(nsIURI* aChildURI,
|
||||
bool* aTerminateSender);
|
||||
|
||||
protected:
|
||||
~PageThumbProtocolHandler() = default;
|
||||
|
@ -113,9 +111,6 @@ class PageThumbProtocolHandler final
|
|||
// handling moz-page-thumb requests from the child.
|
||||
static StaticRefPtr<PageThumbProtocolHandler> sSingleton;
|
||||
|
||||
// Set the channel's content type using the provided URI's type.
|
||||
static void SetContentType(nsIURI* aURI, nsIChannel* aChannel);
|
||||
|
||||
// Gets a SimpleChannel that wraps the provided channel.
|
||||
static void NewSimpleChannel(nsIURI* aURI, nsILoadInfo* aLoadinfo,
|
||||
RemoteStreamGetter* aStreamGetter,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "RemoteStreamGetter.h"
|
||||
|
||||
#include "mozilla/MozPromise.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/ResultExtensions.h"
|
||||
|
@ -25,8 +25,10 @@ RemoteStreamGetter::RemoteStreamGetter(nsIURI* aURI, nsILoadInfo* aLoadInfo)
|
|||
|
||||
// Request an input stream from the parent.
|
||||
RequestOrReason RemoteStreamGetter::GetAsync(nsIStreamListener* aListener,
|
||||
nsIChannel* aChannel) {
|
||||
nsIChannel* aChannel,
|
||||
Method aMethod) {
|
||||
MOZ_ASSERT(IsNeckoChild());
|
||||
MOZ_ASSERT(aMethod);
|
||||
|
||||
mListener = aListener;
|
||||
mChannel = aChannel;
|
||||
|
@ -35,14 +37,11 @@ RequestOrReason RemoteStreamGetter::GetAsync(nsIStreamListener* aListener,
|
|||
|
||||
RefPtr<RemoteStreamGetter> self = this;
|
||||
|
||||
// Request an input stream for this moz-page-thumb URI.
|
||||
gNeckoChild->SendGetPageThumbStream(mURI)->Then(
|
||||
(gNeckoChild->*aMethod)(mURI)->Then(
|
||||
GetMainThreadSerialEventTarget(), __func__,
|
||||
[self](const RefPtr<nsIInputStream>& stream) {
|
||||
self->OnStream(do_AddRef(stream));
|
||||
},
|
||||
[self](const Maybe<RemoteStreamInfo>& info) { self->OnStream(info); },
|
||||
[self](const mozilla::ipc::ResponseRejectReason) {
|
||||
self->OnStream(nullptr);
|
||||
self->OnStream(Nothing());
|
||||
});
|
||||
return RequestOrCancelable(WrapNotNull(cancelableRequest));
|
||||
}
|
||||
|
@ -77,27 +76,33 @@ void RemoteStreamGetter::CancelRequest(nsIStreamListener* aListener,
|
|||
}
|
||||
|
||||
// Handle an input stream sent from the parent.
|
||||
void RemoteStreamGetter::OnStream(already_AddRefed<nsIInputStream> aStream) {
|
||||
void RemoteStreamGetter::OnStream(const Maybe<RemoteStreamInfo>& aStreamInfo) {
|
||||
MOZ_ASSERT(IsNeckoChild());
|
||||
MOZ_ASSERT(mChannel);
|
||||
MOZ_ASSERT(mListener);
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream = std::move(aStream);
|
||||
nsCOMPtr<nsIChannel> channel = std::move(mChannel);
|
||||
|
||||
// We must keep an owning reference to the listener until we pass it on
|
||||
// to AsyncRead.
|
||||
nsCOMPtr<nsIStreamListener> listener = mListener.forget();
|
||||
|
||||
if (aStreamInfo.isNothing()) {
|
||||
// The parent didn't send us back a stream.
|
||||
CancelRequest(listener, channel, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mCanceled) {
|
||||
// The channel that has created this stream getter has been canceled.
|
||||
CancelRequest(listener, channel, mStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream = std::move(aStreamInfo.ref().inputStream());
|
||||
if (!stream) {
|
||||
// The parent didn't send us back a stream.
|
||||
CancelRequest(listener, channel, NS_ERROR_FILE_ACCESS_DENIED);
|
||||
// We somehow failed to get a stream, so just cancel the request.
|
||||
CancelRequest(listener, channel, mStatus);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -110,6 +115,9 @@ void RemoteStreamGetter::OnStream(already_AddRefed<nsIInputStream> aStream) {
|
|||
return;
|
||||
}
|
||||
|
||||
channel->SetContentType(aStreamInfo.ref().contentType());
|
||||
channel->SetContentLength(aStreamInfo.ref().contentLength());
|
||||
|
||||
rv = pump->AsyncRead(listener);
|
||||
if (NS_FAILED(rv)) {
|
||||
CancelRequest(listener, channel, rv);
|
||||
|
|
|
@ -7,16 +7,27 @@
|
|||
#ifndef RemoteStreamGetter_h___
|
||||
#define RemoteStreamGetter_h___
|
||||
|
||||
#include "LoadInfo.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIInputStreamPump.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsICancelable.h"
|
||||
#include "SimpleChannel.h"
|
||||
#include "mozilla/net/NeckoChannelParams.h"
|
||||
#include "mozilla/net/NeckoChild.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
class nsILoadInfo;
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
using RemoteStreamPromise =
|
||||
mozilla::MozPromise<RemoteStreamInfo, nsresult, false>;
|
||||
using Method = RefPtr<
|
||||
MozPromise<Maybe<RemoteStreamInfo>, ipc::ResponseRejectReason, true>> (
|
||||
PNeckoChild::*)(nsIURI*);
|
||||
|
||||
/**
|
||||
* Helper class used with SimpleChannel to asynchronously obtain an input
|
||||
* stream and metadata from the parent for a remote protocol load from the
|
||||
|
@ -30,10 +41,11 @@ class RemoteStreamGetter final : public nsICancelable {
|
|||
RemoteStreamGetter(nsIURI* aURI, nsILoadInfo* aLoadInfo);
|
||||
|
||||
// Get an input stream from the parent asynchronously.
|
||||
RequestOrReason GetAsync(nsIStreamListener* aListener, nsIChannel* aChannel);
|
||||
RequestOrReason GetAsync(nsIStreamListener* aListener, nsIChannel* aChannel,
|
||||
Method aMethod);
|
||||
|
||||
// Handle an input stream being returned from the parent
|
||||
void OnStream(already_AddRefed<nsIInputStream> aStream);
|
||||
void OnStream(const Maybe<RemoteStreamInfo>& aStreamInfo);
|
||||
|
||||
static void CancelRequest(nsIStreamListener* aListener, nsIChannel* aChannel,
|
||||
nsresult aResult);
|
||||
|
|
Загрузка…
Ссылка в новой задаче