diff --git a/src/translation/translate.js b/src/translation/translate.js index 973637b..9fd16e3 100644 --- a/src/translation/translate.js +++ b/src/translation/translate.js @@ -302,6 +302,9 @@ Zotero.Translate.Sandbox = { var translation = Zotero.Translate.newInstance(type); translation._parentTranslator = translate; translation.setTranslatorProvider(translate._translatorProvider); + if (translation instanceof Zotero.Translate.Web || translation instanceof Zotero.Translate.Search) { + translation.setRequestTimeout(translate.requestTimeout); + } if(translation instanceof Zotero.Translate.Export && !(translation instanceof Zotero.Translate.Export)) { throw(new Error("Only export translators may call other export translators")); @@ -2041,6 +2044,15 @@ Zotero.Translate.Web.prototype.setRequestHeaders = function (headers) { this.requestHeaders = headers; }; +/** + * Set a timeout on translator HTTP requests. + * @param {Number | null | undefined} requestTimeout Timeout in milliseconds; 0 to disable; + * null/undefined to use implementation default + */ +Zotero.Translate.Web.prototype.setRequestTimeout = function (requestTimeout) { + this.requestTimeout = requestTimeout; +}; + /** * Sets the location to operate upon * @@ -2621,6 +2633,11 @@ Zotero.Translate.Search.prototype.ERROR_NO_RESULTS = "No items returned from any */ Zotero.Translate.Search.prototype.setCookieSandbox = Zotero.Translate.Web.prototype.setCookieSandbox; +/** + * @borrows Zotero.Translate.Web#setRequestTimeout + */ +Zotero.Translate.Search.prototype.setRequestTimeout = Zotero.Translate.Web.prototype.setRequestTimeout; + /** * Sets the item to be used for searching * @param {Object} item An item, with as many fields as desired, in the format returned by diff --git a/src/utilities_translate.js b/src/utilities_translate.js index f76eb72..efbdd3d 100644 --- a/src/utilities_translate.js +++ b/src/utilities_translate.js @@ -312,7 +312,8 @@ Zotero.Utilities.Translate.prototype.request = async function (url, options = {} body: options.body, responseCharset: options.responseCharset, responseType: options.responseType, - cookieSandbox: this._translate.cookieSandbox + cookieSandbox: this._translate.cookieSandbox, + timeout: this._translate.requestTimeout, }; // If the request fails or a non-2XX status is returned, Zotero.HTTP.request rejects its promise. @@ -426,6 +427,9 @@ Zotero.Utilities.Translate.prototype.doGet = function(urls, processor, done, res translate.complete(false, e); } }, responseCharset, this._translate.cookieSandbox, Object.assign({}, this._translate.requestHeaders, requestHeaders)); + if (translate.requestTimeout !== 0) { + xmlhttp.timeout = translate.requestTimeout || xmlhttp.timeout || 30000; + } } /** @@ -461,6 +465,9 @@ Zotero.Utilities.Translate.prototype.doPost = function(url, body, onDone, header translate.complete(false, e); } }, Object.assign({}, translate.requestHeaders, headers), responseCharset, translate.cookieSandbox ? translate.cookieSandbox : undefined); + if (translate.requestTimeout !== 0) { + xmlhttp.timeout = translate.requestTimeout || xmlhttp.timeout || 30000; + } } Zotero.Utilities.Translate.prototype.urlToProxy = function(url) {