You've already forked Arcturus-Morningstar-Extended
mirror of
https://github.com/duckietm/Arcturus-Morningstar-Extended.git
synced 2026-06-19 15:06:19 +00:00
SMall fix for CORS
This commit is contained in:
@@ -34,3 +34,10 @@ SET @ddl = IF(@col_exists = 0,
|
|||||||
PREPARE stmt FROM @ddl;
|
PREPARE stmt FROM @ddl;
|
||||||
EXECUTE stmt;
|
EXECUTE stmt;
|
||||||
DEALLOCATE PREPARE stmt;
|
DEALLOCATE PREPARE stmt;
|
||||||
|
|
||||||
|
|
||||||
|
UPDATE emulator_settings SET `key`='ws.whitelist' WHERE `key`='websockets.whitelist';
|
||||||
|
UPDATE emulator_settings SET `key`='ws.host' WHERE `key`='ws.nitro.host';
|
||||||
|
UPDATE emulator_settings SET `key`='ws.port' WHERE `key`='ws.nitro.port';
|
||||||
|
INSERT emulator_settings (`key`, `value`) VALUES ('ws.ip.header', 'X-Forwarded-For');
|
||||||
|
INSERT emulator_settings (`key`, `value`) VALUES ('ws.enabled', 'true');
|
||||||
+35
-6
@@ -8,10 +8,13 @@ import io.netty.channel.ChannelHandlerContext;
|
|||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import io.netty.handler.codec.http.*;
|
import io.netty.handler.codec.http.*;
|
||||||
import io.netty.util.ReferenceCountUtil;
|
import io.netty.util.ReferenceCountUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
public class WebSocketHttpHandler extends ChannelInboundHandlerAdapter {
|
public class WebSocketHttpHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(WebSocketHttpHandler.class);
|
||||||
private static final String ORIGIN_HEADER = "Origin";
|
private static final String ORIGIN_HEADER = "Origin";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -27,6 +30,12 @@ public class WebSocketHttpHandler extends ChannelInboundHandlerAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleHttpRequest(ChannelHandlerContext ctx, HttpMessage req) {
|
private boolean handleHttpRequest(ChannelHandlerContext ctx, HttpMessage req) {
|
||||||
|
captureForwardedIp(ctx, req);
|
||||||
|
|
||||||
|
if (!isWebSocketUpgrade(req)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
String origin = "error";
|
String origin = "error";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -38,27 +47,47 @@ public class WebSocketHttpHandler extends ChannelInboundHandlerAdapter {
|
|||||||
|
|
||||||
String whitelist = Emulator.getConfig().getValue("ws.whitelist", "localhost");
|
String whitelist = Emulator.getConfig().getValue("ws.whitelist", "localhost");
|
||||||
if (!isWhitelisted(origin, whitelist.split(","))) {
|
if (!isWhitelisted(origin, whitelist.split(","))) {
|
||||||
|
LOGGER.warn("WebSocket upgrade rejected — origin '{}' not in ws.whitelist='{}'",
|
||||||
|
req.headers().get(ORIGIN_HEADER), whitelist);
|
||||||
|
|
||||||
FullHttpResponse response = new DefaultFullHttpResponse(
|
FullHttpResponse response = new DefaultFullHttpResponse(
|
||||||
HttpVersion.HTTP_1_1,
|
HttpVersion.HTTP_1_1,
|
||||||
HttpResponseStatus.FORBIDDEN,
|
HttpResponseStatus.FORBIDDEN,
|
||||||
Unpooled.wrappedBuffer("Origin forbidden".getBytes())
|
Unpooled.wrappedBuffer("Origin forbidden".getBytes())
|
||||||
);
|
);
|
||||||
|
response.headers().set("Vary", "Origin");
|
||||||
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
|
ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String ipHeader = Emulator.getConfig().getValue("ws.ip.header", "");
|
|
||||||
if (!ipHeader.isEmpty() && req.headers().contains(ipHeader)) {
|
|
||||||
String ip = req.headers().get(ipHeader);
|
|
||||||
ctx.channel().attr(GameServerAttributes.WS_IP).set(ip);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void captureForwardedIp(ChannelHandlerContext ctx, HttpMessage req) {
|
||||||
|
String ipHeader = Emulator.getConfig().getValue("ws.ip.header", "");
|
||||||
|
if (!ipHeader.isEmpty() && req.headers().contains(ipHeader)) {
|
||||||
|
String ip = req.headers().get(ipHeader);
|
||||||
|
ctx.channel().attr(GameServerAttributes.WS_IP).set(ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isWebSocketUpgrade(HttpMessage req) {
|
||||||
|
String upgrade = req.headers().get(HttpHeaderNames.UPGRADE);
|
||||||
|
if (upgrade == null || !"websocket".equalsIgnoreCase(upgrade)) return false;
|
||||||
|
|
||||||
|
String connection = req.headers().get(HttpHeaderNames.CONNECTION);
|
||||||
|
if (connection == null) return false;
|
||||||
|
|
||||||
|
for (String token : connection.split(",")) {
|
||||||
|
if ("upgrade".equalsIgnoreCase(token.trim())) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static String getDomainNameFromUrl(String url) throws Exception {
|
private static String getDomainNameFromUrl(String url) throws Exception {
|
||||||
URI uri = new URI(url);
|
URI uri = new URI(url);
|
||||||
String domain = uri.getHost();
|
String domain = uri.getHost();
|
||||||
|
if (domain == null) return "error";
|
||||||
return domain.startsWith("www.") ? domain.substring(4) : domain;
|
return domain.startsWith("www.") ? domain.substring(4) : domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,16 +27,6 @@ rcon.host=127.0.0.1
|
|||||||
rcon.port=3001
|
rcon.port=3001
|
||||||
rcon.allowed=127.0.0.1;127.0.0.2
|
rcon.allowed=127.0.0.1;127.0.0.2
|
||||||
|
|
||||||
#WebSocket Configuration (for Nitro)
|
|
||||||
#Set ws.enabled to true to enable WebSocket connections.
|
|
||||||
ws.enabled=false
|
|
||||||
ws.host=0.0.0.0
|
|
||||||
ws.port=2096
|
|
||||||
#Comma-separated whitelist of allowed origins. Supports wildcards: *.example.com, * (allow all)
|
|
||||||
ws.whitelist=localhost
|
|
||||||
#Header name for real client IP when behind a proxy (e.g., X-Forwarded-For, CF-Connecting-IP). Leave empty if not using a proxy.
|
|
||||||
ws.ip.header=
|
|
||||||
|
|
||||||
# Databse configuration
|
# Databse configuration
|
||||||
db.pool.connection_timeout_ms = 10000
|
db.pool.connection_timeout_ms = 10000
|
||||||
db.pool.idle_timeout_ms = 600000
|
db.pool.idle_timeout_ms = 600000
|
||||||
@@ -69,3 +59,12 @@ login.remember.jwt.secret=
|
|||||||
|
|
||||||
# Login news API.
|
# Login news API.
|
||||||
login.news.limit=5
|
login.news.limit=5
|
||||||
|
|
||||||
|
|
||||||
|
#WebSocket Configuration (for Nitro)
|
||||||
|
#Please adjust this setting in the Database !!!!
|
||||||
|
### ws.enabled=false
|
||||||
|
### ws.host=0.0.0.0
|
||||||
|
### ws.port=2096
|
||||||
|
### ws.whitelist=localhost #Comma-separated whitelist of allowed origins. Supports wildcards: *.example.com, * (allow all)
|
||||||
|
### ws.ip.header=X-Forwarded-For #Header name for real client IP when behind a proxy (e.g., X-Forwarded-For, CF-Connecting-IP). Leave empty if not using a proxy.
|
||||||
|
|||||||
Reference in New Issue
Block a user