Simple socks5 proxy using vertx 3.2.1.
It always receive only part of the response and then blocked until timeout.
And it had no problems when I used socks codec with netty4.1.
public class ProxyHandler implements Handler<Buffer> {
private NetSocket socket;
private ReqType reqType;
private enum ReqType {
INIT,
CMD,
UNKNOWN
}
public ProxyHandler(NetSocket socket) {
this.socket = socket;
this.reqType = ReqType.INIT;
}
@Override
public void handle(Buffer buffer) {
switch (reqType) {
case INIT:
reqType = ReqType.CMD;
if (buffer.getByte(0) != 0x05) {
socket.close();
Log.debug("Only supports socks5");
return;
}
Buffer buf = Buffer.buffer(2).appendByte((byte) 0x05).appendByte((byte) 0x00);
socket.write(buf);
return;
case CMD:
reqType = ReqType.UNKNOWN;
if (buffer.getByte(1) != (byte) 0x01) {
socket.close();
Log.debug("Only supports CONNECT command");
return;
}
byte addrType = buffer.getByte(3);
if (addrType == 0x01 || addrType == 0x04) {
//ipv4 or ipv6
int o = addrType == 0x01 ? 8 : 20;
byte[] ip = buffer.getBytes(4, o);
int port = buffer.getUnsignedShort(o);
try {
connect(InetAddress.getByAddress(ip).getHostAddress(), port, addrType);
} catch (UnknownHostException e) {
socket.close();
Log.debug(e.getMessage());
}
} else if (addrType == 0x03) {
//domain
byte len = buffer.getByte(4);
byte[] domain = buffer.getBytes(5, len + 5);
int port = buffer.getUnsignedShort(len + 5);
connect(new String(domain, StandardCharsets.US_ASCII), port, addrType);
} else {
socket.close();
throw new IllegalStateException("Unknown address type");
}
break;
default:
throw new IllegalStateException("Unknown socks request type");
}
}
private void connect(String host, int port, byte addrType) {
Vertx v = Context.vertx();
v.executeBlocking(future -> v.createNetClient().connect(port, host, result -> {
if (result.succeeded()) {
NetSocket remote = result.result();
Buffer buf = Buffer.buffer().appendByte((byte) 0x05)
.appendByte((byte) 0x00)
.appendByte((byte) 0x00)
.appendByte(addrType)
.appendString(host, "US-ASCII")
.appendUnsignedShort(port);
socket.write(buf);
Pump.pump(socket, remote).start();
Pump.pump(remote, socket).start();
} else {
socket.close();
}
}), null);
}
}
NetServer server = Context.vertx().createNetServer();
server.connectHandler(socket -> {
socket.handler(new ProxyHandler(socket));
}).listen();
Tested with curl -s -x socks5://127.0.0.1:1080 www.xxx.com,
and it printed both the HTTP header and body!!!
But nothing printed when using curl -I, how can headers and body mixed togenther?
Simple socks5 proxy using vertx 3.2.1. It always receive only part of the response and then blocked until timeout. And it had no problems when I used socks codec with netty4.1.
Tested with
curl -s -x socks5://127.0.0.1:1080 www.xxx.com
, and it printed both the HTTP header and body!!! But nothing printed when usingcurl -I
, how can headers and body mixed togenther?