feat(batch26): implement websocket upgrade/options/server feature group B
This commit is contained in:
@@ -82,6 +82,15 @@ public sealed partial class NatsServer
|
|||||||
internal static Exception WsReturnHTTPError(int statusCode, string message) =>
|
internal static Exception WsReturnHTTPError(int statusCode, string message) =>
|
||||||
new WsHttpError(statusCode, message);
|
new WsHttpError(statusCode, message);
|
||||||
|
|
||||||
|
private static bool wsHeaderContains(NameValueCollection headers, string key, string expected) =>
|
||||||
|
WsHeaderContains(headers, key, expected);
|
||||||
|
|
||||||
|
private static (bool supported, bool noContext) wsPMCExtensionSupport(NameValueCollection headers, bool checkNoContextTakeOver) =>
|
||||||
|
WsPMCExtensionSupport(headers, checkNoContextTakeOver);
|
||||||
|
|
||||||
|
private static Exception wsReturnHTTPError(int statusCode, string message) =>
|
||||||
|
WsReturnHTTPError(statusCode, message);
|
||||||
|
|
||||||
internal static string WsGetHostAndPort(string hostPort, out int port)
|
internal static string WsGetHostAndPort(string hostPort, out int port)
|
||||||
{
|
{
|
||||||
port = 0;
|
port = 0;
|
||||||
@@ -103,6 +112,9 @@ public sealed partial class NatsServer
|
|||||||
return hostPort;
|
return hostPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string wsGetHostAndPort(string hostPort, out int port) =>
|
||||||
|
WsGetHostAndPort(hostPort, out port);
|
||||||
|
|
||||||
internal static byte[] WsMakeChallengeKey(string key)
|
internal static byte[] WsMakeChallengeKey(string key)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(key);
|
ArgumentNullException.ThrowIfNull(key);
|
||||||
@@ -116,6 +128,10 @@ public sealed partial class NatsServer
|
|||||||
return Convert.ToBase64String(digest);
|
return Convert.ToBase64String(digest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static byte[] wsMakeChallengeKey(string key) => WsMakeChallengeKey(key);
|
||||||
|
|
||||||
|
private static string wsAcceptKey(string key) => WsAcceptKey(key);
|
||||||
|
|
||||||
internal static Exception? ValidateWebsocketOptions(WebsocketOpts options)
|
internal static Exception? ValidateWebsocketOptions(WebsocketOpts options)
|
||||||
{
|
{
|
||||||
if (options.Port < 0 || options.Port > 65535)
|
if (options.Port < 0 || options.Port > 65535)
|
||||||
@@ -127,6 +143,8 @@ public sealed partial class NatsServer
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Exception? validateWebsocketOptions(WebsocketOpts options) => ValidateWebsocketOptions(options);
|
||||||
|
|
||||||
private void WsSetOriginOptions()
|
private void WsSetOriginOptions()
|
||||||
{
|
{
|
||||||
lock (_websocket.Mu)
|
lock (_websocket.Mu)
|
||||||
@@ -304,4 +322,11 @@ public sealed partial class NatsServer
|
|||||||
return false;
|
return false;
|
||||||
return uri.Scheme.Equals(WsConstants.SchemePrefixTls, StringComparison.OrdinalIgnoreCase);
|
return uri.Scheme.Equals(WsConstants.SchemePrefixTls, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool isWSURL(string url) => IsWSURL(url);
|
||||||
|
|
||||||
|
private static bool isWSSURL(string url) => IsWSSURL(url);
|
||||||
|
|
||||||
|
private System.Net.Security.SslServerAuthenticationOptions? wsGetTLSConfig() =>
|
||||||
|
GetOpts().Websocket.TlsConfig;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,4 +25,31 @@ internal sealed class WebSocketHandler
|
|||||||
|
|
||||||
public static byte[] WsCreateCloseMessage(int status, string body) =>
|
public static byte[] WsCreateCloseMessage(int status, string body) =>
|
||||||
WebSocketHelpers.WsCreateCloseMessage(status, body);
|
WebSocketHelpers.WsCreateCloseMessage(status, body);
|
||||||
|
|
||||||
|
public static bool WsHeaderContains(System.Collections.Specialized.NameValueCollection headers, string key, string expected) =>
|
||||||
|
NatsServer.WsHeaderContains(headers, key, expected);
|
||||||
|
|
||||||
|
public static (bool supported, bool noContext) WsPMCExtensionSupport(System.Collections.Specialized.NameValueCollection headers, bool checkNoContextTakeOver) =>
|
||||||
|
NatsServer.WsPMCExtensionSupport(headers, checkNoContextTakeOver);
|
||||||
|
|
||||||
|
public static Exception WsReturnHTTPError(int statusCode, string message) =>
|
||||||
|
NatsServer.WsReturnHTTPError(statusCode, message);
|
||||||
|
|
||||||
|
public static string WsGetHostAndPort(string hostPort, out int port) =>
|
||||||
|
NatsServer.WsGetHostAndPort(hostPort, out port);
|
||||||
|
|
||||||
|
public static string WsAcceptKey(string key) =>
|
||||||
|
NatsServer.WsAcceptKey(key);
|
||||||
|
|
||||||
|
public static byte[] WsMakeChallengeKey(string key) =>
|
||||||
|
NatsServer.WsMakeChallengeKey(key);
|
||||||
|
|
||||||
|
public static Exception? ValidateWebsocketOptions(WebsocketOpts options) =>
|
||||||
|
NatsServer.ValidateWebsocketOptions(options);
|
||||||
|
|
||||||
|
public static bool IsWSURL(string url) =>
|
||||||
|
NatsServer.IsWSURL(url);
|
||||||
|
|
||||||
|
public static bool IsWSSURL(string url) =>
|
||||||
|
NatsServer.IsWSSURL(url);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -203,6 +203,31 @@ internal sealed class SrvWebsocket
|
|||||||
public bool Compression { get; set; }
|
public bool Compression { get; set; }
|
||||||
public string Host { get; set; } = string.Empty;
|
public string Host { get; set; } = string.Empty;
|
||||||
public int Port { get; set; }
|
public int Port { get; set; }
|
||||||
|
|
||||||
|
public Exception? checkOrigin(string requestHost, string? origin)
|
||||||
|
{
|
||||||
|
if (!SameOrigin && AllowedOrigins.Count == 0)
|
||||||
|
return null;
|
||||||
|
if (string.IsNullOrWhiteSpace(origin))
|
||||||
|
return new InvalidOperationException("origin header missing");
|
||||||
|
if (!Uri.TryCreate(origin, UriKind.Absolute, out var uri))
|
||||||
|
return new InvalidOperationException("invalid origin");
|
||||||
|
if (SameOrigin && !string.Equals(uri.Host, requestHost, StringComparison.OrdinalIgnoreCase))
|
||||||
|
return new InvalidOperationException("origin not same as host");
|
||||||
|
if (AllowedOrigins.Count == 0)
|
||||||
|
return null;
|
||||||
|
if (!AllowedOrigins.TryGetValue(uri.Host, out var allowed))
|
||||||
|
return new InvalidOperationException("origin host not allowed");
|
||||||
|
|
||||||
|
var port = uri.IsDefaultPort
|
||||||
|
? uri.Scheme.Equals("https", StringComparison.OrdinalIgnoreCase) ? "443" : "80"
|
||||||
|
: uri.Port.ToString();
|
||||||
|
if (!string.Equals(allowed.Scheme, uri.Scheme, StringComparison.OrdinalIgnoreCase))
|
||||||
|
return new InvalidOperationException("origin scheme not allowed");
|
||||||
|
if (!string.Equals(allowed.Port, port, StringComparison.Ordinal))
|
||||||
|
return new InvalidOperationException("origin port not allowed");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal readonly record struct AllowedOrigin(string Scheme, string Port);
|
internal readonly record struct AllowedOrigin(string Scheme, string Port);
|
||||||
|
|||||||
BIN
porting.db
BIN
porting.db
Binary file not shown.
Reference in New Issue
Block a user