diff --git a/src/WebExpress.WebCore.Test/Html/UnitTestRandomId.cs b/src/WebExpress.WebCore.Test/Html/UnitTestRandomId.cs
index 7b9554b..6152894 100644
--- a/src/WebExpress.WebCore.Test/Html/UnitTestRandomId.cs
+++ b/src/WebExpress.WebCore.Test/Html/UnitTestRandomId.cs
@@ -59,7 +59,7 @@ public void HexCharacters()
var id = RandomId.Create();
// validation
- var hex = id.Substring(4);
+ var hex = id.Substring("id_".Length);
Assert.Matches("^[0-9A-F]+$", hex);
}
diff --git a/src/WebExpress.WebCore.Test/Manager/UnitTestStatusPageManager.cs b/src/WebExpress.WebCore.Test/Manager/UnitTestStatusPageManager.cs
index b6cbce4..6b13db3 100644
--- a/src/WebExpress.WebCore.Test/Manager/UnitTestStatusPageManager.cs
+++ b/src/WebExpress.WebCore.Test/Manager/UnitTestStatusPageManager.cs
@@ -165,8 +165,8 @@ public void CreateAndCheckCode(Type applicationType, int statusCode, int? expect
/// Test the CreateStatusResponse function of the status page.
///
[Theory]
- [InlineData(typeof(TestApplicationA), 400, "content", "content", 78)]
- [InlineData(typeof(TestApplicationA), 500, "content", "content", 78)]
+ [InlineData(typeof(TestApplicationA), 400, "content", "content", 72)]
+ [InlineData(typeof(TestApplicationA), 500, "content", "content", 72)]
public void CreateAndCheckMessage(Type applicationType, int statusCode, string content, string expected, int length)
{
// arrange
diff --git a/src/WebExpress.WebCore/WebAttribute/SegmentRegexAttribute.cs b/src/WebExpress.WebCore/WebAttribute/SegmentRegexAttribute.cs
index 9544cd4..207fb83 100644
--- a/src/WebExpress.WebCore/WebAttribute/SegmentRegexAttribute.cs
+++ b/src/WebExpress.WebCore/WebAttribute/SegmentRegexAttribute.cs
@@ -20,19 +20,19 @@ public class SegmentRegexAttribute : Attribute, IEndpointAttribute,
private string Expression { get; set; }
///
- /// Returns or sets the display string.
+ /// Returns or sets the tag.
///
- private string Display { get; set; }
+ private string Tag { get; set; }
///
/// Initializes a new instance of the class.
///
/// The regular expression.
- /// The display string.
- public SegmentRegexAttribute(string expression, string display = null)
+ /// The tag.
+ public SegmentRegexAttribute(string expression, string tag = null)
{
Expression = expression;
- Display = display;
+ Tag = tag;
}
///
@@ -41,7 +41,7 @@ public SegmentRegexAttribute(string expression, string display = null)
/// The path segment.
public IUriPathSegment ToPathSegment()
{
- return new UriPathSegmentVariableRegex(Expression, Display);
+ return new UriPathSegmentVariableRegex(Expression, Tag);
}
}
}
diff --git a/src/WebExpress.WebCore/WebAttribute/SegmentStringAttribute.cs b/src/WebExpress.WebCore/WebAttribute/SegmentStringAttribute.cs
index ad98978..b52850f 100644
--- a/src/WebExpress.WebCore/WebAttribute/SegmentStringAttribute.cs
+++ b/src/WebExpress.WebCore/WebAttribute/SegmentStringAttribute.cs
@@ -15,17 +15,17 @@ public class SegmentStringAttribute : Attribute, IEndpointAttribute,
where TParameter : IParameterStatic, new()
{
///
- /// Returns or sets the display string.
+ /// Returns or sets the tag.
///
- private string Display { get; set; }
+ private string Tag { get; set; }
///
/// Initializes a new instance of the class.
///
- /// The display string.
- public SegmentStringAttribute(string display = null)
+ /// The tag.
+ public SegmentStringAttribute(string tag = null)
{
- Display = display;
+ Tag = tag;
}
///
@@ -34,7 +34,7 @@ public SegmentStringAttribute(string display = null)
/// The path segment.
public IUriPathSegment ToPathSegment()
{
- return new UriPathSegmentVariableString(Display);
+ return new UriPathSegmentVariableString(Tag);
}
}
}
diff --git a/src/WebExpress.WebCore/WebAttribute/SegmentUIntAttribute.cs b/src/WebExpress.WebCore/WebAttribute/SegmentUIntAttribute.cs
index fe2fb27..1d1d8ba 100644
--- a/src/WebExpress.WebCore/WebAttribute/SegmentUIntAttribute.cs
+++ b/src/WebExpress.WebCore/WebAttribute/SegmentUIntAttribute.cs
@@ -18,17 +18,17 @@ public class SegmentUIntAttribute : Attribute, IEndpointAttribute, I
where TParameter : IParameterStatic, new()
{
///
- /// Returns or sets the display string.
+ /// Returns or sets the tag.
///
- private string Display { get; set; }
+ private string Tag { get; set; }
///
/// Initializes a new instance of the class.
///
- /// The display string.
- public SegmentUIntAttribute(string display = null)
+ /// The tag.
+ public SegmentUIntAttribute(string tag = null)
{
- Display = display;
+ Tag = tag;
}
///
@@ -37,7 +37,7 @@ public SegmentUIntAttribute(string display = null)
/// The path segment.
public IUriPathSegment ToPathSegment()
{
- return new UriPathSegmentVariableUInt(Display);
+ return new UriPathSegmentVariableUInt(Tag);
}
}
}
diff --git a/src/WebExpress.WebCore/WebMessage/RequestHeaderFields.cs b/src/WebExpress.WebCore/WebMessage/RequestHeaderFields.cs
index 26bb453..d5a0cad 100644
--- a/src/WebExpress.WebCore/WebMessage/RequestHeaderFields.cs
+++ b/src/WebExpress.WebCore/WebMessage/RequestHeaderFields.cs
@@ -124,11 +124,14 @@ internal RequestHeaderFields(IFeatureCollection contextFeatures)
SecWebSocketVersion = requestFeature.Headers.SecWebSocketVersion;
Cookies = requestFeature.Headers.Cookie
+ .SelectMany(c => c.Split(';', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
.Select(c =>
{
- var split = c.Split('=');
- return new Cookie(split[0], split[1]);
- });
+ var eqIndex = c.IndexOf('=');
+ if (eqIndex < 0) { return null; }
+ return new Cookie(c[..eqIndex].Trim(), c[(eqIndex + 1)..].Trim());
+ })
+ .Where(c => c != null);
Authorization = RequestAuthorization.Parse(requestFeature.Headers.Authorization);
}
diff --git a/src/WebExpress.WebCore/WebMessage/ResponseHeaderFields.cs b/src/WebExpress.WebCore/WebMessage/ResponseHeaderFields.cs
index 642d06d..b1de805 100644
--- a/src/WebExpress.WebCore/WebMessage/ResponseHeaderFields.cs
+++ b/src/WebExpress.WebCore/WebMessage/ResponseHeaderFields.cs
@@ -142,6 +142,11 @@ public override string ToString()
sb.AppendLine("Connection: Upgrade");
}
+ if (!string.IsNullOrWhiteSpace(SecWebSocketAccept))
+ {
+ sb.AppendLine("Sec-WebSocket-Accept: " + SecWebSocketAccept);
+ }
+
foreach (var c in CustomHeader)
{
sb.AppendLine(c.Key + ": " + c.Value);
diff --git a/src/WebExpress.WebCore/WebSocket/ISockt.cs b/src/WebExpress.WebCore/WebSocket/ISocket.cs
similarity index 74%
rename from src/WebExpress.WebCore/WebSocket/ISockt.cs
rename to src/WebExpress.WebCore/WebSocket/ISocket.cs
index 532c651..3d208a2 100644
--- a/src/WebExpress.WebCore/WebSocket/ISockt.cs
+++ b/src/WebExpress.WebCore/WebSocket/ISocket.cs
@@ -11,8 +11,6 @@ public interface ISocket : IEndpoint, IDisposable
{
///
/// Invoked after the websocket handshake has been accepted.
- /// Implementers may use the optional cancellation token to abort long-running startup tasks.
- /// the optional connectMessage provides initial metadata from the client (may be null).
///
/// The socket connection.
/// An asynchronous task.
diff --git a/src/WebExpress.WebCore/WebSocket/ISocketContext.cs b/src/WebExpress.WebCore/WebSocket/ISocketContext.cs
index 2616e19..7042eb0 100644
--- a/src/WebExpress.WebCore/WebSocket/ISocketContext.cs
+++ b/src/WebExpress.WebCore/WebSocket/ISocketContext.cs
@@ -25,7 +25,7 @@ public interface ISocketContext : IEndpointContext
/// Returns the maximum allowed message size in bytes, or null when the endpoint imposes no limit.
/// servers and hosts may use this to protect against excessively large frames.
///
- ulong MaxMessageSize { get; }
+ ulong? MaxMessageSize { get; }
///
/// Indicates whether this websocket endpoint requires an authenticated client.
diff --git a/src/WebExpress.WebCore/WebSocket/Model/SocketItem.cs b/src/WebExpress.WebCore/WebSocket/Model/SocketItem.cs
index 9e0d95c..85f5142 100644
--- a/src/WebExpress.WebCore/WebSocket/Model/SocketItem.cs
+++ b/src/WebExpress.WebCore/WebSocket/Model/SocketItem.cs
@@ -50,7 +50,7 @@ internal class SocketItem : IDisposable
/// Returns the maximum allowed message size in bytes, or null when the endpoint imposes no limit.
/// servers and hosts may use this to protect against excessively large frames.
///
- public ulong MaxMessageSize { get; set; }
+ public ulong? MaxMessageSize { get; set; }
///
/// Returns the conditions that must be met for the resource to be active.
diff --git a/src/WebExpress.WebCore/WebSocket/SocketContext.cs b/src/WebExpress.WebCore/WebSocket/SocketContext.cs
index 5ea54f0..5fa2031 100644
--- a/src/WebExpress.WebCore/WebSocket/SocketContext.cs
+++ b/src/WebExpress.WebCore/WebSocket/SocketContext.cs
@@ -50,7 +50,7 @@ public class SocketContext : ISocketContext
///
/// Maximum allowed message size in bytes, or null when no limit is imposed.
///
- public ulong MaxMessageSize { get; set; }
+ public ulong? MaxMessageSize { get; set; }
///
/// Indicates whether this websocket endpoint requires an authenticated client.
diff --git a/src/WebExpress.WebCore/WebSocket/SocketManager.cs b/src/WebExpress.WebCore/WebSocket/SocketManager.cs
index 9232cc2..72f663d 100644
--- a/src/WebExpress.WebCore/WebSocket/SocketManager.cs
+++ b/src/WebExpress.WebCore/WebSocket/SocketManager.cs
@@ -308,7 +308,7 @@ private void Register(IPluginContext pluginContext, IEnumerable !x.AttributeType.GetInterfaces().Contains(typeof(IEndpointAttribute)));
@@ -376,7 +376,7 @@ var attribute in socketType
// MAX MESSAGE SIZE
if (attributeType == typeof(MaxMessageSizeAttribute))
{
- maxMessageSize = (attribute as MaxMessageSizeAttribute)?.MaxMessageSize ?? 0;
+ maxMessageSize = (attribute as MaxMessageSizeAttribute)?.MaxMessageSize;
continue;
}
}
diff --git a/src/WebExpress.WebCore/WebTask/TaskManager.cs b/src/WebExpress.WebCore/WebTask/TaskManager.cs
index 0859cd7..5543401 100644
--- a/src/WebExpress.WebCore/WebTask/TaskManager.cs
+++ b/src/WebExpress.WebCore/WebTask/TaskManager.cs
@@ -78,7 +78,7 @@ public ITask CreateTask(string id, params object[] args)
{
var key = id?.ToLower();
- if (_dictionary.TryGetValue(id, out var value))
+ if (_dictionary.TryGetValue(key, out var value))
{
return value;
}
@@ -118,7 +118,7 @@ public ITask CreateTask(string id, EventHandler handler, p
{
var key = id?.ToLower();
- if (_dictionary.TryGetValue(id, out var value))
+ if (_dictionary.TryGetValue(key, out var value))
{
return value;
}
@@ -141,7 +141,12 @@ public ITask CreateTask(string id, EventHandler handler, p
/// The task.
public void RemoveTask(ITask task)
{
- var key = task?.Id.ToLower();
+ if (task?.Id is null)
+ {
+ return;
+ }
+
+ var key = task.Id.ToLower();
if (_dictionary.TryGetValue(key, out var storedTask) && storedTask is Task t)
{
diff --git a/src/WebExpress.WebCore/WebUri/IUriPathSegment.cs b/src/WebExpress.WebCore/WebUri/IUriPathSegment.cs
index a876c35..4877693 100644
--- a/src/WebExpress.WebCore/WebUri/IUriPathSegment.cs
+++ b/src/WebExpress.WebCore/WebUri/IUriPathSegment.cs
@@ -8,7 +8,7 @@ public interface IUriPathSegment
///
/// Returns or sets the id.
///
- internal string Id { get; }
+ string Id { get; }
///
/// Returns the value.
@@ -32,12 +32,12 @@ public interface IUriPathSegment
/// This property can be used to determine if the item should be displayed in user
/// interfaces or lists.
///
- bool IsHidden { get; internal set; }
+ bool IsHidden { get; set; }
///
/// Returns the URI to which the user is redirected.
///
- IUri Uri { get; internal set; }
+ IUri Uri { get; set; }
///
/// Checks whether the node matches the path element.
diff --git a/src/WebExpress.WebCore/WebUri/UriQuery.cs b/src/WebExpress.WebCore/WebUri/UriQuery.cs
index ebf5b07..21e3bb2 100644
--- a/src/WebExpress.WebCore/WebUri/UriQuery.cs
+++ b/src/WebExpress.WebCore/WebUri/UriQuery.cs
@@ -41,12 +41,12 @@ public override string ToString()
///
/// Represents a key-value pair used as a query parameter in a URI.
///
- ///
+ ///
/// The type that implements the IParameterStatic interface and defines the structure
/// of the query parameter.
///
- public class UriQuery : IUriQuery
- where TParamerer : IParameterStatic
+ public class UriQuery : IUriQuery
+ where TParameter : IParameterStatic
{
///
/// Returns the key.
@@ -64,7 +64,7 @@ public class UriQuery : IUriQuery
/// The value.
public UriQuery(string value = null)
{
- Key = TParamerer.Key;
+ Key = TParameter.Key;
Value = value;
}