toolkit/modules/Http.jsm

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 const EXPORTED_SYMBOLS = ["httpRequest", "percentEncode"];
     7 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
     9 // Strictly follow RFC 3986 when encoding URI components.
    10 // Accepts a unescaped string and returns the URI encoded string for use in
    11 // an HTTP request.
    12 function percentEncode(aString)
    13   encodeURIComponent(aString).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
    15 /*
    16  * aOptions can have a variety of fields:
    17  *  headers, an array of headers
    18  *  postData, this can be:
    19  *    a string: send it as is
    20  *    an array of parameters: encode as form values
    21  *    null/undefined: no POST data.
    22  *  method, GET, POST or PUT (this is set automatically if postData exists).
    23  *  onLoad, a function handle to call when the load is complete, it takes two
    24  *          parameters: the responseText and the XHR object.
    25  *  onError, a function handle to call when an error occcurs, it takes three
    26  *          parameters: the error, the responseText and the XHR object.
    27  *  logger, an object that implements the debug and log methods (e.g. log.jsm).
    28  *
    29  * Headers or post data are given as an array of arrays, for each each inner
    30  * array the first value is the key and the second is the value, e.g.
    31  *  [["key1", "value1"], ["key2", "value2"]].
    32  */
    33 function httpRequest(aUrl, aOptions) {
    34   let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
    35               .createInstance(Ci.nsIXMLHttpRequest);
    36   xhr.mozBackgroundRequest = true; // no error dialogs
    37   xhr.open(aOptions.method || (aOptions.postData ? "POST" : "GET"), aUrl);
    38   xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS | // don't send cookies
    39                           Ci.nsIChannel.LOAD_BYPASS_CACHE |
    40                           Ci.nsIChannel.INHIBIT_CACHING;
    41   xhr.onerror = function(aProgressEvent) {
    42     if (aOptions.onError) {
    43       // adapted from toolkit/mozapps/extensions/nsBlocklistService.js
    44       let request = aProgressEvent.target;
    45       let status;
    46       try {
    47         // may throw (local file or timeout)
    48         status = request.status;
    49       }
    50       catch (e) {
    51         request = request.channel.QueryInterface(Ci.nsIRequest);
    52         status = request.status;
    53       }
    54       // When status is 0 we don't have a valid channel.
    55       let statusText = status ? request.statusText : "offline";
    56       aOptions.onError(statusText, null, this);
    57     }
    58   };
    59   xhr.onload = function(aRequest) {
    60     try {
    61       let target = aRequest.target;
    62       if (aOptions.logger)
    63         aOptions.logger.debug("Received response: " + target.responseText);
    64       if (target.status < 200 || target.status >= 300) {
    65         let errorText = target.responseText;
    66         if (!errorText || /<(ht|\?x)ml\b/i.test(errorText))
    67           errorText = target.statusText;
    68         throw target.status + " - " + errorText;
    69       }
    70       if (aOptions.onLoad)
    71         aOptions.onLoad(target.responseText, this);
    72     } catch (e) {
    73       Cu.reportError(e);
    74       if (aOptions.onError)
    75         aOptions.onError(e, aRequest.target.responseText, this);
    76     }
    77   };
    79   if (aOptions.headers) {
    80     aOptions.headers.forEach(function(header) {
    81       xhr.setRequestHeader(header[0], header[1]);
    82     });
    83   }
    85   // Handle adding postData as defined above.
    86   let POSTData = aOptions.postData || "";
    87   if (Array.isArray(POSTData)) {
    88     xhr.setRequestHeader("Content-Type",
    89                          "application/x-www-form-urlencoded; charset=utf-8");
    90     POSTData = POSTData.map(function(p) p[0] + "=" + percentEncode(p[1]))
    91                        .join("&");
    92   }
    94   if (aOptions.logger) {
    95     aOptions.logger.log("sending request to " + aUrl + " (POSTData = " +
    96                         POSTData + ")");
    97   }
    98   xhr.send(POSTData);
    99   return xhr;
   100 }

mercurial