I am trying to listen on a socket locally for use as an HTTP proxy and forward everything (TCP) to another HTTP proxy which is protected by mututal TLS.
I've looked around but found no libraries yet that could help me achieve this goal, so I opted for raw java.net.Socket. However, Socket & connection management is a pain, leading to 'socket closed' errors and most of the time no responses being received at all or connection resets. Is this the correct way to pass everything between two Sockets?
public class ThreadServer
implements Runnable
{
private final ServerSocket inSocket;
private final SSLSocketFactory socketFactory;
private final String proxyHost;
private final int proxyPort;
public ThreadServer(final SSLSocketFactory socketFactory,
final String proxyHost, final int proxyPort,
final ServerSocket inSocket)
{
this.proxyHost = proxyHost;
this.proxyPort = proxyPort;
this.socketFactory = socketFactory;
this.inSocket = inSocket;
}
private void process(Socket acceptSocket, Socket sendSocket)
throws IOException
{
try (final InputStream inFromClient = acceptSocket.getInputStream();
final OutputStream outToClient = acceptSocket.getOutputStream();
final InputStream inFromServer = sendSocket.getInputStream();
final OutputStream outToServer = sendSocket.getOutputStream())
{
new Thread(() -> {
try {
// can blocking indefinetely so run in a separate Thread
inFromClient.transferTo(outToServer);
} catch (IOException ignored) {}
}).start();
// now copy everything from response back to the client, blocking as wel
inFromServer.transferTo(outToClient);
} finally {
acceptSocket.close();
sendSocket.close();
}
}
@Override
public void run()
{
while (true) {
try {
Socket socket = this.inSocket.accept();
Socket tlsSocket = socketFactory.createSocket(
SocketFactory.getDefault().createSocket(proxyHost, proxyPort), proxyHost, proxyPort, true);
process(socket, tlsSocket);
} catch (IOException ignored) {}
}
}
}