Bug 1220007 P2 Make InterceptedChannel's collect logs locally and only flush to nsIChannel on main thread r=bz
--- a/CLOBBER
+++ b/CLOBBER
@@ -17,9 +17,9 @@
#
# Modifying this file will now automatically clobber the buildbot machines \o/
#
# Are you updating CLOBBER because you think it's needed for your WebIDL
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
-Merge day clobber
+Bug 1220007 Clobber since .idl changes not getting picked up on emulator-L in b2g-inbound
--- a/dom/workers/ServiceWorkerEvents.cpp
+++ b/dom/workers/ServiceWorkerEvents.cpp
@@ -108,20 +108,17 @@ namespace {
void
AsyncLog(nsIInterceptedChannel *aInterceptedChannel,
const nsACString& aRespondWithScriptSpec,
uint32_t aRespondWithLineNumber, uint32_t aRespondWithColumnNumber,
const nsACString& aMessageName, const nsTArray<nsString>& aParams)
{
MOZ_ASSERT(aInterceptedChannel);
- // Since the intercepted channel is kept alive and paused while handling
- // the FetchEvent, we are guaranteed the reporter is stable on the worker
- // thread.
- nsIConsoleReportCollector* reporter =
+ nsCOMPtr<nsIConsoleReportCollector> reporter =
aInterceptedChannel->GetConsoleReportCollector();
if (reporter) {
reporter->AddConsoleReport(nsIScriptError::errorFlag,
NS_LITERAL_CSTRING("Service Worker Interception"),
nsContentUtils::eDOM_PROPERTIES,
aRespondWithScriptSpec,
aRespondWithLineNumber,
aRespondWithColumnNumber,
--- a/modules/libjar/InterceptedJARChannel.cpp
+++ b/modules/libjar/InterceptedJARChannel.cpp
@@ -118,16 +118,22 @@ InterceptedJARChannel::SetChannelInfo(mo
{
if (!mChannel) {
return NS_ERROR_FAILURE;
}
return aChannelInfo->ResurrectInfoOnChannel(mChannel);
}
+NS_IMETHODIMP
+InterceptedJARChannel::GetConsoleReportCollector(nsIConsoleReportCollector**)
+{
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
void
InterceptedJARChannel::NotifyController()
{
nsresult rv = NS_NewPipe(getter_AddRefs(mSynthesizedInput),
getter_AddRefs(mResponseBody),
0, UINT32_MAX, true, true);
NS_ENSURE_SUCCESS_VOID(rv);
@@ -141,14 +147,8 @@ InterceptedJARChannel::NotifyController(
rv = dispatcher->Dispatch();
if (NS_WARN_IF(NS_FAILED(rv))) {
rv = ResetInterception();
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"Failed to resume intercepted network request");
}
mController = nullptr;
}
-
-nsIConsoleReportCollector*
-InterceptedJARChannel::GetConsoleReportCollector() const
-{
- return nullptr;
-}
--- a/modules/libjar/InterceptedJARChannel.h
+++ b/modules/libjar/InterceptedJARChannel.h
@@ -48,17 +48,14 @@ class InterceptedJARChannel : public nsI
public:
InterceptedJARChannel(nsJARChannel* aChannel,
nsINetworkInterceptController* aController);
NS_DECL_ISUPPORTS
NS_DECL_NSIINTERCEPTEDCHANNEL
void NotifyController();
-
- virtual nsIConsoleReportCollector*
- GetConsoleReportCollector() const override;
};
} // namespace net
} // namespace mozilla
#endif // InterceptedJARChannel_h
--- a/netwerk/base/nsINetworkInterceptController.idl
+++ b/netwerk/base/nsINetworkInterceptController.idl
@@ -2,16 +2,17 @@
/* 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 "nsISupports.idl"
#include "nsIContentPolicyBase.idl"
interface nsIChannel;
+interface nsIConsoleReportCollector;
interface nsIOutputStream;
interface nsIURI;
%{C++
#include "nsIConsoleReportCollector.h"
namespace mozilla {
namespace dom {
class ChannelInfo;
@@ -23,17 +24,17 @@ class ChannelInfo;
/**
* Interface to allow implementors of nsINetworkInterceptController to control the behaviour
* of intercepted channels without tying implementation details of the interception to
* the actual channel. nsIInterceptedChannel is expected to be implemented by objects
* which do not implement nsIChannel.
*/
-[scriptable, uuid(ea78e439-cc42-4b2d-a42b-85ab55a149d1)]
+[scriptable, uuid(231bb567-90e1-4973-9728-7dab93ab29a8)]
interface nsIInterceptedChannel : nsISupports
{
/**
* Instruct a channel that has been intercepted to continue with the original
* network request.
*/
void resetInterception();
@@ -82,26 +83,27 @@ interface nsIInterceptedChannel : nsISup
void setChannelInfo(in ChannelInfo channelInfo);
/**
* Get the internal load type from the underlying channel.
*/
[noscript]
readonly attribute nsContentPolicyType internalContentPolicyType;
+ [noscript]
+ readonly attribute nsIConsoleReportCollector consoleReportCollector;
+
%{C++
- // Allow access to the inner channel as a ConsoleReportCollector off
- // the main thread. Pure C++ method here to avoid requiring an
- // AddRef() during QI. Callers should not save the returned pointer.
- // May return nullptr.
- //
- // Note: Only safe to use OMT prior to resetInterception(),
- // finishSynthesizedResponse(), and cancel().
- virtual nsIConsoleReportCollector*
- GetConsoleReportCollector() const = 0;
+ already_AddRefed<nsIConsoleReportCollector>
+ GetConsoleReportCollector()
+ {
+ nsCOMPtr<nsIConsoleReportCollector> reporter;
+ GetConsoleReportCollector(getter_AddRefs(reporter));
+ return reporter.forget();
+ }
%}
};
/**
* Interface to allow consumers to dispatch the fetch event asynchronously.
* Consumers get access to this interface by calling channelIntercepted(),
* and they can choose to either dispatch() immediately or do that at some
* later time.
--- a/netwerk/protocol/http/InterceptedChannel.cpp
+++ b/netwerk/protocol/http/InterceptedChannel.cpp
@@ -8,16 +8,17 @@
#include "InterceptedChannel.h"
#include "nsInputStreamPump.h"
#include "nsIPipe.h"
#include "nsIStreamListener.h"
#include "nsHttpChannel.h"
#include "HttpChannelChild.h"
#include "nsHttpResponseHead.h"
+#include "mozilla/ConsoleReportCollector.h"
#include "mozilla/dom/ChannelInfo.h"
namespace mozilla {
namespace net {
extern bool
WillRedirect(const nsHttpResponseHead * response);
@@ -32,16 +33,17 @@ DoAddCacheEntryHeaders(nsHttpChannel *se
nsHttpRequestHead *requestHead,
nsHttpResponseHead *responseHead,
nsISupports *securityInfo);
NS_IMPL_ISUPPORTS(InterceptedChannelBase, nsIInterceptedChannel)
InterceptedChannelBase::InterceptedChannelBase(nsINetworkInterceptController* aController)
: mController(aController)
+, mReportCollector(new ConsoleReportCollector())
{
}
InterceptedChannelBase::~InterceptedChannelBase()
{
}
NS_IMETHODIMP
@@ -102,16 +104,25 @@ InterceptedChannelBase::DoSynthesizeHead
nsAutoCString header = aName + NS_LITERAL_CSTRING(": ") + aValue;
// Overwrite any existing header.
nsresult rv = (*mSynthesizedResponseHead)->ParseHeaderLine(header.get());
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
+NS_IMETHODIMP
+InterceptedChannelBase::GetConsoleReportCollector(nsIConsoleReportCollector** aCollectorOut)
+{
+ MOZ_ASSERT(aCollectorOut);
+ nsCOMPtr<nsIConsoleReportCollector> ref = mReportCollector;
+ ref.forget(aCollectorOut);
+ return NS_OK;
+}
+
InterceptedChannelChrome::InterceptedChannelChrome(nsHttpChannel* aChannel,
nsINetworkInterceptController* aController,
nsICacheEntry* aEntry)
: InterceptedChannelBase(aController)
, mChannel(aChannel)
, mSynthesizedCacheEntry(aEntry)
{
nsresult rv = mChannel->GetApplyConversion(&mOldApplyConversion);
@@ -129,40 +140,32 @@ InterceptedChannelChrome::NotifyControll
mChannel->SetApplyConversion(false);
nsresult rv = mSynthesizedCacheEntry->OpenOutputStream(0, getter_AddRefs(mResponseBody));
NS_ENSURE_SUCCESS_VOID(rv);
DoNotifyController();
}
-nsIConsoleReportCollector*
-InterceptedChannelChrome::GetConsoleReportCollector() const
-{
- // The ConsoleReportCollector should only be used when the inner channel is
- // stable. Nothing should try to use it once we return to the main thread
- // and clear the inner channel.
- MOZ_ASSERT(mChannel);
- return mChannel;
-}
-
NS_IMETHODIMP
InterceptedChannelChrome::GetChannel(nsIChannel** aChannel)
{
NS_IF_ADDREF(*aChannel = mChannel);
return NS_OK;
}
NS_IMETHODIMP
InterceptedChannelChrome::ResetInterception()
{
if (!mChannel) {
return NS_ERROR_NOT_AVAILABLE;
}
+ mReportCollector->FlushConsoleReports(mChannel);
+
mSynthesizedCacheEntry->AsyncDoom(nullptr);
mSynthesizedCacheEntry = nullptr;
mChannel->SetApplyConversion(mOldApplyConversion);
nsCOMPtr<nsIURI> uri;
mChannel->GetURI(getter_AddRefs(uri));
@@ -195,16 +198,18 @@ InterceptedChannelChrome::SynthesizeHead
NS_IMETHODIMP
InterceptedChannelChrome::FinishSynthesizedResponse(const nsACString& aFinalURLSpec)
{
if (!mChannel) {
return NS_ERROR_NOT_AVAILABLE;
}
+ mReportCollector->FlushConsoleReports(mChannel);
+
EnsureSynthesizedResponse();
// If the synthesized response is a redirect, then we want to respect
// the encoding of whatever is loaded as a result.
if (WillRedirect(mSynthesizedResponseHead.ref())) {
nsresult rv = mChannel->SetApplyConversion(mOldApplyConversion);
NS_ENSURE_SUCCESS(rv, rv);
}
@@ -268,16 +273,18 @@ NS_IMETHODIMP
InterceptedChannelChrome::Cancel(nsresult aStatus)
{
MOZ_ASSERT(NS_FAILED(aStatus));
if (!mChannel) {
return NS_ERROR_FAILURE;
}
+ mReportCollector->FlushConsoleReports(mChannel);
+
// we need to use AsyncAbort instead of Cancel since there's no active pump
// to cancel which will provide OnStart/OnStopRequest to the channel.
nsresult rv = mChannel->AsyncAbort(aStatus);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
@@ -317,40 +324,32 @@ InterceptedChannelContent::NotifyControl
nsresult rv = NS_NewPipe(getter_AddRefs(mSynthesizedInput),
getter_AddRefs(mResponseBody),
0, UINT32_MAX, true, true);
NS_ENSURE_SUCCESS_VOID(rv);
DoNotifyController();
}
-nsIConsoleReportCollector*
-InterceptedChannelContent::GetConsoleReportCollector() const
-{
- // The ConsoleReportCollector should only be used when the inner channel is
- // stable. Nothing should try to use it once we return to the main thread
- // and clear the inner channel.
- MOZ_ASSERT(mChannel);
- return mChannel;
-}
-
NS_IMETHODIMP
InterceptedChannelContent::GetChannel(nsIChannel** aChannel)
{
NS_IF_ADDREF(*aChannel = mChannel);
return NS_OK;
}
NS_IMETHODIMP
InterceptedChannelContent::ResetInterception()
{
if (!mChannel) {
return NS_ERROR_NOT_AVAILABLE;
}
+ mReportCollector->FlushConsoleReports(mChannel);
+
mResponseBody = nullptr;
mSynthesizedInput = nullptr;
mChannel->ResetInterception();
mChannel = nullptr;
return NS_OK;
}
@@ -376,16 +375,18 @@ InterceptedChannelContent::SynthesizeHea
NS_IMETHODIMP
InterceptedChannelContent::FinishSynthesizedResponse(const nsACString& aFinalURLSpec)
{
if (NS_WARN_IF(!mChannel)) {
return NS_ERROR_NOT_AVAILABLE;
}
+ mReportCollector->FlushConsoleReports(mChannel);
+
EnsureSynthesizedResponse();
nsCOMPtr<nsIURI> originalURI;
mChannel->GetURI(getter_AddRefs(originalURI));
nsCOMPtr<nsIURI> responseURI;
if (!aFinalURLSpec.IsEmpty()) {
nsresult rv = NS_NewURI(getter_AddRefs(responseURI), aFinalURLSpec);
@@ -415,16 +416,18 @@ NS_IMETHODIMP
InterceptedChannelContent::Cancel(nsresult aStatus)
{
MOZ_ASSERT(NS_FAILED(aStatus));
if (!mChannel) {
return NS_ERROR_FAILURE;
}
+ mReportCollector->FlushConsoleReports(mChannel);
+
// we need to use AsyncAbort instead of Cancel since there's no active pump
// to cancel which will provide OnStart/OnStopRequest to the channel.
nsresult rv = mChannel->AsyncAbort(aStatus);
NS_ENSURE_SUCCESS(rv, rv);
mChannel = nullptr;
mStreamListener = nullptr;
return NS_OK;
}
--- a/netwerk/protocol/http/InterceptedChannel.h
+++ b/netwerk/protocol/http/InterceptedChannel.h
@@ -31,32 +31,35 @@ protected:
nsCOMPtr<nsINetworkInterceptController> mController;
// The stream to write the body of the synthesized response
nsCOMPtr<nsIOutputStream> mResponseBody;
// Response head for use when synthesizing
Maybe<nsAutoPtr<nsHttpResponseHead>> mSynthesizedResponseHead;
+ nsCOMPtr<nsIConsoleReportCollector> mReportCollector;
+
void EnsureSynthesizedResponse();
void DoNotifyController();
nsresult DoSynthesizeStatus(uint16_t aStatus, const nsACString& aReason);
nsresult DoSynthesizeHeader(const nsACString& aName, const nsACString& aValue);
virtual ~InterceptedChannelBase();
public:
explicit InterceptedChannelBase(nsINetworkInterceptController* aController);
// Notify the interception controller that the channel has been intercepted
// and prepare the response body output stream.
virtual void NotifyController() = 0;
NS_DECL_ISUPPORTS
NS_IMETHOD GetResponseBody(nsIOutputStream** aOutput) override;
+ NS_IMETHOD GetConsoleReportCollector(nsIConsoleReportCollector** aCollectorOut) override;
};
class InterceptedChannelChrome : public InterceptedChannelBase
{
// The actual channel being intercepted.
RefPtr<nsHttpChannel> mChannel;
// Writeable cache entry for use when synthesizing a response in a parent process
@@ -77,19 +80,16 @@ public:
NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
NS_IMETHOD Cancel(nsresult aStatus) override;
NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override;
NS_IMETHOD GetInternalContentPolicyType(nsContentPolicyType *aInternalContentPolicyType) override;
virtual void NotifyController() override;
-
- virtual nsIConsoleReportCollector*
- GetConsoleReportCollector() const override;
};
class InterceptedChannelContent : public InterceptedChannelBase
{
// The actual channel being intercepted.
RefPtr<HttpChannelChild> mChannel;
// Reader-side of the response body when synthesizing in a child proces
@@ -108,17 +108,14 @@ public:
NS_IMETHOD GetChannel(nsIChannel** aChannel) override;
NS_IMETHOD SynthesizeStatus(uint16_t aStatus, const nsACString& aReason) override;
NS_IMETHOD SynthesizeHeader(const nsACString& aName, const nsACString& aValue) override;
NS_IMETHOD Cancel(nsresult aStatus) override;
NS_IMETHOD SetChannelInfo(mozilla::dom::ChannelInfo* aChannelInfo) override;
NS_IMETHOD GetInternalContentPolicyType(nsContentPolicyType *aInternalContentPolicyType) override;
virtual void NotifyController() override;
-
- virtual nsIConsoleReportCollector*
- GetConsoleReportCollector() const override;
};
} // namespace net
} // namespace mozilla
#endif // InterceptedChannel_h