httplog 1.3.1 → 1.5.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 +4 -4
- data/CHANGELOG.md +32 -0
- data/README.md +53 -22
- data/httplog.gemspec +7 -4
- data/lib/httplog/adapters/ethon.rb +2 -1
- data/lib/httplog/adapters/excon.rb +2 -1
- data/lib/httplog/adapters/http.rb +5 -3
- data/lib/httplog/adapters/httpclient.rb +6 -4
- data/lib/httplog/adapters/net_http.rb +13 -2
- data/lib/httplog/adapters/patron.rb +2 -1
- data/lib/httplog/configuration.rb +27 -21
- data/lib/httplog/http_log.rb +138 -49
- data/lib/httplog/version.rb +1 -1
- metadata +37 -51
- data/.gitignore +0 -7
- data/.rspec +0 -2
- data/.rubocop.yml +0 -55
- data/.rubocop_todo.yml +0 -36
- data/.ruby-version +0 -1
- data/.travis.yml +0 -17
- data/Gemfile +0 -4
- data/Gemfile.lock +0 -130
- data/Guardfile +0 -25
- data/MIT-LICENSE +0 -20
- data/Rakefile +0 -46
- data/gemfiles/http3.gemfile +0 -7
- data/gemfiles/http4.gemfile +0 -7
- data/gemfiles/http5.gemfile +0 -7
- data/gemfiles/rack1.gemfile +0 -7
- data/gemfiles/rack2.gemfile +0 -7
- data/spec/adapters/ethon_adapter.rb +0 -26
- data/spec/adapters/excon_adapter.rb +0 -16
- data/spec/adapters/faraday_adapter.rb +0 -59
- data/spec/adapters/http_adapter.rb +0 -27
- data/spec/adapters/http_base_adapter.rb +0 -39
- data/spec/adapters/httparty_adapter.rb +0 -16
- data/spec/adapters/httpclient_adapter.rb +0 -31
- data/spec/adapters/net_http_adapter.rb +0 -21
- data/spec/adapters/open_uri_adapter.rb +0 -19
- data/spec/adapters/patron_adapter.rb +0 -36
- data/spec/adapters/typhoeus_adapter.rb +0 -28
- data/spec/configuration_spec.rb +0 -22
- data/spec/lib/http_client_spec.rb +0 -15
- data/spec/lib/http_log_spec.rb +0 -320
- data/spec/log/.gitkeep +0 -0
- data/spec/spec_helper.rb +0 -45
- data/spec/support/index.html +0 -8
- data/spec/support/index.html.gz +0 -0
- data/spec/support/log4r.yml +0 -17
- data/spec/support/not_gzipped.html.gz +0 -8
- data/spec/support/shared_examples.rb +0 -79
- data/spec/support/test.bin +0 -0
- data/spec/support/test.pdf +0 -198
- data/spec/support/test_server.rb +0 -34
- data/spec/support/utf8-invalid.html +0 -0
- data/spec/support/utf8.html +0 -8
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'excon'
|
4
|
-
class TyphoeusAdapter < HTTPBaseAdapter
|
5
|
-
def send_get_request
|
6
|
-
Typhoeus.get(parse_uri(true).to_s, headers: @headers)
|
7
|
-
end
|
8
|
-
|
9
|
-
def send_head_request
|
10
|
-
Typhoeus.head(parse_uri.to_s, headers: @headers)
|
11
|
-
end
|
12
|
-
|
13
|
-
def send_post_request
|
14
|
-
Typhoeus.post(parse_uri.to_s, body: @data, headers: @headers)
|
15
|
-
end
|
16
|
-
|
17
|
-
def send_post_form_request
|
18
|
-
Typhoeus.post(parse_uri.to_s, body: @params, headers: @headers)
|
19
|
-
end
|
20
|
-
|
21
|
-
def send_multipart_post_request
|
22
|
-
send_post_form_request
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.is_libcurl?
|
26
|
-
true
|
27
|
-
end
|
28
|
-
end
|
data/spec/configuration_spec.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
module HttpLog
|
6
|
-
describe Configuration do
|
7
|
-
let(:config) { Configuration.new }
|
8
|
-
|
9
|
-
describe '#compact_log' do
|
10
|
-
it 'defaults to false' do
|
11
|
-
expect(config.compact_log).to eq(false)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe '#compact_log=' do
|
16
|
-
it 'sets values' do
|
17
|
-
config.compact_log = true
|
18
|
-
expect(config.compact_log).to eq(true)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe HTTPClient do
|
6
|
-
let(:client) { HTTPClient.new }
|
7
|
-
|
8
|
-
it 'works with transparent_gzip_decompression' do
|
9
|
-
client.transparent_gzip_decompression = true
|
10
|
-
expect { client.get("http://localhost:9292/index.html.gz") }.to_not(raise_error)
|
11
|
-
expect(log).to include(HttpLog::LOG_PREFIX + 'Status: 200')
|
12
|
-
expect(log).to include(HttpLog::LOG_PREFIX + 'Data:')
|
13
|
-
expect(log).to include(HttpLog::LOG_PREFIX + "Response:\n<html>")
|
14
|
-
end
|
15
|
-
end
|
data/spec/lib/http_log_spec.rb
DELETED
@@ -1,320 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
|
5
|
-
describe HttpLog do
|
6
|
-
subject { log } # see spec_helper
|
7
|
-
|
8
|
-
let(:secret) { 'my secret' }
|
9
|
-
let(:host) { 'localhost' }
|
10
|
-
let(:port) { 9292 }
|
11
|
-
let(:path) { '/index.html' }
|
12
|
-
let(:headers) { { 'accept' => '*/*', 'foo' => secret } }
|
13
|
-
let(:data) { "foo=#{secret}&bar=foo" }
|
14
|
-
let(:params) { { 'foo' => secret, 'bar' => 'foo:form-data' } }
|
15
|
-
let(:html) { File.read('./spec/support/index.html') }
|
16
|
-
let(:json) { JSON.parse(log.match(/\[httplog\]\s(.*)/).captures.first) }
|
17
|
-
|
18
|
-
# Default configuration
|
19
|
-
let(:enabled) { HttpLog.configuration.enabled }
|
20
|
-
let(:severity) { HttpLog.configuration.severity }
|
21
|
-
let(:log_headers) { HttpLog.configuration.log_headers }
|
22
|
-
let(:log_request) { HttpLog.configuration.log_request }
|
23
|
-
let(:log_response) { HttpLog.configuration.log_response }
|
24
|
-
let(:log_data) { HttpLog.configuration.log_data }
|
25
|
-
let(:log_connect) { HttpLog.configuration.log_connect }
|
26
|
-
let(:log_benchmark) { HttpLog.configuration.log_benchmark }
|
27
|
-
let(:color) { HttpLog.configuration.color }
|
28
|
-
let(:prefix) { HttpLog.configuration.prefix }
|
29
|
-
let(:prefix_response_lines) { HttpLog.configuration.prefix_response_lines }
|
30
|
-
let(:prefix_line_numbers) { HttpLog.configuration.prefix_line_numbers }
|
31
|
-
let(:json_log) { HttpLog.configuration.json_log }
|
32
|
-
let(:compact_log) { HttpLog.configuration.compact_log }
|
33
|
-
let(:url_blacklist_pattern) { HttpLog.configuration.url_blacklist_pattern }
|
34
|
-
let(:url_whitelist_pattern) { HttpLog.configuration.url_whitelist_pattern }
|
35
|
-
let(:filter_parameters) { HttpLog.configuration.filter_parameters }
|
36
|
-
|
37
|
-
def configure
|
38
|
-
HttpLog.configure do |c|
|
39
|
-
c.enabled = enabled
|
40
|
-
c.severity = severity
|
41
|
-
c.log_headers = log_headers
|
42
|
-
c.log_request = log_request
|
43
|
-
c.log_response = log_response
|
44
|
-
c.log_data = log_data
|
45
|
-
c.log_connect = log_connect
|
46
|
-
c.log_benchmark = log_benchmark
|
47
|
-
c.color = color
|
48
|
-
c.prefix = prefix
|
49
|
-
c.prefix_response_lines = prefix_response_lines
|
50
|
-
c.prefix_line_numbers = prefix_line_numbers
|
51
|
-
c.json_log = json_log
|
52
|
-
c.compact_log = compact_log
|
53
|
-
c.url_blacklist_pattern = url_blacklist_pattern
|
54
|
-
c.url_whitelist_pattern = url_whitelist_pattern
|
55
|
-
c.filter_parameters = filter_parameters
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
ADAPTERS = [
|
60
|
-
NetHTTPAdapter,
|
61
|
-
OpenUriAdapter,
|
62
|
-
HTTPClientAdapter,
|
63
|
-
HTTPartyAdapter,
|
64
|
-
FaradayAdapter,
|
65
|
-
ExconAdapter,
|
66
|
-
EthonAdapter,
|
67
|
-
PatronAdapter,
|
68
|
-
HTTPAdapter
|
69
|
-
].freeze
|
70
|
-
|
71
|
-
ADAPTERS.each do |adapter_class|
|
72
|
-
context adapter_class, adapter: adapter_class.to_s do
|
73
|
-
let(:adapter) { adapter_class.new(host: host, port: port, path: path, headers: headers, data: data, params: params) }
|
74
|
-
before { configure }
|
75
|
-
|
76
|
-
context 'with default configuration' do
|
77
|
-
describe 'GET requests' do
|
78
|
-
let!(:res) { adapter.send_get_request }
|
79
|
-
|
80
|
-
it_behaves_like 'logs request', 'GET'
|
81
|
-
it_behaves_like 'logs data'
|
82
|
-
it_behaves_like 'logs expected response'
|
83
|
-
it_behaves_like 'logs status', 200
|
84
|
-
it_behaves_like 'logs benchmark'
|
85
|
-
|
86
|
-
it { is_expected.to_not include('Header:') }
|
87
|
-
it { is_expected.to_not include("\e[0") }
|
88
|
-
|
89
|
-
unless adapter_class.is_libcurl?
|
90
|
-
it { is_expected.to include("Connecting: #{host}:#{port}") }
|
91
|
-
end
|
92
|
-
|
93
|
-
it { expect(res).to be_a adapter.response if adapter.respond_to? :response }
|
94
|
-
|
95
|
-
context 'with gzip encoding' do
|
96
|
-
let(:path) { '/index.html.gz' }
|
97
|
-
let(:data) { nil }
|
98
|
-
|
99
|
-
it_behaves_like 'logs expected response'
|
100
|
-
|
101
|
-
if adapter_class.method_defined? :send_head_request
|
102
|
-
it "doesn't try to decompress body for HEAD requests" do
|
103
|
-
expect(log).to include('Response:')
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
context 'with UTF-8 response body' do
|
109
|
-
let(:path) { '/utf8.html' }
|
110
|
-
let(:data) { nil }
|
111
|
-
|
112
|
-
it_behaves_like 'logs expected response'
|
113
|
-
it { is_expected.to include(' <title>Блог Яндекса</title>') if adapter.logs_data? }
|
114
|
-
end
|
115
|
-
|
116
|
-
context 'with binary response body' do
|
117
|
-
%w[/test.bin /test.pdf].each do |response_file_name|
|
118
|
-
let(:path) { response_file_name }
|
119
|
-
let(:data) { nil }
|
120
|
-
|
121
|
-
it { is_expected.to include('Response: (not showing binary data)') }
|
122
|
-
|
123
|
-
context 'and JSON logging' do
|
124
|
-
let(:json_log) { true }
|
125
|
-
it { expect(json['response_body']).to eq '(not showing binary data)' }
|
126
|
-
end
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
describe 'POST requests' do
|
132
|
-
if adapter_class.method_defined? :send_post_request
|
133
|
-
let!(:res) { adapter.send_post_request }
|
134
|
-
|
135
|
-
unless adapter_class.is_libcurl?
|
136
|
-
it { is_expected.to include("Connecting: #{host}:#{port}") }
|
137
|
-
end
|
138
|
-
|
139
|
-
it_behaves_like 'logs request', 'POST'
|
140
|
-
it_behaves_like 'logs expected response'
|
141
|
-
it_behaves_like 'logs data'
|
142
|
-
it_behaves_like 'logs status', 200
|
143
|
-
it_behaves_like 'logs benchmark'
|
144
|
-
|
145
|
-
it { is_expected.to_not include('Header:') }
|
146
|
-
|
147
|
-
it { expect(res).to be_a adapter.response if adapter.respond_to? :response }
|
148
|
-
|
149
|
-
context 'with non-UTF request data' do
|
150
|
-
let(:data) { "a UTF-8 striñg with an 8BIT-ASCII character: \xC3" }
|
151
|
-
it_behaves_like 'logs expected response' # == doesn't throw exception
|
152
|
-
end
|
153
|
-
|
154
|
-
context 'with URI encoded non-UTF data' do
|
155
|
-
let(:data) { 'a UTF-8 striñg with a URI encoded 8BIT-ASCII character: %c3' }
|
156
|
-
it_behaves_like 'logs expected response' # == doesn't throw exception
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
context 'with custom configuration' do
|
163
|
-
context 'GET requests' do
|
164
|
-
before { adapter.send_get_request }
|
165
|
-
|
166
|
-
context 'when disabled' do
|
167
|
-
let(:enabled) { false }
|
168
|
-
it_behaves_like 'logs nothing'
|
169
|
-
end
|
170
|
-
|
171
|
-
context 'with different log level' do
|
172
|
-
let(:severity) { Logger::Severity::INFO }
|
173
|
-
it { is_expected.to include('INFO') }
|
174
|
-
end
|
175
|
-
|
176
|
-
context 'with headers logging' do
|
177
|
-
let(:log_headers) { true }
|
178
|
-
it { is_expected.to match(%r{Header: accept: */*}i) } # request
|
179
|
-
it { is_expected.to match(/Header: Server: thin/i) } # response
|
180
|
-
it_behaves_like 'filtered parameters'
|
181
|
-
end
|
182
|
-
|
183
|
-
context 'with blacklist hit' do
|
184
|
-
let(:url_blacklist_pattern) { /#{host}:#{port}/ }
|
185
|
-
it_behaves_like 'logs nothing'
|
186
|
-
end
|
187
|
-
|
188
|
-
context 'with blacklist miss' do
|
189
|
-
let(:url_blacklist_pattern) { /example.com/ }
|
190
|
-
it_behaves_like 'logs request', 'GET'
|
191
|
-
end
|
192
|
-
|
193
|
-
context 'with whitelist hit' do
|
194
|
-
let(:url_whitelist_pattern) { /#{host}:#{port}/ }
|
195
|
-
it_behaves_like 'logs request', 'GET'
|
196
|
-
|
197
|
-
context 'and blacklist hit' do
|
198
|
-
let(:url_blacklist_pattern) { /#{host}:#{port}/ }
|
199
|
-
it_behaves_like 'logs nothing'
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
context 'with whitelist miss' do
|
204
|
-
let(:url_whitelist_pattern) { /example.com/ }
|
205
|
-
it_behaves_like 'logs nothing'
|
206
|
-
end
|
207
|
-
|
208
|
-
it_behaves_like 'with request logging disabled'
|
209
|
-
it_behaves_like 'with connection logging disabled'
|
210
|
-
it_behaves_like 'data logging disabled'
|
211
|
-
it_behaves_like 'response logging disabled'
|
212
|
-
it_behaves_like 'benchmark logging disabled'
|
213
|
-
it_behaves_like 'filtered parameters'
|
214
|
-
|
215
|
-
context 'with single color' do
|
216
|
-
let(:color) { :red }
|
217
|
-
it { is_expected.to include("\e[31m") }
|
218
|
-
end
|
219
|
-
|
220
|
-
context 'with color hash' do
|
221
|
-
let(:color) { { color: :black, background: :yellow } }
|
222
|
-
it { is_expected.to include("\e[30m\e[43m") }
|
223
|
-
end
|
224
|
-
|
225
|
-
context 'with custom prefix' do
|
226
|
-
let(:prefix) { '[my logger]' }
|
227
|
-
it { is_expected.to include('[my logger]') }
|
228
|
-
it { is_expected.to_not include(HttpLog::LOG_PREFIX) }
|
229
|
-
end
|
230
|
-
|
231
|
-
context 'with custom lambda prefix' do
|
232
|
-
let(:prefix) { -> { '[custom prefix]' } }
|
233
|
-
it { is_expected.to include('[custom prefix]') }
|
234
|
-
it { is_expected.to_not include(HttpLog::LOG_PREFIX) }
|
235
|
-
end
|
236
|
-
|
237
|
-
context 'with compact config' do
|
238
|
-
let(:compact_log) { true }
|
239
|
-
it { is_expected.to match(%r{\[httplog\] GET http://#{host}:#{port}#{path}(\?.*)? completed with status code \d{3} in \d+\.\d{1,6} }) }
|
240
|
-
it { is_expected.to_not include("Connecting: #{host}:#{port}") }
|
241
|
-
it { is_expected.to_not include('Response:') }
|
242
|
-
it { is_expected.to_not include('Data:') }
|
243
|
-
it { is_expected.to_not include('Benchmark: ') }
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
context 'POST requests' do
|
248
|
-
if adapter_class.method_defined? :send_post_request
|
249
|
-
before { adapter.send_post_request }
|
250
|
-
|
251
|
-
it_behaves_like 'data logging disabled'
|
252
|
-
it_behaves_like 'response logging disabled'
|
253
|
-
it_behaves_like 'benchmark logging disabled'
|
254
|
-
it_behaves_like 'with prefix response lines'
|
255
|
-
it_behaves_like 'with line numbers'
|
256
|
-
it_behaves_like 'filtered parameters'
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
context 'POST form data requests' do
|
261
|
-
if adapter_class.method_defined? :send_post_form_request
|
262
|
-
before { adapter.send_post_form_request }
|
263
|
-
|
264
|
-
it_behaves_like 'data logging disabled'
|
265
|
-
it_behaves_like 'response logging disabled'
|
266
|
-
it_behaves_like 'benchmark logging disabled'
|
267
|
-
it_behaves_like 'with prefix response lines'
|
268
|
-
it_behaves_like 'with line numbers'
|
269
|
-
it_behaves_like 'filtered parameters'
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
context 'POST multi-part requests (file upload)' do
|
274
|
-
let(:upload) { Tempfile.new('http-log') }
|
275
|
-
let(:params) { { 'foo' => secret, 'file' => upload } }
|
276
|
-
|
277
|
-
if adapter_class.method_defined? :send_multipart_post_request
|
278
|
-
before { adapter.send_multipart_post_request }
|
279
|
-
|
280
|
-
it_behaves_like 'data logging disabled'
|
281
|
-
it_behaves_like 'response logging disabled'
|
282
|
-
it_behaves_like 'benchmark logging disabled'
|
283
|
-
it_behaves_like 'with prefix response lines'
|
284
|
-
it_behaves_like 'with line numbers'
|
285
|
-
it_behaves_like 'filtered parameters'
|
286
|
-
end
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
context 'with JSON config' do
|
291
|
-
let(:json_log) { true }
|
292
|
-
|
293
|
-
if adapter_class.method_defined? :send_post_request
|
294
|
-
before { adapter.send_post_request }
|
295
|
-
|
296
|
-
it { expect(json['method']).to eq('POST') }
|
297
|
-
it { expect(json['request_body']).to eq(data) }
|
298
|
-
it { expect(json['request_headers']).to be_a(Hash) }
|
299
|
-
it { expect(json['response_headers']).to be_a(Hash) }
|
300
|
-
it { expect(json['response_code']).to eq(200) }
|
301
|
-
it { expect(json['response_body']).to eq(html) }
|
302
|
-
it { expect(json['benchmark']).to be_a(Numeric) }
|
303
|
-
it_behaves_like 'filtered parameters'
|
304
|
-
|
305
|
-
context 'and compact config' do
|
306
|
-
let(:compact_log) { true }
|
307
|
-
|
308
|
-
it { expect(json['method']).to eq('POST') }
|
309
|
-
it { expect(json['request_body']).to be_nil }
|
310
|
-
it { expect(json['request_headers']).to be_nil }
|
311
|
-
it { expect(json['response_headers']).to be_nil }
|
312
|
-
it { expect(json['response_code']).to eq(200) }
|
313
|
-
it { expect(json['response_body']).to be_nil }
|
314
|
-
it { expect(json['benchmark']).to be_a(Numeric) }
|
315
|
-
end
|
316
|
-
end
|
317
|
-
end
|
318
|
-
end
|
319
|
-
end
|
320
|
-
end
|
data/spec/log/.gitkeep
DELETED
File without changes
|
data/spec/spec_helper.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
4
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
5
|
-
require 'rspec'
|
6
|
-
require 'httpclient'
|
7
|
-
require 'excon'
|
8
|
-
# require 'typhoeus'
|
9
|
-
require 'ethon'
|
10
|
-
require 'patron'
|
11
|
-
require 'http'
|
12
|
-
require 'simplecov'
|
13
|
-
|
14
|
-
SimpleCov.start
|
15
|
-
|
16
|
-
require 'httplog'
|
17
|
-
|
18
|
-
require 'adapters/http_base_adapter'
|
19
|
-
Dir[File.dirname(__FILE__) + '/adapters/*.rb'].each { |f| require f }
|
20
|
-
Dir['./spec/support/**/*.rb'].each { |f| require f }
|
21
|
-
|
22
|
-
# Start a local rack server to serve up test pages.
|
23
|
-
@server_thread = Thread.new do
|
24
|
-
Rack::Handler::Thin.run Httplog::Test::Server.new, Port: 9292
|
25
|
-
end
|
26
|
-
sleep(3) # wait a moment for the server to be booted
|
27
|
-
|
28
|
-
RSpec.configure do |config|
|
29
|
-
config.before(:each) do
|
30
|
-
require 'stringio'
|
31
|
-
|
32
|
-
@log = StringIO.new
|
33
|
-
@logger = Logger.new @log
|
34
|
-
|
35
|
-
HttpLog.configure { |c| c.logger = @logger }
|
36
|
-
end
|
37
|
-
|
38
|
-
config.after(:each) do
|
39
|
-
HttpLog.reset!
|
40
|
-
end
|
41
|
-
|
42
|
-
def log
|
43
|
-
@log.string
|
44
|
-
end
|
45
|
-
end
|