I have a piece of code to connect to a Socket server, and it works fine.
Socket socket = new Socket();
socket.connect(new InetSocketAddress(address, port));
Now I want to connect via a HTTP proxy, what should I do?
I tried this and failed
SocketAddress proxyAddr = new InetSocketAddress(proxyHost, proxyPort);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, addr);
Socket socket = new Socket(proxy);
socket.connect(new InetSocketAddress(address, port));
this post suggests that I should use Jakarta Commons HttpClient, but how to use it to connect a Socket server via the HTTP proxy?
UPDATED: I used SOCKS proxy and it doesn't work, if I use HTTP proxy:
SocketAddress proxyAddr = new InetSocketAddress(proxyHost, proxyPort);
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
Socket socket = new Socket(proxy);
socket.connect(new InetSocketAddress(address, port));
and it will throw an IllegalArgumentException
java.lang.IllegalArgumentException: Proxy is null or invalid type
at java.net.Socket.<init>(Socket.java:88)
The http. proxyHost property must be defined to configure an HTTP proxy, and https. proxyHost for a HTTPS proxy. The http.proxyHost and http.proxyPort properties indicate the proxy server and the port that the HTTP protocol handler will use.
I've created small Socket Factory class to handle the HTTP CONNECT via socket. The socket then can be used as per-normal provided the proxy supports CONNECT to the destination.
public final class SocketFactory {
public static Socket GetSocket(String host, String port) throws IOException {
/*************************
* Get the jvm arguments
*************************/
int proxyPort = Integer.parseInt(System.getProperty("http.proxyPort"));
String proxyHost = System.getProperty("http.proxyHost");
// Socket object connecting to proxy
Socket sock = new Socket(proxyHost, proxyPort);
/***********************************
* HTTP CONNECT protocol RFC 2616
***********************************/
String proxyConnect = "CONNECT " + host + ":" + port;
// Add Proxy Authorization if proxyUser and proxyPass is set
try {
String proxyUserPass = String.format("%s:%s",
System.getProperty("http.proxyUser"),
System.getProperty("http.proxyPass"));
proxyConnect.concat(" HTTP/1.0\nProxy-Authorization:Basic "
+ Base64.encode(proxyUserPass.getBytes()));
} catch (Exception e) {
} finally {
proxyConnect.concat("\n\n");
}
sock.getOutputStream().write(proxyConnect.getBytes());
/***********************************/
/***************************
* validate HTTP response.
***************************/
byte[] tmpBuffer = new byte[512];
InputStream socketInput = sock.getInputStream();
int len = socketInput.read(tmpBuffer, 0, tmpBuffer.length);
if (len == 0) {
throw new SocketException("Invalid response from proxy");
}
String proxyResponse = new String(tmpBuffer, 0, len, "UTF-8");
// Expecting HTTP/1.x 200 OK
if (proxyResponse.indexOf("200") != -1) {
// Flush any outstanding message in buffer
if (socketInput.available() > 0)
socketInput.skip(socketInput.available());
// Proxy Connect Successful, return the socket for IO
return sock;
} else {
throw new SocketFactoryException("Fail to create Socket",
proxyResponse);
}
}
/**
* Simplest Base64 Encoder adopted from GeorgeK
*
* @see http://stackoverflow.com/questions/469695/decode-base64-data-in-java/4265472#4265472
*/
private static class Base64 {
/***********************
* Base64 character set
***********************/
private final static char[] ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
.toCharArray();
/**
* Translates the specified byte array into Base64 string.
*
* @param buf
* the byte array (not null)
* @return the translated Base64 string (not null)
*/
public static String encode(byte[] buf) {
int size = buf.length;
char[] ar = new char[((size + 2) / 3) * 4];
int a = 0;
int i = 0;
while (i < size) {
byte b0 = buf[i++];
byte b1 = (i < size) ? buf[i++] : 0;
byte b2 = (i < size) ? buf[i++] : 0;
int mask = 0x3F;
ar[a++] = ALPHABET[(b0 >> 2) & mask];
ar[a++] = ALPHABET[((b0 << 4) | ((b1 & 0xFF) >> 4)) & mask];
ar[a++] = ALPHABET[((b1 << 2) | ((b2 & 0xFF) >> 6)) & mask];
ar[a++] = ALPHABET[b2 & mask];
}
switch (size % 3) {
case 1:
ar[--a] = '=';
case 2:
ar[--a] = '=';
}
return new String(ar);
}
}
}
https://code.google.com/p/java-socket-over-http-proxy-connect/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With