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.

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

mercurial