diff --git a/examples/src/main/java/example/HttpProxy.java b/examples/src/main/java/example/HttpProxy.java new file mode 100644 index 00000000000..5a7106c6db9 --- /dev/null +++ b/examples/src/main/java/example/HttpProxy.java @@ -0,0 +1,49 @@ +package example; + +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.AuthenticationStrategy; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.ProxyAuthenticationStrategy; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.dstu2.resource.Patient; +import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.rest.client.IGenericClient; + +public class HttpProxy { + + public static void main(String[] args) { + + final String authUser = "username"; + final String authPassword = "password"; + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials(new AuthScope("10.10.10.10", 8080), + new UsernamePasswordCredentials(authUser, authPassword)); + + HttpHost myProxy = new HttpHost("10.10.10.10", 8080); + + + HttpClientBuilder clientBuilder = HttpClientBuilder.create(); + clientBuilder + .setProxy(myProxy) + .setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()) + .setDefaultCredentialsProvider(credsProvider) + .disableCookieManagement(); + CloseableHttpClient httpClient = clientBuilder.build(); + + FhirContext ctx = new FhirContext(); + String serverBase = "http://spark.furore.com/fhir/"; + ctx.getRestfulClientFactory().setHttpClient(httpClient); + IGenericClient client = ctx.newRestfulGenericClient(serverBase); + + IdDt id = new IdDt("Patient", "123"); + client.read(Patient.class, id); + + } + +} diff --git a/hapi-fhir-jpaserver-base/.classpath b/hapi-fhir-jpaserver-base/.classpath index 9ebe1a6b158..f9148a1a7ac 100644 --- a/hapi-fhir-jpaserver-base/.classpath +++ b/hapi-fhir-jpaserver-base/.classpath @@ -27,7 +27,7 @@ - + diff --git a/hapi-fhir-jpaserver-base/.settings/org.eclipse.wst.common.project.facet.core.xml b/hapi-fhir-jpaserver-base/.settings/org.eclipse.wst.common.project.facet.core.xml index 5c9bd7532ab..4f92af543f1 100644 --- a/hapi-fhir-jpaserver-base/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/hapi-fhir-jpaserver-base/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -1,5 +1,5 @@ - + diff --git a/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/client/HttpProxyTest.java b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/client/HttpProxyTest.java new file mode 100644 index 00000000000..8a2a644b57b --- /dev/null +++ b/hapi-fhir-structures-dstu/src/test/java/ca/uhn/fhir/rest/client/HttpProxyTest.java @@ -0,0 +1,150 @@ +package ca.uhn.fhir.rest.client; + +import static org.junit.Assert.*; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.collections.EnumerationUtils; +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.ProxyAuthenticationStrategy; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.handler.ContextHandlerCollection; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.junit.BeforeClass; +import org.junit.Test; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.api.IResource; +import ca.uhn.fhir.model.dstu.resource.Patient; +import ca.uhn.fhir.model.primitive.IdDt; +import ca.uhn.fhir.rest.annotation.IdParam; +import ca.uhn.fhir.rest.annotation.Read; +import ca.uhn.fhir.rest.server.IResourceProvider; +import ca.uhn.fhir.rest.server.RestfulServer; +import ca.uhn.fhir.util.PortUtil; + +public class HttpProxyTest { + private static FhirContext ourCtx; + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(HttpProxyTest.class); + private static HttpServletRequest ourRequest; + private boolean myFirstRequest; + private String myAuthHeader; + + @SuppressWarnings("serial") + @Test + public void testProxiedRequest() throws Exception { + int port = PortUtil.findFreePort(); + Server server = new Server(port); + myFirstRequest = true; + myAuthHeader = null; + + RestfulServer restServer = new RestfulServer() { + + @Override + protected void doGet(HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException { + if (myFirstRequest) { + theResponse.addHeader("Proxy-Authenticate", "Basic realm=\"some_realm\""); + theResponse.setStatus(407); + theResponse.getWriter().close(); + myFirstRequest = false; + return; + } + String auth = theRequest.getHeader("Proxy-Authorization"); + if (auth != null) { + myAuthHeader = auth; + } + + super.doGet(theRequest, theResponse); + } + + }; + restServer.setFhirContext(ourCtx); + restServer.setResourceProviders(new PatientResourceProvider()); + + // ServletHandler proxyHandler = new ServletHandler(); + ServletHolder servletHolder = new ServletHolder(restServer); + + ServletContextHandler ch = new ServletContextHandler(); + ch.setContextPath("/rootctx/rcp2"); + ch.addServlet(servletHolder, "/fhirctx/fcp2/*"); + + ContextHandlerCollection contexts = new ContextHandlerCollection(); + server.setHandler(contexts); + + server.setHandler(ch); + server.start(); + try { + + final String authUser = "username"; + final String authPassword = "password"; + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials(new AuthScope("127.0.0.1", port), new UsernamePasswordCredentials(authUser, authPassword)); + + HttpHost myProxy = new HttpHost("127.0.0.1", port); + + //@formatter:off + HttpClientBuilder clientBuilder = HttpClientBuilder.create(); + clientBuilder + .setProxy(myProxy) + .setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy()) + .setDefaultCredentialsProvider(credsProvider) + .disableCookieManagement(); + CloseableHttpClient httpClient = clientBuilder.build(); + //@formatter:on + + ourCtx.getRestfulClientFactory().setHttpClient(httpClient); + + String baseUri = "http://99.99.99.99:" + port + "/rootctx/rcp2/fhirctx/fcp2"; + IGenericClient client = ourCtx.newRestfulGenericClient(baseUri); + + IdDt id = new IdDt("Patient", "123"); + client.read(Patient.class, id); + + assertEquals("Basic dXNlcm5hbWU6cGFzc3dvcmQ=", myAuthHeader); + + } finally { + server.stop(); + } + + } + + @BeforeClass + public static void beforeClass() throws Exception { + ourCtx = new FhirContext(); + } + + public static class PatientResourceProvider implements IResourceProvider { + + @Override + public Class getResourceType() { + return Patient.class; + } + + @Read + public Patient read(@IdParam IdDt theId, HttpServletRequest theRequest) { + Patient retVal = new Patient(); + retVal.setId(theId); + ourRequest = theRequest; + + ourLog.info(EnumerationUtils.toList(ourRequest.getHeaderNames()).toString()); + ourLog.info("Proxy-Connection: " + EnumerationUtils.toList(ourRequest.getHeaders("Proxy-Connection"))); + ourLog.info("Host: " + EnumerationUtils.toList(ourRequest.getHeaders("Host"))); + ourLog.info("User-Agent: " + EnumerationUtils.toList(ourRequest.getHeaders("User-Agent"))); + + return retVal; + } + + } + +} diff --git a/pom.xml b/pom.xml index 6d4d7674e8c..28443d308a4 100644 --- a/pom.xml +++ b/pom.xml @@ -393,7 +393,9 @@ var pres = elements[i].getElementsByTagName("pre"); for (var j = 0; j < pres.length; j++) { var pre = pres[j]; - if (pre.innerHTML.match(/\/\*/)) { + if (pre.innerHTML.match(/^\s*\<\;/)) { + pre.className = 'brush: xml'; + } else if (pre.innerHTML.match(/\/\*/)) { pre.className = 'brush: java'; } else if (pre.innerHTML.match(/^\/\//)) { pre.className = 'brush: java'; diff --git a/src/site/resources/hapi.css b/src/site/resources/hapi.css index 84ffd8123b8..d1a0f120dad 100644 --- a/src/site/resources/hapi.css +++ b/src/site/resources/hapi.css @@ -109,11 +109,12 @@ a[name]:before { tt { white-space: pre; - color: #448; + color: #846; margin-bottom: 5px; margin-top: 10px; padding: 2px; border: 1px solid #AAA; + background-color: #F0F0F0; } h1,h2,h3,h4,h5 { diff --git a/src/site/site.xml b/src/site/site.xml index 1af3b531084..0a3bdc989e7 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -22,12 +22,13 @@ - - + + + + + CORS + bootswatch-united sidebar diff --git a/src/site/xdoc/doc_rest_operations.xml b/src/site/xdoc/doc_rest_operations.xml index 9c84a73bf21..6ee614d5a96 100644 --- a/src/site/xdoc/doc_rest_operations.xml +++ b/src/site/xdoc/doc_rest_operations.xml @@ -1,13 +1,12 @@ - + RESTful Operations - HAPI FHIR James Agnew -