internal void ClearOtnPort()
 {
     _currentOtnPort = null;
 }
        private void Context_ValidateResponseHeader(object sender, EventArgs e)
        {
            var ctx      = (HttpContext)sender;
            var response = ctx.Response;

            if (string.Compare(response.ResponseUri.Host, "kyfw.12306.cn", StringComparison.OrdinalIgnoreCase) == -1)
            {
                return;
            }

            var redirection = response.Redirection;

            if (redirection != null && Regex.IsMatch(redirection.Current.ToString(), @"(mormhweb/logFiles|otn/login/error)", RegexOptions.IgnoreCase | RegexOptions.Singleline))
            {
                //系统错误
                throw new SystemBusyException();
            }

            //如果返回了OTN信息,则重置OTN避免掉线
            if (IsUnexpectedLogout(ctx))
            {
                if (ApiConfiguration.Instance.EnableLogoutRescure)
                {
                    Task <bool> task;
                    lock (_lockObject)
                    {
                        task = _resetOtnPortTask;
                        if (task == null)
                        {
                            Debug.WriteLine("OTN重定向已检测到。启动检测任务。");

                            _resetOtnPortTask = Task <bool> .Factory.StartNew(() =>
                            {
                                //先校验原始信息, 最多三次, 只要成功一次即可
                                for (int i = 0; i < 3; i++)
                                {
                                    var ret = VerifySessionValid(noOtnPortCheck: true);
                                    if (ret == true)
                                    {
                                        return(false);
                                    }
                                }

                                if (ctx.ContextData?.ContainsKey("not_important") == true)
                                {
                                    if (_currentOtnPort != null)
                                    {
                                        ResetOtnPort();
                                        return(true);
                                    }
                                }
                                else
                                {
                                    var count      = 0;
                                    var errorCount = 0;
                                    ExportedSession otnSession;
                                    while (count++ < 5 && (otnSession = _currentOtnPort) != null)
                                    {
                                        var client = new NetClient();
                                        otnSession.ToSession(null, client);
                                        var ret = client.VerifySessionValid(noOtnPortCheck: true);
                                        if (ret != null)
                                        {
                                            if (ret == true)
                                            {
                                                _currentOtnPort = new ExportedSession(Session, this);
                                                ResetOtnPort();
                                                return(true);
                                            }
                                            else
                                            {
                                                if (errorCount++ >= 3)
                                                {
                                                    break;
                                                }
                                            }
                                            count--;
                                        }
                                        Thread.Sleep(100);
                                    }
                                }

                                return(false);
                            });

                            task = _resetOtnPortTask;
                        }
                    }

                    task.Wait();
                    _resetOtnPortTask = null;
                    if (task.Result)
                    {
                        Debug.WriteLine("已挽救OTNPORT");
                        throw new Exception("掉线重定向已拦截,请重试");
                    }
                }

                throw new ForceLogoutException();
            }
        }
 internal void StoreOtnPort()
 {
     _currentOtnPort = new ExportedSession();
     _currentOtnPort.FromSession(Session, this);
 }