diff --git a/exist-core/src/main/java/org/exist/http/RESTServer.java b/exist-core/src/main/java/org/exist/http/RESTServer.java
index 1ca05adde8..fe07cfad34 100644
--- a/exist-core/src/main/java/org/exist/http/RESTServer.java
+++ b/exist-core/src/main/java/org/exist/http/RESTServer.java
@@ -2340,6 +2340,19 @@ private void writeResultJSON(final HttpServletResponse response,
int start, final Properties outputProperties, final boolean wrap, final long compilationTime, final long executionTime)
throws BadRequestException {
+ // set output headers
+ final String encoding = getEncoding(outputProperties);
+ if (!response.containsHeader("Content-Type")) {
+ String mimeType = outputProperties.getProperty(OutputKeys.MEDIA_TYPE);
+ if (mimeType != null) {
+ final int semicolon = mimeType.indexOf(';');
+ if (semicolon != Constants.STRING_NOT_FOUND) {
+ mimeType = mimeType.substring(0, semicolon);
+ }
+ response.setContentType(mimeType + "; charset=" + encoding);
+ }
+ }
+
// calculate number of results to return
final int rlen = results.getItemCount();
if (!results.isEmpty()) {
diff --git a/exist-core/src/test/java/org/exist/http/RESTServiceTest.java b/exist-core/src/test/java/org/exist/http/RESTServiceTest.java
index de531161f2..e4ee9bbfd3 100644
--- a/exist-core/src/test/java/org/exist/http/RESTServiceTest.java
+++ b/exist-core/src/test/java/org/exist/http/RESTServiceTest.java
@@ -60,6 +60,7 @@
import org.apache.http.HttpResponse;
import org.apache.http.client.fluent.Request;
import org.apache.http.entity.ContentType;
+import org.apache.http.util.EntityUtils;
import org.eclipse.jetty.http.HttpStatus;
import org.exist.EXistException;
import org.exist.Namespaces;
@@ -234,6 +235,20 @@ public class RESTServiceTest {
private static final XmldbURI TEST_XMLDECL_COLLECTION_URI = XmldbURI.ROOT_COLLECTION_URI.append("rest-test-xmldecl");
private static final XmldbURI TEST_XML_DOC_WITH_XMLDECL_URI = XmldbURI.create("test-with-xmldecl.xml");
+ private static final String TEST_PRODUCES_XML_XQUERY =
+ "xquery version \"3.0\";\n" +
+ "declare namespace output = \"http://www.w3.org/2010/xslt-xquery-serialization\";\n" +
+ "declare option output:method \"xml\";\n" +
+ "declare option output:media-type \"application/xml\";\n" +
+ "xml";
+
+ private static final String TEST_PRODUCES_JSON_XQUERY =
+ "xquery version \"3.0\";\n" +
+ "declare namespace output = \"http://www.w3.org/2010/xslt-xquery-serialization\";\n" +
+ "declare option output:method \"json\";\n" +
+ "declare option output:media-type \"application/json\";\n" +
+ "json json";
+
private static String credentials;
private static String badCredentials;
@@ -1249,6 +1264,111 @@ public void getXmlDeclYes() throws IOException {
assertEquals("\r\n", responseBody);
}
+ @Test
+ public void queryProducesXmlWithAcceptXml() throws IOException {
+ doPut(TEST_PRODUCES_XML_XQUERY, "produces-xml.xq", HttpStatus.CREATED_201);
+ final String uri = getCollectionUri() + "/produces-xml.xq";
+
+ final HttpResponse response = Request.Get(uri)
+ .setHeader("Accept", MediaType.APPLICATION_XML)
+ .setHeader("Authorization", "Basic " + credentials)
+ .execute()
+ .returnResponse();
+
+ final int resultStatusCode = response.getStatusLine().getStatusCode();
+ final String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+ assertEquals("Server returned response code: " + resultStatusCode, HttpStatus.OK_200, resultStatusCode);
+ assertResponseMediaType(MediaType.APPLICATION_XML, response);
+ assertEquals("xml", responseBody);
+ }
+
+ @Test
+ public void queryProducesJsonWithAcceptXml() throws IOException {
+ doPut(TEST_PRODUCES_JSON_XQUERY, "produces-json.xq", HttpStatus.CREATED_201);
+ final String uri = getCollectionUri() + "/produces-json.xq";
+
+ final HttpResponse response = Request.Get(uri)
+ .setHeader("Authorization", "Basic " + credentials)
+ .setHeader("Accept", MediaType.APPLICATION_XML)
+ .execute()
+ .returnResponse();
+
+ final int resultStatusCode = response.getStatusLine().getStatusCode();
+ final String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+ assertEquals("Server returned response code: " + resultStatusCode, HttpStatus.OK_200, resultStatusCode);
+ assertResponseMediaType("application/json", response);
+ assertEquals("{ \"json1\" : \"json\", \"json2\" : \"json\" }", responseBody);
+ }
+
+ @Test
+ public void queryProducesXmlWithAcceptJson() throws IOException {
+ doPut(TEST_PRODUCES_XML_XQUERY, "produces-xml.xq", HttpStatus.CREATED_201);
+ final String uri = getCollectionUri() + "/produces-xml.xq";
+
+ final HttpResponse response = Request.Get(uri)
+ .setHeader("Authorization", "Basic " + credentials)
+ .setHeader("Accept", "application/json")
+ .execute()
+ .returnResponse();
+
+ final int resultStatusCode = response.getStatusLine().getStatusCode();
+ final String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+ assertEquals("Server returned response code: " + resultStatusCode, HttpStatus.OK_200, resultStatusCode);
+ assertResponseMediaType(MediaType.APPLICATION_XML, response);
+ assertEquals("xml", responseBody);
+ }
+
+ @Test
+ public void queryProducesJsonWithAcceptJson() throws IOException {
+ doPut(TEST_PRODUCES_JSON_XQUERY, "produces-json.xq", HttpStatus.CREATED_201);
+ final String uri = getCollectionUri() + "/produces-json.xq";
+
+ final HttpResponse response = Request.Get(uri)
+ .setHeader("Authorization", "Basic " + credentials)
+ .setHeader("Accept", "application/json")
+ .execute()
+ .returnResponse();
+
+ final int resultStatusCode = response.getStatusLine().getStatusCode();
+ final String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+ assertEquals("Server returned response code: " + resultStatusCode, HttpStatus.OK_200, resultStatusCode);
+ assertResponseMediaType("application/json", response);
+ assertEquals("{ \"json1\" : \"json\", \"json2\" : \"json\" }", responseBody);
+ }
+
+ @Test
+ public void queryProducesXmlWithNoAccept() throws IOException {
+ doPut(TEST_PRODUCES_XML_XQUERY, "produces-xml.xq", HttpStatus.CREATED_201);
+ final String uri = getCollectionUri() + "/produces-xml.xq";
+
+ final HttpResponse response = Request.Get(uri)
+ .setHeader("Authorization", "Basic " + credentials)
+ .execute()
+ .returnResponse();
+
+ final int resultStatusCode = response.getStatusLine().getStatusCode();
+ final String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+ assertEquals("Server returned response code: " + resultStatusCode, HttpStatus.OK_200, resultStatusCode);
+ assertResponseMediaType(MediaType.APPLICATION_XML, response);
+ assertEquals("xml", responseBody);
+ }
+
+ @Test
+ public void queryProducesJsonWithNoAccept() throws IOException {
+ doPut(TEST_PRODUCES_JSON_XQUERY, "produces-json.xq", HttpStatus.CREATED_201);
+ final String uri = getCollectionUri() + "/produces-json.xq";
+
+ final HttpResponse response = Request.Get(uri)
+ .setHeader("Authorization", "Basic " + credentials)
+ .execute()
+ .returnResponse();
+
+ final int resultStatusCode = response.getStatusLine().getStatusCode();
+ final String responseBody = EntityUtils.toString(response.getEntity(), "UTF-8");
+ assertEquals("Server returned response code: " + resultStatusCode, HttpStatus.OK_200, resultStatusCode);
+ assertResponseMediaType("application/json", response);
+ assertEquals("{ \"json1\" : \"json\", \"json2\" : \"json\" }", responseBody);
+ }
private void chmod(final String resourcePath, final String mode) throws IOException {