Работа над распаковкой websocket

This commit is contained in:
serega6531
2020-04-05 00:36:52 +03:00
parent e25e66d727
commit 2688e1fc56

View File

@@ -37,11 +37,10 @@ public class WebSocketsParser {
private static final String WEBSOCKET_CONNECTION_HEADER = "connection: upgrade\r\n"; private static final String WEBSOCKET_CONNECTION_HEADER = "connection: upgrade\r\n";
private final List<Packet> packets; private final List<Packet> packets;
private List<Framedata> frames;
@Getter @Getter
private boolean parsed = false; private boolean parsed = false;
private int httpEnd = -1; private List<Packet> parsedPackets;
public WebSocketsParser(List<Packet> packets) { public WebSocketsParser(List<Packet> packets) {
this.packets = packets; this.packets = packets;
@@ -58,6 +57,7 @@ public class WebSocketsParser {
return; return;
} }
int httpEnd = -1;
for (int i = clientHandshakePackets.size(); i < packets.size(); i++) { for (int i = clientHandshakePackets.size(); i < packets.size(); i++) {
if (packets.get(i).getContentString().endsWith("\r\n\r\n")) { if (packets.get(i).getContentString().endsWith("\r\n\r\n")) {
httpEnd = i + 1; httpEnd = i + 1;
@@ -92,56 +92,88 @@ public class WebSocketsParser {
return; return;
} }
final List<Packet> wsPackets = this.packets.subList( final List<Packet> wsPackets = packets.subList(
httpEnd, httpEnd,
this.packets.size()); packets.size());
final byte[] wsContent = wsPackets.stream() if(wsPackets.isEmpty()) {
.map(Packet::getContent)
.reduce(ArrayUtils::addAll)
.orElse(null);
if (wsContent == null) {
return; return;
} }
final ByteBuffer frame = ByteBuffer.wrap(wsContent); final List<Packet> handshakes = packets.subList(0, httpEnd);
try {
frames = draft.translateFrame(frame);
} catch (InvalidDataException e) {
log.warn("WebSocket data", e);
return;
}
parse(wsPackets, handshakes, draft);
parsed = true; parsed = true;
} }
private void parse(final List<Packet> wsPackets, final List<Packet> handshakes, Draft_6455 draft) {
List<List<Packet>> sides = sliceToSides(wsPackets);
parsedPackets = new ArrayList<>(handshakes);
for (List<Packet> side : sides) {
final Packet lastPacket = side.get(0);
final byte[] wsContent = side.stream()
.map(Packet::getContent)
.reduce(ArrayUtils::addAll)
.get();
final ByteBuffer buffer = ByteBuffer.wrap(wsContent);
List<Framedata> frames;
try {
frames = draft.translateFrame(buffer);
} catch (InvalidDataException e) {
log.warn("WebSocket data", e);
return;
}
for (Framedata frame : frames) {
if(frame instanceof DataFrame) {
parsedPackets.add(Packet.builder()
.content(frame.getPayloadData().array())
.incoming(lastPacket.isIncoming())
.timestamp(lastPacket.getTimestamp())
.ttl(lastPacket.getTtl())
.ungzipped(lastPacket.isUngzipped())
.build()
);
}
}
}
}
public List<Packet> getParsedPackets() { public List<Packet> getParsedPackets() {
if (!parsed) { if (!parsed) {
throw new IllegalStateException("WS is not parsed"); throw new IllegalStateException("WS is not parsed");
} }
final List<Packet> handshakes = packets.subList(0, httpEnd); return parsedPackets;
List<Packet> newPackets = new ArrayList<>(handshakes.size() + frames.size()); }
newPackets.addAll(handshakes);
final Packet lastPacket = packets.get(packets.size() - 1); private List<List<Packet>> sliceToSides(List<Packet> packets) {
List<List<Packet>> result = new ArrayList<>();
List<Packet> side = new ArrayList<>();
boolean incoming = true;
for (Framedata frame : frames) { for (Packet packet : packets) {
if(frame instanceof DataFrame) { if(packet.isIncoming() != incoming) {
newPackets.add(Packet.builder() incoming = packet.isIncoming();
.content(frame.getPayloadData().array())
.incoming(true) //TODO if(!side.isEmpty()) {
.timestamp(lastPacket.getTimestamp()) result.add(side);
.ttl(lastPacket.getTtl()) side = new ArrayList<>();
.ungzipped(lastPacket.isUngzipped()) }
.build()
);
} }
side.add(packet);
} }
return newPackets; if(!side.isEmpty()) {
result.add(side);
}
return result;
} }
private String getHandshake(final List<Packet> packets) { private String getHandshake(final List<Packet> packets) {