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));
This is from the link I posted previously:
SocketAddress addr = new InetSocketAddress("webcache.mydomain.com", 8080);
Proxy proxy = new Proxy(Proxy.Type.HTTP, addr);
Remember, this new proxy object represents a proxy definition, nothing more. How do we use such an object? A new openConnection()
method has been added to the URL class and takes a Proxy as an argument, it works the same way as openConnection()
with no arguments, except it forces the connection to be established through the specified proxy, ignoring all other settings, including the system properties mentioned above.
So completing the previous example, we can now add:
URL url = new URL("http://java.sun.com/");
URLConnection conn = url.openConnection(proxy);
This is from the link I posted earlier. I'm on the iPad so can't format it properly.
Can you do it this way? I see you're doing sockets directly but you're doing http so maybe do things this way?
You could try JHttpTunnel, though you need software running on both sides of the tunnel for this to work.
Looks like you're requesting a SOCKS proxy, which is different from an HTTP proxy. Perhaps try Proxy.Type.HTTP.
Question: is your client HTTP based? I'm not sure this will work unless your client speaks HTTP.
Am I correct in saying that what you want is to use the http proxy (for exemple squid) to establish a CONNECT method to a remote server (from http rfc 2616)? Basically, the connection goes like this:
-open a socket to the proxy (host, port)
-send text to the proxy with basic header
....CONNECT remote.internethost.com:1494 HTTP/1.0
....User-Agent: Java Proxy Socket version 1.0a
....Host: remote.internethost.com
....Proxy-Authorization: Basic YourBase64usernamePasswordIfRequired
-then, the proxy will return a http status code (multiline text string) and the actual socket (if successfull)
-this is this socket that needs to be returned to the connection object
That could be done with personal classes but the beauty would be to reuse the proxy classes for it. This way, all the handshake with the http proxy, especially the response code would be handled.
I`m codding an app with c++ using Socks through Proxy, This tool help me a lot, have a look HERE
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/