Improve XML compatibility with trace-level logging

Some providers, notably Azure, include a byte-order mark in their XML
responses.  ParseSax.apply buffers these responses in a String when
users enable trace-level logging to include the response in any thrown
exceptions.  InputSource(InputStream) skips these byte-order marks
while InputSource(Reader) does not, yielding a SAXParseException.
This commit is contained in:
Andrew Gaul 2014-09-05 16:16:07 -07:00
parent f2d897d977
commit 5330699fe7
1 changed files with 5 additions and 2 deletions

View File

@ -21,6 +21,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream; import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
import static org.jclouds.util.Closeables2.closeQuietly; import static org.jclouds.util.Closeables2.closeQuietly;
import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.StringReader; import java.io.StringReader;
@ -91,9 +92,11 @@ public class ParseSax<T> implements Function<HttpResponse, T>, InvocationContext
private T convertStreamToStringAndParse(HttpResponse response) { private T convertStreamToStringAndParse(HttpResponse response) {
String from = null; String from = null;
try { try {
from = new String(closeClientButKeepContentStream(response)); byte[] fromBytes = closeClientButKeepContentStream(response);
from = new String(fromBytes);
validateXml(from); validateXml(from);
return doParse(new InputSource(new StringReader(from))); // Use InputStream to skip over byte order mark.
return doParse(new InputSource(new ByteArrayInputStream(fromBytes)));
} catch (Exception e) { } catch (Exception e) {
return addDetailsAndPropagate(response, e, from); return addDetailsAndPropagate(response, e, from);
} }