Open mkarg opened 2 months ago
I thought we discussed this topic already months back, but I could not find the issue / PR anymore. If I am right and this is a duplicate, please post a reference to the original discussion here. Thanks. 🤔
One thing I want to mention is I've heard rumblings, I don't know if there is anything concrete as I've not been involved, that there may end up being a Jakarta HTTP API specification at some point.
I'm only mentioning this so we don't end up in another scenario like the @Context
and CDI situation we find ourselves in now. I do realize this specific case would likely be less of an issue though as it would just delegate.
One thing I want to mention is I've heard rumblings, I don't know if there is anything concrete as I've not been involved, that there may end up being a Jakarta HTTP API specification at some point.
I'm only mentioning this so we don't end up in another scenario like the
@Context
and CDI situation we find ourselves in now. I do realize this specific case would likely be less of an issue though as it would just delegate.
I do not see any relation to this issue at all. If we add the proposed methods, it is up to the implementation to get the address and port somewhere. Whether it internally refers to Servlet API, HTTP API, a proprietary API, or simply solves the request on its own, does in no way bring us into such a situation like @Context
and CDI. Maybe I missed something?
My only thought was if this new API had something like HttpRequest.remotePort()
and HttpRequest.remoteAddress()
and you could inject the HttpRequest
we now have two ways of getting the remote address/port.
In this case likely not a big deal to have it duplicated in two places. We don't even know if that new API will come to fruition. I just wanted to put it out there that there is potential for duplication.
The Server the implementation is hooked in does not need to provide the information. For instance, I can see Grizzly and Jetty does so, whereas in Netty I cannot find such information.
My only thought was if this new API had something like
HttpRequest.remotePort()
andHttpRequest.remoteAddress()
and you could inject theHttpRequest
we now have two ways of getting the remote address/port.In this case likely not a big deal to have it duplicated in two places. We don't even know if that new API will come to fruition. I just wanted to put it out there that there is potential for duplication.
I do not see a problem in duplication.
The Server the implementation is hooked in does not need to provide the information. For instance, I can see Grizzly and Jetty does so, whereas in Netty I cannot find such information.
ChatGPT told me Netty will do it like this:
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
public class NettyHttpServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new HttpRequestDecoder());
ch.pipeline().addLast(new HttpResponseEncoder());
ch.pipeline().addLast(new SimpleChannelInboundHandler<FullHttpRequest>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) {
System.out.println("Remote Address: " + ctx.channel().remoteAddress());
System.out.println("Remote Port: " + ((InetSocketAddress) ctx.channel().remoteAddress()).getPort());
}
});
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ChannelFuture f = b.bind(8080).sync();
f.channel().closeFuture().sync();
} finally {
workerGroup.shutdownGracefully();
bossGroup.shutdownGracefully();
}
}
}
There are several use cases where it makes sense to obtain the client's IP address (and possibly port). For that sake,
HttpServletRequest
provides the methodsgetRemotePort()
andgetRemoteAddr()
.While this should be sufficient for most scenarios, it binds the application to the Servlet API, just for calling a single method.
As JAX-RS's binding to the Servlet API isn't mandatory (e. g. a Java SE standalone standalone server might implement JAX-RS directly without relying on the Servlet API), this use case should be possible without the use of the Server API. Therefore I suggest to enhance the
Request
class bygetRemotePort()
andgetRemoteAddr()
.