/// <summary> /// 检测请求并抛出异常 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected virtual void CheckResponse(object sender, EventArgs e) { var ctx = (HttpContext)sender; var response = ctx.Response; var content = ctx.ResponseContent; var request = ctx.Request; var cookies = response.Cookies; var redirection = response.Redirection; //IP被封? if (string.Compare(response.ResponseUri.Host, "kyfw.12306.cn", StringComparison.OrdinalIgnoreCase) == -1) { return; } if ( response.ContentType?.IndexOf("application/json") >= 0 && content is ResponseBinaryContent rbc && rbc.StringResult.IndexOf("\":[\"网络繁忙\"]", StringComparison.OrdinalIgnoreCase) != -1 ) { throw new SystemBusyException(); } if (content is ResponseBinaryContent && redirection == null) { var allowEmptyResult = false; allowEmptyResult |= response.ResponseUri.PathAndQuery.IndexOf("login/userLogin") != -1; allowEmptyResult |= response.ResponseUri.PathAndQuery.IndexOf("dynamicJs/") != -1; if (!allowEmptyResult && response.ContentLength == 0) { throw new EmptyResponseException(); } } //更新服务器信息 if ((response.Status == HttpStatusCode.Found || response.Status == HttpStatusCode.OK) && ((response.Headers["X-Cache"].IsNullOrEmpty() || response.Headers["X-Cache"].IndexOf("MISS") != -1) && response.Headers["Age"].IsNullOrEmpty() && !response.Headers["Date"].IsNullOrEmpty())) { var dt = response.Headers["Date"].ToDateTimeNullable(); if (dt.HasValue) { RunTime.UpdateServerTimeOffset(dt.Value); } } //系统维护? //if (content is ResponseStringContent && ((!ctx.Request.Host.IsNullOrEmpty() && ctx.Request.Host.IndexOf("12306.cn") != -1) || ctx.Request.Uri.Host.IndexOf("12306.cn") != -1) && ((content as ResponseStringContent).Result.IndexOf("系统维护") != -1)) //{ // throw new Entity.SystemClosedException(); //} ////登录冲突 //if ((content as ResponseStringContent)?.Result.IndexOf("noticeSessionCollect = 'Y'") > 0) //{ // Session.OnLoginConflict(Session); // throw new EmptyResponseException(); //} if (ApiConfiguration.Instance.EnableDynamicJs && content is ResponseStringContent && (ctx.IsSuccess && response.ContentType.IndexOf("text/html") != -1)) { //检测dynamicjs var m = Regex.Match((content as ResponseStringContent).Result, @"/otn/(dynamicJs\/(.+?))['""]", RegexOptions.Singleline | RegexOptions.IgnoreCase); if (m.Success) { var id = m.GetGroupValue(2); var url = m.GetGroupValue(1); var data = new DynamicJsData() { Id = id, SourceUrl = url }; var jsCtx = Create <string>(HttpMethod.Get, url, request.Uri.ToString()).Send(); if (jsCtx.IsValid()) { var jscontent = jsCtx.Result; var mcs = Regex.Matches(jscontent, @"/otn/(dynamicJs\/(.+?))['""]", RegexOptions.Singleline | RegexOptions.IgnoreCase); var km = Regex.Match(jscontent, @"gc\(\)\s*{.*?['""]([^""']+)['""]", RegexOptions.Singleline); if (mcs.Count >= 1 && km.Success) { data.PingUrl = mcs[0].GetGroupValue(1); data.NeedImmediatePingback = mcs.Count > 1; data.Key = km.GetGroupValue(1); data.EncodedValue = Base32.Encode(data.Key); data.ValidateData = $"{data.Key},-,{Base32.Encode(data.Key)}:::myversion,-,undefined"; if (data.NeedImmediatePingback) { Create <string>(HttpMethod.Post, data.PingUrl, request.Uri.ToString()).Send(); } DynamicJsData = data; } } } } AppContext.ExtensionManager.WebRequestInspectors?.ForEach(s => s.ValidateResponse(ctx, request, response, request.RequestData, content, cookies)); }