Exemple #1
0
 public void DoLogin(Uri pLoginUrl, string tPost, string MimeTypeOverride = null, cdeConcurrentDictionary <string, string> paddHeader = null)
 {
     if (MyRequestData == null)
     {
         MyRequestData = new TheRequestData();
     }
     MyRequestData.PostData   = TheCommonUtils.CUTF8String2Array(tPost);
     MyRequestData.RequestUri = pLoginUrl;
     MyRequestData.HttpMethod = "POST";
     MyRequestData.Header     = null;
     if (paddHeader != null)
     {
         MyRequestData.Header = new cdeConcurrentDictionary <string, string>();
         foreach (string key in paddHeader.Keys)
         {
             MyRequestData.Header.TryAdd(key, paddHeader[key]);
         }
     }
     if (!string.IsNullOrEmpty(MimeTypeOverride))
     {
         MyRequestData.ResponseMimeType = MimeTypeOverride; // "application/x-www-form-urlencoded; charset=UTF-8";
     }
     else
     {
         MyRequestData.ResponseMimeType = mPostMimeType; // "application/x-www-form-urlencoded; charset=UTF-8";
     }
     MyRequestData.ResponseBuffer  = null;
     MyRequestData.TimeOut         = 15000;
     MyRequestData.DisableRedirect = true;
     MyRequestData.RequestCookies  = MyRequestData?.SessionState?.StateCookies;
     MyRest.PostRESTAsync(MyRequestData, LoginSuccess, sinkError);
 }
Exemple #2
0
        private void OnDownloadClick(ICDEThing pThing, object pPara)
        {
            TheProcessMessage pMSG = pPara as TheProcessMessage;

            if (pMSG == null || pMSG.Message == null)
            {
                return;
            }

            string[] cmd = pMSG.Message.PLS.Split(':');
            if (cmd.Length > 2)
            {
                TheThing tThing = TheThingRegistry.GetThingByMID("*", TheCommonUtils.CGuid(cmd[2]), true);
                if (tThing == null)
                {
                    return;
                }

                TSM tFilePush = new TSM(eEngineName.ContentService, string.Format("CDE_FILE:{0}.JSON:application/zip", tThing.FriendlyName))
                {
                    SID = pMSG.Message.SID,
                    PLS = "bin",
                    PLB = TheCommonUtils.CUTF8String2Array(TheCommonUtils.SerializeObjectToJSONString(tThing))
                };
                TheCommCore.PublishToOriginator(pMSG.Message, tFilePush);
            }
        }
Exemple #3
0
        public static void SetResponseValue(TheRequestData pRequest, Guid guidValue)
        {
            pRequest.ResponseMimeType = "application/json";
            string strJson = TheCommonUtils.SerializeObjectToJSONString <Guid>(guidValue);

            pRequest.ResponseBuffer = TheCommonUtils.CUTF8String2Array(strJson);
            pRequest.StatusCode     = (int)eHttpStatusCode.OK;
            pRequest.DontCompress   = true;
            pRequest.AllowStatePush = false;
        }
Exemple #4
0
        public static void CreateJsonResponse <T>(TheRequestData pRequest, T responsedata)
        {
            pRequest.ResponseMimeType = "application/json";
            string strJson = TheCommonUtils.SerializeObjectToJSONString <T>(responsedata);

            pRequest.ResponseBuffer = TheCommonUtils.CUTF8String2Array(strJson);
            pRequest.StatusCode     = (int)eHttpStatusCode.OK;
            pRequest.DontCompress   = true;
            pRequest.AllowStatePush = false;
        }
 private void sinkRequestMeshInfo(TheRequestData request)
 {
     if (request != null)
     {
         request.ResponseMimeType = "application/json";
         string errorText = "";
         Dictionary <string, string> tQ = TheCommonUtils.ParseQueryString(request.RequestUri?.Query);
         if (tQ != null)
         {
             tQ.TryGetValue("MESHINFOTOKEN", out string meshInfoToken);
             if (tQ.TryGetValue("ORG", out string tOrg))
             {
                 Guid requestorMID = TheCommonUtils.CGuid(tOrg);
                 if (requestorMID != Guid.Empty)
                 {
                     TheMeshInfoStatus meshInfoStatus = TheQueuedSenderRegistry.GetMeshInfoForNodeID(requestorMID, meshInfoToken);
                     if (string.IsNullOrEmpty(meshInfoStatus?.StatusMessage))
                     {
                         request.StatusCode     = (int)eHttpStatusCode.OK;
                         request.ResponseBuffer = TheCommonUtils.CUTF8String2Array(TheCommonUtils.SerializeObjectToJSONString(meshInfoStatus.MeshInfo));
                     }
                     else
                     {
                         request.StatusCode = meshInfoStatus.StatusCode; //Better if meshInfoStatus also defines this as there are different messages (wrong MIT, too frequent tests etc)
                         errorText          = meshInfoStatus.StatusMessage;
                     }
                 }
                 else
                 {
                     request.StatusCode = 400;
                     errorText          = "Invalid or badly formed ORG parameter.";
                 }
             }
             else
             {
                 request.StatusCode = 400;
                 errorText          = "No ORG parameter found for mesh info request.";
             }
         }
         else
         {
             request.StatusCode = (int)eHttpStatusCode.AccessDenied;
             errorText          = "Access denied";
         }
         if (!string.IsNullOrEmpty(errorText))
         {
             TheErrorResponse errorResponse = new TheErrorResponse {
                 Error = errorText, CTIM = DateTimeOffset.Now
             };
             request.ResponseBuffer = TheCommonUtils.CUTF8String2Array(TheCommonUtils.SerializeObjectToJSONString(errorResponse));
         }
     }
 }
        private void sinkProcessResponse(TheRequestData pRequest)
        {
            if (pRequest.StatusCode >= 400 && pRequest.ResponseBuffer == null && !string.IsNullOrEmpty(pRequest.ErrorDescription))
            {
                pRequest.ResponseBuffer = TheCommonUtils.CUTF8String2Array(pRequest.ErrorDescription);
            }
            if (pRequest.ResponseBuffer == null && string.IsNullOrEmpty(pRequest.ResponseBufferStr))
            {
                pRequest.ResponseBuffer = TheCommonUtils.CUTF8String2Array("EMPTY");
            }
            if (pRequest.ResponseMimeType.StartsWith("text/html") || pRequest.ResponseMimeType.Contains("javascript"))  //OK
            {
                pRequest.ResponseBufferStr = TheCommonUtils.CArray2UTF8String(pRequest.ResponseBuffer);
            }
            string tReqUri = pRequest.RequestUri.Host;

            if (pRequest.RequestUri.Port != 80)
            {
                tReqUri += ":" + pRequest.RequestUri.Port;
            }
            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 != 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)
                    {
                        Uri tCloudUri = new Uri(pRequest.RequestUriString);
                        //pRequest.ResponseBufferStr = pRequest.ResponseBufferStr.Replace(pRequest.RequestUri.Host + ":" + pRequest.RequestUri.Port, new Uri(tMyApp.CloudUrl).Host + ":" + new Uri(tMyApp.CloudUrl).Port);
                        pRequest.ResponseBufferStr = pRequest.ResponseBufferStr.Replace(pRequest.RequestUri.Scheme + "://" + tReqUri, tCloudUri.Scheme + "://" + tCloudUri.Host + ":" + tCloudUri.Port);
                        pRequest.ResponseBuffer    = TheCommonUtils.CUTF8String2Array(pRequest.ResponseBufferStr);
                    }
                }
            }
            TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Response Bytes:{1} For Page:{0} Sent", pRequest.cdeRealPage, pRequest.ResponseBuffer != null ? pRequest.ResponseBuffer.Length : 0), eMsgLevel.l3_ImportantMessage));
            if (pRequest.ResponseBuffer != null)
            {
                //TheCommonUtils.SleepOneEye(5000, 100);
                TSM message3 = new TSM(MyBaseEngine.GetEngineName(), "WEBRELAY_RESPONSE")
                {
                    PLB = pRequest.ResponseBuffer
                };
                pRequest.ResponseBuffer    = null;
                pRequest.ResponseBufferStr = null;
                pRequest.RequestUriString  = pRequest.RequestUri.ToString();
                TSM tMSG = pRequest.CookieObject as TSM;
                pRequest.CookieObject = null;
                pRequest.PostData     = null;
                message3.PLS          = TheCommonUtils.SerializeObjectToJSONString(pRequest);
                TheCommCore.PublishToOriginator(tMSG, message3);
            }
        }
