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

Commit ee356755 authored by Jesse Wilson's avatar Jesse Wilson Committed by Android (Google) Code Review
Browse files

Merge "Test that we use proxies specified by system properties."

parents 376ee826 10733a71
Loading
Loading
Loading
Loading
+266 −0
Original line number Diff line number Diff line
@@ -20,15 +20,16 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;
import libcore.javax.net.ssl.TestSSLContext;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
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.ssl.AllowAllHostnameVerifier;
import org.apache.http.conn.ssl.SSLSocketFactory;
@@ -37,12 +38,25 @@ import tests.http.MockResponse;
import tests.http.MockWebServer;
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();

        MockWebServer server = new MockWebServer();
        server.useHttps(testSSLContext.serverContext.getSocketFactory(), false);
        server.enqueue(new MockResponse()
                .setResponseCode(200)
@@ -64,66 +78,176 @@ public class HttpsThroughHttpProxyTest extends TestCase {
        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
     */
    public void testConnectViaProxy() throws IOException, InterruptedException {
        MockWebServer proxy = new MockWebServer();
    private void testConnectViaProxy(ProxyConfig proxyConfig) throws Exception {
        MockResponse mockResponse = new MockResponse()
                .setResponseCode(200)
                .setBody("this response comes via a proxy");
        proxy.enqueue(mockResponse);
        proxy.play();
        server.enqueue(mockResponse);
        server.play();

        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));

        RecordedRequest request = proxy.takeRequest();
        assertEquals("GET http://android.com/foo HTTP/1.1", request.getRequestLine());
        assertContains(request.getHeaders(), "Host: android.com");
        RecordedRequest get = server.takeRequest();
        assertEquals("GET http://android.com/foo HTTP/1.1", get.getRequestLine());
        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();

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

        HttpClient httpProxyClient = new DefaultHttpClient();
        HttpHost proxyHost = new HttpHost("localhost", proxy.getPort());
        httpProxyClient.getParams().setParameter(
                ConnRoutePNames.DEFAULT_PROXY, proxyHost);
        SSLSocketFactory sslSocketFactory = new SSLSocketFactory(
                testSSLContext.clientContext.getSocketFactory());
        sslSocketFactory.setHostnameVerifier(new AllowAllHostnameVerifier());
        httpProxyClient.getConnectionManager().getSchemeRegistry()
                .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));

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

        RecordedRequest get = proxy.takeRequest();
        RecordedRequest get = server.takeRequest();
        assertEquals("GET /foo HTTP/1.1", get.getRequestLine());
        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) {
        assertTrue(headers.toString(), headers.contains(header));
    }