Bug 1058551 - Support redirects to data: URIs. r=honza

This commit is contained in:
Blake Kaplan 2015-03-27 13:12:37 -07:00
Родитель 1ec2875702
Коммит f1944c7299
15 изменённых файлов: 342 добавлений и 11 удалений

Просмотреть файл

@ -167,6 +167,20 @@ NeckoChild::DeallocPWebSocketChild(PWebSocketChild* child)
return true;
}
PDataChannelChild*
NeckoChild::AllocPDataChannelChild(const uint32_t& channelId)
{
MOZ_ASSERT_UNREACHABLE("Should never get here");
return nullptr;
}
bool
NeckoChild::DeallocPDataChannelChild(PDataChannelChild* child)
{
// NB: See DataChannelChild::ActorDestroy.
return true;
}
PRtspControllerChild*
NeckoChild::AllocPRtspControllerChild()
{

Просмотреть файл

@ -62,6 +62,8 @@ protected:
const URIParams&,
const OptionalURIParams&) override;
virtual bool DeallocPRemoteOpenFileChild(PRemoteOpenFileChild*) override;
virtual PDataChannelChild* AllocPDataChannelChild(const uint32_t& channelId) override;
virtual bool DeallocPDataChannelChild(PDataChannelChild* child) override;
virtual PRtspControllerChild* AllocPRtspControllerChild() override;
virtual bool DeallocPRtspControllerChild(PRtspControllerChild*) override;
virtual PRtspChannelChild*

Просмотреть файл

