Skip to content

Commit

Permalink
Bug 1170190 - Part 2: Add the nsIHttpChannel::IsTrackingResource() AP…
Browse files Browse the repository at this point in the history
…I to query the channel's tracking annotation; r=mayhemer
  • Loading branch information
ehsan committed Dec 23, 2016
1 parent 2aa37e3 commit cd895c9
Show file tree
Hide file tree
Showing 15 changed files with 151 additions and 8 deletions.
17 changes: 17 additions & 0 deletions netwerk/base/nsChannelClassifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "nsIDocShell.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIHttpChannel.h"
#include "nsIHttpChannelInternal.h"
#include "nsIIOService.h"
#include "nsIParentChannel.h"
Expand All @@ -31,10 +32,12 @@
#include "nsNetUtil.h"
#include "nsPIDOMWindow.h"
#include "nsXULAppAPI.h"
#include "nsQueryObject.h"

#include "mozilla/ErrorNames.h"
#include "mozilla/Logging.h"
#include "mozilla/Preferences.h"
#include "mozilla/net/HttpBaseChannel.h"

namespace mozilla {
namespace net {
Expand Down Expand Up @@ -702,6 +705,20 @@ nsChannelClassifier::OnClassifyComplete(nsresult aErrorCode)

if (aErrorCode == NS_ERROR_TRACKING_URI &&
!mTrackingProtectionEnabled.valueOr(false)) {
if (sAnnotateChannelEnabled) {
nsCOMPtr<nsIParentChannel> parentChannel;
NS_QueryNotificationCallbacks(mChannel, parentChannel);
if (parentChannel) {
// This channel is a parent-process proxy for a child process
// request. We should notify the child process as well.
parentChannel->NotifyTrackingResource();
}
RefPtr<HttpBaseChannel> httpChannel = do_QueryObject(mChannel);
if (httpChannel) {
httpChannel->SetIsTrackingResource();
}
}

if (sLowerNetworkPriority) {
if (LOG_ENABLED()) {
nsCOMPtr<nsIURI> uri;
Expand Down
6 changes: 6 additions & 0 deletions netwerk/base/nsIParentChannel.idl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ interface nsIParentChannel : nsIStreamListener
*/
[noscript] void notifyTrackingProtectionDisabled();

/**
* Called to notify the HttpChannelChild that the resource being loaded
* is on the tracking protection list.
*/
[noscript] void notifyTrackingResource();

/**
* Called to invoke deletion of the IPC protocol.
*/
Expand Down
7 changes: 7 additions & 0 deletions netwerk/protocol/data/DataChannelParent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,13 @@ DataChannelParent::NotifyTrackingProtectionDisabled()
return NS_OK;
}

NS_IMETHODIMP
DataChannelParent::NotifyTrackingResource()
{
// Nothing to do.
return NS_OK;
}

NS_IMETHODIMP
DataChannelParent::Delete()
{
Expand Down
7 changes: 7 additions & 0 deletions netwerk/protocol/ftp/FTPChannelParent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,13 @@ FTPChannelParent::NotifyTrackingProtectionDisabled()
return NS_OK;
}

NS_IMETHODIMP
FTPChannelParent::NotifyTrackingResource()
{
// One day, this should probably be filled in.
return NS_OK;
}

NS_IMETHODIMP
FTPChannelParent::Delete()
{
Expand Down
11 changes: 11 additions & 0 deletions netwerk/protocol/http/HttpBaseChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ HttpBaseChannel::HttpBaseChannel()
, mRequireCORSPreflight(false)
, mReportCollector(new ConsoleReportCollector())
, mForceMainDocumentChannel(false)
, mIsTrackingResource(false)
{
LOG(("Creating HttpBaseChannel @%x\n", this));

Expand Down Expand Up @@ -233,6 +234,9 @@ NS_INTERFACE_MAP_BEGIN(HttpBaseChannel)
NS_INTERFACE_MAP_ENTRY(nsITimedChannel)
NS_INTERFACE_MAP_ENTRY(nsIConsoleReportCollector)
NS_INTERFACE_MAP_ENTRY(nsIThrottledInputChannel)
if (aIID.Equals(NS_GET_IID(HttpBaseChannel))) {
foundInterface = static_cast<nsIWritablePropertyBag*>(this);
} else
NS_INTERFACE_MAP_END_INHERITING(nsHashPropertyBag)

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -1223,6 +1227,13 @@ NS_IMETHODIMP HttpBaseChannel::SetTopLevelContentWindowId(uint64_t aWindowId)
return NS_OK;
}

NS_IMETHODIMP
HttpBaseChannel::GetIsTrackingResource(bool* aIsTrackingResource)
{
*aIsTrackingResource = mIsTrackingResource;
return NS_OK;
}

NS_IMETHODIMP
HttpBaseChannel::GetTransferSize(uint64_t *aTransferSize)
{
Expand Down
16 changes: 16 additions & 0 deletions netwerk/protocol/http/HttpBaseChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
#include "mozilla/net/ChannelEventQueue.h"
#include "nsIThrottledInputChannel.h"

#define HTTP_BASE_CHANNEL_IID \
{ 0x9d5cde03, 0xe6e9, 0x4612, \
{ 0xbf, 0xef, 0xbb, 0x66, 0xf3, 0xbb, 0x74, 0x46 } }


class nsISecurityConsoleMessage;
class nsIPrincipal;

Expand Down Expand Up @@ -94,6 +99,8 @@ class HttpBaseChannel : public nsHashPropertyBag
NS_DECL_NSITIMEDCHANNEL
NS_DECL_NSITHROTTLEDINPUTCHANNEL

NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_BASE_CHANNEL_IID)

HttpBaseChannel();

virtual nsresult Init(nsIURI *aURI, uint32_t aCaps, nsProxyInfo *aProxyInfo,
Expand Down Expand Up @@ -190,6 +197,7 @@ class HttpBaseChannel : public nsHashPropertyBag
NS_IMETHOD SetChannelId(const nsACString& aChannelId) override;
NS_IMETHOD GetTopLevelContentWindowId(uint64_t *aContentWindowId) override;
NS_IMETHOD SetTopLevelContentWindowId(uint64_t aContentWindowId) override;
NS_IMETHOD GetIsTrackingResource(bool* aIsTrackingResource) override;

// nsIHttpChannelInternal
NS_IMETHOD GetDocumentURI(nsIURI **aDocumentURI) override;
Expand Down Expand Up @@ -333,6 +341,11 @@ class HttpBaseChannel : public nsHashPropertyBag
// the new mUploadStream.
void EnsureUploadStreamIsCloneableComplete(nsresult aStatus);

void SetIsTrackingResource()
{
mIsTrackingResource = true;
}

protected:
nsCOMArray<nsISecurityConsoleMessage> mSecurityConsoleMessages;

Expand Down Expand Up @@ -567,12 +580,15 @@ class HttpBaseChannel : public nsHashPropertyBag
nsCString mAvailableCachedAltDataType;

bool mForceMainDocumentChannel;
bool mIsTrackingResource;

nsID mChannelId;

nsString mIntegrityMetadata;
};

NS_DEFINE_STATIC_IID_ACCESSOR(HttpBaseChannel, HTTP_BASE_CHANNEL_IID)

// Share some code while working around C++'s absurd inability to handle casting
// of member functions between base/derived types.
// - We want to store member function pointer to call at resume time, but one
Expand Down
7 changes: 7 additions & 0 deletions netwerk/protocol/http/HttpChannelChild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1497,6 +1497,13 @@ HttpChannelChild::RecvNotifyTrackingProtectionDisabled()
return IPC_OK();
}

mozilla::ipc::IPCResult
HttpChannelChild::RecvNotifyTrackingResource()
{
SetIsTrackingResource();
return IPC_OK();
}

void
HttpChannelChild::FlushedForDiversion()
{
Expand Down
1 change: 1 addition & 0 deletions netwerk/protocol/http/HttpChannelChild.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ class HttpChannelChild final : public PHttpChannelChild
bool IsSuspended();

mozilla::ipc::IPCResult RecvNotifyTrackingProtectionDisabled() override;
mozilla::ipc::IPCResult RecvNotifyTrackingResource() override;
void FlushedForDiversion();

protected:
Expand Down
8 changes: 8 additions & 0 deletions netwerk/protocol/http/HttpChannelParent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,14 @@ HttpChannelParent::NotifyTrackingProtectionDisabled()
return NS_OK;
}

NS_IMETHODIMP
HttpChannelParent::NotifyTrackingResource()
{
if (!mIPCClosed)
Unused << SendNotifyTrackingResource();
return NS_OK;
}

NS_IMETHODIMP
HttpChannelParent::Delete()
{
Expand Down
6 changes: 6 additions & 0 deletions netwerk/protocol/http/NullHttpChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ NullHttpChannel::SetTopLevelContentWindowId(uint64_t aWindowId)
return NS_ERROR_NOT_IMPLEMENTED;
}

NS_IMETHODIMP
NullHttpChannel::GetIsTrackingResource(bool* aIsTrackingResource)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

NS_IMETHODIMP
NullHttpChannel::GetTransferSize(uint64_t *aTransferSize)
{
Expand Down
4 changes: 4 additions & 0 deletions netwerk/protocol/http/PHttpChannel.ipdl
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ child:
// Tell the child that tracking protection was disabled for this load.
async NotifyTrackingProtectionDisabled();

// Tell the child that the resource being loaded is on the tracking
// protection list.
async NotifyTrackingResource();

// Parent has been suspended for diversion; no more events to be enqueued.
async FlushedForDiversion();

Expand Down
8 changes: 8 additions & 0 deletions netwerk/protocol/http/nsIHttpChannel.idl
Original file line number Diff line number Diff line change
Expand Up @@ -469,4 +469,12 @@ interface nsIHttpChannel : nsIChannel
* this channels is being load in.
*/
attribute uint64_t topLevelContentWindowId;

/**
* Returns true if the channel has loaded a resource that is on the tracking
* protection list. This is only available if the
* privacy.trackingprotection.annotate_channels pref is set and its value
* should only be relied on after the channel has established a connection.
*/
[infallible] readonly attribute boolean isTrackingResource;
};
7 changes: 7 additions & 0 deletions netwerk/protocol/viewsource/nsViewSourceChannel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,13 @@ nsViewSourceChannel::SetTopLevelContentWindowId(uint64_t aWindowId)
mHttpChannel->SetTopLevelContentWindowId(aWindowId);
}

NS_IMETHODIMP
nsViewSourceChannel::GetIsTrackingResource(bool* aIsTrackingResource)
{
return !mHttpChannel ? NS_ERROR_NULL_POINTER :
mHttpChannel->GetIsTrackingResource(aIsTrackingResource);
}

NS_IMETHODIMP
nsViewSourceChannel::GetRequestMethod(nsACString & aRequestMethod)
{
Expand Down
48 changes: 40 additions & 8 deletions netwerk/test/unit/test_trackingProtection_annotateChannels.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ do_get_profile();

var Ci = Components.interfaces;

function listener(priority, nextTest) {
function listener(tracking, priority, nextTest) {
this._tracking = tracking;
this._priority = priority;
this._nextTest = nextTest;
}
listener.prototype = {
onStartRequest: function(request, context) {
do_check_eq(request.QueryInterface(Ci.nsIHttpChannel).isTrackingResource,
this._tracking);
do_check_eq(request.QueryInterface(Ci.nsISupportsPriority).priority,
this._priority);
request.cancel(Components.results.NS_ERROR_ABORT);
this._nextTest();
},
onDataAvailable: function(request, context, stream, offset, count) {
Expand All @@ -24,15 +28,17 @@ listener.prototype = {
};

var httpServer;
var origin;
var normalOrigin, trackingOrigin;
var testPriorityMap;
var currentTest;

function setup_test() {
httpServer = new HttpServer();
httpServer.start(-1);
httpServer.identity.setPrimary("http", "tracking.example.com", httpServer.identity.primaryPort);
origin = "http://tracking.example.com:" + httpServer.identity.primaryPort;
httpServer.identity.add("http", "example.com", httpServer.identity.primaryPort);
normalOrigin = "http://localhost:" + httpServer.identity.primaryPort;
trackingOrigin = "http://tracking.example.com:" + httpServer.identity.primaryPort;

runTests();
}
Expand All @@ -45,7 +51,9 @@ function doPriorityTest() {

currentTest = testPriorityMap.shift();
var channel = makeChannel(currentTest.path);
channel.asyncOpen2(new listener(currentTest.expectedPriority, doPriorityTest));
channel.asyncOpen2(new listener(currentTest.expectedTracking,
currentTest.expectedPriority,
doPriorityTest));
}

function makeChannel(path) {
Expand Down Expand Up @@ -76,11 +84,23 @@ var tests =[
Services.prefs.setBoolPref("privacy.trackingprotection.lower_network_priority", false);
testPriorityMap = [
{
path: origin + "/evil.css",
path: normalOrigin + "/innocent.css",
expectedTracking: false,
expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL
},
{
path: origin + "/evil.js",
path: normalOrigin + "/innocent.js",
expectedTracking: false,
expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL
},
{
path: trackingOrigin + "/evil.css",
expectedTracking: false,
expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL
},
{
path: trackingOrigin + "/evil.js",
expectedTracking: false,
expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL
},
];
Expand All @@ -94,11 +114,23 @@ var tests =[
Services.prefs.setBoolPref("privacy.trackingprotection.lower_network_priority", true);
testPriorityMap = [
{
path: origin + "/evil.css",
path: normalOrigin + "/innocent.css",
expectedTracking: false,
expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL
},
{
path: normalOrigin + "/innocent.js",
expectedTracking: false,
expectedPriority: Ci.nsISupportsPriority.PRIORITY_NORMAL
},
{
path: trackingOrigin + "/evil.css",
expectedTracking: true,
expectedPriority: Ci.nsISupportsPriority.PRIORITY_LOWEST
},
{
path: origin + "/evil.js",
path: trackingOrigin + "/evil.js",
expectedTracking: true,
expectedPriority: Ci.nsISupportsPriority.PRIORITY_LOWEST
},
];
Expand Down
6 changes: 6 additions & 0 deletions uriloader/exthandler/nsExternalProtocolHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,12 @@ NS_IMETHODIMP nsExtProtocolChannel::NotifyTrackingProtectionDisabled()
return NS_OK;
}

NS_IMETHODIMP nsExtProtocolChannel::NotifyTrackingResource()
{
// nothing to do
return NS_OK;
}

NS_IMETHODIMP nsExtProtocolChannel::Delete()
{
// nothing to do
Expand Down

0 comments on commit cd895c9

Please sign in to comment.