diff --git a/src/http/interfaces/IHTTP.Map.cs b/src/http/interfaces/IHTTP.Map.cs index bd8546eb..e023a406 100644 --- a/src/http/interfaces/IHTTP.Map.cs +++ b/src/http/interfaces/IHTTP.Map.cs @@ -11,70 +11,70 @@ public interface Map /// /// Request Path /// Response Callback - void WebSocket(string path, Action callback); + void WebSocket(string path, Action callback); /// /// Handle All Http Method from Path /// /// Request Path /// Response Callback - void All(string path, Action callback); + void All(string path, Action callback); /// /// Handle (Get) Http Method /// /// Request Path /// Response Callback - void Get(string path, Action callback); + void Get(string path, Action callback); /// /// Handle (Put) Http Method /// /// Request Path /// Response Callback - void Put(string path, Action callback); + void Put(string path, Action callback); /// /// Handle (Head) Http Method /// /// Request Path /// Response Callback - void Head(string path, Action callback); + void Head(string path, Action callback); /// /// Handle (Post) Http Method /// /// Request Path /// Response Callback - void Post(string path, Action callback); + void Post(string path, Action callback); /// /// Handle (Patch) Http Method /// /// Request Path /// Response Callback - void Patch(string path, Action callback); + void Patch(string path, Action callback); /// /// Handle (Delete) Http Method /// /// Request Path /// Response Callback - void Delete(string path, Action callback); + void Delete(string path, Action callback); /// /// Handle (Trace) Http Method /// /// Request Path /// Response Callback - void Trace(string path, Action callback); + void Trace(string path, Action callback); /// /// Handle (Options) Http Method /// /// Request Path /// Response Callback - void Options(string path, Action callback); + void Options(string path, Action callback); } } } \ No newline at end of file diff --git a/src/http/interfaces/IHTTP.Middleware.cs b/src/http/interfaces/IHTTP.Middleware.cs index 5d2e6316..fa6ab581 100644 --- a/src/http/interfaces/IHTTP.Middleware.cs +++ b/src/http/interfaces/IHTTP.Middleware.cs @@ -16,7 +16,7 @@ public interface Middleware /// /// Middleware handler /// true if callback added successful - bool Add(Func middleware); + bool Add(Func middleware); /// /// Add local middleware handler @@ -25,7 +25,7 @@ public interface Middleware /// Middleware handler /// true if callback added successful /// - bool Add(string path, Func middleware); + bool Add(string path, Func middleware); } } } \ No newline at end of file diff --git a/src/http/interfaces/IHTTP.MiddlewareDescriptor.cs b/src/http/interfaces/IHTTP.MiddlewareDescriptor.cs index f8b7b5fa..5972313e 100644 --- a/src/http/interfaces/IHTTP.MiddlewareDescriptor.cs +++ b/src/http/interfaces/IHTTP.MiddlewareDescriptor.cs @@ -22,7 +22,7 @@ public interface MiddlewareDescriptor /// /// Handler callback /// - Func Callback { get; } + Func Callback { get; } } } } \ No newline at end of file diff --git a/src/http/interfaces/IHTTP.Request.cs b/src/http/interfaces/IHTTP.ServerRequest.cs similarity index 92% rename from src/http/interfaces/IHTTP.Request.cs rename to src/http/interfaces/IHTTP.ServerRequest.cs index 526b50eb..21a83b0d 100644 --- a/src/http/interfaces/IHTTP.Request.cs +++ b/src/http/interfaces/IHTTP.ServerRequest.cs @@ -7,7 +7,7 @@ namespace Netly.Interfaces { public static partial class IHTTP { - public interface Request + public interface ServerRequest { /// /// Request encoding @@ -78,6 +78,11 @@ public interface Request /// Request Body /// Body Body { get; } + + /// + /// Request Enctype + /// + HTTP.Enctype Enctype { get; } /// diff --git a/src/http/interfaces/IHTTP.WebSocket.cs b/src/http/interfaces/IHTTP.WebSocket.cs index 39f3808a..7e7f9781 100644 --- a/src/http/interfaces/IHTTP.WebSocket.cs +++ b/src/http/interfaces/IHTTP.WebSocket.cs @@ -10,7 +10,7 @@ public interface WebSocket /// /// Connection request /// - Request Request { get; } + ServerRequest ServerRequest { get; } /// /// Connection Headers diff --git a/src/http/partials/Server/HTTP.Middleware.cs b/src/http/partials/Server/HTTP.Middleware.cs index 92742c35..3d39ebd3 100644 --- a/src/http/partials/Server/HTTP.Middleware.cs +++ b/src/http/partials/Server/HTTP.Middleware.cs @@ -21,12 +21,12 @@ public Middleware(Server server) public IHTTP.MiddlewareDescriptor[] Middlewares => _middlewares.ToArray(); - public bool Add(Func middleware) + public bool Add(Func middleware) { return Add(GlobalPath, middleware); } - public bool Add(string path, Func middleware) + public bool Add(string path, Func middleware) { if (middleware == null) return false; diff --git a/src/http/partials/Server/HTTP.MiddlewareDescriptor.cs b/src/http/partials/Server/HTTP.MiddlewareDescriptor.cs index 8065dc8c..e362d721 100644 --- a/src/http/partials/Server/HTTP.MiddlewareDescriptor.cs +++ b/src/http/partials/Server/HTTP.MiddlewareDescriptor.cs @@ -9,10 +9,10 @@ internal struct MiddlewareDescriptor : IHTTP.MiddlewareDescriptor { public string Path { get; } public bool UseParams { get; } - public Func Callback { get; } + public Func Callback { get; } public MiddlewareDescriptor(string path, bool useParams, - Func callback) + Func callback) { Path = path; UseParams = useParams; diff --git a/src/http/partials/Server/HTTP.Request.cs b/src/http/partials/Server/HTTP.Request.cs index 91e7042d..051dbe0d 100644 --- a/src/http/partials/Server/HTTP.Request.cs +++ b/src/http/partials/Server/HTTP.Request.cs @@ -12,7 +12,7 @@ namespace Netly { public partial class HTTP { - internal class ServerRequest : IHTTP.Request + internal class ServerRequest : IHTTP.ServerRequest { internal ServerRequest(HttpListenerRequest request) { @@ -61,8 +61,7 @@ internal ServerRequest(HttpListenerRequest request) Encoding = request.ContentEncoding; - // TODO: detect enctype from Header - var enctype = Enctype.None; + var enctype = GetEnctypeFromHeader(); var buffer = new byte[request.ContentLength64]; _ = request.InputStream.Read(buffer, 0, buffer.Length); @@ -103,7 +102,7 @@ internal ServerRequest(ClientWebSocket ws, Uri uri, Dictionary h Status = -1; // Not applicable - Method = HttpMethod.Head; + Method = HttpMethod.Get; Url = uri.AbsoluteUri; @@ -121,11 +120,9 @@ internal ServerRequest(ClientWebSocket ws, Uri uri, Dictionary h IsEncrypted = uri.IsAbsoluteUri && uri.Scheme.ToUpper() == "WSS"; - // Not applicable - Encoding = Encoding.UTF8; + Encoding = GetEncodingFromHeader(); - // Not applicable - var enctype = Enctype.None; + var enctype = GetEnctypeFromHeader(); // Not applicable var buffer = Array.Empty(); @@ -198,11 +195,9 @@ internal ServerRequest(HttpResponseMessage message) IsEncrypted = uri.IsAbsoluteUri && uri.Scheme.ToUpper() == "HTTPS"; - // TODO: detect encoding from Header - Encoding = Encoding.UTF8; + Encoding = GetEncodingFromHeader(); - // TODO: detect enctype from Header - var enctype = Enctype.None; + var enctype = GetEnctypeFromHeader(); var buffer = message.Content.ReadAsByteArrayAsync().Result; Body = new Body(buffer, enctype, Encoding); @@ -223,6 +218,7 @@ internal ServerRequest(HttpResponseMessage message) public bool IsLocalRequest { get; } public bool IsEncrypted { get; } public IHTTP.Body Body { get; } + public Enctype Enctype { get; } public int Status { get; } /// @@ -236,6 +232,40 @@ private void SetQueriesFromUri(Uri uri) foreach (var queryName in queryBuilder.AllKeys) Queries.Add(queryName, queryBuilder[queryName]); } + + private Encoding GetEncodingFromHeader() + { + var comparisonType = StringComparison.InvariantCultureIgnoreCase; + var value = Headers.FirstOrDefault(x => x.Key.Equals("Content-Type", comparisonType)); + var key = (value.Value ?? string.Empty).ToUpper(); + + if (string.IsNullOrWhiteSpace(key)) return Encoding.UTF8; + + // generic + if (key.Contains("UTF-8")) return Encoding.UTF8; + if (key.Contains("ISO-8859-1")) return Encoding.GetEncoding("ISO-8859-1"); + if (key.Contains("ASCII")) return Encoding.ASCII; + if (key.Contains("UTF-16")) return Encoding.Unicode; + if (key.Contains("UTF-32")) return Encoding.UTF32; + + // https://en.wikipedia.org/wiki/Character_encodings_in_HTML + return Encoding.UTF8; + } + + private Enctype GetEnctypeFromHeader() + { + var comparisonType = StringComparison.InvariantCultureIgnoreCase; + var value = Headers.FirstOrDefault(x => x.Key.Equals("Content-Type", comparisonType)); + var key = (value.Value ?? string.Empty).ToUpper(); + + if (string.IsNullOrWhiteSpace(key)) return Enctype.None; + + if (key.Contains("application/x-www-form-urlencoded")) return Enctype.UrlEncoded; + if (key.Contains("multipart/form-data")) return Enctype.Multipart; + if (key.Contains("text/plain")) return Enctype.PlainText; + + return Enctype.None; + } } } } \ No newline at end of file diff --git a/src/http/partials/Server/Map.cs b/src/http/partials/Server/Map.cs index 9eb1f5ba..252bd7f8 100644 --- a/src/http/partials/Server/Map.cs +++ b/src/http/partials/Server/Map.cs @@ -21,7 +21,7 @@ public Map(Server server) m_mapList = new List(); } - public void WebSocket(string path, Action callback) + public void WebSocket(string path, Action callback) { Add ( @@ -33,7 +33,7 @@ public void WebSocket(string path, Action callba ); } - public void All(string path, Action callback) + public void All(string path, Action callback) { Add ( @@ -45,7 +45,7 @@ public void All(string path, Action callbac ); } - public void Get(string path, Action callback) + public void Get(string path, Action callback) { Add ( @@ -57,7 +57,7 @@ public void Get(string path, Action callbac ); } - public void Put(string path, Action callback) + public void Put(string path, Action callback) { Add ( @@ -69,7 +69,7 @@ public void Put(string path, Action callbac ); } - public void Head(string path, Action callback) + public void Head(string path, Action callback) { Add ( @@ -81,7 +81,7 @@ public void Head(string path, Action callba ); } - public void Post(string path, Action callback) + public void Post(string path, Action callback) { Add ( @@ -93,7 +93,7 @@ public void Post(string path, Action callba ); } - public void Patch(string path, Action callback) + public void Patch(string path, Action callback) { Add ( @@ -106,7 +106,7 @@ public void Patch(string path, Action callb ); } - public void Delete(string path, Action callback) + public void Delete(string path, Action callback) { Add ( @@ -118,7 +118,7 @@ public void Delete(string path, Action call ); } - public void Trace(string path, Action callback) + public void Trace(string path, Action callback) { Add ( @@ -130,7 +130,7 @@ public void Trace(string path, Action callb ); } - public void Options(string path, Action callback) + public void Options(string path, Action callback) { Add ( @@ -147,8 +147,8 @@ private void Add string path, string method, bool isWebsocket, - Action httpCallback, - Action websocketCallback + Action httpCallback, + Action websocketCallback ) { path = (path ?? string.Empty).Trim(); @@ -178,8 +178,8 @@ internal struct MapContainer public string Path { get; } public string Method { get; } public bool IsWebsocket { get; } - public Action HttpCallback { get; } - public Action WebsocketCallback { get; } + public Action HttpCallback { get; } + public Action WebsocketCallback { get; } public MapContainer ( @@ -187,8 +187,8 @@ public MapContainer bool useParams, string method, bool isWebsocket, - Action httpCallback, - Action websocketCallback + Action httpCallback, + Action websocketCallback ) { Path = path; diff --git a/src/http/partials/Websocket/HTTP.WebSocket.cs b/src/http/partials/Websocket/HTTP.WebSocket.cs index 855b16a2..479e9d12 100644 --- a/src/http/partials/Websocket/HTTP.WebSocket.cs +++ b/src/http/partials/Websocket/HTTP.WebSocket.cs @@ -23,13 +23,13 @@ public WebSocket() /// Create Server Side Client Instance /// /// - /// - internal WebSocket(System.Net.WebSockets.WebSocket serverSocket, IHTTP.Request request) + /// + internal WebSocket(System.Net.WebSockets.WebSocket serverSocket, IHTTP.ServerRequest serverRequest) { - _to = new WebsocketTo(this, serverSocket, request); + _to = new WebsocketTo(this, serverSocket, serverRequest); } - public IHTTP.Request Request => _to.MyRequest; + public IHTTP.ServerRequest ServerRequest => _to.MyServerRequest; public Dictionary Headers => _to.Headers; public Uri Host => _to.MyUri; public bool IsOpened => _to.IsConnected(); diff --git a/src/http/partials/Websocket/HTTP.WebSocketTo.cs b/src/http/partials/Websocket/HTTP.WebSocketTo.cs index d9f3c52d..4186096d 100644 --- a/src/http/partials/Websocket/HTTP.WebSocketTo.cs +++ b/src/http/partials/Websocket/HTTP.WebSocketTo.cs @@ -27,18 +27,18 @@ public WebsocketTo(WebSocket socket) _tryConnecting = false; _tryClosing = false; _isServerSide = false; - MyRequest = null; + MyServerRequest = null; } - public WebsocketTo(WebSocket socket, System.Net.WebSockets.WebSocket websocket, IHTTP.Request myRequest) + public WebsocketTo(WebSocket socket, System.Net.WebSockets.WebSocket websocket, IHTTP.ServerRequest myServerRequest) { _socket = socket; _isServerSide = true; _websocketServerSide = websocket; - MyRequest = myRequest; + MyServerRequest = myServerRequest; } - public IHTTP.Request MyRequest { get; private set; } + public IHTTP.ServerRequest MyServerRequest { get; private set; } public Task Open(Uri host) { @@ -58,7 +58,7 @@ public Task Open(Uri host) await ws.ConnectAsync(host, CancellationToken.None); - MyRequest = new ServerRequest(ws, host, Headers); + MyServerRequest = new ServerRequest(ws, host, Headers); MyUri = host;