httplog 1.4.3 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
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.