package org.mitre.rhex; import edu.umd.cs.findbugs.annotations.NonNull; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpOptions; import org.mitre.test.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URI; import java.util.Collections; import java.util.List; /** * 6.2.5 OPTIONS * * The OPTIONS operation on the baseURL is per [8], section 9.2, intended to return communications * options to the clients. Within the context of this specification, OPTIONS is used to indicate * which security mechanisms are available for a given baseURL and a list of hData content profiles * supported by this implementation. All implementations MUST support OPTIONS on the baseURL of * each HDR and return a status code of 200, along with: X-hdata-security, X-hdata-hcp, and * X-hdata-extensions HTTP headers. <P> * * The server MAY include additional HTTP headers. The response SHOULD NOT include an HTTP body. The client * MUST NOT use the Max-Forward header when requesting the security mechanisms for a given HDR. <P> * * Status Code: 200 * * @author Jason Mathews, MITRE Corp. * Date: 2/20/12 10:45 AM */ public class BaseUrlOptions extends BaseTest { @NonNull public String getId() { return "6.2.5.1"; } @Override public boolean isRequired() { return true; // MUST } @NonNull public String getName() { return "OPTIONS on HDR baseURL MUST return 200 status code"; } @NonNull public List<Class<? extends TestUnit>> getDependencyClasses() { return Collections.emptyList(); // none } public void execute() throws TestException { final Context context = Loader.getInstance().getContext(); HttpClient client = context.getHttpClient(); try { URI baseURL = context.getBaseURL(); boolean debug = log.isDebugEnabled(); if (debug) System.out.println("\nOPTION URL: " + baseURL); HttpOptions req = createRequest(baseURL); HttpResponse response = context.executeRequest(client, req); int code = response.getStatusLine().getStatusCode(); if(code != 200 || debug) { if (!debug) System.out.println("URL: " + baseURL); dumpResponse(req, response, debug); } assertEquals(200, code); final HttpEntity entity = response.getEntity(); if (entity != null) { // response SHOULD NOT include an HTTP body so entity should be null // addWarning("response SHOULD NOT include an HTTP body"); long len = entity.getContentLength(); // minimum length expected is 66 bytes or a negative number if unknown // assertTrue(len < 0 || len >= 66, "Expecting valid XML document for baseURL/root.xml; returned length was " + len); if (debug && len > 0) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { entity.writeTo(bos); } catch (Exception e) { log.warn("", e); } System.out.println("content length=" + len + "\n" + bos); /* <?xml version="1.0" encoding="UTF-8"?> <feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom"> */ } } // NOTE: check X-hdata-* header fields in follow-up test /* if (response.getFirstHeader("X-hdata-security") == null && response.getFirstHeader("X-hdata-hcp") == null && response.getFirstHeader("X-hdata-extensions") == null) { setStatus(StatusEnumType.FAILED, "Must set required X-hdata HTTP headers in response"); return; } */ /* 6.2.5 OPTIONS All implementations MUST support OPTIONS on the baseURL of each HDR and return a status code of 200, along with following HTTP headers: � The X-hdata-security HTTP header defined in section of this specification. The security mechanisms defined at the baseURL are applicable to all child resources, i.e. to the entire HDR. X-hdata-security: http://openid.net/connect/ � An X-hdata-hcp HTTP header that contains a space separated list of the identifiers of the hData Content Profiles supported by this implementation X-hdata-hcp: http://projecthdata.org/hcp/greenCDA-CoC � The X-hdata-extensions HTTP header contains a space separated list of the identifiers of the hData extensions supported by this implementation independent of their presence in the root document at baseURL/root.xml (cf. section 2.2 in [1] describing the root document format for an explanation of the extensions in a root.xml) X-hdata-extensions: http://projecthdata.org/extension/allergy http://projecthdata.org/extension/care-goal http://projecthdata.org/extension/condition http://projecthdata.org/extension/encounter http://projecthdata.org/extension/immunization http://projecthdata.org/extension/medical-equipment http://projecthdata.org/extension/medication http://projecthdata.org/extension/procedure http://projecthdata.org/extension/result http://projecthdata.org/extension/social-history http://projecthdata.org/extension/vital-sign */ setResponse(response); setStatus(StatusEnumType.SUCCESS); } catch (ClientProtocolException e) { throw new TestException(e); } catch (IOException e) { throw new TestException(e); } finally { client.getConnectionManager().shutdown(); } } protected HttpOptions createRequest(URI baseURL) { return new HttpOptions(baseURL); } }