package org.limewire.http;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import junit.framework.Test;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.limewire.common.LimeWireCommonModule;
import org.limewire.concurrent.SimpleTimer;
import org.limewire.http.httpclient.LimeHttpClient;
import org.limewire.io.IOUtils;
import org.limewire.io.NetworkInstanceUtils;
import org.limewire.io.SimpleNetworkInstanceUtils;
import org.limewire.net.EmptySocketBindingSettings;
import org.limewire.net.LimeWireNetModule;
import org.limewire.net.ProxySettings;
import org.limewire.net.ProxySettings.ProxyType;
import org.limewire.net.ProxySettingsStub;
import org.limewire.net.SocketBindingSettings;
import org.limewire.net.SocketsManager;
import org.limewire.util.BaseTestCase;
import org.limewire.util.StringUtils;
import org.limewire.nio.NIOTestUtils;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.name.Names;
public class ProxyTest extends BaseTestCase {
private static final int PROXY_PORT = 9990;
private final int DEST_PORT = 9999;
private FakeProxyServer fps;
private ProxySettingsStub proxySettings;
private SocketsManager socketsManager;
private LimeHttpClient httpClient;
public ProxyTest(String name) {
super(name);
}
public static Test suite() {
return buildTestSuite(ProxyTest.class);
}
public static void main(String[] args) {
junit.textui.TestRunner.run(suite());
}
@Override
public void setUp() throws Exception {
proxySettings = new ProxySettingsStub();
fps = new FakeProxyServer(PROXY_PORT, DEST_PORT);
fps.setMakeError(false);
Injector injector = Guice.createInjector(new LimeWireCommonModule(), new LimeWireNetModule(), new LimeWireHttpModule(), new AbstractModule() {
@Override
protected void configure() {
bind(ProxySettings.class).toInstance(proxySettings);
bind(SocketBindingSettings.class).to(EmptySocketBindingSettings.class);
SimpleTimer timer = new SimpleTimer(true);
bind(ScheduledExecutorService.class).annotatedWith(Names.named("backgroundExecutor")).toInstance(timer);
bind(ExecutorService.class).annotatedWith(Names.named("backgroundExecutor")).toInstance(timer);
bind(Executor.class).annotatedWith(Names.named("backgroundExecutor")).toInstance(timer);
bind(NetworkInstanceUtils.class).to(SimpleNetworkInstanceUtils.class);
}
});
socketsManager = injector.getInstance(SocketsManager.class);
httpClient = injector.getInstance(LimeHttpClient.class);
proxySettings.setProxyForPrivate(true);
proxySettings.setProxyHost("127.0.0.1");
proxySettings.setProxyPort(PROXY_PORT);
proxySettings.setProxyUser("");
proxySettings.setProxyPass("");
}
@Override
public void tearDown() throws Exception {
fps.killServers();
NIOTestUtils.waitForNIO();
}
/**
* If Proxy is off we should connect directly
*/
public void testConnectionsWithProxyOff() throws Exception {
proxySettings.setProxyType(ProxyType.NONE);
fps.setProxyOn(false);
fps.setAuthentication(false);
fps.setProxyVersion(ProxyType.NONE);
Socket s = socketsManager.connect(new InetSocketAddress("localhost", DEST_PORT), 0);
// we should be connected to something, NPE is an error
s.close();
}
/**
* connect with socks 5
*/
public void testSOCKS5Connection() throws Exception {
runSOCKS5Connection(false);
}
public void testSOCKS5ConnectionNB() throws Exception {
runSOCKS5Connection(true);
}
private void runSOCKS5Connection(boolean nb) throws Exception {
proxySettings.setProxyType(ProxyType.SOCKS5);
fps.setProxyOn(true);
fps.setAuthentication(false);
fps.setProxyVersion(ProxyType.SOCKS5);
connect(nb, true);
}
/**
* connect with socks 5 connection fails with bad code.
*/
public void testSOCKS5ConnectionWithError() throws Exception {
runSOCKS5ConnectionWithError(false);
}
public void testSOCKS5ConnectionWithErrorNB() throws Exception {
runSOCKS5ConnectionWithError(true);
}
private void runSOCKS5ConnectionWithError(boolean nb) throws Exception {
proxySettings.setProxyType(ProxyType.SOCKS5);
fps.setProxyOn(true);
fps.setAuthentication(false);
fps.setProxyVersion(ProxyType.SOCKS5);
fps.setMakeError(true);
connect(nb, false);
fps.setMakeError(false);
}
/**
* connect with socks5 with auth
*/
public void testSOCKS5WithAuth() throws Exception {
runSOCKS5WithAuth(false);
}
public void testSOCKS5WithAuthNB() throws Exception {
runSOCKS5WithAuth(true);
}
private void runSOCKS5WithAuth(boolean nb) throws Exception {
proxySettings.setProxyType(ProxyType.SOCKS5);
proxySettings.setProxyAuthRequired(true);
proxySettings.setProxyUser(FakeProxyServer.USER);
proxySettings.setProxyPass(FakeProxyServer.PASS);
fps.setProxyOn(true);
fps.setAuthentication(true);
fps.setProxyVersion(ProxyType.SOCKS5);
connect(nb, true);
}
public void testSOCKS4Connection() throws Exception {
runSOCKS4Connection(false);
}
public void testSOCKS4ConnectionNB() throws Exception {
runSOCKS4Connection(true);
}
private void runSOCKS4Connection(boolean nb) throws Exception {
proxySettings.setProxyType(ProxyType.SOCKS4);
fps.setProxyOn(true);
fps.setAuthentication(false);
fps.setProxyVersion(ProxyType.SOCKS4);
connect(nb, true);
}
public void testSOCKS4ConnectionWithError() throws Exception {
runSOCKS4ConnectionWithError(false);
}
public void testSOCKS4ConnectionWithErrorNB() throws Exception {
runSOCKS4ConnectionWithError(true);
}
private void runSOCKS4ConnectionWithError(boolean nb) throws Exception {
proxySettings.setProxyType(ProxyType.SOCKS4);
fps.setProxyOn(true);
fps.setAuthentication(false);
fps.setProxyVersion(ProxyType.SOCKS4);
fps.setMakeError(true);
connect(nb, false);
fps.setMakeError(false);
}
public void testSOCKS4WithAuth() throws Exception {
runSOCKS4WithAuth(false);
}
public void testSOCKS4WithAuthNB() throws Exception {
runSOCKS4WithAuth(true);
}
private void runSOCKS4WithAuth(boolean nb) throws Exception {
proxySettings.setProxyType(ProxyType.SOCKS4);
proxySettings.setProxyAuthRequired(true);
proxySettings.setProxyUser(FakeProxyServer.USER);
proxySettings.setProxyPass(FakeProxyServer.PASS);
fps.setProxyOn(true);
fps.setAuthentication(true);
fps.setProxyVersion(ProxyType.SOCKS4);
connect(nb, true);
}
/**
* Tests that HTTP proxies are used correctly
*/
public void testHTTPProxy() throws Exception {
runHTTPProxy(false);
}
public void testHTTPProxyNB() throws Exception {
runHTTPProxy(true);
}
private void runHTTPProxy(boolean nb) throws Exception {
proxySettings.setProxyType(ProxyType.HTTP);
fps.setProxyOn(true);
fps.setAuthentication(false);
fps.setProxyVersion(ProxyType.HTTP);
connect(nb, true);
}
public void testHTTPProxyWithError() throws Exception {
runHTTPProxyWithError(false);
}
public void testHTTPProxyWithErrorNB() throws Exception {
runHTTPProxyWithError(true);
}
private void runHTTPProxyWithError(boolean nb) throws Exception {
proxySettings.setProxyType(ProxyType.HTTP);
fps.setProxyOn(true);
fps.setAuthentication(false);
fps.setProxyVersion(ProxyType.HTTP);
fps.setMakeError(true);
connect(nb, false);
}
private void connect(boolean nb, boolean success) throws Exception {
if (success) {
Socket s;
if (!nb) {
s = socketsManager.connect(new InetSocketAddress("localhost", DEST_PORT), 0);
} else {
ConnectObserverStub o = new ConnectObserverStub();
s = socketsManager.connect(new InetSocketAddress("localhost", DEST_PORT), 0, o);
o.waitForResponse(5000);
assertEquals(s, o.getSocket());
assertNull(o.getIoException());
assertFalse(o.isShutdown());
}
// Must connect somewhere, NPE is an error
s.close();
} else {
if (!nb) {
try {
socketsManager.connect(new InetSocketAddress("localhost", DEST_PORT), 0);
fail("acceptedConnection from a bad proxy server");
} catch (IOException iox) {
// Good -- expected behaviour
}
} else {
ConnectObserverStub o = new ConnectObserverStub();
socketsManager.connect(new InetSocketAddress("localhost", DEST_PORT), 0, o);
o.waitForResponse(5000);
assertNull(o.getSocket());
assertNull(o.getIoException());
assertTrue(o.isShutdown());
}
}
}
public void testHTTPClientWithProxyOff() throws Exception {
proxySettings.setProxyType(ProxyType.NONE);
fps.setProxyOn(false);
fps.setAuthentication(false);
fps.setProxyVersion(ProxyType.NONE);
fps.setHttpRequest(true);
String connectTo = "http://" + "localhost:" + DEST_PORT + "/myFile.txt";
HttpGet get = new HttpGet(connectTo);
get.addHeader("connection", "close");
HttpResponse response = httpClient.execute(get);
byte[] resp = IOUtils.readFully(response.getEntity().getContent());
assertEquals("invalid response from server", "hello", StringUtils.getUTF8String(resp));
get.abort();
}
public void testHTTPClientProxiesWithHttpProxy() throws Exception {
proxySettings.setProxyType(ProxyType.HTTP);
fps.setProxyOn(true);
fps.setAuthentication(false);
fps.setProxyVersion(ProxyType.HTTP);
fps.setHttpRequest(true);
String connectTo = "http://" + "localhost:" + DEST_PORT + "/myFile2.txt";
HttpGet get = new HttpGet(connectTo);
get.addHeader("connection", "close");
// release the connections.
// TODO client.setHttpConnectionManager(new SimpleHttpConnectionManager());
HttpResponse response = httpClient.execute(get);
String resp = StringUtils.getUTF8String(IOUtils.readFully(response.getEntity().getContent()));
assertEquals("invalid response from server", "hello", resp);
get.abort();
}
public void testHTTPClientProxiesWithSocks4() throws Exception {
proxySettings.setProxyType(ProxyType.SOCKS4);
fps.setProxyOn(true);
fps.setAuthentication(false);
fps.setProxyVersion(ProxyType.SOCKS4);
fps.setHttpRequest(true);
String connectTo = "http://" + "localhost:" + DEST_PORT + "/myFile3.txt";
HttpGet get = new HttpGet(connectTo);
get.addHeader("connection", "close");
// release the connections.
// TODO client.setHttpConnectionManager(new SimpleHttpConnectionManager());
HttpResponse response = httpClient.execute(get);
String resp = StringUtils.getUTF8String(IOUtils.readFully(response.getEntity().getContent()));
assertEquals("invalid response from server", "hello", resp);
get.abort();
}
public void testHTTPClientProxiesWithSocks5() throws Exception {
proxySettings.setProxyType(ProxyType.SOCKS5);
fps.setProxyOn(true);
fps.setAuthentication(false);
fps.setProxyVersion(ProxyType.SOCKS5);
fps.setHttpRequest(true);
String connectTo = "http://" + "localhost:" + DEST_PORT + "/myFile4.txt";
HttpGet get = new HttpGet(connectTo);
get.addHeader("connection", "close");
// release the connections.
// TODO client.setHttpConnectionManager(new SimpleHttpConnectionManager());
HttpResponse response = httpClient.execute(get);
String resp = StringUtils.getUTF8String(IOUtils.readFully(response.getEntity().getContent()));
assertEquals("invalid response from server", "hello", resp);
get.abort();
}
public void testHTTPClientProxiesWithAuthSocks4() throws Exception {
proxySettings.setProxyType(ProxyType.SOCKS4);
proxySettings.setProxyAuthRequired(true);
proxySettings.setProxyUser(FakeProxyServer.USER);
proxySettings.setProxyPass(FakeProxyServer.PASS);
fps.setProxyOn(true);
fps.setAuthentication(true);
fps.setProxyVersion(ProxyType.SOCKS4);
fps.setHttpRequest(true);
String connectTo = "http://" + "localhost:" + DEST_PORT + "/myFile3.txt";
HttpGet get = new HttpGet(connectTo);
get.addHeader("connection", "close");
// release the connections.
// TODO client.setHttpConnectionManager(new SimpleHttpConnectionManager());
HttpResponse response = httpClient.execute(get);
String resp = StringUtils.getUTF8String(IOUtils.readFully(response.getEntity().getContent()));
assertEquals("invalid response from server", "hello", resp);
get.abort();
}
public void testHTTPClientProxiesWithAuthSocks5() throws Exception {
proxySettings.setProxyType(ProxyType.SOCKS5);
proxySettings.setProxyAuthRequired(true);
proxySettings.setProxyUser(FakeProxyServer.USER);
proxySettings.setProxyPass(FakeProxyServer.PASS);
fps.setProxyOn(true);
fps.setAuthentication(true);
fps.setProxyVersion(ProxyType.SOCKS5);
fps.setHttpRequest(true);
String connectTo = "http://" + "localhost:" + DEST_PORT + "/myFile4.txt";
HttpGet get = new HttpGet(connectTo);
get.addHeader("connection", "close");
// release the connections.
// TODO client.setHttpConnectionManager(new SimpleHttpConnectionManager());
HttpResponse response = httpClient.execute(get);
String resp = StringUtils.getUTF8String(IOUtils.readFully(response.getEntity().getContent()));
assertEquals("invalid response from server", "hello", resp);
get.abort();
}
}