diff --git a/SharpConnect.WebServer.sln b/SharpConnect.WebServer.sln index a7be0ac..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}" @@ -27,11 +25,16 @@ 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 +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 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 diff --git a/builds/NET20/WebServerApp/WebServerApp.csproj b/builds/NET20/WebServerApp/WebServerApp.csproj index a68ae1b..52b87c6 100644 --- a/builds/NET20/WebServerApp/WebServerApp.csproj +++ b/builds/NET20/WebServerApp/WebServerApp.csproj @@ -8,7 +8,7 @@ Exe WebServerApp WebServerApp - v4.7.2 + v4.8 512 true diff --git a/builds/NET20/WebServerApp/app.config b/builds/NET20/WebServerApp/app.config index 312bb3f..3e0e37c 100644 --- a/builds/NET20/WebServerApp/app.config +++ b/builds/NET20/WebServerApp/app.config @@ -1,3 +1,3 @@ - + 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/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..296335c 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; @@ -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/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/HttpRequest.cs b/src/SharpConnect.WebServer/HttpWebServer0/HttpRequest.cs index 48ccbed..51414d2 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() { @@ -106,16 +106,11 @@ internal virtual void Reset() _targetContentLength = 0; } - public WebRequestParameter[] ReqParameters - { - get; - internal set; - } + public WebRequestParameter[] ReqParameters { get; internal set; } public string GetHeaderKey(string key) { - string found; - _headerKeyValues.TryGetValue(key, out found); + _headerKeyValues.TryGetValue(key, out string found); return found; } public string GetBodyContentAsString() @@ -136,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 { @@ -158,23 +174,38 @@ public HttpMethod HttpMethod get; internal set; } - 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() @@ -185,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 @@ -204,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; } } @@ -219,7 +247,6 @@ void AddMsgBody(byte[] buffer, int start, int count) else { _bodyMs.Write(buffer, start, count); - _contentByteCount += count; } } @@ -245,12 +272,12 @@ void AddHeaderInfo(string key, string value) case "Connection": { _context.KeepAlive = (value.ToLower().Trim() == "keep-alive"); - _context.KeepAlive = false; - } break; } } + + /// /// add and parse data /// @@ -262,16 +289,44 @@ internal ProcessReceiveBufferResult LoadData() case HttpParsingState.Head: { //find html header - int readpos = ParseHttpRequestHeader(); //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(0); + ProcessHtmlPostBody(); break; case HttpParsingState.Complete: break; @@ -369,9 +424,6 @@ int ParseHttpRequestHeader() //start from pos0 int readpos = 0; int lim = _context.RecvByteTransfer - 1; - - - int i = 0; for (; i <= lim; ++i) { @@ -414,39 +466,66 @@ int ParseHttpRequestHeader() return readpos; } - void ProcessHtmlPostBody(int readpos) + + + int _readPos; + FileStream _uploadTempFile = null; + bool _uploadCanceled = false; + + void ProcessHtmlPostBody() { //parse body int transferedBytes = _context.RecvByteTransfer; - int remaining = transferedBytes - readpos; - if (!IsMsgBodyComplete) + int len1 = transferedBytes - _readPos; + + if (!_uploadCanceled && len1 > 0) { - int wantBytes = ContentLength - _contentByteCount; - if (wantBytes <= remaining) - { - //complete here - byte[] buff = new byte[wantBytes]; - _context.RecvCopyTo(readpos, buff, wantBytes); - //add to req - AddMsgBody(buff, 0, wantBytes); - //complete - _parseState = HttpParsingState.Complete; - return; - } - else + //TODO review here + //write to file first, or write to mem *** + //if we upload large content, we should write to file + // + if (UploadTempFileName != null) { - //continue read - if (remaining > 0) + //write data to file + if (_uploadTempFile == null) { - byte[] buff = new byte[remaining]; - _context.RecvCopyTo(readpos, buff, remaining); - //add to req - AddMsgBody(buff, 0, remaining); + _uploadTempFile = new FileStream(UploadTempFileName, FileMode.Create); } - return; + 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 + { + //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/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) { diff --git a/src/SharpConnect.WebServer/HttpWebServer0/SendIO_RecvIO_Code.cs b/src/SharpConnect.WebServer/HttpWebServer0/SendIO_RecvIO_Code.cs index 1386386..4452e21 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 @@ -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/HttpWebServer0/WebServer.cs b/src/SharpConnect.WebServer/HttpWebServer0/WebServer.cs index a65f92d..b32e5b1 100644 --- a/src/SharpConnect.WebServer/HttpWebServer0/WebServer.cs +++ b/src/SharpConnect.WebServer/HttpWebServer0/WebServer.cs @@ -33,7 +33,8 @@ public void LoadCertificate(string certFile, string psw) _certFile = certFile; _certPsw = psw; } - + public LargeFileUploadPermissionReqHandler LargeFileUploadPermissionReqHandler { get; set; } + public int ListeningOnPort { get; private set; } /// /// use https /// @@ -49,16 +50,18 @@ public void Start() var httpsServer = new HttpsWebServer(_port, _localOnly, _reqHandler); httpsServer.LoadCertificate(_certFile, _certPsw); httpsServer.WebSocketServer = WebSocketServer; + httpsServer.LargeFileUploadPermissionReqHandler = this.LargeFileUploadPermissionReqHandler; httpsServer.Start(); - + ListeningOnPort = httpsServer.ListeningOnPort; _server = httpsServer; } else { var httpServer = new HttpWebServer(_port, _localOnly, _reqHandler); httpServer.WebSocketServer = WebSocketServer; + httpServer.LargeFileUploadPermissionReqHandler = this.LargeFileUploadPermissionReqHandler; httpServer.Start(); - + ListeningOnPort = httpServer.ListeningOnPort; _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/HttpWebServer1/HttpWebServer.cs b/src/SharpConnect.WebServer/HttpWebServer1/HttpWebServer.cs index f81f986..04f9473 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,27 @@ 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(); @@ -102,6 +109,7 @@ public void Start() { } } + public int ListeningOnPort => _newConnListener.ListeningOnPort; public void Stop() { _newConnListener.DisposePool(); diff --git a/src/SharpConnect.WebServer/HttpWebServer1/RecvIO_SendIO.cs b/src/SharpConnect.WebServer/HttpWebServer1/RecvIO_SendIO.cs index 8ab4c79..3b2d53a 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 @@ -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/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); } diff --git a/src/SharpConnect.WebServer/HttpWebServer2/HttpsWebServer.cs b/src/SharpConnect.WebServer/HttpWebServer2/HttpsWebServer.cs index 5b2843c..170f457 100644 --- a/src/SharpConnect.WebServer/HttpWebServer2/HttpsWebServer.cs +++ b/src/SharpConnect.WebServer/HttpWebServer2/HttpsWebServer.cs @@ -15,49 +15,18 @@ 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; } + public int ListeningOnPort => _newConnListener.ListeningOnPort; System.Security.Cryptography.X509Certificates.X509Certificate2 _serverCert; public void LoadCertificate(string certFile, string psw) @@ -115,6 +84,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(); 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/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/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 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/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 0d0e990..d29011e 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; @@ -55,29 +55,33 @@ public virtual WebSocketContentCompression Compression } - public virtual void Dispose() - { - } + public virtual void Dispose() { } public virtual void Close() { } public void SetMessageHandler(ReqRespHandler webSocketReqHandler) { _webSocketReqHandler = webSocketReqHandler; } - public void Send(string data) + public void SendTextData(string data) { //send data to server //and wait for result _webSocketResp.Compression = Compression; _webSocketResp.Write(data); } + public void SendTextData(byte[] data, int start, int len) + { + //send data to server + //and wait for result + _webSocketResp.Compression = Compression; + _webSocketResp.Write(data, start, len, false); + } public void SendBinaryData(byte[] data, int start, int len) { //send data to server //and wait for result _webSocketResp.Compression = Compression; _webSocketResp.Write(data, start, len); - } internal void InvokeReqHandler(WebSocketRequest req) { diff --git a/src/SharpConnect.WebServer/WebSocket/WebSocketContext.cs b/src/SharpConnect.WebServer/WebSocket/WebSocketContext.cs index be4df22..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 @@ -22,7 +22,7 @@ internal WebSocketContext(WebSocketConnectionBase webSocketConn) public int ConnectionId => _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..014dd39 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,17 +68,28 @@ internal void SetNewParseResultHandler(Action newResultHandler internal WebSocketConnectionBase OwnerWebSocketConnBase { get; private set; } bool ReadHeader() - { + { if (!_myBufferStream.Ensure(2)) - { + { return false; } //---------------------------------------------------------- //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; @@ -125,9 +136,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 +234,7 @@ bool ReadPayloadLen() { int extendedPayloadByteCount = (_currentPacketLen == 126 ? 2 : 8); if (!_myBufferStream.Ensure(extendedPayloadByteCount)) - { + { return false; } //---------------------------------------------------------- @@ -244,7 +256,7 @@ bool ReadPayloadLen() bool ReadMask() { if (!_myBufferStream.Ensure(_currentMaskLen)) - { + { return false; } //---------------------------------------------------------- @@ -254,6 +266,7 @@ bool ReadMask() _parseState = ParseState.ExpectBody; return true; } + internal void ClearMemBuffer() => _myBufferStream.ForceClear(); internal ProcessReceiveBufferResult ParseRecvData() { @@ -335,7 +348,7 @@ internal ProcessReceiveBufferResult ParseRecvData() bool ReadBodyContent(int readLen) { if (!_myBufferStream.Ensure(readLen)) - { + { return false; } //------------------------------------ diff --git a/src/SharpConnect.WebServer/WebSocket/WebSocketRequest.cs b/src/SharpConnect.WebServer/WebSocket/WebSocketRequest.cs index 7d9b3dc..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) @@ -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/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..81b704b 100644 --- a/src/SharpConnect.WebServer/WebSocket/WsClientSessionBase.cs +++ b/src/SharpConnect.WebServer/WebSocket/WsClientSessionBase.cs @@ -57,10 +57,10 @@ 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.Send(data); + _wbsocketConn.SendTextData(data); } public void SendBinaryData(byte[] data, int start, int len) { 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()); 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..eb64d4e 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) + { + + } } } 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..767700a 100644 --- a/tests/TestWsClient/TestWsClient.csproj +++ b/tests/TestWsClient/TestWsClient.csproj @@ -8,7 +8,7 @@ WinExe TestWsClient TestWsClient - v2.0 + v4.8 512 true 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 @@ - + 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;