Commits

Ivan Vučica committed 5628c53

In case server sends something that isn't content-type'd as XML, browser may refuse to parse it. This patch makes Z-XMPP try hard to get browser to parse the XML.

Comments (0)

Files changed (2)

 			conn.setRequestHeader("X-ZXMPPOldestRid", this.sentUnrespondedRIDs[0]);
 			conn.setRequestHeader("X-ZXMPPMyRid", assignedRid);
 			conn.setRequestHeader("X-ZXMPPReuseRids", JSON.stringify(this.reuseRIDs));
+			conn.setRequestHeader("Accept", "text/xml,application/xml");
 			conn.onreadystatechange = this.zxmpp.stream.handleConnectionStateChange;
 			conn.connrid = assignedRid;
 			conn.connkey = this.assignKey(true); if(conn.connkey) conn.connkey = conn.connkey.key;
 		if(conn.status == 200)
 		{
 			// we need to dig deeper to see if this is a terminate packet
-			var bodyNode = conn.responseXML.firstChild;
+			var responseXML = conn.connzxmpp.util.xmlHttpRequestResponseXML(conn);
+			if(!responseXML)
+			{
+				console.error("Response is not valid XML");
+				console.log(conn.responseText);
+				
+				conn.connzxmpp.stream.terminate();
+
+				var code = "terminate/invalid-xml";
+				var humanreadable = "Did not receive valid XML as the response. Breaking connection.";
+				conn.connzxmpp.notifyConnectionTerminate(code, humanreadable);
+				return;
+			}
+			var bodyNode = responseXML.firstChild;
 			conn.connzxmpp.util.easierAttrs(bodyNode);
 				
 			if(bodyNode.attr["type"] == "terminate" && bodyNode.attr["condition"] == "item-not-found")
 		var packet = new this.zxmpp.packet(this.zxmpp);
 		try
 		{
-			if(!packet.parseXML(conn.responseXML)) // packet not intended for further processing
+			var responseXML = this.zxmpp.util.xmlHttpRequestResponseXML(conn);
+			if(!packet.parseXML(responseXML)) // packet not intended for further processing
 			{
 				return;
 			}
 		return xml.attr;
 	}
 	
-	
+	// by Ivan Vucica
+	this.xmlHttpRequestResponseXML = function zxmpp_util_xmlHttpRequestResponseXML(xhr)
+	{
+		var conn = xhr;
+		var responseXML = xhr.responseXML;
+		if(!responseXML)
+		{
+			responseXML = conn.connzxmpp.util.parsedXMLDocument(conn.responseText);
+			if(responseXML && responseXML.firstChild)
+			{
+				if(!conn.connzxmpp.stream._didWarnAboutXMLContentType)
+					console.warn("Server response was not tagged as XML content-type despite being XML. This is a one time warning.");
+				conn.connzxmpp.stream._didWarnAboutXMLContentType = true;
+			}
+			else
+			{
+				responseXML = conn.connzxmpp.util.parsedXMLDocument('<?xml version="1.0"?>' + conn.responseText);
+			}
+			if(responseXML && responseXML.firstChild)
+			{
+				if(!conn.connzxmpp.stream._didWarnAboutXMLHavingToBePrefixed)
+					console.warn("Server response had to be prefixed with <?xml?> header. This is a one time warning.");
+				conn.connzxmpp.stream._didWarnAboutXMLHavingToBePrefixed = true;
+			}
+		}
+
+		return responseXML;
+	} 
 	
 	/****** base64 code **********/