Bug 628197. Implement do-not-track HTTP header to express user intent to halt tracking across site. r=dwitte, a=jst.
authorSid Stamm <sstamm@mozilla.com>
Wed, 05 Jan 2011 11:53:21 -0800
changeset 61491 6963333a74d1f7a8460d034f374acbc0b5c92e56
parent 61490 408332b0a8342ec2cb2ee4c9a5f4164645785495
child 61492 97e4df25167392923bddc4c6924de728674632ef
push id18366
push userjwatt@jwatt.org
push dateFri, 28 Jan 2011 07:54:23 +0000
treeherdermozilla-central@0e50480c408f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdwitte, jst
bugs628197
milestone2.0b11pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 628197. Implement do-not-track HTTP header to express user intent to halt tracking across site. r=dwitte, a=jst.
modules/libpref/src/init/all.js
netwerk/protocol/http/nsHttpAtomList.h
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -581,16 +581,19 @@ pref("content.sink.pending_event_mode", 
 #endif
 
 // Disable popups from plugins by default
 //   0 = openAllowed
 //   1 = openControlled
 //   2 = openAbused
 pref("privacy.popups.disable_from_plugins", 2);
 
+// "do not track" HTTP header, disabled by default
+pref("privacy.donottrackheader.enabled",    false);
+
 pref("dom.event.contextmenu.enabled",       true);
 
 pref("javascript.enabled",                  true);
 pref("javascript.options.strict",           false);
 #ifdef DEBUG
 pref("javascript.options.strict.debug",     true);
 #endif
 pref("javascript.options.relimit",          true);
--- a/netwerk/protocol/http/nsHttpAtomList.h
+++ b/netwerk/protocol/http/nsHttpAtomList.h
@@ -72,16 +72,17 @@ HTTP_ATOM(Content_Range,             "Co
 HTTP_ATOM(Content_Transfer_Encoding, "Content-Transfer-Encoding")
 HTTP_ATOM(Content_Type,              "Content-Type")
 HTTP_ATOM(Cookie,                    "Cookie")
 HTTP_ATOM(Date,                      "Date")
 HTTP_ATOM(DAV,                       "DAV")
 HTTP_ATOM(Depth,                     "Depth")
 HTTP_ATOM(Derived_From,              "Derived-From")
 HTTP_ATOM(Destination,               "Destination")
+HTTP_ATOM(DoNotTrack,                "DNT")
 HTTP_ATOM(ETag,                      "Etag")
 HTTP_ATOM(Expect,                    "Expect")
 HTTP_ATOM(Expires,                   "Expires")
 HTTP_ATOM(Forwarded,                 "Forwarded")
 HTTP_ATOM(From,                      "From")
 HTTP_ATOM(Host,                      "Host")
 HTTP_ATOM(If,                        "If")
 HTTP_ATOM(If_Match,                  "If-Match")
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -125,16 +125,17 @@ static NS_DEFINE_CID(kSocketProviderServ
 #define UA_SPARE_PLATFORM
 #endif
 
 #define HTTP_PREF_PREFIX        "network.http."
 #define INTL_ACCEPT_LANGUAGES   "intl.accept_languages"
 #define INTL_ACCEPT_CHARSET     "intl.charset.default"
 #define NETWORK_ENABLEIDN       "network.enableIDN"
 #define BROWSER_PREF_PREFIX     "browser.cache."
+#define DONOTTRACK_HEADER_ENABLED "privacy.donottrackheader.enabled"
 
 #define UA_PREF(_pref) UA_PREF_PREFIX _pref
 #define HTTP_PREF(_pref) HTTP_PREF_PREFIX _pref
 #define BROWSER_PREF(_pref) BROWSER_PREF_PREFIX _pref
 
 #define NS_HTTP_PROTOCOL_FLAGS (URI_STD | ALLOWS_PROXY | ALLOWS_PROXY_HTTP | URI_LOADABLE_BY_ANYONE)
 
 //-----------------------------------------------------------------------------
@@ -193,16 +194,17 @@ nsHttpHandler::nsHttpHandler()
     , mLegacyAppName("Mozilla")
     , mLegacyAppVersion("5.0")
     , mProduct("Gecko")
     , mUserAgentIsDirty(PR_TRUE)
     , mUseCache(PR_TRUE)
     , mPromptTempRedirect(PR_TRUE)
     , mSendSecureXSiteReferrer(PR_TRUE)
     , mEnablePersistentHttpsCaching(PR_FALSE)
+    , mDoNotTrackEnabled(PR_FALSE)
 {
 #if defined(PR_LOGGING)
     gHttpLog = PR_NewLogModule("nsHttp");
 #endif
 
     LOG(("Creating nsHttpHandler [this=%x].\n", this));
 
     NS_ASSERTION(!gHttpHandler, "HTTP handler already created!");
@@ -257,16 +259,17 @@ nsHttpHandler::Init()
     nsCOMPtr<nsIPrefBranch2> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
     if (prefBranch) {
         prefBranch->AddObserver(HTTP_PREF_PREFIX, this, PR_TRUE);
         prefBranch->AddObserver(UA_PREF_PREFIX, this, PR_TRUE);
         prefBranch->AddObserver(INTL_ACCEPT_LANGUAGES, this, PR_TRUE); 
         prefBranch->AddObserver(INTL_ACCEPT_CHARSET, this, PR_TRUE);
         prefBranch->AddObserver(NETWORK_ENABLEIDN, this, PR_TRUE);
         prefBranch->AddObserver(BROWSER_PREF("disk_cache_ssl"), this, PR_TRUE);
+        prefBranch->AddObserver(DONOTTRACK_HEADER_ENABLED, this, PR_TRUE);
 
         PrefsChanged(prefBranch, nsnull);
     }
 
     mMisc.AssignLiteral("rv:" MOZILLA_VERSION);
 
     nsCOMPtr<nsIXULAppInfo> appInfo =
         do_GetService("@mozilla.org/xre/app-info;1");
@@ -401,16 +404,23 @@ nsHttpHandler::AddStandardRequestHeaders
         rv = request->SetHeader(nsHttp::Keep_Alive, nsPrintfCString("%u", mIdleTimeout));
         if (NS_FAILED(rv)) return rv;
         connectionType = &keepAlive;
     } else if (useProxy) {
         // Bug 92006
         request->SetHeader(nsHttp::Connection, close);
     }
 
+    // Add the "Do-Not-Track" header
+    if (mDoNotTrackEnabled) {
+      rv = request->SetHeader(nsHttp::DoNotTrack,
+                              NS_LITERAL_CSTRING("1"));
+      if (NS_FAILED(rv)) return rv;
+    }
+
     const nsHttpAtom &header = useProxy ? nsHttp::Proxy_Connection
                                         : nsHttp::Connection;
     return request->SetHeader(header, *connectionType);
 }
 
 PRBool
 nsHttpHandler::IsAcceptableEncoding(const char *enc)
 {
@@ -1121,16 +1131,28 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
         if (enableIDN && !mIDNConverter) {
             mIDNConverter = do_GetService(NS_IDNSERVICE_CONTRACTID);
             NS_ASSERTION(mIDNConverter, "idnSDK not installed");
         }
         else if (!enableIDN && mIDNConverter)
             mIDNConverter = nsnull;
     }
 
+    //
+    // Tracking options
+    //
+
+    if (PREF_CHANGED(DONOTTRACK_HEADER_ENABLED)) {
+        cVar = PR_FALSE;
+        rv = prefs->GetBoolPref(DONOTTRACK_HEADER_ENABLED, &cVar);
+        if (NS_SUCCEEDED(rv)) {
+            mDoNotTrackEnabled = cVar;
+        }
+    }
+
 #undef PREF_CHANGED
 #undef MULTI_PREF_CHANGED
 }
 
 /**
  *  Allocates a C string into that contains a ISO 639 language list
  *  notated with HTTP "q" values for output with a HTTP Accept-Language
  *  header. Previous q values will be stripped because the order of
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -321,16 +321,19 @@ private:
 
     PRPackedBool   mPromptTempRedirect;
     // mSendSecureXSiteReferrer: default is false, 
     // if true allow referrer headers between secure non-matching hosts
     PRPackedBool   mSendSecureXSiteReferrer;
 
     // Persistent HTTPS caching flag
     PRPackedBool   mEnablePersistentHttpsCaching;
+
+    // For broadcasting the preference to not be tracked
+    PRPackedBool   mDoNotTrackEnabled;
 };
 
 //-----------------------------------------------------------------------------
 
 extern nsHttpHandler *gHttpHandler;
 
 //-----------------------------------------------------------------------------
 // nsHttpsHandler - thin wrapper to distinguish the HTTP handler from the