internal static List <string> GetScopesFromCertificate(X509Certificate2 x509cert, ref string error) { string extensions = ""; List <string> scopeIds = new List <string>(); foreach (X509Extension extension in x509cert.Extensions) { // Create an AsnEncodedData object using the extensions information. AsnEncodedData asndata = new AsnEncodedData(extension.Oid, extension.RawData); extensions += $"{extension.Oid.FriendlyName} {asndata.Oid.Value} {asndata.RawData.Length} {asndata.Format(false)}"; try { if (extension.Oid.Value == "2.5.29.17") // SAN { string strSANEntry = asndata.Format(true); var lines = strSANEntry.Split(new[] { "\r\n", "\n\r", "\n", "\r" }, StringSplitOptions.None); foreach (var line in lines) { try { if (line.StartsWith("URL=")) { var scopeidUriStr = line.Substring("URL=".Length); var scopeidUri = TheCommonUtils.CUri(scopeidUriStr, true); if (scopeidUri.Scheme.ToLowerInvariant() == "com.c-labs.cdescope") { var scopeid = scopeidUri.Host; scopeIds.Add(scopeid); } } else if (line.StartsWith("URI:")) // TODO check why .Net Core on Linux returns a different prefix (openssl?) - are there platform agnostic ways of doing this? Are there other platforms with different behavior? { var scopeidUriStr = line.Substring("URI:".Length); var scopeidUri = TheCommonUtils.CUri(scopeidUriStr, true); if (scopeidUri.Scheme.ToLowerInvariant() == "com.c-labs.cdescope") { var scopeid = scopeidUri.Host; scopeIds.Add(scopeid); } } } catch (Exception e) { error += e.ToString(); } } } } catch (Exception e) { error += e.ToString(); } //Console.WriteLine("Extension type: {0}", extension.Oid.FriendlyName); //Console.WriteLine("Oid value: {0}", asndata.Oid.Value); //Console.WriteLine("Raw data length: {0} {1}", asndata.RawData.Length, Environment.NewLine); //Console.WriteLine(asndata.Format(true)); } TheBaseAssets.MySYSLOG.WriteToLog(2351, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("HttpService", $"{DateTimeOffset.Now}: {x509cert?.Subject} ScopeIds: {TheCommonUtils.CListToString(scopeIds, ",")} {error} [ Raw: {extensions} ] [Cert: {Convert.ToBase64String(x509cert.RawData)}]")); return(scopeIds); }
internal static TheRequestData CreateRequest(HttpContext pContext) { var tCon = pContext.Connection; TheRequestData tReq = new TheRequestData { RequestUri = TheCommonUtils.CUri(UriHelper.GetDisplayUrl(pContext.Request), false), HttpMethod = pContext.Request.Method, UserAgent = pContext.Request.Headers[HeaderNames.UserAgent], ResponseMimeType = pContext.Request.ContentType, ClientCert = tCon.ClientCertificate, RemoteAddress = tCon.RemoteIpAddress.ToString() }; if (TheCommCore.MyHttpService != null && TheBaseAssets.MyServiceHostInfo.ClientCertificateUsage > 1) //If CDE requires a certificate, terminate all incoming requests before any processing { var err = TheCommCore.MyHttpService.ValidateCertificateRoot(tReq); if (TheBaseAssets.MyServiceHostInfo.DisableNMI && !string.IsNullOrEmpty(err)) { var terr = $"WebSocket Access with worng Client Certificate root - access is denied: {err}"; TheBaseAssets.MySYSLOG.WriteToLog(423, new TSM("TheCloudWSockets", terr, eMsgLevel.l1_Error)); pContext.Response.StatusCode = (int)eHttpStatusCode.AccessDenied; return(null); } } tReq.Header = new cdeConcurrentDictionary <string, string>(); foreach (var t in pContext.Request.Headers) { tReq.Header[t.Key] = t.Value; } //if (Request.Browser != null) //{ // tReq.BrowserType = Request.Browser.Browser + " " + Request.Browser.Version; // tReq.BrowserPlatform = Request.Browser.Platform; // tReq.BrowserScreenWidth = Request.Browser.ScreenPixelsWidth; //} return(tReq); }
private static bool ProcessRedirect(TheRequestData pRequestData, string tTarget) { if (tTarget.StartsWith(pRequestData.RequestUri.Scheme)) //TODO:SSL to non SSL Scheme Mapping { #if !CDE_NET35 Uri tTargetUri = new Uri(tTarget); Uri tUrl = pRequestData.RequestUri; #else Uri tTargetUri = TheCommonUtils.CUri(tTarget, false); Uri tUrl = TheCommonUtils.CUri(pRequestData.RequestUri, false); #endif if (!string.IsNullOrEmpty(pRequestData.RequestUriString)) { #if !CDE_NET35 tUrl = new Uri(pRequestData.RequestUriString); #else tUrl = TheCommonUtils.CUri(pRequestData.RequestUriString, false); #endif } Uri tCloudUri = new Uri(tUrl.Scheme + "://" + tUrl.Host + ":" + tUrl.Port + tTargetUri.LocalPath + tTargetUri.Query); if (pRequestData.Header == null) { pRequestData.Header = new cdeConcurrentDictionary <string, string>(); } pRequestData.Header.TryAdd("Location", tCloudUri.ToString()); pRequestData.NewLocation = tCloudUri.ToString(); string tTgtHost = tTargetUri.Scheme + "://" + tTargetUri.Host; if ((tTargetUri.Scheme == "http" && tTargetUri.Port != 80) || (tTargetUri.Scheme == "https" && tTargetUri.Port != 443)) { tTgtHost += ":" + tTargetUri.Port; } string tReplUri = tUrl.Scheme + "://" + tUrl.Host; if ((tUrl.Scheme == "http" && tUrl.Port != 80) || (tUrl.Scheme == "https" && tUrl.Port != 443)) { tReplUri += ":" + tUrl.Port; } if (pRequestData.ResponseBuffer == null) { pRequestData.ResponseBufferStr = "<html><head><style>"; pRequestData.ResponseBufferStr += "div.cdeLiveTile {font-size: 24px; font-family: Arial,sans-serif; font-weight: bold; width:145px; height:145px; text-align:center; float: left; cursor: pointer; margin:5px; color: #2B8EFB; background-color: #EBDEC7; overflow: hidden; background-image: url('../Images/glasoverlay.png'); } "; pRequestData.ResponseBufferStr += "table.MyFullTableCentered { border: 0px; border-collapse: collapse; padding: 0px; width: 100%; height:100%; margin-left: auto; margin-right: auto; text-align: center; } "; pRequestData.ResponseBufferStr += "div.cdeTileText { margin: 5%; cursor: pointer; }"; pRequestData.ResponseBufferStr += "</style></head><body><div class='cdeLiveTile' onclick='location.href=\"" + tTargetUri + "\"'><table class='MyFullTableCentered'><tbody><tr><td><div class='cdeTileText'>Redirected!<br>Touch to go to App</div></td></tr></tbody></table></div></body></html>"; //pRequestData.ResponseBufferStr = "<html><a href='" + tTargetUri + "'>Click to see result</a><p>" + pRequestData.RequestUri + "<br>" + pRequestData.RequestUriString + "</html>"; pRequestData.ResponseBuffer = TheCommonUtils.CUTF8String2Array(pRequestData.ResponseBufferStr.Replace(tTgtHost, tReplUri)); pRequestData.ResponseMimeType = "text/html"; //pRequestData.StatusCode = 200; } pRequestData.RequestUri = tTargetUri; if (!string.IsNullOrEmpty(tTargetUri.AbsolutePath) && tTargetUri.AbsolutePath.Length > 1 && tTargetUri.AbsolutePath.Substring(1).Contains("/")) { return(false); } } else { #if !CDE_NET35 pRequestData.RequestUri = new Uri(pRequestData.RequestUri.Scheme + "://" + pRequestData.RequestUri.Host + ":" + pRequestData.RequestUri.Port + tTarget); #else var requestUri = TheCommonUtils.CUri(pRequestData.RequestUri, false); pRequestData.RequestUri = new Uri(requestUri.Scheme + "://" + requestUri.Host + ":" + requestUri.Port + tTarget); #endif if (tTarget.Length > 1 && tTarget.Substring(1).Contains("/")) { return(false); } } return(true); }
private void InterceptHttpRequest(TheRequestData pRequest, Guid MyApp, IBaseEngine MyBaseEngine, int pRequestTimeout) // TheRelayAppInfo MyApp) { if (MyApp == Guid.Empty) { return; } TheRequestData tOutBuffer = null; //NEW BY CM string tMagixc = Guid.NewGuid().ToString(); ReqBuffer.AddOrUpdateItem(TheCommonUtils.CGuid(tMagixc), null, null); if (!MyBaseEngine.GetEngineState().IsService) // || string.IsNullOrEmpty(MyApp.TargetUrl) || !TheCommonUtils.IsLocalhost(MyApp.HostUrl)) // !MyApp.HostUrl.Equals(TheBaseAssets.MyServiceHostInfo.MyStation URL)) { TSM tTSM = new TSM(MyBaseEngine.GetEngineName(), "WEBRELAY_REQUEST") { PLB = pRequest.PostData }; pRequest.PostData = null; pRequest.ResponseBuffer = null; if (!string.IsNullOrEmpty(pRequest.CookieString)) { pRequest.CookieString += ";"; } else { pRequest.CookieString = ""; } pRequest.CookieString += tMagixc; //if (string.IsNullOrEmpty(MyApp.CloudUrl)) MyApp.CloudUrl = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false); if (string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.RootDir)) { pRequest.RequestUriString = pRequest.RequestUri.ToString(); } else { pRequest.RequestUriString = pRequest.RequestUri.Scheme + "://" + pRequest.RequestUri.Host + ":" + pRequest.RequestUri.Port + pRequest.cdeRealPage; if (!string.IsNullOrEmpty(pRequest.RequestUri.Query)) { pRequest.RequestUriString += "?" + pRequest.RequestUri.Query; } } TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Requesting Page:{0}", pRequest.RequestUriString), eMsgLevel.l6_Debug)); tTSM.PLS = TheCommonUtils.SerializeObjectToJSONString(pRequest); tTSM.SID = pRequest.SessionState.GetSID(); //.SScopeID; TheCommCore.PublishCentral(tTSM); // .PublishToNode(MyApp.HostUrl, pRequest.SessionState.SScopeID, tTSM); } else { TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("AppID:{1} Requesting Page:{0}", pRequest.cdeRealPage, MyApp))); ReadHttpPage(pRequest, MyApp, tMagixc, sinkResults); } int SyncFailCount = 0; ManualResetEvent MyMRE = new ManualResetEvent(false); do { try { tOutBuffer = ReqBuffer.GetEntryByID(TheCommonUtils.CGuid(tMagixc)); if (tOutBuffer != null) { pRequest.ResponseBuffer = tOutBuffer.ResponseBuffer; pRequest.ResponseMimeType = tOutBuffer.ResponseMimeType; if (pRequest.SessionState.StateCookies == null) { pRequest.SessionState.StateCookies = new cdeConcurrentDictionary <string, string>(); } if (tOutBuffer.SessionState != null && tOutBuffer.SessionState.StateCookies != null && tOutBuffer != pRequest) { foreach (KeyValuePair <String, String> kvp in tOutBuffer.SessionState.StateCookies.GetDynamicEnumerable()) { string value; if (!pRequest.SessionState.StateCookies.TryGetValue(kvp.Key, out value)) { pRequest.SessionState.StateCookies.TryAdd(kvp.Key, kvp.Value); } else { pRequest.SessionState.StateCookies[kvp.Key] = kvp.Value; } } } if (!string.IsNullOrEmpty(tOutBuffer.ResponseBufferStr)) { pRequest.ResponseBufferStr = tOutBuffer.ResponseBufferStr; } else { if (pRequest.ResponseMimeType.StartsWith("text/html") || pRequest.ResponseMimeType.Contains("javascript")) //OK { pRequest.ResponseBufferStr = TheCommonUtils.CArray2UTF8String(tOutBuffer.ResponseBuffer); } } string tReqUri = pRequest.RequestUri.Host; if (pRequest.RequestUri.Port != 80) { tReqUri += ":" + pRequest.RequestUri.Port; } TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Got Response Page:{0}", tReqUri), eMsgLevel.l6_Debug)); if (!string.IsNullOrEmpty(pRequest.ResponseBufferStr) && (pRequest.ResponseMimeType.StartsWith("text/html") || pRequest.ResponseMimeType.Contains("javascript")) && pRequest.ResponseBufferStr.IndexOf(tReqUri, StringComparison.CurrentCultureIgnoreCase) >= 0) { if (pRequest.SessionState.ARApp != null && pRequest.SessionState.ARApp != Guid.Empty) { TheRelayAppInfo tMyApp = TheThingRegistry.GetThingObjectByMID(MyBaseEngine.GetEngineName(), pRequest.SessionState.ARApp) as TheRelayAppInfo; //MyRelayApps.MyMirrorCache.GetEntryByFunc(s => s.cdeMID.Equals(pRequest.SessionState.ARApp)); if (tMyApp != null && tMyApp.CloudUrl != null) { Uri tCloudUri = TheCommonUtils.CUri(tMyApp.CloudUrl, false); if (!string.IsNullOrEmpty(pRequest.NewLocation)) { pRequest.NewLocation = pRequest.NewLocation.Replace(pRequest.RequestUri.Scheme + "://" + tReqUri, tCloudUri.Scheme + "://" + tCloudUri.Host + ":" + tCloudUri.Port); } TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Patching Uri from:{0} to:{1}", tReqUri, tCloudUri), eMsgLevel.l6_Debug)); pRequest.ResponseBufferStr = pRequest.ResponseBufferStr.Replace(pRequest.RequestUri.Scheme + "://" + tReqUri, tCloudUri.Scheme + "://" + tCloudUri.Host + ":" + tCloudUri.Port); pRequest.ResponseBuffer = TheCommonUtils.CUTF8String2Array(pRequest.ResponseBufferStr); } } } break; } MyMRE.WaitOne(50); SyncFailCount++; if (SyncFailCount > (pRequestTimeout * 20)) { if (TheCommonUtils.IsMono()) { TheBaseAssets.MySYSLOG.WriteToLog(400, new TSM(MyBaseEngine.GetEngineName(), string.Format("Requesting Page:{0} FAILED", pRequest.cdeRealPage), eMsgLevel.l1_Error)); } else { TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Requesting Page:{0} FAILED", pRequest.cdeRealPage), eMsgLevel.l1_Error)); } break; } } catch (Exception ee) { TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Error during HttpIntercept for Page:{0}", pRequest.cdeRealPage), eMsgLevel.l1_Error, ee.ToString())); } } while (tOutBuffer == null); if (MyMRE != null) { MyMRE = null; //.Dispose(); } if ((pRequest.ResponseBuffer == null && string.IsNullOrEmpty(pRequest.ResponseBufferStr)) || pRequest.StatusCode != 0) { if (pRequest.StatusCode == 0) { pRequest.StatusCode = 404; } } else { pRequest.AllowStatePush = true; pRequest.StatusCode = 200; } ReqBuffer.RemoveAnItemByID(TheCommonUtils.CGuid(tMagixc), null); }
private void parseRequest(TheRequestData pReqData) { firstRequestLine = streamReadLine(mRequestStream); string[] tokens = firstRequestLine.Split(' '); if (tokens.Length != 3) { throw new Exception("HttpMidiServer: invalid http request head-line"); } pReqData.HttpMethod = tokens[0].ToUpper(); pReqData.RequestUri = tokens[1].StartsWith("http", StringComparison.OrdinalIgnoreCase) ? TheCommonUtils.CUri(tokens[1], false) : TheCommonUtils.CUri(TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false) + tokens[1], false); pReqData.HttpVersionStr = tokens[2]; pReqData.HttpVersion = TheCommonUtils.CDbl(pReqData.HttpVersionStr.Split('/')[1]); }
public bool RegisterDevice(TheUPnPDeviceInfo pNewDevice, bool ForceUpdate) { TheDiagnostics.SetThreadName("UPnP-Notify", true); if (!TheBaseAssets.MasterSwitch || (TheCommonUtils.cdeIsLocked(LockNotify) && !ForceUpdate) || string.IsNullOrEmpty(pNewDevice?.LocationURL)) { return(false); } lock (LockNotify) { TheUPnPDeviceInfo tHistory = null; //tHistory = MyUPnPDiscoveryPast.MyMirrorCache.GetEntryByFunc((s) => s.LocationURL.Equals(pNewDevice.LocationURL, StringComparison.OrdinalIgnoreCase)); // string[] tUsn = pNewDevice.USN.Split(':'); string tNewUsn = pNewDevice.USN; if (tUsn.Length > 2) { tNewUsn = tUsn[0] + ':' + tUsn[1]; } tHistory = MyUPnPDiscoveryPast.MyMirrorCache.GetEntryByFunc((s) => s.USN.StartsWith(tNewUsn, StringComparison.OrdinalIgnoreCase)); // if (tHistory != null) //gUSN { try { tHistory.SourceIP = IPAddress.TryParse(pNewDevice.LocationURL.Split(':')[0], out IPAddress tIp) ? pNewDevice.LocationURL : new Uri(pNewDevice.LocationURL).Host; tHistory.LocationURL = pNewDevice.LocationURL; if (DateTimeOffset.Now.Subtract(tHistory.LastSeenAt).TotalSeconds < tHistory.MaxAge) { MyUPnPDiscoveryPast.MyMirrorCache.AddOrUpdateItem(tHistory); //gUSN if (tHistory.IsCDEngine) { ProcessCDEngine(tHistory, TheCommonUtils.CUri(tHistory.LocationURL, false)); } else { CheckForDeviceMatch(tHistory, null); } return(true); } tHistory.LastSeenAt = DateTimeOffset.Now; } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(111, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("UPnP", string.Format("UPnP {0} Invalid Device URL", pNewDevice), eMsgLevel.l1_Error, e.ToString())); return(false); } } if (tHistory == null) { tHistory = pNewDevice; } MyUPnPDiscoveryPast.MyMirrorCache.AddOrUpdateItem(tHistory); //gUSN Uri tLocationUrl; try { tLocationUrl = TheCommonUtils.CUri(tHistory.LocationURL, false); TheBaseAssets.MySYSLOG.WriteToLog(111, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("UPnP", string.Format("UPnP {0} Device Found", tHistory), eMsgLevel.l3_ImportantMessage)); CheckForDeviceMatch(tHistory, tLocationUrl); } catch (Exception eee) { TheBaseAssets.MySYSLOG.WriteToLog(111, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("UPnP", string.Format("Non UPnP conform device found: {0}", tHistory), eMsgLevel.l7_HostDebugMessage, eee.ToString())); return(false); } if (tHistory.IsCDEngine) { ProcessCDEngine(tHistory, tLocationUrl); } } return(true); }
public void TheRESTSenderThread() { if (IsSenderThreadRunning) { return; } try { TheDiagnostics.SetThreadName($"QSender:{MyTargetNodeChannel} SenderThread", true); MyREST = new TheREST(); IsSenderThreadRunning = true; StringBuilder tSendBufferStr = new StringBuilder(TheBaseAssets.MyServiceHostInfo?.IsMemoryOptimized == true ? 1024 : TheBaseAssets.MAX_MessageSize[(int)MyTargetNodeChannel.SenderType] * 2); TargetUri = TheCommonUtils.CUri(MyTargetNodeChannel.TargetUrl, true); TargetUriPath = TargetUri.AbsolutePath; int QDelay = TheCommonUtils.CInt(TheBaseAssets.MySettings.GetSetting("ThrottleWS")); if (QDelay < 2) { QDelay = 2; } if (MyTargetNodeChannel.SenderType == cdeSenderType.CDE_JAVAJASON && TheBaseAssets.MyServiceHostInfo.WsJsThrottle > QDelay) { QDelay = TheBaseAssets.MyServiceHostInfo.WsJsThrottle; } mre = new ManualResetEvent(false); if (eventSenderThreadRunning != null) { TheCommonUtils.cdeRunAsync("EventSenderThreadRunning", true, (p) => { eventSenderThreadRunning(this); }); } MyISBlock?.FireEvent("SenderThreadCreated"); while (TheBaseAssets.MasterSwitch && IsAlive && IsSenderThreadRunning) { if (QDelay > 2) { mre.WaitOne(QDelay); //Throtteling should be here not in the wait loop } int WaitCounter = 0; while (TheBaseAssets.MasterSwitch && IsAlive && IsSenderThreadRunning && ((MyCoreQueue.Count == 0 && IsConnected) || IsConnecting || IsInPost || MyREST.IsPosting > (IsConnected?TheBaseAssets.MyServiceHostInfo.ParallelPosts:0))) { // CODE REVIEW: This was seen looping after service route to local node was closed (due to node shutdown): IsCOnnecting/IsConnected/IsInPost were false; ISAlive true. MyREST.IsPosting was 8. Queue count ~345 // This should be fixed now with IsSenderThreadRunning in the loop (I was wrong :) this happens only with cloud connections where POST fails and the IsPosting was not reset properly). // Update: If found the same problem. Sometime IsPosting is not reduced properly when a Timeout or other error occured during Posting if (IsInPost && MyCoreQueue.Count > 100) { TheBaseAssets.MySYSLOG.WriteToLog(235, new TSM("QueuedSender", $"IsInPost was still on and has been reset for {MyTargetNodeChannel?.ToMLString()}", eMsgLevel.l2_Warning)); IsInPost = false; } if (!IsConnected) { if (IsConnecting && MyREST.IsPosting == 0) { TheBaseAssets.MySYSLOG.WriteToLog(235, new TSM("QueuedSender", $"IsConnecting is set but no Pending Post {MyTargetNodeChannel?.ToMLString()} - resetting IsConnecting", eMsgLevel.l2_Warning)); IsConnecting = false; } if (!IsConnecting && MyREST.IsPosting > (IsConnected ? 10 : 0)) { WaitCounter++; if (WaitCounter > (10000 / QDelay)) { TheBaseAssets.MySYSLOG.WriteToLog(235, new TSM("QueuedSender", $"MyREST.IsPosting ({MyREST.IsPosting}) was higher then expected...possible POST problem. Resetting POST Counter for {MyTargetNodeChannel?.ToMLString()}", eMsgLevel.l2_Warning)); MyREST.IsPosting = 0; } } } mre.WaitOne(QDelay); } if (!TheBaseAssets.MasterSwitch || !IsAlive || !IsSenderThreadRunning) { IsInPost = false; break; } IsInPost = true; if (MyTargetNodeChannel.SenderType == cdeSenderType.CDE_BACKCHANNEL || MyTargetNodeChannel.SenderType == cdeSenderType.CDE_PHONE || MyTargetNodeChannel.SenderType == cdeSenderType.CDE_DEVICE || MyTargetNodeChannel.SenderType == cdeSenderType.CDE_JAVAJASON) { TheBaseAssets.MySYSLOG.WriteToLog(235, new TSM("QueuedSender", $"QSender Should NEVER GO HERE because SenderType is {MyTargetNodeChannel?.ToMLString()}", eMsgLevel.l1_Error)); IsInPost = false; IsSenderThreadRunning = false; return; } //NEW3.124: Sender Loop has to terminate if Cloud was Disabled. if (MyTargetNodeChannel.SenderType == cdeSenderType.CDE_CLOUDROUTE && (TheBaseAssets.MyServiceHostInfo.IsCloudDisabled || string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.ServiceRoute) || !TheBaseAssets.MyServiceHostInfo.HasServiceRoute(TargetUri))) //ServiceRoute can contain multiple routes... { break; } TheCoreQueueContent tQueued = null; int MCQCount = 0; int IsBatchOn = 0; #if CDE_NET35 tSendBufferStr = new StringBuilder(TheBaseAssets.MAX_MessageSize[(int)MyTargetNodeChannel.SenderType] * 2); #else tSendBufferStr.Clear(); #endif tSendBufferStr.Append("["); byte[] BinSendBuffer = null; do { if (!IsConnected) { tQueued = new TheCoreQueueContent(); IsConnecting = true; ConnectRetries = 0; if (CloudInRetry) { var count = Interlocked.Increment(ref CloudRetryCount); if (count > 10) { int delaySeconds = TheBaseAssets.MyServiceHostInfo.HeartbeatDelay * TheBaseAssets.MyServiceHostInfo.TO.HeartBeatRate; TheBaseAssets.MySYSLOG.WriteToLog(235, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("QueuedSender", $"Too many retries for {MyTargetNodeChannel?.ToMLString()}: {count}. Waiting {delaySeconds} seconds.", eMsgLevel.l2_Warning)); TheCommonUtils.SleepOneEye((uint)delaySeconds * 1000, 100); Interlocked.Exchange(ref CloudRetryCount, 0); } if (!TheBaseAssets.MasterSwitch || !IsAlive || !IsSenderThreadRunning || (MyTargetNodeChannel.SenderType == cdeSenderType.CDE_CLOUDROUTE && (TheBaseAssets.MyServiceHostInfo.IsCloudDisabled || string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.ServiceRoute) || !TheBaseAssets.MyServiceHostInfo.HasServiceRoute(TargetUri)))) { //Very rare but required after Sleep throw new Exception("QSender had to be terminated in Cloud Retry due to disabling of ServiceRoute or C-DEngine Shutdown"); } }//NEW3.124: Sender Loop has to terminate if Cloud was Disabled. if (MyTargetNodeChannel.SenderType == cdeSenderType.CDE_CLOUDROUTE && (TheBaseAssets.MyServiceHostInfo.IsCloudDisabled || string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.ServiceRoute) || !TheBaseAssets.MyServiceHostInfo.HasServiceRoute(TargetUri))) { break; } } else { if (CloudInRetry) { CloudInRetry = false; IsInPost = false; continue; } tQueued = GetNextMessage(out MCQCount); } if (tQueued != null) { TheCDEKPIs.IncrementKPI(eKPINames.QSSent); if (tQueued.OrgMessage == null && !IsConnecting) { if (MySubscriptions.Count == 0) { if (IsBatchOn == 0) //Only jump out if no telegrams are in batch.. { IsInPost = false; continue; } } if (IsBatchOn == 0) //If telegrams are in the batch dont send short message { BinSendBuffer = new byte[1]; BinSendBuffer[0] = (byte)((int)(TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.SenderType)).ToString()[0]; break; } } if (tQueued.OrgMessage != null && tQueued.OrgMessage.ToCloudOnly() && MyTargetNodeChannel.SenderType == cdeSenderType.CDE_CLOUDROUTE) { tQueued.OrgMessage.SetToCloudOnly(false); } TheDeviceMessage tDev = new TheDeviceMessage { DID = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID.ToString() // MyTargetNodeChannel.cdeMID.ToString(); }; if (MyTargetNodeChannel.MySessionState != null) { //BUGFIX: After fast Cloud Disconnect/reconnect-Relay lost Scopeing because it Scope was not properly stored in SessionState if (string.IsNullOrEmpty(MyTargetNodeChannel.MySessionState.SScopeID) && TheBaseAssets.MyScopeManager.IsScopingEnabled) { MyTargetNodeChannel.MySessionState.SScopeID = TheBaseAssets.MyScopeManager.GetScrambledScopeID(); //GRSI: rare } if (TheBaseAssets.MyServiceHostInfo.EnableFastSecurity) { tDev.SID = MyTargetNodeChannel.MySessionState.SScopeID; } else { tDev.SID = TheBaseAssets.MyScopeManager.GetScrambledScopeID(MyTargetNodeChannel.MySessionState.SScopeID, false); //GRSI: high frequency! } } else { tDev.SID = TheBaseAssets.MyScopeManager.GetScrambledScopeID(); //GRSI: rare } tDev.MSG = tQueued.OrgMessage; tDev.FID = "1"; if (IsConnecting) { tDev.TOP = TheCommCore.SetConnectingBufferStr(MyTargetNodeChannel, null); } else { tDev.TOP = tQueued.Topic; tQueued.OrgMessage?.GetNextSerial(tQueued.SubMsgCnt); if (MyTargetNodeChannel.MySessionState != null) { tDev.FID = MyTargetNodeChannel.MySessionState.GetNextSerial().ToString(); //(SendCounter + 1).ToString(); //V3B3: New was empty //V4.1010: Same as WS now } } #region Batch Serialization IsBatchOn++; if (MCQCount == 0 || IsBatchOn > TheBaseAssets.MyServiceHostInfo.MaxBatchedTelegrams || tQueued.IsChunked) { if (MCQCount != 0) { tDev.CNT = MCQCount; } IsBatchOn = 0; } else { if (tSendBufferStr.Length > TheBaseAssets.MAX_MessageSize[(int)MyTargetNodeChannel.SenderType]) { tDev.CNT = MCQCount; IsBatchOn = 0; } } if (tSendBufferStr.Length > 1) { tSendBufferStr.Append(","); } tSendBufferStr.Append(TheCommonUtils.SerializeObjectToJSONString(tDev)); #endregion } else { IsBatchOn = 0; } } while (IsBatchOn > 0 && IsInPost && TheBaseAssets.MasterSwitch); if ((!IsInPost || tSendBufferStr.Length < 2) && BinSendBuffer == null) { IsInPost = false; continue; } string tMimeType = "application/octet-stream"; if (BinSendBuffer == null) { tSendBufferStr.Append("]"); if (MyTargetNodeChannel.SenderType == cdeSenderType.CDE_MINI || TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.SenderType == cdeSenderType.CDE_MINI) { tMimeType = "application/json"; BinSendBuffer = TheCommonUtils.CUTF8String2Array(tSendBufferStr.ToString()); } else { tMimeType = "application/x-gzip"; BinSendBuffer = TheCommonUtils.cdeCompressString(tSendBufferStr.ToString()); } } if (MyTargetNodeChannel == null) { TheBaseAssets.MySYSLOG.WriteToLog(235, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("QueuedSender", $"Channel was deleted - exiting SenderThread", eMsgLevel.l2_Warning)); IsInPost = false; break; } string ISBPath = new Uri(TargetUri, TheBaseAssets.MyScopeManager.GetISBPath(TargetUriPath, TheCommonUtils.GetOriginST(MyTargetNodeChannel), MyTargetNodeChannel.SenderType, MyTargetNodeChannel.MySessionState == null? 1: MyTargetNodeChannel.MySessionState.FID /*Interlocked.Increment(ref SendCounter)*/, (MyTargetNodeChannel.MySessionState == null || !IsConnected) ?Guid.Empty: MyTargetNodeChannel.MySessionState.cdeMID, MyTargetNodeChannel.IsWebSocket)).ToString(); //V3B4: changed from TheBaseAssets.MyServiceHostInfo.MyDeviceInfo TheRequestData pData = new TheRequestData { RemoteAddress = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false), RequestUri = new Uri(ISBPath), PostData = BinSendBuffer, ResponseMimeType = tMimeType, DeviceID = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID, HttpMethod = "POST" }; if (!TheCertificates.SetClientCert(pData, MyTargetNodeChannel?.ClientCertificateThumb)) { throw new Exception("Client Certificate could not be added"); } MyREST.PostRESTAsync(pData, sinkUploadDataCompleted, FireSenderProblem); if (BinSendBuffer != null) { TheCDEKPIs.IncrementKPI(eKPINames.QKBSent, BinSendBuffer.Length); } IsInPost = false; } FlushQueue(); TheBaseAssets.MySYSLOG.WriteToLog(235, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("QueuedSender", $"QSenderThread was closed for {MyTargetNodeChannel?.ToMLString()}", eMsgLevel.l6_Debug)); } catch (Exception e) { IsInPost = false; TheBaseAssets.MySYSLOG.WriteToLog(235, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("QueuedSender", "Exception in jcSenderThread.", eMsgLevel.l1_Error, "Error:" + e)); if (MyTargetNodeChannel?.SenderType != cdeSenderType.CDE_BACKCHANNEL) { FireSenderProblem(new TheRequestData() { ErrorDescription = $"1308:{e}" }); } } finally { IsSenderThreadRunning = false; IsAlive = false; IsInPost = false; CloudInRetry = false; StopHeartBeat(); } }
public bool Startup(ushort pPort, bool IsOnThread) { if (pPort == 0) //new in 4.211: If no MyStationPort is specified, Webserver is disabled and cdeNodeType falls back to "Active" (outbound only) { TheBaseAssets.MySYSLOG.WriteToLog(4340, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("HttpMidiServer", "WebServer NOT started as no station Port was specified", eMsgLevel.l3_ImportantMessage)); return(false); } if (!TheBaseAssets.MyServiceHostInfo.UseTcpListenerInsteadOfHttpListener) { try { mHttpListener = new HttpListener(); #if !CDE_NET35 Uri tUri = new Uri(TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false)); #else Uri tUri = TheCommonUtils.CUri(TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false), false); #endif MyHttpUrl = tUri.Scheme + "://*"; // +tUri.Host; if ((tUri.Scheme.Equals("https") && tUri.Port != 443) || (tUri.Scheme.Equals("http") && tUri.Port != 80)) { MyHttpUrl += ":" + pPort; // tUri.Port; } MyHttpUrl += "/"; mHttpListener.Prefixes.Add(MyHttpUrl); mHttpListener.Start(); TheBaseAssets.MySYSLOG.WriteToLog(4340, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("HttpMidiServer", $"HttpListener started listening on port: {pPort}", eMsgLevel.l3_ImportantMessage)); IsHttpListener = true; IsActive = true; } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(4341, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("HttpMidiServer", $"HttpListener on port:{pPort} failed to Start", eMsgLevel.l2_Warning, e.ToString())); mHttpListener = null; } } else { mHttpListener = null; } if (mHttpListener == null) { try { mPort = pPort; mListener = new TcpListener(IPAddress.Any, mPort); mListener.Start(); if (TheBaseAssets.MyServiceHostInfo.FailOnAdminCheck) //New in 4.207: This was the original intension of the IgnoreAdminCheck (Bug#1544). In order to keep the current behavior the Flag was inverted { TheBaseAssets.MySYSLOG.WriteToLog(4342, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("HttpMidiServer", "TcpListener started but HttpListener Failed. This is an indicator that this node is not running As Administrator. Please restart with Admin rights or set IgnoreAdminCheck=true - Client Certificates WILL NOT WORK!", eMsgLevel.l3_ImportantMessage, $"Port: {pPort}")); return(false); } TheBaseAssets.MySYSLOG.WriteToLog(4342, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("HttpMidiServer", $"TcpListener started on port:{pPort} (Failed to start HttpListener - Not run as admin?) - IgnoreAdminCheck is true - Node will continue in User-Mode but Client Certificates WILL NOT WORK!", eMsgLevel.l3_ImportantMessage)); IsActive = true; } catch (Exception ee) { TheBaseAssets.MySYSLOG.WriteToLog(4343, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("HttpMidiServer", $"HttpMidiServer:TcpListener start Failed - Port Conflict? There might be another application/server using Port {mPort}", eMsgLevel.l2_Warning, $"{ee.ToString()}")); return(IsActive); } } TheCommonUtils.cdeRunTaskAsync("MidiWebServer - Processing Thread", o => // new Thread(() => { while (IsActive && TheBaseAssets.MasterSwitch) { try { if (mHttpListener != null) { HttpListenerContext context = mHttpListener.GetContext(); #if CDE_USEWSS8 TheBaseAssets.MySYSLOG.WriteToLog(4343, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("HttpMidiServer", $"Incoming Request. IsWebSocketRequest:{context.Request.IsWebSocketRequest}", eMsgLevel.l3_ImportantMessage)); if (!TheBaseAssets.MyServiceHostInfo.DisableWebSockets && TheBaseAssets.MyServiceHostInfo.MyStationWSPort > 0 && TheBaseAssets.MyServiceHostInfo.MyStationWSPort == TheBaseAssets.MyServiceHostInfo.MyStationPort && context.Request.IsWebSocketRequest) { if (!TheBaseAssets.MyServiceHostInfo.DisableWebSockets && TheBaseAssets.MyServiceHostInfo.MyStationWSPort > 0) //TheBaseAssets.MyServiceHostInfo.MyStationWSPort==TheBaseAssets.MyServiceHostInfo.MyStationPort { TheCommonUtils.cdeRunAsync("WSWait4AcceptThread", false, async oo => { try { await TheWSServer8.WaitForWSAccept(context); } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(4344, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("TheWSServer", "Error During WSAccept", eMsgLevel.l1_Error, e.ToString())); IsActive = false; } }); } } else #endif { TheCommonUtils.cdeRunAsync("MidiWebServer-HttpProcessing", false, (p) => { //TheSystemMessageLog.ToCo("HTTP Connected and processing", true); var tmyProcessor = new cdeHttpProcessor(); tmyProcessor.ProcessHttpRequest(p as HttpListenerContext); }, context); } } else { TcpClient s = mListener.AcceptTcpClient(); TheCommonUtils.cdeRunAsync("MidiWebServer-Processing", false, p => { var tmyProcessor = new cdeHttpProcessor(); //TheSystemMessageLog.ToCo("TCP Connected and processing", true); tmyProcessor.ProcessRequest(p as TcpClient, this); }, s); } } catch (Exception e) { if (!(e is HttpListenerException) || TheBaseAssets.MasterSwitch) { TheBaseAssets.MySYSLOG.WriteToLog(4345, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("HttpMidiServer", "Failed - Will Stop!", eMsgLevel.l1_Error, e.ToString())); } else { TheBaseAssets.MySYSLOG.WriteToLog(4345, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("HttpMidiServer", "Failed - Will Stop!", eMsgLevel.l4_Message, e.ToString())); } IsActive = false; } } ShutDown(); }, null, true); //.Start(); return(IsActive); }
internal override bool Connect(TheQueuedSender pSender) { if (pSender == null) // || pSender.IsConnecting) return false; if (pSender.IsConnected) return true; IsClient = true; if (MyQSender == null) MyQSender = pSender; Uri TargetUri = TheCommonUtils.CUri(pSender.MyTargetNodeChannel.TargetUrl, true); string TargetUriPath = TargetUri.AbsolutePath; OwnerNodeID = MyQSender.MyTargetNodeChannel.cdeMID; Uri tTarget = new Uri(TargetUri, TheBaseAssets.MyScopeManager.GetISBPath(TargetUriPath, TheCommonUtils.GetOriginST(pSender.MyTargetNodeChannel), pSender.MyTargetNodeChannel.SenderType, 1, Guid.Empty, true)); tTarget = tTarget.SetWSInfo(tTarget.Port, ""); try { IsActive = true; CloseFired = false; ConnectSuccess = true; if (websocket != null && !websocket.IsAlive) { try { websocket.OnError -= websocket_OnError; websocket.OnOpen -= websocket_Opened; websocket.OnMessage -= websocket_OnMessage; websocket.OnClose -= websocket_OnClose; websocket.Close(); TheBaseAssets.MySYSLOG.WriteToLog(8812, new TSM("WSProcessorConnect", string.Format("Websockets were still valid but not alive: closed and will recreate! IsConnecting:{0}", pSender.IsConnecting), eMsgLevel.l4_Message)); } catch { TheBaseAssets.MySYSLOG.WriteToLog(8812, new TSM("WSProcessorConnect", string.Format("Websockets were still valid but not alive: Error while closing, will recreate. Possible socket leak! IsConnecting:{0}", pSender.IsConnecting), eMsgLevel.l4_Message)); } finally { websocket = null; } } if (websocket == null) { websocket = new WebSocket(tTarget.ToString()); if (!string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.ProxyUrl)) { try { websocket.SetProxy(TheBaseAssets.MyServiceHostInfo.ProxyUrl, TheBaseAssets.MyServiceHostInfo.ProxyUID, TheBaseAssets.MyServiceHostInfo.ProxyPWD); TheBaseAssets.MySYSLOG.WriteToLog(8812, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("WSProcessorCSWS", $"Websockets proxy set: {TheBaseAssets.MyServiceHostInfo.ProxyUrl} UID: {!string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.ProxyUID)} PWD: {!string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.ProxyPWD)}", eMsgLevel.l4_Message)); } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(4365, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("WSProcessor", "Error setting Proxy credentials:", eMsgLevel.l1_Error, e.ToString())); } } websocket.Log.Level = LogLevel.Fatal; websocket.Log.Output = sinkLog; websocket.SslConfiguration.ServerCertificateValidationCallback += TheCommCore.ValidateServerCertificate; var myTargetNodeChannel = MyQSender?.MyTargetNodeChannel; if (!string.IsNullOrEmpty(myTargetNodeChannel?.ClientCertificateThumb)) { try { X509Certificate2Collection certs = TheCertificates.GetClientCertificatesByThumbprint(myTargetNodeChannel?.ClientCertificateThumb); if (certs?.Count < 1) { TheBaseAssets.MySYSLOG.WriteToLog(4365, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("WSProcessor", $"Error setting Client Certificate - Requested Cert with Thumbprint {myTargetNodeChannel?.ClientCertificateThumb} not found", eMsgLevel.l1_Error)); return false; } websocket.SslConfiguration.ClientCertificates = certs; websocket.SslConfiguration.ClientCertificateSelectionCallback = wsSharpClientCertSelector; } catch (Exception certex) { TheBaseAssets.MySYSLOG.WriteToLog(4365, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("WSProcessor", "Error setting Client Certificate", eMsgLevel.l1_Error, certex.ToString())); return false; } } websocket.OnError += websocket_OnError; websocket.OnOpen += websocket_Opened; websocket.OnMessage += websocket_OnMessage; websocket.OnClose += websocket_OnClose; websocket.Connect(); } else TheBaseAssets.MySYSLOG.WriteToLog(8812, new TSM("WSProcessorConnect", string.Format("Websockets are still valid and will be recycled! IsConnecting:{0}",pSender.IsConnecting),eMsgLevel.l4_Message)); } catch (Exception ex) { Shutdown(true, "1650:Connect Failed: " + ex); } return ConnectSuccess; }
internal override bool Connect(TheQueuedSender pSender) { if (pSender == null /*|| pSender.MyTargetNodeChannel==null*/) { return(false); } if (pSender.IsConnected) { return(true); } IsClient = true; if (MyQSender == null) { MyQSender = pSender; } var _MyTargetNodeChannel = pSender?.MyTargetNodeChannel; Uri TargetUri = TheCommonUtils.CUri(_MyTargetNodeChannel?.TargetUrl, true); if (TargetUri == null) { TheBaseAssets.MySYSLOG.WriteToLog(4365, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("WSProcessor", "Invalid Target URL", eMsgLevel.l1_Error, $"{_MyTargetNodeChannel?.ToString()}")); return(false); } OwnerNodeID = _MyTargetNodeChannel.cdeMID; string TargetUriPath = TargetUri.AbsolutePath; Uri tTarget = new Uri(TargetUri, TheBaseAssets.MyScopeManager.GetISBPath(TargetUriPath, TheCommonUtils.GetOriginST(_MyTargetNodeChannel), _MyTargetNodeChannel.SenderType, 1, Guid.Empty, true)); tTarget = tTarget.SetWSInfo(tTarget.Port, ""); string connectFailureReason = ""; try { IsActive = true; CloseFired = false; ConnectSuccess = false; ClientWebSocket wsClientSocket = new ClientWebSocket(); websocket = wsClientSocket; if (!string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.ProxyUrl)) { try { System.Net.NetworkCredential tNet = null; if (!string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.ProxyUID)) { tNet = new System.Net.NetworkCredential(TheBaseAssets.MyServiceHostInfo.ProxyUID, TheBaseAssets.MyServiceHostInfo.ProxyPWD); } if (wsClientSocket.Options != null) { wsClientSocket.Options.Proxy = new System.Net.WebProxy(TheBaseAssets.MyServiceHostInfo.ProxyUrl, true, null, tNet); TheBaseAssets.MySYSLOG.WriteToLog(4365, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("WSProcessor", $"Web Proxy set: {TheBaseAssets.MyServiceHostInfo.ProxyUrl} UID: {!string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.ProxyUID)} PWD: {!string.IsNullOrEmpty(TheBaseAssets.MyServiceHostInfo.ProxyPWD)}", eMsgLevel.l4_Message)); } } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(4365, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("WSProcessor", "Error setting Proxy credentials:", eMsgLevel.l1_Error, e.ToString())); } } if (!string.IsNullOrEmpty(_MyTargetNodeChannel?.ClientCertificateThumb)) { try { X509Certificate2Collection cert = TheCertificates.GetClientCertificatesByThumbprint(_MyTargetNodeChannel?.ClientCertificateThumb); if (cert?.Count < 1) { TheBaseAssets.MySYSLOG.WriteToLog(4365, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("WSProcessor", $"Error setting Client Certificate - Requested Cert with Thumbprint {_MyTargetNodeChannel?.ClientCertificateThumb} not found", eMsgLevel.l1_Error)); return(false); } wsClientSocket.Options.ClientCertificates = cert; } catch (Exception certex) { TheBaseAssets.MySYSLOG.WriteToLog(4365, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("WSProcessor", "Error setting Client Certificate", eMsgLevel.l1_Error, certex.ToString())); return(false); } } Task myTask = wsClientSocket.ConnectAsync(tTarget, CancellationToken.None); myTask.Wait(TheBaseAssets.MyServiceHostInfo.TO.WsTimeOut * 12); if (myTask.IsCompleted) { // CODE REVIEW MH: ProcessWS synchronously can run for quite a bit until the first await. Should we start this as a new task? ConnectSuccess = true; var taskNoWait = ProcessWS(); //Sets Connecting and Connected when ready } else { TheBaseAssets.MySYSLOG.WriteToLog(4365, new TSM("WSProcessor", $"WSClient Connect Request timed out Task:{myTask.Status}", eMsgLevel.l2_Warning)); connectFailureReason += "Connect Request Timeout"; } } catch (Exception e) { TheBaseAssets.MySYSLOG.WriteToLog(4365, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("WSProcessor", "ClientConnect Request Failed:", eMsgLevel.l1_Error, e.ToString())); connectFailureReason += TheCommonUtils.GetAggregateExceptionMessage(e, false); } if (ConnectSuccess) //This prevents double shutdown as the eventconnecte with ConnectSuccess=false will cause a shutdown again { eventConnected?.Invoke(this, ConnectSuccess, $"1602:{connectFailureReason}"); } else { Shutdown(true, $"1603:WSConnect was not successful ({connectFailureReason})"); } return(ConnectSuccess); }