rack-mini-profiler 2.2.0 → 2.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 42690a86bcd4e4cfd8bf17289dc7b2f583bdd4ec286b4bbcdd50454f0f73551b
4
- data.tar.gz: 723291f0ae196b09f585a331fc4e33b54bfd4be7fba527b623d851dc77524cce
3
+ metadata.gz: 24c598b577f43c0c0e9b1a35cdd187383d99ac139eb345f2fa013f3aaf64b8b7
4
+ data.tar.gz: f825e2da4a72520d2b932b743f7a842d591c07ece8925db303c76851d04dcb3c
5
5
  SHA512:
6
- metadata.gz: ca4bd7e3f35d42171bf2e39775a4a8fb565b907ba1eab40002886f7933bb4e9d30bfb8d9a87a7cb408e68b3f7e1a5dbbd360fa633f8e5c94793218abb40b32d5
7
- data.tar.gz: 877164b6caf03efc6fa4183bed8f6dfce09c691e98c9ac3588fae8307d6b1632be8e666140c4a581280b6f0bfb69c2f5d4cb100ecca0f4afe1d3a9cd770b8e7f
6
+ metadata.gz: 627fe9b6795ea764316c04c0953d3bb686961ec7cca449aadb1a97901d41d3e40d79d9131f0291aec7921e51a447bb15b77e2c9dff92df14a8e1cbfde71d469d
7
+ data.tar.gz: 9e47290fb3bf24d312ef9d9d7e3d60a9db968f39b40229a48a81a354152822cce7d0bb072c09427f1a1d63b811aa6e48c398ff96a9dd20126f7e512bd2dbce15
@@ -1,5 +1,11 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 2.2.1 - 2020-12-23
4
+
5
+ - [FIX] Turbolinks integration causing increasing number of GET requests
6
+ - [FEATURE] enahanced log transporter with compression and exponential backoff
7
+ - [FEATURE] sameSite=Lax added to MiniProfiler cookie
8
+
3
9
  ## 2.2.0 - 2020-10-19
4
10
 
5
11
  - [UX] Enhancements to snapshots UI
data/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # rack-mini-profiler
2
2
 
