From 7ca7b6f9228d47106e502dcfa1f97a468ac3bc5a Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 29 Jun 2017 01:04:20 +1000 Subject: [PATCH] Allows for the mini profiler in the back office (again) --- .../common/security/securityinterceptor.js | 14 ++++++++- .../src/common/services/util.service.js | 29 +++++++++++++++-- src/Umbraco.Web.UI.Client/src/init.js | 9 ++++-- .../umbraco/Views/Default.cshtml | 1 + .../umbraco_client/Application/Extensions.js | 31 +++++++++++++++++-- src/Umbraco.Web/Profiling/WebProfiler.cs | 14 ++++++--- 6 files changed, 85 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/security/securityinterceptor.js b/src/Umbraco.Web.UI.Client/src/common/security/securityinterceptor.js index 89aec01554..eb16279815 100644 --- a/src/Umbraco.Web.UI.Client/src/common/security/securityinterceptor.js +++ b/src/Umbraco.Web.UI.Client/src/common/security/securityinterceptor.js @@ -96,7 +96,18 @@ angular.module('umbraco.security.interceptor') }); }; }]) - + //used to set headers on all requests where necessary + .factory('umbracoRequestInterceptor', function ($q, queryStrings) { + return { + //dealing with requests: + 'request': function(config) { + if (queryStrings.getParams().umbDebug === "true" || queryStrings.getParams().umbdebug === "true") { + config.headers["X-UMB-DEBUG"] = "true"; + } + return config; + } + }; + }) .value('requestInterceptorFilter', function() { return ["www.gravatar.com"]; }) @@ -104,4 +115,5 @@ angular.module('umbraco.security.interceptor') // We have to add the interceptor to the queue as a string because the interceptor depends upon service instances that are not available in the config block. .config(['$httpProvider', function ($httpProvider) { $httpProvider.responseInterceptors.push('securityInterceptor'); + $httpProvider.interceptors.push('umbracoRequestInterceptor'); }]); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/util.service.js b/src/Umbraco.Web.UI.Client/src/common/services/util.service.js index 54863be0e4..067ef60492 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/util.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/util.service.js @@ -574,7 +574,32 @@ function umbPropEditorHelper() { } angular.module('umbraco.services').factory('umbPropEditorHelper', umbPropEditorHelper); - - +/** +* @ngdoc service +* @name umbraco.services.queryStrings +* @description A helper used to get query strings in the real URL (not the hash URL) +**/ +function queryStrings($window) { + + var pl = /\+/g; // Regex for replacing addition symbol with a space + var search = /([^&=]+)=?([^&]*)/g; + var decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }; + + return { + + getParams: function () { + var match; + var query = $window.location.search.substring(1); + + var urlParams = {}; + while (match = search.exec(query)) { + urlParams[decode(match[1])] = decode(match[2]); + } + + return urlParams; + } + }; +} +angular.module('umbraco.services').factory('queryStrings', queryStrings); diff --git a/src/Umbraco.Web.UI.Client/src/init.js b/src/Umbraco.Web.UI.Client/src/init.js index 016c33015d..5c70ca6a90 100644 --- a/src/Umbraco.Web.UI.Client/src/init.js +++ b/src/Umbraco.Web.UI.Client/src/init.js @@ -1,13 +1,16 @@ /** Executed when the application starts, binds to events and set global state */ -app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', 'appState', 'editorState', 'fileManager', 'assetsService', 'eventsService', '$cookies', '$templateCache', 'localStorageService', - function (userService, $log, $rootScope, $location, navigationService, appState, editorState, fileManager, assetsService, eventsService, $cookies, $templateCache, localStorageService) { +app.run(['userService', '$log', '$rootScope', '$location', 'queryStrings', 'navigationService', 'appState', 'editorState', 'fileManager', 'assetsService', 'eventsService', '$cookies', '$templateCache', 'localStorageService', + function (userService, $log, $rootScope, $location, queryStrings, navigationService, appState, editorState, fileManager, assetsService, eventsService, $cookies, $templateCache, localStorageService) { //This sets the default jquery ajax headers to include our csrf token, we // need to user the beforeSend method because our token changes per user/login so // it cannot be static $.ajaxSetup({ beforeSend: function (xhr) { - xhr.setRequestHeader("X-XSRF-TOKEN", $cookies["XSRF-TOKEN"]); + xhr.setRequestHeader("X-XSRF-TOKEN", $cookies["XSRF-TOKEN"]); + if (queryStrings.getParams().umbDebug === "true" || queryStrings.getParams().umbdebug === "true") { + xhr.setRequestHeader("X-UMB-DEBUG", "true"); + } } }); diff --git a/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml b/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml index 07063934b3..f8b7eb86cf 100644 --- a/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml +++ b/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml @@ -84,6 +84,7 @@ @if (isDebug) { + @Html.RenderProfiler() } diff --git a/src/Umbraco.Web.UI/umbraco_client/Application/Extensions.js b/src/Umbraco.Web.UI/umbraco_client/Application/Extensions.js index 63870fad08..87eb0863ad 100644 --- a/src/Umbraco.Web.UI/umbraco_client/Application/Extensions.js +++ b/src/Umbraco.Web.UI/umbraco_client/Application/Extensions.js @@ -26,7 +26,24 @@ } }; } + + if (!window.location.search.getParams) { + var pl = /\+/g; // Regex for replacing addition symbol with a space + var search = /([^&=]+)=?([^&]*)/g; + var decode = function(s) { return decodeURIComponent(s.replace(pl, " ")); }; + + window.location.search.getParams = function() { + var match; + var query = window.location.search.substring(1); + var urlParams = {}; + while (match = search.exec(query)) + urlParams[decode(match[1])] = decode(match[2]); + + return urlParams; + } + } + if (!String.prototype.startsWith) { String.prototype.startsWith = function (str) { ///startsWith extension method for string @@ -366,10 +383,20 @@ function getCookie(name) { var value = "; " + document.cookie; var parts = value.split("; " + name + "="); - if (parts.length === 2) return parts.pop().split(";").shift(); + if (parts.length === 2) + return parts.pop().split(";").shift(); + return null; } - xhr.setRequestHeader("X-XSRF-TOKEN", getCookie("XSRF-TOKEN")); + var cookieVal = getCookie("XSRF-TOKEN"); + if (cookieVal) { + xhr.setRequestHeader("X-XSRF-TOKEN", cookieVal); + } + + var queryString = window.location.search.getParams(); + if (queryString.umbDebug === "true") { + xhr.setRequestHeader("X-UMB-DEBUG", cookieVal); + } } }); diff --git a/src/Umbraco.Web/Profiling/WebProfiler.cs b/src/Umbraco.Web/Profiling/WebProfiler.cs index b1c2d9eefb..fd980db2d1 100644 --- a/src/Umbraco.Web/Profiling/WebProfiler.cs +++ b/src/Umbraco.Web/Profiling/WebProfiler.cs @@ -99,13 +99,17 @@ namespace Umbraco.Web.Profiling if (request.Success == false || request.Result.Url.IsClientSideRequest()) return false; - if (string.IsNullOrEmpty(request.Result.QueryString["umbDebug"])) - return false; + //if there is an umbDebug query string than profile it + bool umbDebug; + if (string.IsNullOrEmpty(request.Result.QueryString["umbDebug"]) == false && bool.TryParse(request.Result.QueryString["umbDebug"], out umbDebug)) + return true; - if (request.Result.Url.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath)) - return false; + //if there is an umbDebug header than profile it + if (string.IsNullOrEmpty(request.Result.Headers["X-UMB-DEBUG"]) == false && bool.TryParse(request.Result.Headers["X-UMB-DEBUG"], out umbDebug)) + return true; - return true; + //everything else is ok to profile + return false; } ///