From e6cdfb852102eaa025fe34b27a5055cc89ae7588 Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Sun, 4 Aug 2024 23:15:48 -0400 Subject: [PATCH] support POST form data --- src/lib/MBS.Web/Control.cs | 11 +++++-- src/lib/MBS.Web/UI/ThemeColorPreset.cs | 9 ++++++ src/lib/MBS.Web/UI/WebControl.cs | 13 ++++++++ src/lib/MBS.Web/WebHeaderCollection.cs | 34 ++++++++++---------- src/lib/MBS.Web/WebRequest.cs | 6 +++- src/lib/MBS.Web/WebServer.cs | 44 +++++++++++++++++++++++--- 6 files changed, 91 insertions(+), 26 deletions(-) create mode 100644 src/lib/MBS.Web/UI/ThemeColorPreset.cs diff --git a/src/lib/MBS.Web/Control.cs b/src/lib/MBS.Web/Control.cs index 13b03af..da34d3d 100644 --- a/src/lib/MBS.Web/Control.cs +++ b/src/lib/MBS.Web/Control.cs @@ -32,6 +32,11 @@ public abstract class Control : IWebHandler public Dictionary Attributes { get; } = new Dictionary(); public CssClassList ClassList { get; } = new CssClassList(); + protected virtual IEnumerable GetStyleClasses() + { + return new string[0]; + } + private bool _initted = false; protected void EnsureInitialized() { @@ -57,15 +62,17 @@ public abstract class Control : IWebHandler if (kvp.Key == "class") { IEnumerable classList = ClassList.Union(kvp.Value.Split(new char[] { ' ' })); + value = String.Join(' ', classList); classListWritten = true; } writer.WriteAttributeString(kvp.Key, value); } - if (!classListWritten && ClassList.Count > 0) + IEnumerable actualClassList = ClassList.Union(GetStyleClasses()); + if (!classListWritten && actualClassList.Count() > 0) { - writer.WriteAttributeString("class", String.Join(' ', ClassList)); + writer.WriteAttributeString("class", String.Join(' ', actualClassList)); } } protected virtual void RenderEndTag(XmlWriter writer) diff --git a/src/lib/MBS.Web/UI/ThemeColorPreset.cs b/src/lib/MBS.Web/UI/ThemeColorPreset.cs new file mode 100644 index 0000000..c3f9957 --- /dev/null +++ b/src/lib/MBS.Web/UI/ThemeColorPreset.cs @@ -0,0 +1,9 @@ +namespace MBS.Web.UI; + +public enum ThemeColorPreset +{ + Unspecified = 0, + Primary, + Warning, + Danger +} \ No newline at end of file diff --git a/src/lib/MBS.Web/UI/WebControl.cs b/src/lib/MBS.Web/UI/WebControl.cs index bb80c9a..8016756 100644 --- a/src/lib/MBS.Web/UI/WebControl.cs +++ b/src/lib/MBS.Web/UI/WebControl.cs @@ -18,6 +18,19 @@ public abstract class WebControl : Control } } public string ClientId { get { return String.Format("UWT{0}", NanoIdString); } } + public ThemeColorPreset ThemeColorPreset { get; set;} = ThemeColorPreset.Unspecified; + + protected override IEnumerable GetStyleClasses() + { + List styleClasses = new List(); + switch (ThemeColorPreset) + { + case ThemeColorPreset.Primary: styleClasses.Add("uwt-color-primary"); break; + case ThemeColorPreset.Warning: styleClasses.Add("uwt-color-warning"); break; + case ThemeColorPreset.Danger: styleClasses.Add("uwt-color-danger"); break; + } + return styleClasses; + } protected override IDictionary GetControlAttributes() { diff --git a/src/lib/MBS.Web/WebHeaderCollection.cs b/src/lib/MBS.Web/WebHeaderCollection.cs index 2ae349f..cff1780 100644 --- a/src/lib/MBS.Web/WebHeaderCollection.cs +++ b/src/lib/MBS.Web/WebHeaderCollection.cs @@ -3,9 +3,8 @@ using MBS.Core; namespace MBS.Web; -public class WebHeaderCollection : List> +public class WebHeaderCollection : Dictionary> { - private Dictionary> _list = new Dictionary>(); public string? this[System.Net.HttpRequestHeader key] { get @@ -35,51 +34,50 @@ public class WebHeaderCollection : List> } } - public string? this[string key] + public new string this[string key] { get { - if (_list.ContainsKey(key)) + if (base.ContainsKey(key)) { - if (_list[key].Count > 0) + if (base[key].Count > 0) { - return _list[key][_list[key].Count - 1]; + return base[key][base[key].Count - 1]; } } - return null; + return String.Empty; } set { - if (!_list.ContainsKey(key)) + if (!base.ContainsKey(key)) { - _list[key] = new List(); + base[key] = new List(); } - if (!_list[key].Contains(value)) + if (!base[key].Contains(value)) { - _list[key].Add(value); + base[key].Add(value); } } } public IReadOnlyList GetValues(string key) { - return _list[key]; + return base[key]; } public void Add(string key, string value) { Add(new KeyValuePair(key, value)); } - public new void Add(KeyValuePair value) + public void Add(KeyValuePair value) { - if (!_list.ContainsKey(value.Key)) + if (!base.ContainsKey(value.Key)) { - _list[value.Key] = new List(); + base[value.Key] = new List(); } - if (!_list[value.Key].Contains(value.Value)) + if (!base[value.Key].Contains(value.Value)) { - _list[value.Key].Add(value.Value); + base[value.Key].Add(value.Value); } - base.Add(value); } } diff --git a/src/lib/MBS.Web/WebRequest.cs b/src/lib/MBS.Web/WebRequest.cs index 1d04edb..3881936 100644 --- a/src/lib/MBS.Web/WebRequest.cs +++ b/src/lib/MBS.Web/WebRequest.cs @@ -1,3 +1,4 @@ +using System.Collections.ObjectModel; using System.Net; namespace MBS.Web; @@ -13,7 +14,9 @@ public class WebRequest public Dictionary PathVariables { get; } public WebHeaderCollection Headers { get; } - public WebRequest(string version, string method, string path, WebHeaderCollection headers, Dictionary pathVariables) + public ReadOnlyDictionary Form { get; } + + public WebRequest(string version, string method, string path, WebHeaderCollection headers, Dictionary pathVariables, Dictionary form) { Version = version; Method = method; @@ -24,5 +27,6 @@ public class WebRequest } Headers = headers; PathVariables = pathVariables; + Form = new ReadOnlyDictionary(form); } } diff --git a/src/lib/MBS.Web/WebServer.cs b/src/lib/MBS.Web/WebServer.cs index 8479d6b..5bad89c 100644 --- a/src/lib/MBS.Web/WebServer.cs +++ b/src/lib/MBS.Web/WebServer.cs @@ -1,4 +1,6 @@ using System.Net; +using System.Net.Sockets; +using System.Security.Cryptography.X509Certificates; using System.Text; using MBS.Core; using MBS.Web.UI; @@ -86,9 +88,12 @@ public class WebServer { sw.WriteLine(String.Format("{0}: {1}", header.Key, header.Value)); } - foreach (KeyValuePair header in context.Response.Headers) + foreach (KeyValuePair> header in context.Response.Headers) { - sw.WriteLine(String.Format("{0}: {1}", header.Key, header.Value)); + foreach (string val in header.Value) + { + sw.WriteLine(String.Format("{0}: {1}", header.Key, val)); + } } foreach (WebCookie cookie in context.Response.Cookies) { @@ -139,8 +144,11 @@ public class WebServer return; } */ + // client.ReceiveTimeout = 5000; + // client.SendTimeout = 5000; - StreamReader sr = new StreamReader(client.GetStream()); + NetworkStream st = client.GetStream(); + StreamReader sr = new StreamReader(st); string line = sr.ReadLine(); if (line == null) { @@ -164,6 +172,8 @@ public class WebServer while (true) { string headerLine = sr.ReadLine(); + Console.WriteLine(headerLine); + if (String.IsNullOrEmpty(headerLine)) break; @@ -171,7 +181,28 @@ public class WebServer if (headerParts.Length != 2) continue; - headers[headerParts[0]] = headerParts[1]; + headers[headerParts[0].Trim()] = headerParts[1].Trim(); + + Console.WriteLine("remaining: {0}", client.Available); + } + + Dictionary form = new Dictionary(); + + string contentLength = headers["Content-Length"]; + if (contentLength != "") + { + int contentLengthInt = Int32.Parse(contentLength); + + char[] buffer = new char[contentLengthInt]; + sr.ReadBlock(buffer, 0, contentLengthInt); + + string content = new string(buffer); + string[] kvps = content.Split(new char[] { '&' }); + foreach (string kvp in kvps) + { + string[] pv = kvp.Split(new char[] { '=' }); + form[pv[0]] = pv[1]; + } } if (headers[HttpRequestHeader.Cookie] != null) @@ -181,7 +212,8 @@ public class WebServer bool found = false; Dictionary pathVariables = new Dictionary(); - WebContext context = new WebContext((WebApplication)Application.Instance, new WebRequest(version, requestMethod, path, headers, pathVariables), new WebResponse()); + + WebContext context = new WebContext((WebApplication)Application.Instance, new WebRequest(version, requestMethod, path, headers, pathVariables, form), new WebResponse()); context.Response.Cookies.Add("JSESSIONID", "0068F5AD24A89AB4AFCC4057F619EADF.authgwy-prod-mzzygbiy.prod-ui-auth.pr502.cust.pdx.wd", WebCookieScope.FromPath("/"), WebCookieSecurity.Secure | WebCookieSecurity.HttpOnly, WebCookieSameSite.None); WebServerProcessRequestEventArgs e = new WebServerProcessRequestEventArgs(client, context); @@ -232,10 +264,12 @@ public class WebServer catch (System.Net.Sockets.SocketException ex) { Console.Error.WriteLine("caught SocketException; ignoring"); + Console.Error.WriteLine(ex.Message); } catch (System.IO.IOException ex) { Console.Error.WriteLine("caught IOException; ignoring"); + Console.Error.WriteLine(ex.Message); } }