Proxy system overhaul
- Only one preference for recognizing proxies for transparent redirection - Blacklists sites and http://%h/%p - Fixes to EZProxy This will clear all existing proxies from Zotero
This commit is contained in:
parent
5aae6bc9ce
commit
9ca461c59b
|
@ -24,7 +24,7 @@ var openURLServerField;
|
||||||
var openURLVersionMenu;
|
var openURLVersionMenu;
|
||||||
var proxies;
|
var proxies;
|
||||||
var charsets;
|
var charsets;
|
||||||
var _io;
|
var _io = {};
|
||||||
|
|
||||||
function init()
|
function init()
|
||||||
{
|
{
|
||||||
|
@ -47,14 +47,16 @@ function init()
|
||||||
charsetMap[Zotero.Prefs.get("import.charset")] ?
|
charsetMap[Zotero.Prefs.get("import.charset")] ?
|
||||||
charsetMap[Zotero.Prefs.get("import.charset")] : charsetMap["auto"];
|
charsetMap[Zotero.Prefs.get("import.charset")] : charsetMap["auto"];
|
||||||
|
|
||||||
_io = window.arguments[0];
|
if(window.arguments) {
|
||||||
|
_io = window.arguments[0];
|
||||||
if (_io.pane) {
|
|
||||||
var pane = document.getElementById(_io.pane);
|
if(_io.pane) {
|
||||||
document.getElementById('zotero-prefs').showPane(pane);
|
var pane = document.getElementById(_io.pane);
|
||||||
// Quick hack to support install prompt from PDF recognize option
|
document.getElementById('zotero-prefs').showPane(pane);
|
||||||
if (_io.action && _io.action == 'pdftools-install') {
|
// Quick hack to support install prompt from PDF recognize option
|
||||||
checkPDFToolsDownloadVersion();
|
if (_io.action && _io.action == 'pdftools-install') {
|
||||||
|
checkPDFToolsDownloadVersion();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1313,7 +1315,13 @@ function deleteProxy() {
|
||||||
*/
|
*/
|
||||||
function refreshProxyList() {
|
function refreshProxyList() {
|
||||||
// get and sort proxies
|
// get and sort proxies
|
||||||
proxies = Zotero.Proxies.get();
|
proxies = Zotero.Proxies.proxies.slice();
|
||||||
|
for(var i=0; i<proxies.length; i++) {
|
||||||
|
if(!proxies[i].proxyID) {
|
||||||
|
proxies.splice(i, 1);
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
}
|
||||||
proxies = proxies.sort(function(a, b) {
|
proxies = proxies.sort(function(a, b) {
|
||||||
if(a.multiHost) {
|
if(a.multiHost) {
|
||||||
if(b.multiHost) {
|
if(b.multiHost) {
|
||||||
|
@ -1362,7 +1370,6 @@ function refreshProxyList() {
|
||||||
|
|
||||||
document.getElementById('proxyTree').currentIndex = -1;
|
document.getElementById('proxyTree').currentIndex = -1;
|
||||||
document.getElementById('proxyTree-delete').disabled = true;
|
document.getElementById('proxyTree-delete').disabled = true;
|
||||||
document.getElementById('zotero-proxies-autoRecognize').checked = Zotero.Prefs.get("proxies.autoRecognize");
|
|
||||||
document.getElementById('zotero-proxies-transparent').checked = Zotero.Prefs.get("proxies.transparent");
|
document.getElementById('zotero-proxies-transparent').checked = Zotero.Prefs.get("proxies.transparent");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1370,16 +1377,10 @@ function refreshProxyList() {
|
||||||
* Updates proxy autoRecognize and transparent settings based on checkboxes
|
* Updates proxy autoRecognize and transparent settings based on checkboxes
|
||||||
*/
|
*/
|
||||||
function updateProxyPrefs() {
|
function updateProxyPrefs() {
|
||||||
Zotero.Prefs.set("proxies.autoRecognize", document.getElementById('zotero-proxies-autoRecognize').checked);
|
Zotero.Prefs.set("proxies.transparent", document.getElementById('zotero-proxies-transparent').checked);
|
||||||
|
|
||||||
var oldTransparent = Zotero.Prefs.get("proxies.transparent");
|
var oldTransparent = Zotero.Prefs.get("proxies.transparent");
|
||||||
var newTransparent = document.getElementById('zotero-proxies-transparent').checked;
|
var newTransparent = document.getElementById('zotero-proxies-transparent').checked;
|
||||||
if(!oldTransparent && newTransparent) {
|
|
||||||
Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
|
||||||
.getService(Components.interfaces.nsIPromptService).alert(window,
|
|
||||||
Zotero.getString("proxies.enableTransparentWarning.title"),
|
|
||||||
Zotero.getString("proxies.enableTransparentWarning.description"));
|
|
||||||
}
|
|
||||||
Zotero.Prefs.set("proxies.transparent", newTransparent);
|
Zotero.Prefs.set("proxies.transparent", newTransparent);
|
||||||
|
|
||||||
Zotero.Proxies.init()
|
Zotero.Proxies.init()
|
||||||
|
|
|
@ -535,13 +535,16 @@ To add a new preference:
|
||||||
<prefpane id="zotero-prefpane-proxies"
|
<prefpane id="zotero-prefpane-proxies"
|
||||||
label="&zotero.preferences.prefpane.proxies;"
|
label="&zotero.preferences.prefpane.proxies;"
|
||||||
image="chrome://zotero/skin/prefs-proxies.png">
|
image="chrome://zotero/skin/prefs-proxies.png">
|
||||||
<groupbox>
|
<description width="45em" style="font-size: 12px">
|
||||||
<command id="zotero-proxies-update" oncommand="updateProxyPrefs()"/>
|
&zotero.preferences.proxies.desc_before_link;
|
||||||
<checkbox id="zotero-proxies-autoRecognize" label="&zotero.preferences.proxies.autoRecognize;"
|
<label class="text-link" href="http://www.zotero.org/support/proxies"
|
||||||
command="zotero-proxies-update"/>
|
value="&zotero.preferences.proxies.desc_link;"/>
|
||||||
<checkbox id="zotero-proxies-transparent" label="&zotero.preferences.proxies.transparent;"
|
&zotero.preferences.proxies.desc_after_link;
|
||||||
command="zotero-proxies-update"/>
|
</description>
|
||||||
</groupbox>
|
|
||||||
|
<command id="zotero-proxies-update" oncommand="updateProxyPrefs()"/>
|
||||||
|
<checkbox id="zotero-proxies-transparent" label="&zotero.preferences.proxies.transparent;"
|
||||||
|
command="zotero-proxies-update"/>
|
||||||
|
|
||||||
<groupbox flex="1">
|
<groupbox flex="1">
|
||||||
<caption label="&zotero.preferences.proxies.configured;"/>
|
<caption label="&zotero.preferences.proxies.configured;"/>
|
||||||
|
|
|
@ -111,17 +111,18 @@ var Zotero_ProxyEditor = new function() {
|
||||||
|
|
||||||
var hasErrors = proxy.validate();
|
var hasErrors = proxy.validate();
|
||||||
if(hasErrors) {
|
if(hasErrors) {
|
||||||
|
error = hasErrors.shift();
|
||||||
|
|
||||||
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
||||||
.getService(Components.interfaces.nsIPromptService);
|
.getService(Components.interfaces.nsIPromptService);
|
||||||
promptService.alert(
|
promptService.alert(
|
||||||
window,
|
window, Zotero.getString("proxies.error"),
|
||||||
Zotero.getString("proxies.error"),
|
Zotero.getString("proxies.error." + error, hasErrors)
|
||||||
Zotero.getString("proxies.error." + hasErrors)
|
|
||||||
);
|
);
|
||||||
if(window.arguments && window.arguments[0]) proxy.revert();
|
if(window.arguments && window.arguments[0]) proxy.revert();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
proxy.save();
|
proxy.save(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,6 @@
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
Utilities based in part on code taken from Piggy Bank 2.1.1 (BSD-licensed)
|
|
||||||
|
|
||||||
|
|
||||||
***** END LICENSE BLOCK *****
|
***** END LICENSE BLOCK *****
|
||||||
*/
|
*/
|
||||||
|
@ -27,15 +23,17 @@
|
||||||
/**
|
/**
|
||||||
* A singleton to handle URL rewriting proxies
|
* A singleton to handle URL rewriting proxies
|
||||||
* @namespace
|
* @namespace
|
||||||
|
* @property transparent {Boolean} Whether transparent proxy functionality is enabled
|
||||||
|
* @property proxies {Zotero.Proxy[]} All loaded proxies
|
||||||
|
* @property hosts {Zotero.Proxy{}} Object mapping hosts to proxies
|
||||||
*/
|
*/
|
||||||
Zotero.Proxies = new function() {
|
Zotero.Proxies = new function() {
|
||||||
var on = false;
|
this.proxies = false;
|
||||||
var proxies = false;
|
this.transparent = false;
|
||||||
var hosts;
|
this.hosts = {};
|
||||||
|
|
||||||
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||||
.getService(Components.interfaces.nsIIOService);
|
.getService(Components.interfaces.nsIIOService);
|
||||||
var autoRecognize = false;
|
|
||||||
var transparent = false;
|
|
||||||
var lastRecognizedURI = false;
|
var lastRecognizedURI = false;
|
||||||
var lastButton = false;
|
var lastButton = false;
|
||||||
|
|
||||||
|
@ -43,15 +41,21 @@ Zotero.Proxies = new function() {
|
||||||
* Initializes http-on-examine-response observer to intercept page loads and gets preferences
|
* Initializes http-on-examine-response observer to intercept page loads and gets preferences
|
||||||
*/
|
*/
|
||||||
this.init = function() {
|
this.init = function() {
|
||||||
if(!on) {
|
if(!this.proxies) {
|
||||||
var me = this;
|
var me = this;
|
||||||
Zotero.MIMETypeHandler.addObserver(function(ch) { me.observe(ch) });
|
Zotero.MIMETypeHandler.addObserver(function(ch) { me.observe(ch) });
|
||||||
this.get();
|
|
||||||
on = true;
|
var rows = Zotero.DB.query("SELECT * FROM proxies");
|
||||||
|
Zotero.Proxies.proxies = [new Zotero.Proxy(row) for each(row in rows)];
|
||||||
|
|
||||||
|
for each(var proxy in Zotero.Proxies.proxies) {
|
||||||
|
for each(var host in proxy.hosts) {
|
||||||
|
Zotero.Proxies.hosts[host] = proxy;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
autoRecognize = Zotero.Prefs.get("proxies.autoRecognize");
|
Zotero.Proxies.transparent = Zotero.Prefs.get("proxies.transparent");
|
||||||
transparent = Zotero.Prefs.get("proxies.transparent");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,23 +73,22 @@ Zotero.Proxies = new function() {
|
||||||
// see if there is a proxy we already know
|
// see if there is a proxy we already know
|
||||||
var m = false;
|
var m = false;
|
||||||
var proxy;
|
var proxy;
|
||||||
for each(proxy in proxies) {
|
for each(proxy in Zotero.Proxies.proxies) {
|
||||||
if(proxy.regexp && proxy.multiHost) {
|
if(proxy.proxyID && proxy.regexp && proxy.multiHost) {
|
||||||
m = proxy.regexp.exec(url);
|
m = proxy.regexp.exec(url);
|
||||||
if(m) break;
|
if(m) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m) {
|
if(m) {
|
||||||
|
var host = m[proxy.parameters.indexOf("%h")+1];
|
||||||
// add this host if we know a proxy
|
// add this host if we know a proxy
|
||||||
if(proxy.autoAssociate) {
|
if(proxy.autoAssociate && !Zotero.Proxies.hosts[host] && proxy.hosts.indexOf(host) == -1 && !_isBlacklisted(host)) {
|
||||||
var host = m[proxy.parameters.indexOf("%h")+1];
|
// if no saved host and host is not blacklisted, auto associate
|
||||||
if(proxy.hosts.indexOf(host) == -1) {
|
proxy.hosts.push(host);
|
||||||
proxy.hosts.push(host);
|
proxy.save(true);
|
||||||
proxy.save();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if(autoRecognize) {
|
} else {
|
||||||
// otherwise, try to detect a proxy
|
// otherwise, try to detect a proxy
|
||||||
var proxy = false;
|
var proxy = false;
|
||||||
for each(var detector in Zotero.Proxies.Detectors) {
|
for each(var detector in Zotero.Proxies.Detectors) {
|
||||||
|
@ -95,78 +98,50 @@ Zotero.Proxies = new function() {
|
||||||
Components.utils.reportError(e);
|
Components.utils.reportError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!proxy) {
|
if(!proxy) continue;
|
||||||
continue;
|
var transparent = _showDialog(proxy.hosts[0], channel.URI.hostPort);
|
||||||
}
|
proxy.save(transparent);
|
||||||
|
|
||||||
// if transparent is turned off, just save the proxy
|
|
||||||
if(!transparent) {
|
|
||||||
proxy.save();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// otherwise, make sure we want it
|
|
||||||
var io = {site:proxy.hosts[0], proxy:channel.URI.hostPort};
|
|
||||||
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);
|
|
||||||
|
|
||||||
if(io.add) proxy.save();
|
|
||||||
if(io.disable) {
|
|
||||||
transparent = false;
|
|
||||||
Zotero.Prefs.set("proxies.transparent", false);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to get an applicable proxy
|
// try to get an applicable proxy
|
||||||
if(transparent) {
|
var webNav = null;
|
||||||
var webNav = null;
|
try {
|
||||||
try {
|
webNav = channel.notificationCallbacks.QueryInterface(Components.interfaces.nsIWebNavigation);
|
||||||
webNav = channel.notificationCallbacks.QueryInterface(Components.interfaces.nsIWebNavigation);
|
} catch(e) {}
|
||||||
} catch(e) {}
|
|
||||||
|
if(webNav) {
|
||||||
if(webNav) {
|
var proxied = Zotero.Proxies.properToProxy(url, true);
|
||||||
var proxied = this.properToProxy(url, true);
|
if(proxied) {
|
||||||
if(proxied) {
|
channel.QueryInterface(Components.interfaces.nsIHttpChannel);
|
||||||
channel.QueryInterface(Components.interfaces.nsIHttpChannel);
|
// If the referrer is a proxiable host, we already have access
|
||||||
// If the referrer is a proxiable host, we already have access
|
// (e.g., we're on-campus) and shouldn't redirect
|
||||||
// (e.g., we're on-campus) and shouldn't redirect
|
if (channel.referrer) {
|
||||||
if (channel.referrer) {
|
if (Zotero.Proxies.properToProxy(channel.referrer.spec, true)) {
|
||||||
if (this.properToProxy(channel.referrer.spec, true)) {
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
webNav.loadURI(proxied, 0, channel.URI, null, null);
|
|
||||||
}
|
}
|
||||||
|
webNav.loadURI(proxied, 0, channel.URI, null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all proxy objects
|
|
||||||
* @type Zotero.Proxy[]
|
|
||||||
*/
|
|
||||||
this.get = function() {
|
|
||||||
if(!proxies) {
|
|
||||||
var rows = Zotero.DB.query("SELECT * FROM proxies");
|
|
||||||
proxies = [new Zotero.Proxy(row) for each(row in rows)];
|
|
||||||
this.refreshHostMap();
|
|
||||||
}
|
|
||||||
return proxies;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes a proxy object from the list of proxy objects
|
* 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
|
* @returns {Boolean} True if the proxy was in the list, false if it was not
|
||||||
*/
|
*/
|
||||||
this.remove = function(proxy) {
|
this.remove = function(proxy) {
|
||||||
var index = proxies.indexOf(proxy);
|
var index = Zotero.Proxies.proxies.indexOf(proxy);
|
||||||
if(index == -1) return false;
|
if(index == -1) return false;
|
||||||
proxies.splice(index, 1);
|
// remove proxy from proxy list
|
||||||
this.refreshHostMap();
|
Zotero.Proxies.proxies.splice(index, 1);
|
||||||
|
// remove hosts from host list
|
||||||
|
for(var host in Zotero.Proxies.hosts) {
|
||||||
|
if(Zotero.Proxies.hosts[host] == proxy) {
|
||||||
|
delete Zotero.Proxies.hosts[host];
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,10 +149,14 @@ Zotero.Proxies = new function() {
|
||||||
* Inserts a proxy into the host map; necessary when proxies are added
|
* Inserts a proxy into the host map; necessary when proxies are added
|
||||||
*/
|
*/
|
||||||
this.save = function(proxy) {
|
this.save = function(proxy) {
|
||||||
proxies.push(proxy);
|
// add to list of proxies
|
||||||
for each(var host in proxy.hosts) {
|
if(Zotero.Proxies.proxies.indexOf(proxy) == -1) Zotero.Proxies.proxies.push(proxy);
|
||||||
if(!hosts[host]) {
|
|
||||||
hosts[host] = proxy;
|
// if there is a proxy ID (i.e., if this is a persisting, transparent proxy), add to host
|
||||||
|
// list to do reverse mapping
|
||||||
|
if(proxy.proxyID) {
|
||||||
|
for each(var host in proxy.hosts) {
|
||||||
|
Zotero.Proxies.hosts[host] = proxy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,19 +164,22 @@ Zotero.Proxies = new function() {
|
||||||
/**
|
/**
|
||||||
* Refreshes host map; necessary when proxies are changed or deleted
|
* Refreshes host map; necessary when proxies are changed or deleted
|
||||||
*/
|
*/
|
||||||
this.refreshHostMap = function() {
|
this.refreshHostMap = function(proxy) {
|
||||||
hosts = {};
|
// if there is no proxyID, then return immediately, since there is no need to update
|
||||||
for each(var proxy in proxies) {
|
if(!proxy.proxyID) return;
|
||||||
for each(var host in proxy.hosts) {
|
|
||||||
if(!hosts[host]) {
|
// delete hosts that point to this proxy if they no longer exist
|
||||||
hosts[host] = proxy;
|
for(var host in Zotero.Proxies.hosts) {
|
||||||
}
|
if(Zotero.Proxies.hosts[host] == proxy && proxy.hosts.indexOf(host) == -1) {
|
||||||
|
delete Zotero.Proxies.hosts[host];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// add new hosts for this proxy
|
||||||
|
Zotero.Proxies.save(proxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a page's proper URL from a proxied URL
|
* Returns a page's proper URL from a proxied URL. Uses both transparent and opaque proxies.
|
||||||
* @param {String} url
|
* @param {String} url
|
||||||
* @param {Boolean} onlyReturnIfProxied Controls behavior if the given URL is not proxied. If
|
* @param {Boolean} onlyReturnIfProxied Controls behavior if the given URL is not proxied. If
|
||||||
* it is false or unspecified, unproxied URLs are returned verbatim. If it is true, the
|
* it is false or unspecified, unproxied URLs are returned verbatim. If it is true, the
|
||||||
|
@ -205,7 +187,7 @@ Zotero.Proxies = new function() {
|
||||||
* @type String
|
* @type String
|
||||||
*/
|
*/
|
||||||
this.proxyToProper = function(url, onlyReturnIfProxied) {
|
this.proxyToProper = function(url, onlyReturnIfProxied) {
|
||||||
for each(var proxy in proxies) {
|
for each(var proxy in Zotero.Proxies.proxies) {
|
||||||
if(proxy.regexp) {
|
if(proxy.regexp) {
|
||||||
var m = proxy.regexp.exec(url);
|
var m = proxy.regexp.exec(url);
|
||||||
if(m) {
|
if(m) {
|
||||||
|
@ -219,7 +201,7 @@ Zotero.Proxies = new function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a page's proxied URL from the proper URL
|
* Returns a page's proxied URL from the proper URL. Uses only transparent proxies.
|
||||||
* @param {String} url
|
* @param {String} url
|
||||||
* @param {Boolean} onlyReturnIfProxied Controls behavior if the given URL is not proxied. If
|
* @param {Boolean} onlyReturnIfProxied Controls behavior if the given URL is not proxied. If
|
||||||
* it is false or unspecified, unproxied URLs are returned verbatim. If it is true, the
|
* it is false or unspecified, unproxied URLs are returned verbatim. If it is true, the
|
||||||
|
@ -228,13 +210,78 @@ Zotero.Proxies = new function() {
|
||||||
*/
|
*/
|
||||||
this.properToProxy = function(url, onlyReturnIfProxied) {
|
this.properToProxy = function(url, onlyReturnIfProxied) {
|
||||||
var uri = ioService.newURI(url, null, null);
|
var uri = ioService.newURI(url, null, null);
|
||||||
if(hosts[uri.hostPort]) {
|
if(Zotero.Proxies.hosts[uri.hostPort] && Zotero.Proxies.hosts[uri.hostPort].proxyID) {
|
||||||
var toProxy = hosts[uri.hostPort].toProxy(uri);
|
var toProxy = Zotero.Proxies.hosts[uri.hostPort].toProxy(uri);
|
||||||
Zotero.debug("Zotero.Proxies.properToProxy: "+url+" to "+toProxy);
|
Zotero.debug("Zotero.Proxies.properToProxy: "+url+" to "+toProxy);
|
||||||
return toProxy;
|
return toProxy;
|
||||||
}
|
}
|
||||||
return (onlyReturnIfProxied ? false : url);
|
return (onlyReturnIfProxied ? false : url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 = [
|
||||||
|
/google\.com$/,
|
||||||
|
/wikipedia\.org$/
|
||||||
|
];
|
||||||
|
/**
|
||||||
|
* Regular expression patterns of hosts that should always be proxied, regardless of whether
|
||||||
|
* they're on the blacklist
|
||||||
|
* @const
|
||||||
|
*/
|
||||||
|
const hostWhitelist = [
|
||||||
|
/^scholar\.google\.com$/
|
||||||
|
]
|
||||||
|
|
||||||
|
for each(var blackPattern in hostBlacklist) {
|
||||||
|
if(blackPattern.test(host)) {
|
||||||
|
for each(var whitePattern in 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.
|
||||||
|
*/
|
||||||
|
function _showDialog(proxiedHost, proxyHost) {
|
||||||
|
if(!Zotero.Proxies.transparent) return false;
|
||||||
|
|
||||||
|
// 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.transparent = false;
|
||||||
|
Zotero.Prefs.set("proxies.transparent", false);
|
||||||
|
}
|
||||||
|
return io.add;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -260,7 +307,7 @@ const Zotero_Proxy_schemeParameters = {
|
||||||
"%p":"(.*?)", // path
|
"%p":"(.*?)", // path
|
||||||
"%d":"(.*?)", // directory
|
"%d":"(.*?)", // directory
|
||||||
"%f":"(.*?)", // filename
|
"%f":"(.*?)", // filename
|
||||||
"%a":"(.*?)" // filename
|
"%a":"(.*?)" // anything
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -275,13 +322,13 @@ const Zotero_Proxy_schemeParameterRegexps = {
|
||||||
"%a":/([^%])%a/
|
"%a":/([^%])%a/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Zotero_Proxy_metaRegexp = /[-[\]{}()*+?.\\^$|,#\s]/g;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles the regular expression against which we match URLs to determine if this proxy is in use
|
* Compiles the regular expression against which we match URLs to determine if this proxy is in use
|
||||||
* and saves it in this.regexp
|
* and saves it in this.regexp
|
||||||
*/
|
*/
|
||||||
Zotero.Proxy.prototype.compileRegexp = function() {
|
Zotero.Proxy.prototype.compileRegexp = function() {
|
||||||
const metaRe = /[-[\]{}()*+?.\\^$|,#\s]/g;
|
|
||||||
|
|
||||||
// take host only if flagged as multiHost
|
// take host only if flagged as multiHost
|
||||||
var parametersToCheck = Zotero_Proxy_schemeParameters;
|
var parametersToCheck = Zotero_Proxy_schemeParameters;
|
||||||
if(this.multiHost) parametersToCheck["%h"] = "([a-zA-Z0-9]+\\.[a-zA-Z0-9\.]+)";
|
if(this.multiHost) parametersToCheck["%h"] = "([a-zA-Z0-9]+\\.[a-zA-Z0-9\.]+)";
|
||||||
|
@ -309,7 +356,7 @@ Zotero.Proxy.prototype.compileRegexp = function() {
|
||||||
})
|
})
|
||||||
|
|
||||||
// now replace with regexp fragment in reverse order
|
// now replace with regexp fragment in reverse order
|
||||||
var re = "^"+this.scheme.replace(metaRe, "\\$&")+"$";
|
var re = "^"+this.scheme.replace(Zotero_Proxy_metaRegexp, "\\$&")+"$";
|
||||||
for(var i=this.parameters.length-1; i>=0; i--) {
|
for(var i=this.parameters.length-1; i>=0; i--) {
|
||||||
var param = this.parameters[i];
|
var param = this.parameters[i];
|
||||||
re = re.replace(Zotero_Proxy_schemeParameterRegexps[param], "$1"+parametersToCheck[param]);
|
re = re.replace(Zotero_Proxy_schemeParameterRegexps[param], "$1"+parametersToCheck[param]);
|
||||||
|
@ -326,19 +373,30 @@ Zotero.Proxy.prototype.compileRegexp = function() {
|
||||||
*/
|
*/
|
||||||
Zotero.Proxy.prototype.validate = function() {
|
Zotero.Proxy.prototype.validate = function() {
|
||||||
if(this.scheme.length < 8 || (this.scheme.substr(0, 7) != "http://" && this.scheme.substr(0, 8) != "https://")) {
|
if(this.scheme.length < 8 || (this.scheme.substr(0, 7) != "http://" && this.scheme.substr(0, 8) != "https://")) {
|
||||||
return "scheme.noHTTP";
|
return ["scheme.noHTTP"];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this.multiSite && (!this.hosts.length || !this.hosts[0])) {
|
if(!this.multiSite && (!this.hosts.length || !this.hosts[0])) {
|
||||||
return "host.invalid";
|
return ["host.invalid"];
|
||||||
} else if(this.multiSite && !Zotero_Proxy_schemeParameterRegexps["%h"].test(this.scheme)) {
|
} else if(this.multiSite && !Zotero_Proxy_schemeParameterRegexps["%h"].test(this.scheme)) {
|
||||||
return "scheme.noHost";
|
return ["scheme.noHost"];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Zotero_Proxy_schemeParameterRegexps["%p"].test(this.scheme) &&
|
if(!Zotero_Proxy_schemeParameterRegexps["%p"].test(this.scheme) &&
|
||||||
(!Zotero_Proxy_schemeParameterRegexps["%d"].test(this.scheme) ||
|
(!Zotero_Proxy_schemeParameterRegexps["%d"].test(this.scheme) ||
|
||||||
!Zotero_Proxy_schemeParameterRegexps["%f"].test(this.scheme))) {
|
!Zotero_Proxy_schemeParameterRegexps["%f"].test(this.scheme))) {
|
||||||
return "scheme.noPath";
|
return ["scheme.noPath"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.scheme.substr(0, 10) == "http://%h/" || this.scheme.substr(0, 11) == "https://%h/") {
|
||||||
|
return ["scheme.invalid"];
|
||||||
|
}
|
||||||
|
|
||||||
|
for each(var host in this.hosts) {
|
||||||
|
var oldHost = Zotero.Proxies.hosts[host];
|
||||||
|
if(oldHost && oldHost.proxyID && oldHost != this) {
|
||||||
|
return ["host.proxyExists", host];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -346,45 +404,50 @@ Zotero.Proxy.prototype.validate = function() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves any changes to this proxy
|
* Saves any changes to this proxy
|
||||||
|
*
|
||||||
|
* @param {Boolean} transparent True if proxy should be saved as a persisting, transparent proxy
|
||||||
*/
|
*/
|
||||||
Zotero.Proxy.prototype.save = function() {
|
Zotero.Proxy.prototype.save = function(transparent) {
|
||||||
// ensure this proxy is valid
|
// ensure this proxy is valid
|
||||||
Zotero.debug(this);
|
Zotero.debug(this);
|
||||||
var hasErrors = this.validate();
|
var hasErrors = this.validate();
|
||||||
if(hasErrors) throw "Proxy could not be saved because it is invalid: error "+hasErrors;
|
if(hasErrors) throw "Zotero.Proxy: could not be saved because it is invalid: error "+hasErrors[0];
|
||||||
|
|
||||||
this.autoAssociate = this.multiHost && this.autoAssociate;
|
this.autoAssociate = this.multiHost && this.autoAssociate;
|
||||||
this.compileRegexp();
|
this.compileRegexp();
|
||||||
if(this.proxyID) {
|
if(this.proxyID) {
|
||||||
Zotero.Proxies.refreshHostMap();
|
Zotero.Proxies.refreshHostMap(this);
|
||||||
|
if(!transparent) throw "Zotero.Proxy: cannot save transparent proxy without transparent param";
|
||||||
} else {
|
} else {
|
||||||
Zotero.Proxies.save(this);
|
Zotero.Proxies.save(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if(transparent) {
|
||||||
Zotero.DB.beginTransaction();
|
try {
|
||||||
|
Zotero.DB.beginTransaction();
|
||||||
if(this.proxyID) {
|
|
||||||
Zotero.DB.query("UPDATE proxies SET multiHost = ?, autoAssociate = ?, scheme = ? WHERE proxyID = ?",
|
if(this.proxyID) {
|
||||||
[this.multiHost ? 1 : 0, this.autoAssociate ? 1 : 0, this.scheme, this.proxyID]);
|
Zotero.DB.query("UPDATE proxies SET multiHost = ?, autoAssociate = ?, scheme = ? WHERE proxyID = ?",
|
||||||
Zotero.DB.query("DELETE FROM proxyHosts WHERE proxyID = ?", [this.proxyID]);
|
[this.multiHost ? 1 : 0, this.autoAssociate ? 1 : 0, this.scheme, this.proxyID]);
|
||||||
} else {
|
Zotero.DB.query("DELETE FROM proxyHosts WHERE proxyID = ?", [this.proxyID]);
|
||||||
this.proxyID = Zotero.DB.query("INSERT INTO proxies (multiHost, autoAssociate, scheme) VALUES (?, ?, ?)",
|
} else {
|
||||||
[this.multiHost ? 1 : 0, this.autoAssociate ? 1 : 0, this.scheme])
|
this.proxyID = Zotero.DB.query("INSERT INTO proxies (multiHost, autoAssociate, scheme) VALUES (?, ?, ?)",
|
||||||
|
[this.multiHost ? 1 : 0, this.autoAssociate ? 1 : 0, this.scheme])
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hosts = this.hosts.sort();
|
||||||
|
var host;
|
||||||
|
for(var i in this.hosts) {
|
||||||
|
host = this.hosts[i] = this.hosts[i].toLowerCase();
|
||||||
|
Zotero.DB.query("INSERT INTO proxyHosts (proxyID, hostname) VALUES (?, ?)",
|
||||||
|
[this.proxyID, host]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Zotero.DB.commitTransaction();
|
||||||
|
} catch(e) {
|
||||||
|
Zotero.DB.rollbackTransaction();
|
||||||
|
throw(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.hosts = this.hosts.sort();
|
|
||||||
var host;
|
|
||||||
for(var i in this.hosts) {
|
|
||||||
host = this.hosts[i] = this.hosts[i].toLowerCase();
|
|
||||||
Zotero.DB.query("INSERT INTO proxyHosts (proxyID, hostname) VALUES (?, ?)",
|
|
||||||
[this.proxyID, host]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Zotero.DB.commitTransaction();
|
|
||||||
} catch(e) {
|
|
||||||
Zotero.DB.rollbackTransaction();
|
|
||||||
throw(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,17 +463,18 @@ Zotero.Proxy.prototype.revert = function() {
|
||||||
* Deletes this proxy
|
* Deletes this proxy
|
||||||
*/
|
*/
|
||||||
Zotero.Proxy.prototype.erase = function() {
|
Zotero.Proxy.prototype.erase = function() {
|
||||||
if(!this.proxyID) throw "Tried to erase an unsaved proxy";
|
|
||||||
Zotero.Proxies.remove(this);
|
Zotero.Proxies.remove(this);
|
||||||
|
|
||||||
try {
|
if(this.proxyID) {
|
||||||
Zotero.DB.beginTransaction();
|
try {
|
||||||
Zotero.DB.query("DELETE FROM proxyHosts WHERE proxyID = ?", [this.proxyID]);
|
Zotero.DB.beginTransaction();
|
||||||
Zotero.DB.query("DELETE FROM proxies WHERE proxyID = ?", [this.proxyID]);
|
Zotero.DB.query("DELETE FROM proxyHosts WHERE proxyID = ?", [this.proxyID]);
|
||||||
Zotero.DB.commitTransaction();
|
Zotero.DB.query("DELETE FROM proxies WHERE proxyID = ?", [this.proxyID]);
|
||||||
} catch(e) {
|
Zotero.DB.commitTransaction();
|
||||||
Zotero.DB.rollbackTransaction();
|
} catch(e) {
|
||||||
throw(e);
|
Zotero.DB.rollbackTransaction();
|
||||||
|
throw(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,7 +578,7 @@ Zotero.Proxies.Detectors.EZProxy = function(channel) {
|
||||||
if(fromProxy && toProxy && fromProxy.host == toProxy.host && fromProxy.port != toProxy.port
|
if(fromProxy && toProxy && fromProxy.host == toProxy.host && fromProxy.port != toProxy.port
|
||||||
&& [80, 443, -1].indexOf(toProxy.port) == -1) {
|
&& [80, 443, -1].indexOf(toProxy.port) == -1) {
|
||||||
var proxy;
|
var proxy;
|
||||||
for each(proxy in Zotero.Proxies.get()) {
|
for each(proxy in Zotero.Proxies.proxies) {
|
||||||
if(proxy.regexp) {
|
if(proxy.regexp) {
|
||||||
var m = proxy.regexp.exec(fromProxy.spec);
|
var m = proxy.regexp.exec(fromProxy.spec);
|
||||||
if(m) break;
|
if(m) break;
|
||||||
|
@ -569,7 +633,7 @@ Zotero.Proxies.Detectors.EZProxy = function(channel) {
|
||||||
proxy.multiHost = false;
|
proxy.multiHost = false;
|
||||||
proxy.scheme = proxiedURI.scheme+"://"+proxiedURI.hostPort+"/%p";
|
proxy.scheme = proxiedURI.scheme+"://"+proxiedURI.hostPort+"/%p";
|
||||||
proxy.hosts = [properURI.hostPort];
|
proxy.hosts = [properURI.hostPort];
|
||||||
} else if(proxiedURI.host != channel.URI.host) {
|
} else if(proxiedURI.host != channel.URI.host && proxiedURI.hostPort.indexOf(properURI.host) != -1) {
|
||||||
// Proxy by host
|
// Proxy by host
|
||||||
var proxy = new Zotero.Proxy();
|
var proxy = new Zotero.Proxy();
|
||||||
proxy.multiHost = proxy.autoAssociate = true;
|
proxy.multiHost = proxy.autoAssociate = true;
|
||||||
|
@ -628,7 +692,8 @@ Zotero.Proxies.Detectors.Juniper = function(channel) {
|
||||||
if(!m) return false;
|
if(!m) return false;
|
||||||
|
|
||||||
var proxy = new Zotero.Proxy();
|
var proxy = new Zotero.Proxy();
|
||||||
proxy.multiHost = proxy.autoAssociate = true;
|
proxy.multiHost = true;
|
||||||
|
proxy.autoAssociate = false;
|
||||||
proxy.scheme = m[1]+"/%d"+",DanaInfo=%h%a+%f";
|
proxy.scheme = m[1]+"/%d"+",DanaInfo=%h%a+%f";
|
||||||
proxy.hosts = [m[3]];
|
proxy.hosts = [m[3]];
|
||||||
return proxy;
|
return proxy;
|
||||||
|
|
|
@ -2194,6 +2194,11 @@ Zotero.Schema = new function(){
|
||||||
Zotero.DB.query("DROP TABLE savedSearchesOld");
|
Zotero.DB.query("DROP TABLE savedSearchesOld");
|
||||||
Zotero.DB.query("DROP TABLE tagsOld");
|
Zotero.DB.query("DROP TABLE tagsOld");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (i==50) {
|
||||||
|
Zotero.DB.query("DELETE FROM proxyHosts");
|
||||||
|
Zotero.DB.query("DELETE FROM proxies");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateDBVersion('userdata', toVersion);
|
_updateDBVersion('userdata', toVersion);
|
||||||
|
|
|
@ -87,8 +87,10 @@
|
||||||
<!ENTITY zotero.preferences.prefpane.proxies "Proxies">
|
<!ENTITY zotero.preferences.prefpane.proxies "Proxies">
|
||||||
|
|
||||||
<!ENTITY zotero.preferences.proxies.proxyOptions "Proxy Options">
|
<!ENTITY zotero.preferences.proxies.proxyOptions "Proxy Options">
|
||||||
<!ENTITY zotero.preferences.proxies.autoRecognize "Automatically recognize common URL-rewriting proxy systems">
|
<!ENTITY zotero.preferences.proxies.desc_before_link "Zotero will transparently redirect requests through saved proxies. See the">
|
||||||
<!ENTITY zotero.preferences.proxies.transparent "Transparently redirect requests through previously used proxies">
|
<!ENTITY zotero.preferences.proxies.desc_link "proxy documentation">
|
||||||
|
<!ENTITY zotero.preferences.proxies.desc_after_link "for more information.">
|
||||||
|
<!ENTITY zotero.preferences.proxies.transparent "Automatically remember proxied resources">
|
||||||
<!ENTITY zotero.preferences.proxies.configured "Configured Proxies">
|
<!ENTITY zotero.preferences.proxies.configured "Configured Proxies">
|
||||||
<!ENTITY zotero.preferences.proxies.hostname "Hostname">
|
<!ENTITY zotero.preferences.proxies.hostname "Hostname">
|
||||||
<!ENTITY zotero.preferences.proxies.scheme "Scheme">
|
<!ENTITY zotero.preferences.proxies.scheme "Scheme">
|
||||||
|
|
|
@ -519,10 +519,10 @@ proxies.error.scheme.noHTTP = Valid proxy schemes must start with "http://" or
|
||||||
proxies.error.host.invalid = You must enter a full hostname for the site served by this proxy (e.g., jstor.org).
|
proxies.error.host.invalid = You must enter a full hostname for the site served by this proxy (e.g., jstor.org).
|
||||||
proxies.error.scheme.noHost = A multi-site proxy scheme must contain the host variable (%h).
|
proxies.error.scheme.noHost = A multi-site proxy scheme must contain the host variable (%h).
|
||||||
proxies.error.scheme.noPath = A valid proxy scheme must contain either the path variable (%p) or the directory and filename variables (%d and %f).
|
proxies.error.scheme.noPath = A valid proxy scheme must contain either the path variable (%p) or the directory and filename variables (%d and %f).
|
||||||
|
proxies.error.host.proxyExists = You have already defined another proxy for the host %1$S.
|
||||||
|
proxies.error.scheme.invalid = The entered proxy scheme is invalid; it would apply to all hosts.
|
||||||
proxies.recognized.message = Adding this proxy will allow Zotero to recognize items from its pages and will automatically redirect future requests to %1$S through %2$S.
|
proxies.recognized.message = Adding this proxy will allow Zotero to recognize items from its pages and will automatically redirect future requests to %1$S through %2$S.
|
||||||
proxies.recognized.add = Add Proxy
|
proxies.recognized.add = Add Proxy
|
||||||
proxies.enableTransparentWarning.title = Warning
|
|
||||||
proxies.enableTransparentWarning.description = Please ensure that the proxies listed below belong to a library, school, or other institution with which you are affiliated. A malicious proxy could pose a security risk.
|
|
||||||
|
|
||||||
recognizePDF.noOCR = PDF does not contain OCRed text.
|
recognizePDF.noOCR = PDF does not contain OCRed text.
|
||||||
recognizePDF.couldNotRead = Could not read text from PDF.
|
recognizePDF.couldNotRead = Could not read text from PDF.
|
||||||
|
|
|
@ -104,7 +104,6 @@ pref("extensions.zotero.sync.storage.maxUploads", 4);
|
||||||
pref("extensions.zotero.sync.storage.deleteDelayDays", 30);
|
pref("extensions.zotero.sync.storage.deleteDelayDays", 30);
|
||||||
|
|
||||||
// Proxy
|
// Proxy
|
||||||
pref("extensions.zotero.proxies.autoRecognize", true);
|
|
||||||
pref("extensions.zotero.proxies.transparent", true);
|
pref("extensions.zotero.proxies.transparent", true);
|
||||||
|
|
||||||
// Data layer purging
|
// Data layer purging
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
-- 49
|
-- 50
|
||||||
|
|
||||||
-- This file creates tables containing user-specific data -- any changes made
|
-- This file creates tables containing user-specific data -- any changes made
|
||||||
-- here must be mirrored in transition steps in schema.js::_migrateSchema()
|
-- here must be mirrored in transition steps in schema.js::_migrateSchema()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user