I set up Java HTTPS Server using io.undertow.core, created HttpListener, looks like my code is perfect, but... It doesn't work. It gives me 400 Bad Request on any request.
Here's the code related to undertow, http, etc.:
package ru.epserv.epmodule.modules.serverapi;
import org.bukkit.Bukkit;
import org.json.simple.JSONObject;
import io.undertow.Undertow;
import io.undertow.server.HttpHandler;
import io.undertow.server.HttpServerExchange;
import ru.epserv.epmodule.modules.serverapi.contexts.BanwhyContext;
import ru.epserv.epmodule.modules.serverapi.contexts.FirstseenContext;
import ru.epserv.epmodule.modules.serverapi.contexts.GetPlayerContext;
import ru.epserv.epmodule.modules.serverapi.contexts.GetPlayersContext;
import ru.epserv.epmodule.modules.serverapi.contexts.GetWarningsContext;
import ru.epserv.epmodule.modules.serverapi.contexts.IsOnlineContext;
import ru.epserv.epmodule.modules.serverapi.contexts.LastseenContext;
import ru.epserv.epmodule.modules.serverapi.contexts.Ping;
import ru.epserv.epmodule.modules.serverapi.contexts.SendContext;
import ru.epserv.epmodule.modules.serverapi.contexts.SkillsContext;
import ru.epserv.epmodule.modules.serverapi.contexts.TimeplayedContext;
import ru.epserv.epmodule.modules.serverapi.contexts.UptimeContext;
import ru.epserv.epmodule.modules.serverapi.utils.ParsedRequest;
public class HTTPSServer {
public static String notFound;
public Undertow server;
@SuppressWarnings("unchecked")
public void start() {
JSONObject notFoundJSON = new JSONObject();
notFoundJSON.put("response", null);
notFoundJSON.put("error", "not_found");
HTTPSServer.notFound = notFoundJSON.toJSONString();
Ping ping = new Ping();
SendContext send = new SendContext();
GetPlayersContext list = new GetPlayersContext();
IsOnlineContext isOnline = new IsOnlineContext();
UptimeContext uptime = new UptimeContext();
FirstseenContext firstseen = new FirstseenContext();
LastseenContext lastseen = new LastseenContext();
TimeplayedContext timeplayed = new TimeplayedContext();
BanwhyContext banwhy = new BanwhyContext();
GetWarningsContext getWarnings = new GetWarningsContext();
SkillsContext skills = new SkillsContext();
GetPlayerContext getPlayer = new GetPlayerContext();
this.server = Undertow.builder()
.addHttpsListener(45105, "0.0.0.0", HTTPSServer.getSSLContextFromLetsEncrypt())
.setHandler(new HttpHandler() {
@Override
public void handleRequest(final HttpServerExchange t) throws Exception {
ParsedRequest r = new ParsedRequest(t);
r.setResponseHeader("Access-Control-Allow-Origin", "*");
Bukkit.getLogger().warning(r.getRequestURI().getPath());
switch (r.getRequestURI().getPath().substring(1).trim()) {
case "ping":
ping.handle(r, t);
break;
case "send":
send.handle(r, t);
break;
case "list":
list.handle(r, t);
break;
case "isonline":
ServerAPI.log
.warn("Отправлен запрос на устаревший адрес https://mc.epserv.ru:45105/isonline, "
+ "используйте isOnline. Адрес подключения: "
+ r.getRemoteAddress().toString() + ". User-Agent: "
+ r.getRequestHeaders().getFirst("User-Agent") + ".");
isOnline.handle(r, t);
break;
case "isOnline":
isOnline.handle(r, t);
break;
case "uptime":
uptime.handle(r, t);
break;
case "firstseen":
firstseen.handle(r, t);
break;
case "lastseen":
lastseen.handle(r, t);
break;
case "timeplayed":
timeplayed.handle(r, t);
break;
case "banwhy":
banwhy.handle(r, t);
break;
case "getWarnings":
getWarnings.handle(r, t);
break;
case "skills":
skills.handle(r, t);
break;
case "getPlayer":
getPlayer.handle(r, t);
break;
default:
r.setResponseCode(404);
r.write(HTTPSServer.notFound);
r.send();
}
}
})
.build();
this.server.start();
}
public void stop() {
server.stop();
}
}
I also tried to get more info using curl -v --data "" https://mc.epserv.ru:45105/list
, here's the output:
boom@kali:~$ curl -v --data "" https://mc.epserv.ru:45105/list
* Trying 5.228.179.67:45105...
* TCP_NODELAY set
* Connected to mc.epserv.ru (5.228.179.67) port 45105 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server did not agree to a protocol
* Server certificate:
* subject: CN=mc.epserv.ru
* start date: May 18 13:27:54 2020 GMT
* expire date: Aug 16 13:27:54 2020 GMT
* subjectAltName: host "mc.epserv.ru" matched cert's "mc.epserv.ru"
* issuer: C=US; O=Let's Encrypt; CN=Let's Encrypt Authority X3
* SSL certificate verify ok.
> POST /list HTTP/1.1
> Host: mc.epserv.ru:45105
> User-Agent: curl/7.68.0
> Accept: */*
> Content-Length: 0
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 400 Bad Request
< Content-Length: 0
< Connection: close
<
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, close notify (256):
I tried to use AccessLogHandler
, RequestDumpingHandler
, but nothing, Undertow doesn't log anything and continues responding with 400 Bad Request.
What am I doing wrong? I found a bug or what? What's wrong? Ask me for more info if needed, and sorry if my English is bad
Question solved - I built Undertow again with mvn install
(from https://github.com/undertow-io/undertow
repo), now it works as expected. It may be a bug of Undertow 2.1.2.Final-SNAPSHOT, but on Undertow 2.1.4.Final-SNAPSHOT everything works as needed.