2
0
mirror of https://github.com/esiur/esiur-dotnet.git synced 2025-06-27 13:33:13 +00:00

.Net 6 Upgrade

This commit is contained in:
2021-12-01 12:17:45 +03:00
parent 1166e93ba9
commit 530df018ec
164 changed files with 21247 additions and 21425 deletions

View File

@ -38,400 +38,399 @@ using Esiur.Misc;
using System.Security.Cryptography;
using Esiur.Core;
namespace Esiur.Net.HTTP
namespace Esiur.Net.HTTP;
public class HTTPConnection : NetworkConnection
{
public class HTTPConnection : NetworkConnection
public bool WSMode { get; internal set; }
public HTTPServer Server { get; internal set; }
public WebsocketPacket WSRequest { get; set; }
public HTTPRequestPacket Request { get; set; }
public HTTPResponsePacket Response { get; } = new HTTPResponsePacket();
HTTPSession session;
public KeyList<string, object> Variables { get; } = new KeyList<string, object>();
internal long Parse(byte[] data)
{
public bool WSMode { get; internal set; }
public HTTPServer Server { get; internal set; }
public WebsocketPacket WSRequest { get; set; }
public HTTPRequestPacket Request { get; set; }
public HTTPResponsePacket Response { get; } = new HTTPResponsePacket();
HTTPSession session;
public KeyList<string, object> Variables { get; } = new KeyList<string, object>();
internal long Parse(byte[] data)
if (WSMode)
{
if (WSMode)
// now parse WS protocol
WebsocketPacket ws = new WebsocketPacket();
var pSize = ws.Parse(data, 0, (uint)data.Length);
if (pSize > 0)
{
// now parse WS protocol
WebsocketPacket ws = new WebsocketPacket();
var pSize = ws.Parse(data, 0, (uint)data.Length);
if (pSize > 0)
{
WSRequest = ws;
return 0;
}
else
{
return pSize;
}
WSRequest = ws;
return 0;
}
else
{
var rp = new HTTPRequestPacket();
var pSize = rp.Parse(data, 0, (uint)data.Length);
if (pSize > 0)
{
Request = rp;
return 0;
}
else
{
return pSize;
}
return pSize;
}
}
public void Flush()
else
{
// close the connection
if (Request.Headers["connection"].ToLower() != "keep-alive" & IsConnected)
Close();
var rp = new HTTPRequestPacket();
var pSize = rp.Parse(data, 0, (uint)data.Length);
if (pSize > 0)
{
Request = rp;
return 0;
}
else
{
return pSize;
}
}
}
public void Flush()
{
// close the connection
if (Request.Headers["connection"].ToLower() != "keep-alive" & IsConnected)
Close();
}
public bool Upgrade()
{
if (IsWebsocketRequest())
{
string magicString = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
string ret = Request.Headers["Sec-WebSocket-Key"] + magicString;
// Compute the SHA1 hash
SHA1 sha = SHA1.Create();
byte[] sha1Hash = sha.ComputeHash(Encoding.UTF8.GetBytes(ret));
Response.Headers["Upgrade"] = Request.Headers["Upgrade"];
Response.Headers["Connection"] = Request.Headers["Connection"];// "Upgrade";
Response.Headers["Sec-WebSocket-Accept"] = Convert.ToBase64String(sha1Hash);
if (Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
Response.Headers["Sec-WebSocket-Protocol"] = Request.Headers["Sec-WebSocket-Protocol"];
Response.Number = HTTPResponsePacket.ResponseCode.Switching;
Response.Text = "Switching Protocols";
WSMode = true;
Send();
return true;
}
public bool Upgrade()
return false;
}
public HTTPServer Parent
{
get
{
if (IsWebsocketRequest())
return Server;
}
}
public void Send(WebsocketPacket packet)
{
if (packet.Data != null)
base.Send(packet.Data);
}
public override void Send(string data)
{
Response.Message = Encoding.UTF8.GetBytes(data);
Send();
}
public override void Send(byte[] msg, int offset, int length)
{
Response.Message = DC.Clip(msg, (uint)offset, (uint)length);
Send();
}
public override void Send(byte[] message)
{
Response.Message = message;
Send();
}
public void Send(HTTPResponsePacket.ComposeOptions Options = HTTPResponsePacket.ComposeOptions.AllCalculateLength)
{
if (Response.Handled)
return;
try
{
Response.Compose(Options);
base.Send(Response.Data);
// Refresh the current session
if (session != null)
session.Refresh();
}
catch
{
try
{
string magicString = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
string ret = Request.Headers["Sec-WebSocket-Key"] + magicString;
// Compute the SHA1 hash
SHA1 sha = SHA1.Create();
byte[] sha1Hash = sha.ComputeHash(Encoding.UTF8.GetBytes(ret));
Response.Headers["Upgrade"] = Request.Headers["Upgrade"];
Response.Headers["Connection"] = Request.Headers["Connection"];// "Upgrade";
Response.Headers["Sec-WebSocket-Accept"] = Convert.ToBase64String(sha1Hash);
Close();
}
finally { }
}
finally
{
if (Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
Response.Headers["Sec-WebSocket-Protocol"] = Request.Headers["Sec-WebSocket-Protocol"];
}
}
Response.Number = HTTPResponsePacket.ResponseCode.Switching;
Response.Text = "Switching Protocols";
WSMode = true;
public void CreateNewSession()
{
if (session == null)
{
// Create a new one
session = Server.CreateSession(Global.GenerateCode(12), 60 * 20);
Send();
HTTPResponsePacket.HTTPCookie cookie = new HTTPResponsePacket.HTTPCookie("SID", session.Id);
cookie.Expires = DateTime.MaxValue;
cookie.Path = "/";
cookie.HttpOnly = true;
Response.Cookies.Add(cookie);
}
}
public bool IsWebsocketRequest()
{
if (Request.Headers.ContainsKey("connection")
&& Request.Headers["connection"].ToLower().Contains("upgrade")
&& Request.Headers.ContainsKey("upgrade")
&& Request.Headers["upgrade"].ToLower() == "websocket"
&& Request.Headers.ContainsKey("Sec-WebSocket-Version")
&& Request.Headers["Sec-WebSocket-Version"] == "13"
&& Request.Headers.ContainsKey("Sec-WebSocket-Key"))
//&& Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
{
return true;
}
else
{
return false;
}
}
protected override void DataReceived(NetworkBuffer data)
{
byte[] msg = data.Read();
var BL = Parse(msg);
if (BL == 0)
{
if (Request.Method == HTTPRequestPacket.HTTPMethod.UNKNOWN)
{
Close();
return;
}
if (Request.URL == "")
{
Close();
return;
}
}
else if (BL == -1)
{
data.HoldForNextWrite(msg);
return;
}
else if (BL < 0)
{
data.HoldFor(msg, (uint)(msg.Length - BL));
return;
}
else if (BL > 0)
{
if (BL > Server.MaxPost)
{
Send(
"<html><body>POST method content is larger than "
+ Server.MaxPost
+ " bytes.</body></html>");
Close();
}
else
{
data.HoldFor(msg, (uint)(msg.Length + BL));
}
return;
}
else if (BL < 0) // for security
{
Close();
return;
}
if (IsWebsocketRequest() & !WSMode)
{
Upgrade();
//return;
}
//return;
try
{
if (!Server.Execute(this))
{
Response.Number = HTTPResponsePacket.ResponseCode.InternalServerError;
Send("Bad Request");
Close();
}
}
catch (Exception ex)
{
if (ex.Message != "Thread was being aborted.")
{
Global.Log("HTTPServer", LogType.Error, ex.ToString());
//Console.WriteLine(ex.ToString());
//EventLog.WriteEntry("HttpServer", ex.ToString(), EventLogEntryType.Error);
Send(Error500(ex.Message));
}
}
}
private string Error500(string msg)
{
return "<html><head><title>500 Internal Server Error</title></head><br>\r\n"
+ "<body><br>\r\n"
+ "<b>500</b> Internal Server Error<br>" + msg + "\r\n"
+ "</body><br>\r\n"
+ "</html><br>\r\n";
}
public async AsyncReply<bool> SendFile(string filename)
{
if (Response.Handled == true)
return false;
try
{
//HTTP/1.1 200 OK
//Server: Microsoft-IIS/5.0
//Content-Location: http://127.0.0.1/index.html
//Date: Wed, 10 Dec 2003 19:10:25 GMT
//Content-Type: text/html
//Accept-Ranges: bytes
//Last-Modified: Mon, 22 Sep 2003 22:36:56 GMT
//Content-Length: 1957
if (!File.Exists(filename))
{
Response.Number = HTTPResponsePacket.ResponseCode.NotFound;
Send("File Not Found");
return true;
}
return false;
}
public HTTPServer Parent
{
get
{
return Server;
}
}
public void Send(WebsocketPacket packet)
{
if (packet.Data != null)
base.Send(packet.Data);
}
public override void Send(string data)
{
Response.Message = Encoding.UTF8.GetBytes(data);
Send();
}
public override void Send(byte[] msg, int offset, int length)
{
Response.Message = DC.Clip(msg, (uint)offset, (uint)length);
Send();
}
public override void Send(byte[] message)
{
Response.Message = message;
Send();
}
public void Send(HTTPResponsePacket.ComposeOptions Options = HTTPResponsePacket.ComposeOptions.AllCalculateLength)
{
if (Response.Handled)
return;
try
{
Response.Compose(Options);
base.Send(Response.Data);
// Refresh the current session
if (session != null)
session.Refresh();
}
catch
var fileEditTime = File.GetLastWriteTime(filename).ToUniversalTime();
if (Request.Headers.ContainsKey("if-modified-since"))
{
try
{
Close();
var ims = DateTime.Parse(Request.Headers["if-modified-since"]);
if ((fileEditTime - ims).TotalSeconds < 2)
{
Response.Number = HTTPResponsePacket.ResponseCode.NotModified;
Response.Headers.Clear();
//Response.Text = "Not Modified";
Send(HTTPResponsePacket.ComposeOptions.SpecifiedHeadersOnly);
return true;
}
}
finally { }
catch
{
return false;
}
}
Response.Number = HTTPResponsePacket.ResponseCode.OK;
// Fri, 30 Oct 2007 14:19:41 GMT
Response.Headers["Last-Modified"] = fileEditTime.ToString("ddd, dd MMM yyyy HH:mm:ss");
FileInfo fi = new FileInfo(filename);
Response.Headers["Content-Length"] = fi.Length.ToString();
Send(HTTPResponsePacket.ComposeOptions.SpecifiedHeadersOnly);
//var fd = File.ReadAllBytes(filename);
//base.Send(fd);
using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var buffer = new byte[60000];
while (true)
{
var n = fs.Read(buffer, 0, 60000);
if (n <= 0)
break;
//Thread.Sleep(50);
await base.SendAsync(buffer, 0, n);
}
}
return true;
}
catch
{
try
{
Close();
}
finally
{
}
}
public void CreateNewSession()
{
if (session == null)
{
// Create a new one
session = Server.CreateSession(Global.GenerateCode(12), 60 * 20);
HTTPResponsePacket.HTTPCookie cookie = new HTTPResponsePacket.HTTPCookie("SID", session.Id);
cookie.Expires = DateTime.MaxValue;
cookie.Path = "/";
cookie.HttpOnly = true;
Response.Cookies.Add(cookie);
}
}
public bool IsWebsocketRequest()
{
if (Request.Headers.ContainsKey("connection")
&& Request.Headers["connection"].ToLower().Contains("upgrade")
&& Request.Headers.ContainsKey("upgrade")
&& Request.Headers["upgrade"].ToLower() == "websocket"
&& Request.Headers.ContainsKey("Sec-WebSocket-Version")
&& Request.Headers["Sec-WebSocket-Version"] == "13"
&& Request.Headers.ContainsKey("Sec-WebSocket-Key"))
//&& Request.Headers.ContainsKey("Sec-WebSocket-Protocol"))
{
return true;
}
else
{
return false;
}
}
protected override void DataReceived(NetworkBuffer data)
{
byte[] msg = data.Read();
var BL = Parse(msg);
if (BL == 0)
{
if (Request.Method == HTTPRequestPacket.HTTPMethod.UNKNOWN)
{
Close();
return;
}
if (Request.URL == "")
{
Close();
return;
}
}
else if (BL == -1)
{
data.HoldForNextWrite(msg);
return;
}
else if (BL < 0)
{
data.HoldFor(msg, (uint)(msg.Length - BL));
return;
}
else if (BL > 0)
{
if (BL > Server.MaxPost)
{
Send(
"<html><body>POST method content is larger than "
+ Server.MaxPost
+ " bytes.</body></html>");
Close();
}
else
{
data.HoldFor(msg, (uint)(msg.Length + BL));
}
return;
}
else if (BL < 0) // for security
{
Close();
return;
}
if (IsWebsocketRequest() & !WSMode)
{
Upgrade();
//return;
}
//return;
try
{
if (!Server.Execute(this))
{
Response.Number = HTTPResponsePacket.ResponseCode.InternalServerError;
Send("Bad Request");
Close();
}
}
catch (Exception ex)
{
if (ex.Message != "Thread was being aborted.")
{
Global.Log("HTTPServer", LogType.Error, ex.ToString());
//Console.WriteLine(ex.ToString());
//EventLog.WriteEntry("HttpServer", ex.ToString(), EventLogEntryType.Error);
Send(Error500(ex.Message));
}
}
}
private string Error500(string msg)
{
return "<html><head><title>500 Internal Server Error</title></head><br>\r\n"
+ "<body><br>\r\n"
+ "<b>500</b> Internal Server Error<br>" + msg + "\r\n"
+ "</body><br>\r\n"
+ "</html><br>\r\n";
}
public async AsyncReply<bool> SendFile(string filename)
{
if (Response.Handled == true)
return false;
try
{
//HTTP/1.1 200 OK
//Server: Microsoft-IIS/5.0
//Content-Location: http://127.0.0.1/index.html
//Date: Wed, 10 Dec 2003 19:10:25 GMT
//Content-Type: text/html
//Accept-Ranges: bytes
//Last-Modified: Mon, 22 Sep 2003 22:36:56 GMT
//Content-Length: 1957
if (!File.Exists(filename))
{
Response.Number = HTTPResponsePacket.ResponseCode.NotFound;
Send("File Not Found");
return true;
}
var fileEditTime = File.GetLastWriteTime(filename).ToUniversalTime();
if (Request.Headers.ContainsKey("if-modified-since"))
{
try
{
var ims = DateTime.Parse(Request.Headers["if-modified-since"]);
if ((fileEditTime - ims).TotalSeconds < 2)
{
Response.Number = HTTPResponsePacket.ResponseCode.NotModified;
Response.Headers.Clear();
//Response.Text = "Not Modified";
Send(HTTPResponsePacket.ComposeOptions.SpecifiedHeadersOnly);
return true;
}
}
catch
{
return false;
}
}
Response.Number = HTTPResponsePacket.ResponseCode.OK;
// Fri, 30 Oct 2007 14:19:41 GMT
Response.Headers["Last-Modified"] = fileEditTime.ToString("ddd, dd MMM yyyy HH:mm:ss");
FileInfo fi = new FileInfo(filename);
Response.Headers["Content-Length"] = fi.Length.ToString();
Send(HTTPResponsePacket.ComposeOptions.SpecifiedHeadersOnly);
//var fd = File.ReadAllBytes(filename);
//base.Send(fd);
using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var buffer = new byte[60000];
while (true)
{
var n = fs.Read(buffer, 0, 60000);
if (n <= 0)
break;
//Thread.Sleep(50);
await base.SendAsync(buffer, 0, n);
}
}
return true;
}
catch
{
try
{
Close();
}
finally {
}
return false;
}
}
protected override void Connected()
{
// do nothing
}
protected override void Disconencted()
{
// do nothing
return false;
}
}
}
protected override void Connected()
{
// do nothing
}
protected override void Disconencted()
{
// do nothing
}
}