Backout c3081b5db3d1 (bug 572652) and 4c77addce789 (bug 655628), as they cause bug 657153 and we are worried about the impact. The reward for keeping this in seems really low as well. a=LegNeato
authorChristian Legnitto <clegnitto@mozilla.com>
Thu, 15 Dec 2011 15:43:44 -0800
changeset 79322 cba021dbebc9060bbbbb6012a2f077144fe2a29e
parent 79309 d2f1a400e4303c8ec267e2e059396a46e7a314c8
child 79323 7018a8ca5a3a1ac82565da0a65f9956651551ac8
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersLegNeato
bugs572652, 655628, 657153
milestone9.0
backs outc3081b5db3d1db9213e5ed4531369f1970b0f60a
Backout c3081b5db3d1 (bug 572652) and 4c77addce789 (bug 655628), as they cause bug 657153 and we are worried about the impact. The reward for keeping this in seems really low as well. a=LegNeato
docshell/base/nsDocShell.cpp
modules/libpref/src/init/all.js
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/http/nsHttpHandler.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -574,16 +574,18 @@ SendPing(void *closure, nsIContent *cont
 
   httpChan->SetRequestMethod(NS_LITERAL_CSTRING("POST"));
 
   // Remove extraneous request headers (to reduce request size)
   httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept"),
                              EmptyCString(), PR_FALSE);
   httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept-language"),
                              EmptyCString(), PR_FALSE);
+  httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept-charset"),
+                             EmptyCString(), PR_FALSE);
   httpChan->SetRequestHeader(NS_LITERAL_CSTRING("accept-encoding"),
                              EmptyCString(), PR_FALSE);
 
   nsCOMPtr<nsIUploadChannel> uploadChan = do_QueryInterface(httpChan);
   if (!uploadChan)
     return;
 
   // To avoid sending an unnecessary Content-Type header, we encode the
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -1086,16 +1086,17 @@ pref("network.proxy.autoconfig_url", "")
 // until we reach interval_max or the PAC file is successfully loaded).
 pref("network.proxy.autoconfig_retry_interval_min", 5);    // 5 seconds
 pref("network.proxy.autoconfig_retry_interval_max", 300);  // 5 minutes
 
 pref("converter.html2txt.structs",          true); // Output structured phrases (strong, em, code, sub, sup, b, i, u)
 pref("converter.html2txt.header_strategy",  1); // 0 = no indention; 1 = indention, increased with header level; 2 = numbering and slight indention
 
 pref("intl.accept_languages",               "chrome://global/locale/intl.properties");
+pref("intl.accept_charsets",                "iso-8859-1,*,utf-8");
 pref("intl.menuitems.alwaysappendaccesskeys","chrome://global/locale/intl.properties");
 pref("intl.menuitems.insertseparatorbeforeaccesskeys","chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.static",     "chrome://global/locale/intl.properties");
 pref("intl.charsetmenu.browser.more1",      "ISO-8859-1, ISO-8859-15, IBM850, x-mac-roman, windows-1252, ISO-8859-14, ISO-8859-7, x-mac-greek, windows-1253, x-mac-icelandic, ISO-8859-10, ISO-8859-3");
 pref("intl.charsetmenu.browser.more2",      "ISO-8859-4, ISO-8859-13, windows-1257, IBM852, ISO-8859-2, x-mac-ce, windows-1250, x-mac-croatian, IBM855, ISO-8859-5, ISO-IR-111, KOI8-R, x-mac-cyrillic, windows-1251, IBM866, KOI8-U, x-mac-ukrainian, ISO-8859-16, x-mac-romanian");
 pref("intl.charsetmenu.browser.more3",      "GB2312, gbk, gb18030, HZ-GB-2312, ISO-2022-CN, Big5, Big5-HKSCS, x-euc-tw, EUC-JP, ISO-2022-JP, Shift_JIS, EUC-KR, x-windows-949, x-johab, ISO-2022-KR");
 pref("intl.charsetmenu.browser.more4",      "armscii-8, GEOSTD8, TIS-620, ISO-8859-11, windows-874, IBM857, ISO-8859-9, x-mac-turkish, windows-1254, x-viet-tcvn5712, VISCII, x-viet-vps, windows-1258, x-mac-devanagari, x-mac-gujarati, x-mac-gurmukhi");
 pref("intl.charsetmenu.browser.more5",      "ISO-8859-6, windows-1256, IBM864, ISO-8859-8-I, windows-1255, ISO-8859-8, IBM862");
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -117,16 +117,17 @@ static NS_DEFINE_CID(kSocketProviderServ
 
 #define UA_PREF_PREFIX          "general.useragent."
 #ifdef XP_WIN
 #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
 
@@ -250,16 +251,17 @@ nsHttpHandler::Init()
     InitUserAgentComponents();
 
     // monitor some preference changes
     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);
@@ -370,16 +372,20 @@ nsHttpHandler::AddStandardRequestHeaders
         rv = request->SetHeader(nsHttp::Accept_Language, mAcceptLanguages);
         if (NS_FAILED(rv)) return rv;
     }
 
     // Add the "Accept-Encoding" header
     rv = request->SetHeader(nsHttp::Accept_Encoding, mAcceptEncodings);
     if (NS_FAILED(rv)) return rv;
 
+    // Add the "Accept-Charset" header
+    rv = request->SetHeader(nsHttp::Accept_Charset, mAcceptCharsets);
+    if (NS_FAILED(rv)) return rv;
+
     // RFC2616 section 19.6.2 states that the "Connection: keep-alive"
     // and "Keep-alive" request headers should not be sent by HTTP/1.1
     // user-agents.  Otherwise, problems with proxy servers (especially
     // transparent proxies) can result.
     //
     // However, we need to send something so that we can use keepalive
     // with HTTP/1.0 servers/proxies. We use "Proxy-Connection:" when 
     // we're talking to an http proxy, and "Connection:" otherwise.
@@ -1077,16 +1083,29 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
         if (pls) {
             nsXPIDLString uval;
             pls->ToString(getter_Copies(uval));
             if (uval)
                 SetAcceptLanguages(NS_ConvertUTF16toUTF8(uval).get());
         } 
     }
 
