1 /*
2  * Copyright (C) 2014 Square, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.squareup.okhttp;
17 
18 import com.squareup.okhttp.mockwebserver.MockResponse;
19 import com.squareup.okhttp.mockwebserver.MockWebServer;
20 import java.io.IOException;
21 import java.net.Proxy;
22 import java.net.ProxySelector;
23 import java.net.SocketAddress;
24 import java.net.URI;
25 import java.util.Collections;
26 import java.util.List;
27 import org.junit.After;
28 import org.junit.Before;
29 import org.junit.Test;
30 
31 import static org.junit.Assert.assertEquals;
32 
33 public final class SocksProxyTest {
34   private final SocksProxy socksProxy = new SocksProxy();
35   private final MockWebServer server = new MockWebServer();
36 
setUp()37   @Before public void setUp() throws Exception {
38     server.start();
39     socksProxy.play();
40   }
41 
tearDown()42   @After public void tearDown() throws Exception {
43     server.shutdown();
44     socksProxy.shutdown();
45   }
46 
proxy()47   @Test public void proxy() throws Exception {
48     server.enqueue(new MockResponse().setBody("abc"));
49     server.enqueue(new MockResponse().setBody("def"));
50 
51     OkHttpClient client = new OkHttpClient()
52         .setProxy(socksProxy.proxy());
53 
54     Request request1 = new Request.Builder().url(server.url("/")).build();
55     Response response1 = client.newCall(request1).execute();
56     assertEquals("abc", response1.body().string());
57 
58     Request request2 = new Request.Builder().url(server.url("/")).build();
59     Response response2 = client.newCall(request2).execute();
60     assertEquals("def", response2.body().string());
61 
62     // The HTTP calls should share a single connection.
63     assertEquals(1, socksProxy.connectionCount());
64   }
65 
proxySelector()66   @Test public void proxySelector() throws Exception {
67     server.enqueue(new MockResponse().setBody("abc"));
68 
69     ProxySelector proxySelector = new ProxySelector() {
70       @Override public List<Proxy> select(URI uri) {
71         return Collections.singletonList(socksProxy.proxy());
72       }
73 
74       @Override public void connectFailed(URI uri, SocketAddress socketAddress, IOException e) {
75         throw new AssertionError();
76       }
77     };
78 
79     OkHttpClient client = new OkHttpClient()
80         .setProxySelector(proxySelector);
81 
82     Request request = new Request.Builder().url(server.url("/")).build();
83     Response response = client.newCall(request).execute();
84     assertEquals("abc", response.body().string());
85 
86     assertEquals(1, socksProxy.connectionCount());
87   }
88 
checkRemoteDNSResolve()89   @Test public void checkRemoteDNSResolve() throws Exception {
90     // This testcase will fail if the target is resolved locally instead of through the proxy.
91     server.enqueue(new MockResponse().setBody("abc"));
92 
93     OkHttpClient client = new OkHttpClient()
94         .setProxy(socksProxy.proxy());
95 
96     HttpUrl url = server.url("/")
97         .newBuilder()
98         .host(socksProxy.HOSTNAME_THAT_ONLY_THE_PROXY_KNOWS)
99         .build();
100 
101     Request request = new Request.Builder().url(url).build();
102     Response response1 = client.newCall(request).execute();
103     assertEquals("abc", response1.body().string());
104 
105     assertEquals(1, socksProxy.connectionCount());
106   }
107 }
108