Exemple #7
0
 private void sinkRelay(TheRequestData pRequest)
 {
     pRequest.ResponseMimeType  = "text/html";
     pRequest.ResponseBufferStr = "<html>"
                                  + "    <body>"
                                  + "        <h1>This is My *Dynamic* Relay Server</h1>"
                                  + "    </body>"
                                  + "</html>";
     pRequest.ResponseBuffer = TheCommonUtils.CUTF8String2Array(pRequest.ResponseBufferStr);
     pRequest.StatusCode     = (int)eHttpStatusCode.OK;
     pRequest.DontCompress   = true;
     pRequest.AllowStatePush = false;
 }
Exemple #8
0
        private void sinkProcessBand(TheRequestData pRequest)
        {
            if (pRequest == null)
            {
                return;
            }
            if (IsInterceptorProcessing)
            {
                return;
            }

            IsInterceptorProcessing = true;
            try
            {
                if (pRequest.RequestUri != null && !string.IsNullOrEmpty(pRequest.RequestUri.Query) && pRequest.RequestUri.Query.Length > 1)
                {
                    string[] QParts = pRequest.RequestUri.Query.Split('=');
                    if (QParts.Length > 1 && QParts[0].ToUpper() == "?SID")
                    {
                        lock (LastMsgs.MyLock)
                        {
                            string msg   = "ERR: No Message from target, yet";
                            string token = TheScopeManager.GetTokenFromScrambledScopeID(TheScopeManager.GetScrambledScopeIDFromEasyID(QParts[1])) + "@";
                            if (TheScopeManager.IsValidScopeID(TheScopeManager.GetScrambledScopeIDFromEasyID(QParts[1])))
                            {
                                msg             = ReturnLastMessage();
                                LastMsgs[token] = msg;
                            }
                            else
                            {
                                TSM tTSM = new TSM(MyBaseEngine.GetEngineName(), "GET_LAST_MSG");
                                tTSM.SID = TheScopeManager.GetScrambledScopeIDFromEasyID(QParts[1]);
                                TheCommCore.PublishToService(tTSM);
                                //TODO: Wait here until SET_LAST_MSG returns
                                if (LastMsgs.ContainsKey(token))
                                {
                                    msg = LastMsgs[token];
                                }
                            }
                            pRequest.ResponseBuffer   = TheCommonUtils.CUTF8String2Array(msg);
                            pRequest.StatusCode       = 200;
                            pRequest.ResponseMimeType = "text/html";
                            LastMsgs.RemoveNoCare(token);
                        }
                    }
                }
            }
            catch { }
            IsInterceptorProcessing = false;
        }
        private void sinkResults(TheRequestData resBytes)
        {
            TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Result Bytes:{1} with Cookie:{2} For Page:{0} Sent", resBytes.cdeRealPage, resBytes.ResponseBuffer != null ? resBytes.ResponseBuffer.Length : 0, resBytes.CookieString), eMsgLevel.l4_Message));
            if (!string.IsNullOrEmpty(resBytes.CookieString))
            {
                string[] tCookies = resBytes.CookieString.Split(';');
                if (ReqBuffer.ContainsID(TheCommonUtils.CGuid(tCookies[tCookies.Length - 1])))
                {
                    if (tCookies.Length > 1)
                    {
                        resBytes.CookieString = "";
                        for (int i = 0; i < tCookies.Length - 1; i++)
                        {
                            if (resBytes.CookieString.Length > 0)
                            {
                                resBytes.CookieString += ";";
                            }
                            resBytes.CookieString += tCookies[i];
                        }
                    }
                    if (resBytes.ResponseBuffer == null && !string.IsNullOrEmpty(resBytes.ErrorDescription))
                    {
                        resBytes.ResponseBuffer = TheCommonUtils.CUTF8String2Array(resBytes.ErrorDescription);
                    }

                    //TODO: HackProcessing - Advanced Hack Table: Replace X with Y
                    //Console.WriteLine("SR:" + resBytes.cdeRealPage.ToLower());

                    /*
                     * if (resBytes.cdeRealPage.ToLower().StartsWith("/js/default.js"))
                     * {
                     *  string t = TheCommonUtils.CArray2UTF8String(resBytes.ResponseBuffer);
                     *  //var checkLocal = document.URL replace with return true; //TODO: Hack List
                     *  if (t.IndexOf("var checkLocal=document.URL;") >= 0)
                     *      t = t.Replace("var checkLocal=document.URL;", "return true;");
                     *  //if (t.IndexOf("return _.isObject(user)&&user.isLogin()") >= 0)
                     *  //  t = t.Replace("return _.isObject(user)&&user.isLogin()", "return true;");
                     *  t = t.Replace("window.location.hostname", "window.location.hostname+':'+window.location.port");
                     *  resBytes.ResponseBuffer = TheCommonUtils.CUTF8String2Array(t);
                     * }*/

                    ReqBuffer.AddOrUpdateItem(TheCommonUtils.CGuid(tCookies[tCookies.Length - 1]), resBytes, null);
                }
                else
                {
                    TheBaseAssets.MySYSLOG.WriteToLog(400, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM(MyBaseEngine.GetEngineName(), string.Format("Result Bytes For Page:{0} NoLonger in ReqBuffer", resBytes.cdeRealPage), eMsgLevel.l2_Warning));
                }
            }
        }
Exemple #10
0
        public bool PostToWeb(Uri pUrl, string tPost, Action <TheRequestData> pCallback, string MimeTypeOverride = null, cdeConcurrentDictionary <string, string> paddHeader = null, string pMethodOveride = "POST")
        {
            if (!IsConnected || !TheBaseAssets.MasterSwitch || MyRequestData == null || pUrl == null)
            {
                return(false);
            }
            TheRequestData tD = MyRequestData;

            if (!string.IsNullOrEmpty(tPost))
            {
                tD.PostData = TheCommonUtils.CUTF8String2Array(tPost);
            }
            else
            {
                tD.PostData = null;
            }
            tD.RequestUri = pUrl; // new Uri($"https://ptdevices.com{Url}");
            tD.HttpMethod = pMethodOveride;
            tD.Header     = null;
            if (paddHeader != null)
            {
                tD.Header = new cdeConcurrentDictionary <string, string>();
                foreach (string key in paddHeader.Keys)
                {
                    tD.Header.TryAdd(key, paddHeader[key]);
                }
            }
            tD.DisableRedirect = true;
            tD.RequestCookies  = MyRequestData?.SessionState?.StateCookies;
            if (!string.IsNullOrEmpty(MimeTypeOverride))
            {
                tD.ResponseMimeType = MimeTypeOverride; // "application/x-www-form-urlencoded; charset=UTF-8";
            }
            else
            {
                tD.ResponseMimeType = mPostMimeType; // "application/x-www-form-urlencoded; charset=UTF-8";
            }
            while (MyRest.IsPosting > 1 && IsConnected)
            {
                TheCommonUtils.SleepOneEye(1000, 100);
            }
            if (IsConnected)
            {
                MyRest.PostRESTAsync(tD, pCallback, sinkError);
            }
            return(true);
        }
Exemple #11
0
        // Parsing input parameters and returning a value.
        private void sinkHelloHttpInterceptor(TheRequestData pRequest)
        {
            string Query = pRequest.RequestUri.Query;

            if (Query.StartsWith("?"))
            {
                Query = Query.Substring(1);
            }
            Dictionary <string, string> tQ = TheCommonUtils.ParseQueryString(Query);

            pRequest.ResponseMimeType  = "text/plain";
            pRequest.ResponseBufferStr = "Hello From Http Interceptor!";
            pRequest.ResponseBuffer    = TheCommonUtils.CUTF8String2Array(pRequest.ResponseBufferStr);
            pRequest.StatusCode        = (int)eHttpStatusCode.OK;
            pRequest.DontCompress      = true;
            pRequest.AllowStatePush    = false;
        }
        private static void ResponseCreateToken(TheRequestData pRequest)
        {
            Guid     pNewToken = Guid.NewGuid();
            DateTime pNow      = DateTime.Now;

            if (dictValidAccessTokens == null)
            {
                InitAccessTokenTable();
            }

            dictValidAccessTokens[pNewToken] = pNow;

            pRequest.ResponseMimeType = "application/json";
            string strJson = TheCommonUtils.SerializeObjectToJSONString <Guid>(pNewToken);

            pRequest.ResponseBuffer = TheCommonUtils.CUTF8String2Array(strJson);
            pRequest.StatusCode     = (int)eHttpStatusCode.OK;
            pRequest.DontCompress   = true;
            pRequest.AllowStatePush = false;
        }
