fix some issues in HTTP server and try to implement SSL
This commit is contained in:
parent
05c3fd5274
commit
0054320a0e
@ -18,7 +18,7 @@ public class Button : WebControlWithMnemonic
|
||||
{
|
||||
if (DropDown != null)
|
||||
{
|
||||
return base.GetStyleClasses().Union(["uwt-button-dropdownbutton"]);
|
||||
return base.GetStyleClasses().Union(new string[] { "uwt-button-dropdownbutton" });
|
||||
}
|
||||
return base.GetStyleClasses();
|
||||
}
|
||||
|
||||
@ -4,7 +4,7 @@ namespace MBS.Web.UI.WebControls;
|
||||
|
||||
public abstract class ContainerBase : WebControl
|
||||
{
|
||||
private IEnumerable<Control> _list = [ ];
|
||||
private IEnumerable<Control> _list = new Control[0];
|
||||
protected virtual IEnumerable<Control> GetChildControls()
|
||||
{
|
||||
return _list;
|
||||
|
||||
@ -47,7 +47,7 @@ public class DockableContainer : Container
|
||||
|
||||
public CardinalDirection Position { get; set; } = CardinalDirection.Bottom;
|
||||
protected override IEnumerable<string> GetStyleClasses()
|
||||
{
|
||||
{
|
||||
string uwtDockPosition = "";
|
||||
switch (Position)
|
||||
{
|
||||
@ -56,7 +56,7 @@ public class DockableContainer : Container
|
||||
case CardinalDirection.Right: uwtDockPosition = "uwt-dock-right"; break;
|
||||
case CardinalDirection.Bottom: uwtDockPosition = "uwt-dock-bottom"; break;
|
||||
}
|
||||
return base.GetStyleClasses().Union([ "uwt-dockable", uwtDockPosition ]);
|
||||
return base.GetStyleClasses().Union(new string[] { "uwt-dockable", uwtDockPosition });
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ public class ListView : Container
|
||||
|
||||
protected override IEnumerable<string> GetStyleClasses()
|
||||
{
|
||||
return [ "uwt-listview" ];
|
||||
return new string[] { "uwt-listview" };
|
||||
}
|
||||
protected override IReadOnlyDictionary<string, string> GetStyleProperties()
|
||||
{
|
||||
|
||||
@ -6,7 +6,7 @@ public class Menu : ContainerBase
|
||||
protected override string TagName => "ul";
|
||||
protected override IEnumerable<string> GetStyleClasses()
|
||||
{
|
||||
return [ "uwt-menu" ];
|
||||
return new string[] { "uwt-menu" };
|
||||
}
|
||||
|
||||
private IEnumerable<MenuItem>? _items = null;
|
||||
@ -25,7 +25,7 @@ public class Menu : ContainerBase
|
||||
{
|
||||
return _items;
|
||||
}
|
||||
return [];
|
||||
return new Control[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -27,14 +27,14 @@ public abstract class MenuItem : ContainerBase
|
||||
|
||||
protected override IEnumerable<string> GetStyleClasses()
|
||||
{
|
||||
return base.GetStyleClasses().Union(["uwt-menu-item"]);
|
||||
return base.GetStyleClasses().Union(new string[] { "uwt-menu-item" });
|
||||
}
|
||||
}
|
||||
public class CommandMenuItem : MenuItem
|
||||
{
|
||||
protected override IEnumerable<string> GetStyleClasses()
|
||||
{
|
||||
return base.GetStyleClasses().Union(["uwt-menu-item-command"]);
|
||||
return base.GetStyleClasses().Union(new string[] { "uwt-menu-item-command" });
|
||||
}
|
||||
|
||||
public string Text { get; set; }
|
||||
@ -55,7 +55,7 @@ public class CommandMenuItem : MenuItem
|
||||
{
|
||||
a.TargetUrl = TargetUrl;
|
||||
}
|
||||
return [a];
|
||||
return new Control[] { a };
|
||||
}
|
||||
|
||||
}
|
||||
@ -39,7 +39,7 @@ public class WebPage : Control
|
||||
|
||||
protected virtual IEnumerable<Control> GetHeaderControls()
|
||||
{
|
||||
return [ ];
|
||||
return new Control[0];
|
||||
}
|
||||
|
||||
protected override string TagName => "html";
|
||||
|
||||
@ -24,7 +24,7 @@ public abstract class WebApplication : Application
|
||||
ProcessRequest?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private void server_OnProcessRequest(object sender, WebServerProcessRequestEventArgs e)
|
||||
private void server_OnProcessRequest(object? sender, WebServerProcessRequestEventArgs e)
|
||||
{
|
||||
OnProcessRequest(e);
|
||||
}
|
||||
@ -35,11 +35,16 @@ public abstract class WebApplication : Application
|
||||
ServerCreated?.Invoke(this, e);
|
||||
}
|
||||
|
||||
protected virtual WebServer CreateWebServer()
|
||||
{
|
||||
return new WebServer(new IPEndPoint(IPAddress.Any, DefaultPort));
|
||||
}
|
||||
|
||||
protected override void OnStartup(EventArgs e)
|
||||
{
|
||||
base.OnStartup(e);
|
||||
|
||||
WebServer server = new WebServer(new IPEndPoint(IPAddress.Any, DefaultPort));
|
||||
WebServer server = CreateWebServer();
|
||||
Console.WriteLine("attempting to start server listening on port {0}", DefaultPort);
|
||||
|
||||
OnServerCreated(new WebServerCreatedEventArgs(server));
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Data.SqlTypes;
|
||||
using System.Net;
|
||||
using MBS.Core;
|
||||
|
||||
namespace MBS.Web;
|
||||
|
||||
@ -31,12 +32,12 @@ public class WebRequest
|
||||
int queryStringIndex = path.IndexOf('?');
|
||||
if (queryStringIndex > -1)
|
||||
{
|
||||
Path = path.Substring(0, queryStringIndex);
|
||||
Path = path.Substring(0, queryStringIndex).UrlDecode();
|
||||
QueryString = path.Substring(queryStringIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
Path = path;
|
||||
Path = path.UrlDecode();
|
||||
}
|
||||
PathParts = Path.Split(new char[] { '/' });
|
||||
|
||||
@ -44,17 +45,18 @@ public class WebRequest
|
||||
foreach (string queryStringPart in queryStringParts)
|
||||
{
|
||||
string[] nameValue = queryStringPart.Split(new char[] { '=' });
|
||||
string key = nameValue[0].UrlDecode();
|
||||
if (nameValue.Length > 1)
|
||||
{
|
||||
if (!Query.ContainsKey(nameValue[0]))
|
||||
if (!Query.ContainsKey(key))
|
||||
{
|
||||
Query[nameValue[0]] = new List<string>();
|
||||
Query[key] = new List<string>();
|
||||
}
|
||||
Query[nameValue[0]].Add(nameValue[1]);
|
||||
Query[key].Add(nameValue[1].UrlDecode());
|
||||
}
|
||||
else
|
||||
{
|
||||
Query[nameValue[0]] = new List<string>();
|
||||
Query[key] = new List<string>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Authentication;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using MBS.Core;
|
||||
@ -160,6 +162,9 @@ public class WebServer
|
||||
|
||||
private Dictionary<string, Dictionary<string, object>> _sessions = new Dictionary<string, Dictionary<string, object>>();
|
||||
|
||||
public string? SSLCertificateFile = null;
|
||||
public string? SSLCertificateKeyFile = null;
|
||||
|
||||
private void HandleClient(System.Net.Sockets.TcpClient client)
|
||||
{
|
||||
// WebServerProcessRequestEventArgs e = new WebServerProcessRequestEventArgs();
|
||||
@ -174,9 +179,40 @@ public class WebServer
|
||||
// client.ReceiveTimeout = 5000;
|
||||
// client.SendTimeout = 5000;
|
||||
|
||||
NetworkStream st = client.GetStream();
|
||||
Stream st = client.GetStream();
|
||||
|
||||
if (ServerCertificate != null)
|
||||
{
|
||||
SslStream ssl = new SslStream(client.GetStream(), false);
|
||||
try
|
||||
{
|
||||
ssl.AuthenticateAsServer(ServerCertificate, false, SslProtocols.None, false);
|
||||
}
|
||||
catch (AuthenticationException ex)
|
||||
{
|
||||
Console.Error.WriteLine("AuthenticationException: {0}", ex.Message);
|
||||
}
|
||||
|
||||
st = ssl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("MBS.Web.WebServer: !! NOT using SSL !!");
|
||||
}
|
||||
|
||||
StreamReader sr = new StreamReader(st);
|
||||
/*
|
||||
byte[] buffer = new byte[4096];
|
||||
int len = st.Read(buffer, 0, buffer.Length);
|
||||
Array.Resize<byte>(ref buffer, len);
|
||||
|
||||
string text = System.Text.Encoding.UTF8.GetString(buffer);
|
||||
Console.WriteLine(text);
|
||||
*/
|
||||
|
||||
string line = sr.ReadLine();
|
||||
Console.Error.WriteLine(line);
|
||||
|
||||
if (line == null)
|
||||
{
|
||||
Console.Error.WriteLine("unexpected NULL line from client");
|
||||
@ -186,7 +222,7 @@ public class WebServer
|
||||
string[] lineParts = line.Split(new char[] { ' ' });
|
||||
if (lineParts.Length != 3)
|
||||
{
|
||||
Console.Error.WriteLine("unexpected request from client:\n----> {0}", line);
|
||||
Console.Error.WriteLine("unexpected request from client");
|
||||
client.Close();
|
||||
return;
|
||||
}
|
||||
@ -224,18 +260,21 @@ public class WebServer
|
||||
if (contentLength != "")
|
||||
{
|
||||
int contentLengthInt = Int32.Parse(contentLength);
|
||||
Console.Error.WriteLine("Content-Length: {0}", contentLengthInt);
|
||||
|
||||
char[] buffer = new char[contentLengthInt];
|
||||
sr.ReadBlock(buffer, 0, contentLengthInt);
|
||||
|
||||
string content = new string(buffer);
|
||||
Console.Error.WriteLine(content);
|
||||
|
||||
if (!String.IsNullOrEmpty(content))
|
||||
{
|
||||
string[] kvps = content.Split(new char[] { '&' });
|
||||
foreach (string kvp in kvps)
|
||||
{
|
||||
string[] pv = kvp.Split(new char[] { '=' });
|
||||
form[pv[0]] = pv[1].Replace('+', ' ');
|
||||
form[pv[0].UrlDecode()] = pv[1].UrlDecode().Replace('+', ' ');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -328,34 +367,39 @@ public class WebServer
|
||||
|
||||
client.Close();
|
||||
}
|
||||
private void tClientThread_ParameterizedThreadStart(object parm)
|
||||
private void tClientThread_ParameterizedThreadStart(object? parm)
|
||||
{
|
||||
System.Net.Sockets.TcpClient client = (System.Net.Sockets.TcpClient)parm;
|
||||
Console.WriteLine("Client connected");
|
||||
if (parm is System.Net.Sockets.TcpClient client)
|
||||
{
|
||||
Console.WriteLine("Client connected");
|
||||
|
||||
try
|
||||
{
|
||||
HandleClient(client);
|
||||
try
|
||||
{
|
||||
HandleClient(client);
|
||||
}
|
||||
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);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine("caught exception of type {0}", ex.GetType().FullName);
|
||||
Console.Error.WriteLine(ex.Message);
|
||||
Console.Error.WriteLine(ex.StackTrace);
|
||||
}
|
||||
|
||||
client.Close();
|
||||
}
|
||||
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);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.Error.WriteLine("caught exception of type {0}", ex.GetType().FullName);
|
||||
Console.Error.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
client.Close();
|
||||
}
|
||||
|
||||
public X509Certificate? ServerCertificate { get; private set; } = null;
|
||||
|
||||
private bool _Stopping = false;
|
||||
private Thread? tServer = null;
|
||||
public void Start()
|
||||
@ -365,6 +409,31 @@ public class WebServer
|
||||
|
||||
_Stopping = false;
|
||||
|
||||
|
||||
if (SSLCertificateFile != null && SSLCertificateKeyFile != null)
|
||||
{
|
||||
Console.WriteLine("MBS.Web.WebServer: using SSL :)");
|
||||
|
||||
if (!System.IO.File.Exists(SSLCertificateFile))
|
||||
{
|
||||
Console.Error.WriteLine("SSLCertificateFile not found: {0}", SSLCertificateFile);
|
||||
}
|
||||
else if (!System.IO.File.Exists(SSLCertificateKeyFile))
|
||||
{
|
||||
Console.Error.WriteLine("SSLCertificateKeyFile not found: {0}", SSLCertificateKeyFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
// assuming an 509 certificate has been loaded before in an init method of some sort
|
||||
// X509Certificate serverCertificate = X509Certificate2.CreateFromCertFile(SSLCertificateFile);
|
||||
ServerCertificate = X509Certificate2.CreateFromPemFile(SSLCertificateFile, SSLCertificateKeyFile);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("MBS.Web.WebServer: !! NOT using SSL !!");
|
||||
}
|
||||
|
||||
tServer = new Thread(tServer_ThreadStart);
|
||||
tServer.Start();
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user