commit 7a062a74930c7ef398c8792188a8a6604538ac30
parent da21c9c47bccb651ab64eb9211c001fb53d90c1b
Author: Adomas VenĨkauskas <adomas.ven@gmail.com>
Date: Mon, 25 Sep 2017 14:56:57 +0300
Remove connector proxy code
Observing requests, auto-redirecting and learning proxies no longer
relevant on this codebase (and interferes with Scaffold).
Diffstat:
1 file changed, 0 insertions(+), 521 deletions(-)
diff --git a/chrome/content/zotero/xpcom/proxy.js b/chrome/content/zotero/xpcom/proxy.js
@@ -41,9 +41,6 @@ Zotero.Proxies = new function() {
*/
this.init = Zotero.Promise.coroutine(function* () {
if(!this.proxies) {
- var me = this;
- Zotero.MIMETypeHandler.addObserver(function(ch) { me.observe(ch) });
-
var rows = yield Zotero.DB.queryAsync("SELECT * FROM proxies");
Zotero.Proxies.proxies = yield Zotero.Promise.all(
rows.map(row => this.newProxyFromRow(row))
@@ -82,201 +79,6 @@ Zotero.Proxies = new function() {
/**
- * Observe method to capture page loads and determine if they're going through an EZProxy.
- *
- * @param {nsIChannel} channel
- */
- this.observe = Zotero.Promise.coroutine(function* (channel) {
- // try to detect a proxy
- channel.QueryInterface(Components.interfaces.nsIHttpChannel);
- var url = channel.URI.spec;
-
- try {
- var { browser, window } = _getBrowserAndWindow(channel);
- }
- catch (e) {
- Zotero.logError(e);
- }
- if (!browser) {
- Zotero.debug("Couldn't get browser from channel", 2);
- }
-
- // see if there is a proxy we already know
- var m = false;
- var proxy;
- for (proxy of Zotero.Proxies.proxies) {
- if(proxy.proxyID && proxy.regexp && proxy.multiHost) {
- m = proxy.regexp.exec(url);
- if(m) break;
- }
- }
-
- if(m) {
- var host = m[proxy.parameters.indexOf("%h")+1];
- // add this host if we know a proxy
- if(proxy.autoAssociate // if autoAssociate is on
- && channel.responseStatus < 400 // and query was successful
- && !Zotero.Proxies.hosts[host] // and host is not saved
- && proxy.hosts.indexOf(host) === -1
- && !_isBlacklisted(host) // and host is not blacklisted
- ) {
- proxy.hosts.push(host);
- yield proxy.save(true);
-
- if (!browser) return;
- _showNotification(
- browser,
- window,
- Zotero.getString('proxies.notification.associated.label', [host, channel.URI.hostPort]),
- [
- {
- label: "proxies.notification.settings.button",
- callback: () => _prefsOpenCallback(window)
- }
- ]
- );
- }
- } else {
- if (!browser) return;
-
- // otherwise, try to detect a proxy
- var proxy = false;
- for(var detectorName in Zotero.Proxies.Detectors) {
- var detector = Zotero.Proxies.Detectors[detectorName];
- try {
- proxy = detector(channel);
- } catch(e) {
- Zotero.logError(e);
- }
-
- if(!proxy) continue;
- Zotero.debug("Proxies: Detected "+detectorName+" proxy "+proxy.scheme+
- (proxy.multiHost ? " (multi-host)" : " for "+proxy.hosts[0]));
-
- var savedTransparent = false;
- if(Zotero.Proxies.autoRecognize) {
- // Ask to save only if automatic proxy recognition is on
- savedTransparent = _showNotification(
- browser,
- window,
- Zotero.getString('proxies.notification.recognized.label', [proxy.hosts[0], channel.URI.hostPort]),
- [{ label: "proxies.notification.enable.button", callback: function() { _showDialog(proxy.hosts[0], channel.URI.hostPort, proxy); } }]);
- }
-
- yield proxy.save();
-
- break;
- }
- }
-
- // try to get an applicable proxy
- var docShell = browser.docShell;
- if (!docShell) {
- Zotero.logError("Couldn't get docshell");
- return;
- }
-
- if (!docShell || !docShell.allowMetaRedirects) return;
-
- // check that proxy redirection is actually enabled
- if(!Zotero.Proxies.transparent) return;
-
- var proxied = Zotero.Proxies.properToProxy(url, true);
- if(!proxied) return;
-
- if(Zotero.Proxies.disableByDomain) {
- var now = new Date();
-
- // IP update interval is every 15 minutes
- if((now - Zotero.Proxies.lastIPCheck) > 900000) {
- Zotero.Proxies.DNS.getHostnames().then(function (hosts) {
- // if domains necessitate disabling, disable them
- Zotero.Proxies.disabledByDomain = false;
- for (var host of hosts) {
- Zotero.Proxies.disabledByDomain = host.toLowerCase().indexOf(Zotero.Proxies.disableByDomain) != -1;
- if (Zotero.Proxies.disabledByDomain) return;
- }
- _maybeRedirect(channel, browser, window, proxied);
- }, function(e) {
- _maybeRedirect(channel, browser, window, proxied);
- });
- Zotero.Proxies.lastIPCheck = now;
- return;
- }
-
- if(Zotero.Proxies.disabledByDomain) return;
- }
-
- _maybeRedirect(channel, browser, window, proxied);
- });
-
- function _maybeRedirect(channel, browser, window, proxied) {
- channel.QueryInterface(Components.interfaces.nsIHttpChannel);
- var proxiedURI = Services.io.newURI(proxied, null, null);
- if(channel.referrer) {
- // If the referrer is a proxiable host, we already have access (e.g., we're
- // on-campus) and shouldn't redirect
- if(Zotero.Proxies.properToProxy(channel.referrer.spec, true)) {
- Zotero.debug("Proxies: skipping redirect; referrer was proxiable");
- return;
- }
- // If the referrer is the same host as we're about to redirect to, we shouldn't
- // or we risk a loop
- if(channel.referrer.host == proxiedURI.host) {
- Zotero.debug("Proxies: skipping redirect; redirect URI and referrer have same host");
- return;
- }
- }
-
- if(channel.originalURI) {
- // If the original URI was a proxied host, we also shouldn't redirect, since any
- // links handed out by the proxy should already be proxied
- if(Zotero.Proxies.proxyToProper(channel.originalURI.spec, true)) {
- Zotero.debug("Proxies: skipping redirect; original URI was proxied");
- return;
- }
- // Finally, if the original URI is the same as the host we're about to redirect
- // to, then we also risk a loop
- if(channel.originalURI.host == proxiedURI.host) {
- Zotero.debug("Proxies: skipping redirect; redirect URI and original URI have same host");
- return;
- }
- }
-
- // make sure that the top two domains (e.g. gmu.edu in foo.bar.gmu.edu) of the
- // channel and the site to which we're redirecting don't match, to prevent loops.
- const top2DomainsRe = /[^\.]+\.[^\.]+$/;
- top21 = top2DomainsRe.exec(channel.URI.host);
- top22 = top2DomainsRe.exec(proxiedURI.host);
- if(!top21 || !top22 || top21[0] == top22[0]) {
- Zotero.debug("Proxies: skipping redirect; redirect URI and URI have same top 2 domains");
- return;
- }
-
- // Otherwise, redirect. Note that we save the URI we're redirecting from as the
- // referrer, since we can't make a proper redirect
- if(Zotero.Proxies.showRedirectNotification) {
- _showNotification(
- browser,
- window,
- Zotero.getString('proxies.notification.redirected.label', [channel.URI.hostPort, proxiedURI.hostPort]),
- [
- {
- label: "general.dontShowAgain",
- callback: () => _disableRedirectNotification()
- },
- {
- label: "proxies.notification.settings.button",
- callback: () => _prefsOpenCallback(window)
- }
- ]
- );
- }
-
- browser.loadURIWithFlags(proxied, 0, channel.URI, null, null);
- }
-
- /**
* Removes a proxy object from the list of proxy objects
* @returns {Boolean} True if the proxy was in the list, false if it was not
*/
@@ -425,145 +227,6 @@ Zotero.Proxies = new function() {
}
return urlToProxy;
};
-
- /**
- * Determines whether a host is blacklisted, i.e., whether we should refuse to save transparent
- * proxy entries for this host. This is necessary because EZProxy offers to proxy all Google and
- * Wikipedia subdomains, but in practice, this would get really annoying.
- *
- * @type Boolean
- * @private
- */
- function _isBlacklisted(host) {
- /**
- * Regular expression patterns of hosts never to proxy
- * @const
- */
- const hostBlacklist = [
- /edu$/,
- /google\.com$/,
- /wikipedia\.org$/,
- /^[^.]*$/,
- /doubleclick\.net$/
- ];
- /**
- * Regular expression patterns of hosts that should always be proxied, regardless of whether
- * they're on the blacklist
- * @const
- */
- const hostWhitelist = [
- /^scholar\.google\.com$/,
- /^muse\.jhu\.edu$/
- ]
-
- for (let blackPattern of hostBlacklist) {
- if(blackPattern.test(host)) {
- for (let whitePattern of hostWhitelist) {
- if(whitePattern.test(host)) {
- return false;
- }
- }
- return true;
- }
- }
- return false;
- }
-
- /**
- * If transparent is enabled, shows a dialog asking user whether to add a proxy to the
- * transparent proxy list.
- *
- * @param {String} proxiedHost The host that would be redirected through the proxy.
- * @param {String} proxyHost The host through which the given site would be redirected.
- * @returns {Boolean} True if proxy should be added; false if it should not be.
- */
- var _showDialog = Zotero.Promise.coroutine(function* (proxiedHost, proxyHost, proxy) {
- // ask user whether to add this proxy
- var io = {site:proxiedHost, proxy:proxyHost};
- var window = Components.classes["@mozilla.org/appshell/window-mediator;1"]
- .getService(Components.interfaces.nsIWindowMediator)
- .getMostRecentWindow("navigator:browser");
- window.openDialog('chrome://zotero/content/proxy.xul', '', 'chrome,modal', io);
-
- // disable transparent if checkbox checked
- if(io.disable) {
- Zotero.Proxies.autoRecognize = false;
- Zotero.Prefs.set("proxies.autoRecognize", false);
- }
-
- if(io.add) {
- yield proxy.erase();
- yield proxy.save(true);
- }
- });
-
- /**
- * Get browser and window from a channel
- * @return {Object} Object containing the content browser as 'browser' and a ChromeWindow as 'window'
- */
- function _getBrowserAndWindow(channel) {
- let outerWindowID = channel.loadInfo.outerWindowID;
- var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
- .getService(Ci.nsIWindowMediator);
- let outerContentWin = wm.getOuterWindowWithId(outerWindowID);
- if (!outerContentWin) {
- return { browser: null, window: null };
- }
- var browser = outerContentWin.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell).chromeEventHandler;
- return {
- browser,
- window: browser.ownerDocument.defaultView
- };
- }
-
- /**
- * Show a proxy-related notification
- * @param {Browser} browser
- * @param {Window} window
- * @param {String} label - notification text
- * @param {Object[]} buttons - Array of objects with 'label' (for getString()) and 'callback'
- */
- function _showNotification(browser, window, label, buttons) {
- // Get localized button labels
- buttons = buttons.map(function(button) {
- return {
- label: Zotero.getString(button.label),
- callback: button.callback
- }
- });
-
- var listener = function() {
- var nb = window.gBrowser.getNotificationBox();
- nb.appendNotification(label,
- 'zotero-proxy', 'chrome://browser/skin/Info.png', nb.PRIORITY_WARNING_MEDIUM,
- buttons);
- browser.removeEventListener("pageshow", listener, false);
- }
-
- browser.addEventListener("pageshow", listener, false);
- }
-
- /**
- * Disables proxy redirection notification
- */
- function _disableRedirectNotification() {
- Zotero.Proxies.showRedirectNotification = false;
- Zotero.Prefs.set("proxies.showRedirectNotification",false);
- }
-
- /**
- * Opens preferences window
- */
- function _prefsOpenCallback(window) {
- window.openDialog('chrome://zotero/content/preferences/preferences.xul',
- 'zotero-prefs',
- 'chrome,titlebar,toolbar,'
- + Zotero.Prefs.get('browser.preferences.instantApply', true) ? 'dialog=no' : 'modal',
- {"pane":"zotero-prefpane-proxies"}
- );
- }
}
/**
@@ -864,190 +527,6 @@ Zotero.Proxy.prototype.loadHosts = Zotero.Promise.coroutine(function* () {
);
});
-/**
- * Detectors for various proxy systems
- * @namespace
- */
-Zotero.Proxies.Detectors = new Object();
-
-/**
- * Detector for OCLC EZProxy
- * @param {nsIChannel} channel
- * @type Boolean|Zotero.Proxy
- */
-Zotero.Proxies.Detectors.EZProxy = function(channel) {
- // Try to catch links from one proxy-by-port site to another
- if([80, 443, -1].indexOf(channel.URI.port) == -1) {
- // Two options here: we could have a redirect from an EZProxy site to another, or a link
- // If it's a redirect, we'll have to catch the Location: header
- var toProxy = false;
- var fromProxy = false;
- if([301, 302, 303].indexOf(channel.responseStatus) !== -1) {
- try {
- toProxy = Services.io.newURI(channel.getResponseHeader("Location"), null, null);
- fromProxy = channel.URI;
- } catch(e) {}
- } else {
- toProxy = channel.URI;
- fromProxy = channel.referrer;
- }
-
- if(fromProxy && toProxy && fromProxy.host == toProxy.host && fromProxy.port != toProxy.port
- && [80, 443, -1].indexOf(toProxy.port) == -1) {
- var proxy;
- for (proxy of Zotero.Proxies.proxies) {
- if(proxy.regexp) {
- var m = proxy.regexp.exec(fromProxy.spec);
- if(m) break;
- }
- }
- if(m) {
- // Make sure caught proxy is not multi-host and that we don't have this new proxy already
- if(proxy.multiHost || Zotero.Proxies.proxyToProper(toProxy.spec, true)) return false;
-
- // Create a new nsIObserver and nsIChannel to figure out real URL (by failing to
- // send cookies, so we get back to the login page)
- var newChannel = Services.io.newChannelFromURI(toProxy);
- newChannel.originalURI = channel.originalURI ? channel.originalURI : channel.URI;
- newChannel.QueryInterface(Components.interfaces.nsIRequest).loadFlags = newChannel.loadFlags;
- Zotero.debug("Proxies: Identified putative port-by-port EZProxy link from "+fromProxy.hostPort+" to "+toProxy.hostPort);
-
- new Zotero.Proxies.Detectors.EZProxy.Observer(newChannel);
- newChannel.asyncOpen(new Zotero.Proxies.Detectors.EZProxy.DummyStreamListener(), null);
- return false;
- }
- }
- }
-
- // Now try to catch redirects
- if(channel.responseStatus != 302) return false;
- try {
- if(channel.getResponseHeader("Server") != "EZproxy") return false;
- var proxiedURI = Services.io.newURI(channel.getResponseHeader("Location"), null, null);
- } catch(e) {
- return false;
- }
- return Zotero.Proxies.Detectors.EZProxy.learn(channel.URI, proxiedURI);
-}
-
-/**
- * Learn about a mapping from an EZProxy to a normal proxy
- * @param {nsIURI} loginURI The URL of the login page
- * @param {nsIURI} proxiedURI The URI of the page
- * @return {Zotero.Proxy | false}
- */
-Zotero.Proxies.Detectors.EZProxy.learn = function(loginURI, proxiedURI) {
- // look for query
- var m = /\?(?:.+&)?(url|qurl)=([^&]+)/i.exec(loginURI.path);
- if(!m) return false;
-
- // Ignore if we already know about it
- if(Zotero.Proxies.proxyToProper(proxiedURI.spec, true)) return false;
-
- // Found URL
- var properURL = (m[1].toLowerCase() == "qurl" ? unescape(m[2]) : m[2]);
- var properURI = Services.io.newURI(properURL, null, null);
-
- var proxy = false;
- if(loginURI.host == proxiedURI.host && [loginURI.port, 80, 443, -1].indexOf(proxiedURI.port) == -1) {
- // Proxy by port
- proxy = new Zotero.Proxy();
- proxy.multiHost = false;
- proxy.scheme = proxiedURI.scheme+"://"+proxiedURI.hostPort+"/%p";
- proxy.hosts = [properURI.hostPort];
- } else if(proxiedURI.host != loginURI.host && proxiedURI.hostPort.indexOf(properURI.host) != -1) {
- // Proxy by host
- proxy = new Zotero.Proxy();
- proxy.multiHost = proxy.autoAssociate = true;
- proxy.scheme = proxiedURI.scheme+"://"+proxiedURI.hostPort.replace(properURI.host, "%h")+"/%p";
- proxy.hosts = [properURI.hostPort];
- }
- return proxy;
-}
-
-/**
- * @class Do-nothing stream listener
- * @private
- */
-Zotero.Proxies.Detectors.EZProxy.DummyStreamListener = function() {}
-Zotero.Proxies.Detectors.EZProxy.DummyStreamListener.prototype.onDataAvailable = function(request,
- context, inputStream, offset, count) {}
-Zotero.Proxies.Detectors.EZProxy.DummyStreamListener.prototype.onStartRequest = function(request, context) {}
-Zotero.Proxies.Detectors.EZProxy.DummyStreamListener.prototype.onStopRequest = function(request, context, status) {}
-
-/**
- * @class Observer to clear cookies on an HTTP request, then remove itself
- * @private
- */
-Zotero.Proxies.Detectors.EZProxy.Observer = function(newChannel) {
- this.channel = newChannel;
- Services.obs.addObserver(this, "http-on-modify-request", false);
- Services.obs.addObserver(this, "http-on-examine-response", false);
-}
-Zotero.Proxies.Detectors.EZProxy.Observer.prototype.observe = Zotero.Promise.coroutine(function* (aSubject, aTopic, aData) {
- if (aSubject == this.channel) {
- if(aTopic === "http-on-modify-request") {
- try {
- aSubject.QueryInterface(Components.interfaces.nsIHttpChannel).setRequestHeader("Cookie", "", false);
- } catch(e) {
- Zotero.logError(e);
- } finally {
- Services.obs.removeObserver(this, "http-on-modify-request");
- }
- } else if(aTopic === "http-on-examine-response") {
- try {
- // Make sure this is a redirect involving an EZProxy
- if(aSubject.responseStatus !== 302) return;
- try {
- if(aSubject.getResponseHeader("Server") !== "EZproxy") return;
- var loginURL = aSubject.getResponseHeader("Location");
- } catch(e) {
- return;
- }
-
- var proxy = Zotero.Proxies.Detectors.EZProxy.learn(Services.io.newURI(loginURL, null, null), aSubject.URI);
- if(proxy) {
- Zotero.debug("Proxies: Proxy-by-port EZProxy "+aSubject.URI.hostPort+" corresponds to "+proxy.hosts[0]);
- yield proxy.save();
- }
- } catch(e) {
- Zotero.logError(e);
- } finally {
- Services.obs.removeObserver(this, "http-on-examine-response");
- aSubject.cancel(0x80004004 /*NS_ERROR_ABORT*/);
- }
- }
- }
-});
-Zotero.Proxies.Detectors.EZProxy.Observer.prototype.QueryInterface = function(aIID) {
- if (aIID.equals(Components.interfaces.nsISupports) ||
- aIID.equals(Components.interfaces.nsIObserver)) return this;
- throw Components.results.NS_NOINTERFACE;
-}
-
-/**
- * Detector for Juniper Networks WebVPN
- * @param {nsIChannel} channel
- * @type Boolean|Zotero.Proxy
- */
-Zotero.Proxies.Detectors.Juniper = function(channel) {
- const juniperRe = /^(https?:\/\/[^\/:]+(?:\:[0-9]+)?)\/(.*),DanaInfo=([^+,]*)([^+]*)(?:\+(.*))?$/;
- try {
- var url = channel.URI.spec;
- var m = juniperRe.exec(url);
- } catch(e) {
- return false;
- }
- if(!m) return false;
-
- var proxy = new Zotero.Proxy();
- proxy.multiHost = true;
- proxy.autoAssociate = false;
- proxy.scheme = m[1]+"/%d"+",DanaInfo=%h%a+%f";
- proxy.hosts = [m[3]];
- return proxy;
-}
-
Zotero.Proxies.DNS = new function() {
this.getHostnames = function() {
if (!Zotero.isWin && !Zotero.isMac && !Zotero.isLinux) return Zotero.Promise.resolve([]);