rails-profiler 0.19.1 → 0.19.2

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: 713e1b01bcd916191e3ae2b89124f4637eeb95d7b9837d350d2ee76a575a2f14
4
- data.tar.gz: 9f1becf53b9b39145a4ebdf81981793aeb5f0494cce1e6872facdcf11c0a597a
3
+ metadata.gz: 8c4382b8c5ad1cd162614ae7eaf1ca940f979c86c8daf511a72a697d9336817e
4
+ data.tar.gz: 88e34726b5a3944a12656aab0259f71534b5b085bb6afd7e1dd06857bd8b081b
5
5
  SHA512:
6
- metadata.gz: 298e772fd273b734126c095e57186e36d7f6fbaf26c7bb7db9899d02a38431231e4ecbde42f0b1a103deac26c29f48a596a065b5dd93f16a900b24d66e69a280
7
- data.tar.gz: 78f23d51a52d0467e3acf9d912cbcbeebec03cf245632d88c7306d00d7c00645dda2be0a6208f3e58f4c815ea3a9efe0cb4e6783a3c6c4be44b784fd72e35f37
6
+ metadata.gz: '0378c6853fd21cbf6ca6c7f999c6cff53b2896e03422f326350fac13b8c83f66e4e72bdbf9602b3c84b50ec93f8cec5b2bcbbe9491257c1d4619095a98a17dbd'
7
+ data.tar.gz: a3f70d63f227306d3f01138bbbd3131fc2862f9545b73221f366d580e6c0bd0c809a0258372474fc92dd1b0e2e5e880b1ecd9e765332cff89f09a5aa60a118e8
@@ -25,6 +25,24 @@ module Profiler
25
25
  # Fallback: body may be passed as the 2nd argument and only applied
26
26
  # to req inside super via req.set_body_internal(body)
27
27
  req_body = body.to_s if req_body.empty? && body
28
+ # Fallback: libraries like RestClient set body_stream instead of body
29
+ # and pass nil as the 2nd argument to Net::HTTP#request.
30
+ # Read the stream content, then restore it so the actual request works.
31
+ # RestClient::Payload doesn't implement #rewind, so we fall back to
32
+ # replacing body_stream with a fresh StringIO.
33
+ if req_body.empty? && req.body_stream
34
+ begin
35
+ stream = req.body_stream
36
+ req_body = stream.read.to_s
37
+ if stream.respond_to?(:rewind)
38
+ stream.rewind
39
+ else
40
+ req.body_stream = StringIO.new(req_body)
41
+ end
42
+ rescue
43
+ req_body = ""
44
+ end
45
+ end
28
46
  req_headers = req.to_hash.transform_values { |v| v.join(", ") }
29
47
  request_id = SecureRandom.hex(8)
30
48
  started_at = Time.now.iso8601(3)
@@ -105,9 +123,6 @@ module Profiler
105
123
 
106
124
  SKIP_HOSTS = %w[127.0.0.1 localhost ::1].freeze
107
125
 
108
- TEXT_BODY_LIMIT = 512 * 1024 # 512 KB
109
- BINARY_BODY_LIMIT = 256 * 1024 # 256 KB (before base64)
110
-
111
126
  TEXT_CONTENT_TYPES = /\A(text\/|application\/(json|xml|xhtml|javascript|x-www-form-urlencoded)|image\/svg)/i
112
127
  BINARY_CONTENT_TYPES = /\A(image\/|application\/pdf|application\/octet-stream|application\/zip|audio\/|video\/)/i
113
128
 
@@ -143,12 +158,10 @@ module Profiler
143
158
  mime = content_type.split(";").first.to_s.strip
144
159
 
145
160
  if mime.match?(BINARY_CONTENT_TYPES)
146
- truncated = body.byteslice(0, BINARY_BODY_LIMIT) || ""
147
- { body: Base64.strict_encode64(truncated.b), encoding: "base64" }
161
+ { body: Base64.strict_encode64(body.b), encoding: "base64" }
148
162
  else
149
- # Text (including unknown content types)
150
163
  text = body.encode("UTF-8", invalid: :replace, undef: :replace, replace: "?")
151
- { body: text.byteslice(0, TEXT_BODY_LIMIT), encoding: "text" }
164
+ { body: text, encoding: "text" }
152
165
  end
153
166
  end
154
167
 