@ -13,6 +13,7 @@
#include "mozilla/net/WyciwygChannelParent.h"
#include "mozilla/net/FTPChannelParent.h"
#include "mozilla/net/WebSocketChannelParent.h"
#include "mozilla/net/DataChannelParent.h"
#ifdef NECKO_PROTOCOL_rtsp
#include "mozilla/net/RtspControllerParent.h"
#include "mozilla/net/RtspChannelParent.h"
@ -349,6 +350,29 @@ NeckoParent::DeallocPWebSocketParent(PWebSocketParent* actor)
return true;
}
PDataChannelParent*
NeckoParent::AllocPDataChannelParent(const uint32_t &channelId)
{
nsRefPtr<DataChannelParent> p = new DataChannelParent();
return p.forget().take();
}
bool
NeckoParent::DeallocPDataChannelParent(PDataChannelParent* actor)
{
nsRefPtr<DataChannelParent> p = dont_AddRef(static_cast<DataChannelParent*>(actor));
return true;
}
bool
NeckoParent::RecvPDataChannelConstructor(PDataChannelParent* actor,
const uint32_t& channelId)
{
DataChannelParent* p = static_cast<DataChannelParent*>(actor);
p->Init(channelId);
return true;
}
PRtspControllerParent*
NeckoParent::AllocPRtspControllerParent()
{

Просмотреть файл

@ -170,6 +170,14 @@ protected:
virtual mozilla::ipc::IProtocol*
CloneProtocol(Channel* aChannel,
mozilla::ipc::ProtocolCloneContext* aCtx) override;
virtual PDataChannelParent*
AllocPDataChannelParent(const uint32_t& channelId) override;
virtual bool DeallocPDataChannelParent(PDataChannelParent* parent) override;
virtual bool RecvPDataChannelConstructor(PDataChannelParent* aActor,
const uint32_t& channelId) override;
virtual PRtspControllerParent* AllocPRtspControllerParent() override;
virtual bool DeallocPRtspControllerParent(PRtspControllerParent*) override;

Просмотреть файл

@ -0,0 +1,25 @@
/* -*- 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;
namespace mozilla {
namespace net {
async protocol PDataChannel
{
manager PNecko;
parent:
// Note: channels are opened during construction, so no open method here:
// see PNecko.ipdl
__delete__();
};
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -20,6 +20,7 @@ include protocol PDNSRequest;
include protocol PChannelDiverter;
include protocol PBlob; //FIXME: bug #792908
include protocol PFileDescriptorSet;
include protocol PDataChannel;
include protocol PRtspController;
include protocol PRtspChannel;
@ -48,6 +49,7 @@ prio(normal upto urgent) sync protocol PNecko
manages PUDPSocket;
manages PDNSRequest;
manages PRemoteOpenFile;
manages PDataChannel;
manages PRtspController;
manages PRtspChannel;
manages PChannelDiverter;
@ -76,6 +78,13 @@ parent:
SpeculativeConnect(URIParams uri);
HTMLDNSPrefetch(nsString hostname, uint16_t flags);
CancelHTMLDNSPrefetch(nsString hostname, uint16_t flags, nsresult reason);
/**
* channelId is used to establish a connection between redirect channels in
* the parent and the child when we're redirecting to a data: URI.
*/
PDataChannel(uint32_t channelId);
PRtspController();
PRtspChannel(RtspChannelConnectArgs args);
PChannelDiverter(ChannelDiverterArgs channel);

Просмотреть файл

@ -32,6 +32,7 @@ UNIFIED_SOURCES += [
IPDL_SOURCES = [
'NeckoChannelParams.ipdlh',
'PChannelDiverter.ipdl',
'PDataChannel.ipdl',
'PNecko.ipdl',
'PRemoteOpenFile.ipdl',
'PRtspChannel.ipdl',

Просмотреть файл

@ -0,0 +1,70 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=4 sw=4 sts=4 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 "DataChannelChild.h"
#include "mozilla/unused.h"
#include "mozilla/net/NeckoChild.h"
namespace mozilla {
namespace net {
NS_IMPL_ISUPPORTS_INHERITED(DataChannelChild, nsDataChannel, nsIChildChannel)
DataChannelChild::DataChannelChild(nsIURI* aURI)
: nsDataChannel(aURI)
, mIPCOpen(false)
{
}
DataChannelChild::~DataChannelChild()
{
}
NS_IMETHODIMP
DataChannelChild::ConnectParent(uint32_t aId)
{
if (!gNeckoChild->SendPDataChannelConstructor(this, aId)) {
return NS_ERROR_FAILURE;
}
// IPC now has a ref to us.
AddIPDLReference();
return NS_OK;
}
NS_IMETHODIMP
DataChannelChild::CompleteRedirectSetup(nsIStreamListener *aListener,
nsISupports *aContext)
{
nsresult rv = AsyncOpen(aListener, aContext);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (mIPCOpen) {
unused << Send__delete__(this);
}
return NS_OK;
}
void
DataChannelChild::AddIPDLReference()
{
AddRef();
mIPCOpen = true;
}
void
DataChannelChild::ActorDestroy(ActorDestroyReason why)
{
MOZ_ASSERT(mIPCOpen);
mIPCOpen = false;
Release();
}
} // namespace mozilla
} // namespace net

Просмотреть файл

@ -0,0 +1,43 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=4 sw=4 sts=4 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_DATACHANNELCHILD_H
#define NS_DATACHANNELCHILD_H
#include "nsDataChannel.h"
#include "nsIChildChannel.h"
#include "nsISupportsImpl.h"
#include "mozilla/net/PDataChannelChild.h"
namespace mozilla {
namespace net {
class DataChannelChild : public nsDataChannel
, public nsIChildChannel
, public PDataChannelChild
{
public:
explicit DataChannelChild(nsIURI *uri);
NS_DECL_ISUPPORTS
NS_DECL_NSICHILDCHANNEL
protected:
virtual void ActorDestroy(ActorDestroyReason why) override;
private:
~DataChannelChild();
void AddIPDLReference();
bool mIPCOpen;
};
} // namespace mozilla
} // namespace net
#endif /* NS_DATACHANNELCHILD_H */

Просмотреть файл

@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=4 sw=4 sts=4 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 "DataChannelParent.h"
#include "mozilla/Assertions.h"
namespace mozilla {
namespace net {
NS_IMPL_ISUPPORTS(DataChannelParent, nsIParentChannel, nsIStreamListener)
DataChannelParent::~DataChannelParent()
{
}
bool
DataChannelParent::Init(const uint32_t &channelId)
{
nsCOMPtr<nsIChannel> channel;
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
NS_LinkRedirectChannels(channelId, this, getter_AddRefs(channel))));
return true;
}
NS_IMETHODIMP
DataChannelParent::SetParentListener(HttpChannelParentListener* aListener)
{
// Nothing to do.
return NS_OK;
}
NS_IMETHODIMP
DataChannelParent::NotifyTrackingProtectionDisabled()
{
// Nothing to do.
return NS_OK;
}
NS_IMETHODIMP
DataChannelParent::Delete()
{
// Nothing to do.
return NS_OK;
}
void
DataChannelParent::ActorDestroy(ActorDestroyReason why)
{
}
NS_IMETHODIMP
DataChannelParent::OnStartRequest(nsIRequest *aRequest,
nsISupports *aContext)
{
// We don't have a way to prevent nsBaseChannel from calling AsyncOpen on
// the created nsDataChannel. We don't have anywhere to send the data in the
// parent, so abort the binding.
return NS_BINDING_ABORTED;
}
NS_IMETHODIMP
DataChannelParent::OnStopRequest(nsIRequest *aRequest,
nsISupports *aContext,
nsresult aStatusCode)
{
// See above.
MOZ_ASSERT(NS_FAILED(aStatusCode));
return NS_OK;
}
NS_IMETHODIMP
DataChannelParent::OnDataAvailable(nsIRequest *aRequest,
nsISupports *aContext,
nsIInputStream *aInputStream,
uint64_t aOffset,
uint32_t aCount)
{
// See above.
MOZ_CRASH("Should never be called");
}
} // namespace mozilla
} // namespace net

Просмотреть файл

@ -0,0 +1,41 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=4 sw=4 sts=4 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_DATACHANNELPARENT_H
#define NS_DATACHANNELPARENT_H
#include "nsIParentChannel.h"
#include "nsISupportsImpl.h"
#include "mozilla/net/PDataChannelParent.h"
namespace mozilla {
namespace net {
// In order to support HTTP redirects to data:, we need to implement the HTTP
// redirection API, which requires a class that implements nsIParentChannel
// and which calls NS_LinkRedirectChannels.
class DataChannelParent : public nsIParentChannel
, public PDataChannelParent
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPARENTCHANNEL
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
bool Init(const uint32_t& aArgs);
private:
~DataChannelParent();
virtual void ActorDestroy(ActorDestroyReason why) override;
};
} // namespace mozilla
} // namespace net
#endif /* NS_DATACHANNELPARENT_H */

Просмотреть файл

@ -4,11 +4,19 @@
# 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/.
EXPORTS.mozilla.net += [
'DataChannelParent.h',
]
UNIFIED_SOURCES += [
'DataChannelChild.cpp',
'DataChannelParent.cpp',
'nsDataChannel.cpp',
'nsDataHandler.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
FAIL_ON_WARNINGS = True
FINAL_LIBRARY = 'xul'

Просмотреть файл

@ -12,7 +12,8 @@
class nsIInputStream;
class nsDataChannel : public nsBaseChannel {
class nsDataChannel : public nsBaseChannel
{
public:
explicit nsDataChannel(nsIURI *uri) {
SetURI(uri);

Просмотреть файл

@ -7,6 +7,7 @@
#include "nsDataHandler.h"
#include "nsNetCID.h"
#include "nsError.h"
#include "DataChannelChild.h"
static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
@ -108,9 +109,12 @@ nsDataHandler::NewChannel2(nsIURI* uri,
nsIChannel** result)
{
NS_ENSURE_ARG_POINTER(uri);
nsDataChannel* channel = new nsDataChannel(uri);
if (!channel)
return NS_ERROR_OUT_OF_MEMORY;
nsDataChannel* channel;
if (XRE_GetProcessType() == GeckoProcessType_Default) {
channel = new nsDataChannel(uri);
} else {
channel = new mozilla::net::DataChannelChild(uri);
}
NS_ADDREF(channel);
nsresult rv = channel->Init();

Просмотреть файл

@ -44,13 +44,7 @@ function redirectHandler(metadata, response)
function finish_test(request, buffer)
{
if (inChildProcess()) {
// redirects to protocols other than http/ftp will fail until bug 590682 is fixed.
do_check_eq(buffer, response301Body);
} else {
do_check_eq(buffer, redirectTargetBody);
}
do_check_eq(buffer, redirectTargetBody);
httpServer.stop(do_test_finished);
}