Internet networking newbie here. I'm attempting to send https requests from a Node JS server using the 'socks' npm module through a socks proxy to a Java HTTPS server. I can make individual https requests through the proxy without a socket fine, for example using the 'socks5-https-client' npm module.
I expect back a 200 OK response from my request but instead the Java server throws an SSLException: Unrecognized SSL message, plaintext connection error.
My Node JS code is very simple:
const options = {
proxy: {
host: '<proxy ip>',
port: 1080,
type: 5
},
destination: {
host: '<java server ip>',
port: 443
},
command: 'connect'
};
try {
const info = await SocksClient.createConnection(options);
info.socket.write('GET /users HTTP/1.1\nAuthorization: Basic <token>\n\n');
info.socket.on('data', (data) => {
console.log(data.toString());
} catch (err) {
// Handle errors
}
The Java server code is:
SSLServerSocketFactory ssf = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
SSLServerSocket listenSocket = (SSLServerSocket) ssf.createServerSocket(portNum, 50);
boolean done = false;
while (!done) {
clientSocket = listenSocket.accept();
if (Thread.currentThread().isInterrupted()) {
Logger.logMessage("interrupted during accept()");
done = true;
break;
}
InputStream in = clientSocket.getInputStream();
// Read the initial request line from the client
ByteArrayOutputStream inLineA = new ByteArrayOutputStream(100);
int ch = -1;
try {
clientSocket.setSoTimeout(10000);
while ((ch = in.read()) != '\n' && ch != -1)
inLineA.write((byte) ch);
}
catch (Exception e) {
e.printStackTrace(System.out);
clientSocket.close();
continue;
}
[ ... process HTTP request here ]
}
After a lot of googling, I thought the issue was because the 'socks' module uses net.Socket which is not secure. However, when I switch it out for a tls.TLSSocket, it results in a proxy connection timeout.
How can I connect a socket through the proxy and send https requests? Is there an issue with my thinking?
Big thanks to dave_thompson_085. It worked after wrapping the TCP socket returned in a TLS socket like so:
Socks.SocksClient.createConnection(options)
.then(info => {
const tlsSocket= tls.connect(
{
host: <java server ip>,
port: 443,
socket: info.socket
},
() => {
tlsSocket.write('GET /users HTTP/1.1\r\nAuthorization: Basic <token>\r\nHost: <java server ip>:443\r\n\r\n');
}
);
tlsSocket.on("data", function(data) {
// do something with data
});
})
.catch(err => {
console.log(err);
});