Respect server default encoding if an Accept header is received which
indicates equal weight for both encodings
This commit is contained in:
parent
291fd21836
commit
1361e69177
|
@ -245,7 +245,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
|||
Set<SummaryEnum> summaryMode = RestfulServerUtils.determineSummaryMode(theRequest);
|
||||
|
||||
// Determine response encoding
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequest.getServletRequest());
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequest.getServletRequest(), theServer.getDefaultResponseEncoding());
|
||||
|
||||
// Is this request coming from a browser
|
||||
String uaHeader = theRequest.getServletRequest().getHeader("user-agent");
|
||||
|
|
|
@ -54,7 +54,7 @@ public class Constants {
|
|||
public static final String FORMAT_XML = "xml";
|
||||
public static final String HEADER_ACCEPT = "Accept";
|
||||
public static final String HEADER_ACCEPT_ENCODING = "Accept-Encoding";
|
||||
public static final String HEADER_ACCEPT_VALUE_ALL = CT_FHIR_XML + ";q=1.0, " + CT_FHIR_XML + ";q=1.0";
|
||||
public static final String HEADER_ACCEPT_VALUE_ALL = CT_FHIR_XML + ";q=1.0, " + CT_FHIR_JSON + ";q=1.0";
|
||||
public static final String HEADER_ALLOW = "Allow";
|
||||
public static final String HEADER_AUTHORIZATION = "Authorization";
|
||||
public static final String HEADER_AUTHORIZATION_VALPREFIX_BASIC = "Basic ";
|
||||
|
|
|
@ -491,7 +491,7 @@ public class RestfulServer extends HttpServlet {
|
|||
|
||||
int start = Math.min(offsetI, resultList.size() - 1);
|
||||
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequest.getServletRequest());
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequest.getServletRequest(), getDefaultResponseEncoding());
|
||||
boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(this, theRequest);
|
||||
boolean requestIsBrowser = requestIsBrowser(theRequest.getServletRequest());
|
||||
Set<SummaryEnum> summaryMode = RestfulServerUtils.determineSummaryMode(theRequest);
|
||||
|
|
|
@ -214,7 +214,11 @@ public class RestfulServerUtils {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
public static EncodingEnum determineResponseEncodingNoDefault(HttpServletRequest theReq) {
|
||||
/**
|
||||
* Returns null if the request doesn't express that it wants FHIR. If it expresses that it wants
|
||||
* XML and JSON equally, returns thePrefer.
|
||||
*/
|
||||
public static EncodingEnum determineResponseEncodingNoDefault(HttpServletRequest theReq, EncodingEnum thePrefer) {
|
||||
String[] format = theReq.getParameterValues(Constants.PARAM_FORMAT);
|
||||
if (format != null) {
|
||||
for (String nextFormat : format) {
|
||||
|
@ -257,9 +261,11 @@ public class RestfulServerUtils {
|
|||
}
|
||||
}
|
||||
|
||||
if (q > bestQ && encoding != null) {
|
||||
retVal = encoding;
|
||||
bestQ = q;
|
||||
if (encoding != null) {
|
||||
if (q > bestQ || (q == bestQ && encoding == thePrefer)) {
|
||||
retVal = encoding;
|
||||
bestQ = q;
|
||||
}
|
||||
}
|
||||
|
||||
if (!",".equals(m.group(5))) {
|
||||
|
@ -278,7 +284,7 @@ public class RestfulServerUtils {
|
|||
* Determine whether a response should be given in JSON or XML format based on the incoming HttpServletRequest's <code>"_format"</code> parameter and <code>"Accept:"</code> HTTP header.
|
||||
*/
|
||||
public static EncodingEnum determineResponseEncodingWithDefault(RestfulServer theServer, HttpServletRequest theReq) {
|
||||
EncodingEnum retVal = determineResponseEncodingNoDefault(theReq);
|
||||
EncodingEnum retVal = determineResponseEncodingNoDefault(theReq, theServer.getDefaultResponseEncoding());
|
||||
if (retVal == null) {
|
||||
retVal = theServer.getDefaultResponseEncoding();
|
||||
}
|
||||
|
@ -328,10 +334,7 @@ public class RestfulServerUtils {
|
|||
public static IParser getNewParser(FhirContext theContext, RequestDetails theRequestDetails) {
|
||||
|
||||
// Determine response encoding
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequestDetails.getServletRequest());
|
||||
if (responseEncoding == null) {
|
||||
responseEncoding = theRequestDetails.getServer().getDefaultResponseEncoding();
|
||||
}
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingWithDefault(theRequestDetails.getServer(), theRequestDetails.getServletRequest());
|
||||
IParser parser;
|
||||
switch (responseEncoding) {
|
||||
case JSON:
|
||||
|
@ -472,8 +475,7 @@ public class RestfulServerUtils {
|
|||
theHttpResponse.setStatus(200);
|
||||
|
||||
// Determine response encoding
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequestDetails.getServletRequest());
|
||||
responseEncoding = responseEncoding != null ? responseEncoding : theServer.getDefaultResponseEncoding();
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingWithDefault(theServer, theRequestDetails.getServletRequest());
|
||||
|
||||
if (theRequestIsBrowser && theServer.isUseBrowserFriendlyContentTypes()) {
|
||||
theHttpResponse.setContentType(responseEncoding.getBrowserFriendlyBundleContentType());
|
||||
|
@ -502,7 +504,7 @@ public class RestfulServerUtils {
|
|||
theHttpResponse.setStatus(stausCode);
|
||||
|
||||
// Determine response encoding
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequestDetails.getServletRequest());
|
||||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequestDetails.getServletRequest(), theServer.getDefaultResponseEncoding());
|
||||
|
||||
String serverBase = theRequestDetails.getFhirServerBase();
|
||||
if (theAddContentLocationHeader && theResource.getIdElement() != null && theResource.getIdElement().hasIdPart() && isNotBlank(serverBase)) {
|
||||
|
|
|
@ -198,7 +198,7 @@ public class LoggingInterceptor extends InterceptorAdapter {
|
|||
} else if (theKey.startsWith("remoteAddr")) {
|
||||
return StringUtils.defaultString(myRequest.getRemoteAddr());
|
||||
} else if (theKey.equals("responseEncodingNoDefault")) {
|
||||
EncodingEnum encoding = RestfulServerUtils.determineResponseEncodingNoDefault(myRequest);
|
||||
EncodingEnum encoding = RestfulServerUtils.determineResponseEncodingNoDefault(myRequest, myRequestDetails.getServer().getDefaultResponseEncoding());
|
||||
if (encoding != null) {
|
||||
return encoding.name();
|
||||
} else {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package ca.uhn.fhirtest;
|
||||
|
||||
import java.sql.DriverManager;
|
||||
|
||||
import org.apache.derby.drda.NetworkServerControl;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
<util:list id="myServerInterceptors">
|
||||
<ref bean="myLoggingInterceptor"/>
|
||||
<ref bean="mySubscriptionSecurityInterceptor"/>
|
||||
<!-- <ref bean="mySubscriptionSecurityInterceptor"/> -->
|
||||
</util:list>
|
||||
|
||||
<!--
|
||||
|
@ -44,7 +44,9 @@
|
|||
<bean id="dbServer" class="ca.uhn.fhirtest.DerbyNetworkServer">
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
<bean id="mySubscriptionSecurityInterceptor" class="ca.uhn.fhir.jpa.util.SubscriptionsRequireManualActivationInterceptor"/>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Do some fancy logging to create a nice access log that has details
|
||||
|
|
|
@ -36,9 +36,6 @@ import ca.uhn.fhir.rest.annotation.IdParam;
|
|||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public class DefaultEncodingTest {
|
||||
|
||||
private static CloseableHttpClient ourClient;
|
||||
|
@ -47,6 +44,59 @@ public class DefaultEncodingTest {
|
|||
private static final FhirContext ourCtx = FhirContext.forDstu1();
|
||||
private static RestfulServer ourRestfulServer;
|
||||
|
||||
@Test
|
||||
public void testHonoursAcceptHeader() throws Exception {
|
||||
ourRestfulServer.setDefaultPrettyPrint(false);
|
||||
ourRestfulServer.setDefaultResponseEncoding(EncodingEnum.JSON);
|
||||
|
||||
HttpGet httpGet;
|
||||
HttpResponse status;
|
||||
String responseContent;
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", "application/json");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, containsString("\"identifier\":"));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", "application/json+fhir");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, containsString("\"identifier\":"));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", "application/json+fhir, application/xml+fhir");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, containsString("\"identifier\":"));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", "application/xml+fhir, application/json+fhir");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, containsString("\"identifier\":"));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", "application/xml+fhir; q=0.9, application/json+fhir; q=1.0");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, containsString("\"identifier\":"));
|
||||
|
||||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
|
||||
httpGet.addHeader("Accept", "application/xml+fhir; q=1.0, application/json+fhir; q=0.9");
|
||||
status = ourClient.execute(httpGet);
|
||||
responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertThat(responseContent, not(containsString("\"identifier\":")));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadWithDefaultJsonPretty() throws Exception {
|
||||
ourRestfulServer.setDefaultPrettyPrint(true);
|
||||
|
|
|
@ -220,9 +220,11 @@ public class GenericClientDstu2Test {
|
|||
assertEquals("http://"+methodName+".example.com/fhir/metadata?_format=json", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(0).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), not(containsString(Constants.CT_FHIR_XML)));
|
||||
assertEquals("http://"+methodName+".example.com/fhir/Patient/123?_format=json", capt.getAllValues().get(1).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(1).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), not(containsString(Constants.CT_FHIR_XML)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -259,9 +261,13 @@ public class GenericClientDstu2Test {
|
|||
assertEquals("http://"+methodName+".example.com/fhir/metadata", capt.getAllValues().get(0).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(0).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
||||
assertThat(capt.getAllValues().get(0).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
assertEquals("http://"+methodName+".example.com/fhir/Patient/123", capt.getAllValues().get(1).getURI().toASCIIString());
|
||||
assertEquals(1, capt.getAllValues().get(1).getHeaders("Accept").length);
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.HEADER_ACCEPT_VALUE_ALL));
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_XML));
|
||||
assertThat(capt.getAllValues().get(1).getHeaders("Accept")[0].getValue(), containsString(Constants.CT_FHIR_JSON));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -66,6 +66,10 @@
|
|||
to a resource that is not valid in the location it is found in (e.g. points to Patient/123 but
|
||||
the field supposed to reference an Organization). Thanks to Bill de Beaubien for reporting!
|
||||
</action>
|
||||
<action type="fix">
|
||||
In server, if a client request is received and it has an Accept header indicating
|
||||
that it supports both XML and JSON with equal weight, the server's default is used instead of the first entry in the list.
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.2" date="2015-09-18">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue