support POST form data

This commit is contained in:
Michael Becker 2024-08-04 23:15:48 -04:00
parent 0750456c5f
commit e6cdfb8521
6 changed files with 91 additions and 26 deletions

View File

@ -32,6 +32,11 @@ public abstract class Control : IWebHandler
public Dictionary<string, string> Attributes { get; } = new Dictionary<string, string>(); public Dictionary<string, string> Attributes { get; } = new Dictionary<string, string>();
public CssClassList ClassList { get; } = new CssClassList(); public CssClassList ClassList { get; } = new CssClassList();
protected virtual IEnumerable<string> GetStyleClasses()
{
return new string[0];
}
private bool _initted = false; private bool _initted = false;
protected void EnsureInitialized() protected void EnsureInitialized()
{ {
@ -57,15 +62,17 @@ public abstract class Control : IWebHandler
if (kvp.Key == "class") if (kvp.Key == "class")
{ {
IEnumerable<string> classList = ClassList.Union(kvp.Value.Split(new char[] { ' ' })); IEnumerable<string> classList = ClassList.Union(kvp.Value.Split(new char[] { ' ' }));
value = String.Join(' ', classList); value = String.Join(' ', classList);
classListWritten = true; classListWritten = true;
} }
writer.WriteAttributeString(kvp.Key, value); writer.WriteAttributeString(kvp.Key, value);
} }
if (!classListWritten && ClassList.Count > 0) IEnumerable<string> 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) protected virtual void RenderEndTag(XmlWriter writer)

View File

@ -0,0 +1,9 @@
namespace MBS.Web.UI;
public enum ThemeColorPreset
{
Unspecified = 0,
Primary,
Warning,
Danger
}

View File

@ -18,6 +18,19 @@ public abstract class WebControl : Control
} }
} }
public string ClientId { get { return String.Format("UWT{0}", NanoIdString); } } public string ClientId { get { return String.Format("UWT{0}", NanoIdString); } }
public ThemeColorPreset ThemeColorPreset { get; set;} = ThemeColorPreset.Unspecified;
protected override IEnumerable<string> GetStyleClasses()
{
List<string> styleClasses = new List<string>();
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<string, string> GetControlAttributes() protected override IDictionary<string, string> GetControlAttributes()
{ {

View File

@ -3,9 +3,8 @@ using MBS.Core;
namespace MBS.Web; namespace MBS.Web;
public class WebHeaderCollection : List<KeyValuePair<string, string>> public class WebHeaderCollection : Dictionary<string, List<string>>
{ {
private Dictionary<string, List<string>> _list = new Dictionary<string, List<string>>();
public string? this[System.Net.HttpRequestHeader key] public string? this[System.Net.HttpRequestHeader key]
{ {
get get
@ -35,51 +34,50 @@ public class WebHeaderCollection : List<KeyValuePair<string, string>>
} }
} }
public string? this[string key] public new string this[string key]
{ {
get 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 set
{ {
if (!_list.ContainsKey(key)) if (!base.ContainsKey(key))
{ {
_list[key] = new List<string>(); base[key] = new List<string>();
} }
if (!_list[key].Contains(value)) if (!base[key].Contains(value))
{ {
_list[key].Add(value); base[key].Add(value);
} }
} }
} }
public IReadOnlyList<string> GetValues(string key) public IReadOnlyList<string> GetValues(string key)
{ {
return _list[key]; return base[key];
} }
public void Add(string key, string value) public void Add(string key, string value)
{ {
Add(new KeyValuePair<string, string>(key, value)); Add(new KeyValuePair<string, string>(key, value));
} }
public new void Add(KeyValuePair<string, string> value) public void Add(KeyValuePair<string, string> value)
{ {
if (!_list.ContainsKey(value.Key)) if (!base.ContainsKey(value.Key))
{ {
_list[value.Key] = new List<string>(); base[value.Key] = new List<string>();
} }
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);
} }
} }

View File

@ -1,3 +1,4 @@
using System.Collections.ObjectModel;
using System.Net; using System.Net;
namespace MBS.Web; namespace MBS.Web;
@ -13,7 +14,9 @@ public class WebRequest
public Dictionary<string, string> PathVariables { get; } public Dictionary<string, string> PathVariables { get; }
public WebHeaderCollection Headers { get; } public WebHeaderCollection Headers { get; }
public WebRequest(string version, string method, string path, WebHeaderCollection headers, Dictionary<string, string> pathVariables) public ReadOnlyDictionary<string, string> Form { get; }
public WebRequest(string version, string method, string path, WebHeaderCollection headers, Dictionary<string, string> pathVariables, Dictionary<string, string> form)
{ {
Version = version; Version = version;
Method = method; Method = method;
@ -24,5 +27,6 @@ public class WebRequest
} }
Headers = headers; Headers = headers;
PathVariables = pathVariables; PathVariables = pathVariables;
Form = new ReadOnlyDictionary<string, string>(form);
} }
} }

View File

@ -1,4 +1,6 @@
using System.Net; using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography.X509Certificates;
using System.Text; using System.Text;
using MBS.Core; using MBS.Core;
using MBS.Web.UI; using MBS.Web.UI;
@ -86,9 +88,12 @@ public class WebServer
{ {
sw.WriteLine(String.Format("{0}: {1}", header.Key, header.Value)); sw.WriteLine(String.Format("{0}: {1}", header.Key, header.Value));
} }
foreach (KeyValuePair<string, string> header in context.Response.Headers) foreach (KeyValuePair<string, List<string>> 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) foreach (WebCookie cookie in context.Response.Cookies)
{ {
@ -139,8 +144,11 @@ public class WebServer
return; 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(); string line = sr.ReadLine();
if (line == null) if (line == null)
{ {
@ -164,6 +172,8 @@ public class WebServer
while (true) while (true)
{ {
string headerLine = sr.ReadLine(); string headerLine = sr.ReadLine();
Console.WriteLine(headerLine);
if (String.IsNullOrEmpty(headerLine)) if (String.IsNullOrEmpty(headerLine))
break; break;
@ -171,7 +181,28 @@ public class WebServer
if (headerParts.Length != 2) if (headerParts.Length != 2)
continue; continue;
headers[headerParts[0]] = headerParts[1]; headers[headerParts[0].Trim()] = headerParts[1].Trim();
Console.WriteLine("remaining: {0}", client.Available);
}
Dictionary<string, string> form = new Dictionary<string, string>();
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) if (headers[HttpRequestHeader.Cookie] != null)
@ -181,7 +212,8 @@ public class WebServer
bool found = false; bool found = false;
Dictionary<string, string> pathVariables = new Dictionary<string, string>(); Dictionary<string, string> pathVariables = new Dictionary<string, string>();
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); 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); WebServerProcessRequestEventArgs e = new WebServerProcessRequestEventArgs(client, context);
@ -232,10 +264,12 @@ public class WebServer
catch (System.Net.Sockets.SocketException ex) catch (System.Net.Sockets.SocketException ex)
{ {
Console.Error.WriteLine("caught SocketException; ignoring"); Console.Error.WriteLine("caught SocketException; ignoring");
Console.Error.WriteLine(ex.Message);
} }
catch (System.IO.IOException ex) catch (System.IO.IOException ex)
{ {
Console.Error.WriteLine("caught IOException; ignoring"); Console.Error.WriteLine("caught IOException; ignoring");
Console.Error.WriteLine(ex.Message);
} }
} }