//----------------------------------------------------------------------------------------------------------------------------------------------------------- /// <summary> /// And remove the session - Anon cookie ID pairing from the application list given the specific session ID /// </summary> public void RemoveSessionRequiringHTTPS(string sessionID) { if (sessionID != null && SessionsRequiringHTTPs != null) { //Logger.Log("XXXXX RemoveSessionRequiringHTTPS: " + sessionID + " " + MGLApplicationInterface.Instance().SessionsRequiringHTTPs.Count); int index = -1; int count = 0; foreach (KeyValuePair <string, string> kvp in MGLApplicationInterface.Instance().SessionsRequiringHTTPs) { //Logger.Log("XXXXX KVP: " + kvp.Key + " " + kvp.Value); if (kvp.Value.Equals(sessionID)) { index = count; break; } count++; } if (index >= 0) { sessionsRequiringHTTPs.RemoveAt(index); } } }
//----------------------------------------------------------------------------------------------------------------------------------------------------------- /// <summary> /// Probably this is a custom cookie called AnonID .... /// </summary> public void SetSessionRequiresHTTPs(HttpCookie seshCookie, string sessionID, bool isLocal) { if (isLocal == false && seshCookie != null && sessionID != null && MGLApplicationInterface.Instance().SessionsRequiringHTTPs != null ) { // only check if it exists based on the seshCookie, not the session ID // this should catch for old sessions ... bool existsAlready = false; foreach (KeyValuePair <string, string> kvp in MGLApplicationInterface.Instance().SessionsRequiringHTTPs) { if (kvp.Key.Equals(seshCookie.Value)) { existsAlready = true; break; } } // remove it if it exists if (existsAlready == true) { MGLApplicationInterface.Instance().RemoveSessionRequiringHTTPS(sessionID); } // now add it MGLApplicationInterface.Instance().SessionsRequiringHTTPs.Add(new KeyValuePair <string, string>(seshCookie.Value, sessionID)); MGLSessionInterface.Instance().UseHTTPS = true; //Logger.Log("XXXXX SetSessionRequiresHTTPs: " + seshCookie.Value + " " + sessionID); } }
//--------------------------------------------------------------------------------------------------------------------------------------------------------- /// <summary> /// Using the OnUnload method for performance benchmarking of pages /// </summary> protected override void OnUnload(EventArgs e) { // Performance benchmarking ... DateTime dt2 = DateTime.Now; TimeSpan t1 = dt2.Subtract(dt1); string currentPageName = HttpContext.Current.Request.Url.AbsoluteUri; int currentUserID = (Authorisation.CurrentUser != null) ? Authorisation.CurrentUser.ID : 0; // 14-Jan-2015 - Get the IP Address string srcIPAddress = IPAddressHelper.GetIP4OrAnyAddressFromHTTPRequest(); // 11-Mar-2016 - Sanity check - when pages crash, dt1 is not always set so is the null date, so if the difference between dt1 and dt2 is more than one day (!!), use dt2 // 16-Mar-2016 - And reset the timespan so it is sensible, otherwise the average response time queries in view page performance do not work! // you can find the crashed pages in the db with this query: SELECT * FROM Log_PageRequests WHERE Server_Render_Speed > 63593600000000; DateTime logTime = dt1; if (t1.TotalMilliseconds > 86400000) { logTime = dt2; t1 = new TimeSpan(0, 0, 0, 0, 50); } LoggerDB.LogPageRequestInDatabase(MGLSessionInterface.Instance().Config, MGLApplicationInterface.Instance().ApplicationName, Session.SessionID, MGLSessionInterface.Instance().SessionID, currentPageName, dt2, t1.TotalMilliseconds, currentUserID, srcIPAddress); // Logger.LogError(currentPageName + "Time to build page: " + t1.TotalMilliseconds); base.OnUnload(e); }
//--------------------------------------------------------------------------------------------------------------------------------------------------------- /// <summary> /// Strims the leading white space from all lines /// WARNING - Note that this has not yet been load tested.... /// The concept is from http://optimizeasp.net/remove-whitespace-from-html /// This saves about 25% of the download size /// </summary> protected override void Render(HtmlTextWriter writer) { using (HtmlTextWriter htmlwriter = new HtmlTextWriter(new System.IO.StringWriter())) { base.Render(htmlwriter); // Only remove the leading and trailing whitespace from pages, if this has been explicitly set in the application level variables if (MGLApplicationInterface.Instance().RemoveWhitespaceFromAllPages == false) { writer.Write(htmlwriter.InnerWriter); } else { //string html = htmlwriter.InnerWriter.ToString(); // Trim the leading and trailing whitespace from the 'html' variable ////html = Regex.Replace(html, "[ \t]*[\r]?\n[ \t]*", "\r\n"); //html = R.Replace(html, "\r\n"); //writer.Write(html); // lets try concatenating all the objects to reduce the memory load slightly ... writer.Write(R.Replace(htmlwriter.InnerWriter.ToString(), "\r\n")); } } }
public static MGLApplicationInterface Instance() { MGLApplicationInterface appSingleton; //This allows us to switch which application object // we are using for secure/non-secure sessions string APPLICATION_CACHE = APP_SINGLETON; // If not in an http context (e.g. in a test context) // use a static variable to cache the ApplicationInterface if (null == System.Web.HttpContext.Current) { if (cachedApp == null) { cachedApp = new MGLApplicationInterface(); } appSingleton = cachedApp; return(appSingleton); } else if (null == System.Web.HttpContext.Current.Application[APPLICATION_CACHE]) { //No current Application object exists, use private constructor to // create an instance, place it into the Application appSingleton = new MGLApplicationInterface(); System.Web.HttpContext.Current.Application[APPLICATION_CACHE] = appSingleton; } else { //Retrieve the already instance that was already created appSingleton = (MGLApplicationInterface)System.Web.HttpContext.Current.Application[APPLICATION_CACHE]; } return(appSingleton); }
//------------------------------------------------------------------------------------------------------------------------------------------------------------- /// <summary> /// 22-Mar-2016 - This method builds the html to include static resources like javascript and css files. /// /// We want to move towards retreiving all the JS and Styles from a static resource domain e.g. static.datanirvana.org /// To do this is fine, but we also want to be able to test using local resources, so lets setup a web config param specifying the static resource path /// ~/ is the local path and e.g. static.datanirvana.org would be the static path /// If an external resource we need to choose https or not depending on the current session ... /// THe resource list will appear like this: "Scripts/jquery-1.11.3.min.js", "Scripts/Site.js", "Styles/Site.css" /// The Scripts or Styles prefix is critical as this determines which type of resource is referenced. /// Note that for external resources like maps.googleapi.com still DO NOT include the http / https prefix ... /// </summary> public static string BuildStaticResourcesHTML(Page currentPage, string[] resourceNames) { StringBuilder str = new StringBuilder(); if (resourceNames != null) { //-----a1----- declare all the variables to building these static resources to improve the readability! string staticResourcePath = MGLApplicationInterface.Instance().StaticResourcePath; bool minifyJS = MGLApplicationInterface.Instance().StaticJavascriptIsMinified; string httpPrefix = (MGLSessionInterface.Instance().UseHTTPS == true) ? "https://" : "http://"; //-----a2----- 11-May-2016 - Ok so here, if the SSLError bool in the session is set, then we DONT want to use the external resources as they wont work, so reset to use the local variants if (MGLSessionInterface.Instance().SSLError == true) { staticResourcePath = "~/"; int userID = (Authorisation.CurrentUser != null) ? Authorisation.CurrentUser.ID : 0; // This may be a little verbose on some sites, but lets keep it in for now to see how often this occurs.... Logger.LogWarning("SSL configuration error detected for user " + userID + " with ipaddress " + IPAddressHelper.GetIPAddressFromHTTPRequest() + " on page '" + currentPage.Title + "'."); } //-----a3---- And double check if we need to add a trailing forward slash .... string dir = (staticResourcePath.EndsWith("/") == true) ? "" : "/"; //-----a4----- 31-Mar-2016 - lets append the JSVersion to ALL static resources, so that we can try to influence clients browsers to automatically refresh after updates // without having to visit the new DefaultFullReload page - this needs testing!! // http://stackoverflow.com/questions/32414/how-can-i-force-clients-to-refresh-javascript-files#32427 // lets also remove the . from the version just to make 100% sure we dont confuse any legacy code that splits the file suffix on the last dot (oooops!) string versionSuffix = "?v=" + MGLApplicationInterface.Instance().JSVersion.Replace(".", ""); //-----b----- loop through the static resources foreach (string staticResource in resourceNames) { //-----c----- Get the relative path to this resource string tempPath = httpPrefix + staticResourcePath + dir + staticResource; // 31-Mar-2016 - special case for script files that are built dynamically and accessed from the code directory // We dont want to get these from the remote resource location, these should always be local.... // Note that we cannot use the default path as this gets reset to the full default path - we always just want to use the simple ~/ if (staticResource.StartsWith("Code", StringComparison.CurrentCultureIgnoreCase) == true) { tempPath = currentPage.ResolveClientUrl("~/" + staticResource); } // And lets resolve the right relative URL if this is a local implementation if (staticResourcePath.StartsWith("~")) { tempPath = currentPage.ResolveClientUrl(staticResourcePath + staticResource); } //-----d----- Build the resource tag! // 31-Mar-2016 - also include the code prefix here so that the semi-static files for the Information and Map pages are treated in the same way with the v suffix if (staticResource.StartsWith("Scripts", StringComparison.CurrentCultureIgnoreCase) == true || staticResource.StartsWith("Code", StringComparison.CurrentCultureIgnoreCase) == true) { //-----e----- Determine whether or not the javascript needs to be minified - if it does then convert the JS at the end to be .min.js if it has not already been set if (minifyJS == true && tempPath.EndsWith(".min.js", StringComparison.CurrentCultureIgnoreCase) == false) { tempPath = tempPath.ToLower().Replace(".js", ".min.js"); } str.Append("<script src=\"" + tempPath + versionSuffix + "\" type=\"text/javascript\"></script>"); } else if (staticResource.StartsWith("Styles", StringComparison.CurrentCultureIgnoreCase)) { //-----f1----- 19-Apr-2016 - we are now also minifying the CSS too - if it does then convert the css at the end to be .min.css if it has not already been set if (minifyJS == true && tempPath.EndsWith(".min.css", StringComparison.CurrentCultureIgnoreCase) == false) { tempPath = tempPath.ToLower().Replace(".css", ".min.css"); } //-----f2----- Build the styles link! str.Append("<link href=\"" + tempPath + versionSuffix + "\" rel=\"stylesheet\" type=\"text/css\" />"); } else { // Unusual / unknown static resource ... In fact, most probably an external resource! So lets not amend the staticResource string, we just prefix and dont add the ?v= // To reiterate - DO prefix with http / https and DO NOT add the version as a parameter ... // e.g. maps.googleapis.com/maps/api/js?key=MY_API_KEY str.Append("<script src=\"" + httpPrefix + staticResource + "\" type=\"text/javascript\"></script>"); } } } return(str.ToString()); }