Fix #313 - Do not treat OPTIONS [base]/foo as a request for server's

conformance statement. Thanks to Michael Lawley for reporting!
This commit is contained in:
James Agnew 2016-03-12 14:53:20 -05:00
parent 270ba270cc
commit 452316aed7
3 changed files with 87 additions and 22 deletions

View File

@ -81,7 +81,9 @@ public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding
@Override @Override
public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) {
if (theRequest.getRequestType() == RequestTypeEnum.OPTIONS) { if (theRequest.getRequestType() == RequestTypeEnum.OPTIONS) {
return true; if (theRequest.getOperation() == null && theRequest.getResourceName() == null) {
return true;
}
} }
if (theRequest.getResourceName() != null) { if (theRequest.getResourceName() != null) {

View File

@ -36,9 +36,11 @@ import ca.uhn.fhir.util.PortUtil;
public class ServerFeaturesDstu2Test { public class ServerFeaturesDstu2Test {
private static CloseableHttpClient ourClient; private static CloseableHttpClient ourClient;
private static FhirContext ourCtx = FhirContext.forDstu2();
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServerFeaturesDstu2Test.class);
private static int ourPort; private static int ourPort;
private static Server ourServer; private static Server ourServer;
private static FhirContext ourCtx = FhirContext.forDstu2();
private static RestfulServer ourServlet; private static RestfulServer ourServlet;
@Test @Test
@ -50,6 +52,72 @@ public class ServerFeaturesDstu2Test {
assertEquals(200, status.getStatusLine().getStatusCode()); assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(responseContent, containsString("<Conformance")); assertThat(responseContent, containsString("<Conformance"));
/*
* Now with a leading /
*/
httpGet = new HttpOptions("http://localhost:" + ourPort + "/");
status = ourClient.execute(httpGet);
responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(responseContent, containsString("<Conformance"));
}
/**
* See #313
*/
@Test
public void testOptionsForNonBasePath1() throws Exception {
HttpOptions httpGet = new HttpOptions("http://localhost:" + ourPort + "/Foo");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(400, status.getStatusLine().getStatusCode());
}
/**
* See #313
*/
@Test
public void testOptionsForNonBasePath3() throws Exception {
HttpOptions httpGet = new HttpOptions("http://localhost:" + ourPort + "/metadata");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(405, status.getStatusLine().getStatusCode());
}
/**
* See #313
*/
@Test
public void testOptionsForNonBasePath2() throws Exception {
HttpOptions httpGet = new HttpOptions("http://localhost:" + ourPort + "/Patient/1");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(400, status.getStatusLine().getStatusCode());
}
@Test
public void testOptionsJson() throws Exception {
HttpOptions httpGet = new HttpOptions("http://localhost:" + ourPort + "?_format=json");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(responseContent, containsString("resourceType\":\"Conformance"));
} }
@Test @Test
@ -77,17 +145,6 @@ public class ServerFeaturesDstu2Test {
} }
@Test
public void testOptionsJson() throws Exception {
HttpOptions httpGet = new HttpOptions("http://localhost:" + ourPort + "?_format=json");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
assertThat(responseContent, containsString("resourceType\":\"Conformance"));
}
@AfterClass @AfterClass
public static void afterClass() throws Exception { public static void afterClass() throws Exception {
ourServer.stop(); ourServer.stop();
@ -119,6 +176,11 @@ public class ServerFeaturesDstu2Test {
public static class DummyPatientResourceProvider implements IResourceProvider { public static class DummyPatientResourceProvider implements IResourceProvider {
@Override
public Class<? extends IResource> getResourceType() {
return Patient.class;
}
@Read @Read
public Patient read(@IdParam IdDt theId) { public Patient read(@IdParam IdDt theId) {
Patient p1 = new Patient(); Patient p1 = new Patient();
@ -127,15 +189,15 @@ public class ServerFeaturesDstu2Test {
return p1; return p1;
} }
}
public static class DummyPatientResourceProvider2 implements IResourceProvider {
@Override @Override
public Class<? extends IResource> getResourceType() { public Class<? extends IResource> getResourceType() {
return Patient.class; return Patient.class;
} }
}
public static class DummyPatientResourceProvider2 implements IResourceProvider {
@Read @Read
public Patient read(@IdParam IdDt theId) { public Patient read(@IdParam IdDt theId) {
Patient p1 = new Patient(); Patient p1 = new Patient();
@ -144,11 +206,6 @@ public class ServerFeaturesDstu2Test {
return p1; return p1;
} }
@Override
public Class<? extends IResource> getResourceType() {
return Patient.class;
}
} }
} }

View File

@ -224,6 +224,12 @@
field in the deserialized object could not be field in the deserialized object could not be
modified. Thanks to Thomas Andersen for reporting! modified. Thanks to Thomas Andersen for reporting!
</action> </action>
<action type="fix" issue="313">
REST Server responded to HTTP OPTIONS requests with
any URI as being a request for the server's
Conformance statement. This is incorrect, as only
a request for <![CDATA[<code>OPTIONS [base url]</code>]]> should be treated as such. Thanks to Michael Lawley for reporting!
</action>
</release> </release>
<release version="1.4" date="2016-02-04"> <release version="1.4" date="2016-02-04">
<action type="add"> <action type="add">