com.king.platform.net.http.netty.websocket.WebSocketUtil Maven / Gradle / Ivy
package com.king.platform.net.http.netty.websocket;
import com.king.platform.net.http.netty.ServerInfo;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpScheme;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.FastThreadLocal;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import static io.netty.handler.codec.http.HttpHeaderNames.SEC_WEBSOCKET_VERSION;
public class WebSocketUtil {
public static final String MAGIC_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
private static final FastThreadLocal SHA1 = new FastThreadLocal() {
@Override
protected MessageDigest initialValue() throws Exception {
try {
return MessageDigest.getInstance("SHA1");
} catch (NoSuchAlgorithmException e) {
throw new InternalError("SHA-1 not supported on this platform - Outdated?");
}
}
};
public static byte[] sha1(byte[] data) {
return digest(SHA1, data);
}
private static byte[] digest(FastThreadLocal digestFastThreadLocal, byte[] data) {
MessageDigest digest = digestFastThreadLocal.get();
digest.reset();
return digest.digest(data);
}
public static String getAcceptKey(String key) {
Base64.Encoder encoder = Base64.getEncoder();
byte[] bytes = (key + MAGIC_GUID).getBytes(StandardCharsets.US_ASCII);
byte[] encode = encoder.encode(digest(SHA1, bytes));
return new String(encode, StandardCharsets.US_ASCII);
}
public static void populateHeaders(ServerInfo serverInfo, HttpHeaders headers) {
byte[] nonce = randomBytes(16);
String key = base64(nonce);
headers.set(HttpHeaderNames.UPGRADE, HttpHeaderValues.WEBSOCKET)
.set(HttpHeaderNames.CONNECTION, HttpHeaderValues.UPGRADE)
.set(HttpHeaderNames.SEC_WEBSOCKET_KEY, key)
.set(HttpHeaderNames.SEC_WEBSOCKET_ORIGIN, websocketOriginValue(serverInfo.getHost(), serverInfo.getPort()))
.set(SEC_WEBSOCKET_VERSION, "13");
}
public static byte[] randomBytes(int size) {
byte[] bytes = new byte[size];
for (int index = 0; index < size; index++) {
bytes[index] = (byte) randomNumber(0, 255);
}
return bytes;
}
public static String base64(byte[] data) {
ByteBuf encodedData = Unpooled.wrappedBuffer(data);
ByteBuf encoded = io.netty.handler.codec.base64.Base64.encode(encodedData);
String encodedString = encoded.toString(CharsetUtil.UTF_8);
encoded.release();
return encodedString;
}
private static String websocketOriginValue(String host, int wsPort) {
String originValue = (wsPort == HttpScheme.HTTPS.port() ?
HttpScheme.HTTPS.name() : HttpScheme.HTTP.name()) + "://" + host;
if (wsPort != HttpScheme.HTTP.port() && wsPort != HttpScheme.HTTPS.port()) {
// if the port is not standard (80/443) its needed to add the port to the header.
// See http://tools.ietf.org/html/rfc6454#section-6.2
return originValue + ':' + wsPort;
}
return originValue;
}
private static int randomNumber(int minimum, int maximum) {
return (int) (Math.random() * maximum + minimum);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy