59 lines
2.0 KiB
Java
59 lines
2.0 KiB
Java
package io.gitlab.jfronny.libjf.mainhttp.impl;
|
|
|
|
import io.gitlab.jfronny.libjf.mainhttp.impl.util.Trie;
|
|
import io.netty.buffer.ByteBuf;
|
|
import io.netty.buffer.Unpooled;
|
|
import io.netty.channel.*;
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import java.util.List;
|
|
|
|
public class HttpDecoder extends ChannelInboundHandlerAdapter {
|
|
private static final Trie<String> METHOD = Trie.of(List.of(
|
|
"GET",
|
|
"HEAD",
|
|
"POST",
|
|
"PUT",
|
|
"PATCH",
|
|
"DELETE",
|
|
|
|
"OPTIONS", "TRACE", "CONNECT"
|
|
));
|
|
|
|
@Override
|
|
public void channelRead(@NotNull ChannelHandlerContext ctx, @NotNull Object msg) throws Exception {
|
|
ByteBuf buf = (ByteBuf) msg;
|
|
buf.markReaderIndex();
|
|
boolean passOn = true;
|
|
try {
|
|
// Check whether buf starts with an HTTP method, as a request would
|
|
Trie<String> current = METHOD;
|
|
while (buf.isReadable()
|
|
&& current != null
|
|
&& current.content == null)
|
|
current = current.next.get((char) buf.readByte());
|
|
if (current == null || current.content == null) return;
|
|
// Method identified, this is HTTP!
|
|
passOn = false;
|
|
// Read all data from buffer
|
|
buf.resetReaderIndex();
|
|
byte[] data = new byte[buf.readableBytes()];
|
|
buf.readBytes(data);
|
|
buf.release();
|
|
// Process request
|
|
ctx.pipeline()
|
|
.firstContext()
|
|
.writeAndFlush(Unpooled.wrappedBuffer(MainHttp.handle(data)))
|
|
.addListener(ChannelFutureListener.CLOSE);
|
|
} catch (RuntimeException re) {
|
|
MainHttp.LOGGER.error("Could not process HTTP", re);
|
|
} finally {
|
|
if (passOn) {
|
|
buf.resetReaderIndex();
|
|
ctx.channel().pipeline().remove(this);
|
|
ctx.fireChannelRead(msg);
|
|
}
|
|
}
|
|
}
|
|
}
|