Exemple #13
0
        public override void OnNewEvent(TheProcessMessage timer, object unused)
        {
            TheEventLogEntry tEntry = timer?.Cookie as TheEventLogEntry;

            if (tEntry == null)
            {
                return;
            }
            if (!string.IsNullOrEmpty(MyBaseThing.Address) && tEntry?.Message?.TXT?.Contains(MyBaseThing.Address) == true) //Avoid recursive
            {
                return;
            }
            var t = new TheGELFLogEntry()
            {
                version = "1.1",
                host    = TheBaseAssets.MyServiceHostInfo.GetPrimaryStationURL(false),
                level   = (int)tEntry.Message?.LVL,
#if CDE_NET45 || CDE_NET4 || CDE_NET35
                timestamp = TheCommonUtils.CDbl($"{(tEntry.Message.TIM.Subtract(new DateTime(1970, 1, 1))).TotalSeconds}.{tEntry.Message.TIM.Millisecond}"),
#else
                timestamp = TheCommonUtils.CDbl($"{tEntry.Message.TIM.ToUnixTimeSeconds()}.{tEntry.Message.TIM.Millisecond}"),
#endif
                full_message  = tEntry.Message?.PLS,
                short_message = tEntry.Message?.TXT,
                _log_id       = tEntry.EventID,
                _serial_no    = tEntry.Serial,
                _engine       = tEntry.Message.ENG,
                _device_id    = tEntry.Message.GetOriginator().ToString()
            };

            try
            {
                if (!string.IsNullOrEmpty(MyBaseThing.Address))
                {
                    var pData = new TheRequestData()
                    {
                        RequestUri       = new Uri($"{MyBaseThing.Address}/gelf"),
                        ResponseMimeType = "application/json",
                        PostData         = TheCommonUtils.CUTF8String2Array(TheCommonUtils.SerializeObjectToJSONString <TheGELFLogEntry>(t)),
                        DontCompress     = true
                    };

                    MyRest.PostRESTAsync(pData, (okData) =>
                    {
                        MyBaseThing.StatusLevel = 1;
                    }, (errData) =>
                    {
                        MyBaseThing.LastMessage = $"Post to Log Error: {errData.ErrorDescription}";
                        MyBaseThing.StatusLevel = 2;
                    });
                }
            }
            catch (Exception e)
            {
                MyBaseThing.LastMessage = $"Cannot Post to Log Error: {e.Message}";
                MyBaseThing.StatusLevel = 2;
            }

            if (TheThing.GetSafePropertyBool(MyBaseThing, "ToConsole"))
            {
                Console.WriteLine(TheCommonUtils.SerializeObjectToJSONString <TheGELFLogEntry>(t));
            }
        }
        internal static void SetResponseBuffer(TheRequestData pRequestData, TheChannelInfo pChannelInfo, bool pSendPulse, string NopTopic, Guid owner, string pRefreshToken)
        {
            if (string.IsNullOrEmpty(NopTopic))
            {
                TheQueuedSender tQ = null;
                if (pChannelInfo != null && pChannelInfo.cdeMID != Guid.Empty)    //Send to Device First
                {
                    tQ = TheQueuedSenderRegistry.GetSenderByGuid(pChannelInfo.cdeMID);
                }
                if (tQ != null)
                {
                    if (pRequestData.WebSocket != null)
                    {
                        if (tQ.GetQueLength() == 0)
                        {
                            tQ.SendPickupMessage();
                        }
                        return;
                    }
                    tQ.GetNextBackChannelBuffer(pRequestData);
                }
            }
            if (string.IsNullOrEmpty(NopTopic) && pRequestData.WebSocket != null)
            {
                return;                                                                   //NEW:3.084  && !pSendPulse removed          NEW:V3B3:2014-7-22 removed && pRequestData.ResponseBuffer != null
            }
            if (pRequestData.ResponseBuffer == null && pChannelInfo != null && (pSendPulse || (pChannelInfo.cdeMID != Guid.Empty || TheQueuedSenderRegistry.IsNodeIdInSenderList(pChannelInfo.cdeMID))))
            {
                TheDeviceMessage tDev = new TheDeviceMessage {
                    CNT = 0
                };
                //tDev.MET = 0;
                if (!string.IsNullOrEmpty(NopTopic))
                {
                    tDev.MSG = new TSM();   //Can be set without ORG and SID
                    if (owner != Guid.Empty)
                    {
                        tDev.MSG.OWN = owner.ToString();
                    }
                    if (NopTopic == "CDE_WSINIT")
                    {
                        NopTopic = TheCommCore.SetConnectingBufferStr(pChannelInfo, null);
                    }
                }
                if (pChannelInfo.SenderType != cdeSenderType.CDE_JAVAJASON) //4.209: No longer sending SID to Browser;
                {
                    if (TheBaseAssets.MyServiceHostInfo.EnableFastSecurity)
                    {
                        tDev.SID = pRequestData.SessionState.SScopeID;  //SECURITY: All responses will have same Scrambled ScopeID - but ok because this is init telegram or HB
                    }
                    else
                    {
                        tDev.SID = TheBaseAssets.MyScopeManager.GetScrambledScopeID(pRequestData.SessionState.SScopeID, false); //GRSI: high frequency
                    }
                }
                else
                {
                    if (!string.IsNullOrEmpty(pRefreshToken))
                    {
                        tDev.SID = pRefreshToken;
                    }
                }
                tDev.FID = pRequestData.SessionState.GetNextSerial().ToString();
                if (TheCommonUtils.IsDeviceSenderType(pChannelInfo.SenderType)) //IDST-OK: Must create RSA for Devices
                {
                    TheCommonUtils.CreateRSAKeys(pRequestData.SessionState);
                    tDev.RSA = pRequestData.SessionState.RSAPublic;
                }
                tDev.NPA = TheBaseAssets.MyScopeManager.GetISBPath(TheBaseAssets.MyServiceHostInfo.RootDir, pChannelInfo.SenderType, TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.SenderType, pRequestData.SessionState.FID, pRequestData.SessionState.cdeMID, pRequestData.WebSocket != null);
                tDev.CNT = pSendPulse ? 1 : 0;
                tDev.TOP = NopTopic;
                tDev.DID = pChannelInfo.SenderType == cdeSenderType.CDE_JAVAJASON ? pChannelInfo.cdeMID.ToString() : TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID.ToString();

                //There will be only one Message here - single poke or Mini Command or NOP Pickup
                List <TheDeviceMessage> tDevList = new List <TheDeviceMessage> {
                    tDev
                };
                if (pChannelInfo.SenderType == cdeSenderType.CDE_JAVAJASON || TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.SenderType == cdeSenderType.CDE_MINI || pChannelInfo.SenderType == cdeSenderType.CDE_MINI || pRequestData.WebSocket != null)
                {
                    pRequestData.ResponseBuffer   = TheCommonUtils.CUTF8String2Array(TheCommonUtils.SerializeObjectToJSONString(tDevList));
                    pRequestData.ResponseMimeType = "application/json";
                }
                else
                {
                    pRequestData.ResponseBuffer   = TheCommonUtils.cdeCompressString(TheCommonUtils.SerializeObjectToJSONString(tDevList));
                    pRequestData.ResponseMimeType = "application/x-gzip";
                }
            }
            if (pRequestData.ResponseBuffer == null && pChannelInfo != null && pChannelInfo.cdeMID != Guid.Empty)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(290, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("CoreComm", $"Nothing to Send Back to {pChannelInfo?.ToMLString()}", eMsgLevel.l7_HostDebugMessage));
            }
        }
