rails-profiler 0.9.1 → 0.10.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3979c04655c3ab2204af54f67c500176ad26fd5224656fe82cf815f13190bca8
4
- data.tar.gz: e6de19b5d127577c9921559b682d1f5f49daeb7c2fb0dcbfe2a6877aad579dfb
3
+ metadata.gz: b6d4b62a0b2dafdfc36928cd302f7babff3dabe36c1bdfba68c5694acae2fed3
4
+ data.tar.gz: 0fc45e2e2f0e9bdbaa005b18b9d89f2dfc99462724351951e6ecdebc3043c496
5
5
  SHA512:
6
- metadata.gz: 913739ef55cf291e47ea2dd1bd7fe764518d19a297c070e545dd212b647a9a90145427e1e215b6cea44688cb42f94307aedd74be47af434702c18a09dbd3ce82
7
- data.tar.gz: 57b500b690441ce98c5b29f064c57882eeab685a79c1278857b4899c4fd498a03fde64a63bb421d3361ce8dc3bd3d6acd0aa0b6fa132225e9e77167c60d5e44b
6
+ metadata.gz: e027318a52c3ba6ef6803571b18f276174a7f86e6cd07726f0b687b42b1f759fc474a7db88bb0f689e02a6b02cecc5ebeee6a0b18966de56ab5507b78ca5a321
7
+ data.tar.gz: 48479831a40187a451f558cae42a2b73e6e89b286d0416713dda886ba64e90ea04ce464919c2df357f1fa6feef1d9972606e887cae3b0b9defa49949b44ef628
@@ -7,9 +7,11 @@ module Profiler
7
7
  :track_memory, :memory_warning_threshold,
8
8
  :mcp_enabled, :mcp_transport, :mcp_port,
9
9
  :authorization_mode, :max_profiles, :extension_cors_enabled,
10
+ :cors_allowed_origins,
10
11
  :track_ajax, :ajax_skip_paths,
11
12
  :track_http, :slow_http_threshold, :http_skip_hosts,
12
- :track_jobs
13
+ :track_jobs,
14
+ :compress_bodies, :compress_body_threshold
13
15
 
14
16
  attr_reader :authorize_block
15
17
 
@@ -30,12 +32,15 @@ module Profiler
30
32
  @authorize_block = nil
31
33
  @max_profiles = 100
32
34
  @extension_cors_enabled = true
35
+ @cors_allowed_origins = ["*"]
33
36
  @track_ajax = true
34
37
  @ajax_skip_paths = [/^\/_profiler/]
35
38
  @track_http = true
36
39
  @slow_http_threshold = 500 # milliseconds
37
40
  @http_skip_hosts = []
38
41
  @track_jobs = true
42
+ @compress_bodies = true
43
+ @compress_body_threshold = 10 * 1024 # 10 KB
39
44
  end
40
45
 
41
46
  def authorize_with(&block)
@@ -14,7 +14,7 @@ module Profiler
14
14
  if env['REQUEST_METHOD'] == 'OPTIONS'
15
15
  return [
16
16
  200,
17
- cors_headers,
17
+ cors_headers(env),
18
18
  ['']
19
19
  ]
20
20
  end
@@ -22,7 +22,7 @@ module Profiler
22
22
  status, headers, body = @app.call(env)
23
23
 
24
24
  # Add CORS headers
25
- cors_headers.each do |key, value|
25
+ cors_headers(env).each do |key, value|
26
26
  headers[key] = value
27
27
  end
28
28
 
@@ -42,13 +42,28 @@ module Profiler
42
42
 
43
43
  private
44
44
 
