sniffer 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +6 -0
- data/.travis.yml +1 -10
- data/CHANGELOG.md +12 -0
- data/README.md +29 -7
- data/lib/sniffer.rb +13 -8
- data/lib/sniffer/adapters/curb_adapter.rb +2 -1
- data/lib/sniffer/adapters/ethon_adapter.rb +1 -3
- data/lib/sniffer/adapters/eventmachine_adapter.rb +63 -0
- data/lib/sniffer/adapters/excon_adapter.rb +49 -0
- data/lib/sniffer/config.rb +13 -0
- data/lib/sniffer/data.rb +31 -0
- data/lib/sniffer/data_item.rb +2 -2
- data/lib/sniffer/version.rb +1 -1
- data/sniffer.gemspec +2 -0
- metadata +34 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a791b41dd917e6bd37ad0a30f52edfb29316305
|
4
|
+
data.tar.gz: '08393e568d23b31a060406b390b85ddee72c20a5'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70eea24423a67f79778531924b3957d87f64d73ef62198bd7ad76dc05f24ae363706e5a29f69b99a961f2e4dc86509b2e6a35fa5c6d65ca69fc7b585ab678b33
|
7
|
+
data.tar.gz: d0178703da107888ebd02bd115f64ebed1421fc72618708b649b7d711e3f0ac5da58e3ffcb07c7da30318ee2f8146b7802b4c33eab1a22a8bd2eff21a2104054
|
data/.rubocop.yml
CHANGED
@@ -33,12 +33,18 @@ Style/BlockDelimiters:
|
|
33
33
|
Exclude:
|
34
34
|
- 'spec/**/*.rb'
|
35
35
|
|
36
|
+
Style/DoubleNegation:
|
37
|
+
Enabled: false
|
38
|
+
|
36
39
|
Layout/SpaceInsideStringInterpolation:
|
37
40
|
EnforcedStyle: no_space
|
38
41
|
|
39
42
|
Lint/AmbiguousRegexpLiteral:
|
40
43
|
Enabled: false
|
41
44
|
|
45
|
+
Lint/AmbiguousBlockAssociation:
|
46
|
+
Enabled: false
|
47
|
+
|
42
48
|
Metrics/MethodLength:
|
43
49
|
Exclude:
|
44
50
|
- 'spec/**/*.rb'
|
data/.travis.yml
CHANGED
@@ -1,14 +1,5 @@
|
|
1
1
|
sudo: false
|
2
2
|
language: ruby
|
3
|
-
env:
|
4
|
-
global:
|
5
|
-
- CC_TEST_REPORTER_ID=bc054bdf814431bf40559f1cd62a86956fa5666296895400e1282a47ec6d1c69
|
6
3
|
rvm:
|
4
|
+
- 2.2.2
|
7
5
|
- 2.4.2
|
8
|
-
before_install: gem install bundler -v 1.15.4
|
9
|
-
before_script:
|
10
|
-
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
11
|
-
- chmod +x ./cc-test-reporter
|
12
|
-
- ./cc-test-reporter before-build
|
13
|
-
after_script:
|
14
|
-
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
|
-
# Sniffer
|
1
|
+
# Sniffer
|
2
2
|
|
3
|
+
[![Build Status](https://travis-ci.org/aderyabin/sniffer.svg?branch=master)](https://travis-ci.org/aderyabin/sniffer) [![Gem Version](https://badge.fury.io/rb/sniffer.svg)](https://rubygems.org/gems/sniffer) [![Join the chat at https://gitter.im/aderyabin/sniffer](https://badges.gitter.im/aderyabin/sniffer.svg)](https://gitter.im/aderyabin/sniffer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
3
4
|
|
4
5
|
Sniffer aims to help:
|
5
6
|
|
@@ -15,6 +16,8 @@ Sniffer supports most common HTTP accessing libraries:
|
|
15
16
|
* [Curb](https://github.com/taf2/curb/)
|
16
17
|
* [Ethon](https://github.com/typhoeus/ethon)
|
17
18
|
* [Typhoeus](https://github.com/typhoeus/typhoeus)
|
19
|
+
* [EM-HTTP-Request](https://github.com/igrigorik/em-http-request)
|
20
|
+
* [Excon](https://github.com/excon/excon)
|
18
21
|
|
19
22
|
|
20
23
|
<a href="https://evilmartians.com/">
|
@@ -45,11 +48,11 @@ Or install it yourself as:
|
|
45
48
|
Sniffer default options:
|
46
49
|
|
47
50
|
```ruby
|
48
|
-
Sniffer.config do
|
49
|
-
logger
|
50
|
-
severity
|
51
|
+
Sniffer.config do |c|
|
52
|
+
c.logger = Logger.new($stdout),
|
53
|
+
c.severity = Logger::Severity::DEBUG,
|
51
54
|
# HTTP options to log
|
52
|
-
log
|
55
|
+
c.log = {
|
53
56
|
request_url: true,
|
54
57
|
request_headers: true,
|
55
58
|
request_body: true,
|
@@ -59,8 +62,8 @@ Sniffer.config do
|
|
59
62
|
response_body: true,
|
60
63
|
timing: true
|
61
64
|
},
|
62
|
-
store
|
63
|
-
enabled
|
65
|
+
c.store = true, # save requests/responses to Sniffer.data
|
66
|
+
c.enabled = false # Sniffer disabled by default
|
64
67
|
end
|
65
68
|
```
|
66
69
|
|
@@ -108,6 +111,18 @@ You can clear saved data
|
|
108
111
|
Sniffer.clear!
|
109
112
|
```
|
110
113
|
|
114
|
+
You can configure capacity of storage to prevent the huge memory usage and set up log rotation.
|
115
|
+
By default log rotation is active (when capacity is set) and log works like a queue.
|
116
|
+
If rotation is disabled - requests will be logged until result log size reaches the capacity.
|
117
|
+
|
118
|
+
```
|
119
|
+
# will fill the storage and stop logging
|
120
|
+
Sniffer.config.store = {capacity: 1000, rotate: false}
|
121
|
+
|
122
|
+
# will rotate logs to fit 1000 results (rotate is true by default)
|
123
|
+
Sniffer.config.store = {capacity: 1000}
|
124
|
+
```
|
125
|
+
|
111
126
|
You can reset config to default
|
112
127
|
|
113
128
|
```
|
@@ -139,6 +154,13 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
139
154
|
|
140
155
|
Bug reports and pull requests are welcome on GitHub at https://github.com/aderyabin/sniffer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
141
156
|
|
157
|
+
## Acknowledge
|
158
|
+
|
159
|
+
* [Sergey Ponomarev](https://github.com/sponomarev)
|
160
|
+
* [Salahutdinov Dmitry](https://github.com/dsalahutdinov)
|
161
|
+
* [Stanislav Chereshkevich](https://github.com/dissident)
|
162
|
+
* [Anatoliy Kurichev](https://github.com/russo-matrosso)
|
163
|
+
|
142
164
|
## License
|
143
165
|
|
144
166
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/lib/sniffer.rb
CHANGED
@@ -5,14 +5,11 @@ require "logger"
|
|
5
5
|
require_relative "sniffer/version"
|
6
6
|
require_relative "sniffer/config"
|
7
7
|
require_relative "sniffer/data_item"
|
8
|
+
require_relative "sniffer/data"
|
8
9
|
|
9
10
|
# Sniffer allows to log http requests
|
10
11
|
module Sniffer
|
11
|
-
@data = Set.new
|
12
|
-
|
13
12
|
class << self
|
14
|
-
attr_reader :data
|
15
|
-
|
16
13
|
def config
|
17
14
|
@config ||= Config.new
|
18
15
|
yield @config if block_given?
|
@@ -20,15 +17,16 @@ module Sniffer
|
|
20
17
|
end
|
21
18
|
|
22
19
|
def enable!
|
23
|
-
|
20
|
+
Thread.current[:sniffer] = true
|
24
21
|
end
|
25
22
|
|
26
23
|
def disable!
|
27
|
-
|
24
|
+
Thread.current[:sniffer] = false
|
28
25
|
end
|
29
26
|
|
30
27
|
def enabled?
|
31
|
-
config.enabled
|
28
|
+
Thread.current[:sniffer] = config.enabled if Thread.current[:sniffer].nil?
|
29
|
+
!!Thread.current[:sniffer]
|
32
30
|
end
|
33
31
|
|
34
32
|
def configure
|
@@ -41,11 +39,16 @@ module Sniffer
|
|
41
39
|
|
42
40
|
def reset!
|
43
41
|
@config = Config.new
|
42
|
+
Thread.current[:sniffer] = config.enabled
|
44
43
|
clear!
|
45
44
|
end
|
46
45
|
|
46
|
+
def data
|
47
|
+
@data ||= Sniffer::Data.new
|
48
|
+
end
|
49
|
+
|
47
50
|
def store(data_item)
|
48
|
-
|
51
|
+
data.store(data_item)
|
49
52
|
end
|
50
53
|
|
51
54
|
def logger
|
@@ -60,3 +63,5 @@ require_relative "sniffer/adapters/http_adapter"
|
|
60
63
|
require_relative "sniffer/adapters/patron_adapter"
|
61
64
|
require_relative "sniffer/adapters/curb_adapter"
|
62
65
|
require_relative "sniffer/adapters/ethon_adapter"
|
66
|
+
require_relative "sniffer/adapters/eventmachine_adapter"
|
67
|
+
require_relative "sniffer/adapters/excon_adapter"
|
@@ -14,7 +14,6 @@ module Sniffer
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
18
17
|
def http_with_sniffer(verb)
|
19
18
|
sniffer_request(verb)
|
20
19
|
|
@@ -47,6 +46,7 @@ module Sniffer
|
|
47
46
|
@data_item ||= Sniffer::DataItem.new if Sniffer.enabled?
|
48
47
|
end
|
49
48
|
|
49
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
50
50
|
def sniffer_request(verb, *args)
|
51
51
|
return unless data_item
|
52
52
|
|
@@ -63,6 +63,7 @@ module Sniffer
|
|
63
63
|
|
64
64
|
Sniffer.store(data_item)
|
65
65
|
end
|
66
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
|
66
67
|
|
67
68
|
def sniffer_response(timing)
|
68
69
|
return unless data_item
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sniffer
|
4
|
+
module Adapters
|
5
|
+
# Em-Http-Connection Adapter
|
6
|
+
module EventMachineAdapter
|
7
|
+
# Overrides #send_request, #parse_response, #on_body_data
|
8
|
+
module Client
|
9
|
+
def self.included(base)
|
10
|
+
base.class_eval do
|
11
|
+
alias_method :send_request_without_sniffer, :send_request
|
12
|
+
alias_method :send_request, :send_request_with_sniffer
|
13
|
+
alias_method :parse_response_header_without_sniffer, :parse_response_header
|
14
|
+
alias_method :parse_response_header, :parse_response_header_with_sniffer
|
15
|
+
alias_method :on_body_data_without_sniffer, :on_body_data
|
16
|
+
alias_method :on_body_data, :on_body_data_with_sniffer
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
21
|
+
def send_request_with_sniffer(head, body)
|
22
|
+
if Sniffer.enabled?
|
23
|
+
@data_item = Sniffer::DataItem.new
|
24
|
+
@data_item.response = Sniffer::DataItem::Response.new
|
25
|
+
@data_item.request = Sniffer::DataItem::Request.new(host: @req.host,
|
26
|
+
method: @req.method.to_sym,
|
27
|
+
query: encode_query(@req.uri, @req.query),
|
28
|
+
headers: @req.headers,
|
29
|
+
body: @req.body.to_s,
|
30
|
+
port: @req.port)
|
31
|
+
Sniffer.store(@data_item)
|
32
|
+
|
33
|
+
@start_time = Time.now
|
34
|
+
end
|
35
|
+
|
36
|
+
send_request_without_sniffer(head, body)
|
37
|
+
end
|
38
|
+
# rubocop:enable Metrics/AbcSize,Metrics/MethodLength
|
39
|
+
|
40
|
+
def parse_response_header_with_sniffer(header, version, status)
|
41
|
+
if Sniffer.enabled?
|
42
|
+
@data_item.response.timing = Time.now - @start_time
|
43
|
+
@data_item.response.status = status
|
44
|
+
@data_item.response.headers = header
|
45
|
+
end
|
46
|
+
|
47
|
+
parse_response_header_without_sniffer(header, version, status)
|
48
|
+
end
|
49
|
+
|
50
|
+
def on_body_data_with_sniffer(data)
|
51
|
+
if Sniffer.enabled?
|
52
|
+
@data_item.response.body = data
|
53
|
+
@data_item.log
|
54
|
+
end
|
55
|
+
|
56
|
+
on_body_data_without_sniffer(data)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
EventMachine::HttpClient.send(:include, Sniffer::Adapters::EventMachineAdapter::Client) if defined?(::EventMachine)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sniffer
|
4
|
+
module Adapters
|
5
|
+
# Excon adapter
|
6
|
+
module ExconAdapter
|
7
|
+
def self.included(base)
|
8
|
+
base.class_eval do
|
9
|
+
alias_method :request_without_sniffer, :request
|
10
|
+
alias_method :request, :request_with_sniffer
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# rubocop:disable Metrics/AbcSize,Metrics/MethodLength
|
15
|
+
def request_with_sniffer(params = {}, &block)
|
16
|
+
if Sniffer.enabled?
|
17
|
+
datum = data.merge(params)
|
18
|
+
data_item = Sniffer::DataItem.new
|
19
|
+
data_item.request = Sniffer::DataItem::Request.new(host: datum[:host],
|
20
|
+
method: datum[:method],
|
21
|
+
query: datum[:path] + ::Excon::Utils.query_string(datum),
|
22
|
+
headers: datum[:headers] || {},
|
23
|
+
body: datum[:body].to_s,
|
24
|
+
port: datum[:port])
|
25
|
+
|
26
|
+
Sniffer.store(data_item)
|
27
|
+
end
|
28
|
+
|
29
|
+
bm = Benchmark.realtime do
|
30
|
+
@response = request_without_sniffer(params, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
if Sniffer.enabled?
|
34
|
+
data_item.response = Sniffer::DataItem::Response.new(status: @response.status,
|
35
|
+
headers: @response.headers,
|
36
|
+
body: @response.body,
|
37
|
+
timing: bm)
|
38
|
+
|
39
|
+
data_item.log
|
40
|
+
end
|
41
|
+
|
42
|
+
@response
|
43
|
+
end
|
44
|
+
# rubocop:enable Metrics/AbcSize,Metrics/MethodLength
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
::Excon::Connection.send(:include, Sniffer::Adapters::ExconAdapter) if defined?(::Excon::Connection)
|
data/lib/sniffer/config.rb
CHANGED
@@ -21,5 +21,18 @@ module Sniffer
|
|
21
21
|
},
|
22
22
|
store: true,
|
23
23
|
enabled: false
|
24
|
+
|
25
|
+
def capacity?
|
26
|
+
store.is_a?(Hash) && store.key?(:capacity)
|
27
|
+
end
|
28
|
+
|
29
|
+
def capacity
|
30
|
+
store.fetch(:capacity).to_i
|
31
|
+
end
|
32
|
+
|
33
|
+
def rotate?
|
34
|
+
return false unless capacity?
|
35
|
+
store.fetch(:rotate, true)
|
36
|
+
end
|
24
37
|
end
|
25
38
|
end
|
data/lib/sniffer/data.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sniffer
|
4
|
+
# Data class stores the data and controls capacity
|
5
|
+
class Data < Array
|
6
|
+
def store(data_item)
|
7
|
+
return unless config.store
|
8
|
+
|
9
|
+
if config.rotate?
|
10
|
+
rotate(data_item)
|
11
|
+
else
|
12
|
+
push(data_item) unless overflow?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def rotate(data_item)
|
19
|
+
shift if overflow?
|
20
|
+
push(data_item)
|
21
|
+
end
|
22
|
+
|
23
|
+
def overflow?
|
24
|
+
config.capacity? && length >= config.capacity
|
25
|
+
end
|
26
|
+
|
27
|
+
def config
|
28
|
+
Sniffer.config
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/sniffer/data_item.rb
CHANGED
data/lib/sniffer/version.rb
CHANGED
data/sniffer.gemspec
CHANGED
@@ -35,4 +35,6 @@ Gem::Specification.new do |spec|
|
|
35
35
|
spec.add_development_dependency "curb", ">= 0.9.4"
|
36
36
|
spec.add_development_dependency "ethon", ">= 0.11.0"
|
37
37
|
spec.add_development_dependency "typhoeus", ">= 0.9.0"
|
38
|
+
spec.add_development_dependency "em-http-request", ">= 1.1.0"
|
39
|
+
spec.add_development_dependency "excon", ">= 0.60.0"
|
38
40
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sniffer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrey Deryabin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: anyway_config
|
@@ -220,6 +220,34 @@ dependencies:
|
|
220
220
|
- - ">="
|
221
221
|
- !ruby/object:Gem::Version
|
222
222
|
version: 0.9.0
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: em-http-request
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: 1.1.0
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - ">="
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: 1.1.0
|
237
|
+
- !ruby/object:Gem::Dependency
|
238
|
+
name: excon
|
239
|
+
requirement: !ruby/object:Gem::Requirement
|
240
|
+
requirements:
|
241
|
+
- - ">="
|
242
|
+
- !ruby/object:Gem::Version
|
243
|
+
version: 0.60.0
|
244
|
+
type: :development
|
245
|
+
prerelease: false
|
246
|
+
version_requirements: !ruby/object:Gem::Requirement
|
247
|
+
requirements:
|
248
|
+
- - ">="
|
249
|
+
- !ruby/object:Gem::Version
|
250
|
+
version: 0.60.0
|
223
251
|
description: Analyze HTTP Requests
|
224
252
|
email:
|
225
253
|
- aderyabin@evilmartians.com
|
@@ -232,6 +260,7 @@ files:
|
|
232
260
|
- ".rubocop.yml"
|
233
261
|
- ".ruby-version"
|
234
262
|
- ".travis.yml"
|
263
|
+
- CHANGELOG.md
|
235
264
|
- CODE_OF_CONDUCT.md
|
236
265
|
- Gemfile
|
237
266
|
- LICENSE.txt
|
@@ -243,11 +272,14 @@ files:
|
|
243
272
|
- lib/sniffer.rb
|
244
273
|
- lib/sniffer/adapters/curb_adapter.rb
|
245
274
|
- lib/sniffer/adapters/ethon_adapter.rb
|
275
|
+
- lib/sniffer/adapters/eventmachine_adapter.rb
|
276
|
+
- lib/sniffer/adapters/excon_adapter.rb
|
246
277
|
- lib/sniffer/adapters/http_adapter.rb
|
247
278
|
- lib/sniffer/adapters/httpclient_adapter.rb
|
248
279
|
- lib/sniffer/adapters/net_http_adapter.rb
|
249
280
|
- lib/sniffer/adapters/patron_adapter.rb
|
250
281
|
- lib/sniffer/config.rb
|
282
|
+
- lib/sniffer/data.rb
|
251
283
|
- lib/sniffer/data_item.rb
|
252
284
|
- lib/sniffer/version.rb
|
253
285
|
- sniffer.gemspec
|