Closed deathcap closed 8 years ago
Figured this was caused by the Host
header, but seems to be binding to only IPv6 not IPv4(?!):
wsmc $ perl -e'print "GET / HTTP/1.0\r\n\r\n"'|nc -vv localhost 24444
found 0 associations
found 1 connections:
1: flags=82<CONNECTED,PREFERRED>
outif lo0
src ::1 port 49606
dst ::1 port 24444
rank info not available
TCP aux info available
Connection to localhost port 24444 [tcp/*] succeeded!
HTTP/1.1 200 OK
Content-Type: text/html; charset=UTF-8
Content-Length: 633
<!DOCTYPE HTML>
<html>
<head>
<title>voxel-clientmc</title>
<style>
body {
background-color: lightgray;
}
</style>
</head>
<body>
<a href="https://github.com/voxel/voxel-clientmc"><img style="position: absolute; top: 0; left: 0; border: 0;" src="https://camo.githubusercontent.com/121cd7cbdc3e4855075ea8b558508b91ac463ac2/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f6c6566745f677265656e5f3030373230302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_left_green_007200.png"></a>
<script src="bundle.js"></script>
</body>
</html>
wsmc $ perl -e'print "GET / HTTP/1.0\r\n\r\n"'|nc -vv 127.0.0.1 24444
found 0 associations
found 1 connections:
1: flags=82<CONNECTED,PREFERRED>
outif lo0
src 127.0.0.1 port 49607
dst 127.0.0.1 port 24444
rank info not available
TCP aux info available
Connection to 127.0.0.1 port 24444 [tcp/*] succeeded!
HTTP/1.1 200 OK
Content-Type: text/plain
Date: Tue, 09 Feb 2016 09:10:43 GMT
Connection: close
Not implementedwsmc $
passing to ServerBootstrap bind, "0.0.0.0" wsAddress by default:
Channel channel = bootstrap.bind(this.wsAddress, this.wsPort)
bind(SocketAddress) : ChannelFuture bind(int) : ChannelFuture bind(InetAddress, int) : ChannelFuture bind(String, int) : ChannelFuture
all call into InetSocketAddress() constructor: http://docs.oracle.com/javase/7/docs/api/java/net/InetSocketAddress.html - "A null address will assign the wildcard address."
Testing this:
ChannelFuture channelFuture;
if (this.wsAddress == null || this.wsAddress.equals("0.0.0.0") || this.wsAddress.equals("")) {
channelFuture = bootstrap.bind(this.wsPort);
} else {
channelFuture = bootstrap.bind(this.wsAddress, this.wsPort);
}
but no difference. Doesn't seem to be a problem in binding but in handling? https://github.com/netty/netty/pull/4770?
ServerHandler pipeline is:
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
ChannelPipeline pipeline = socketChannel.pipeline();
pipeline.addLast("codec-http", new HttpServerCodec());
pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
pipeline.addLast("handler", new HTTPHandler(this.webThread.wsPort));
pipeline.addLast("websocket", new WebSocketServerProtocolHandler("/server"));
pipeline.addLast("websocket-handler", new WebSocketHandler(webThread, this.mcAddress, this.mcPort, this.users, this.filter, this.verbose));
}
first my code runs in HTTPHandler, but none of the `@Override'en methods in HTTPHandler are called when accessing over IPv4 (ok over IPv6).
protected void messageReceived(ChannelHandlerContext ctx, FullHttpRequest msg)
throws Exception {
System.out.println("HTTPHANDLER MESSAGERECEIVED");
private static void copyStream(InputStream in, OutputStream out) throws IOException {
System.out.println("HTTPHANDLER COPYSTREAM");
public void httpRequest(ChannelHandlerContext context, FullHttpRequest request) throws IOException {
System.out.println("HTTPHANDLER HTTPREQUEST");
public void sendHttpResponse(ChannelHandlerContext context, FullHttpRequest request, FullHttpResponse response) {
System.out.println("HTTPHANDLER SENDHTTPRESPONSE");
need to find out where and what is returning the "Not implemented" response before I get it
https://github.com/netty/netty/search?utf8=✓&q=%22Not+implemented%22 shows there are "501 Not Implemented" (notice capital "I") HttpResponseStatus.NOT_IMPLEMENTED
responses, but this is a HTTP/1.1 200 OK with body "Not implemented"
--- a/src/main/java/deathcap/wsmc/web/WebThread.java
+++ b/src/main/java/deathcap/wsmc/web/WebThread.java
@@ -27,6 +27,7 @@ import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
+import io.netty.util.NetUtil;
import io.netty.util.ResourceLeakDetector;
import io.netty.util.concurrent.GlobalEventExecutor;
@@ -72,7 +73,7 @@ public class WebThread extends Thread {
SocketAddress socketAddress;
if (this.wsAddress == null || this.wsAddress.equals("")) {
- socketAddress = new InetSocketAddress((InetAddress) null, this.wsPort);
+ socketAddress = new InetSocketAddress(NetUtil.LOCALHOST4, this.wsPort);
} else {
socketAddress = new InetSocketAddress(this.wsAddress, this.wsPort);
}
Using NetUtil.LOCALHOST4 (per https://github.com/netty/netty/pull/4770, which was "Cherry-picked into 4.0 (52ba4f4) and 4.1 (3616d9e)" in Netty 13 days ago) correctly allows accessing the server over IPv4 at these URLs: http://127.0.0.1:24444/#testuser:VXVbHahf http://localhost:24444/ http://0.0.0.0:24444/ - but not my local (RFC1918) IP, nor the IPv6 local http://[::1]:24444/ nor the IPv6 global address. What I'm looking for is not a localhost IPv4 but "wildcard IPv4" (and/or wildcard IPv4+IPv6)
+ socketAddress = new InetSocketAddress(Inet4Address.getLocalHost(), this.wsPort);
allows using my IPv4 RFC1918 local network address, but not localhost, 127.0.0.1, 0.0.0.0, ::1, anything else. Am I really going to have to listen multiple servers for each interface?
Turns out "Not implemented" is from wsmc/JavaScript (wsmc.js). Related: https://github.com/deathcap/wsmc/pull/31 [Broken] Update all dependencies (ws/websocket-stream) 🌴
Always something simple... (InetAddress) null = wildcard works correctly for both IPv4 and IPv6, lo0 and en1. Why I was seeing different behavior is that wsmc.js was erroneously running (user error, nonetheless non-informative error message) but only bound to IPv4 (bug/missing feature?), and wsmc.jar tried to bind everywhere but silently failed on IPv4 since the port was occupied so it only bound to IPv6 (missing error message?).
Fixed wsmc.js to bind to '' instead of '0.0.0.0' by default (IPv4+IPv6), now wsmc.jar gives a more informative binding error message:
[23:49:41 WARN]: java.net.BindException: Address already in use
[23:49:41 INFO]: Cactus Growth Modifier: 100%
[23:49:41 WARN]: at sun.nio.ch.Net.bind0(Native Method)
[23:49:41 WARN]: at sun.nio.ch.Net.bind(Net.java:344)
[23:49:41 WARN]: at sun.nio.ch.Net.bind(Net.java:336)
[23:49:41 INFO]: Cane Growth Modifier: 100%
[23:49:41 WARN]: at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:199)
[23:49:41 WARN]: at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
[23:49:41 WARN]: at deathcap.wsmc.lib.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:104)
[23:49:41 INFO]: Melon Growth Modifier: 100%
[23:49:41 WARN]: at deathcap.wsmc.lib.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:464)
[23:49:41 INFO]: Mushroom Growth Modifier: 100%
[23:49:41 WARN]: at deathcap.wsmc.lib.netty.channel.DefaultChannelPipeline$HeadHandler.bind(DefaultChannelPipeline.java:1032)
[23:49:41 INFO]: Pumpkin Growth Modifier: 100%
[23:49:41 WARN]: at deathcap.wsmc.lib.netty.channel.ChannelHandlerInvokerUtil.invokeBindNow(ChannelHandlerInvokerUtil.java:99)
[23:49:41 INFO]: Sapling Growth Modifier: 100%
[23:49:41 WARN]: at deathcap.wsmc.lib.netty.channel.DefaultChannelHandlerInvoker.invokeBind(DefaultChannelHandlerInvoker.java:196)
[23:49:41 INFO]: Wheat Growth Modifier: 100%
[23:49:41 WARN]: at deathcap.wsmc.lib.netty.channel.DefaultChannelHandlerContext.bind(DefaultChannelHandlerContext.java:366)
[23:49:41 WARN]: at deathcap.wsmc.lib.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:898)
[23:49:41 INFO]: NetherWart Growth Modifier: 100%
[23:49:41 WARN]: at deathcap.wsmc.lib.netty.channel.AbstractChannel.bind(AbstractChannel.java:189)
[23:49:41 WARN]: at deathcap.wsmc.lib.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:309)
[23:49:41 INFO]: Entity Activation Range: An 32 / Mo 32 / Mi 16
[23:49:41 WARN]: at deathcap.wsmc.lib.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:318)
[23:49:41 WARN]: at deathcap.wsmc.lib.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353)
[23:49:41 WARN]: at deathcap.wsmc.lib.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:794)
[23:49:41 INFO]: Entity Tracking Range: Pl 48 / An 48 / Mo 48 / Mi 32 / Other 64
[23:49:41 WARN]: at java.lang.Thread.run(Thread.java:724)
[23:49:41 INFO]: Hopper Transfer: 8 Hopper Check: 8 Hopper Amount: 1
http://localhost:24444/ - ok http://127.0.0.1:24444/ - Not implemented http://anythingelse:24444/ - Not implemented
Non-localhost hosts are very important so that the service can be reachable externally