+    if (PREF_CHANGED(INTL_ACCEPT_CHARSET)) {
+        nsCOMPtr<nsIPrefLocalizedString> pls;
+        prefs->GetComplexValue(INTL_ACCEPT_CHARSET,
+                                NS_GET_IID(nsIPrefLocalizedString),
+                                getter_AddRefs(pls));
+        if (pls) {
+            nsXPIDLString uval;
+            pls->ToString(getter_Copies(uval));
+            if (uval)
+                SetAcceptCharsets(NS_ConvertUTF16toUTF8(uval).get());
+        } 
+    }
+
     //
     // IDN options
     //
 
     if (PREF_CHANGED(NETWORK_ENABLEIDN)) {
         PRBool enableIDN = PR_FALSE;
         prefs->GetBoolPref(NETWORK_ENABLEIDN, &enableIDN);
         // No locking is required here since this method runs in the main
@@ -1196,16 +1215,146 @@ nsHttpHandler::SetAcceptLanguages(const 
 {
     nsCAutoString buf;
     nsresult rv = PrepareAcceptLanguages(aAcceptLanguages, buf);
     if (NS_SUCCEEDED(rv))
         mAcceptLanguages.Assign(buf);
     return rv;
 }
 
+/**
+ *  Allocates a C string into that contains a character set/encoding list
+ *  notated with HTTP "q" values for output with a HTTP Accept-Charset
+ *  header. If the UTF-8 character set is not present, it will be added.
+ *  If a wildcard catch-all is not present, it will be added. If more than
+ *  one charset is set (as of 2001-02-07, only one is used), they will be
+ *  comma delimited and with q values set for each charset in decending order.
+ *
+ *  Ex: passing: "euc-jp"
+ *      returns: "euc-jp,utf-8;q=0.6,*;q=0.6"
+ *
+ *      passing: "UTF-8"
+ *      returns: "UTF-8, *"
+ */
+static nsresult
+PrepareAcceptCharsets(const char *i_AcceptCharset, nsACString &o_AcceptCharset)
+{
+    PRUint32 n, size, wrote, u;
+    PRInt32 available;
+    double q, dec;
+    char *p, *p2, *token, *q_Accept, *o_Accept;
+    const char *acceptable, *comma;
+    PRBool add_utf = PR_FALSE;
+    PRBool add_asterisk = PR_FALSE;
+
+    if (!i_AcceptCharset)
+        acceptable = "";
+    else
+        acceptable = i_AcceptCharset;
+    o_Accept = nsCRT::strdup(acceptable);
+    if (nsnull == o_Accept)
+        return NS_ERROR_OUT_OF_MEMORY;
+    for (p = o_Accept, n = size = 0; '\0' != *p; p++) {
+        if (*p == ',') n++;
+            size++;
+    }
+
+    // only add "utf-8" and "*" to the list if they aren't
+    // already specified.
+
+    if (PL_strcasestr(acceptable, "utf-8") == NULL) {
+        n++;
+        add_utf = PR_TRUE;
+    }
+    if (PL_strchr(acceptable, '*') == NULL) {
+        n++;
+        add_asterisk = PR_TRUE;
+    }
+
+    available = size + ++n * 11 + 1;
+    q_Accept = new char[available];
+    if ((char *) 0 == q_Accept)
+        return NS_ERROR_OUT_OF_MEMORY;
+    *q_Accept = '\0';
+    q = 1.0;
+    dec = q / (double) n;
+    n = 0;
+    p2 = q_Accept;
+    for (token = nsCRT::strtok(o_Accept, ",", &p);
+         token != (char *) 0;
+         token = nsCRT::strtok(p, ",", &p)) {
+        token = net_FindCharNotInSet(token, HTTP_LWS);
+        char* trim;
+        trim = net_FindCharInSet(token, ";" HTTP_LWS);
+        if (trim != (char*)0)  // remove "; q=..." if present
+            *trim = '\0';
+
+        if (*token != '\0') {
+            comma = n++ != 0 ? "," : ""; // delimiter if not first item
+            u = QVAL_TO_UINT(q);
+            if (u < 10)
+                wrote = PR_snprintf(p2, available, "%s%s;q=0.%u", comma, token, u);
+            else
+                wrote = PR_snprintf(p2, available, "%s%s", comma, token);
+            q -= dec;
+            p2 += wrote;
+            available -= wrote;
+            NS_ASSERTION(available > 0, "allocated string not long enough");
+        }
+    }
+    if (add_utf) {
+        comma = n++ != 0 ? "," : ""; // delimiter if not first item
+        u = QVAL_TO_UINT(q);
+        if (u < 10)
+            wrote = PR_snprintf(p2, available, "%sutf-8;q=0.%u", comma, u);
+        else
+            wrote = PR_snprintf(p2, available, "%sutf-8", comma);
+        q -= dec;
+        p2 += wrote;
+        available -= wrote;
+        NS_ASSERTION(available > 0, "allocated string not long enough");
+    }
+    if (add_asterisk) {
+        comma = n++ != 0 ? "," : ""; // delimiter if not first item
+
+        // keep q of "*" equal to the lowest q value
+        // in the event of a tie between the q of "*" and a non-wildcard
+        // the non-wildcard always receives preference.
+
+        q += dec;
+        u = QVAL_TO_UINT(q);
+        if (u < 10)
+            wrote = PR_snprintf(p2, available, "%s*;q=0.%u", comma, u);
+        else
+            wrote = PR_snprintf(p2, available, "%s*", comma);
+        available -= wrote;
+        p2 += wrote;
+        NS_ASSERTION(available > 0, "allocated string not long enough");
+    }
+    nsCRT::free(o_Accept);
+
+    // change alloc from C++ new/delete to nsCRT::strdup's way
+    o_AcceptCharset.Assign(q_Accept);
+#if defined DEBUG_havill
+    printf("Accept-Charset: %s\n", q_Accept);
+#endif
+    delete [] q_Accept;
+    return NS_OK;
+}
+
+nsresult
+nsHttpHandler::SetAcceptCharsets(const char *aAcceptCharsets) 
+{
+    nsCString buf;
+    nsresult rv = PrepareAcceptCharsets(aAcceptCharsets, buf);
+    if (NS_SUCCEEDED(rv))
+        mAcceptCharsets.Assign(buf);
+    return rv;
+}
+
 nsresult
 nsHttpHandler::SetAccept(const char *aAccept) 
 {
     mAccept = aAccept;
     return NS_OK;
 }
 
 nsresult
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -224,16 +224,17 @@ private:
     //
     void     BuildUserAgent();
     void     InitUserAgentComponents();
     void     PrefsChanged(nsIPrefBranch *prefs, const char *pref);
 
     nsresult SetAccept(const char *);
     nsresult SetAcceptLanguages(const char *);
     nsresult SetAcceptEncodings(const char *);
+    nsresult SetAcceptCharsets(const char *);
 
     nsresult InitConnectionMgr();
 
     void     NotifyObservers(nsIHttpChannel *chan, const char *event);
 
 private:
 
     // cached services
@@ -290,16 +291,17 @@ private:
         PRIVATE_BROWSING_OFF = PR_FALSE,
         PRIVATE_BROWSING_ON = PR_TRUE,
         PRIVATE_BROWSING_UNKNOWN = 2
     } mInPrivateBrowsingMode;
 
     nsCString mAccept;
     nsCString mAcceptLanguages;
     nsCString mAcceptEncodings;
+    nsCString mAcceptCharsets;
 
     nsXPIDLCString mDefaultSocketType;
 
     // cache support
     PRUint32                  mLastUniqueID;
     PRUint32                  mSessionStartTime;
 
     // useragent components