/
actions.rb
157 lines (141 loc) · 5.43 KB
/
actions.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# frozen_string_literal: true
module Rack
class MiniProfiler
module Actions
def serve_snapshot(env)
MiniProfiler.authorize_request
status = 200
headers = { 'Content-Type' => 'text/html' }
qp = Rack::Utils.parse_nested_query(env['QUERY_STRING'])
if group_name = qp["group_name"]
list = @storage.snapshots_group(group_name)
list.each do |snapshot|
snapshot[:url] = url_for_snapshot(snapshot[:id], group_name)
end
data = {
group_name: group_name,
list: list
}
else
list = @storage.snapshots_overview
list.each do |group|
group[:url] = url_for_snapshots_group(group[:name])
end
data = {
page: "overview",
list: list
}
end
data_html = <<~HTML
<div style="display: none;" id="snapshots-data">
#{data.to_json}
</div>
HTML
response = Rack::Response.new([], status, headers)
response.write <<~HTML
<!DOCTYPE html>
<html>
<head>
<title>Rack::MiniProfiler Snapshots</title>
</head>
<body class="mp-snapshots">
HTML
response.write(data_html)
script = self.get_profile_script(env)
response.write(script)
response.write <<~HTML
</body>
</html>
HTML
response.finish
end
def serve_file(env, file_name:)
resources_env = env.dup
resources_env['PATH_INFO'] = file_name
if Gem::Version.new(Rack.release) >= Gem::Version.new("2.1.0")
rack_file = Rack::Files.new(resources_root, 'Cache-Control' => "max-age=#{cache_control_value}")
else
rack_file = Rack::File.new(resources_root, 'Cache-Control' => "max-age=#{cache_control_value}")
end
rack_file.call(resources_env)
end
def serve_results(env)
request = Rack::Request.new(env)
id = request.params['id']
group_name = request.params['group']
is_snapshot = group_name && group_name.size > 0
if is_snapshot
page_struct = @storage.load_snapshot(id, group_name)
else
page_struct = @storage.load(id)
end
if !page_struct && is_snapshot
id = ERB::Util.html_escape(id)
return [404, {}, ["Snapshot with id '#{id}' not found"]]
elsif !page_struct
@storage.set_viewed(user(env), id)
id = ERB::Util.html_escape(id)
user_info = ERB::Util.html_escape(user(env))
return [404, {}, ["Request not found: #{id} - user #{user_info}"]]
end
if !page_struct[:has_user_viewed] && !is_snapshot
page_struct[:client_timings] = TimerStruct::Client.init_from_form_data(env, page_struct)
page_struct[:has_user_viewed] = true
@storage.save(page_struct)
@storage.set_viewed(user(env), id)
end
# If we're an XMLHttpRequest, serve up the contents as JSON
if request.xhr?
result_json = page_struct.to_json
[200, { 'Content-Type' => 'application/json' }, [result_json]]
else
# Otherwise give the HTML back
html = generate_html(page_struct, env)
[200, { 'Content-Type' => 'text/html' }, [html]]
end
end
def serve_flamegraph(env)
request = Rack::Request.new(env)
id = request.params['id']
page_struct = @storage.load(id)
if !page_struct
id = ERB::Util.html_escape(id)
user_info = ERB::Util.html_escape(user(env))
return [404, {}, ["Request not found: #{id} - user #{user_info}"]]
end
if !page_struct[:flamegraph]
return [404, {}, ["No flamegraph available for #{ERB::Util.html_escape(id)}"]]
end
self.flamegraph(page_struct[:flamegraph], page_struct[:request_path], env)
end
def serve_profile_gc(env, client_settings)
return tool_disabled_message(client_settings) if !advanced_debugging_enabled?
client_settings.handle_cookie(Rack::MiniProfiler::GCProfiler.new.profile_gc(@app, env))
end
def serve_profile_memory(env, client_settings)
return tool_disabled_message(client_settings) if !advanced_debugging_enabled?
unless defined?(MemoryProfiler) && MemoryProfiler.respond_to?(:report)
message = "Please install the memory_profiler gem and require it: add gem 'memory_profiler' to your Gemfile"
status, headers, body = @app.call(env)
body.close if body.respond_to? :close
return client_settings.handle_cookie(
text_result(message, status: 500, headers: headers)
)
end
query_params = Rack::Utils.parse_nested_query(env['QUERY_STRING'])
options = {
ignore_files: query_params['memory_profiler_ignore_files'],
allow_files: query_params['memory_profiler_allow_files'],
}
options[:top] = Integer(query_params['memory_profiler_top']) if query_params.key?('memory_profiler_top')
result = StringIO.new
report = MemoryProfiler.report(options) do
_, _, body = @app.call(env)
body.close if body.respond_to? :close
end
report.pretty_print(result)
client_settings.handle_cookie(text_result(result.string))
end
end
end
end