Exemple #15
0
        internal override void PostToSocket(TheDeviceMessage pMsg, byte[] pPostBuffer, bool PostAsBinary, bool IsInitialConnect)
        {
            TheDiagnostics.SetThreadName("WSPostToSocketCSWS:" + (MyQSender.MyTargetNodeChannel?.ToString() ?? "DEAD"));

            if (MyQSender != null && !MyQSender.IsConnected && !IsInitialConnect)
            {
                Shutdown(true, "1653:QSenderCSWS not connected but Posting in illegal state");
                return;
            }

            if (!ProcessingAllowed)         //NEW:V3BETA2: New Waiting Algorythm
                WaitUntilProcessingAllowed();

            if (!IsActive || !TheBaseAssets.MasterSwitch)
                return;

            if (websocket == null && webSocketSession==null)
            {
                eventClosed?.Invoke("1654:WebSockets are down");
                return;
            }
            ProcessingAllowed = false;

            try
            {
                if (pPostBuffer != null)
                {
                    TheCDEKPIs.IncrementKPI(eKPINames.QKBSent, pPostBuffer.Length);
                    if (PostAsBinary)
                    {
                        if (webSocketSession != null)
                            webSocketSession.SendB(pPostBuffer);
                        else
                        {
                            websocket?.Send(pPostBuffer);
                        }
                    }
                    else
                    {
                        if (webSocketSession != null)
                            webSocketSession.SendB(TheCommonUtils.CArray2UTF8String(pPostBuffer));
                        else
                        {
                            websocket?.Send(TheCommonUtils.CArray2UTF8String(pPostBuffer));
                        }
                    }
                }
                else
                {
                    string toSend = TheCommonUtils.SerializeObjectToJSONString(pMsg);
                    if (PostAsBinary)
                    {
                        byte[] toSendb = TheCommonUtils.CUTF8String2Array(toSend);
                        TheCDEKPIs.IncrementKPI(eKPINames.QKBSent, toSendb.Length);
                        if (webSocketSession != null)
                            webSocketSession.SendB(toSendb);
                        else
                        {
                            websocket?.Send(toSendb);
                        }
                    }
                    else
                    {
                        if (webSocketSession != null)
                            webSocketSession.SendB(toSend);
                        else
                        {
                            websocket?.Send(toSend);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Shutdown(true, "1655:DoPostToSocketCSWS had a fault: "+e);
            }

            if (mre != null)
                ProcessingAllowed = 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);
        }
Exemple #17
0
        public void GetDevices(Uri pDeviceURL = null, string tPost = null, cdeConcurrentDictionary <string, string> addHeader = null)
        {
            if (!IsConnected || !TheBaseAssets.MasterSwitch)
            {
                return;
            }
            if (pDeviceURL != null)
            {
                mDeviceUrl = pDeviceURL;
            }
            if (tPost != null)
            {
                mDevicePost = tPost;
            }
            if (addHeader != null)
            {
                mAddHeader = addHeader;
            }
            if (mDevicePost == null)
            {
                TheRequestData tRequest = new TheRequestData
                {
                    RequestUri     = mDeviceUrl,
                    RequestCookies = MyRequestData?.SessionState?.StateCookies
                };
                if (mAddHeader != null)
                {
                    tRequest.Header = new cdeConcurrentDictionary <string, string>();
                    foreach (string key in mAddHeader.Keys)
                    {
                        tRequest.Header.TryAdd(key, mAddHeader[key]);
                    }
                }
                TheREST.GetRESTAsync(tRequest, ParseDevices, sinkError);
            }
            else
            {
                MyRequestData.RequestUri = mDeviceUrl; // new Uri("https://ptdevices.com/device/all");
                //tPost = $"_token={WebSocketSharp.Ext.UrlEncode(mToken)}";
                MyRequestData.PostData   = TheCommonUtils.CUTF8String2Array(mDevicePost);
                MyRequestData.HttpMethod = "POST";
                MyRequestData.Header     = null;
                if (mAddHeader != null)
                {
                    MyRequestData.Header = new cdeConcurrentDictionary <string, string>();
                    foreach (string key in mAddHeader.Keys)
                    {
                        MyRequestData.Header.TryAdd(key, mAddHeader[key]);
                    }
                }

                MyRequestData.RequestCookies   = MyRequestData?.SessionState?.StateCookies;
                MyRequestData.ResponseMimeType = mPostMimeType; // "application/x-www-form-urlencoded; charset=UTF-8";
                while (MyRest.IsPosting > 1 && IsConnected)
                {
                    TheCommonUtils.SleepOneEye(1000, 100);
                }
                if (IsConnected)
                {
                    MyRest.PostRESTAsync(MyRequestData, ParseDevices, sinkError);
                }
            }
        }
Exemple #18
0
        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();
            }
        }