@@ -60,7 +60,7 @@ module Profiler
60
60
  lines += section_views(profile) if want.("views")
61
61
  lines += section_cache(profile) if want.("cache")
62
62
  lines += section_ajax(profile) if want.("ajax")
63
- lines += section_http(profile) if want.("http")
63
+ lines += section_http(profile, params) if want.("http")
64
64
  lines += section_routes(profile) if want.("routes")
65
65
  lines += section_dumps(profile) if want.("dumps")
66
66
  lines += section_related_jobs(profile) if want.("related_jobs")
@@ -325,7 +325,7 @@ module Profiler
325
325
  lines
326
326
  end
327
327
 
328
- def self.section_http(profile)
328
+ def self.section_http(profile, params = {})
329
329
  lines = []
330
330
  http_data = profile.collector_data("http")
331
331
  return lines unless http_data && http_data["total_requests"].to_i > 0
@@ -339,10 +339,39 @@ module Profiler
339
339
 
340
340
  if http_data["requests"] && !http_data["requests"].empty?
341
341
  lines << "### Request List"
342
- http_data["requests"].each do |req|
342
+ http_data["requests"].each_with_index do |req, index|
343
343
  flag = req["duration"] >= threshold ? " [SLOW]" : ""
344
344
  err = req["status"] >= 400 || req["status"] == 0 ? " [ERROR]" : ""
345
- lines << "- **#{req['method']} #{req['url']}** — #{req['status'] == 0 ? 'error' : req['status']} — #{req['duration'].round(2)} ms#{flag}#{err}"
345
+ lines << "\n**#{index + 1}. #{req['method']} #{req['url']}** — #{req['status'] == 0 ? 'error' : req['status']} — #{req['duration'].round(2)} ms#{flag}#{err}"
346
+
347
+ if req["request_body"] && !req["request_body"].empty?
348
+ lines << "**Request Body:**"
349
+ formatted = BodyFormatter.format_body(
350
+ profile.token,
351
+ "http_#{index}_request_body",
352
+ req["request_body"],
353
+ req["request_body_encoding"],
354
+ params
355
+ )
356
+ lines << formatted if formatted
357
+ end
358
+
359
+ if req["response_body"] && !req["response_body"].empty?
360
+ lines << "**Response Body:**"
361
+ formatted = BodyFormatter.format_body(
362
+ profile.token,
363
+ "http_#{index}_response_body",
364
+ req["response_body"],
365
+ req["response_body_encoding"],
366
+ params
367
+ )
368
+ lines << formatted if formatted
369
+ end
370
+
371
+ if req["backtrace"] && !req["backtrace"].empty?
372
+ lines << "_Backtrace:_"
373
+ req["backtrace"].each { |frame| lines << " #{frame}" }
374
+ end
346
375
  end
347
376
  lines << ""
348
377
  end
@@ -32,9 +32,6 @@ module Profiler
32
32
  end
33
33
  end
34
34
 
35
- TEXT_BODY_LIMIT = 512 * 1024
36
- BINARY_BODY_LIMIT = 256 * 1024
37
-
38
35
  def set_bodies(request_body:, response_body:, req_content_type:, resp_content_type:)
39
36
  req = process_body(request_body, req_content_type)
40
37
  resp = process_body(response_body, resp_content_type)
@@ -159,10 +156,9 @@ module Profiler
159
156
  return { body: nil, encoding: "text" } if raw.nil? || raw.empty?
160
157
 
161
158
  if binary_content_type?(content_type)
162
- truncated = raw.b[0, BINARY_BODY_LIMIT]
163
- { body: Base64.strict_encode64(truncated), encoding: "base64" }
159
+ { body: Base64.strict_encode64(raw.b), encoding: "base64" }
164
160
  else
165
- text = raw.encode("UTF-8", invalid: :replace, undef: :replace)[0, TEXT_BODY_LIMIT]
161
+ text = raw.encode("UTF-8", invalid: :replace, undef: :replace)
166
162
  if compress_body?(text)
167
163
  { body: Base64.strict_encode64(Zlib::Deflate.deflate(text)), encoding: "gzip+base64" }
168
164
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Profiler
4
- VERSION = "0.19.1"
4
+ VERSION = "0.19.2"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails-profiler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.1
4
+ version: 0.19.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sébastien Duplessy
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-04-17 00:00:00.000000000 Z
11
+ date: 2026-04-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails