rack-mini-profiler 1.0.2 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,25 +1,23 @@
1
- <script id="profilerTemplate" type="text/x-jquery-tmpl">
2
-
1
+ <script id="profilerTemplate" type="text/x-dot-tmpl">
3
2
  <div class="profiler-result">
4
-
5
- <div class="profiler-button {{if has_duplicate_sql_timings}}profiler-warning{{/if}}">
6
- {{if has_duplicate_sql_timings}}<span class="profiler-nuclear">!</span>{{/if}}
7
- <span class="profiler-number">
8
- ${MiniProfiler.formatDuration(duration_milliseconds)} <span class="profiler-unit">ms</span>
9
- </span>
10
- {{if MiniProfiler.showTotalSqlCount()}}
3
+ <div class="profiler-button {{? it.has_duplicate_sql_timings}}profiler-warning{{?}}">
4
+ {{? it.has_duplicate_sql_timings}}<span class="profiler-nuclear">!</span>{{?}}
11
5
  <span class="profiler-number">
12
- ${sql_count} <span class="profiler-unit">sql</span>
6
+ {{= MiniProfiler.formatDuration(it.duration_milliseconds)}} <span class="profiler-unit">ms</span>
13
7
  </span>
14
- {{/if}}
8
+ {{? MiniProfiler.showTotalSqlCount()}}
9
+ <span class="profiler-number">
10
+ {{= it.sql_count}} <span class="profiler-unit">sql</span>
11
+ </span>
12
+ {{?}}
15
13
  </div>
16
14
 
17
15
  <div class="profiler-popup">
18
16
  <div class="profiler-info">
19
17
  <span class="profiler-name">
20
- ${name} <span class="profiler-overall-duration">(${MiniProfiler.formatDuration(duration_milliseconds)} ms)</span>
18
+ {{= it.name}} <span class="profiler-overall-duration">({{= MiniProfiler.formatDuration(it.duration_milliseconds)}} ms)</span>
21
19
  </span>
22
- <span class="profiler-server-time">${machine_name} on ${MiniProfiler.renderDate(started)}</span>
20
+ <span class="profiler-server-time">{{= it.machine_name}} on {{= MiniProfiler.renderDate(it.started)}}</span>
23
21
  </div>
24
22
  <div class="profiler-output">
25
23
  <table class="profiler-timings">
@@ -29,200 +27,192 @@
29
27
  <th>duration (ms)</th>
30
28
  <th class="profiler-duration-with-children">with children (ms)</th>
31
29
  <th class="time-from-start">from start (ms)</th>
32
- {{if has_sql_timings}}
30
+ {{? it.has_sql_timings}}
33
31
  <th colspan="2">query time (ms)</th>
34
- {{/if}}
35
- {{each custom_timing_names}}
36
- <th colspan="2">${$value.toLowerCase()} (ms)</th>
37
- {{/each}}
32
+ {{?}}
33
+ {{~ it.custom_timing_names :value}}
34
+ <th colspan="2">{{= value.toLowerCase() }} (ms)</th>
35
+ {{~}}
38
36
  </tr>
39
37
  </thead>
40
38
  <tbody>
41
- {{tmpl({timing:root, page:this.data}) "#timingTemplate"}}
39
+ {{= MiniProfiler.templates.timingTemplate({timing: it.root, page: it}) }}
42
40
  </tbody>
43
41
  <tfoot>
44
42
  <tr>
45
43
  <td colspan="3">
46
- {{if !client_timings}}
47
- {{tmpl "#linksTemplate"}}
48
- {{/if}}
44
+ {{? !it.client_timings}}
45
+ {{= MiniProfiler.templates.linksTemplate({timing: it.root, page: it}) }}
46
+ {{?}}
49
47
  <a class="profiler-toggle-duration-with-children" title="toggles column with aggregate child durations">show time with children</a>
50
48
  </td>
51
- {{if has_sql_timings}}
52
- <td colspan="2" class="profiler-number profiler-percent-in-sql" title="${MiniProfiler.getSqlTimingsCount(root)} queries spent ${MiniProfiler.formatDuration(duration_milliseconds_in_sql)} ms of total request time">
53
- ${MiniProfiler.formatDuration(duration_milliseconds_in_sql / duration_milliseconds * 100)}
54
- <span class="profiler-unit">% in sql</span>
55
- </td>
56
- {{/if}}
57
- {{each custom_timing_names}}
58
- <td colspan="2" class="profiler-number profiler-percentage-in-sql" title="${custom_timing_stats[$value].count} ${$value.toLowerCase()} invocations spent ${MiniProfiler.formatDuration(custom_timing_stats[$value].duration)} ms of total request time">
59
- ${MiniProfiler.formatDuration(custom_timing_stats[$value].duration / duration_milliseconds * 100)}
60
- <span class="profiler-unit">% in ${$value.toLowerCase()}</span>
61
- </td>
62
- {{/each}}
49
+ {{? it.has_sql_timings}}
50
+ <td colspan="2" class="profiler-number profiler-percent-in-sql" title="{{= MiniProfiler.getSqlTimingsCount(it.root) }} queries spent {{= MiniProfiler.formatDuration(it.duration_milliseconds_in_sql) }} ms of total request time">
51
+ {{= MiniProfiler.formatDuration(it.duration_milliseconds_in_sql / it.duration_milliseconds * 100) }}
52
+ <span class="profiler-unit">% in sql</span>
53
+ </td>
54
+ {{?}}
55
+ {{~ it.custom_timing_names :value}}
56
+ <td colspan="2" class="profiler-number profiler-percentage-in-sql" title="{{= it.custom_timing_stats[value].count }} {{= value.toLowerCase() }} invocations spent {{= MiniProfiler.formatDuration(it.custom_timing_stats[value].duration) }} ms of total request time">
57
+ {{= MiniProfiler.formatDuration(it.custom_timing_stats[value].duration / duration_milliseconds * 100) }}
58
+ <span class="profiler-unit">% in {{= value.toLowerCase() }}</span>
59
+ </td>
60
+ {{~}}
63
61
  </tr>
64
62
  </tfoot>
65
63
  </table>
66
- {{if client_timings}}
67
- <table class="profiler-timings profiler-client-timings">
68
- <thead>
69
- <tr>
70
- <th>client event</th>
71
- <th>duration (ms)</th>
72
- <th>from start (ms)</th>
73
- </tr>
74
- </thead>
75
- <tbody>
76
- {{each MiniProfiler.getClientTimings(client_timings)}}
77
- <tr class="{{if $value.isTrivial }}profiler-trivial{{/if}}">
78
- <td class="profiler-label">${$value.name}</td>
79
- <td class="profiler-duration">
80
- {{if $value.duration >= 0}}
81
- <span class="profiler-unit"></span>${MiniProfiler.formatDuration($value.duration)}
82
- {{/if}}
83
- </td>
84
- <td class="profiler-duration time-from-start">
85
- <span class="profiler-unit">+</span>${MiniProfiler.formatDuration($value.start)}
64
+ {{? it.client_timings}}
65
+ <table class="profiler-timings profiler-client-timings">
66
+ <thead>
67
+ <tr>
68
+ <th>client event</th>
69
+ <th>duration (ms)</th>
70
+ <th>from start (ms)</th>
71
+ </tr>
72
+ </thead>
73
+ <tbody>
74
+ {{~ MiniProfiler.getClientTimings(it.client_timings) :value}}
75
+ <tr class="{{? value.isTrivial }}profiler-trivial{{?}}">
76
+ <td class="profiler-label">{{= value.name }}</td>
77
+ <td class="profiler-duration">
78
+ {{? value.duration >= 0}}
79
+ <span class="profiler-unit"></span>{{= MiniProfiler.formatDuration(value.duration) }}
80
+ {{?}}
81
+ </td>
82
+ <td class="profiler-duration time-from-start">
83
+ <span class="profiler-unit">+</span>{{= MiniProfiler.formatDuration(value.start) }}
84
+ </td>
85
+ </tr>
86
+ {{~}}
87
+ </tbody>
88
+ <tfoot>
89
+ <td colspan="3">
90
+ {{= MiniProfiler.templates.linksTemplate({timing: it.root, page: it}) }}
86
91
  </td>
87
- </tr>
88
- {{/each}}
89
- </tbody>
90
- <tfoot>
91
- <td colspan="3">
92
- {{tmpl "#linksTemplate"}}
93
- </td>
94
- </tfoot>
95
- </table>
96
- {{/if}}
92
+ </tfoot>
93
+ </table>
94
+ {{?}}
97
95
  </div>
98
96
  </div>
99
97
 
100
- {{if has_sql_timings}}
101
- <div class="profiler-queries">
102
- <table>
103
- <thead>
104
- <tr>
105
- <th style="text-align:right">step<br />time from start<br />query type<br />duration</th>
106
- <th style="text-align:left">call stack<br />query</th>
107
- </tr>
108
- </thead>
109
- <tbody>
110
- {{each(i, s) MiniProfiler.getSqlTimings(root)}}
111
- {{tmpl({ g:s.prevGap }) "#sqlGapTemplate"}}
112
- {{tmpl({ i:i, s:s }) "#sqlTimingTemplate"}}
113
- {{if s.nextGap}}
114
- {{tmpl({ g:s.nextGap }) "#sqlGapTemplate"}}
115
- {{/if}}
116
- {{/each}}
117
- </tbody>
118
- </table>
119
- <p class="profiler-trivial-gap-container">
120
- <a class="profiler-toggle-trivial-gaps" href="#">show trivial gaps</a>
121
- </p>
122
- </div>
123
- {{/if}}
124
-
98
+ {{? it.has_sql_timings}}
99
+ <div class="profiler-queries">
100
+ <table>
101
+ <thead>
102
+ <tr>
103
+ <th style="text-align:right">step<br />time from start<br />query type<br />duration</th>
104
+ <th style="text-align:left">call stack<br />query</th>
105
+ </tr>
106
+ </thead>
107
+ <tbody>
108
+ {{~ MiniProfiler.getSqlTimings(it.root) :value:index}}
109
+ {{= MiniProfiler.templates.sqlGapTemplate({g: value.prevGap}) }}
110
+ {{= MiniProfiler.templates.sqlTimingTemplate({i: index, s: value}) }}
111
+ {{? value.nextGap}}
112
+ {{= MiniProfiler.templates.sqlGapTemplate({g: value.nextGap}) }}
113
+ {{?}}
114
+ {{~}}
115
+ </tbody>
116
+ </table>
117
+ <p class="profiler-trivial-gap-container">
118
+ <a class="profiler-toggle-trivial-gaps">show trivial gaps</a>
119
+ </p>
120
+ </div>
121
+ {{?}}
125
122
  </div>
126
-
127
123
  </script>
128
124
 
129
- <script id="linksTemplate" type="text/x-jquery-tmpl">
130
- <a href="${MiniProfiler.shareUrl(id)}" class="profiler-share-profiler-results" target="_blank">share</a>
131
- <a href="${MiniProfiler.moreUrl()}" class="profiler-more-actions">more</a>
132
- {{if custom_link}}
133
- <a href="${custom_link}" class="profiler-custom-link" target="_blank">${custom_link_name}</a>
134
- {{/if}}
135
- {{if has_trivial_timings}}
136
- <a class="profiler-toggle-trivial" data-show-on-load="${has_all_trivial_timings}" title="toggles any rows with &lt; ${trivial_duration_threshold_milliseconds} ms">
137
- show trivial
138
- </a>
139
- {{/if}}
125
+ <script id="linksTemplate" type="text/x-dot-tmpl">
126
+ <a href="{{= MiniProfiler.shareUrl(it.page.id) }}" class="profiler-share-profiler-results" target="_blank">share</a>
127
+ <a href="{{= MiniProfiler.moreUrl(it.timing.name) }}" class="profiler-more-actions">more</a>
128
+ {{? it.custom_link}}
129
+ <a href="{{= it.custom_link }}" class="profiler-custom-link" target="_blank">{{= it.custom_link_name }}</a>
130
+ {{?}}
131
+ {{? it.has_trivial_timings}}
132
+ <a class="profiler-toggle-trivial" data-show-on-load="{{= it.has_all_trivial_timings }}" title="toggles any rows with &lt; {{= it.trivial_duration_threshold_milliseconds }} ms">
133
+ show trivial
134
+ </a>
135
+ {{?}}
140
136
  </script>
141
137
 
142
- <script id="timingTemplate" type="text/x-jquery-tmpl">
143
-
144
- <tr class="{{if timing.is_trivial }}profiler-trivial{{/if}}" data-timing-id="${timing.id}">
145
- <td class="profiler-label" title="{{if timing.name && timing.name.length > 45 }}${timing.name}{{/if}}">
146
- <span class="profiler-indent">${MiniProfiler.renderIndent(timing.depth)}</span> ${timing.name.slice(0,45)}{{if timing.name && timing.name.length > 45 }}...{{/if}}
138
+ <script id="timingTemplate" type="text/x-dot-tmpl">
139
+ <tr class="{{? it.timing.is_trivial }}profiler-trivial{{?}}" data-timing-id="{{= it.timing.id }}">
140
+ <td class="profiler-label" title="{{? it.timing.name && it.timing.name.length > 45 }}{{= it.timing.name }}{{?}}">
141
+ <span class="profiler-indent">{{= MiniProfiler.renderIndent(it.timing.depth) }}</span> {{= it.timing.name.slice(0,45) }}{{? it.timing.name && it.timing.name.length > 45 }}...{{?}}
147
142
  </td>
148
143
  <td class="profiler-duration" title="duration of this step without any children's durations">
149
- ${MiniProfiler.formatDuration(timing.duration_without_children_milliseconds)}
144
+ {{= MiniProfiler.formatDuration(it.timing.duration_without_children_milliseconds) }}
150
145
  </td>
151
146
  <td class="profiler-duration profiler-duration-with-children" title="duration of this step and its children">
152
- ${MiniProfiler.formatDuration(timing.duration_milliseconds)}
147
+ {{= MiniProfiler.formatDuration(it.timing.duration_milliseconds) }}
153
148
  </td>
154
149
  <td class="profiler-duration time-from-start" title="time elapsed since profiling started">
155
- <span class="profiler-unit">+</span>${MiniProfiler.formatDuration(timing.start_milliseconds)}
150
+ <span class="profiler-unit">+</span>{{= MiniProfiler.formatDuration(it.timing.start_milliseconds) }}
156
151
  </td>
157
152
 
158
- {{if timing.has_sql_timings}}
159
- <td class="profiler-duration {{if timing.has_duplicate_sql_timings}}profiler-warning{{/if}}" title="{{if timing.has_duplicate_sql_timings}}duplicate queries detected - {{/if}}{{if timing.executed_readers > 0 || timing.executed_scalars > 0 || timing.executed_non_queries > 0}}${timing.executed_readers} reader, ${timing.executed_scalars} scalar, ${timing.executed_non_queries} non-query statements executed{{/if}}">
153
+ {{? it.timing.has_sql_timings}}
154
+ <td class="profiler-duration {{? it.timing.has_duplicate_sql_timings}}profiler-warning{{?}}" title="{{? it.timing.has_duplicate_sql_timings}}duplicate queries detected - {{?}}{{? it.timing.executed_readers > 0 || it.timing.executed_scalars > 0 || it.timing.executed_non_queries > 0}}{{= it.timing.executed_readers }} reader, {{= it.timing.executed_scalars }} scalar, {{= it.timing.executed_non_queries }} non-query statements executed{{?}}">
160
155
  <a class="profiler-queries-show">
161
- {{if timing.has_duplicate_sql_timings}}<span class="profiler-nuclear">!</span>{{/if}}
162
- ${timing.sql_timings.length} <span class="profiler-unit">sql</span>
156
+ {{? it.timing.has_duplicate_sql_timings}}<span class="profiler-nuclear">!</span>{{?}}
157
+ {{= it.timing.sql_timings.length }} <span class="profiler-unit">sql</span>
163
158
  </a>
164
159
  </td>
165
160
  <td class="profiler-duration" title="aggregate duration of all queries in this step (excludes children)">
166
- ${MiniProfiler.formatDuration(timing.sql_timings_duration_milliseconds)}
161
+ {{= MiniProfiler.formatDuration(it.timing.sql_timings_duration_milliseconds) }}
167
162
  </td>
168
- {{else}}
163
+ {{??}}
169
164
  <td colspan="2"></td>
170
- {{/if}}
165
+ {{?}}
171
166
 
172
- {{each page.custom_timing_names}}
173
- {{if timing.custom_timings && timing.custom_timings[$value]}}
174
- <td class="profiler-duration" title="aggregate number of all ${$value.toLowerCase()} invocations in this step (excludes children)">
175
- ${timing.custom_timings[$value].length} ${$value.toLowerCase()}
167
+ {{~ it.page.custom_timing_names :value}}
168
+ {{? it.timing.custom_timings && it.timing.custom_timings[value]}}
169
+ <td class="profiler-duration" title="aggregate number of all {{= value.toLowerCase() }} invocations in this step (excludes children)">
170
+ {{= it.timing.custom_timings[value].length }} {{= value.toLowerCase() }}
176
171
  </td>
