public void ProcessRequest(HttpContextBase context) { var response = context.Response; var path = context.GlimpseResourcePath(""); var requestId = context.GetGlimpseRequestId(); response.Write("<!DOCTYPE html><html><head><title>Glimpse - Popup</title>"); response.Write("<style type='text/css'>html{color:#000;background:#FFF;} body{margin:0;padding:0;} .glimpse-holder { position:relative !important; display: block !important; } .glimpse-popout, .glimpse-close, .glimpse-terminate, .glimpse-open { display:none !important; } .glimpse-panel { overflow:visible !important; }</style>"); response.Write("</head><body>"); response.Write(string.Format(@"<script type='text/javascript' id='glimpseData' data-glimpse-requestID='{1}'>var glimpse, glimpsePath = '{0}'</script>", path, requestId)); response.Write("<script type='text/javascript' id='glimpseClient' src='" + context.GlimpseResourcePath("client.js") + "'></script>"); response.Write("</body></html>"); }
public bool IsValid(HttpContextBase context, LifecycleEvent lifecycleEvent) { if (context == null) return false; foreach (var validator in Validators) { if (!validator.IsValid(context, lifecycleEvent)) { Logger.Warn(validator.GetType().FullName + " invalided request (it will now be ignored) with id " + context.GetGlimpseRequestId() + " (" + context.Request.Path + ")"); return false; } } return true; }
//20 private static void PreSendRequestHeaders(HttpContextBase context) { if (!RequestValidator.IsValid(context, LifecycleEvent.PreSendRequestHeaders)) return; var requestId = context.GetGlimpseRequestId().ToString(); context.Response.AddHeader(GlimpseConstants.HttpHeader, requestId); }
//12 private static void PostRequestHandlerExecute(HttpContextBase context) { if (!RequestValidator.IsValid(context, LifecycleEvent.PostRequestHandlerExecute)) return; ProcessData(context, true); //Run all plugins that DO need access to Session Logger.Info("PostRequestHandlerExecute handling complete for requestId " + context.GetGlimpseRequestId() + " (" + context.Request.Path + ")"); }
//14 private static void PostReleaseRequestState(HttpContextBase context) { if (!RequestValidator.IsValid(context, LifecycleEvent.PostReleaseRequestState)) return; if (!context.IsAjax()) context.Response.Filter = new GlimpseResponseFilter(context.Response.Filter, context); Logger.Info("PostReleaseRequestState handling complete for requestId " + context.GetGlimpseRequestId() + " (" + context.Request.Path + ")"); }
private static string GenerateGlimpseOutput(HttpContextBase context) { IDictionary<string, object> data; if (!context.TryGetData(out data)) return "Error: No Glimpse Data Found"; string json = CreateJsonPayload(data, context); Logger.Info("Glimpse JSON payload created for requestId " + context.GetGlimpseRequestId() + " (" + context.Request.Path + ")"); json = Sanitizer.Sanitize(json); return json; }
//19 private static void EndRequest(HttpContextBase context) { if (!RequestValidator.IsValid(context, LifecycleEvent.EndRequest)) return; GlimpseTimer.Moment("End Request"); ProcessData(context, false); //Run all plugins that DO NOT need access to Session var requestId = context.GetGlimpseRequestId().ToString(); CheckForPRG(context); var jsonPayload = GenerateGlimpseOutput(context); Logger.Info("Glimpse output generated for requestId " + requestId + " (" + context.Request.Path + ")"); MetadataStore.Persist(context.GetRequestMetadata(jsonPayload)); Logger.Info("RequestId " + requestId + " (" + context.Request.Path + ")" + " persisted"); Logger.Info("EndRequest handling complete for requestId " + context.GetGlimpseRequestId() + " (" + context.Request.Path + ")"); }
//TODO: clean up this massive method private static string CreateJsonPayload(IDictionary<string, object> data, HttpContextBase context) { var sb = new StringBuilder("{"); if (data.Count > 0) { foreach (var item in data) { try { string dataString = Serializer.Serialize(item.Value); sb.Append(string.Format("\"{0}\":{1},", item.Key, dataString)); } catch (Exception ex) { Logger.Warn("Problem serializing " + item.GetType().FullName, ex); var message = Serializer.Serialize(ex.Message); message = message.Remove(message.Length - 1).Remove(0, 1); var callstack = Serializer.Serialize(ex.StackTrace); callstack = callstack.Remove(callstack.Length - 1).Remove(0, 1); const string helpMessage = "Please implement an IGlimpseConverter for the type mentioned above, or one of its base types, to fix this problem. More info on a better experience for this coming soon, keep an eye on <a href='http://getGlimpse.com' target='main'>getGlimpse.com</a></span>"; sb.Append( string.Format( "\"{0}\":\"<span style='color:red;font-weight:bold'>{1}</span><br/>{2}</br><span style='color:black;font-weight:bold'>{3}</span>\",", item.Key, message, callstack, helpMessage)); } } if (sb.Length > 1) sb.Remove(sb.Length - 1, 1); var requestMetadata = new Dictionary<string, object>(); var pluginsMetadata = new Dictionary<string, object>(); var metadata = new Dictionary<string, object> { {"request", requestMetadata}, {"plugins", pluginsMetadata}, }; //environment specific metadata var environmentUrls = new Dictionary<string, string>(); foreach (Environment environment in Configuration.Environments) { environmentUrls.Add(environment.Name, environment.Something(context.Request.Url).ToString()); } //prg specific metadata string prgKey = "prgLocation"; string prgKeyRedirect = prgKey + "Redirect"; string prgKeyId = prgKey + "Id"; string prgKeyMethod = prgKey + "Method"; string prgKeyCorrelated = prgKey + "IsCorrelated"; if (context.Response.Cookies.AllKeys.Where(x => x == prgKeyCorrelated).Count() > 0) { var legs = new[] { new { method = context.Request.Cookies[prgKeyMethod].Value, url = context.Request.Cookies[prgKey].Value, glimpseId = context.Request.Cookies[prgKeyId].Value }, new { method = context.Request.HttpMethod, url = context.Request.RawUrl, glimpseId = context.GetGlimpseRequestId().ToString() } }; var correlation = new { legs = legs, title = String.Format("{0}R{1}", legs[0].method[0], legs[1].method[0]) }; requestMetadata.Add("correlation", correlation); context.Response.Cookies.Remove(prgKey); context.Response.Cookies.Remove(prgKeyRedirect); context.Response.Cookies.Remove(prgKeyId); context.Response.Cookies.Remove(prgKeyMethod); context.Response.Cookies.Remove(prgKeyCorrelated); } /* correlation = { title : 'PRG Request', legs : [ { method : 'POST', url : '/Help/Feature/Add', glimpseId : 'GUID' }, { method : 'GET', url : '/Help/Feature/', glimpseId : 'GUID' } ] };*/ requestMetadata.Add("environmentUrls", environmentUrls); requestMetadata.Add("runningVersion", decimal.Parse(RunningVersion, NumberFormatInfo.InvariantInfo)); //plugin specific metadata);)) foreach (var plugin in Plugins) { var pluginData = new Dictionary<string, object>(); var pluginValue = plugin.Value; var helpPlugin = pluginValue as IProvideGlimpseHelp; if (helpPlugin != null) pluginData.Add("helpUrl", helpPlugin.HelpUrl); var structurePlugin = pluginValue as IProvideGlimpseStructuredLayout; if (structurePlugin != null) pluginData.Add("structure", BuildStructuredLayout(structurePlugin.StructuredLayout)); var pagingPlugin = pluginValue as IProvideGlimpsePaging; if (pagingPlugin != null) pluginData.Add("pagingInfo", new { pagerKey = pagingPlugin.PagerKey, pagerType = pagingPlugin.PagerType, pageSize = pagingPlugin.PageSize, pageIndex = pagingPlugin.PageIndex, totalNumberOfRecords = pagingPlugin.TotalNumberOfRecords }); if (pluginData.Count > 0) pluginsMetadata.Add(pluginValue.Name, pluginData); } var metadataString = Serializer.Serialize(metadata); sb.Append(string.Format(",\"{0}\":{1},", "_metadata", metadataString)); if (sb.Length > 1) sb.Remove(sb.Length - 1, 1); } sb.Append("}"); return sb.ToString(); }
private static void CheckForPRG(HttpContextBase context) { string Key = "prgLocation"; string KeyRedirect = Key + "Redirect"; string KeyId = Key + "Id"; string KeyMethod = Key + "Method"; string KeyCorrelated = Key + "IsCorrelated"; //Check token Func<HttpContextBase, bool> IsCorrelated = ctx => { var isGet = ctx.Request.HttpMethod.Equals("GET", StringComparison.InvariantCultureIgnoreCase); var hasCookie = ctx.Request.Cookies.AllKeys.Contains(Key); var cookieValue = hasCookie ? ctx.Request.Cookies[KeyRedirect].Value : ""; var cookieEqualsPath = ctx.Request.Path.Equals(cookieValue); return (isGet && hasCookie && cookieEqualsPath); }; Func<HttpContextBase, bool> IsCandidate = ctx => { var isPost = true;// ctx.Request.HttpMethod.Equals("POST", StringComparison.InvariantCultureIgnoreCase); var isRedirect = (ctx.Response.StatusCode == 301 || ctx.Response.StatusCode == 302); return (isPost && isRedirect); }; if(IsCorrelated(context)) context.Response.AppendCookie(new HttpCookie(KeyCorrelated, "true")); else { //context.Response.Cookies[Key].Expires = DateTime.Now.AddDays(-5); //context.Response.Cookies[KeyId].Expires = DateTime.Now.AddDays(-5); //context.Response.Cookies[KeyMethod].Expires = DateTime.Now.AddDays(-5); context.Response.Cookies.Remove(Key); context.Response.Cookies.Remove(KeyRedirect); context.Response.Cookies.Remove(KeyId); context.Response.Cookies.Remove(KeyMethod); } //Set token if (IsCandidate(context)) { context.Response.AppendCookie(new HttpCookie(Key, context.Request.RawUrl)); context.Response.AppendCookie(new HttpCookie(KeyRedirect, context.Response.RedirectLocation)); context.Response.AppendCookie(new HttpCookie(KeyId, context.GetGlimpseRequestId().ToString())); context.Response.AppendCookie(new HttpCookie(KeyMethod, context.Request.HttpMethod)); } }
//1 private static void BeginRequest(HttpContextBase context) { if (!RequestValidator.IsValid(context, LifecycleEvent.BeginRequest)) return; context.InitGlimpseContext(); GlimpseTimer.Moment("Begin Request"); Logger.Info("BeginRequest handling complete for requestId " + context.GetGlimpseRequestId() + " (" + context.Request.Path+")"); }
private static void PreSendRequestHeaders(HttpContextBase context) { if (!RequestValidator.IsValid(context, LifecycleEvent.PreSendRequestHeaders)) return; var jsonPayload = GenerateGlimpseOutput(context); Logger.Info("Glimpse output generated for requestId " + context.GetGlimpseRequestId() + " (" + context.Request.Path + ")"); MetadataStore.Persist(context.GetRequestMetadata(jsonPayload)); Logger.Info("RequestId " + context.GetGlimpseRequestId() + " (" + context.Request.Path + ")" + " persisted"); }
private static void EndRequest(HttpContextBase context) { if (!RequestValidator.IsValid(context, LifecycleEvent.EndRequest)) return; ProcessData(context, false); //Run all plugins that DO NOT need access to Session Logger.Info("EndRequest handling complete for requestId " + context.GetGlimpseRequestId() + " (" + context.Request.Path + ")"); }
private static void AppendToResponse(HttpContextBase context, string json) { var requestId = context.GetGlimpseRequestId().ToString(); if (context.IsAjax()) { Logger.Info("Ajax request, adding HTTP Header for requestId " + context.GetGlimpseRequestId() + " (" + context.Request.Path + ")"); context.Response.AddHeader(GlimpseConstants.HttpHeader, requestId); } else { if (context.GetGlimpseMode() == GlimpseMode.On) { //var path = VirtualPathUtility.ToAbsolute("~/", context.Request.ApplicationPath); var path = context.GlimpseResourcePath(""); var html = string.Format(@"<script type='text/javascript' id='glimpseData' data-glimpse-requestID='{1}'>var glimpse = {0}, glimpsePath = '{2}';</script>", json, requestId, path); html += @"<script type='text/javascript' id='glimpseClient' src='" + context.GlimpseResourcePath("client.js") + "'></script>"; context.Response.Write(html);//TODO: Use a filter and put this inside </body> } } }