httplog 1.4.3 → 1.6.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: 9ce910d7c04847c28f836de26906c0c50aa4642b553b298d15067bf6ee25db56
4
- data.tar.gz: 8600e756f28e033b6e39ac91235f69bf772fe467b05040d88c02ce54e982ef0b
3
+ metadata.gz: b45410a66dcec431137326ea3402d5f7aa46aec70ad5bd826dc3fe24021c4dfe
4
+ data.tar.gz: a7fb94896bd9456ca53f83c78a9b0ed025e9dffd537bf531b56350488334ee1f
5
5
  SHA512:
6
- metadata.gz: 6a76055079c7bfa4a229fda0861f90276c94cb64859ae7ce3c269e86656f3ad69fb3d5e8ed7eb2b82e9fe1facb0a73619951f099aafbbac7b0b503a52eb21046
7
- data.tar.gz: f541eec119d175cc50563bc2673d60dae6246a43bcf570f9fe4db9a6295697ea94f7ffddb709aa8c9d0264f274f48c42bca3322d3364c1edd47298a984421363
6
+ metadata.gz: 4abf19d31bcf87d0f4f5cdf4eab1eee36f1974581310077be364a3a89d9f5dae956b7cd5fa021b2711606ac6657ce904a293119a3da8738d95e45d52fc98d50b
7
+ data.tar.gz: 567406b24ed46bf14bec3960ad246c8ca866f9f96160fcb3578c99969548d2720a5dde179eb69ac129c787cd9121839560914900bd9eef7f68986cd545c93438
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## 1.5.0 - 2021-05-20
2
+
3
+ * Support for Ruby 2.7 and frozen strings
4
+ * Development dependency updates
5
+ * Dropped support for net/http v3
6
+ * Performance tweaks
7
+ * Fix for RestClient body read issue (WARNING: this may be reverted, see [#105](https://github.com/trusche/httplog/issues/105))
8
+
1
9
  ## 1.4.3 - 2020-06-10
2
10
 
3
11
  * Masking `password` parameter by default... doh.
data/README.md CHANGED
@@ -1,18 +1,15 @@
1
1
  ## httplog
2
2
 
3
- **VERSION 1.4.0 and 1.4.1 HAVE BEEN YANKED** from rubygems.org due to [this issue](https://github.com/trusche/httplog/issues/89), please update to version 1.4.2 or higher. Sorry about that...
4
-
5
- [![Gem Version](https://badge.fury.io/rb/httplog.svg)](http://badge.fury.io/rb/httplog) [![Build Status](https://travis-ci.org/trusche/httplog.svg?branch=master)](https://travis-ci.org/trusche/httplog) [![Code Climate](https://codeclimate.com/github/trusche/httplog.svg)](https://codeclimate.com/github/trusche/httplog)
3
+ [![Gem Version](https://badge.fury.io/rb/httplog.svg)](http://badge.fury.io/rb/httplog) [![Build Status](https://travis-ci.com/trusche/httplog.svg?branch=master)](https://travis-ci.org/trusche/httplog) [![Code Climate](https://codeclimate.com/github/trusche/httplog.svg)](https://codeclimate.com/github/trusche/httplog)
6
4
  [![Release Version](https://img.shields.io/github/release/trusche/httplog.svg)](https://img.shields.io/github/release/trusche/httplog.svg)
7
- <a href="https://www.bearer.sh?ref=httplog"><img src="/bearer-badge.png" height="20px"/></a>
8
5
 
9
6
  Log outgoing HTTP requests made from your application. Helps with debugging pesky API error responses, or just generally understanding what's going on under the hood.
10
7
 
11
- Requires ruby >= 2.5
8
+ Requires ruby >= 2.6
12
9
 
13
10
  This gem works with the following ruby modules and libraries:
14
11
 
15
- * [Net::HTTP](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/index.html)
12
+ * [Net::HTTP](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/index.html) v4+
16
13
  * [Ethon](https://github.com/typhoeus/ethon)
17
14
  * [Excon](https://github.com/geemus/excon)
18
15
  * [OpenURI](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/open-uri/rdoc/index.html)
@@ -32,10 +29,6 @@ This is very much a development and debugging tool; it is **not recommended** to
32
29
  use this in a production environment as it is monkey-patching the respective HTTP implementations.
33
30
  You have been warned - use at your own risk.
34
31
 
35
- Httplog is kindly sponsored by <a href="https://www.bearer.sh?ref=httplog">Bearer.sh</a> - go check them out please!
36
-
37
- <a href="https://www.bearer.sh?ref=httplog"><img src="/bearer-sponsor.png" height="72px" /></a>
38
-
39
32
  ### Installation
40
33
 
41
34
  gem install httplog
@@ -103,6 +96,9 @@ HttpLog.configure do |config|
103
96
 
104
97
  # Mask the values of sensitive request parameters
105
98
  config.filter_parameters = %w[password]
99
+
100
+ # Customize the prefix with a proc or lambda
101
+ config.prefix = ->{ "[httplog] #{Time.now} " }
106
102
  end
107
103
  ```
108
104
 
@@ -267,9 +263,6 @@ a suggestion for a fix, please open an issue or, even better, submit a pull requ
267
263
 
268
264
  * Benchmarking only covers the time between starting the HTTP request and receiving the response. It does *not* cover the time it takes to establish the TCP connection.
269
265
 
270
- * When using [REST Client](https://github.com/rest-client/rest-client), POST requests might be missing the requests
271
- data. See #54 for details.
272
-
273
266
  ### Running the specs
274
267
 
275
268
  Make sure you have the necessary dependencies installed by running `bundle install`.
data/httplog.gemspec CHANGED
@@ -22,23 +22,25 @@ Gem::Specification.new do |gem|
22
22
  gem.test_files = `git ls-files -- test/*`.split("\n")
23
23
  gem.require_paths = ['lib']
24
24
 
25
- gem.required_ruby_version = '>= 2.2'
25
+ gem.required_ruby_version = '>= 2.6'
26
26
 
27
27
  gem.add_development_dependency 'ethon', ['~> 0.11']
28
28
  gem.add_development_dependency 'excon', ['~> 0.60']
29
- gem.add_development_dependency 'faraday', ['~> 0.14']
29
+ gem.add_development_dependency 'faraday', ['~> 1.3']
30
30
  gem.add_development_dependency 'guard-rspec', ['~> 4.7']
31
31
  gem.add_development_dependency 'http', ['~> 4.0']
32
32
  gem.add_development_dependency 'httparty', ['~> 0.16']
33
33
  gem.add_development_dependency 'httpclient', ['~> 2.8']
34
+ gem.add_development_dependency 'rest-client', ['~> 2.0']
35
+ gem.add_development_dependency 'typhoeus', ['~> 1.4']
34
36
  gem.add_development_dependency 'listen', ['~> 3.0']
35
37
  gem.add_development_dependency 'patron', ['~> 0.12']
36
- gem.add_development_dependency 'rake', ['~> 12.3']
38
+ gem.add_development_dependency 'rake', ['~> 13.0']
37
39
  gem.add_development_dependency 'rspec', ['~> 3.7']
38
40
  gem.add_development_dependency 'simplecov', ['~> 0.15']
39
41
  gem.add_development_dependency 'thin', ['~> 1.7']
40
42
  gem.add_development_dependency 'oj', ['>= 3.9.2']
41
43
 
42
- gem.add_dependency 'rack', ['>= 1.0']
44
+ gem.add_dependency 'rack', ['>= 2.0']
43
45
  gem.add_dependency 'rainbow', ['>= 2.0.0']
44
46
  end
@@ -8,7 +8,7 @@ if defined?(Ethon)
8
8
  module Http
9
9
  alias orig_http_request http_request
10
10
  def http_request(url, action_name, options = {})
11
- @http_log = options.merge(method: action_name) # remember this for compact logging
11
+ @http_log = options.merge(method: action_name, url: url) # remember this for compact logging
12
12
  orig_http_request(url, action_name, options)
13
13
  end
14
14
  end
@@ -18,32 +18,50 @@ if defined?(Ethon)
18
18
  def perform
19
19
  return orig_perform unless HttpLog.url_approved?(url)
20
20
 
21
- bm = Benchmark.realtime { orig_perform }
21
+ httplog_add_callback
22
22
 
23
- # Not sure where the actual status code is stored - so let's
24
- # extract it from the response header.
25
- encoding = response_headers.scan(/Content-Encoding: (\S+)/).flatten.first
26
- content_type = response_headers.scan(/Content-Type: (\S+(; charset=\S+)?)/).flatten.first
23
+ bm = Benchmark.realtime { orig_perform }
27
24
 
28
- # Hard to believe that Ethon wouldn't parse out the headers into
29
- # an array; probably overlooked it. Anyway, let's do it ourselves:
30
- headers = response_headers.split(/\r?\n/).drop(1)
25
+ url = @http_log[:url]
26
+ url = "#{url}?#{@http_log[:params]}" if @http_log[:params]
31
27
 
32
28
  HttpLog.call(
33
29
  method: @http_log[:method],
34
- url: @url,
30
+ url: url,
35
31
  request_body: @http_log[:body],
36
32
  request_headers: @http_log[:headers],
37
33
  response_code: @return_code,
38
- response_body: response_body,
39
- response_headers: headers.map { |header| header.split(/:\s/) }.to_h,
34
+ response_body: @http_log[:response_body],
35
+ response_headers: @http_log[:response_headers].map { |header| header.split(/:\s/) }.to_h,
40
36
  benchmark: bm,
41
- encoding: encoding,
42
- content_type: content_type,
43
- mask_body: HttpLog.masked_body_url?(url)
37
+ encoding: @http_log[:encoding],
38
+ content_type: @http_log[:content_type],
39
+ mask_body: HttpLog.masked_body_url?(@http_log[:url])
44
40
  )
45
41
  return_code
46
42
  end
43
+
44
+ def httplog_add_callback
45
+ # Hack to perform this callback before the cleanup
46
+ @on_complete ||= []
47
+ @on_complete.unshift -> (*) do
48
+ # Not sure where the actual status code is stored - so let's
49
+ # extract it from the response header.
50
+ encoding = response_headers.scan(/Content-Encoding: (\S+)/).flatten.first
51
+ content_type = response_headers.scan(/Content-Type: (\S+(; charset=\S+)?)/).flatten.first
52
+
53
+ # Hard to believe that Ethon wouldn't parse out the headers into
54
+ # an array; probably overlooked it. Anyway, let's do it ourselves:
55
+ headers = response_headers.split(/\r?\n/).drop(1)
56
+
57
+ @http_log.merge!(
58
+ encoding: encoding,
59
+ content_type: content_type,
60
+ response_headers: headers,
61
+ response_body: response_body
62
+ )
63
+ end
64
+ end
47
65
  end
48
66
  end
49
67
  end
@@ -11,12 +11,22 @@ module Net
11
11
  bm = Benchmark.realtime do
12
12
  @response = orig_request(req, body, &block)
13
13
  end
14
+ body_stream = req.body_stream
15
+ request_body = if body_stream
16
+ body_stream.to_s # read and rewind for RestClient::Payload::Base
17
+ body_stream.rewind if body_stream.respond_to?(:rewind) # RestClient::Payload::Base has no method rewind
18
+ body_stream.read
19
+ elsif req.body.nil? || req.body.empty?
20
+ body
21
+ else
22
+ req.body
23
+ end
14
24
 
15
25
  if HttpLog.url_approved?(url) && started?
16
26
  HttpLog.call(
17
27
  method: req.method,
18
28
  url: url,
19
- request_body: req.body.nil? || req.body.empty? ? body : req.body,
29
+ request_body: request_body,
20
30
  request_headers: req.each_header.collect,
21
31
  response_code: @response.code,
22
32
  response_body: @response.body,
@@ -50,7 +50,7 @@ module HttpLog
50
50
  @prefix_data_lines = false
51
51
  @prefix_response_lines = false
52
52
  @prefix_line_numbers = false
53
- @json_parser = JSON
53
+ @json_parser = nil
54
54
  @filter_parameters = %w[password]
55
55
  end
56
56
  end
@@ -26,6 +26,7 @@ module HttpLog
26
26
 
27
27
  def configure
28
28
  yield(configuration)
29
+ configuration.json_parser ||= ::JSON if configuration.json_log || configuration.url_masked_body_pattern
29
30
  end
30
31
 
31
32
  def call(options = {})
@@ -121,22 +122,24 @@ module HttpLog
121
122
  raise BodyParsingError, '(not available yet)'
122
123
  end
123
124
 
124
- body = body.to_s if defined?(HTTP::Response::Body) && body.is_a?(HTTP::Response::Body)
125
- body = body.dup
125
+ body_copy = body.dup
126
+ body_copy = body.to_s if defined?(HTTP::Response::Body) && body.is_a?(HTTP::Response::Body)
127
+ return nil if body_copy.nil? || body_copy.empty?
126
128
 
127
- if encoding =~ /gzip/ && body && !body.empty?
129
+
130
+ if encoding =~ /gzip/
128
131
  begin
129
- sio = StringIO.new(body.to_s)
132
+ sio = StringIO.new(body_copy.to_s)
130
133
  gz = Zlib::GzipReader.new(sio)
131
- body = gz.read
134
+ body_copy = gz.read
132
135
  rescue Zlib::GzipFile::Error
133
136
  log("(gzip decompression failed)")
134
137
  end
135
138
  end
136
139
 
137
- result = utf_encoded(body.to_s, content_type)
140
+ result = utf_encoded(body_copy.to_s, content_type)
138
141
 
139
- if mask_body && body && !body.empty?
142
+ if mask_body
140
143
  if content_type =~ /json/
141
144
  result = begin
142
145
  masked_data config.json_parser.load(result)
@@ -259,12 +262,14 @@ module HttpLog
259
262
  # in its entirety.
260
263
  return (config.filter_parameters.include?(key.downcase) ? PARAM_MASK : msg) if key
261
264
 
262
- # Otherwise, we'll parse Strings for key=valye pairs...
265
+ # Otherwise, we'll parse Strings for key=value pairs,
266
+ # for name="key"\n value...
263
267
  case msg
264
268
  when *string_classes
265
269
  config.filter_parameters.reduce(msg) do |m,key|
266
270
  scrubbed = m.to_s.encode('UTF-8', invalid: :replace, undef: :replace)
267
- scrubbed.gsub(/(#{key})=[^&]+/i, "#{key}=#{PARAM_MASK}")
271
+ scrubbed.to_s.gsub(/(#{key})=[^&]+/i, "#{key}=#{PARAM_MASK}")
272
+ .gsub(/name="#{key}"\s+\K[\s\w]+/, "#{PARAM_MASK}\r\n") # multi-part Faraday
268
273
  end
269
274
  # ...and recurse over hashes
270
275
  when *hash_classes
@@ -345,7 +350,7 @@ module HttpLog
345
350
  end
346
351
 
347
352
  def log_data_lines(data)
348
- data.each_line.with_index do |line, row|
353
+ data.to_s.each_line.with_index do |line, row|
349
354
  if config.prefix_line_numbers
350
355
  log("#{row + 1}: #{line.chomp}")
351
356
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module HttpLog
4
- VERSION = '1.4.3'.freeze
4
+ VERSION = '1.6.0'.freeze
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httplog
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.3
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thilo Rusche
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-11 00:00:00.000000000 Z
11
+ date: 2022-09-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ethon
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0.14'
47
+ version: '1.3'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0.14'
54
+ version: '1.3'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: guard-rspec
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +108,34 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '2.8'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rest-client
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '2.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '2.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: typhoeus
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '1.4'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '1.4'
111
139
  - !ruby/object:Gem::Dependency
112
140
  name: listen
113
141
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +170,14 @@ dependencies:
142
170
  requirements:
143
171
  - - "~>"
144
172
  - !ruby/object:Gem::Version
145
- version: '12.3'
173
+ version: '13.0'
146
174
  type: :development
147
175
  prerelease: false
148
176
  version_requirements: !ruby/object:Gem::Requirement
149
177
  requirements:
150
178
  - - "~>"
151
179
  - !ruby/object:Gem::Version
152
- version: '12.3'
180
+ version: '13.0'
153
181
  - !ruby/object:Gem::Dependency
154
182
  name: rspec
155
183
  requirement: !ruby/object:Gem::Requirement
@@ -212,14 +240,14 @@ dependencies:
212
240
  requirements:
213
241
  - - ">="
214
242
  - !ruby/object:Gem::Version
215
- version: '1.0'
243
+ version: '2.0'
216
244
  type: :runtime
217
245
  prerelease: false
218
246
  version_requirements: !ruby/object:Gem::Requirement
219
247
  requirements:
220
248
  - - ">="
221
249
  - !ruby/object:Gem::Version
222
- version: '1.0'
250
+ version: '2.0'
223
251
  - !ruby/object:Gem::Dependency
224
252
  name: rainbow
225
253
  requirement: !ruby/object:Gem::Requirement
@@ -267,14 +295,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
267
295
  requirements:
268
296
  - - ">="
269
297
  - !ruby/object:Gem::Version
270
- version: '2.2'
298
+ version: '2.6'
271
299
  required_rubygems_version: !ruby/object:Gem::Requirement
272
300
  requirements:
273
301
  - - ">="
274
302
  - !ruby/object:Gem::Version
275
303
  version: '0'
276
304
  requirements: []
277
- rubygems_version: 3.0.3
305
+ rubygems_version: 3.3.7
278
306
  signing_key:
279
307
  specification_version: 4
280
308
  summary: Log outgoing HTTP requests.