177
- <td class="profiler-duration" title="aggregate duration of all ${$value.toLowerCase()} invocations in this step (excludes children)">
178
- ${MiniProfiler.formatDuration(timing.custom_timing_stats[$value].duration)}
172
+ <td class="profiler-duration" title="aggregate duration of all {{= value.toLowerCase() }} invocations in this step (excludes children)">
173
+ {{= MiniProfiler.formatDuration(it.timing.custom_timing_stats[value].duration) }}
179
174
  </td>
180
- {{else}}
175
+ {{??}}
181
176
  <td colspan="2"></td>
182
- {{/if}}
183
- {{/each}}
177
+ {{?}}
178
+ {{~}}
184
179
 
185
180
  </tr>
186
181
 
187
- {{if timing.has_children}}
188
- {{each timing.children}}
189
- {{tmpl({timing: $value, page: page}) "#timingTemplate"}}
190
- {{/each}}
191
- {{/if}}
192
-
182
+ {{? it.timing.has_children}}
183
+ {{~ it.timing.children :value}}
184
+ {{= MiniProfiler.templates.timingTemplate({timing: value, page: it}) }}
185
+ {{~}}
186
+ {{?}}
193
187
  </script>
194
188
 
195
- <script id="sqlTimingTemplate" type="text/x-jquery-tmpl">
196
-
197
- <tr class="${s.row_class}" data-timing-id="${s.parent_timing_id}">
189
+ <script id="sqlTimingTemplate" type="text/x-dot-tmpl">
190
+ <tr class="{{= it.s.row_class || '' }}" data-timing-id="{{= it.s.parent_timing_id }}">
198
191
  <td class="profiler-info">
199
- <div>${s.parent_timing_name}</div>
200
- <div class="profiler-number"><span class="profiler-unit">T+</span>${MiniProfiler.formatDuration(s.start_milliseconds)} <span class="profiler-unit">ms</span></div>
192
+ <div>{{= it.s.parent_timing_name }}</div>
193
+ <div class="profiler-number"><span class="profiler-unit">T+</span>{{= MiniProfiler.formatDuration(it.s.start_milliseconds) }} <span class="profiler-unit">ms</span></div>
201
194
  <div>
202
- {{if s.is_duplicate}}<span class="profiler-warning">DUPLICATE</span>{{/if}}
203
- ${MiniProfiler.renderExecuteType(s.execute_type)}
195
+ {{? it.s.is_duplicate}}<span class="profiler-warning">DUPLICATE</span>{{?}}
196
+ {{= MiniProfiler.renderExecuteType(it.s.execute_type) }}
204
197
  </div>
205
- <div title="{{if s.execute_type == 3}}first result fetched: ${s.first_fetch_duration_milliseconds}ms{{/if}}">${MiniProfiler.formatDuration(s.duration_milliseconds)} <span class="profiler-unit">ms</span></div>
198
+ <div title="{{? it.s.execute_type == 3}}first result fetched: {{= it.s.first_fetch_duration_milliseconds }}ms{{?}}">{{= MiniProfiler.formatDuration(it.s.duration_milliseconds) }} <span class="profiler-unit">ms</span></div>
206
199
  </td>
207
200
  <td>
208
201
  <div class="query">
209
- <pre class="profiler-stack-trace">${s.stack_trace_snippet}</pre>
210
- <pre class="prettyprint lang-sql"><code>${s.formatted_command_string}; ${MiniProfiler.formatParameters(s.parameters)}</code></pre>
202
+ <pre class="profiler-stack-trace">{{= it.s.stack_trace_snippet }}</pre>
203
+ <pre class="prettyprint lang-sql"><code>{{= it.s.formatted_command_string }}; {{= MiniProfiler.formatParameters(it.s.parameters) }}</code></pre>
211
204
  </div>
212
205
  </td>
213
206
  </tr>
214
-
215
207
  </script>
216
208
 
