diff --git a/jetty-client/src/test/java/org/eclipse/jetty/client/Socks4ProxyTest.java b/jetty-client/src/test/java/org/eclipse/jetty/client/Socks4ProxyTest.java new file mode 100644 index 00000000000..6711061e6aa --- /dev/null +++ b/jetty-client/src/test/java/org/eclipse/jetty/client/Socks4ProxyTest.java @@ -0,0 +1,119 @@ +// +// ======================================================================== +// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.client; + +import java.net.InetSocketAddress; +import java.nio.ByteBuffer; +import java.nio.channels.ServerSocketChannel; +import java.nio.channels.SocketChannel; +import java.nio.charset.StandardCharsets; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import org.eclipse.jetty.client.api.Response; +import org.eclipse.jetty.client.api.Result; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class Socks4ProxyTest +{ + private ServerSocketChannel server; + private HttpClient client; + + @Before + public void prepare() throws Exception + { + server = ServerSocketChannel.open(); + server.bind(new InetSocketAddress("localhost", 0)); + + client = new HttpClient(); + client.start(); + } + + @After + public void dispose() throws Exception + { + server.close(); + client.stop(); + } + + @Test + public void testSocks4Proxy() throws Exception + { + int proxyPort = server.socket().getLocalPort(); + client.getProxyConfiguration().getProxies().add(new Socks4Proxy("localhost", proxyPort)); + + final CountDownLatch latch = new CountDownLatch(1); + + byte ip1 = 127; + byte ip2 = 0; + byte ip3 = 0; + byte ip4 = 13; + String serverHost = ip1 + "." + ip2 + "." + ip3 + "." + ip4; + int serverPort = proxyPort + 1; // Any port will do + client.newRequest(serverHost, serverPort) + .path("/path") + .timeout(5, TimeUnit.SECONDS) + .send(new Response.CompleteListener() + { + @Override + public void onComplete(Result result) + { + if (result.isSucceeded()) + latch.countDown(); + } + }); + + SocketChannel channel = server.accept(); + + int socks4MessageLength = 9; + ByteBuffer buffer = ByteBuffer.allocate(socks4MessageLength); + int read = channel.read(buffer); + Assert.assertEquals(socks4MessageLength, read); + Assert.assertEquals(4, buffer.get(0) & 0xFF); + Assert.assertEquals(1, buffer.get(1) & 0xFF); + Assert.assertEquals(serverPort, buffer.getShort(2) & 0xFFFF); + Assert.assertEquals(ip1, buffer.get(4) & 0xFF); + Assert.assertEquals(ip2, buffer.get(5) & 0xFF); + Assert.assertEquals(ip3, buffer.get(6) & 0xFF); + Assert.assertEquals(ip4, buffer.get(7) & 0xFF); + Assert.assertEquals(0, buffer.get(8) & 0xFF); + + // Socks4 response. + channel.write(ByteBuffer.wrap(new byte[]{0, 0x5A, 0, 0, 0, 0, 0, 0})); + + buffer = ByteBuffer.allocate(3); + read = channel.read(buffer); + Assert.assertEquals(3, read); + buffer.flip(); + Assert.assertEquals("GET", StandardCharsets.UTF_8.decode(buffer).toString()); + + // Response + String response = "" + + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 0\r\n" + + "Connection: close\r\n" + + "\r\n"; + channel.write(ByteBuffer.wrap(response.getBytes("UTF-8"))); + + Assert.assertTrue(latch.await(5, TimeUnit.SECONDS)); + } +}