Exemple #19
0
        public void ProcessHttpRequest(HttpListenerContext mContext)
        {
            TheRequestData tRequestData = new TheRequestData();

            try
            {
                tRequestData.RequestUri = mContext.Request.Url;
                // TheSystemMessageLog.ToCo(tRequestData.RequestUri.ToString(), true);
                tRequestData.UserAgent        = mContext.Request.UserAgent;
                tRequestData.ServerTags       = null;
                tRequestData.HttpMethod       = mContext.Request.HttpMethod; //NEW 3.200
                tRequestData.Header           = TheCommonUtils.cdeNameValueToDirectory(mContext.Request.Headers);
                tRequestData.ResponseMimeType = mContext.Request.ContentType;

                tRequestData.ClientCert = mContext.Request.GetClientCertificate();

                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(tRequestData);
                    if (TheBaseAssets.MyServiceHostInfo.DisableNMI && !string.IsNullOrEmpty(err))
                    {
                        mContext.Response.StatusCode = (int)eHttpStatusCode.NotAcceptable;
                        mContext.Response.OutputStream.Close();
                        return;
                    }
                }

                if (mContext.Request.InputStream != null)
                {
#if CDE_NET4 || CDE_NET45
                    using (MemoryStream ms = new MemoryStream())
                    {
                        mContext.Request.InputStream.CopyTo(ms);
                        tRequestData.PostData = ms.ToArray();
                    }
#else
                    byte[] buffer = new byte[TheBaseAssets.MAX_MessageSize[0]];
                    using (MemoryStream ms = new MemoryStream())
                    {
                        int read;
                        while ((read = mContext.Request.InputStream.Read(buffer, 0, buffer.Length)) > 0)
                        {
                            ms.Write(buffer, 0, read);
                        }
                        tRequestData.PostData = ms.ToArray();
                    }
#endif

                    tRequestData.PostDataLength = tRequestData.PostData.Length;
                }

                if (TheCommCore.MyHttpService != null)
                {
                    TheCommCore.MyHttpService.cdeProcessPost(tRequestData);
                }
            }
            catch (Exception e)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(4350, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("HttpMidiServer", "ProcessRequest Error:" + firstRequestLine, eMsgLevel.l1_Error, e.ToString()));
                tRequestData.ResponseBuffer = TheCommonUtils.CUTF8String2Array(e.ToString());
                tRequestData.StatusCode     = (int)eHttpStatusCode.ServerError;
            }

            if ((tRequestData.ResponseBuffer == null && tRequestData.StatusCode != 200) || tRequestData.StatusCode == 404)    //NEW:UPNP
            {
                tRequestData.ResponseBufferStr  = "<html><head><meta http-equiv=\"Expires\" content=\"0\" /><meta http-equiv=\"Cache-Control\" content=\"no-cache\" /><meta http-equiv=\"Pragma\" content=\"no-cache\" /></html><body style=\"background-color: " + TheBaseAssets.MyServiceHostInfo.BaseBackgroundColor + ";\"><table width=\"100%\" style=\"height:100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td style=\"text-align:center;\"><p style=\"color: " + TheBaseAssets.MyServiceHostInfo.BaseForegroundColor + "; font-family: Arial; font-size: 36px\">";
                tRequestData.ResponseBufferStr += string.Format("Resource {0} not found", tRequestData.RequestUri);
                tRequestData.ResponseBufferStr += "</p></td></tr></table></body></HTML>";
                tRequestData.ResponseMimeType   = "text/html";
                tRequestData.ResponseBuffer     = TheCommonUtils.CUTF8String2Array(tRequestData.ResponseBufferStr);
                tRequestData.StatusCode         = (int)eHttpStatusCode.NotFound;
            }

            try
            {
                if (tRequestData.AllowStatePush && tRequestData.ResponseBuffer != null &&
                    (tRequestData.StatusCode == (int)eHttpStatusCode.OK || tRequestData.StatusCode == (int)eHttpStatusCode.PermanentMoved))
                {
                    if (tRequestData.SessionState != null && tRequestData.SessionState.StateCookies != null && tRequestData.SessionState.StateCookies.Count > 0)
                    {
                        string tCookie = "";
                        foreach (string nam in tRequestData.SessionState.StateCookies.Keys)
                        {
                            try
                            {
                                if (tCookie.Length > 0)
                                {
                                    tCookie += ";";
                                }
                                string[] cp = tRequestData.SessionState.StateCookies[nam].Split(';');
                                tCookie  = "";
                                tCookie += $"{nam}={cp[0]}; SameSite=none; Secure";
                                mContext.Response.Headers.Add(HttpResponseHeader.SetCookie, tCookie);
                            }
                            catch
                            {
                                //ignored
                            }
                        }
                    }
                }
                else
                {
                    if (!string.IsNullOrEmpty(tRequestData.cdeRealPage) && tRequestData.cdeRealPage.StartsWith("/cdeClean", StringComparison.OrdinalIgnoreCase) &&
                        tRequestData.Header != null && tRequestData.Header.ContainsKey("Cookie"))
                    {
                        string cookieDate   = DateTime.UtcNow.AddMilliseconds(100).ToString("ddd, dd-MMM-yyyy H:mm:ss"); //Offset not needed
                        string cookieHeader = tRequestData.Header.cdeSafeGetValue("Cookie");
                        if (!string.IsNullOrEmpty(cookieHeader))
                        {
                            string        tCookie  = "";
                            List <string> tCookies = TheCommonUtils.CStringToList(cookieHeader, ';');
                            foreach (string t in tCookies)
                            {
                                if (tCookie.Length > 0)
                                {
                                    tCookie += ";";
                                }
                                string[] tc = t.Split('=');
                                tCookie += string.Format("{0}=;Path=/;Expires={1} GMT", tc[0], cookieDate);
                            }
                            mContext.Response.Headers.Add(HttpResponseHeader.SetCookie, tCookie);
                        }
                    }
                }

                if (!tRequestData.DontCompress)
                {
                    if (tRequestData.AllowCaching && !TheBaseAssets.MyServiceHostInfo.DisableCache)
                    {
                        mContext.Response.AddHeader("Cache-Control", $"max-age={TheBaseAssets.MyServiceHostInfo.CacheMaxAge}, public");
                    }
                    else
                    {
                        mContext.Response.AddHeader("Cache-Control", "no-cache");
                    }
                    mContext.Response.AddHeader("cdeDeviceID", TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID.ToString());
                    if (tRequestData.StatusCode > 300 && tRequestData.StatusCode < 400 && tRequestData.Header != null)
                    {
                        mContext.Response.AddHeader("Location", tRequestData.Header.cdeSafeGetValue("Location"));
                    }
                }
                else
                {
                    mContext.Response.Headers.Clear();
                }

                mContext.Response.Headers.Set(HttpResponseHeader.Server, "C-DEngine V4");
                if (TheBaseAssets.MyServiceHostInfo.IsSSLEnforced)
                {
                    mContext.Response.Headers.Set("Strict-Transport-Security", "max-age=298000; includeSubDomains; preload"); //HSTS Header for SSL sites...test still required
                    mContext.Response.Headers.Set("X-Frame-Options", "sameorigin");                                           //iFrame protection Header for SSL sites...test still required
                }

                var tCors = TheBaseAssets.MySettings.GetSetting("Access-Control-Allow-Origin");
                if (!string.IsNullOrEmpty(tCors))
                {
                    mContext.Response.AppendHeader("Access-Control-Allow-Origin", tCors);
                }
                if (!string.IsNullOrEmpty(tRequestData.AllowedMethods))
                {
                    mContext.Response.AppendHeader("Access-Control-Allow-Methods", tRequestData.AllowedMethods);
                }
                if (!string.IsNullOrEmpty(tRequestData.AllowedMethods))
                {
                    mContext.Response.AppendHeader("Access-Control-Allow-Headers", tRequestData.AllowedHeaders);
                }

                mContext.Response.StatusCode = tRequestData.StatusCode;
                if (tRequestData.StatusCode != 200)
                {
                    TheCDEKPIs.IncrementKPI(eKPINames.BruteDelay);
                    //Security Fix: ID#770 - wait 200 ms before returning anything with error code to limit BruteForce
                    TheCommonUtils.SleepOneEye(200, 100);
                }
                mContext.Response.ContentType = tRequestData.ResponseMimeType;

                if (tRequestData.ResponseBuffer != null)
                {
                    if (!tRequestData.DontCompress && (TheBaseAssets.MyServiceHostInfo.IsOutputCompressed || (tRequestData.Header != null && tRequestData.Header.ContainsKey("Accept-Encoding") && tRequestData.Header["Accept-Encoding"].Contains("gzip"))))
                    {
                        byte[] bBuffer = TheCommonUtils.cdeCompressBuffer(tRequestData.ResponseBuffer, 0, tRequestData.ResponseBuffer.Length);
                        mContext.Response.AddHeader("Content-Encoding", "gzip");
                        mContext.Response.ContentLength64 = bBuffer.Length;
                        mContext.Response.OutputStream.Write(bBuffer, 0, bBuffer.Length);
                    }
                    else
                    {
                        if (!string.IsNullOrEmpty(tRequestData.ResponseEncoding))
                        {
                            mContext.Response.AddHeader("Content-Encoding", tRequestData.ResponseEncoding);
                        }
                        mContext.Response.ContentLength64 = tRequestData.ResponseBuffer.Length;
                        mContext.Response.OutputStream.Write(tRequestData.ResponseBuffer, 0, tRequestData.ResponseBuffer.Length);
                    }
                }
                if (tRequestData.DisableChunking)
                {
                    mContext.Response.SendChunked = false;
                }
                if (tRequestData.DisableKeepAlive)
                {
                    mContext.Response.KeepAlive = false;
                }
                mContext.Response.OutputStream.Close();
            }
            catch (Exception ee)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(4351, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("HttpMidiServer", "HttpWriteResponse Error", eMsgLevel.l1_Error, ee.ToString()));
            }
        }