3
- [![Code Climate](https://codeclimate.com/github/MiniProfiler/rack-mini-profiler/badges/gpa.svg)](https://codeclimate.com/github/MiniProfiler/rack-mini-profiler) [![Build Status](https://travis-ci.org/MiniProfiler/rack-mini-profiler.svg)](https://travis-ci.org/MiniProfiler/rack-mini-profiler)
4
-
5
3
  Middleware that displays speed badge for every html page. Designed to work both in production and in development.
6
4
 
7
5
  #### Features
@@ -202,9 +200,11 @@ Mini Profiler will keep a maximum of 1000 snapshots by default, and you can chan
202
200
 
203
201
  Mini Profiler can be configured so that it sends snapshots over HTTP using the snapshots transporter. The main use-case of the transporter is to allow the aggregation of snapshots from multiple applications/sources in a single place. To enable the snapshots transporter, you need to provide a destination URL to the `snapshots_transport_destination_url` config, and a secure key to the `snapshots_transport_auth_key` config (will be used for authorization). Both of these configs are required for the transporter to be enabled.
204
202
 
205
- The transporter uses a buffer to temporarily hold snapshots in memory with a limit of 100 snapshots. Every 10 seconds, *if* the buffer is not empty, the transporter will make a `POST` request with the buffer content to the destination URL. Requests made by the transporter will have a `Mini-Profiler-Transport-Auth` header with the value of the `snapshots_transport_auth_key` config. The destination should only accept requests that include this header AND the header's value matches the key you set to the `snapshots_transport_auth_key` config.
203
+ The transporter uses a buffer to temporarily hold snapshots in memory with a limit of 100 snapshots. Every 30 seconds, *if* the buffer is not empty, the transporter will make a `POST` request with the buffer content to the destination URL. Requests made by the transporter will have a `Mini-Profiler-Transport-Auth` header with the value of the `snapshots_transport_auth_key` config. The destination should only accept requests that include this header AND the header's value matches the key you set to the `snapshots_transport_auth_key` config.
204
+
205
+ If the specified destination responds with a non-200 status code, the transporter will increase the interval between requests by `2^n` seconds where `n` is the number of failed requests since the last successful request. The base interval between requests is 30 seconds. So if a request fails, the next request will be `30 + 2^1 = 32` seconds later. If the next request fails too, the next one will be `30 + 2^2 = 34` seconds later and so on until a request succeeds at which point the interval will return to 30 seconds. The interval will not go beyond 1 hour.
206
206
 
207
- The body of the requests made by the transporter is a JSON string with a single top-level key called `snapshots` and it has an array of snapshots. The structure of a snapshot is too complex to be explained here, but it has the same structure that Mini Profiler client expects. So if your use-case is to simply be able to view snapshots from multiple sources in one place, you should simply store the snapshots as-is, and then serve them to Mini Profiler client to consume. If the destination application also has Mini Profiler, you can simply use the API of the storage backends to store the incoming snapshots and Mini Profiler will treat them the same as local snapshots (e.g. they'll be grouped and displayed in the same manner described in the previous section).
207
+ Requests made by the transporter can be optionally gzip-compressed by setting the `snapshots_transport_gzip_requests` config to true. The body of the requests (after decompression, if you opt for compression) is a JSON string with a single top-level key called `snapshots` and it has an array of snapshots. The structure of a snapshot is too complex to be explained here, but it has the same structure that Mini Profiler client expects. So if your use-case is to simply be able to view snapshots from multiple sources in one place, you should simply store the snapshots as-is, and then serve them to Mini Profiler client to consume. If the destination application also has Mini Profiler, you can simply use the API of the storage backends to store the incoming snapshots and Mini Profiler will treat them the same as local snapshots (e.g. they'll be grouped and displayed in the same manner described in the previous section).
208
208
 
209
209
  Mini Profiler offers an API to add extra fields (a.k.a custom fields) to snapshots. For example, you may want to add whether the request was made by a logged-in or anonymous user, the version of your application or any other things that are specific to your application. To add custom fields to a snapshot, call the `Rack::MiniProfiler.add_snapshot_custom_field(<key>, <value>)` method anywhere during the lifetime of a request, and the snapshot of that request will include the fields you added. If you have a Rails app, you can call that method in an `after_action` callback. Custom fields are cleared between requests.
210
210
 
@@ -398,6 +398,7 @@ snapshot_hidden_custom_fields|`[]`|Each snapshot custom field will have a dedica
398
398
  snapshots_transport_destination_url|`nil`|Set this config to a valid URL to enable snapshots transporter which will `POST` snapshots to the given URL. The transporter requires `snapshots_transport_auth_key` config to be set as well.
399
399
  snapshots_transport_auth_key|`nil`|`POST` requests made by the snapshots transporter to the destination URL will have a `Mini-Profiler-Transport-Auth` header with the value of this config. Make sure you use a secure and random key for this config.
400
400
  snapshots_redact_sql_queries|`true`|When this is true, SQL queries will be redacted from sampling snapshots, but the backtrace and duration of each SQL query will be saved with the snapshot to keep debugging performance issues possible.
401
+ snapshots_transport_gzip_requests|`false`|Make the snapshots transporter gzip the requests it makes to `snapshots_transport_destination_url`.
401
402
 
402
403
  ### Using MiniProfiler with `Rack::Deflate` middleware
403
404
 
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
 
3
- var MiniProfiler = (function() {
3
+ var _MiniProfiler = (function() {
4
4
  var _arguments = arguments;
5
5
  var options,
6
6
  container,
7
7
  controls,
8
- fetchedIds = [],
9
- fetchingIds = [],
8
+ fetchedIds = (window.MiniProfiler && window.MiniProfiler.fetchedIds) || [],
9
+ fetchingIds =
10
+ (window.MiniProfiler && window.MiniProfiler.fetchingIds) || [],
10
11
  // so we never pull down a profiler twice
11
12
  ajaxStartTime,
12
13
  totalsControl,
@@ -634,6 +635,10 @@ var MiniProfiler = (function() {
634
635
  }
635
636
  };
636
637
 
638
+ var turbolinksSkipResultsFetch = function turbolinksSkipResultsFetch(event) {
639
+ event.data.xhr.__miniProfilerSkipResultsFetch = true;
640
+ };
641
+
637
642
  var bindDocumentEvents = function bindDocumentEvents() {
638
643
  document.addEventListener("click", onClickEvents);
639
644
  document.addEventListener("keyup", onClickEvents);
@@ -642,6 +647,10 @@ var MiniProfiler = (function() {
642
647
  if (typeof Turbolinks !== "undefined" && Turbolinks.supported) {
643
648
  document.addEventListener("page:change", unbindDocumentEvents);
644
649
  document.addEventListener("turbolinks:load", unbindDocumentEvents);
650
+ document.addEventListener(
651
+ "turbolinks:request-start",
652
+ turbolinksSkipResultsFetch
653
+ );
645
654
  }
646
655
  };
647
656
 
@@ -651,6 +660,10 @@ var MiniProfiler = (function() {
651
660
  document.removeEventListener("keyup", toggleShortcutEvent);
652
661
  document.removeEventListener("page:change", unbindDocumentEvents);
653
662
  document.removeEventListener("turbolinks:load", unbindDocumentEvents);
663
+ document.removeEventListener(
664
+ "turbolinks:request-start",
665
+ turbolinksSkipResultsFetch
666
+ );
654
667
  };
655
668
 
656
669
  var initFullView = function initFullView() {
@@ -680,10 +693,12 @@ var MiniProfiler = (function() {
680
693
  temp.innerHTML = MiniProfiler.templates.snapshotsGroupsList(data);
681
694
  } else if (data.group_name) {
682
695
  var allCustomFieldsNames = [];
683
- data.list.forEach(function (snapshot) {
684
- Object.keys(snapshot.custom_fields).forEach(function (k) {
685
- if (allCustomFieldsNames.indexOf(k) === -1 &&
686
- options.hiddenCustomFields.indexOf(k.toLowerCase()) === -1) {
696
+ data.list.forEach(function(snapshot) {
697
+ Object.keys(snapshot.custom_fields).forEach(function(k) {
698
+ if (
699
+ allCustomFieldsNames.indexOf(k) === -1 &&
700
+ options.hiddenCustomFields.indexOf(k.toLowerCase()) === -1
701
+ ) {
687
702
  allCustomFieldsNames.push(k);
688
703
  }
689
704
  });
@@ -694,7 +709,7 @@ var MiniProfiler = (function() {
694
709
  allCustomFieldsNames: allCustomFieldsNames
695
710
  });
696
711
  }
697
- Array.from(temp.children).forEach(function (child) {
712
+ Array.from(temp.children).forEach(function(child) {
698
713
  document.body.appendChild(child);
699
714
  });
700
715
  };
@@ -767,213 +782,220 @@ var MiniProfiler = (function() {
767
782
  fetchResults(options.ids);
768
783
  }
769
784
 
770
- var send = XMLHttpRequest.prototype.send;
771
-
772
- XMLHttpRequest.prototype.send = function(data) {
773
- ajaxStartTime = new Date();
774
- this.addEventListener("load", function() {
775
- // responseURL isn't available in IE11
776
- if (
777
- this.responseURL &&
778
- this.responseURL.indexOf(window.location.origin) !== 0
779
- ) {
780
- return;
781
- }
782
- // getAllResponseHeaders isn't available in Edge.
783
- var allHeaders = this.getAllResponseHeaders
784
- ? this.getAllResponseHeaders()
785
- : null;
786
- if (
787
- allHeaders &&
788
- allHeaders.toLowerCase().indexOf("x-miniprofiler-ids") === -1
789
- ) {
790
- return;
791
- }
792
- // should be a string of comma-separated ids
793
- var stringIds = this.getResponseHeader("X-MiniProfiler-Ids");
794
-
795
- if (stringIds) {
796
- var ids = stringIds.split(",");
797
- fetchResults(ids);
798
- }
799
- });
800
- send.call(this, data);
801
- }; // fetch results after ASP Ajax calls
802
-
803
- if (
804
- typeof Sys != "undefined" &&
805
- typeof Sys.WebForms != "undefined" &&
806
- typeof Sys.WebForms.PageRequestManager != "undefined"
807
- ) {
808
- // Get the instance of PageRequestManager.
809
- var PageRequestManager = Sys.WebForms.PageRequestManager.getInstance();
810
- PageRequestManager.add_endRequest(function(sender, args) {
811
- if (args) {
812
- var response = args.get_response();
785
+ if (!window.MiniProfiler || !window.MiniProfiler.patchesApplied) {
786
+ var send = XMLHttpRequest.prototype.send;
813
787
 
788
+ XMLHttpRequest.prototype.send = function(data) {
789
+ ajaxStartTime = new Date();
790
+ this.addEventListener("load", function() {
791
+ // responseURL isn't available in IE11
814
792
  if (
815
- response.get_responseAvailable() &&
816
- response._xmlHttpRequest !== null
793
+ this.responseURL &&
794
+ this.responseURL.indexOf(window.location.origin) !== 0
817
795
  ) {
818
- var stringIds = args
819
- .get_response()
820
- .getResponseHeader("X-MiniProfiler-Ids");
821
-
822
- if (stringIds) {
823
- var ids = stringIds.split(",");
824
- fetchResults(ids);
825
- }
796
+ return;
826
797
  }
827
- }
828
- });
829
- } // more Asp.Net callbacks
830
-
831
- if (typeof WebForm_ExecuteCallback == "function") {
832
- WebForm_ExecuteCallback = (function(callbackObject) {
833
- // Store original function
834
- var original = WebForm_ExecuteCallback;
835
- return function(callbackObject) {
836
- original(callbackObject);
837
- var stringIds = callbackObject.xmlRequest.getResponseHeader(
838
- "X-MiniProfiler-Ids"
839
- );
798
+ if (this.__miniProfilerSkipResultsFetch) {
799
+ return;
800
+ }
801
+ // getAllResponseHeaders isn't available in Edge.
802
+ var allHeaders = this.getAllResponseHeaders
803
+ ? this.getAllResponseHeaders()
804
+ : null;
805
+ if (
806
+ allHeaders &&
807
+ allHeaders.toLowerCase().indexOf("x-miniprofiler-ids") === -1
808
+ ) {
809
+ return;
810
+ }
811
+ // should be a string of comma-separated ids
812
+ var stringIds = this.getResponseHeader("X-MiniProfiler-Ids");
840
813
 
841
814
  if (stringIds) {
842
815
  var ids = stringIds.split(",");
843
816
  fetchResults(ids);
844
817
  }
845
- };
846
- })();
847
- } // also fetch results after ExtJS requests, in case it is being used
818
+ });
819
+ send.call(this, data);
820
+ }; // fetch results after ASP Ajax calls
848
821
 
849
- if (
850
- typeof Ext != "undefined" &&
851
- typeof Ext.Ajax != "undefined" &&
852
- typeof Ext.Ajax.on != "undefined"
853
- ) {
854
- // Ext.Ajax is a singleton, so we just have to attach to its 'requestcomplete' event
855
- Ext.Ajax.on("requestcomplete", function(e, xhr, settings) {
856
- //iframed file uploads don't have headers
857
- if (!xhr || !xhr.getResponseHeader) {
858
- return;
859
- }
822
+ if (
823
+ typeof Sys != "undefined" &&
824
+ typeof Sys.WebForms != "undefined" &&
825
+ typeof Sys.WebForms.PageRequestManager != "undefined"
826
+ ) {
827
+ // Get the instance of PageRequestManager.
828
+ var PageRequestManager = Sys.WebForms.PageRequestManager.getInstance();
829
+ PageRequestManager.add_endRequest(function(sender, args) {
830
+ if (args) {
831
+ var response = args.get_response();
832
+
833
+ if (
834
+ response.get_responseAvailable() &&
835
+ response._xmlHttpRequest !== null
836
+ ) {
837
+ var stringIds = args
838
+ .get_response()
839
+ .getResponseHeader("X-MiniProfiler-Ids");
840
+
841
+ if (stringIds) {
842
+ var ids = stringIds.split(",");
843
+ fetchResults(ids);
844
+ }
845
+ }
846
+ }
847
+ });
848
+ } // more Asp.Net callbacks
849
+
850
+ if (typeof WebForm_ExecuteCallback == "function") {
851
+ WebForm_ExecuteCallback = (function(callbackObject) {
852
+ // Store original function
853
+ var original = WebForm_ExecuteCallback;
854
+ return function(callbackObject) {
855
+ original(callbackObject);
856
+ var stringIds = callbackObject.xmlRequest.getResponseHeader(
857
+ "X-MiniProfiler-Ids"
858
+ );
860
859
 
861
- var stringIds = xhr.getResponseHeader("X-MiniProfiler-Ids");
860
+ if (stringIds) {
861
+ var ids = stringIds.split(",");
862
+ fetchResults(ids);
863
+ }
864
+ };
865
+ })();
866
+ } // also fetch results after ExtJS requests, in case it is being used
862
867
 
863
- if (stringIds) {
864
- var ids = stringIds.split(",");
865
- fetchResults(ids);
866
- }
867
- });
868
- }
868
+ if (
869
+ typeof Ext != "undefined" &&
870
+ typeof Ext.Ajax != "undefined" &&
871
+ typeof Ext.Ajax.on != "undefined"
872
+ ) {
873
+ // Ext.Ajax is a singleton, so we just have to attach to its 'requestcomplete' event
874
+ Ext.Ajax.on("requestcomplete", function(e, xhr, settings) {
875
+ //iframed file uploads don't have headers
876
+ if (!xhr || !xhr.getResponseHeader) {
877
+ return;
878
+ }
869
879
 
870
- if (typeof MooTools != "undefined" && typeof Request != "undefined") {
871
- Request.prototype.addEvents({
872
- onComplete: function onComplete() {
873
- var stringIds = this.xhr.getResponseHeader("X-MiniProfiler-Ids");
880
+ var stringIds = xhr.getResponseHeader("X-MiniProfiler-Ids");
874
881
 
875
882
  if (stringIds) {
876
883
  var ids = stringIds.split(",");
877
884
  fetchResults(ids);
878
885
  }
879
- }
880
- });
881
- } // add support for AngularJS, which use the basic XMLHttpRequest object.
882
-
883
- if (window.angular && typeof XMLHttpRequest != "undefined") {
884
- var _send = XMLHttpRequest.prototype.send;
885
-
886
- XMLHttpRequest.prototype.send = function sendReplacement(data) {
887
- if (this.onreadystatechange) {
888
- if (
889
- typeof this.miniprofiler == "undefined" ||
890
- typeof this.miniprofiler.prev_onreadystatechange == "undefined"
891
- ) {
892
- this.miniprofiler = {
893
- prev_onreadystatechange: this.onreadystatechange
894
- };
886
+ });
887
+ }
895
888
 
896
- this.onreadystatechange = function onReadyStateChangeReplacement() {
897
- if (this.readyState == 4) {
898
- var stringIds = this.getResponseHeader("X-MiniProfiler-Ids");
889
+ if (typeof MooTools != "undefined" && typeof Request != "undefined") {
890
+ Request.prototype.addEvents({
891
+ onComplete: function onComplete() {
892
+ var stringIds = this.xhr.getResponseHeader("X-MiniProfiler-Ids");
899
893
 
900
- if (stringIds) {
901
- var ids = stringIds.split(",");
902
- fetchResults(ids);
894
+ if (stringIds) {
895
+ var ids = stringIds.split(",");
896
+ fetchResults(ids);
897
+ }
898
+ }
899
+ });
900
+ } // add support for AngularJS, which use the basic XMLHttpRequest object.
901
+
902
+ if (window.angular && typeof XMLHttpRequest != "undefined") {
903
+ var _send = XMLHttpRequest.prototype.send;
904
+
905
+ XMLHttpRequest.prototype.send = function sendReplacement(data) {
906
+ if (this.onreadystatechange) {
907
+ if (
908
+ typeof this.miniprofiler == "undefined" ||
909
+ typeof this.miniprofiler.prev_onreadystatechange == "undefined"
910
+ ) {
911
+ this.miniprofiler = {
912
+ prev_onreadystatechange: this.onreadystatechange
913
+ };
914
+
915
+ this.onreadystatechange = function onReadyStateChangeReplacement() {
916
+ if (this.readyState == 4) {
917
+ var stringIds = this.getResponseHeader("X-MiniProfiler-Ids");
918
+
919
+ if (stringIds) {
920
+ var ids = stringIds.split(",");
921
+ fetchResults(ids);
922
+ }
903
923
  }
904
- }
905
924
 
906
- if (this.miniprofiler.prev_onreadystatechange !== null)
907
- return this.miniprofiler.prev_onreadystatechange.apply(
908
- this,
909
- arguments
910
- );
911
- };
925
+ if (this.miniprofiler.prev_onreadystatechange !== null)
926
+ return this.miniprofiler.prev_onreadystatechange.apply(
927
+ this,
928
+ arguments
929
+ );
930
+ };
931
+ }
912
932
  }
913
- }
914
-
915
- return _send.apply(this, arguments);
916
- };
917
- } // https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
918
933
 
919
- if (
920
- typeof window.fetch === "function" &&
921
- window.fetch.__patchedByMiniProfiler === undefined
922
- ) {
923
- var __originalFetch = window.fetch;
934
+ return _send.apply(this, arguments);
935
+ };
936
+ } // https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
924
937
 
925
- window.fetch = function(input, init) {
926
- var originalFetchRun = __originalFetch(input, init);
938
+ if (typeof window.fetch === "function") {
939
+ var __originalFetch = window.fetch;
927
940
 
928
- originalFetchRun.then(function(response) {
929
- try {
930
- // look for x-mini-profile-ids
931
- var entries = response.headers.entries();
932
- var _iteratorNormalCompletion = true;
933
- var _didIteratorError = false;
934
- var _iteratorError = undefined;
941
+ window.fetch = function(input, init) {
942
+ var originalFetchRun = __originalFetch(input, init);
935
943
 
944
+ originalFetchRun.then(function(response) {
936
945
  try {
937
- for (
938
- var _iterator = entries[Symbol.iterator](), _step;
939
- !(_iteratorNormalCompletion = (_step = _iterator.next()).done);
940
- _iteratorNormalCompletion = true
941
- ) {
942
- var pair = _step.value;
943
-
944
- if (pair[0] && pair[0].toLowerCase() == "x-miniprofiler-ids") {
945
- var ids = pair[1].split(",");
946
- fetchResults(ids);
947
- }
948
- }
949
- } catch (err) {
950
- _didIteratorError = true;
951
- _iteratorError = err;
952
- } finally {
946
+ // look for x-mini-profile-ids
947
+ var entries = response.headers.entries();
948
+ var _iteratorNormalCompletion = true;
949
+ var _didIteratorError = false;
950
+ var _iteratorError = undefined;
951
+
953
952
  try {
954
- if (!_iteratorNormalCompletion && _iterator.return != null) {
955
- _iterator.return();
953
+ for (
954
+ var _iterator = entries[Symbol.iterator](), _step;
955
+ !(_iteratorNormalCompletion = (_step = _iterator.next())
956
+ .done);
957
+ _iteratorNormalCompletion = true
958
+ ) {
959
+ var pair = _step.value;
960
+
961
+ if (
962
+ pair[0] &&
963
+ pair[0].toLowerCase() == "x-miniprofiler-ids"
964
+ ) {
965
+ var ids = pair[1].split(",");
966
+ fetchResults(ids);
967
+ }
956
968
  }
969
+ } catch (err) {
970
+ _didIteratorError = true;
971
+ _iteratorError = err;
957
972
  } finally {
958
- if (_didIteratorError) {
959
- throw _iteratorError;
973
+ try {
974
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
975
+ _iterator.return();
976
+ }
977
+ } finally {
978
+ if (_didIteratorError) {
979
+ throw _iteratorError;
980
+ }
960
981
  }
961
982
  }
983
+ } catch (e) {
984
+ console.error(e);
962
985
  }
963
- } catch (e) {
964
- console.error(e);
965
- }
966
- });
967
- return originalFetchRun;
968
- };
969
-
970
- window.fetch.__patchedByMiniProfiler = true;
971
- } // some elements want to be hidden on certain doc events
986
+ });
987
+ return originalFetchRun;
988
+ };
989
+ }
990
+ window.MiniProfiler.patchesApplied = true;
991
+ }
972
992
 
973
993
  bindDocumentEvents();
974
994
  };
975
995
 
976
996
  return {
997
+ fetchedIds: fetchedIds,
998
+ fetchingIds: fetchingIds,
977
999
  init: function init() {
978
1000
  var script = document.getElementById("mini-profiler");
979
1001
  if (!script || !script.getAttribute) return;
@@ -1007,7 +1029,10 @@ var MiniProfiler = (function() {
1007
1029
  sessionStorage["rack-mini-profiler-start-hidden"] === "true";
1008
1030
  var htmlContainer = script.getAttribute("data-html-container");
1009
1031
  var cssUrl = script.getAttribute("data-css-url");
1010
- var hiddenCustomFields = script.getAttribute("data-hidden-custom-fields").toLowerCase().split(",");
1032
+ var hiddenCustomFields = script
1033
+ .getAttribute("data-hidden-custom-fields")
1034
+ .toLowerCase()
1035
+ .split(",");
1011
1036
  return {
1012
1037
  ids: ids,
1013
1038
  path: path,
@@ -1432,7 +1457,7 @@ var MiniProfiler = (function() {
1432
1457
  return options.showTotalSqlCount;
1433
1458
  },
1434
1459
  timestampToRelative: function timestampToRelative(timestamp) {
1435
- var now = Math.round((new Date()).getTime() / 1000);
1460
+ var now = Math.round(new Date().getTime() / 1000);
1436
1461
  timestamp = Math.round(timestamp / 1000);
1437
1462
  var diff = now - timestamp;
1438
1463
  if (diff < 60) {
@@ -1444,7 +1469,7 @@ var MiniProfiler = (function() {
1444
1469
  res += "s";
1445
1470
  }
1446
1471
  return res;
1447
- }
1472
+ };
1448
1473
  diff = Math.round(diff / 60);
1449
1474
  if (diff <= 60) {
1450
1475
  return buildDisplayTime(diff, "minute");
@@ -1459,5 +1484,8 @@ var MiniProfiler = (function() {
1459
1484
  };
1460
1485
  })();
1461
1486
 
1462
- window.MiniProfiler = MiniProfiler;
1463
- MiniProfiler.init();
1487
+ if (window.MiniProfiler) {
1488
+ _MiniProfiler.patchesApplied = window.MiniProfiler.patchesApplied;
1489
+ }
1490
+ window.MiniProfiler = _MiniProfiler;
1491
+ _MiniProfiler.init();
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module Rack
3
3
  class MiniProfiler
4
- ASSET_VERSION = 'f8924c1fd3fbe1787f0bed5c8998b636'
4
+ ASSET_VERSION = '10da952c710f6abd9f1bd50fe50ed714'
5
5
  end
6
6
  end
@@ -56,6 +56,7 @@ module Rack
56
56
  @snapshots_transport_destination_url = nil
57
57
  @snapshots_transport_auth_key = nil
58
58
  @snapshots_redact_sql_queries = true
59
+ @snapshots_transport_gzip_requests = false
59
60
 
60
61
  self
61
62
  }
@@ -77,7 +78,8 @@ module Rack
77
78
  # snapshot related config
78
79
  attr_accessor :snapshot_every_n_requests, :snapshots_limit,
79
80
  :snapshot_hidden_custom_fields, :snapshots_transport_destination_url,
80
- :snapshots_transport_auth_key, :snapshots_redact_sql_queries
81
+ :snapshots_transport_auth_key, :snapshots_redact_sql_queries,
82
+ :snapshots_transport_gzip_requests
81
83
 
82
84
  # Deprecated options
83
85
  attr_accessor :use_existing_jquery
@@ -23,16 +23,18 @@ class ::Rack::MiniProfiler::SnapshotsTransporter
23
23
  end
24
24
 
25
25
  attr_reader :buffer
26
- attr_accessor :max_buffer_size
26
+ attr_accessor :max_buffer_size, :gzip_requests
27
27
 
28
28
  def initialize(config)
29
29
  @uri = URI(config.snapshots_transport_destination_url)
30
30
  @auth_key = config.snapshots_transport_auth_key
31
+ @gzip_requests = config.snapshots_transport_gzip_requests
31
32
  @thread = nil
32
33
  @thread_mutex = Mutex.new
33
34
  @buffer = []
34
35
  @buffer_mutex = Mutex.new
35
36
  @max_buffer_size = 100
37
+ @consecutive_failures_count = 0
36
38
  @testing = false
37
39
  end
38
40
 
@@ -49,12 +51,24 @@ class ::Rack::MiniProfiler::SnapshotsTransporter
49
51
  @buffer.dup if @buffer.size > 0
50
52
  end
51
53
  if buffer_content
52
- request = Net::HTTP::Post.new(
53
- @uri,
54
+ headers = {
54
55
  'Content-Type' => 'application/json',
55
56
  'Mini-Profiler-Transport-Auth' => @auth_key
56
- )
57
- request.body = { snapshots: buffer_content }.to_json
57
+ }
58
+ json = { snapshots: buffer_content }.to_json
59
+ body = if @gzip_requests
60
+ require 'zlib'
61
+ io = StringIO.new
62
+ gzip_writer = Zlib::GzipWriter.new(io)
63
+ gzip_writer.write(json)
64
+ gzip_writer.close
65
+ headers['Content-Encoding'] = 'gzip'
66
+ io.string
67
+ else
68
+ json
69
+ end
70
+ request = Net::HTTP::Post.new(@uri, headers)
71
+ request.body = body
58
72
  http = Net::HTTP.new(@uri.hostname, @uri.port)
59
73
  http.use_ssl = @uri.scheme == 'https'
60
74
  res = http.request(request)
@@ -64,19 +78,30 @@ class ::Rack::MiniProfiler::SnapshotsTransporter
64
78
  @buffer_mutex.synchronize do
65
79
  @buffer -= buffer_content
66
80
  end
81
+ @consecutive_failures_count = 0
67
82
  else
68
83
  @@failed_http_requests_count += 1
84
+ @consecutive_failures_count += 1
69
85
  end
70
86
  end
71
87
  end
72
88
 
89
+ def requests_interval
90
+ [30 + backoff_delay, 60 * 60].min
91
+ end
92
+
73
93
  private
74
94
 
95
+ def backoff_delay
96
+ return 0 if @consecutive_failures_count == 0
97
+ 2**@consecutive_failures_count
98
+ end
99
+
75
100
  def start_thread
76
101
  return if @thread&.alive? || @testing
77
102
  @thread = Thread.new do
78
103
  while true
79
- sleep 10
104
+ sleep requests_interval
80
105
  flush_buffer
81
106
  end
82
107
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rack
4
4
  class MiniProfiler
5
- VERSION = '2.2.0'
5
+ VERSION = '2.2.1'
6
6
  end
7
7
  end
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
28
28
  'changelog_uri' => 'https://github.com/MiniProfiler/rack-mini-profiler/blob/master/CHANGELOG.md'
29
29
  }
30
30
 
31
- s.add_development_dependency 'rake', '< 11'
31
+ s.add_development_dependency 'rake'
32
32
  s.add_development_dependency 'rack-test'
33
33
  s.add_development_dependency 'dalli'
34
34
  s.add_development_dependency 'rspec', '~> 3.6.0'
@@ -40,8 +40,8 @@ Gem::Specification.new do |s|
40
40
  s.add_development_dependency 'nokogiri'
41
41
  s.add_development_dependency 'rubocop-discourse'
42
42
  s.add_development_dependency 'listen'
43
- s.add_development_dependency 'webpacker', '~> 5.1'
44
- s.add_development_dependency 'rails', '~> 5.1'
43
+ s.add_development_dependency 'webpacker'
44
+ s.add_development_dependency 'rails', '~> 6.0'
45
45
  s.add_development_dependency 'webmock', '3.9.1'
46
46
 
47
47
  s.require_paths = ["lib"]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-mini-profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2020-10-20 00:00:00.000000000 Z
13
+ date: 2020-12-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rack
@@ -30,16 +30,16 @@ dependencies:
30
30
  name: rake
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
- - - "<"
33
+ - - ">="
34
34
  - !ruby/object:Gem::Version
35
- version: '11'
35
+ version: '0'
36
36
  type: :development
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
39
39
  requirements:
40
- - - "<"
40
+ - - ">="
41
41
  - !ruby/object:Gem::Version
42
- version: '11'
42
+ version: '0'
43
43
  - !ruby/object:Gem::Dependency
44
44
  name: rack-test
45
45
  requirement: !ruby/object:Gem::Requirement
@@ -198,30 +198,30 @@ dependencies:
198
198
  name: webpacker
199
199
  requirement: !ruby/object:Gem::Requirement
200
200
  requirements:
201
- - - "~>"
201
+ - - ">="
202
202
  - !ruby/object:Gem::Version
203
- version: '5.1'
203
+ version: '0'
204
204
  type: :development
205
205
  prerelease: false
206
206
  version_requirements: !ruby/object:Gem::Requirement
207
207
  requirements:
208
- - - "~>"
208
+ - - ">="
209
209
  - !ruby/object:Gem::Version
210
- version: '5.1'
210
+ version: '0'
211
211
  - !ruby/object:Gem::Dependency
212
212
  name: rails
213
213
  requirement: !ruby/object:Gem::Requirement
214
214
  requirements:
215
215
  - - "~>"
216
216
  - !ruby/object:Gem::Version
217
- version: '5.1'
217
+ version: '6.0'
218
218
  type: :development
219
219
  prerelease: false
220
220
  version_requirements: !ruby/object:Gem::Requirement
221
221
  requirements:
222
222
  - - "~>"
223
223
  - !ruby/object:Gem::Version
224
- version: '5.1'
224
+ version: '6.0'
225
225
  - !ruby/object:Gem::Dependency
226
226
  name: webmock
227
227
  requirement: !ruby/object:Gem::Requirement
@@ -322,7 +322,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
322
322
  - !ruby/object:Gem::Version
323
323
  version: '0'
324
324
  requirements: []
325
- rubygems_version: 3.0.3
325
+ rubygems_version: 3.2.2
326
326
  signing_key:
327
327
  specification_version: 4
328
328
  summary: Profiles loading speed for rack applications.