110733a71c5557861160292e07de011ea9a4db25cJesse Wilson/*
210733a71c5557861160292e07de011ea9a4db25cJesse Wilson * Copyright (C) 2010 The Android Open Source Project
310733a71c5557861160292e07de011ea9a4db25cJesse Wilson *
410733a71c5557861160292e07de011ea9a4db25cJesse Wilson * Licensed under the Apache License, Version 2.0 (the "License");
510733a71c5557861160292e07de011ea9a4db25cJesse Wilson * you may not use this file except in compliance with the License.
610733a71c5557861160292e07de011ea9a4db25cJesse Wilson * You may obtain a copy of the License at
710733a71c5557861160292e07de011ea9a4db25cJesse Wilson *
810733a71c5557861160292e07de011ea9a4db25cJesse Wilson *      http://www.apache.org/licenses/LICENSE-2.0
910733a71c5557861160292e07de011ea9a4db25cJesse Wilson *
1010733a71c5557861160292e07de011ea9a4db25cJesse Wilson * Unless required by applicable law or agreed to in writing, software
1110733a71c5557861160292e07de011ea9a4db25cJesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
1210733a71c5557861160292e07de011ea9a4db25cJesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1310733a71c5557861160292e07de011ea9a4db25cJesse Wilson * See the License for the specific language governing permissions and
1410733a71c5557861160292e07de011ea9a4db25cJesse Wilson * limitations under the License.
1510733a71c5557861160292e07de011ea9a4db25cJesse Wilson */
1610733a71c5557861160292e07de011ea9a4db25cJesse Wilson
1710733a71c5557861160292e07de011ea9a4db25cJesse Wilsonpackage android.net.http;
1810733a71c5557861160292e07de011ea9a4db25cJesse Wilson
197ad00e6f5ccaf975a49870cdd267d28ae144314eJesse Wilsonimport com.google.mockwebserver.MockResponse;
207ad00e6f5ccaf975a49870cdd267d28ae144314eJesse Wilsonimport com.google.mockwebserver.MockWebServer;
217ad00e6f5ccaf975a49870cdd267d28ae144314eJesse Wilsonimport com.google.mockwebserver.RecordedRequest;
227ad00e6f5ccaf975a49870cdd267d28ae144314eJesse Wilsonimport com.google.mockwebserver.SocketPolicy;
2310733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport java.io.IOException;
2410733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport java.io.InputStreamReader;
2510733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport java.io.Reader;
2610733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport java.io.StringWriter;
2710733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport java.util.List;
2810733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport junit.framework.TestCase;
2910733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport libcore.javax.net.ssl.TestSSLContext;
3010733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport org.apache.http.HttpHost;
3110733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport org.apache.http.HttpRequest;
3210733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport org.apache.http.HttpResponse;
3310733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport org.apache.http.client.HttpClient;
3410733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport org.apache.http.client.methods.HttpGet;
3510733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport org.apache.http.conn.params.ConnRoutePNames;
3610733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport org.apache.http.conn.params.ConnRouteParams;
3710733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport org.apache.http.conn.scheme.Scheme;
3810733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport org.apache.http.conn.ssl.AllowAllHostnameVerifier;
3910733a71c5557861160292e07de011ea9a4db25cJesse Wilsonimport org.apache.http.conn.ssl.SSLSocketFactory;
4010733a71c5557861160292e07de011ea9a4db25cJesse Wilson
41bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilsonpublic abstract class AbstractProxyTest extends TestCase {
4210733a71c5557861160292e07de011ea9a4db25cJesse Wilson
4310733a71c5557861160292e07de011ea9a4db25cJesse Wilson    private MockWebServer server = new MockWebServer();
4410733a71c5557861160292e07de011ea9a4db25cJesse Wilson
45bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson    protected abstract HttpClient newHttpClient();
46bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson
4710733a71c5557861160292e07de011ea9a4db25cJesse Wilson    @Override protected void tearDown() throws Exception {
4810733a71c5557861160292e07de011ea9a4db25cJesse Wilson        System.clearProperty("proxyHost");
4910733a71c5557861160292e07de011ea9a4db25cJesse Wilson        System.clearProperty("proxyPort");
5010733a71c5557861160292e07de011ea9a4db25cJesse Wilson        System.clearProperty("http.proxyHost");
5110733a71c5557861160292e07de011ea9a4db25cJesse Wilson        System.clearProperty("http.proxyPort");
5210733a71c5557861160292e07de011ea9a4db25cJesse Wilson        System.clearProperty("https.proxyHost");
5310733a71c5557861160292e07de011ea9a4db25cJesse Wilson        System.clearProperty("https.proxyPort");
5410733a71c5557861160292e07de011ea9a4db25cJesse Wilson
5510733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.shutdown();
5610733a71c5557861160292e07de011ea9a4db25cJesse Wilson        super.tearDown();
5710733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
5810733a71c5557861160292e07de011ea9a4db25cJesse Wilson
59bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson    public void testConnectToHttps() throws Exception {
6010733a71c5557861160292e07de011ea9a4db25cJesse Wilson        TestSSLContext testSSLContext = TestSSLContext.create();
6110733a71c5557861160292e07de011ea9a4db25cJesse Wilson
6210733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.useHttps(testSSLContext.serverContext.getSocketFactory(), false);
6310733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.enqueue(new MockResponse()
6410733a71c5557861160292e07de011ea9a4db25cJesse Wilson                .setResponseCode(200)
6510733a71c5557861160292e07de011ea9a4db25cJesse Wilson                .setBody("this response comes via HTTPS"));
6610733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.play();
6710733a71c5557861160292e07de011ea9a4db25cJesse Wilson
68bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson        HttpClient httpClient = newHttpClient();
69bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson
70bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson        SSLSocketFactory sslSocketFactory = newSslSocketFactory(testSSLContext);
7110733a71c5557861160292e07de011ea9a4db25cJesse Wilson        sslSocketFactory.setHostnameVerifier(new AllowAllHostnameVerifier());
7210733a71c5557861160292e07de011ea9a4db25cJesse Wilson        httpClient.getConnectionManager().getSchemeRegistry()
7310733a71c5557861160292e07de011ea9a4db25cJesse Wilson                .register(new Scheme("https", sslSocketFactory, server.getPort()));
7410733a71c5557861160292e07de011ea9a4db25cJesse Wilson
7510733a71c5557861160292e07de011ea9a4db25cJesse Wilson        HttpResponse response = httpClient.execute(
7610733a71c5557861160292e07de011ea9a4db25cJesse Wilson                new HttpGet("https://localhost:" + server.getPort() + "/foo"));
7710733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertEquals("this response comes via HTTPS", contentToString(response));
7810733a71c5557861160292e07de011ea9a4db25cJesse Wilson
7910733a71c5557861160292e07de011ea9a4db25cJesse Wilson        RecordedRequest request = server.takeRequest();
8010733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertEquals("GET /foo HTTP/1.1", request.getRequestLine());
8110733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
8210733a71c5557861160292e07de011ea9a4db25cJesse Wilson
83bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson    private SSLSocketFactory newSslSocketFactory(TestSSLContext testSSLContext) throws Exception {
84bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson        // call through to Apache HTTP's non-public SSLSocketFactory constructor
85bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson        return SSLSocketFactory.class.getConstructor(javax.net.ssl.SSLSocketFactory.class)
86bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson                .newInstance(testSSLContext.clientContext.getSocketFactory());
87bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson    }
88bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson
8910733a71c5557861160292e07de011ea9a4db25cJesse Wilson    /**
9010733a71c5557861160292e07de011ea9a4db25cJesse Wilson     * We had bugs where proxy system properties weren't being honored.
9110733a71c5557861160292e07de011ea9a4db25cJesse Wilson     * http://b/3254717
9210733a71c5557861160292e07de011ea9a4db25cJesse Wilson     */
9310733a71c5557861160292e07de011ea9a4db25cJesse Wilson    public void testConnectViaProxyUsingProxySystemProperty() throws Exception {
9410733a71c5557861160292e07de011ea9a4db25cJesse Wilson        testConnectViaProxy(ProxyConfig.PROXY_SYSTEM_PROPERTY);
9510733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
9610733a71c5557861160292e07de011ea9a4db25cJesse Wilson
9710733a71c5557861160292e07de011ea9a4db25cJesse Wilson    public void testConnectViaProxyUsingHttpProxySystemProperty() throws Exception {
9810733a71c5557861160292e07de011ea9a4db25cJesse Wilson        testConnectViaProxy(ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY);
9910733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
10010733a71c5557861160292e07de011ea9a4db25cJesse Wilson
10110733a71c5557861160292e07de011ea9a4db25cJesse Wilson    public void testConnectViaProxyUsingRequestParameter() throws Exception {
10210733a71c5557861160292e07de011ea9a4db25cJesse Wilson        testConnectViaProxy(ProxyConfig.REQUEST_PARAMETER);
10310733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
10410733a71c5557861160292e07de011ea9a4db25cJesse Wilson
10510733a71c5557861160292e07de011ea9a4db25cJesse Wilson    public void testConnectViaProxyUsingClientParameter() throws Exception {
10610733a71c5557861160292e07de011ea9a4db25cJesse Wilson        testConnectViaProxy(ProxyConfig.CLIENT_PARAMETER);
10710733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
10810733a71c5557861160292e07de011ea9a4db25cJesse Wilson
10910733a71c5557861160292e07de011ea9a4db25cJesse Wilson    /**
11010733a71c5557861160292e07de011ea9a4db25cJesse Wilson     * http://code.google.com/p/android/issues/detail?id=2690
11110733a71c5557861160292e07de011ea9a4db25cJesse Wilson     */
11210733a71c5557861160292e07de011ea9a4db25cJesse Wilson    private void testConnectViaProxy(ProxyConfig proxyConfig) throws Exception {
11310733a71c5557861160292e07de011ea9a4db25cJesse Wilson        MockResponse mockResponse = new MockResponse()
11410733a71c5557861160292e07de011ea9a4db25cJesse Wilson                .setResponseCode(200)
11510733a71c5557861160292e07de011ea9a4db25cJesse Wilson                .setBody("this response comes via a proxy");
11610733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.enqueue(mockResponse);
11710733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.play();
11810733a71c5557861160292e07de011ea9a4db25cJesse Wilson
119bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson        HttpClient httpProxyClient = newHttpClient();
12010733a71c5557861160292e07de011ea9a4db25cJesse Wilson
12110733a71c5557861160292e07de011ea9a4db25cJesse Wilson        HttpGet request = new HttpGet("http://android.com/foo");
12210733a71c5557861160292e07de011ea9a4db25cJesse Wilson        proxyConfig.configure(server, httpProxyClient, request);
12310733a71c5557861160292e07de011ea9a4db25cJesse Wilson
12410733a71c5557861160292e07de011ea9a4db25cJesse Wilson        HttpResponse response = httpProxyClient.execute(request);
12510733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertEquals("this response comes via a proxy", contentToString(response));
12610733a71c5557861160292e07de011ea9a4db25cJesse Wilson
12710733a71c5557861160292e07de011ea9a4db25cJesse Wilson        RecordedRequest get = server.takeRequest();
12810733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertEquals("GET http://android.com/foo HTTP/1.1", get.getRequestLine());
12910733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertContains(get.getHeaders(), "Host: android.com");
13010733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
13110733a71c5557861160292e07de011ea9a4db25cJesse Wilson
13210733a71c5557861160292e07de011ea9a4db25cJesse Wilson    public void testConnectViaHttpProxyToHttpsUsingProxySystemProperty() throws Exception {
13310733a71c5557861160292e07de011ea9a4db25cJesse Wilson        testConnectViaHttpProxyToHttps(ProxyConfig.PROXY_SYSTEM_PROPERTY);
13410733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
13510733a71c5557861160292e07de011ea9a4db25cJesse Wilson
13610733a71c5557861160292e07de011ea9a4db25cJesse Wilson    public void testConnectViaHttpProxyToHttpsUsingHttpsProxySystemProperty() throws Exception {
13710733a71c5557861160292e07de011ea9a4db25cJesse Wilson        testConnectViaHttpProxyToHttps(ProxyConfig.HTTPS_PROXY_SYSTEM_PROPERTY);
13810733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
13910733a71c5557861160292e07de011ea9a4db25cJesse Wilson
14010733a71c5557861160292e07de011ea9a4db25cJesse Wilson    public void testConnectViaHttpProxyToHttpsUsingClientParameter() throws Exception {
14110733a71c5557861160292e07de011ea9a4db25cJesse Wilson        testConnectViaHttpProxyToHttps(ProxyConfig.CLIENT_PARAMETER);
14210733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
14310733a71c5557861160292e07de011ea9a4db25cJesse Wilson
14410733a71c5557861160292e07de011ea9a4db25cJesse Wilson    public void testConnectViaHttpProxyToHttpsUsingRequestParameter() throws Exception {
14510733a71c5557861160292e07de011ea9a4db25cJesse Wilson        testConnectViaHttpProxyToHttps(ProxyConfig.REQUEST_PARAMETER);
14610733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
14710733a71c5557861160292e07de011ea9a4db25cJesse Wilson
14810733a71c5557861160292e07de011ea9a4db25cJesse Wilson    private void testConnectViaHttpProxyToHttps(ProxyConfig proxyConfig) throws Exception {
14910733a71c5557861160292e07de011ea9a4db25cJesse Wilson        TestSSLContext testSSLContext = TestSSLContext.create();
15010733a71c5557861160292e07de011ea9a4db25cJesse Wilson
15110733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.useHttps(testSSLContext.serverContext.getSocketFactory(), true);
152a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom        server.enqueue(new MockResponse()
153a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom                .setSocketPolicy(SocketPolicy.UPGRADE_TO_SSL_AT_END)
154a7284f0e72745d66155e1e282fc07113332790faBrian Carlstrom                .clearHeaders());
15510733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.enqueue(new MockResponse()
15610733a71c5557861160292e07de011ea9a4db25cJesse Wilson                .setResponseCode(200)
15710733a71c5557861160292e07de011ea9a4db25cJesse Wilson                .setBody("this response comes via a secure proxy"));
15810733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.play();
15910733a71c5557861160292e07de011ea9a4db25cJesse Wilson
160bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson        HttpClient httpProxyClient = newHttpClient();
161bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson        SSLSocketFactory sslSocketFactory = newSslSocketFactory(testSSLContext);
16210733a71c5557861160292e07de011ea9a4db25cJesse Wilson        sslSocketFactory.setHostnameVerifier(new AllowAllHostnameVerifier());
16310733a71c5557861160292e07de011ea9a4db25cJesse Wilson        httpProxyClient.getConnectionManager().getSchemeRegistry()
16410733a71c5557861160292e07de011ea9a4db25cJesse Wilson                .register(new Scheme("https", sslSocketFactory, 443));
16510733a71c5557861160292e07de011ea9a4db25cJesse Wilson
16610733a71c5557861160292e07de011ea9a4db25cJesse Wilson        HttpGet request = new HttpGet("https://android.com/foo");
16710733a71c5557861160292e07de011ea9a4db25cJesse Wilson        proxyConfig.configure(server, httpProxyClient, request);
16810733a71c5557861160292e07de011ea9a4db25cJesse Wilson
16910733a71c5557861160292e07de011ea9a4db25cJesse Wilson        HttpResponse response = httpProxyClient.execute(request);
17010733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertEquals("this response comes via a secure proxy", contentToString(response));
17110733a71c5557861160292e07de011ea9a4db25cJesse Wilson
17210733a71c5557861160292e07de011ea9a4db25cJesse Wilson        RecordedRequest connect = server.takeRequest();
17310733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertEquals("Connect line failure on proxy " + proxyConfig,
17410733a71c5557861160292e07de011ea9a4db25cJesse Wilson                "CONNECT android.com:443 HTTP/1.1", connect.getRequestLine());
17510733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertContains(connect.getHeaders(), "Host: android.com");
17610733a71c5557861160292e07de011ea9a4db25cJesse Wilson
17710733a71c5557861160292e07de011ea9a4db25cJesse Wilson        RecordedRequest get = server.takeRequest();
17810733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertEquals("GET /foo HTTP/1.1", get.getRequestLine());
17910733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertContains(get.getHeaders(), "Host: android.com");
18010733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
18110733a71c5557861160292e07de011ea9a4db25cJesse Wilson
18210733a71c5557861160292e07de011ea9a4db25cJesse Wilson    public void testClientParamPreferredOverSystemProperty() throws Exception {
18310733a71c5557861160292e07de011ea9a4db25cJesse Wilson        testParamPreferredOverSystemProperty(ProxyConfig.CLIENT_PARAMETER);
18410733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
18510733a71c5557861160292e07de011ea9a4db25cJesse Wilson
18610733a71c5557861160292e07de011ea9a4db25cJesse Wilson    public void testRequestParamPreferredOverSystemProperty() throws Exception {
18710733a71c5557861160292e07de011ea9a4db25cJesse Wilson        testParamPreferredOverSystemProperty(ProxyConfig.REQUEST_PARAMETER);
18810733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
18910733a71c5557861160292e07de011ea9a4db25cJesse Wilson
19010733a71c5557861160292e07de011ea9a4db25cJesse Wilson    private void testParamPreferredOverSystemProperty(ProxyConfig proxyConfig) throws Exception {
19110733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.enqueue(new MockResponse().setBody("Via request parameter proxy!"));
19210733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.play();
19310733a71c5557861160292e07de011ea9a4db25cJesse Wilson        System.setProperty("http.proxyHost", "proxy.foo");
19410733a71c5557861160292e07de011ea9a4db25cJesse Wilson        System.setProperty("http.proxyPort", "8080");
19510733a71c5557861160292e07de011ea9a4db25cJesse Wilson
196bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson        HttpClient client = newHttpClient();
19710733a71c5557861160292e07de011ea9a4db25cJesse Wilson        HttpGet request = new HttpGet("http://origin.foo/bar");
19810733a71c5557861160292e07de011ea9a4db25cJesse Wilson        proxyConfig.configure(server, client, request);
19910733a71c5557861160292e07de011ea9a4db25cJesse Wilson        HttpResponse response = client.execute(request);
20010733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertEquals("Via request parameter proxy!", contentToString(response));
20110733a71c5557861160292e07de011ea9a4db25cJesse Wilson
20210733a71c5557861160292e07de011ea9a4db25cJesse Wilson        RecordedRequest recordedRequest = server.takeRequest();
20310733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertEquals("GET http://origin.foo/bar HTTP/1.1", recordedRequest.getRequestLine());
20410733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
20510733a71c5557861160292e07de011ea9a4db25cJesse Wilson
20610733a71c5557861160292e07de011ea9a4db25cJesse Wilson    public void testExplicitNoProxyCancelsSystemProperty() throws Exception {
20710733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.enqueue(new MockResponse().setBody("Via the origin server!"));
20810733a71c5557861160292e07de011ea9a4db25cJesse Wilson        server.play();
20910733a71c5557861160292e07de011ea9a4db25cJesse Wilson        System.setProperty("http.proxyHost", "proxy.foo");
21010733a71c5557861160292e07de011ea9a4db25cJesse Wilson        System.setProperty("http.proxyPort", "8080");
21110733a71c5557861160292e07de011ea9a4db25cJesse Wilson
212bf1df887d4b87f7da69cd4fe9306eb0d19166d52Jesse Wilson        HttpClient client = newHttpClient();
21310733a71c5557861160292e07de011ea9a4db25cJesse Wilson        HttpGet request = new HttpGet(server.getUrl("/bar").toURI());
21410733a71c5557861160292e07de011ea9a4db25cJesse Wilson        request.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, ConnRouteParams.NO_HOST);
21510733a71c5557861160292e07de011ea9a4db25cJesse Wilson        HttpResponse response = client.execute(request);
21610733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertEquals("Via the origin server!", contentToString(response));
21710733a71c5557861160292e07de011ea9a4db25cJesse Wilson
21810733a71c5557861160292e07de011ea9a4db25cJesse Wilson        RecordedRequest recordedRequest = server.takeRequest();
21910733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertEquals("GET /bar HTTP/1.1", recordedRequest.getRequestLine());
22010733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
22110733a71c5557861160292e07de011ea9a4db25cJesse Wilson
222de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson    // http://b/5372438
223de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson    public void testRetryWithProxy() throws Exception {
224de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson        server.enqueue(new MockResponse()
225de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson                .setSocketPolicy(SocketPolicy.DISCONNECT_AT_START));
226de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson        server.play();
227de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson
228de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson        HttpClient httpProxyClient = newHttpClient();
229de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson        HttpGet request = new HttpGet("http://android.com/foo");
230de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson        ProxyConfig.REQUEST_PARAMETER.configure(server, httpProxyClient, request);
231de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson
232de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson        try {
233de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson            httpProxyClient.execute(request);
234de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson            fail();
235de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson        } catch (IOException expected) {
236de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson        }
237de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson    }
238de5d7d250848b0db4119f362e2e700cb19e02293Jesse Wilson
23910733a71c5557861160292e07de011ea9a4db25cJesse Wilson    enum ProxyConfig {
24010733a71c5557861160292e07de011ea9a4db25cJesse Wilson        PROXY_SYSTEM_PROPERTY() {
24110733a71c5557861160292e07de011ea9a4db25cJesse Wilson            @Override void configure(MockWebServer server, HttpClient client, HttpRequest request) {
24210733a71c5557861160292e07de011ea9a4db25cJesse Wilson                System.setProperty("proxyHost", "localhost");
24310733a71c5557861160292e07de011ea9a4db25cJesse Wilson                System.setProperty("proxyPort", Integer.toString(server.getPort()));
24410733a71c5557861160292e07de011ea9a4db25cJesse Wilson            }
24510733a71c5557861160292e07de011ea9a4db25cJesse Wilson        },
24610733a71c5557861160292e07de011ea9a4db25cJesse Wilson        HTTP_PROXY_SYSTEM_PROPERTY() {
24710733a71c5557861160292e07de011ea9a4db25cJesse Wilson            @Override void configure(MockWebServer server, HttpClient client, HttpRequest request) {
24810733a71c5557861160292e07de011ea9a4db25cJesse Wilson                System.setProperty("http.proxyHost", "localhost");
24910733a71c5557861160292e07de011ea9a4db25cJesse Wilson                System.setProperty("http.proxyPort", Integer.toString(server.getPort()));
25010733a71c5557861160292e07de011ea9a4db25cJesse Wilson            }
25110733a71c5557861160292e07de011ea9a4db25cJesse Wilson        },
25210733a71c5557861160292e07de011ea9a4db25cJesse Wilson        HTTPS_PROXY_SYSTEM_PROPERTY() {
25310733a71c5557861160292e07de011ea9a4db25cJesse Wilson            @Override void configure(MockWebServer server, HttpClient client, HttpRequest request) {
25410733a71c5557861160292e07de011ea9a4db25cJesse Wilson                System.setProperty("https.proxyHost", "localhost");
25510733a71c5557861160292e07de011ea9a4db25cJesse Wilson                System.setProperty("https.proxyPort", Integer.toString(server.getPort()));
25610733a71c5557861160292e07de011ea9a4db25cJesse Wilson            }
25710733a71c5557861160292e07de011ea9a4db25cJesse Wilson        },
25810733a71c5557861160292e07de011ea9a4db25cJesse Wilson        CLIENT_PARAMETER() {
25910733a71c5557861160292e07de011ea9a4db25cJesse Wilson            @Override void configure(MockWebServer server, HttpClient client, HttpRequest request) {
26010733a71c5557861160292e07de011ea9a4db25cJesse Wilson                client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
26110733a71c5557861160292e07de011ea9a4db25cJesse Wilson                        new HttpHost("localhost", server.getPort()));
26210733a71c5557861160292e07de011ea9a4db25cJesse Wilson            }
26310733a71c5557861160292e07de011ea9a4db25cJesse Wilson        },
26410733a71c5557861160292e07de011ea9a4db25cJesse Wilson        REQUEST_PARAMETER() {
26510733a71c5557861160292e07de011ea9a4db25cJesse Wilson            @Override void configure(MockWebServer server, HttpClient client, HttpRequest request) {
26610733a71c5557861160292e07de011ea9a4db25cJesse Wilson                request.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
26710733a71c5557861160292e07de011ea9a4db25cJesse Wilson                        new HttpHost("localhost", server.getPort()));
26810733a71c5557861160292e07de011ea9a4db25cJesse Wilson            }
26910733a71c5557861160292e07de011ea9a4db25cJesse Wilson        };
27010733a71c5557861160292e07de011ea9a4db25cJesse Wilson
27110733a71c5557861160292e07de011ea9a4db25cJesse Wilson        abstract void configure(MockWebServer proxy, HttpClient client, HttpRequest request);
27210733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
27310733a71c5557861160292e07de011ea9a4db25cJesse Wilson
27410733a71c5557861160292e07de011ea9a4db25cJesse Wilson    private void assertContains(List<String> headers, String header) {
27510733a71c5557861160292e07de011ea9a4db25cJesse Wilson        assertTrue(headers.toString(), headers.contains(header));
27610733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
27710733a71c5557861160292e07de011ea9a4db25cJesse Wilson
27810733a71c5557861160292e07de011ea9a4db25cJesse Wilson    private String contentToString(HttpResponse response) throws IOException {
27910733a71c5557861160292e07de011ea9a4db25cJesse Wilson        StringWriter writer = new StringWriter();
28010733a71c5557861160292e07de011ea9a4db25cJesse Wilson        char[] buffer = new char[1024];
28110733a71c5557861160292e07de011ea9a4db25cJesse Wilson        Reader reader = new InputStreamReader(response.getEntity().getContent());
28210733a71c5557861160292e07de011ea9a4db25cJesse Wilson        int length;
28310733a71c5557861160292e07de011ea9a4db25cJesse Wilson        while ((length = reader.read(buffer)) != -1) {
28410733a71c5557861160292e07de011ea9a4db25cJesse Wilson            writer.write(buffer, 0, length);
28510733a71c5557861160292e07de011ea9a4db25cJesse Wilson        }
28610733a71c5557861160292e07de011ea9a4db25cJesse Wilson        reader.close();
28710733a71c5557861160292e07de011ea9a4db25cJesse Wilson        return writer.toString();
28810733a71c5557861160292e07de011ea9a4db25cJesse Wilson    }
28910733a71c5557861160292e07de011ea9a4db25cJesse Wilson}
290