package jenkins.plugins.asynchttpclient; import com.ning.http.client.AsyncHttpClient; import com.ning.http.client.ListenableFuture; import com.ning.http.client.RequestBuilder; import com.ning.http.client.Response; import hudson.ProxyConfiguration; import hudson.model.FreeStyleProject; import java.net.HttpURLConnection; import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLConnection; import java.util.Random; import java.util.concurrent.ExecutionException; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.TrustManagerFactory; import jenkins.model.Jenkins; import org.junit.AssumptionViolatedException; import org.junit.Rule; import org.junit.Test; import org.jvnet.hudson.test.JenkinsRule; import sun.security.provider.certpath.SunCertPathBuilderException; import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import static org.junit.Assume.assumeThat; public class AHCTest { @Rule public JenkinsRule j = new JenkinsRule(); @Test public void closeCausesRecycle() { assertThat(AHC.instance(), notNullValue()); AHC.instance().close(); assertThat(AHC.instance(), notNullValue()); assertThat(AHC.instance(), hasProperty("closed", is(false))); } @Test public void worksOnJenkinsClasspath() throws Exception { final Random entropy = new Random(); final String jobName = String.format("Random job name %d", entropy.nextLong()); final String systemMessage = String.format("Random system message %d", entropy.nextLong()); j.jenkins.setSystemMessage(systemMessage); j.getInstance().createProject(j.getInstance().getDescriptorByType(FreeStyleProject.DescriptorImpl.class), jobName); final ListenableFuture<Response> response = AHC.instance().executeRequest(new RequestBuilder("GET").setUrl(j.getURL().toURI().toString()).build()); assertThat(response.get().getResponseBody(), allOf( containsString(Jenkins.getVersion().toString()), containsString(systemMessage), containsString(jobName) )); } @Test(expected=SunCertPathBuilderException.class) public void failsOnSelfSignedCertificate() throws Throwable { try { ProxyConfiguration proxy = Jenkins.getInstance().proxy; URL url = new URL("https://letsencrypt.org"); HttpURLConnection connection = (HttpURLConnection) (proxy == null ? url.openConnection() : url.openConnection(proxy.createProxy("self-signed.badssl.com"))); connection.setRequestMethod("HEAD"); connection.setConnectTimeout(30000); connection.connect(); throw new AssumptionViolatedException("The certificate for self-signed.badssl.com is not trusted"); } catch (SSLHandshakeException e) { // yeah we have a test } catch (SocketTimeoutException e) { throw new AssumptionViolatedException("We can connect to self-signed.badssl.com", e); } AsyncHttpClient ahc = AHC.instance(); ListenableFuture<Response> response = ahc.prepareGet("https://self-signed.badssl.com/").execute(); try { response.get(); } catch (ExecutionException e) { // walk the cause stack to get the real cause throw e.getCause().getCause().getCause().getCause().getCause(); } fail("Self Signed certificate accepted"); } @Test(expected=SunCertPathBuilderException.class) public void failsOnExpiredCertificate() throws Throwable { try { ProxyConfiguration proxy = Jenkins.getInstance().proxy; URL url = new URL("https://letsencrypt.org"); HttpURLConnection connection = (HttpURLConnection) (proxy == null ? url.openConnection() : url.openConnection(proxy.createProxy("expired.badssl.com"))); connection.setRequestMethod("HEAD"); connection.setConnectTimeout(30000); connection.connect(); throw new AssumptionViolatedException("The certificate for expired.badssl.com is expired"); } catch (SSLHandshakeException e) { // yeah we have a test } catch (SocketTimeoutException e) { throw new AssumptionViolatedException("We can connect to expired.badssl.com", e); } AsyncHttpClient ahc = AHC.instance(); ListenableFuture<Response> response = ahc.prepareGet("https://expired.badssl.com/").execute(); try { response.get(); } catch (ExecutionException e) { // walk the cause stack to get the real cause throw e.getCause().getCause().getCause().getCause().getCause(); } fail("Expired certificate accepted"); } @Test public void acceptGoodCertificate() throws Throwable { try { ProxyConfiguration proxy = Jenkins.getInstance().proxy; URL url = new URL("https://letsencrypt.org"); HttpURLConnection connection = (HttpURLConnection) (proxy == null ? url.openConnection() : url.openConnection(proxy.createProxy("letsencrypt.org"))); connection.setRequestMethod("HEAD"); connection.setConnectTimeout(30000); connection.connect(); } catch (SSLHandshakeException e) { throw new AssumptionViolatedException("The Root CA for letsencrypt.org is in the JVM trust store", e); } catch (SocketTimeoutException e) { throw new AssumptionViolatedException("We can connect to letsencrypt.org", e); } AsyncHttpClient ahc = AHC.instance(); ListenableFuture<Response> response = ahc.prepareGet("https://letsencrypt.org").execute(); assertTrue(response.get().hasResponseStatus()); } }