Closes #397, Support authenticated PAC setups in Standalone
Trigger a proxy authentication prompt at startup if a PAC file is installed and one of a few randomly chosen big sites requires a proxy. This also improves general proxy detection by not making a request to S3 unless it would actually be proxied.
This commit is contained in:
parent
db43af33ac
commit
1089856622
3 changed files with 136 additions and 22 deletions
|
@ -473,29 +473,116 @@ Zotero.HTTP = new function() {
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
Zotero.proxyAuthComplete = deferred.promise;
|
Zotero.proxyAuthComplete = deferred.promise;
|
||||||
|
|
||||||
var uri = ZOTERO_CONFIG.PROXY_AUTH_URL;
|
Q.fcall(function () {
|
||||||
|
var uris = Zotero.Prefs.get('proxyAuthenticationURLs').split(',');
|
||||||
Zotero.debug("HTTP GET " + uri);
|
uris = Zotero.Utilities.arrayShuffle(uris);
|
||||||
|
uris.unshift(ZOTERO_CONFIG.PROXY_AUTH_URL);
|
||||||
var xmlhttp = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
|
||||||
.createInstance();
|
return Q.async(function () {
|
||||||
xmlhttp.open("GET", uri, true);
|
let max = 3; // how many URIs to try after the general Zotero one
|
||||||
|
for (let i = 0; i <= max; i++) {
|
||||||
xmlhttp.channel.loadFlags |= Components.interfaces.nsIRequest.LOAD_BYPASS_CACHE;
|
let uri = uris.shift();
|
||||||
|
if (!uri) {
|
||||||
var useMethodjit = Components.utils.methodjit;
|
break;
|
||||||
/** @ignore */
|
}
|
||||||
xmlhttp.onreadystatechange = function() {
|
|
||||||
// XXX Remove when we drop support for Fx <24
|
// For non-Zotero URLs, wait for PAC initialization,
|
||||||
if(useMethodjit !== undefined) Components.utils.methodjit = useMethodjit;
|
// in a rather ugly and inefficient manner
|
||||||
_stateChange(xmlhttp, function (xmlhttp) {
|
if (i == 1) {
|
||||||
Zotero.debug("Proxy auth request completed with status "
|
let installed = yield Q.fcall(_pacInstalled)
|
||||||
+ xmlhttp.status + ": " + xmlhttp.responseText);
|
.then(function (installed) {
|
||||||
|
if (installed) throw true;
|
||||||
|
})
|
||||||
|
.delay(500)
|
||||||
|
.then(_pacInstalled)
|
||||||
|
.then(function (installed) {
|
||||||
|
if (installed) throw true;
|
||||||
|
})
|
||||||
|
.delay(1000)
|
||||||
|
.then(_pacInstalled)
|
||||||
|
.then(function (installed) {
|
||||||
|
if (installed) throw true;
|
||||||
|
})
|
||||||
|
.delay(2000)
|
||||||
|
.then(_pacInstalled)
|
||||||
|
.catch(function () {
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
if (!installed) {
|
||||||
|
Zotero.debug("No general proxy or PAC file found -- assuming direct connection");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let proxyInfo = yield _proxyAsyncResolve(uri);
|
||||||
|
if (proxyInfo) {
|
||||||
|
Zotero.debug("Proxy required for " + uri + " -- making HEAD request to trigger auth prompt");
|
||||||
|
yield Zotero.HTTP.promise("HEAD", uri, {
|
||||||
|
foreground: true,
|
||||||
|
dontCache: true
|
||||||
|
})
|
||||||
|
.catch(function (e) {
|
||||||
|
Components.utils.reportError(e);
|
||||||
|
var msg = "Error connecting to proxy -- proxied requests may not work";
|
||||||
|
Zotero.log(msg, 'error');
|
||||||
|
Zotero.debug(msg, 1);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Zotero.debug("Proxy not required for " + uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
});
|
})();
|
||||||
};
|
})
|
||||||
xmlhttp.send(null);
|
.catch(function (e) {
|
||||||
return xmlhttp;
|
Components.utils.reportError(e);
|
||||||
|
Zotero.debug(e, 1);
|
||||||
|
deferred.resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test if a PAC file is installed
|
||||||
|
*
|
||||||
|
* There might be a better way to do this that doesn't require stepping
|
||||||
|
* through the error log and doing a fragile string comparison.
|
||||||
|
*/
|
||||||
|
_pacInstalled = function () {
|
||||||
|
return Zotero.getErrors(true).some(function (val) val.indexOf("PAC file installed") == 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
_proxyAsyncResolve = function (uri) {
|
||||||
|
Components.utils.import("resource://gre/modules/NetUtil.jsm");
|
||||||
|
var pps = Components.classes["@mozilla.org/network/protocol-proxy-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIProtocolProxyService);
|
||||||
|
var deferred = Q.defer();
|
||||||
|
pps.asyncResolve(
|
||||||
|
NetUtil.newURI(uri),
|
||||||
|
0,
|
||||||
|
{
|
||||||
|
onProxyAvailable: function (req, uri, proxyInfo, status) {
|
||||||
|
//Zotero.debug("onProxyAvailable");
|
||||||
|
//Zotero.debug(status);
|
||||||
|
deferred.resolve(proxyInfo);
|
||||||
|
},
|
||||||
|
|
||||||
|
QueryInterface: function (iid) {
|
||||||
|
const interfaces = [
|
||||||
|
Components.interfaces.nsIProtocolProxyCallback,
|
||||||
|
Components.interfaces.nsISupports
|
||||||
|
];
|
||||||
|
if (!interfaces.some(function(v) { return iid.equals(v) })) {
|
||||||
|
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -575,6 +575,31 @@ Zotero.Utilities = {
|
||||||
return vals;
|
return vals;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return new array with values shuffled
|
||||||
|
*
|
||||||
|
* From http://stackoverflow.com/a/6274398
|
||||||
|
*
|
||||||
|
* @param {Array} arr
|
||||||
|
* @return {Array}
|
||||||
|
*/
|
||||||
|
"arrayShuffle": function (array) {
|
||||||
|
var counter = array.length, temp, index;
|
||||||
|
|
||||||
|
// While there are elements in the array
|
||||||
|
while (counter--) {
|
||||||
|
// Pick a random index
|
||||||
|
index = (Math.random() * counter) | 0;
|
||||||
|
|
||||||
|
// And swap the last element with it
|
||||||
|
temp = array[counter];
|
||||||
|
array[counter] = array[index];
|
||||||
|
array[index] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return new array with duplicate values removed
|
* Return new array with duplicate values removed
|
||||||
|
|
|
@ -22,6 +22,8 @@ pref("extensions.zotero.debug.time", false);
|
||||||
pref("extensions.zotero.automaticScraperUpdates",true);
|
pref("extensions.zotero.automaticScraperUpdates",true);
|
||||||
pref("extensions.zotero.zoteroDotOrgVersionHeader", true);
|
pref("extensions.zotero.zoteroDotOrgVersionHeader", true);
|
||||||
pref("extensions.zotero.triggerProxyAuthentication", true);
|
pref("extensions.zotero.triggerProxyAuthentication", true);
|
||||||
|
// Proxy auth URLs should respond successfully to HEAD requests over HTTP and HTTPS (in case of forced HTTPS requests)
|
||||||
|
pref("extensions.zotero.proxyAuthenticationURLs", 'http://www.acm.org,http://www.ebscohost.com,http://www.elsevier.com,http://www.ieee.org,http://www.jstor.org,http://www.ovid.com,http://www.springer.com,http://www.tandfonline.com');
|
||||||
pref("extensions.zotero.cacheTranslatorData",true);
|
pref("extensions.zotero.cacheTranslatorData",true);
|
||||||
pref("extensions.zotero.showIn", 1);
|
pref("extensions.zotero.showIn", 1);
|
||||||
pref("extensions.zotero.statusBarIcon", 2);
|
pref("extensions.zotero.statusBarIcon", 2);
|
||||||
|
|
Loading…
Reference in a new issue