217
- <script id="sqlGapTemplate" type="text/x-jquery-tmpl">
218
-
219
- <tr class="profiler-gap-info{{if g.duration < 4}} profiler-trivial-gaps{{/if}}">
209
+ <script id="sqlGapTemplate" type="text/x-dot-tmpl">
210
+ <tr class="profiler-gap-info{{? it.g.duration < 4}} profiler-trivial-gaps{{?}}">
220
211
  <td class="profiler-info">
221
- ${g.duration} <span class="profiler-unit">ms</span>
212
+ {{= it.g.duration }} <span class="profiler-unit">ms</span>
222
213
  </td>
223
214
  <td class="query">
224
- <div>${g.topReason.name} &mdash; ${g.topReason.duration.toFixed(2)} <span class="profiler-unit">ms</span></div>
215
+ <div>{{= it.g.topReason.name }} &mdash; {{= it.g.topReason.duration.toFixed(2) }} <span class="profiler-unit">ms</span></div>
225
216
  </td>
226
217
  </tr>
227
-
228
218
  </script>
@@ -1,7 +1,6 @@
1
1
  <html>
2
2
  <head>
3
3
  <title><%= name %> (<%= duration %> ms) - Profiling Results</title>
4
- <script type='text/javascript' src='<%= path %>jquery.1.7.1.js?v=<%= version %>'></script>
5
4
  <script type='text/javascript'> var profiler = <%= json %>; </script>
6
5
  <%= includes %>
7
6
  </head>
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  module Rack
2
3
  class MiniProfiler
3
- ASSET_VERSION = '355f78011d9b95de14a5b1014b088681'.freeze
4
+ ASSET_VERSION = '0ade3000608cde95db93022b6576d63a'
4
5
  end
5
- end
6
+ end
@@ -34,9 +34,9 @@ module Rack
34
34
  end
35
35
  end
36
36
  @enabled = true
37
- @disable_env_dump = false
38
37
  @max_sql_param_length = 0 # disable sql parameter collection by default
39
38
  @skip_sql_param_names = /password/ # skips parameters with the name password by default
39
+ @enable_advanced_debugging_tools = false
40
40
 
41
41
  # ui parameters
42
42
  @autorized = true
@@ -47,7 +47,7 @@ module Rack
47
47
  @show_trivial = false
48
48
  @show_total_sql_count = false
49
49
  @start_hidden = false
50
- @toggle_shortcut = 'Alt+P'
50
+ @toggle_shortcut = 'alt+p'
51
51
  @html_container = 'body'
52
52
  @position = "top-left"
53
53
 
@@ -57,10 +57,10 @@ module Rack
57
57
 
58
58
  attr_accessor :authorization_mode, :auto_inject, :backtrace_ignores,
59
59
  :backtrace_includes, :backtrace_remove, :backtrace_threshold_ms,
60
- :base_url_path, :disable_caching, :disable_env_dump, :enabled,
60
+ :base_url_path, :disable_caching, :enabled,
61
61
  :flamegraph_sample_rate, :logger, :pre_authorize_cb, :skip_paths,
62
62
  :skip_schema_queries, :storage, :storage_failure, :storage_instance,
63
- :storage_options, :user_provider
63
+ :storage_options, :user_provider, :enable_advanced_debugging_tools
64
64
  attr_accessor :skip_sql_param_names, :suppress_encoding, :max_sql_param_length
65
65
 
66
66
  # ui accessors
@@ -62,6 +62,11 @@ module Rack
62
62
  Thread.current[:mp_authorized]
63
63
  end
64
64
 
65
+ def advanced_tools_message
66
+ <<~TEXT
67
+ This feature is disabled by default, to enable set the enable_advanced_debugging_tools option to true in Mini Profiler config.
68
+ TEXT
69
+ end
65
70
  end
66
71
 
67
72
  #
@@ -71,7 +76,7 @@ module Rack
71
76
  MiniProfiler.config.merge!(config)
72
77
  @config = MiniProfiler.config
73
78
  @app = app
74
- @config.base_url_path << "/" unless @config.base_url_path.end_with? "/"
79
+ @config.base_url_path += "/" unless @config.base_url_path.end_with? "/"
75
80
  unless @config.storage_instance
76
81
  @config.storage_instance = @config.storage.new(@config.storage_options)
77
82
  end
@@ -84,11 +89,11 @@ module Rack
84
89
 
85
90
  def serve_results(env)
86
91
  request = Rack::Request.new(env)
87
- id = request[:id]
92
+ id = request.params['id']
88
93
  page_struct = @storage.load(id)