45
- def cors_headers
46
- {
47
- 'Access-Control-Allow-Origin' => '*',
45
+ def cors_headers(env)
46
+ allowed_origins = Profiler.configuration.cors_allowed_origins
47
+ request_origin = env['HTTP_ORIGIN']
48
+
49
+ if allowed_origins.include?('*')
50
+ origin_header = '*'
51
+ elsif request_origin && allowed_origins.include?(request_origin)
52
+ origin_header = request_origin
53
+ end
54
+
55
+ headers = {
48
56
  'Access-Control-Allow-Methods' => 'GET, POST, OPTIONS',
49
57
  'Access-Control-Allow-Headers' => 'Content-Type, X-Requested-With, Accept',
50
58
  'Access-Control-Expose-Headers' => 'X-Profiler-Token'
51
59
  }
60
+
61
+ if origin_header
62
+ headers['Access-Control-Allow-Origin'] = origin_header
63
+ headers['Vary'] = 'Origin' unless origin_header == '*'
64
+ end
65
+
66
+ headers
52
67
  end
53
68
  end
54
69
  end
@@ -70,7 +70,8 @@ module Profiler
70
70
 
71
71
  # Inject toolbar if HTML response
72
72
  if html_response?(headers)
73
- body = ToolbarInjector.new(body, profile.token).inject
73
+ nonce = env['action_dispatch.content_security_policy_nonce']
74
+ body = ToolbarInjector.new(body, profile.token, nonce).inject
74
75
  end
75
76
 
76
77
  [status, headers, body]
@@ -5,9 +5,10 @@ module Profiler
5
5
  class ToolbarInjector
6
6
  CLOSING_BODY_TAG = "</body>"
7
7
 
8
- def initialize(body, token)
8
+ def initialize(body, token, nonce = nil)
9
9
  @body = body
10
10
  @token = token
11
+ @nonce = nonce
11
12
  end
12
13
 
13
14
  def inject
@@ -26,10 +27,10 @@ module Profiler
26
27
  return "" unless Profiler.configuration.track_ajax
27
28
 
28
29
  <<~HTML
29
- <script>
30
+ <script#{nonce_attr}>
30
31
  window.__PROFILER_PARENT_TOKEN__ = '#{@token}';
31
32
  </script>
32
- <script>
33
+ <script#{nonce_attr}>
33
34
  #{ajax_interceptor_code}
34
35
  </script>
35
36
  HTML
@@ -62,11 +63,15 @@ module Profiler
62
63
  <<~HTML
63
64
  #{ajax_interceptor_script}
64
65
  <div id="profiler-toolbar" data-token="#{@token}"></div>
65
- <script src="/_profiler/assets/profiler-toolbar.js" defer></script>
66
+ <script src="/_profiler/assets/profiler-toolbar.js" defer#{nonce_attr}></script>
66
67
  <style>#{toolbar_styles}</style>
67
68
  HTML
68
69
  end
69
70
 
71
+ def nonce_attr
72
+ @nonce ? " nonce=\"#{@nonce}\"" : ""
73
+ end
74
+
70
75
  # Thermal design system — self-contained CSS for the injected toolbar.
71
76
  # Variables are defined on #profiler-toolbar to avoid polluting the host app.
72
77
  def toolbar_styles
@@ -3,6 +3,7 @@
3
3
  require "base64"
4
4
  require "securerandom"
5
5
  require "json"
6
+ require "zlib"
6
7
 
7
8
  module Profiler
8
9
  module Models
@@ -159,10 +160,19 @@ module Profiler
159
160
  { body: Base64.strict_encode64(truncated), encoding: "base64" }
160
161
  else
161
162
  text = raw.encode("UTF-8", invalid: :replace, undef: :replace)[0, TEXT_BODY_LIMIT]
162
- { body: text, encoding: "text" }
163
+ if compress_body?(text)
164
+ { body: Base64.strict_encode64(Zlib::Deflate.deflate(text)), encoding: "gzip+base64" }
165
+ else
166
+ { body: text, encoding: "text" }
167
+ end
163
168
  end
164
169
  end
165
170
 
171
+ def compress_body?(text)
172
+ Profiler.configuration.compress_bodies &&
173
+ text.bytesize > Profiler.configuration.compress_body_threshold
174
+ end
175
+
166
176
  def binary_content_type?(ct)
167
177
  ct.to_s.match?(%r{image/(?!svg)|application/(?:pdf|octet-stream|zip)|audio/|video/})
168
178
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Profiler
4
- VERSION = "0.9.1"
4
+ VERSION = "0.10.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sébastien Duplessy