Exemple #20
0
        public void ProcessRequest(TcpClient mSocket, cdeMidiHttpService pService)
        {
            mHServer       = pService;
            mRequestStream = new BufferedStream(mSocket.GetStream());

            TheRequestData tRequestData = new TheRequestData();

            try
            {
                parseRequest(tRequestData);
                readHeaders(tRequestData);
                if (tRequestData.HttpVersion > 1.0)
                {
                    if (tRequestData.Header.ContainsKey("Expect") && tRequestData.Header["Expect"].Equals("100-Continue"))
                    {
                        mRequestStream.Write(mContinue100, 0, mContinue100.Length);//Per HTTP1.1 Requirement
                    }
                }
                if (tRequestData.StatusCode != (int)eHttpStatusCode.NotFound)
                {
                    if (tRequestData.HttpMethod.Equals("GET"))
                    {
                        TheCommCore.MyHttpService.cdeProcessPost(tRequestData);
                    }
                    else if (tRequestData.HttpMethod.Equals("POST"))
                    {
                        handlePOST(tRequestData);
                    }
                }
            }
            catch (Exception e)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(4352, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("HttpMidiServer", "ProcessRequest Error:" + firstRequestLine, eMsgLevel.l1_Error, e.ToString()));
                tRequestData.ResponseBuffer = TheCommonUtils.CUTF8String2Array(e.ToString());
                tRequestData.StatusCode     = (int)eHttpStatusCode.ServerError;
            }

            if ((tRequestData.ResponseBuffer == null && tRequestData.StatusCode != 200) || tRequestData.StatusCode == 404)
            {
                tRequestData.ResponseBufferStr  = "<html><head><meta http-equiv=\"Expires\" content=\"0\" /><meta http-equiv=\"Cache-Control\" content=\"no-cache\" /><meta http-equiv=\"Pragma\" content=\"no-cache\" /></html><body style=\"background-color: " + TheBaseAssets.MyServiceHostInfo.BaseBackgroundColor + ";\"><table width=\"100%\" style=\"height:100%;\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\"><tr><td style=\"text-align:center;\"><p style=\"color: " + TheBaseAssets.MyServiceHostInfo.BaseForegroundColor + "; font-family: Arial; font-size: 36px\">";
                tRequestData.ResponseBufferStr += string.Format("Resource {0} not found", tRequestData.RequestUri);
                tRequestData.ResponseBufferStr += "</p></td></tr></table></body></HTML>";
                tRequestData.ResponseMimeType   = "text/html";
                tRequestData.ResponseBuffer     = TheCommonUtils.CUTF8String2Array(tRequestData.ResponseBufferStr);
                if (tRequestData.StatusCode == 0)
                {
                    tRequestData.StatusCode = (int)eHttpStatusCode.NotFound;
                }
            }

            try
            {
                if (!tRequestData.DontCompress && (TheBaseAssets.MyServiceHostInfo.IsOutputCompressed || (tRequestData.Header != null && tRequestData.Header.ContainsKey("Accept-Encoding") && tRequestData.Header["Accept-Encoding"].Contains("gzip"))))
                {
                    byte[] bBuffer = TheCommonUtils.cdeCompressBuffer(tRequestData.ResponseBuffer, 0, tRequestData.ResponseBuffer.Length);
                    tRequestData.ResponseBuffer = bBuffer;
                }
                else
                {
                    tRequestData.DontCompress = true;
                }

                string tHead  = TheCommCore.MyHttpService.CreateHttpHeader(tRequestData);
                byte[] tBHead = TheCommonUtils.CUTF8String2Array(tHead);
                mRequestStream.Write(tBHead, 0, tBHead.Length);
                mRequestStream.Write(tRequestData.ResponseBuffer, 0, tRequestData.ResponseBuffer.Length);
                mRequestStream.Flush();
                mRequestStream = null;
                mSocket.Close();
            }
            catch (Exception ee)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(4353, TSM.L(eDEBUG_LEVELS.VERBOSE) ? null : new TSM("HttpMidiServer", "HttpWriteResponse Error", eMsgLevel.l1_Error, ee.ToString()));
            }
        }
Exemple #21
0
 public cdeHttpProcessor()
 {
     mContinue100 = TheCommonUtils.CUTF8String2Array("HTTP/1.1 100 Continue\r\n\r\n");
 }