89
94
  unless page_struct
90
95
  @storage.set_viewed(user(env), id)
91
- id = ERB::Util.html_escape(request['id'])
96
+ id = ERB::Util.html_escape(request.params['id'])
92
97
  user_info = ERB::Util.html_escape(user(env))
93
98
  return [404, {}, ["Request not found: #{id} - user #{user_info}"]]
94
99
  end
@@ -147,6 +152,14 @@ module Rack
147
152
  @config
148
153
  end
149
154
 
155
+ def advanced_debugging_enabled?
156
+ config.enable_advanced_debugging_tools
157
+ end
158
+
159
+ def tool_disabled_message(client_settings)
160
+ client_settings.handle_cookie(text_result(Rack::MiniProfiler.advanced_tools_message))
161
+ end
162
+
150
163
  def call(env)
151
164
 
152
165
  start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
@@ -195,12 +208,14 @@ module Rack
195
208
 
196
209
  # profile gc
197
210
  if query_string =~ /pp=profile-gc/
211
+ return tool_disabled_message(client_settings) if !advanced_debugging_enabled?
198
212
  current.measure = false if current
199
213
  return client_settings.handle_cookie(Rack::MiniProfiler::GCProfiler.new.profile_gc(@app, env))
200
214
  end
201
215
 
202
216
  # profile memory
203
217
  if query_string =~ /pp=profile-memory/
218
+ return tool_disabled_message(client_settings) if !advanced_debugging_enabled?
204
219
  query_params = Rack::Utils.parse_nested_query(query_string)
205
220
  options = {
206
221
  ignore_files: query_params['memory_profiler_ignore_files'],
@@ -307,12 +322,14 @@ module Rack
307
322
  return client_settings.handle_cookie(dump_exceptions exceptions)
308
323
  end
309
324
 
310
- if query_string =~ /pp=env/ && !config.disable_env_dump
325
+ if query_string =~ /pp=env/
326
+ return tool_disabled_message(client_settings) if !advanced_debugging_enabled?
311
327
  body.close if body.respond_to? :close
312
328
  return client_settings.handle_cookie(dump_env env)
313
329
  end
314
330
 
315
331
  if query_string =~ /pp=analyze-memory/
332
+ return tool_disabled_message(client_settings) if !advanced_debugging_enabled?
316
333
  body.close if body.respond_to? :close
317
334
  return client_settings.handle_cookie(analyze_memory)
318
335
  end
@@ -331,6 +348,17 @@ module Rack
331
348
  return client_settings.handle_cookie(self.flamegraph(flamegraph))
332
349
  end
333
350
 
351
+ if path == '/rack-mini-profiler/requests'
352
+ blank_page_html = <<~HTML
353
+ <html>
354
+ <head></head>
355
+ <body></body>
356
+ </html>
357
+ HTML
358
+
359
+ status, headers, body = [200, { 'Content-Type' => 'text/html' }, [blank_page_html.dup]]
360
+ end
361
+
334
362
  begin
335
363
  @storage.save(page_struct)
336
364
  # no matter what it is, it should be unviewed, otherwise we will miss POST
@@ -369,7 +397,7 @@ module Rack
369
397
 
370
398
  # inject header
371
399
  if headers.is_a? Hash
372
- headers['X-MiniProfiler-Ids'] = ids_json(env)
400
+ headers['X-MiniProfiler-Ids'] = ids_comma_separated(env)
373
401
  end
374
402
 
375
403
  if current.inject_js && content_type =~ /text\/html/
@@ -528,7 +556,7 @@ module Rack
528
556
 
529
557
  def make_link(postfix, env)
530
558
  link = env["PATH_INFO"] + "?" + env["QUERY_STRING"].sub("pp=help", "pp=#{postfix}")
531
- "pp=<a href='#{link}'>#{postfix}</a>"
559
+ "pp=<a href='#{ERB::Util.html_escape(link)}'>#{postfix}</a>"
532
560
  end
533
561
 
534
562
  def help(client_settings, env)
@@ -574,10 +602,6 @@ Append the following to your query string:
574
602
  all
575
603
  end
576
604
 
577
- def ids_json(env)
578
- ::JSON.generate(ids(env))
579
- end
580
-
581
605
  def ids_comma_separated(env)
582
606
  ids(env).join(",")
583
607
  end