Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10733a71 authored by Jesse Wilson's avatar Jesse Wilson
Browse files

Test that we use proxies specified by system properties.

This tests that we use the properties and also that the
precedence prefers client and request properties.

Change-Id: I480dacaf373e3ddd7642d3c918fa50695b36cdba
http://b/3254717
parent fff4ab09
Loading
Loading
Loading
Loading
+266 −0
Original line number Original line Diff line number Diff line
@@ -20,15 +20,16 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;
import java.util.List;
import junit.framework.TestCase;
import junit.framework.TestCase;
import libcore.javax.net.ssl.TestSSLContext;
import libcore.javax.net.ssl.TestSSLContext;
import org.apache.http.HttpHost;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.SSLSocketFactory;
@@ -37,12 +38,25 @@ import tests.http.MockResponse;
import tests.http.MockWebServer;
import tests.http.MockWebServer;
import tests.http.RecordedRequest;
import tests.http.RecordedRequest;


public class HttpsThroughHttpProxyTest extends TestCase {
public class ProxyTest extends TestCase {


    public void testConnectViaHttps() throws IOException, InterruptedException {
    private MockWebServer server = new MockWebServer();

    @Override protected void tearDown() throws Exception {
        System.clearProperty("proxyHost");
        System.clearProperty("proxyPort");
        System.clearProperty("http.proxyHost");
        System.clearProperty("http.proxyPort");
        System.clearProperty("https.proxyHost");
        System.clearProperty("https.proxyPort");

        server.shutdown();
        super.tearDown();
    }

    public void testConnectToHttps() throws IOException, InterruptedException {
        TestSSLContext testSSLContext = TestSSLContext.create();
        TestSSLContext testSSLContext = TestSSLContext.create();


        MockWebServer server = new MockWebServer();
        server.useHttps(testSSLContext.serverContext.getSocketFactory(), false);
        server.useHttps(testSSLContext.serverContext.getSocketFactory(), false);
        server.enqueue(new MockResponse()
        server.enqueue(new MockResponse()
                .setResponseCode(200)
                .setResponseCode(200)
@@ -64,66 +78,176 @@ public class HttpsThroughHttpProxyTest extends TestCase {
        assertEquals("GET /foo HTTP/1.1", request.getRequestLine());
        assertEquals("GET /foo HTTP/1.1", request.getRequestLine());
    }
    }


    /**
     * We had bugs where proxy system properties weren't being honored.
     * http://b/3254717
     */
    public void testConnectViaProxyUsingProxySystemProperty() throws Exception {
        testConnectViaProxy(ProxyConfig.PROXY_SYSTEM_PROPERTY);
    }

    public void testConnectViaProxyUsingHttpProxySystemProperty() throws Exception {
        testConnectViaProxy(ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY);
    }

    public void testConnectViaProxyUsingRequestParameter() throws Exception {
        testConnectViaProxy(ProxyConfig.REQUEST_PARAMETER);
    }

    public void testConnectViaProxyUsingClientParameter() throws Exception {
        testConnectViaProxy(ProxyConfig.CLIENT_PARAMETER);
    }

    /**
    /**
     * http://code.google.com/p/android/issues/detail?id=2690
     * http://code.google.com/p/android/issues/detail?id=2690
     */
     */
    public void testConnectViaProxy() throws IOException, InterruptedException {
    private void testConnectViaProxy(ProxyConfig proxyConfig) throws Exception {
        MockWebServer proxy = new MockWebServer();
        MockResponse mockResponse = new MockResponse()
        MockResponse mockResponse = new MockResponse()
                .setResponseCode(200)
                .setResponseCode(200)
                .setBody("this response comes via a proxy");
                .setBody("this response comes via a proxy");
        proxy.enqueue(mockResponse);
        server.enqueue(mockResponse);
        proxy.play();
        server.play();


        HttpClient httpProxyClient = new DefaultHttpClient();
        HttpClient httpProxyClient = new DefaultHttpClient();
        httpProxyClient.getParams().setParameter(
                ConnRoutePNames.DEFAULT_PROXY, new HttpHost("localhost", proxy.getPort()));


        HttpResponse response = httpProxyClient.execute(new HttpGet("http://android.com/foo"));
        HttpGet request = new HttpGet("http://android.com/foo");
        proxyConfig.configure(server, httpProxyClient, request);

        HttpResponse response = httpProxyClient.execute(request);
        assertEquals("this response comes via a proxy", contentToString(response));
        assertEquals("this response comes via a proxy", contentToString(response));


        RecordedRequest request = proxy.takeRequest();
        RecordedRequest get = server.takeRequest();
        assertEquals("GET http://android.com/foo HTTP/1.1", request.getRequestLine());
        assertEquals("GET http://android.com/foo HTTP/1.1", get.getRequestLine());
        assertContains(request.getHeaders(), "Host: android.com");
        assertContains(get.getHeaders(), "Host: android.com");
    }

    public void testConnectViaHttpProxyToHttpsUsingProxySystemProperty() throws Exception {
        testConnectViaHttpProxyToHttps(ProxyConfig.PROXY_SYSTEM_PROPERTY);
    }

    public void testConnectViaHttpProxyToHttpsUsingHttpsProxySystemProperty() throws Exception {
        testConnectViaHttpProxyToHttps(ProxyConfig.HTTPS_PROXY_SYSTEM_PROPERTY);
    }

    public void testConnectViaHttpProxyToHttpsUsingClientParameter() throws Exception {
        testConnectViaHttpProxyToHttps(ProxyConfig.CLIENT_PARAMETER);
    }

    public void testConnectViaHttpProxyToHttpsUsingRequestParameter() throws Exception {
        testConnectViaHttpProxyToHttps(ProxyConfig.REQUEST_PARAMETER);
    }
    }


    public void testConnectViaHttpProxyToHttps() throws IOException, InterruptedException {
    private void testConnectViaHttpProxyToHttps(ProxyConfig proxyConfig) throws Exception {
        TestSSLContext testSSLContext = TestSSLContext.create();
        TestSSLContext testSSLContext = TestSSLContext.create();


        MockWebServer proxy = new MockWebServer();
        server.useHttps(testSSLContext.serverContext.getSocketFactory(), true);
        proxy.useHttps(testSSLContext.serverContext.getSocketFactory(), true);
        MockResponse connectResponse = new MockResponse()
        MockResponse connectResponse = new MockResponse()
                .setResponseCode(200);
                .setResponseCode(200);
        connectResponse.getHeaders().clear();
        connectResponse.getHeaders().clear();
        proxy.enqueue(connectResponse);
        server.enqueue(connectResponse);
        proxy.enqueue(new MockResponse()
        server.enqueue(new MockResponse()
                .setResponseCode(200)
                .setResponseCode(200)
                .setBody("this response comes via a secure proxy"));
                .setBody("this response comes via a secure proxy"));
        proxy.play();
        server.play();


        HttpClient httpProxyClient = new DefaultHttpClient();
        HttpClient httpProxyClient = new DefaultHttpClient();
        HttpHost proxyHost = new HttpHost("localhost", proxy.getPort());
        httpProxyClient.getParams().setParameter(
                ConnRoutePNames.DEFAULT_PROXY, proxyHost);
        SSLSocketFactory sslSocketFactory = new SSLSocketFactory(
        SSLSocketFactory sslSocketFactory = new SSLSocketFactory(
                testSSLContext.clientContext.getSocketFactory());
                testSSLContext.clientContext.getSocketFactory());
        sslSocketFactory.setHostnameVerifier(new AllowAllHostnameVerifier());
        sslSocketFactory.setHostnameVerifier(new AllowAllHostnameVerifier());
        httpProxyClient.getConnectionManager().getSchemeRegistry()
        httpProxyClient.getConnectionManager().getSchemeRegistry()
                .register(new Scheme("https", sslSocketFactory, 443));
                .register(new Scheme("https", sslSocketFactory, 443));


        HttpResponse response = httpProxyClient.execute(new HttpGet("https://android.com/foo"));
        HttpGet request = new HttpGet("https://android.com/foo");
        proxyConfig.configure(server, httpProxyClient, request);

        HttpResponse response = httpProxyClient.execute(request);
        assertEquals("this response comes via a secure proxy", contentToString(response));
        assertEquals("this response comes via a secure proxy", contentToString(response));


        RecordedRequest connect = proxy.takeRequest();
        RecordedRequest connect = server.takeRequest();
        assertEquals("Connect line failure on proxy " + proxyHost.toHostString(),
        assertEquals("Connect line failure on proxy " + proxyConfig,
                "CONNECT android.com:443 HTTP/1.1", connect.getRequestLine());
                "CONNECT android.com:443 HTTP/1.1", connect.getRequestLine());
        assertContains(connect.getHeaders(), "Host: android.com");
        assertContains(connect.getHeaders(), "Host: android.com");


        RecordedRequest get = proxy.takeRequest();
        RecordedRequest get = server.takeRequest();
        assertEquals("GET /foo HTTP/1.1", get.getRequestLine());
        assertEquals("GET /foo HTTP/1.1", get.getRequestLine());
        assertContains(get.getHeaders(), "Host: android.com");
        assertContains(get.getHeaders(), "Host: android.com");
    }
    }


    public void testClientParamPreferredOverSystemProperty() throws Exception {
        testParamPreferredOverSystemProperty(ProxyConfig.CLIENT_PARAMETER);
    }

    public void testRequestParamPreferredOverSystemProperty() throws Exception {
        testParamPreferredOverSystemProperty(ProxyConfig.REQUEST_PARAMETER);
    }

    private void testParamPreferredOverSystemProperty(ProxyConfig proxyConfig) throws Exception {
        server.enqueue(new MockResponse().setBody("Via request parameter proxy!"));
        server.play();
        System.setProperty("http.proxyHost", "proxy.foo");
        System.setProperty("http.proxyPort", "8080");

        HttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet("http://origin.foo/bar");
        proxyConfig.configure(server, client, request);
        HttpResponse response = client.execute(request);
        assertEquals("Via request parameter proxy!", contentToString(response));

        RecordedRequest recordedRequest = server.takeRequest();
        assertEquals("GET http://origin.foo/bar HTTP/1.1", recordedRequest.getRequestLine());
    }

    public void testExplicitNoProxyCancelsSystemProperty() throws Exception {
        server.enqueue(new MockResponse().setBody("Via the origin server!"));
        server.play();
        System.setProperty("http.proxyHost", "proxy.foo");
        System.setProperty("http.proxyPort", "8080");

        HttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet(server.getUrl("/bar").toURI());
        request.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, ConnRouteParams.NO_HOST);
        HttpResponse response = client.execute(request);
        assertEquals("Via the origin server!", contentToString(response));

        RecordedRequest recordedRequest = server.takeRequest();
        assertEquals("GET /bar HTTP/1.1", recordedRequest.getRequestLine());
    }

    enum ProxyConfig {
        PROXY_SYSTEM_PROPERTY() {
            @Override void configure(MockWebServer server, HttpClient client, HttpRequest request) {
                System.setProperty("proxyHost", "localhost");
                System.setProperty("proxyPort", Integer.toString(server.getPort()));
            }
        },
        HTTP_PROXY_SYSTEM_PROPERTY() {
            @Override void configure(MockWebServer server, HttpClient client, HttpRequest request) {
                System.setProperty("http.proxyHost", "localhost");
                System.setProperty("http.proxyPort", Integer.toString(server.getPort()));
            }
        },
        HTTPS_PROXY_SYSTEM_PROPERTY() {
            @Override void configure(MockWebServer server, HttpClient client, HttpRequest request) {
                System.setProperty("https.proxyHost", "localhost");
                System.setProperty("https.proxyPort", Integer.toString(server.getPort()));
            }
        },
        CLIENT_PARAMETER() {
            @Override void configure(MockWebServer server, HttpClient client, HttpRequest request) {
                client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
                        new HttpHost("localhost", server.getPort()));
            }
        },
        REQUEST_PARAMETER() {
            @Override void configure(MockWebServer server, HttpClient client, HttpRequest request) {
                request.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
                        new HttpHost("localhost", server.getPort()));
            }
        };

        abstract void configure(MockWebServer proxy, HttpClient client, HttpRequest request);
    }

    private void assertContains(List<String> headers, String header) {
    private void assertContains(List<String> headers, String header) {
        assertTrue(headers.toString(), headers.contains(header));
        assertTrue(headers.toString(), headers.contains(header));
    }
    }