*
* @throws IOException
* @throws XPathException
*/
private void insertResponseBody(final XQueryContext context, final HttpMethod method, final MemTreeBuilder builder, final Map<String, Boolean>parserFeatures, final Map<String, String>parserProperties) throws IOException, XPathException {
NodeImpl responseNode = null;
final InputStream bodyAsStream = method.getResponseBodyAsStream();
// check if there is a response body
if(bodyAsStream != null) {
CachingFilterInputStream cfis = null;
FilterInputStreamCache cache = null;
try {
//we have to cache the input stream, so we can reread it, as we may use it twice (once for xml attempt and once for string attempt)
cache = FilterInputStreamCacheFactory.getCacheInstance(new FilterInputStreamCacheFactory.FilterInputStreamCacheConfiguration(){
@Override
public String getCacheClass() {
return (String) context.getBroker().getConfiguration().getProperty(Configuration.BINARY_CACHE_CLASS_PROPERTY);
}
});
cfis = new CachingFilterInputStream(cache, bodyAsStream);
//mark the start of the stream
cfis.mark(Integer.MAX_VALUE);
// determine the type of the response document
final Header responseContentType = method.getResponseHeader("Content-Type");
final MimeType responseMimeType = getResponseMimeType(responseContentType);
if(responseContentType != null) {
builder.addAttribute(new QName("mimetype", null, null), responseContentType.getValue());
}
//try and parse the response as XML
try {
//we have to use CloseShieldInputStream otherwise the parser closes the stream and we cant later reread
final InputStream shieldedInputStream = new CloseShieldInputStream(cfis);
responseNode = (NodeImpl)ModuleUtils.streamToXML(context, shieldedInputStream);
builder.addAttribute(new QName("type", null, null ), "xml");
responseNode.copyTo(null, new DocumentBuilderReceiver(builder));
} catch(final SAXException se) {
// could not parse to xml
// not an error in itself, it will be treated either as HTML,
// text or binary here below
final String msg = "Request for URI '"
+ method.getURI().toString()
+ "' Could not parse http response content as XML (will try html, text or fallback to binary): "
+ se.getMessage();
if(logger.isDebugEnabled()) {
logger.debug(msg, se);
} else {
logger.info(msg);
}
} catch(final IOException ioe) {
final String msg = "Request for URI '" + method.getURI().toString() + "' Could not read http response content: " + ioe.getMessage();
logger.error(msg, ioe);
throw new XPathException(msg, ioe);
}
if(responseNode == null) {
//response is NOT parseable as XML
//is it a html document?
if(responseMimeType.getName().equals(MimeType.HTML_TYPE.getName())) {
//html document
try {
//reset the stream to the start, as we need to reuse since attempting to parse to XML
cfis.reset();
//parse html to xml(html)
//we have to use CloseShieldInputStream otherwise the parser closes the stream and we cant later reread
final InputStream shieldedInputStream = new CloseShieldInputStream(cfis);
responseNode = (NodeImpl)ModuleUtils.htmlToXHtml(context, method.getURI().toString(), new InputSource(shieldedInputStream), parserFeatures, parserProperties).getDocumentElement();
builder.addAttribute(new QName("type", null, null), "xhtml" );
responseNode.copyTo(null, new DocumentBuilderReceiver(builder));
} catch(final URIException ue) {
throw new XPathException(this, ue.getMessage(), ue);
} catch(final SAXException se) {
//could not parse to xml(html)
logger.debug("Could not parse http response content from HTML to XML: " + se.getMessage(), se);