Add content-disposition header for binary resources
This commit is contained in:
parent
fc74cda994
commit
e53aaf0950
|
@ -8,7 +8,7 @@
|
||||||
<body>
|
<body>
|
||||||
<release version="0.5" date="TBD">
|
<release version="0.5" date="TBD">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
Allow server methods to return wildcard genrric types (e.g. List<? extends IResource>)
|
Allow server methods to return wildcard generic types (e.g. List<? extends IResource>)
|
||||||
</action>
|
</action>
|
||||||
<action type="add">
|
<action type="add">
|
||||||
Search parameters are not properly escaped and unescaped. E.g. for a token parameter such as
|
Search parameters are not properly escaped and unescaped. E.g. for a token parameter such as
|
||||||
|
@ -47,6 +47,12 @@
|
||||||
Fix issue where vread invocations on server incorrectly get routed to instance history method if one is
|
Fix issue where vread invocations on server incorrectly get routed to instance history method if one is
|
||||||
defined. Thanks to Neal Acharya from UHN for surfacing this one!
|
defined. Thanks to Neal Acharya from UHN for surfacing this one!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="add">
|
||||||
|
Binary reads on a server not include the Content-Disposition header, to prevent HTML in binary
|
||||||
|
blobs from being used for nefarious purposes. See
|
||||||
|
<![CDATA[<a href="http://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_id=677&tracker_item_id=3298">FHIR Tracker Bug 3298</a>]]>
|
||||||
|
for more information.
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="0.4" date="2014-Jul-13">
|
<release version="0.4" date="2014-Jul-13">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
|
@ -95,6 +95,7 @@ public class Constants {
|
||||||
public static final String HEADERVALUE_CORS_ALLOW_METHODS_ALL = "GET, POST, PUT, DELETE";
|
public static final String HEADERVALUE_CORS_ALLOW_METHODS_ALL = "GET, POST, PUT, DELETE";
|
||||||
public static final String HEADER_AUTHORIZATION = "Authorization";
|
public static final String HEADER_AUTHORIZATION = "Authorization";
|
||||||
public static final String PARAMQUALIFIER_TOKEN_TEXT = ":text";
|
public static final String PARAMQUALIFIER_TOKEN_TEXT = ":text";
|
||||||
|
public static final String HEADER_CONTENT_DISPOSITION = "Content-Disposition";
|
||||||
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
|
|
@ -1099,6 +1099,9 @@ public class RestfulServer extends HttpServlet {
|
||||||
if (bin.getContent() == null || bin.getContent().length == 0) {
|
if (bin.getContent() == null || bin.getContent().length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
theHttpResponse.addHeader(Constants.HEADER_CONTENT_DISPOSITION, "Attachment;");
|
||||||
|
|
||||||
theHttpResponse.setContentLength(bin.getContent().length);
|
theHttpResponse.setContentLength(bin.getContent().length);
|
||||||
ServletOutputStream oos = theHttpResponse.getOutputStream();
|
ServletOutputStream oos = theHttpResponse.getOutputStream();
|
||||||
oos.write(bin.getContent());
|
oos.write(bin.getContent());
|
||||||
|
|
|
@ -21,6 +21,7 @@ import org.junit.Test;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
import ca.uhn.fhir.model.api.IResource;
|
||||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.Binary;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||||
|
@ -58,6 +59,36 @@ public class ReadTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBinaryRead() throws Exception {
|
||||||
|
{
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Binary/1");
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
byte[] responseContent = IOUtils.toByteArray(status.getEntity().getContent());
|
||||||
|
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||||
|
|
||||||
|
|
||||||
|
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||||
|
assertEquals("application/x-foo", status.getEntity().getContentType().getValue());
|
||||||
|
|
||||||
|
Header cl = status.getFirstHeader(Constants.HEADER_CONTENT_LOCATION_LC);
|
||||||
|
assertNotNull(cl);
|
||||||
|
assertEquals("http://localhost:" + ourPort + "/Binary/1/_history/1", cl.getValue());
|
||||||
|
|
||||||
|
Header cd = status.getFirstHeader("content-disposition");
|
||||||
|
assertNotNull(cd);
|
||||||
|
assertEquals("Attachment;", cd.getValue());
|
||||||
|
|
||||||
|
assertEquals(4,responseContent.length);
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
assertEquals(i+1, responseContent[i]); // should be 1,2,3,4
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testVRead() throws Exception {
|
public void testVRead() throws Exception {
|
||||||
|
@ -93,7 +124,7 @@ public class ReadTest {
|
||||||
ServletHandler proxyHandler = new ServletHandler();
|
ServletHandler proxyHandler = new ServletHandler();
|
||||||
RestfulServer servlet = new RestfulServer();
|
RestfulServer servlet = new RestfulServer();
|
||||||
ourCtx = servlet.getFhirContext();
|
ourCtx = servlet.getFhirContext();
|
||||||
servlet.setResourceProviders(patientProvider);
|
servlet.setResourceProviders(patientProvider, new DummyBinaryProvider());
|
||||||
ServletHolder servletHolder = new ServletHolder(servlet);
|
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||||
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||||
ourServer.setHandler(proxyHandler);
|
ourServer.setHandler(proxyHandler);
|
||||||
|
@ -126,4 +157,27 @@ public class ReadTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by dsotnikov on 2/25/2014.
|
||||||
|
*/
|
||||||
|
public static class DummyBinaryProvider implements IResourceProvider {
|
||||||
|
|
||||||
|
@Read(version = true)
|
||||||
|
public Binary findPatient(@IdParam IdDt theId) {
|
||||||
|
Binary bin = new Binary();
|
||||||
|
bin.setContentType("application/x-foo");
|
||||||
|
bin.setContent(new byte[] {1,2,3,4});
|
||||||
|
bin.setId("Binary/1/_history/1");
|
||||||
|
return bin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends IResource> getResourceType() {
|
||||||
|
return Binary.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue