Better handling of invalid HTTP responses
If a server returns an invalid HTTP response (e.g., Content-Encoding: gzip with a plaintext body, a.k.a. NS_ERROR_INVALID_CONTENT_ENCODING) but we can still parse a 4xx or 5xx HTTP response code, use that for the XHR status, since it might be enough for what we need to do (e.g., verify a 404 from a WebDAV server). This fixes a current problem with Box [1]. Also fix a "msg is not defined" error when the XHR status is 0 but the SSL connection is fine and include the channel and response status on the UnexpectedStatusException object (though both of these would now only happen on an invalid 2xx response, when the XHR status would remain as 0). [1] https://forums.zotero.org/discussion/comment/301014/#Comment_301014
This commit is contained in:
parent
1aade0f268
commit
4bbae6e17a
1 changed files with 44 additions and 12 deletions
|
@ -12,6 +12,8 @@ Zotero.HTTP = new function() {
|
|||
this.UnexpectedStatusException = function(xmlhttp, msg) {
|
||||
this.xmlhttp = xmlhttp;
|
||||
this.status = xmlhttp.status;
|
||||
this.channelStatus = null;
|
||||
this.responseStatus = null;
|
||||
this.channel = xmlhttp.channel;
|
||||
this.message = msg;
|
||||
this.stack = new Error().stack;
|
||||
|
@ -33,6 +35,24 @@ Zotero.HTTP = new function() {
|
|||
catch (e) {
|
||||
Zotero.debug(e, 1);
|
||||
}
|
||||
|
||||
// If the connection failed, try to find out what really happened
|
||||
if (!this.status) {
|
||||
try {
|
||||
if (xmlhttp.channel.status) {
|
||||
this.channelStatus = xmlhttp.channel.status;
|
||||
Zotero.debug("Channel status was " + this.channelStatus, 2);
|
||||
}
|
||||
}
|
||||
catch (e) {}
|
||||
try {
|
||||
if (xmlhttp.channel.responseStatus) {
|
||||
this.responseStatus = xmlhttp.channel.responseStatus;
|
||||
Zotero.debug("Response status was " + this.responseStatus, 2);
|
||||
}
|
||||
}
|
||||
catch (e) {}
|
||||
}
|
||||
};
|
||||
this.UnexpectedStatusException.prototype = Object.create(Error.prototype);
|
||||
this.UnexpectedStatusException.prototype.is4xx = function () {
|
||||
|
@ -248,6 +268,18 @@ Zotero.HTTP = new function() {
|
|||
xmlhttp.onloadend = function() {
|
||||
var status = xmlhttp.status;
|
||||
|
||||
// If an invalid HTTP response (e.g., NS_ERROR_INVALID_CONTENT_ENCODING) includes a
|
||||
// 4xx or 5xx HTTP response code, swap it in, since it might be enough info to do
|
||||
// what we need (e.g., verify a 404 from a WebDAV server)
|
||||
try {
|
||||
if (!status && xmlhttp.channel.responseStatus >= 400) {
|
||||
Zotero.warn(`Overriding status for invalid response for ${dispURL} `
|
||||
+ `(${xmlhttp.channel.status})`);
|
||||
status = xmlhttp.channel.responseStatus;
|
||||
}
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
if (options.successCodes) {
|
||||
var success = options.successCodes.indexOf(status) != -1;
|
||||
}
|
||||
|
@ -264,13 +296,13 @@ Zotero.HTTP = new function() {
|
|||
|
||||
if(success) {
|
||||
Zotero.debug("HTTP " + method + " " + dispURL
|
||||
+ " succeeded with " + xmlhttp.status);
|
||||
+ " succeeded with " + status);
|
||||
if (options.debug) {
|
||||
Zotero.debug(xmlhttp.responseText);
|
||||
}
|
||||
deferred.resolve(xmlhttp);
|
||||
} else {
|
||||
let msg = "HTTP " + method + " " + dispURL + " failed with status code " + xmlhttp.status;
|
||||
let msg = "HTTP " + method + " " + dispURL + " failed with status code " + status;
|
||||
if (!xmlhttp.responseType && xmlhttp.responseText) {
|
||||
msg += ":\n\n" + xmlhttp.responseText;
|
||||
}
|
||||
|
@ -1025,6 +1057,8 @@ Zotero.HTTP = new function() {
|
|||
|
||||
let secInfo = channel.securityInfo;
|
||||
let msg;
|
||||
let dialogButtonText;
|
||||
let dialogButtonCallback;
|
||||
if (secInfo instanceof Ci.nsITransportSecurityInfo) {
|
||||
secInfo.QueryInterface(Ci.nsITransportSecurityInfo);
|
||||
if ((secInfo.securityState & Ci.nsIWebProgressListener.STATE_IS_INSECURE)
|
||||
|
@ -1053,17 +1087,15 @@ Zotero.HTTP = new function() {
|
|||
== Ci.nsIWebProgressListener.STATE_IS_BROKEN) {
|
||||
msg = Zotero.getString('sync.error.sslConnectionError');
|
||||
}
|
||||
else {
|
||||
Zotero.debug(secInfo.securityState, 1);
|
||||
msg = Zotero.getString('sync.error.sslConnectionError');
|
||||
if (msg) {
|
||||
throw new Zotero.HTTP.SecurityException(
|
||||
msg,
|
||||
{
|
||||
dialogButtonText,
|
||||
dialogButtonCallback
|
||||
}
|
||||
);
|
||||
}
|
||||
throw new Zotero.HTTP.SecurityException(
|
||||
msg,
|
||||
{
|
||||
dialogButtonText,
|
||||
dialogButtonCallback
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue