Follow meta redirects and use the final URL when processing documents (#1568)
This commit is contained in:
parent
a59ce2c343
commit
ec5424d5ae
2 changed files with 68 additions and 2 deletions
|
@ -355,6 +355,48 @@ Zotero.HTTP = new function() {
|
|||
if (options.debug) {
|
||||
Zotero.debug(xmlhttp.responseText);
|
||||
}
|
||||
|
||||
// Follow meta redirects
|
||||
if (options.responseType === 'document' &&
|
||||
(!options.numRedirects || options.numRedirects < 3)) {
|
||||
let contentType = xmlhttp.getResponseHeader('Content-Type');
|
||||
if (contentType && contentType.startsWith('text/html')) {
|
||||
let meta = xmlhttp.response.querySelector('meta[http-equiv="refresh" i]');
|
||||
if (meta) {
|
||||
let content = meta.getAttribute('content');
|
||||
if (content) {
|
||||
let parts = content.split(/;\s*url=/);
|
||||
// If there's a redirect to another URL in less than 15 seconds,
|
||||
// follow it
|
||||
if (parts.length === 2 && parseInt(parts[0]) <= 15) {
|
||||
let url = parts[1].trim().replace(/^'(.+)'/, '$1');
|
||||
|
||||
// Resolve URL. P.S.: For unknown reason this only works
|
||||
// if server returns 'Content-Type: text/html' header
|
||||
let a = xmlhttp.response.createElement('a');
|
||||
a.href = url;
|
||||
let resolvedUrl = a.href;
|
||||
|
||||
// Make sure the absolute URL is actually resolved
|
||||
if (/^https?:\/\//.test(resolvedUrl)) {
|
||||
if (options.numRedirects) {
|
||||
options.numRedirects++;
|
||||
}
|
||||
else {
|
||||
options.numRedirects = 1;
|
||||
}
|
||||
|
||||
// Meta redirect is always GET
|
||||
return Zotero.HTTP.request("GET", resolvedUrl, options)
|
||||
.then(xmlhttp => deferred.resolve(xmlhttp))
|
||||
.catch(e => deferred.reject(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deferred.resolve(xmlhttp);
|
||||
} else {
|
||||
let msg = "HTTP " + method + " " + dispURL + " failed with status code " + status;
|
||||
|
@ -863,8 +905,8 @@ Zotero.HTTP = new function() {
|
|||
}
|
||||
)
|
||||
.then((xhr) => {
|
||||
var doc = this.wrapDocument(xhr.response, url);
|
||||
return processor(doc, url);
|
||||
var doc = this.wrapDocument(xhr.response, xhr.responseURL);
|
||||
return processor(doc, xhr.responseURL);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -29,6 +29,16 @@ describe("Zotero.HTTP", function () {
|
|||
}
|
||||
}
|
||||
);
|
||||
httpd.registerPathHandler(
|
||||
'/test-redirect.html',
|
||||
{
|
||||
handle: function (request, response) {
|
||||
response.setHeader("Content-Type", 'text/html', false);
|
||||
response.setStatusLine(null, 200, "OK");
|
||||
response.write("<html><head><meta http-equiv=\"refresh\" content=\"2;url=test.html\"/></head><body></body></html>");
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
after(function* () {
|
||||
|
@ -68,6 +78,20 @@ describe("Zotero.HTTP", function () {
|
|||
);
|
||||
assert.isTrue(called);
|
||||
});
|
||||
|
||||
it("should follow meta redirect for a document", async function () {
|
||||
let url1 = `http://127.0.0.1:${port}/test-redirect.html`;
|
||||
let url2 = `http://127.0.0.1:${port}/test.html`;
|
||||
let called = false;
|
||||
await Zotero.HTTP.processDocuments(
|
||||
url1,
|
||||
function (doc) {
|
||||
assert.equal(doc.location.href, url2);
|
||||
called = true;
|
||||
}
|
||||
);
|
||||
assert.isTrue(called);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#loadDocuments()", function () {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue