From b3ea03c5e51540e15956d0d17f68902c9b956654 Mon Sep 17 00:00:00 2001 From: enginekit Date: Tue, 17 Dec 2019 09:38:42 +0700 Subject: [PATCH 01/13] minor update license year --- src/SharpConnect.WebServer/General/BufferManager.cs | 2 +- src/SharpConnect.WebServer/General/ConnectionBase.cs | 2 +- src/SharpConnect.WebServer/General/NewConnListener.cs | 2 +- .../General/NewConnListenerSettings.cs | 2 +- src/SharpConnect.WebServer/General/ReqRespHandler.cs | 2 +- src/SharpConnect.WebServer/General/SharedResoucePool.cs | 2 +- .../General/dbugAcceptOpUserToken.cs | 2 +- src/SharpConnect.WebServer/General/dbugLOG.cs | 2 +- src/SharpConnect.WebServer/General/dbugTestFileWriter.cs | 2 +- .../HttpWebServer0/SendIO_RecvIO_Code.cs | 2 +- .../HttpWebServer1/RecvIO_SendIO.cs | 2 +- .../HttpWebServer2/RecvIO_SendIO_2.cs | 6 +++--- .../WebSocket/WebSocketConnectionBase.cs | 4 +--- src/SharpConnect.WebServer/WebSocket/WebSocketRequest.cs | 8 ++++---- tests/WebServerApp/Program.cs | 8 ++++---- 15 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/SharpConnect.WebServer/General/BufferManager.cs b/src/SharpConnect.WebServer/General/BufferManager.cs index fd609ed..182697e 100644 --- a/src/SharpConnect.WebServer/General/BufferManager.cs +++ b/src/SharpConnect.WebServer/General/BufferManager.cs @@ -1,4 +1,4 @@ -//2010, CPOL, Stan Kirk +//CPOL, 2010, Stan Kirk //MIT, 2015-present, EngineKit using System; diff --git a/src/SharpConnect.WebServer/General/ConnectionBase.cs b/src/SharpConnect.WebServer/General/ConnectionBase.cs index 64c3c4b..b52f957 100644 --- a/src/SharpConnect.WebServer/General/ConnectionBase.cs +++ b/src/SharpConnect.WebServer/General/ConnectionBase.cs @@ -1,4 +1,4 @@ -//2010, CPOL, Stan Kirk +//CPOL, 2010, Stan Kirk //MIT, 2015-present, EngineKit diff --git a/src/SharpConnect.WebServer/General/NewConnListener.cs b/src/SharpConnect.WebServer/General/NewConnListener.cs index 5ba8baf..3e522b4 100644 --- a/src/SharpConnect.WebServer/General/NewConnListener.cs +++ b/src/SharpConnect.WebServer/General/NewConnListener.cs @@ -1,4 +1,4 @@ -//2010, CPOL, Stan Kirk +//CPOL, 2010, Stan Kirk //MIT, 2015-present, EngineKit using System; using System.Net.Sockets; diff --git a/src/SharpConnect.WebServer/General/NewConnListenerSettings.cs b/src/SharpConnect.WebServer/General/NewConnListenerSettings.cs index 79c6940..6dfb98c 100644 --- a/src/SharpConnect.WebServer/General/NewConnListenerSettings.cs +++ b/src/SharpConnect.WebServer/General/NewConnListenerSettings.cs @@ -1,4 +1,4 @@ -//2010, CPOL, Stan Kirk +//CPOL, 2010, Stan Kirk //MIT, 2015-present, EngineKit using System; diff --git a/src/SharpConnect.WebServer/General/ReqRespHandler.cs b/src/SharpConnect.WebServer/General/ReqRespHandler.cs index bd62260..98cb72d 100644 --- a/src/SharpConnect.WebServer/General/ReqRespHandler.cs +++ b/src/SharpConnect.WebServer/General/ReqRespHandler.cs @@ -1,4 +1,4 @@ -//2010, CPOL, Stan Kirk +//CPOL, 2010, Stan Kirk //MIT, 2015-present, EngineKit namespace SharpConnect diff --git a/src/SharpConnect.WebServer/General/SharedResoucePool.cs b/src/SharpConnect.WebServer/General/SharedResoucePool.cs index 59200cf..c9cd140 100644 --- a/src/SharpConnect.WebServer/General/SharedResoucePool.cs +++ b/src/SharpConnect.WebServer/General/SharedResoucePool.cs @@ -1,4 +1,4 @@ -//2010, CPOL, Stan Kirk +//CPOL, 2010, Stan Kirk //MIT, 2015-present, EngineKit using System; diff --git a/src/SharpConnect.WebServer/General/dbugAcceptOpUserToken.cs b/src/SharpConnect.WebServer/General/dbugAcceptOpUserToken.cs index 68890e3..425a42c 100644 --- a/src/SharpConnect.WebServer/General/dbugAcceptOpUserToken.cs +++ b/src/SharpConnect.WebServer/General/dbugAcceptOpUserToken.cs @@ -1,4 +1,4 @@ -//2010, CPOL, Stan Kirk +//CPOL, 2010, Stan Kirk //MIT, 2015-present, EngineKit using System; diff --git a/src/SharpConnect.WebServer/General/dbugLOG.cs b/src/SharpConnect.WebServer/General/dbugLOG.cs index fc45008..49c80e5 100644 --- a/src/SharpConnect.WebServer/General/dbugLOG.cs +++ b/src/SharpConnect.WebServer/General/dbugLOG.cs @@ -1,4 +1,4 @@ -//2010, CPOL, Stan Kirk +//CPOL, 2010, Stan Kirk //MIT, 2015-present, EngineKit using System; diff --git a/src/SharpConnect.WebServer/General/dbugTestFileWriter.cs b/src/SharpConnect.WebServer/General/dbugTestFileWriter.cs index 2a7edd1..ee66927 100644 --- a/src/SharpConnect.WebServer/General/dbugTestFileWriter.cs +++ b/src/SharpConnect.WebServer/General/dbugTestFileWriter.cs @@ -1,4 +1,4 @@ -//2010, CPOL, Stan Kirk +//CPOL, 2010, Stan Kirk //MIT, 2015-present, EngineKit using System; diff --git a/src/SharpConnect.WebServer/HttpWebServer0/SendIO_RecvIO_Code.cs b/src/SharpConnect.WebServer/HttpWebServer0/SendIO_RecvIO_Code.cs index 1386386..ac30bf5 100644 --- a/src/SharpConnect.WebServer/HttpWebServer0/SendIO_RecvIO_Code.cs +++ b/src/SharpConnect.WebServer/HttpWebServer0/SendIO_RecvIO_Code.cs @@ -1,4 +1,4 @@ -//2010, CPOL, Stan Kirk +//CPOL, 2010, Stan Kirk //MIT, 2015-present, EngineKit and contributors //https://docs.microsoft.com/en-us/dotnet/framework/network-programming/socket-performance-enhancements-in-version-3-5 diff --git a/src/SharpConnect.WebServer/HttpWebServer1/RecvIO_SendIO.cs b/src/SharpConnect.WebServer/HttpWebServer1/RecvIO_SendIO.cs index 8ab4c79..5200e85 100644 --- a/src/SharpConnect.WebServer/HttpWebServer1/RecvIO_SendIO.cs +++ b/src/SharpConnect.WebServer/HttpWebServer1/RecvIO_SendIO.cs @@ -1,4 +1,4 @@ -//2010, CPOL, Stan Kirk +//CPOL, 2010, Stan Kirk //MIT, 2015-present, EngineKit and contributors //https://docs.microsoft.com/en-us/dotnet/framework/network-programming/socket-performance-enhancements-in-version-3-5 diff --git a/src/SharpConnect.WebServer/HttpWebServer2/RecvIO_SendIO_2.cs b/src/SharpConnect.WebServer/HttpWebServer2/RecvIO_SendIO_2.cs index c62605f..b471377 100644 --- a/src/SharpConnect.WebServer/HttpWebServer2/RecvIO_SendIO_2.cs +++ b/src/SharpConnect.WebServer/HttpWebServer2/RecvIO_SendIO_2.cs @@ -1,4 +1,4 @@ -//2010, CPOL, Stan Kirk +//CPOL, 2010, Stan Kirk //MIT, 2015-present, EngineKit and contributors //https://docs.microsoft.com/en-us/dotnet/framework/network-programming/socket-performance-enhancements-in-version-3-5 @@ -136,14 +136,14 @@ public int ReadBufferTo(byte[] dstBuffer, int dstIndex, int count) { if (dstIndex + count > dstBuffer.Length) { - //only available + //only available int availableLen = dstBuffer.Length - dstIndex; Buffer.BlockCopy(_largeBuffer, _startAt + _readIndex, dstBuffer, _startAt + dstIndex, availableLen); _readIndex += availableLen; return availableLen; } else - { + { Buffer.BlockCopy(_largeBuffer, _startAt + _readIndex, dstBuffer, _startAt + dstIndex, count); _readIndex += count; return count; diff --git a/src/SharpConnect.WebServer/WebSocket/WebSocketConnectionBase.cs b/src/SharpConnect.WebServer/WebSocket/WebSocketConnectionBase.cs index 0d0e990..70d6692 100644 --- a/src/SharpConnect.WebServer/WebSocket/WebSocketConnectionBase.cs +++ b/src/SharpConnect.WebServer/WebSocket/WebSocketConnectionBase.cs @@ -55,9 +55,7 @@ public virtual WebSocketContentCompression Compression } - public virtual void Dispose() - { - } + public virtual void Dispose() { } public virtual void Close() { } public void SetMessageHandler(ReqRespHandler webSocketReqHandler) { diff --git a/src/SharpConnect.WebServer/WebSocket/WebSocketRequest.cs b/src/SharpConnect.WebServer/WebSocket/WebSocketRequest.cs index 7d9b3dc..468b9f3 100644 --- a/src/SharpConnect.WebServer/WebSocket/WebSocketRequest.cs +++ b/src/SharpConnect.WebServer/WebSocket/WebSocketRequest.cs @@ -61,10 +61,10 @@ public byte[] ReadAsBinary() default: case WebSocketContentCompression.NoCompression: return _ms.ToArray(); - case WebSocketContentCompression.Deflate: - return CompressionUtils.DeflateDecompress(_ms.ToArray()); - case WebSocketContentCompression.Gzip: - return CompressionUtils.GZipDecompress(_ms.ToArray()); + //case WebSocketContentCompression.Deflate: + // return CompressionUtils.DeflateDecompress(_ms.ToArray()); + //case WebSocketContentCompression.Gzip: + // return CompressionUtils.GZipDecompress(_ms.ToArray()); } } public string ReadAsString() diff --git a/tests/WebServerApp/Program.cs b/tests/WebServerApp/Program.cs index 5d49268..e10a814 100644 --- a/tests/WebServerApp/Program.cs +++ b/tests/WebServerApp/Program.cs @@ -24,7 +24,7 @@ static void Main_Http() { //1. create #if DEBUG - var webServer = new SharpConnect.WebServers.WebServer(8080, true, testApp.HandleRequest); + var webServer = new SharpConnect.WebServers.WebServer(8080, false, testApp.HandleRequest); #else var webServer = new SharpConnect.WebServers.WebServer(8080, false, testApp.HandleRequest); #endif @@ -88,11 +88,11 @@ static void Main_Https() { //1. create #if DEBUG - var webServer = new SharpConnect.WebServers.WebServer(8080, true, testApp.HandleRequest); -#else + var webServer = new SharpConnect.WebServers.WebServer(8080, false, testApp.HandleRequest); +#else var webServer = new SharpConnect.WebServers.WebServer(8080, false, testApp.HandleRequest); #endif - + webServer.LoadCertificate(@"mycert.p12", "12345"); webServer.UseSsl = true; From 68b10826ac2bc3f1e2a4d0ad4129d145253c85ca Mon Sep 17 00:00:00 2001 From: enginekit Date: Tue, 28 Jan 2020 13:34:20 +0700 Subject: [PATCH 02/13] 132: fix keep alive --- src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs b/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs index 48ccbed..08642e8 100644 --- a/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs +++ b/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs @@ -244,9 +244,7 @@ void AddHeaderInfo(string key, string value) break; case "Connection": { - _context.KeepAlive = (value.ToLower().Trim() == "keep-alive"); - _context.KeepAlive = false; - + _context.KeepAlive = (value.ToLower().Trim() == "keep-alive"); } break; } From f2ed727a6118911a4fc7077acdc1b81ffb53e877 Mon Sep 17 00:00:00 2001 From: enginekit Date: Tue, 28 Jan 2020 13:41:35 +0700 Subject: [PATCH 03/13] 132.1 --- SharpConnect.WebServer.sln | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SharpConnect.WebServer.sln b/SharpConnect.WebServer.sln index a7be0ac..ebb5f5a 100644 --- a/SharpConnect.WebServer.sln +++ b/SharpConnect.WebServer.sln @@ -27,11 +27,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestLoad", "builds\NET20\Te EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLoadNetStd", "builds\NETSTD\TestLoadNetStd\TestLoadNetStd.csproj", "{3FA078C1-4A8D-4D71-81C7-C8C978D8191C}" EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "TestLoad", "tests\TestLoad\TestLoad.shproj", "{A793836F-ECFA-4009-B36B-B812BAA4C7E1}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\SharpConnect.WebServer\SharpConnect.WebServer.projitems*{1585f301-4ece-462c-a9d5-49bfe1c40041}*SharedItemsImports = 13 tests\TestLoad\TestLoad.projitems*{24e7e45b-3716-4dd3-b4b0-10dff0a6211a}*SharedItemsImports = 4 src\SharpConnect.WebServer\SharpConnect.WebServer.projitems*{741a7428-705d-4928-b02c-0db087fde753}*SharedItemsImports = 4 + tests\TestLoad\TestLoad.projitems*{a793836f-ecfa-4009-b36b-b812baa4c7e1}*SharedItemsImports = 13 tests\WebServerApp\WebServerApp.projitems*{ce060f7f-6f5f-45fa-855f-81f28ff00d21}*SharedItemsImports = 4 tests\WebServerApp\WebServerApp.projitems*{cf4bfb13-5a72-4328-9700-8f27bc1c570a}*SharedItemsImports = 13 EndGlobalSection From 05ac53a9a5006e48e6701689aa6d94315c4b0601 Mon Sep 17 00:00:00 2001 From: enginekit Date: Tue, 28 Jan 2020 13:59:52 +0700 Subject: [PATCH 04/13] 132.2 --- SharpConnect.WebServer.sln | 4 ++-- builds/NETSTD/WebServerAppNetSTD/WebServerAppNetSTD.csproj | 6 ++---- ...ct.WebServer.shproj => SharpConnect.WebServer_SH.shproj} | 0 3 files changed, 4 insertions(+), 6 deletions(-) rename src/SharpConnect.WebServer/{SharpConnect.WebServer.shproj => SharpConnect.WebServer_SH.shproj} (100%) diff --git a/SharpConnect.WebServer.sln b/SharpConnect.WebServer.sln index ebb5f5a..c450ebf 100644 --- a/SharpConnect.WebServer.sln +++ b/SharpConnect.WebServer.sln @@ -11,8 +11,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{A4D07531-C EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "WebServerApp", "tests\WebServerApp\WebServerApp.shproj", "{CF4BFB13-5A72-4328-9700-8F27BC1C570A}" EndProject -Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SharpConnect.WebServer", "src\SharpConnect.WebServer\SharpConnect.WebServer.shproj", "{1585F301-4ECE-462C-A9D5-49BFE1C40041}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpConnect.WebServer", "builds\NETSTD\SharpConnect.WebServer\SharpConnect.WebServer.csproj", "{24CA242A-B8F4-450D-A08F-69B23F54B4C9}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpConnect.WebServer", "builds\NET20\SharpConnect.WebServer\SharpConnect.WebServer.csproj", "{741A7428-705D-4928-B02C-0DB087FDE753}" @@ -29,6 +27,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestLoadNetStd", "builds\NE EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "TestLoad", "tests\TestLoad\TestLoad.shproj", "{A793836F-ECFA-4009-B36B-B812BAA4C7E1}" EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "SharpConnect.WebServer_SH", "src\SharpConnect.WebServer\SharpConnect.WebServer_SH.shproj", "{1585F301-4ECE-462C-A9D5-49BFE1C40041}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\SharpConnect.WebServer\SharpConnect.WebServer.projitems*{1585f301-4ece-462c-a9d5-49bfe1c40041}*SharedItemsImports = 13 diff --git a/builds/NETSTD/WebServerAppNetSTD/WebServerAppNetSTD.csproj b/builds/NETSTD/WebServerAppNetSTD/WebServerAppNetSTD.csproj index fac381c..d867f6d 100644 --- a/builds/NETSTD/WebServerAppNetSTD/WebServerAppNetSTD.csproj +++ b/builds/NETSTD/WebServerAppNetSTD/WebServerAppNetSTD.csproj @@ -13,10 +13,8 @@ true - - - - + + diff --git a/src/SharpConnect.WebServer/SharpConnect.WebServer.shproj b/src/SharpConnect.WebServer/SharpConnect.WebServer_SH.shproj similarity index 100% rename from src/SharpConnect.WebServer/SharpConnect.WebServer.shproj rename to src/SharpConnect.WebServer/SharpConnect.WebServer_SH.shproj From 9f2dd4bc9b198fb4e04b1b453a16e089db5f85a5 Mon Sep 17 00:00:00 2001 From: enginekit Date: Wed, 29 Jan 2020 10:01:43 +0700 Subject: [PATCH 05/13] 133: update POST body --- .../HttpWebServer0/HttpRequest.cs | 20 ++++++++++--------- tests/TestLoad/Program.cs | 4 ++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs b/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs index 08642e8..c25fe56 100644 --- a/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs +++ b/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs @@ -66,7 +66,7 @@ internal HttpRequest() } public void Dispose() { - + OnDispose(); } protected virtual void OnDispose() { @@ -114,8 +114,7 @@ public WebRequestParameter[] ReqParameters public string GetHeaderKey(string key) { - string found; - _headerKeyValues.TryGetValue(key, out found); + _headerKeyValues.TryGetValue(key, out string found); return found; } public string GetBodyContentAsString() @@ -244,7 +243,7 @@ void AddHeaderInfo(string key, string value) break; case "Connection": { - _context.KeepAlive = (value.ToLower().Trim() == "keep-alive"); + _context.KeepAlive = (value.ToLower().Trim() == "keep-alive"); } break; } @@ -260,16 +259,17 @@ internal ProcessReceiveBufferResult LoadData() case HttpParsingState.Head: { //find html header - int readpos = ParseHttpRequestHeader(); + //check if complete or not + _readPos = ParseHttpRequestHeader(); if (_parseState == HttpParsingState.Body) { - ProcessHtmlPostBody(readpos); + ProcessHtmlPostBody(_readPos); } } break; case HttpParsingState.Body: - ProcessHtmlPostBody(0); + ProcessHtmlPostBody(_readPos); break; case HttpParsingState.Complete: break; @@ -412,13 +412,15 @@ int ParseHttpRequestHeader() return readpos; } + int _readPos; void ProcessHtmlPostBody(int readpos) { //parse body + int transferedBytes = _context.RecvByteTransfer; int remaining = transferedBytes - readpos; if (!IsMsgBodyComplete) - { + { int wantBytes = ContentLength - _contentByteCount; if (wantBytes <= remaining) { @@ -427,6 +429,7 @@ void ProcessHtmlPostBody(int readpos) _context.RecvCopyTo(readpos, buff, wantBytes); //add to req AddMsgBody(buff, 0, wantBytes); + //complete _parseState = HttpParsingState.Complete; return; @@ -441,7 +444,6 @@ void ProcessHtmlPostBody(int readpos) //add to req AddMsgBody(buff, 0, remaining); } - return; } } diff --git a/tests/TestLoad/Program.cs b/tests/TestLoad/Program.cs index 0282f08..6068e89 100644 --- a/tests/TestLoad/Program.cs +++ b/tests/TestLoad/Program.cs @@ -44,6 +44,10 @@ static void TestHttpsCall(object s) wb.Proxy = null; try { + for (int i = 0; i < 100; ++i) + { + wb.UploadString("https://localhost:8080", "hello!1111222333_" + i); + } for (int i = 0; i < 1010; ++i) { Console.WriteLine(i.ToString()); From 94ea8cbfba0ef077415b97b882861b3e1881fb71 Mon Sep 17 00:00:00 2001 From: enginekit Date: Fri, 17 Jan 2020 18:00:19 +0700 Subject: [PATCH 06/13] 60: SendTextData() --- builds/NET20/WebServerApp/WebServerApp.csproj | 2 +- builds/NET20/WebServerApp/app.config | 2 +- .../HttpWebServer0/HttpRequest.cs | 2 -- .../HttpWebServer2/SockAsyncNetworkStream.cs | 30 ++++++++++++++----- .../WebSocket/WebSocketConnectionBase.cs | 13 ++++++-- .../WebSocket/WebSocketContext.cs | 2 +- .../WebSocket/WebSocketProtocolParser.cs | 15 +++++----- .../WebSocket/WebSocketResponse.cs | 6 ++-- .../WebSocket/WsClientSessionBase.cs | 2 +- 9 files changed, 48 insertions(+), 26 deletions(-) diff --git a/builds/NET20/WebServerApp/WebServerApp.csproj b/builds/NET20/WebServerApp/WebServerApp.csproj index a68ae1b..faab80b 100644 --- a/builds/NET20/WebServerApp/WebServerApp.csproj +++ b/builds/NET20/WebServerApp/WebServerApp.csproj @@ -8,7 +8,7 @@ Exe WebServerApp WebServerApp - v4.7.2 + v2.0 512 true diff --git a/builds/NET20/WebServerApp/app.config b/builds/NET20/WebServerApp/app.config index 312bb3f..2fa6e95 100644 --- a/builds/NET20/WebServerApp/app.config +++ b/builds/NET20/WebServerApp/app.config @@ -1,3 +1,3 @@ - + diff --git a/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs b/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs index c25fe56..ae7ff90 100644 --- a/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs +++ b/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs @@ -157,9 +157,7 @@ public HttpMethod HttpMethod get; internal set; } - protected int ContentLength => _targetContentLength; - } class HttpRequestImpl : HttpRequest diff --git a/src/SharpConnect.WebServer/HttpWebServer2/SockAsyncNetworkStream.cs b/src/SharpConnect.WebServer/HttpWebServer2/SockAsyncNetworkStream.cs index 7706f06..abbea37 100644 --- a/src/SharpConnect.WebServer/HttpWebServer2/SockAsyncNetworkStream.cs +++ b/src/SharpConnect.WebServer/HttpWebServer2/SockAsyncNetworkStream.cs @@ -293,7 +293,7 @@ void RecvAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e) if (e.BytesTransferred > 0) { RecvDataAfterHandshake(); - } + } } else @@ -387,14 +387,18 @@ int ReadAfterPassHandshake(byte[] buffer, int offset, int count) return 0; } } - - void RecvDataAfterHandshake() { + TRY_AGAIN2: + if (_invokeCheck1 != 0) + { + goto TRY_AGAIN2; + } if (Interlocked.CompareExchange(ref _invokeCheck1, 1, 0) != 0) { System.Diagnostics.Debugger.Break(); + } //call by RecvAsyncEventArgs_Completed thread #if DEBUG @@ -471,6 +475,10 @@ void RecvDataAfterHandshake() } } + if (_invokeCheck1 == 0) + { + + } if (Interlocked.CompareExchange(ref _invokeCheck1, 0, 1) != 1) { //System.Diagnostics.Debugger.Break(); @@ -1104,6 +1112,7 @@ public void AuthenAsClient(string targetHost, AuthenCallbackDelegate whenFinish) { _sslStream.EndAuthenticateAsClient(state); whenFinish(); + }, new object()); } @@ -1137,12 +1146,19 @@ private void LowLevelForSSL_RecvCompleted(bool result, int lowLevelByteCount) { //decrypt data from sslStream to readable data //and write to _readableRecvBuffer - int latestReadLen = _readableRecvBuffer.WriteBufferFromStream(_sslStream); - while (latestReadLen > 0) + try + { + int latestReadLen = _readableRecvBuffer.WriteBufferFromStream(_sslStream); + while (latestReadLen > 0) + { + latestReadLen = _readableRecvBuffer.WriteBufferFromStream(_sslStream); + } + readableDataLen = _readableRecvBuffer.BufferLength; + } + catch (Exception ex) { - latestReadLen = _readableRecvBuffer.WriteBufferFromStream(_sslStream); + } - readableDataLen = _readableRecvBuffer.BufferLength; } } _startRecv = false; diff --git a/src/SharpConnect.WebServer/WebSocket/WebSocketConnectionBase.cs b/src/SharpConnect.WebServer/WebSocket/WebSocketConnectionBase.cs index 70d6692..27e9301 100644 --- a/src/SharpConnect.WebServer/WebSocket/WebSocketConnectionBase.cs +++ b/src/SharpConnect.WebServer/WebSocket/WebSocketConnectionBase.cs @@ -26,7 +26,7 @@ namespace SharpConnect.WebServers { - abstract class WebSocketConnectionBase : IDisposable + public abstract class WebSocketConnectionBase : IDisposable { WebSocketContentCompression _compression; protected WebSocketResponse _webSocketResp; @@ -62,20 +62,27 @@ public void SetMessageHandler(ReqRespHandler _webSocketConn.ConnectionId; public void Send(string str) { - _webSocketConn.Send(str); + _webSocketConn.SendTextData(str); } public void SendAsBinaryData(byte[] data, int start, int len) { diff --git a/src/SharpConnect.WebServer/WebSocket/WebSocketProtocolParser.cs b/src/SharpConnect.WebServer/WebSocket/WebSocketProtocolParser.cs index fe1a9d9..8c8f62c 100644 --- a/src/SharpConnect.WebServer/WebSocket/WebSocketProtocolParser.cs +++ b/src/SharpConnect.WebServer/WebSocket/WebSocketProtocolParser.cs @@ -27,7 +27,7 @@ namespace SharpConnect.WebServers { - class WebSocketProtocolParser + public class WebSocketProtocolParser { enum ParseState @@ -68,9 +68,9 @@ internal void SetNewParseResultHandler(Action newResultHandler internal WebSocketConnectionBase OwnerWebSocketConnBase { get; private set; } bool ReadHeader() - { + { if (!_myBufferStream.Ensure(2)) - { + { return false; } //---------------------------------------------------------- @@ -125,9 +125,10 @@ bool ReadHeader() //---------------------------------------------------------- // Payload Length byte payloadLen = (byte)(b2 & 0x7f); //is 7 bits of the b2 + + bool allowMoreFrame = false; if (fin == Fin.More || _currentOpCode == Opcode.Cont) { - //process fragment frame *** throw new NotSupportedException(); } else @@ -222,7 +223,7 @@ bool ReadPayloadLen() { int extendedPayloadByteCount = (_currentPacketLen == 126 ? 2 : 8); if (!_myBufferStream.Ensure(extendedPayloadByteCount)) - { + { return false; } //---------------------------------------------------------- @@ -244,7 +245,7 @@ bool ReadPayloadLen() bool ReadMask() { if (!_myBufferStream.Ensure(_currentMaskLen)) - { + { return false; } //---------------------------------------------------------- @@ -335,7 +336,7 @@ internal ProcessReceiveBufferResult ParseRecvData() bool ReadBodyContent(int readLen) { if (!_myBufferStream.Ensure(readLen)) - { + { return false; } //------------------------------------ diff --git a/src/SharpConnect.WebServer/WebSocket/WebSocketResponse.cs b/src/SharpConnect.WebServer/WebSocket/WebSocketResponse.cs index b6f74b7..a9d7758 100644 --- a/src/SharpConnect.WebServer/WebSocket/WebSocketResponse.cs +++ b/src/SharpConnect.WebServer/WebSocket/WebSocketResponse.cs @@ -63,13 +63,13 @@ public void Write(string content) _sendIO.EnqueueSendingData(dataToSend, dataToSend.Length); _sendIO.SendIOStartSend(); } - public void Write(byte[] content, int start, int len) + public void Write(byte[] content, int start, int len, bool isBinary = true) { //send as binary data int maskKey = _asClient ? _rdForMask.Next() : 0; - byte[] dataToSend = CreateSendBuffer(content, maskKey, true, Compression); + byte[] dataToSend = CreateSendBuffer(content, maskKey, isBinary, Compression); _sendIO.EnqueueSendingData(dataToSend, dataToSend.Length); - _sendIO.SendIOStartSend(); + _sendIO.SendIOStartSend(); } static void MaskAgain(byte[] data, byte[] key) { diff --git a/src/SharpConnect.WebServer/WebSocket/WsClientSessionBase.cs b/src/SharpConnect.WebServer/WebSocket/WsClientSessionBase.cs index ce46c02..61c5173 100644 --- a/src/SharpConnect.WebServer/WebSocket/WsClientSessionBase.cs +++ b/src/SharpConnect.WebServer/WebSocket/WsClientSessionBase.cs @@ -60,7 +60,7 @@ protected static StringBuilder CreateWebSocketUpgradeReq(string host, string url public void SendData(string data) { _wbsocketConn.Compression = Compression; - _wbsocketConn.Send(data); + _wbsocketConn.SendTextData(data); } public void SendBinaryData(byte[] data, int start, int len) { From 69bd499366a09896b71a6e044cbbc0e34569b51a Mon Sep 17 00:00:00 2001 From: enginekit Date: Fri, 17 Jan 2020 18:07:24 +0700 Subject: [PATCH 07/13] 60.1 --- src/SharpConnect.WebServer/WebSocket/WebSocketClient.cs | 4 ++-- .../WebSocket/WebSocketConnectionBase.cs | 1 - src/SharpConnect.WebServer/WebSocket/WsClientSessionBase.cs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/SharpConnect.WebServer/WebSocket/WebSocketClient.cs b/src/SharpConnect.WebServer/WebSocket/WebSocketClient.cs index 069c87d..0bbef92 100644 --- a/src/SharpConnect.WebServer/WebSocket/WebSocketClient.cs +++ b/src/SharpConnect.WebServer/WebSocket/WebSocketClient.cs @@ -55,10 +55,10 @@ public void Connect(string url) _clientBase = plainWebSocketClient; } } - public void SendData(string data) + public void SendTextData(string data) { _clientBase.Compression = Compression; - _clientBase.SendData(data); + _clientBase.SendTextData(data); } public void SendBinaryData(byte[] binaryData) { diff --git a/src/SharpConnect.WebServer/WebSocket/WebSocketConnectionBase.cs b/src/SharpConnect.WebServer/WebSocket/WebSocketConnectionBase.cs index 27e9301..d29011e 100644 --- a/src/SharpConnect.WebServer/WebSocket/WebSocketConnectionBase.cs +++ b/src/SharpConnect.WebServer/WebSocket/WebSocketConnectionBase.cs @@ -82,7 +82,6 @@ public void SendBinaryData(byte[] data, int start, int len) //and wait for result _webSocketResp.Compression = Compression; _webSocketResp.Write(data, start, len); - } internal void InvokeReqHandler(WebSocketRequest req) { diff --git a/src/SharpConnect.WebServer/WebSocket/WsClientSessionBase.cs b/src/SharpConnect.WebServer/WebSocket/WsClientSessionBase.cs index 61c5173..81b704b 100644 --- a/src/SharpConnect.WebServer/WebSocket/WsClientSessionBase.cs +++ b/src/SharpConnect.WebServer/WebSocket/WsClientSessionBase.cs @@ -57,7 +57,7 @@ protected static StringBuilder CreateWebSocketUpgradeReq(string host, string url /// send text data to the server /// /// - public void SendData(string data) + public void SendTextData(string data) { _wbsocketConn.Compression = Compression; _wbsocketConn.SendTextData(data); From e733e502cc140fc9a88778b1915f1f2dc5b544af Mon Sep 17 00:00:00 2001 From: enginekit Date: Wed, 29 Jan 2020 10:24:22 +0700 Subject: [PATCH 08/13] 61: update websocket SendTextData() --- builds/NET20/WebServerApp/WebServerApp.csproj | 2 +- builds/NET20/WebServerApp/app.config | 2 +- .../WebSocket/WebSocketContext.cs | 2 +- .../WebSocket/WebSocketRequest.cs | 2 +- tests/TestWsClient/Form1.Designer.cs | 13 ++++++++ tests/TestWsClient/Form1.cs | 31 ++++++++++++++++--- tests/TestWsClient/Form1.resx | 4 +-- tests/TestWsClient/Program.cs | 3 ++ .../Properties/Settings.Designer.cs | 2 +- tests/TestWsClient/TestWsClient.csproj | 3 +- tests/TestWsClient/app.config | 2 +- 11 files changed, 52 insertions(+), 14 deletions(-) diff --git a/builds/NET20/WebServerApp/WebServerApp.csproj b/builds/NET20/WebServerApp/WebServerApp.csproj index faab80b..52b87c6 100644 --- a/builds/NET20/WebServerApp/WebServerApp.csproj +++ b/builds/NET20/WebServerApp/WebServerApp.csproj @@ -8,7 +8,7 @@ Exe WebServerApp WebServerApp - v2.0 + v4.8 512 true diff --git a/builds/NET20/WebServerApp/app.config b/builds/NET20/WebServerApp/app.config index 2fa6e95..3e0e37c 100644 --- a/builds/NET20/WebServerApp/app.config +++ b/builds/NET20/WebServerApp/app.config @@ -1,3 +1,3 @@ - + diff --git a/src/SharpConnect.WebServer/WebSocket/WebSocketContext.cs b/src/SharpConnect.WebServer/WebSocket/WebSocketContext.cs index 50f1f9c..9be57a2 100644 --- a/src/SharpConnect.WebServer/WebSocket/WebSocketContext.cs +++ b/src/SharpConnect.WebServer/WebSocket/WebSocketContext.cs @@ -1,4 +1,4 @@ -//MIT, 2019, EngineKit +//MIT, 2019-present, EngineKit namespace SharpConnect.WebServers diff --git a/src/SharpConnect.WebServer/WebSocket/WebSocketRequest.cs b/src/SharpConnect.WebServer/WebSocket/WebSocketRequest.cs index 468b9f3..155e249 100644 --- a/src/SharpConnect.WebServer/WebSocket/WebSocketRequest.cs +++ b/src/SharpConnect.WebServer/WebSocket/WebSocketRequest.cs @@ -36,7 +36,7 @@ internal WebSocketRequest(WebSocketConnectionBase ownerConn) _ownerConn = ownerConn; } public WebSocketContentCompression Compression { get; internal set; } - + public int OwnerContextId => _ownerConn.ConnectionId; public void Dispose() { if (_ms != null) diff --git a/tests/TestWsClient/Form1.Designer.cs b/tests/TestWsClient/Form1.Designer.cs index 7a150d7..6e425ad 100644 --- a/tests/TestWsClient/Form1.Designer.cs +++ b/tests/TestWsClient/Form1.Designer.cs @@ -33,6 +33,7 @@ private void InitializeComponent() this.button2 = new System.Windows.Forms.Button(); this.button3 = new System.Windows.Forms.Button(); this.button4 = new System.Windows.Forms.Button(); + this.button5 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // button1 @@ -83,11 +84,22 @@ private void InitializeComponent() this.button4.UseVisualStyleBackColor = true; this.button4.Click += new System.EventHandler(this.button4_Click); // + // button5 + // + this.button5.Location = new System.Drawing.Point(273, 30); + this.button5.Name = "button5"; + this.button5.Size = new System.Drawing.Size(124, 51); + this.button5.TabIndex = 5; + this.button5.Text = "Secure WebSocket"; + this.button5.UseVisualStyleBackColor = true; + this.button5.Click += new System.EventHandler(this.button5_Click); + // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(615, 337); + this.Controls.Add(this.button5); this.Controls.Add(this.button4); this.Controls.Add(this.button3); this.Controls.Add(this.button2); @@ -107,6 +119,7 @@ private void InitializeComponent() private System.Windows.Forms.Button button2; private System.Windows.Forms.Button button3; private System.Windows.Forms.Button button4; + private System.Windows.Forms.Button button5; } } diff --git a/tests/TestWsClient/Form1.cs b/tests/TestWsClient/Form1.cs index 7afc31f..45c5af6 100644 --- a/tests/TestWsClient/Form1.cs +++ b/tests/TestWsClient/Form1.cs @@ -1,7 +1,9 @@ using System; using System.Windows.Forms; using SharpConnect.WebServers; - +using System.Net; +using System.Net.Sockets; +using System.Net.Security; namespace TestWsClient { @@ -37,6 +39,8 @@ private void button1_Click(object sender, EventArgs e) private void button3_Click(object sender, EventArgs e) { + + //secure websocket if (_client != null) return; //------------------------------------------------ @@ -57,7 +61,9 @@ private void button3_Click(object sender, EventArgs e) })); }); //_client.Connect("https://localhost:8080/websocket"); - _client.Connect("https://localhost:8080/websocket"); + //_client.Connect("https://localhost:8080/websocket"); + //_client.LoadCertificate("mycert.pfx", "12345"); + _client.Connect("https://localhost:8080/"); } private void Form1_Load(object sender, EventArgs e) @@ -67,16 +73,31 @@ private void Form1_Load(object sender, EventArgs e) private void button2_Click(object sender, EventArgs e) { - _client.SendData("LOOPBACK: hello server " + _outputMsgCount++); + _client.SendTextData("LOOPBACK: hello server " + _outputMsgCount++); } private void button4_Click(object sender, EventArgs e) { - for (int i = 0; i < 10; ++i) + for (int i = 0; i < 100; ++i) { - _client.SendData("LOOPBACK: hello server " + _outputMsgCount++); + _client.SendTextData("LOOPBACK: hello server " + _outputMsgCount++); + //_client.SendData("LOOPBACK: hello server " + _outputMsgCount++); + //_client.SendData("LOOPBACK: hello server " + _outputMsgCount++); + //_client.SendData("LOOPBACK: hello server " + _outputMsgCount++); + //_client.SendData("LOOPBACK: hello server " + _outputMsgCount++); + //_client.SendData("LOOPBACK: hello server " + _outputMsgCount++); + //_client.SendData("LOOPBACK: hello server " + _outputMsgCount++); + //_client.SendData("LOOPBACK: hello server " + _outputMsgCount++); + //_client.SendData("LOOPBACK: hello server " + _outputMsgCount++); + //_client.SendData("LOOPBACK: hello server " + _outputMsgCount++); + } } + + private void button5_Click(object sender, EventArgs e) + { + Examples.System.Net.SslTcpClient.Main1(); + } } } diff --git a/tests/TestWsClient/Form1.resx b/tests/TestWsClient/Form1.resx index 7080a7d..1af7de1 100644 --- a/tests/TestWsClient/Form1.resx +++ b/tests/TestWsClient/Form1.resx @@ -112,9 +112,9 @@ 2.0 - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 \ No newline at end of file diff --git a/tests/TestWsClient/Program.cs b/tests/TestWsClient/Program.cs index 68e0378..7a1161e 100644 --- a/tests/TestWsClient/Program.cs +++ b/tests/TestWsClient/Program.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Windows.Forms; +using System.Net; +using System.Net.Security; namespace TestWsClient { @@ -12,6 +14,7 @@ static class Program [STAThread] static void Main() { + ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(delegate { return true; }); Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); diff --git a/tests/TestWsClient/Properties/Settings.Designer.cs b/tests/TestWsClient/Properties/Settings.Designer.cs index 169d787..28816f0 100644 --- a/tests/TestWsClient/Properties/Settings.Designer.cs +++ b/tests/TestWsClient/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace TestWsClient.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.8.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.9.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/tests/TestWsClient/TestWsClient.csproj b/tests/TestWsClient/TestWsClient.csproj index 12c2941..0cbd1ad 100644 --- a/tests/TestWsClient/TestWsClient.csproj +++ b/tests/TestWsClient/TestWsClient.csproj @@ -8,7 +8,7 @@ WinExe TestWsClient TestWsClient - v2.0 + v4.8 512 true @@ -49,6 +49,7 @@ + Form1.cs diff --git a/tests/TestWsClient/app.config b/tests/TestWsClient/app.config index 2fa6e95..3e0e37c 100644 --- a/tests/TestWsClient/app.config +++ b/tests/TestWsClient/app.config @@ -1,3 +1,3 @@ - + From e3640c870fbaf91950db8f0f6c0c7e59e1542ae0 Mon Sep 17 00:00:00 2001 From: enginekit Date: Tue, 3 Mar 2020 14:58:14 +0700 Subject: [PATCH 09/13] 62: move init steps --- .../HttpWebServer1/HttpWebServer.cs | 52 ++++++----- .../HttpWebServer2/HttpsWebServer.cs | 88 +++++++++++-------- 2 files changed, 81 insertions(+), 59 deletions(-) diff --git a/src/SharpConnect.WebServer/HttpWebServer1/HttpWebServer.cs b/src/SharpConnect.WebServer/HttpWebServer1/HttpWebServer.cs index f81f986..7dad4fd 100644 --- a/src/SharpConnect.WebServer/HttpWebServer1/HttpWebServer.cs +++ b/src/SharpConnect.WebServer/HttpWebServer1/HttpWebServer.cs @@ -19,35 +19,21 @@ class HttpWebServer : IHttpServer BufferManager _bufferMan; SharedResoucePool _contextPool; + int _port; + bool _localOnly; public HttpWebServer( int port, bool localOnly, ReqRespHandler reqHandler) { + _port = port; + _localOnly = localOnly; _reqHandler = reqHandler; - int maxNumberOfConnections = 500; - int excessSaeaObjectsInPool = 200; - int backlog = 100; - int maxSimultaneousAcceptOps = 100; - - var setting = new NewConnListenerSettings(maxNumberOfConnections, - excessSaeaObjectsInPool, - backlog, - maxSimultaneousAcceptOps, - new IPEndPoint(localOnly ? IPAddress.Loopback : IPAddress.Any, port));//check only local host or not - - CreateContextPool(maxNumberOfConnections); - _newConnListener = new NewConnectionListener(setting, - clientSocket => - { - //when accept new client - HttpContext context = _contextPool.Pop(); - context.BindSocket(clientSocket); //*** bind to client socket - context.StartReceive(); //start receive data - }); } + public LargeFileUploadPermissionReqHandler LargeFileUploadPermissionReqHandler { get; set; } + void CreateContextPool(int maxNumberOfConnnections) { int recvSize = 1024; @@ -94,6 +80,32 @@ public void Start() //------------------------------ try { + + int maxNumberOfConnections = 500; + int excessSaeaObjectsInPool = 200; + int backlog = 100; + int maxSimultaneousAcceptOps = 100; + + var setting = new NewConnListenerSettings(maxNumberOfConnections, + excessSaeaObjectsInPool, + backlog, + maxSimultaneousAcceptOps, + new IPEndPoint(_localOnly ? IPAddress.Loopback : IPAddress.Any, _port));//check only local host or not + + CreateContextPool(maxNumberOfConnections); + _newConnListener = new NewConnectionListener(setting, + clientSocket => + { + //when accept new client + HttpContext context = _contextPool.Pop(); + context.BindSocket(clientSocket); //*** bind to client socket + context.StartReceive(); //start receive data + }); + + + + + //start web server _isRunning = true; _newConnListener.StartListening(); diff --git a/src/SharpConnect.WebServer/HttpWebServer2/HttpsWebServer.cs b/src/SharpConnect.WebServer/HttpWebServer2/HttpsWebServer.cs index 5b2843c..21fea21 100644 --- a/src/SharpConnect.WebServer/HttpWebServer2/HttpsWebServer.cs +++ b/src/SharpConnect.WebServer/HttpWebServer2/HttpsWebServer.cs @@ -15,49 +15,17 @@ class HttpsWebServer : IHttpServer BufferManager _bufferMan; SharedResoucePool _contextPool; + + bool _localOnly; + int _port; public HttpsWebServer(int port, bool localOnly, ReqRespHandler reqHandler) { - _reqHandler = reqHandler; - - int maxNumberOfConnections = 500; - int excessSaeaObjectsInPool = 200; - int backlog = 100; - int maxSimultaneousAcceptOps = 100; - - var setting = new NewConnListenerSettings(maxNumberOfConnections, - excessSaeaObjectsInPool, - backlog, - maxSimultaneousAcceptOps, - new IPEndPoint(localOnly ? IPAddress.Loopback : IPAddress.Any, port));//check only local host or not - - CreateContextPool(maxNumberOfConnections); - _newConnListener = new NewConnectionListener(setting, - clientSocket => - { - //when accept new client - - int recvSize = 1024 * 2; - int sendSize = 1024 * 2; - HttpsContext context = new HttpsContext(this, recvSize, sendSize); - context.BindReqHandler(_reqHandler); //client handler -#if DEBUG - context.dbugForHttps = true; -#endif - - - context.BindSocket(clientSocket); //*** bind to client socket - //for ssl -> cert must not be null - context.StartReceive(_serverCert); - //TODO:: - //USE https context from Pool???? - //{ - // HttpsContext context = _contextPool.Pop(); - // context.BindSocket(clientSocket); //*** bind to client socket - // context.StartReceive(UseSsl ? _serverCert : null); - //} - }); + _port = port; + _localOnly = localOnly; + _reqHandler = reqHandler; } + public LargeFileUploadPermissionReqHandler LargeFileUploadPermissionReqHandler { get; set; } System.Security.Cryptography.X509Certificates.X509Certificate2 _serverCert; public void LoadCertificate(string certFile, string psw) @@ -115,6 +83,48 @@ public void Start() //------------------------------ try { + + //------------------------------ + int maxNumberOfConnections = 500; + int excessSaeaObjectsInPool = 200; + int backlog = 100; + int maxSimultaneousAcceptOps = 100; + + var setting = new NewConnListenerSettings(maxNumberOfConnections, + excessSaeaObjectsInPool, + backlog, + maxSimultaneousAcceptOps, + new IPEndPoint(_localOnly ? IPAddress.Loopback : IPAddress.Any, _port));//check only local host or not + + CreateContextPool(maxNumberOfConnections); + _newConnListener = new NewConnectionListener(setting, + clientSocket => + { + //when accept new client + + int recvSize = 1024 * 2; + int sendSize = 1024 * 2; + HttpsContext context = new HttpsContext(this, recvSize, sendSize); + context.BindReqHandler(_reqHandler); //client handler +#if DEBUG + context.dbugForHttps = true; +#endif + + + context.BindSocket(clientSocket); //*** bind to client socket + //for ssl -> cert must not be null + context.StartReceive(_serverCert); + //TODO:: + //USE https context from Pool???? + //{ + // HttpsContext context = _contextPool.Pop(); + // context.BindSocket(clientSocket); //*** bind to client socket + // context.StartReceive(UseSsl ? _serverCert : null); + //} + }); + //------------------------------ + + //start web server _isRunning = true; _newConnListener.StartListening(); From 9c129cfc0195453510dcf2edb69f4dbea16841f2 Mon Sep 17 00:00:00 2001 From: enginekit Date: Tue, 3 Mar 2020 14:58:43 +0700 Subject: [PATCH 10/13] 63: LargeFileUploadPermissionReqHandler --- .../HttpWebServer0/HttpRequest.cs | 175 +++++++++++++----- .../HttpWebServer0/WebServer.cs | 4 +- .../HttpWebServer1/HttpContext.cs | 6 +- .../HttpWebServer2/HttpsContext.cs | 2 + 4 files changed, 136 insertions(+), 51 deletions(-) diff --git a/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs b/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs index ae7ff90..51414d2 100644 --- a/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs +++ b/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs @@ -106,11 +106,7 @@ internal virtual void Reset() _targetContentLength = 0; } - public WebRequestParameter[] ReqParameters - { - get; - internal set; - } + public WebRequestParameter[] ReqParameters { get; internal set; } public string GetHeaderKey(string key) { @@ -135,16 +131,37 @@ public string GetBodyContentAsString() } static readonly byte[] s_empty = new byte[0]; + + /// + /// max byte count of body in mem stream + /// + public int InMemMaxUploadBodySize { get; protected set; } + + public string UploadTempFileName { get; protected set; } + public byte[] GetBodyContentAsBuffer() { if (_contentByteCount > 0) { - var pos = _bodyMs.Position; - _bodyMs.Position = 0; - byte[] buffer = new byte[_contentByteCount]; - _bodyMs.Read(buffer, 0, _contentByteCount); - _bodyMs.Position = pos; - return buffer; + if (UploadTempFileName != null) + { + //read all data from temp filename + //TODO: check if it is large file or not + //if it is a large file *** + //we should read it as file stream + + return null; + } + else + { + //copy from mem-stream + var pos = _bodyMs.Position; + _bodyMs.Position = 0; + byte[] buffer = new byte[_contentByteCount]; + _bodyMs.Read(buffer, 0, _contentByteCount); + _bodyMs.Position = pos; + return buffer; + } } else { @@ -160,18 +177,35 @@ public HttpMethod HttpMethod protected int ContentLength => _targetContentLength; } + public class LargetFileUploadPolicyResult + { + public bool Cancel { get; set; } + public string TempUploadFilename { get; set; } + } + + public delegate void LargeFileUploadPermissionReqHandler(HttpRequest req, LargetFileUploadPolicyResult result); + class HttpRequestImpl : HttpRequest { readonly IHttpContext _context; + LargeFileUploadPermissionReqHandler _largeFileUploadPermissionReqHandler; + internal HttpRequestImpl(IHttpContext context) : base() { _context = context; _bodyMs = new MemoryStream(); + InMemMaxUploadBodySize = 1024 * 4;//default 4k } + public void SetLargeUploadFilePolicyHandler(LargeFileUploadPermissionReqHandler largeFileUploadPermissionReqHandler) + { + _largeFileUploadPermissionReqHandler = largeFileUploadPermissionReqHandler; + } //=================== + + //parsing HttpParsingState _parseState; internal override void Reset() @@ -182,8 +216,7 @@ internal override void Reset() } bool IsMsgBodyComplete => _contentByteCount >= _targetContentLength; - - object _bodyLock = new object(); + readonly object _bodyLock = new object(); void AddMsgBody(byte[] buffer, int start, int count) { try @@ -201,13 +234,11 @@ void AddMsgBody(byte[] buffer, int start, int count) { _bodyMs.Write(buffer, s1, remaining); remaining = 0; - _contentByteCount += remaining; } else { _bodyMs.Write(buffer, s1, blockSize); remaining -= blockSize; - _contentByteCount += blockSize; s1 += blockSize; } } @@ -216,7 +247,6 @@ void AddMsgBody(byte[] buffer, int start, int count) else { _bodyMs.Write(buffer, start, count); - _contentByteCount += count; } } @@ -246,6 +276,8 @@ void AddHeaderInfo(string key, string value) break; } } + + /// /// add and parse data /// @@ -257,17 +289,44 @@ internal ProcessReceiveBufferResult LoadData() case HttpParsingState.Head: { //find html header - //check if complete or not + _contentByteCount = 0; //reset + _uploadCanceled = false;//reset + _readPos = ParseHttpRequestHeader(); + + if (ContentLength > InMemMaxUploadBodySize) + { + if (_largeFileUploadPermissionReqHandler != null) + { + //what to do with large file + LargetFileUploadPolicyResult permissionResult = new LargetFileUploadPolicyResult(); + _largeFileUploadPermissionReqHandler(this, permissionResult); + if (!permissionResult.Cancel && permissionResult.TempUploadFilename != null) + { + UploadTempFileName = permissionResult.TempUploadFilename; + } + else + { + UploadTempFileName = null; + _uploadCanceled = true; + } + } + + } + else + { + UploadTempFileName = null; //reset + } + if (_parseState == HttpParsingState.Body) { - ProcessHtmlPostBody(_readPos); + ProcessHtmlPostBody(); } } break; case HttpParsingState.Body: - ProcessHtmlPostBody(_readPos); + ProcessHtmlPostBody(); break; case HttpParsingState.Complete: break; @@ -365,9 +424,6 @@ int ParseHttpRequestHeader() //start from pos0 int readpos = 0; int lim = _context.RecvByteTransfer - 1; - - - int i = 0; for (; i <= lim; ++i) { @@ -410,41 +466,66 @@ int ParseHttpRequestHeader() return readpos; } + + int _readPos; - void ProcessHtmlPostBody(int readpos) + FileStream _uploadTempFile = null; + bool _uploadCanceled = false; + + void ProcessHtmlPostBody() { //parse body - int transferedBytes = _context.RecvByteTransfer; - int remaining = transferedBytes - readpos; - if (!IsMsgBodyComplete) - { - int wantBytes = ContentLength - _contentByteCount; - if (wantBytes <= remaining) + int len1 = transferedBytes - _readPos; + + if (!_uploadCanceled && len1 > 0) + { + //TODO review here + //write to file first, or write to mem *** + //if we upload large content, we should write to file + // + if (UploadTempFileName != null) { - //complete here - byte[] buff = new byte[wantBytes]; - _context.RecvCopyTo(readpos, buff, wantBytes); - //add to req - AddMsgBody(buff, 0, wantBytes); - - //complete - _parseState = HttpParsingState.Complete; - return; + //write data to file + if (_uploadTempFile == null) + { + _uploadTempFile = new FileStream(UploadTempFileName, FileMode.Create); + } + + byte[] buff = new byte[len1]; //TODO: reuse the buffer + _context.RecvCopyTo(_readPos, buff, len1); + _uploadTempFile.Write(buff, 0, len1); + _uploadTempFile.Flush();//** ensure write to disk } else { - //continue read - if (remaining > 0) - { - byte[] buff = new byte[remaining]; - _context.RecvCopyTo(readpos, buff, remaining); - //add to req - AddMsgBody(buff, 0, remaining); - } - return; + //write to mem + byte[] buff = new byte[len1]; //TODO: reuse the buffer + _context.RecvCopyTo(_readPos, buff, len1); + AddMsgBody(buff, 0, len1); } } + + _contentByteCount += len1; //*** + _readPos = 0; + //read until end of buffer + + //System.Diagnostics.Debug.WriteLine("expect" + ContentLength + "tx:" + _contentByteCount + ",rem:" + (ContentLength - _contentByteCount)); + + if (!IsMsgBodyComplete) + { + return; + } + + //finish + //close the file stream + if (_uploadTempFile != null) + { + _uploadTempFile.Close(); + _uploadTempFile.Dispose(); + _uploadTempFile = null; + } + _parseState = HttpParsingState.Complete; } } diff --git a/src/SharpConnect.WebServer/HttpWebServer0/WebServer.cs b/src/SharpConnect.WebServer/HttpWebServer0/WebServer.cs index a65f92d..b0f1029 100644 --- a/src/SharpConnect.WebServer/HttpWebServer0/WebServer.cs +++ b/src/SharpConnect.WebServer/HttpWebServer0/WebServer.cs @@ -33,6 +33,7 @@ public void LoadCertificate(string certFile, string psw) _certFile = certFile; _certPsw = psw; } + public LargeFileUploadPermissionReqHandler LargeFileUploadPermissionReqHandler { get; set; } /// /// use https @@ -49,6 +50,7 @@ public void Start() var httpsServer = new HttpsWebServer(_port, _localOnly, _reqHandler); httpsServer.LoadCertificate(_certFile, _certPsw); httpsServer.WebSocketServer = WebSocketServer; + httpsServer.LargeFileUploadPermissionReqHandler = this.LargeFileUploadPermissionReqHandler; httpsServer.Start(); _server = httpsServer; @@ -57,8 +59,8 @@ public void Start() { var httpServer = new HttpWebServer(_port, _localOnly, _reqHandler); httpServer.WebSocketServer = WebSocketServer; + httpServer.LargeFileUploadPermissionReqHandler = this.LargeFileUploadPermissionReqHandler; httpServer.Start(); - _server = httpServer; } } diff --git a/src/SharpConnect.WebServer/HttpWebServer1/HttpContext.cs b/src/SharpConnect.WebServer/HttpWebServer1/HttpContext.cs index 17bf1e8..1069d9a 100644 --- a/src/SharpConnect.WebServer/HttpWebServer1/HttpContext.cs +++ b/src/SharpConnect.WebServer/HttpWebServer1/HttpContext.cs @@ -49,9 +49,7 @@ class HttpContext : IHttpContext, ISendIO HttpRequestImpl _httpReq; HttpResponseImpl _httpResp; ReqRespHandler _reqHandler; - HttpWebServer _ownerServer; - - + HttpWebServer _ownerServer; public HttpContext( HttpWebServer ownerServer, @@ -76,6 +74,8 @@ public HttpContext( _sendIO = new SendIO(_send_a, _send_a.Offset, sendBufferSize, HandleSend); //---------------------------------------------------------------------------------------------------------- _httpReq = new HttpRequestImpl(this); + _httpReq.SetLargeUploadFilePolicyHandler(_ownerServer.LargeFileUploadPermissionReqHandler); + _httpResp = new HttpResponseImpl(this); //common(shared) event listener*** diff --git a/src/SharpConnect.WebServer/HttpWebServer2/HttpsContext.cs b/src/SharpConnect.WebServer/HttpWebServer2/HttpsContext.cs index 72001f5..f123f58 100644 --- a/src/SharpConnect.WebServer/HttpWebServer2/HttpsContext.cs +++ b/src/SharpConnect.WebServer/HttpWebServer2/HttpsContext.cs @@ -86,6 +86,8 @@ public HttpsContext( //ownerServer.SetBufferFor(this.recvSendArgs = new SocketAsyncEventArgs()); //---------------------------------------------------------------------------------------------------------- _httpReq = new HttpRequestImpl(this); + _httpReq.SetLargeUploadFilePolicyHandler(_ownerServer.LargeFileUploadPermissionReqHandler); + _httpResp = new HttpResponseImpl(this); } From 0d927b8834fc7468f86588a814f105ddfc167e2f Mon Sep 17 00:00:00 2001 From: enginekit Date: Wed, 4 Mar 2020 13:21:05 +0700 Subject: [PATCH 11/13] 64: fix websocket parser --- .../HttpWebServer0/SendIO_RecvIO_Code.cs | 16 +++++++++++++--- .../HttpWebServer1/RecvIO_SendIO.cs | 2 +- .../WebSocket/PlainWebSocketConn.cs | 5 ++++- .../WebSocket/WebSocketProtocolParser.cs | 12 ++++++++++++ tests/TestWsClient/Form1.cs | 2 +- tests/TestWsClient/TestWsClient.csproj | 1 - 6 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/SharpConnect.WebServer/HttpWebServer0/SendIO_RecvIO_Code.cs b/src/SharpConnect.WebServer/HttpWebServer0/SendIO_RecvIO_Code.cs index ac30bf5..4452e21 100644 --- a/src/SharpConnect.WebServer/HttpWebServer0/SendIO_RecvIO_Code.cs +++ b/src/SharpConnect.WebServer/HttpWebServer0/SendIO_RecvIO_Code.cs @@ -380,7 +380,7 @@ class RecvIOBufferStream : IDisposable { MemoryStream _ms = new MemoryStream(); int _latestReadPos = 0; - + public RecvIOBufferStream() { @@ -472,13 +472,23 @@ public byte ReadByte() { lock (_ms) { - _ms.Position = _latestReadPos; _latestReadPos++; return (byte)_ms.ReadByte(); } } - +#if DEBUG + public void dbugPeekBytes(byte[] output, int count) + { + lock (_ms) + { + _ms.Position = _latestReadPos; + long backup = _ms.Position; + _ms.Read(output, 0, count); + _ms.Position = backup; + } + } +#endif } } diff --git a/src/SharpConnect.WebServer/HttpWebServer1/RecvIO_SendIO.cs b/src/SharpConnect.WebServer/HttpWebServer1/RecvIO_SendIO.cs index 5200e85..3b2d53a 100644 --- a/src/SharpConnect.WebServer/HttpWebServer1/RecvIO_SendIO.cs +++ b/src/SharpConnect.WebServer/HttpWebServer1/RecvIO_SendIO.cs @@ -117,7 +117,7 @@ public void RecvCopyTo(byte[] target, int startAt, int len) public void RecvClearBuffer() { - throw new NotImplementedException(); + throw new NotSupportedException(); } } diff --git a/src/SharpConnect.WebServer/WebSocket/PlainWebSocketConn.cs b/src/SharpConnect.WebServer/WebSocket/PlainWebSocketConn.cs index 98dac87..247d94b 100644 --- a/src/SharpConnect.WebServer/WebSocket/PlainWebSocketConn.cs +++ b/src/SharpConnect.WebServer/WebSocket/PlainWebSocketConn.cs @@ -164,7 +164,10 @@ void HandleReceivedData(RecvEventCode recvCode) if (text.StartsWith("HTTP/1.1 101 Switching Protocols\r\nUpgrade")) { - _beginWebSocketMode = true; + //clear prev buffer + + _webSocketReqParser.ClearMemBuffer(); + _beginWebSocketMode = true; _recvIO.StartReceive(); ////*** clear prev buffer before new recv diff --git a/src/SharpConnect.WebServer/WebSocket/WebSocketProtocolParser.cs b/src/SharpConnect.WebServer/WebSocket/WebSocketProtocolParser.cs index 8c8f62c..014dd39 100644 --- a/src/SharpConnect.WebServer/WebSocket/WebSocketProtocolParser.cs +++ b/src/SharpConnect.WebServer/WebSocket/WebSocketProtocolParser.cs @@ -77,8 +77,19 @@ bool ReadHeader() //when we read header we start a new websocket request _currentReq = new WebSocketRequest(this.OwnerWebSocketConnBase); +#if DEBUG + //byte[] peek = new byte[8]; + //_myBufferStream.dbugPeekBytes(peek, 8); + + //System.Text.StringBuilder stbuilder = new System.Text.StringBuilder(); + //for (int i = 0; i < peek.Length; ++i) + //{ + // stbuilder.Append((char)peek[i]); + //} +#endif byte b1 = _myBufferStream.ReadByte(); + // FIN Fin fin = (b1 & (1 << 7)) == (1 << 7) ? Fin.Final : Fin.More; @@ -255,6 +266,7 @@ bool ReadMask() _parseState = ParseState.ExpectBody; return true; } + internal void ClearMemBuffer() => _myBufferStream.ForceClear(); internal ProcessReceiveBufferResult ParseRecvData() { diff --git a/tests/TestWsClient/Form1.cs b/tests/TestWsClient/Form1.cs index 45c5af6..eb64d4e 100644 --- a/tests/TestWsClient/Form1.cs +++ b/tests/TestWsClient/Form1.cs @@ -97,7 +97,7 @@ private void button4_Click(object sender, EventArgs e) private void button5_Click(object sender, EventArgs e) { - Examples.System.Net.SslTcpClient.Main1(); + } } } diff --git a/tests/TestWsClient/TestWsClient.csproj b/tests/TestWsClient/TestWsClient.csproj index 0cbd1ad..767700a 100644 --- a/tests/TestWsClient/TestWsClient.csproj +++ b/tests/TestWsClient/TestWsClient.csproj @@ -49,7 +49,6 @@ - Form1.cs From 39cbbbf43d570f975c56d50b2bce7cc9b6b6296d Mon Sep 17 00:00:00 2001 From: enginekit Date: Wed, 4 Mar 2020 13:38:11 +0700 Subject: [PATCH 12/13] 65: ListeningOnPort --- src/SharpConnect.WebServer/General/NewConnListener.cs | 8 ++++++-- src/SharpConnect.WebServer/HttpWebServer0/WebServer.cs | 5 +++-- .../HttpWebServer1/HttpWebServer.cs | 8 ++------ .../HttpWebServer2/HttpsWebServer.cs | 1 + 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/SharpConnect.WebServer/General/NewConnListener.cs b/src/SharpConnect.WebServer/General/NewConnListener.cs index 3e522b4..296335c 100644 --- a/src/SharpConnect.WebServer/General/NewConnListener.cs +++ b/src/SharpConnect.WebServer/General/NewConnListener.cs @@ -85,6 +85,11 @@ void InitListenSocket() //max # for backlog can be limited by the operating system. _listenSocket.Listen(_setting.Backlog); + if (_listenSocket.LocalEndPoint is System.Net.IPEndPoint ipEndPoint) + { + ListeningOnPort = ipEndPoint.Port; + } + //#if DEBUG // if (dbugLOG.watchProgramFlow) //for testing // { @@ -95,9 +100,8 @@ void InitListenSocket() // Calls the method which will post accepts on the listening socket. // This call just occurs one time from this StartListen method. // After that the StartAccept method will be called in a loop. - - } + public int ListeningOnPort { get; private set; } SocketAsyncEventArgs CreateSocketAsyncEventArgsForAccept() { diff --git a/src/SharpConnect.WebServer/HttpWebServer0/WebServer.cs b/src/SharpConnect.WebServer/HttpWebServer0/WebServer.cs index b0f1029..b32e5b1 100644 --- a/src/SharpConnect.WebServer/HttpWebServer0/WebServer.cs +++ b/src/SharpConnect.WebServer/HttpWebServer0/WebServer.cs @@ -34,7 +34,7 @@ public void LoadCertificate(string certFile, string psw) _certPsw = psw; } public LargeFileUploadPermissionReqHandler LargeFileUploadPermissionReqHandler { get; set; } - + public int ListeningOnPort { get; private set; } /// /// use https /// @@ -52,7 +52,7 @@ public void Start() httpsServer.WebSocketServer = WebSocketServer; httpsServer.LargeFileUploadPermissionReqHandler = this.LargeFileUploadPermissionReqHandler; httpsServer.Start(); - + ListeningOnPort = httpsServer.ListeningOnPort; _server = httpsServer; } else @@ -61,6 +61,7 @@ public void Start() httpServer.WebSocketServer = WebSocketServer; httpServer.LargeFileUploadPermissionReqHandler = this.LargeFileUploadPermissionReqHandler; httpServer.Start(); + ListeningOnPort = httpServer.ListeningOnPort; _server = httpServer; } } diff --git a/src/SharpConnect.WebServer/HttpWebServer1/HttpWebServer.cs b/src/SharpConnect.WebServer/HttpWebServer1/HttpWebServer.cs index 7dad4fd..04f9473 100644 --- a/src/SharpConnect.WebServer/HttpWebServer1/HttpWebServer.cs +++ b/src/SharpConnect.WebServer/HttpWebServer1/HttpWebServer.cs @@ -100,12 +100,7 @@ public void Start() HttpContext context = _contextPool.Pop(); context.BindSocket(clientSocket); //*** bind to client socket context.StartReceive(); //start receive data - }); - - - - - + }); //start web server _isRunning = true; _newConnListener.StartListening(); @@ -114,6 +109,7 @@ public void Start() { } } + public int ListeningOnPort => _newConnListener.ListeningOnPort; public void Stop() { _newConnListener.DisposePool(); diff --git a/src/SharpConnect.WebServer/HttpWebServer2/HttpsWebServer.cs b/src/SharpConnect.WebServer/HttpWebServer2/HttpsWebServer.cs index 21fea21..170f457 100644 --- a/src/SharpConnect.WebServer/HttpWebServer2/HttpsWebServer.cs +++ b/src/SharpConnect.WebServer/HttpWebServer2/HttpsWebServer.cs @@ -26,6 +26,7 @@ public HttpsWebServer(int port, bool localOnly, ReqRespHandler _newConnListener.ListeningOnPort; System.Security.Cryptography.X509Certificates.X509Certificate2 _serverCert; public void LoadCertificate(string certFile, string psw) From 0d00e36ed6db6cc020579be72890faaea1534d1e Mon Sep 17 00:00:00 2001 From: enginekit Date: Mon, 9 Mar 2020 12:57:45 +0700 Subject: [PATCH 13/13] 66: minor, SetHeader() --- .../HttpWebServer0/HttpResponse.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/SharpConnect.WebServer/HttpWebServer0/HttpResponse.cs b/src/SharpConnect.WebServer/HttpWebServer0/HttpResponse.cs index 264d010..f7a058c 100644 --- a/src/SharpConnect.WebServer/HttpWebServer0/HttpResponse.cs +++ b/src/SharpConnect.WebServer/HttpWebServer0/HttpResponse.cs @@ -236,6 +236,17 @@ public void ActualEnd() default: throw new NotSupportedException(); } + if (_headers.Count > 0) + { + foreach (var kv in _headers) + { + _headerStBuilder.Append(kv.Key); + _headerStBuilder.Append(": "); + _headerStBuilder.Append(kv.Value); + _headerStBuilder.Append("\r\n"); + } + } + //-------------------------------------------------------------------------------------------------------- switch (ContentEncoding) {