Exemple #22
0
        internal void ProcessIncomingData(string pPostString, byte[] pPostData, int pPostDataLength)
        {
            if (!IsActive)
            {
                return;
            }

            if (MySessionRequestData == null || MySessionRequestData?.SessionState?.HasExpired == true)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(4360, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("TheWSProcessor", $"Incoming Data on expired session ({MySessionRequestData?.SessionState?.HasExpired}) detected - shutting down websockets", eMsgLevel.l6_Debug));
                Shutdown(false, "1600:Incoming Data on expired session detected - shutting down websockets");
                return;
            }
            TheRequestData tRequestData = TheRequestData.CloneForWS(MySessionRequestData);

            TheCDEKPIs.IncrementKPI(eKPINames.QSReceivedTSM);
            tRequestData.PostData    = pPostData;
            tRequestData.PostDataIdx = 0;
            if (pPostData == null)
            {
                tRequestData.PostDataLength = 0;
            }
            else
            {
                tRequestData.PostDataLength = pPostDataLength > 0 ? pPostDataLength : pPostData.Length;
                TheCDEKPIs.IncrementKPI(eKPINames.QKBReceived, tRequestData.PostDataLength);
            }

            if (IsClient)
            {
                string cmdString = "";
                try
                {
                    List <TheDeviceMessage> tDevList;
                    if (tRequestData.PostData == null && !string.IsNullOrEmpty(pPostString))
                    {
                        if (pPostString[0] != '[')
                        {
                            return;
                        }
                        tDevList = TheDeviceMessage.DeserializeJSONToObject(pPostString);
                    }
                    else
                    {
                        if (tRequestData.PostData == null)
                        {
                            return;                              //Edge Case but could happen - all what follows required ProcessClientDeviceMsg
                        }
                        cmdString = tRequestData.PostData[0] == (byte)'[' ? TheCommonUtils.CArray2UTF8String(tRequestData.PostData, 0, tRequestData.PostDataLength) : TheCommonUtils.cdeDecompressToString(tRequestData.PostData, 0, tRequestData.PostDataLength);
                        tDevList  = TheDeviceMessage.DeserializeJSONToObject(cmdString);
                    }

                    TheCorePubSub.ProcessClientDeviceMessage(MyQSender, tRequestData, tDevList);
                }
                catch (Exception e)
                {
                    TheBaseAssets.MySYSLOG.WriteToLog(4361, new TSM("WSClient", "Message-Received Processing Error", eMsgLevel.l1_Error, e.ToString()));
                }
            }
            else
            {
                try
                {
                    if (tRequestData.PostData == null && !string.IsNullOrEmpty(pPostString))
                    {
                        tRequestData.PostData       = TheCommonUtils.CUTF8String2Array(pPostString);
                        tRequestData.PostDataLength = tRequestData.PostData.Length;
                    }
                    if (TheCommCore.MyHttpService != null)
                    {
                        TheCommCore.MyHttpService.cdeProcessPost(tRequestData);
                    }
                }
                catch (Exception e)
                {
                    TheBaseAssets.MySYSLOG.WriteToLog(4362, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("TheWSServer", "WebSocketServer-ProcessRequest Error", eMsgLevel.l1_Error, e.ToString()));
                }
            }
            if (MySessionRequestData.SessionState == null)
            {
                MySessionRequestData.SessionState = tRequestData.SessionState;
            }
            if (MySessionRequestData.DeviceID == Guid.Empty)
            {
                MySessionRequestData.DeviceID = tRequestData.DeviceID;
            }
            if (tRequestData.SessionState != null && MyQSender != null)
            {
                if (MyQSender.IsConnecting)
                {
                    MyQSender.IsConnected = true;
                    if (MyQSender.eventConnected != null)
                    {
                        TheCommonUtils.cdeRunAsync("QueueConnected", true, (p) =>
                        {
                            MyQSender?.eventConnected?.Invoke(MyQSender, MyQSender.MyTargetNodeChannel);
                        });
                    }
                    MyQSender.MyISBlock?.FireEvent("Connected");
                }
                //NEW3.124: Reset Heartbeat on Ws Post
                MyQSender.ResetHeartbeatTimer(false, tRequestData.SessionState);
            }
            else
            {
                TheBaseAssets.MySYSLOG.WriteToLog(4361, TSM.L(eDEBUG_LEVELS.ESSENTIALS)?null: new TSM("WSClient", $"No Request Session {tRequestData.SessionState!=null} or no QSender Found {MyQSender!=null}) IsClient={IsClient}", eMsgLevel.l2_Warning));
            }


            try
            {
                if (tRequestData.ResponseBuffer != null)
                {
                    PostToSocket(null, tRequestData.ResponseBuffer, IsClient, false);
                }
            }
            catch (Exception ex) // For debugging
            {
                //if (eventClosed != null)
                //  eventClosed("Connection Error: " + ex.ToString());
                Shutdown(true, "1601:PostToSocket Error: " + ex);
            }
        }
        /// <summary>
        /// sinkThingApiInterceptor - Called when our URL is referenced.
        /// </summary>
        /// <param name="pRequest"></param>
        public void sinkThingApiInterceptor(TheRequestData pRequest)
        {
            string[] astrURLPath = pRequest.cdeRealPage.Split(new char[1] {
                '/'
            }, StringSplitOptions.RemoveEmptyEntries);
            bool bHandled = false;

            if (astrURLPath.Length > 1)
            {
                Dictionary <string, string> aParameters = new Dictionary <string, string>();
                ParseQueryParameters(pRequest.RequestUri.Query, aParameters);

                string strEngineContext   = astrURLPath[1];
                string strThingContext    = (astrURLPath.Length < 3) ? "" : astrURLPath[2];
                string strPropertyContext = (astrURLPath.Length < 4) ? "" : astrURLPath[3];
                string strPropertyName    = (astrURLPath.Length < 5) ? "" : astrURLPath[4];

                // Login is only user action that does not require a login key.
                if (strEngineContext.StartsWith("Login"))
                {
                    // Is user logging in?
                    //
                    // Sample URL:
                    //     http://c-labs-paul-yao-laptop:8700/ThingApi/Login?User=paul&Pwd=yao
                    //
                    // Sample Return value:
                    //     "a6221f63-c88c-4aa1-8a83-b0fd18a6811e"
                    ValidateUserCredentials(pRequest, astrURLPath, aParameters);
                    bHandled = true;
                }
                else if (IsTokenValid(aParameters))
                {
                    if (strEngineContext.StartsWith("Engines"))
                    {
                        // Is user enumerating engines?
                        //
                        // Sample URL:
                        //     http://c-labs-paul-yao-laptop:8700/ThingApi/Engines?key=a6221f63-c88c-4aa1-8a83-b0fd18a6811e
                        //
                        // Sample Return value:
                        //     ["NMIService.TheNMIHtml5RT","NMIService","ThingService","CDMyThingInspector.cdePluginService1","ContentService"]

                        List <string> listEngines = TheThingRegistry.GetEngineNames(true);
                        pRequest.ResponseMimeType = "application/json";
                        string strJson = TheCommonUtils.SerializeObjectToJSONString <List <string> >(listEngines);
                        pRequest.ResponseBuffer = TheCommonUtils.CUTF8String2Array(strJson);
                        pRequest.StatusCode     = (int)eHttpStatusCode.OK;
                        pRequest.DontCompress   = true;
                        pRequest.AllowStatePush = false;
                        bHandled = true;
                    }
                    else
                    {
                        // Is user performing a query on a specific engine?
                        //
                        // Sample URL:
                        //     http://c-labs-paul-yao-laptop:8700/ThingApi/NMIService/Things?key=a6221f63-c88c-4aa1-8a83-b0fd18a6811e
                        //
                        // Sample Return value:
                        //     ["b0710f68-5d0f-4e00-93ea-b32c1a5a40c7", "d7bec9f2-4dbc-4119-97e0-f34ed09e5ae1"]
                        //
                        // Sample URL to get all things for all engines:
                        //     http://c-labs-paul-yao-laptop:8700/ThingApi/*/Things?key=a6221f63-c88c-4aa1-8a83-b0fd18a6811e
                        //
                        bool bEngineFound = IsValidEngine(strEngineContext);
                        if (bEngineFound)
                        {
                            if (!String.IsNullOrEmpty(strThingContext))
                            {
                                if (strThingContext == "Things")
                                {
                                    // Enumerate available things for this engine.
                                    List <TheThing> listThings       = TheThingRegistry.GetThingsOfEngine(strEngineContext);
                                    List <string>   listReturnValues = new List <string>();
                                    foreach (TheThing t in listThings)
                                    {
                                        listReturnValues.Add(t.cdeMID.ToString());
                                    }

                                    pRequest.ResponseMimeType = "application/json";
                                    string strJson = TheCommonUtils.SerializeObjectToJSONString <List <string> >(listReturnValues);
                                    pRequest.ResponseBuffer = TheCommonUtils.CUTF8String2Array(strJson);
                                    pRequest.StatusCode     = (int)eHttpStatusCode.OK;
                                    pRequest.DontCompress   = true;
                                    pRequest.AllowStatePush = false;
                                    bHandled = true;
                                }
                                else
                                {
                                    // Is user performing a query on all of the properties of a specific thing?
                                    //
                                    // Sample URL:
                                    //     http://c-labs-paul-yao-laptop:8700/ThingApi/*/b0710f68-5d0f-4e00-93ea-b32c1a5a40c7/Properties?key=a6221f63-c88c-4aa1-8a83-b0fd18a6811e
                                    //
                                    // Sample Return value:
                                    //     ["Id", "Value", "FriendlyName"]
                                    //
                                    // Sample URL to get all things for all engines:
                                    //     http://c-labs-paul-yao-laptop:8700/ThingApi/*/Things?key=a6221f63-c88c-4aa1-8a83-b0fd18a6811e
                                    //
                                    // Value is Guid for a specific thing
                                    List <TheThing> listThings       = TheThingRegistry.GetThingsOfEngine(strEngineContext);
                                    List <string>   listReturnValues = new List <string>();
                                    foreach (TheThing t in listThings)
                                    {
                                        if (strThingContext == t.cdeMID.ToString())
                                        {
                                            if (strPropertyContext == "Properties")
                                            {
                                                // Enumerate all properties for the thing.

                                                bHandled = true;
                                            }
                                            else if (strPropertyContext == "Property")
                                            {
                                                // Act on an individual property

                                                bHandled = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if (!bHandled)
            {
                ResponseNotImplemented(pRequest);
            }
        }
        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 TheWSSenderThread()
        {
            if (IsSenderThreadRunning /*|| MyTargetNodeChannel==null*/)
            {
                return;
            }
            if (MyTargetNodeChannel == null)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(2371, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("WSQueuedSender", $"WSSender Thread could not be started because MTNC is null", eMsgLevel.l4_Message));
                return;
            }
            TheDiagnostics.SetThreadName($"QSender:{MyTargetNodeChannel} WSSenderThread", true);
            IsSenderThreadRunning = true;
            mre = new ManualResetEvent(false);

            CloudCounter++;
            StringBuilder tSendBufferStr = new StringBuilder(TheBaseAssets.MyServiceHostInfo?.IsMemoryOptimized == true ? 1024 : TheBaseAssets.MAX_MessageSize[(int)MyTargetNodeChannel.SenderType] * 2);
            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;
            }
            if (eventSenderThreadRunning != null)
            {
                TheCommonUtils.cdeRunAsync("EventSenderThreadRunning", true, (p) => { eventSenderThreadRunning(this); });
            }
            MyISBlock?.FireEvent("SenderThreadCreated");
            try
            {
                while (TheBaseAssets.MasterSwitch && IsAlive && MyWebSocketProcessor.IsActive && IsSenderThreadRunning)
                {
                    while (TheBaseAssets.MasterSwitch && IsAlive && MyWebSocketProcessor.IsActive && IsSenderThreadRunning && (MyTargetNodeChannel.MySessionState == null || IsConnecting || IsInWSPost || !MyWebSocketProcessor.ProcessingAllowed || MyCoreQueue.Count == 0))
                    {
                        if (IsInWSPost && MyCoreQueue.Count > 200)
                        {
                            TheBaseAssets.MySYSLOG.WriteToLog(235, new TSM("WSQueuedSender", $"IsInWSPost was still on and has been reset for {MyTargetNodeChannel?.ToMLString()}", eMsgLevel.l2_Warning));
                            IsInWSPost = false;
                        }
                        if (MyTargetNodeChannel.MySessionState == null && !IsConnecting && MyCoreQueue.Count > 0)
                        {
                            break;
                        }
                        mre.WaitOne(QDelay);
                        // System.Diagnostics.Debug.WriteLine($"Waiting :{IsAlive} {MyCoreQueue.Count} {IsConnected} {IsConnecting} {IsInWSPost} {MyWebSocketProcessor.ProcessingAllowed}");
                    }
                    if (!TheBaseAssets.MasterSwitch || !IsAlive || !MyWebSocketProcessor.IsActive || MyTargetNodeChannel.MySessionState == null)
                    {
                        TheBaseAssets.MySYSLOG.WriteToLog(235, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("WSQueuedSender", $"WSSender Thread Condition failed - Ending SenderThread IsAlive:{IsAlive} MyWSProccAlive:{(MyWebSocketProcessor == null ? false : MyWebSocketProcessor.IsActive)},SessionState:{(MyTargetNodeChannel?.MySessionState != null)} IsConnecting:{IsConnecting} IsConnected:{IsConnected}", eMsgLevel.l2_Warning));
                        break;
                    }
                    IsInWSPost = true;

                    int MCQCount  = 0;
                    int IsBatchOn = 0;
                    int FinalCnt  = 0;
#if CDE_NET35
                    tSendBufferStr = new StringBuilder(TheBaseAssets.MAX_MessageSize[(int)MyTargetNodeChannel.SenderType] * 2);
#else
                    tSendBufferStr.Clear();
#endif
                    tSendBufferStr.Append("[");
                    do
                    {
                        TheCoreQueueContent tQueued = GetNextMessage(out MCQCount);
                        if (tQueued != null)
                        {
                            TheDeviceMessage tDev = new TheDeviceMessage();
                            if (tQueued.OrgMessage != null)
                            {
                                if (tQueued.OrgMessage.ToCloudOnly() && MyTargetNodeChannel.SenderType == cdeSenderType.CDE_CLOUDROUTE)
                                {
                                    tQueued.OrgMessage.SetToCloudOnly(false);
                                }

                                tQueued.OrgMessage.GetNextSerial(tQueued.SubMsgCnt);
                                tDev.MSG = tQueued.OrgMessage;
                            }
                            var tCurSessState = MyTargetNodeChannel.MySessionState;
                            if (MyTargetNodeChannel.SenderType == cdeSenderType.CDE_JAVAJASON)
                            {
                                if (tDev.MSG == null)
                                {
                                    // we have a pickup: never send to browser
                                    if (IsBatchOn > 0)
                                    {
                                        continue;   //ignore HB as other messages are already in the queue
                                    }
                                    else
                                    {
                                        IsInWSPost = false;
                                        continue;   //dont sent empty Message to Browser - HB not necessary
                                    }
                                }
                                else
                                {
                                    tDev.MSG.SEID = null; //SECURITY: Don't send SEID to Browser
                                    tDev.MSG.UID  = null; //SECURITY: Don't send SEID to Browser
                                    tDev.MSG.SID  = null; //SECURITY: Don't send SID to Browser
                                }
                                tDev.DID = MyTargetNodeChannel.cdeMID.ToString();
                            }
                            else
                            {
                                if (tDev.MSG == null) // CODE REVIEW: DO we also need to detect other simple topics with response message and ensure they get into their own batch?
                                {
                                    // we have a pickup (only to be sent if nothing else is being sent)
                                    if (IsBatchOn > 0)
                                    {
                                        // Ignore pickups if another message is already being sent (can happen with race condition between check before pickup enqueue and dequeue here - another TSM could be enqueue in that time)
                                        continue;
                                    }
                                    else
                                    {
                                        // Close the batch here so that no other TSM gets into the same batch
                                        // Possible optimization: check if other TSMs are available and skip the pickup here as well
                                        IsBatchOn = -1; // IsInWSPost = false;
                                    }
                                }
                                tDev.DID = TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.DeviceID.ToString();
                                if (!string.IsNullOrEmpty(tQueued?.OrgMessage?.SID))
                                {
                                    tDev.SID = tQueued.OrgMessage.SID;
                                }
                                else
                                {
                                    if (TheBaseAssets.MyServiceHostInfo.EnableFastSecurity)
                                    {
                                        tDev.SID = tCurSessState.SScopeID;  //SECURITY: All tDevs will have same Session Scrambled ScopeID - 4.209: SID from TSM if set.
                                    }
                                    else
                                    {
                                        tDev.SID = TheBaseAssets.MyScopeManager.GetScrambledScopeID(tCurSessState.SScopeID, false);  //GRSI: high frequency
                                    }
                                }
                            }

                            TheCDEKPIs.IncrementKPI(eKPINames.QSSent);
                            tDev.TOP = tQueued.Topic;
                            tDev.FID = tCurSessState.GetNextSerial().ToString();
                            if (TheCommonUtils.IsDeviceSenderType(MyTargetNodeChannel.SenderType))  //IDST-OK: Must create RSA for Devices
                            {
                                TheCommonUtils.CreateRSAKeys(tCurSessState);
                                if (TheBaseAssets.MyServiceHostInfo.SecurityLevel > 3)
                                {
                                    tDev.RSA = tCurSessState.RSAPublic;  //TODO: Make depending on switch (HighSecurity=RSAGeneration every three seconds
                                }
                            }
                            if (MyTargetNodeChannel.SenderType != cdeSenderType.CDE_CLOUDROUTE) //CODE-REVIEW: 4.0113 is this still valid: Must not reset HB if talking to cloud due to Cloud-Disconnect issue
                            {
                                ResetHeartbeatTimer(false, tCurSessState);
                            }
                            if (!cdeSenderType.CDE_JAVAJASON.Equals(MyTargetNodeChannel.SenderType))
                            {
                                tDev.NPA = TheBaseAssets.MyScopeManager.GetISBPath(TheBaseAssets.MyServiceHostInfo.RootDir, MyTargetNodeChannel.SenderType, TheBaseAssets.MyServiceHostInfo.MyDeviceInfo.SenderType, tCurSessState.FID, tCurSessState.cdeMID, true);
                            }
                            if (MyTargetNodeChannel.MySessionState == null || MyTargetNodeChannel.MySessionState.HasExpired)
                            {
                                throw new Exception($"Session was deleted or has expired ({MyTargetNodeChannel?.MySessionState?.HasExpired})");
                            }
                            #region Batch Serialization
                            IsBatchOn++;
                            FinalCnt++;
                            var tToAdd = TheCommonUtils.SerializeObjectToJSONString(tDev);
                            if (MCQCount == 0 || tQueued.IsChunked || IsBatchOn > TheBaseAssets.MyServiceHostInfo.MaxBatchedTelegrams)
                            {
                                if (MCQCount != 0)
                                {
                                    tDev.CNT = MCQCount;
                                }
                                IsBatchOn = 0;
                            }
                            else
                            {
                                if (tSendBufferStr.Length + tToAdd.Length > TheBaseAssets.MAX_MessageSize[(int)MyTargetNodeChannel.SenderType])
                                {
                                    tDev.CNT  = MCQCount;
                                    IsBatchOn = 0;
                                }
                            }
                            if (tSendBufferStr.Length > 1)
                            {
                                tSendBufferStr.Append(",");
                            }
                            tSendBufferStr.Append(tToAdd);
                            #endregion
                        }
                        else
                        {
                            IsBatchOn = 0;
                        }
                    } while (IsBatchOn > 0 && IsInWSPost && TheBaseAssets.MasterSwitch);
                    if (!IsInWSPost || tSendBufferStr.Length < 2)
                    {
                        IsInWSPost = false;
                        continue;
                    }
                    tSendBufferStr.Append("]");
                    if (FinalCnt > 1)
                    {
                        TheBaseAssets.MySYSLOG.WriteToLog(235, TSM.L(eDEBUG_LEVELS.FULLVERBOSE) ? null : new TSM("WSQueuedSender", $"Batched:{FinalCnt}", eMsgLevel.l3_ImportantMessage));
                    }

                    if (!cdeSenderType.CDE_JAVAJASON.Equals(MyTargetNodeChannel.SenderType))
                    {
                        MyWebSocketProcessor.PostToSocket(null, TheCommonUtils.cdeCompressString(tSendBufferStr.ToString()), true, false);
                    }
                    else
                    {
                        MyWebSocketProcessor.PostToSocket(null, TheCommonUtils.CUTF8String2Array(tSendBufferStr.ToString()), false, false);
                    }
                    IsInWSPost = false;
                }
                TheBaseAssets.MySYSLOG.WriteToLog(235, TSM.L(eDEBUG_LEVELS.ESSENTIALS) ? null : new TSM("WSQueuedSender", $"WSQSenderThread was closed for {MyTargetNodeChannel?.ToMLString()} IsAlive:{IsAlive} MyWSProccAlive:{(MyWebSocketProcessor == null ? "Is Null" : MyWebSocketProcessor?.IsActive.ToString())},SessionState:{(MyTargetNodeChannel?.MySessionState != null)} IsConnecting:{IsConnecting} IsConnected:{IsConnected}", eMsgLevel.l1_Error));
            }
            catch (Exception e)
            {
                TheBaseAssets.MySYSLOG.WriteToLog(235, TSM.L(eDEBUG_LEVELS.OFF) ? null : new TSM("WSQueuedSender", "Exception in WSSenderThread.", eMsgLevel.l1_Error, "Error:" + e));
            }
            finally
            {
                IsInWSPost            = false;
                IsSenderThreadRunning = false;
                StopHeartBeat();
            }
            if (IsAlive || (MyWebSocketProcessor != null && MyWebSocketProcessor.IsActive))
            {
                IsAlive = false;
                if (MyWebSocketProcessor != null)
                {
                    MyWebSocketProcessor.Shutdown(true, "1310:SenderThread Closed");
                }
            }
            CloudCounter--;
        }