http_tracker 0.1.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.
- data/examples/mongodb.rb +46 -0
- data/examples/simple_tracker.rb +20 -0
- data/lib/http_tracker/class_methods.rb +32 -0
- data/lib/http_tracker/manager.rb +50 -0
- data/lib/http_tracker.rb +2 -0
- data/spec/helpers/request_helper.rb +26 -0
- data/spec/http_tracker/manager_spec.rb +149 -0
- data/spec/spec_helper.rb +18 -0
- metadata +105 -0
data/examples/mongodb.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "http_tracker"
|
3
|
+
require "sinatra"
|
4
|
+
require "pp"
|
5
|
+
require "mongo"
|
6
|
+
|
7
|
+
class MongoTracker
|
8
|
+
include Mongo
|
9
|
+
|
10
|
+
def valid?(env); true; end
|
11
|
+
|
12
|
+
def on_request(env)
|
13
|
+
storage.save \
|
14
|
+
"ip" => env["REMOTE_ADDR"],
|
15
|
+
"path_info" => env["PATH_INFO"],
|
16
|
+
"method" => env["REQUEST_METHOD"]
|
17
|
+
end
|
18
|
+
|
19
|
+
def on_response(env, status, headers, body)
|
20
|
+
puts "Total requests made: #{storage.count}"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
def storage
|
25
|
+
@storage ||= begin
|
26
|
+
db_name, collection_name = "http_tracker_examples", "test"
|
27
|
+
|
28
|
+
connection = Connection.new.db(db_name)
|
29
|
+
unless connection.collection_names.include?(collection_name)
|
30
|
+
connection.create_collection(collection_name)
|
31
|
+
end
|
32
|
+
|
33
|
+
connection.collection(collection_name)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
HTTPTracker::Manager.add(:mongo, MongoTracker)
|
39
|
+
|
40
|
+
use HTTPTracker::Manager
|
41
|
+
|
42
|
+
get "/foo" do
|
43
|
+
":-)"
|
44
|
+
end
|
45
|
+
|
46
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "http_tracker"
|
3
|
+
require "sinatra"
|
4
|
+
require "pp"
|
5
|
+
|
6
|
+
HTTPTracker::Manager.add(:simple) do
|
7
|
+
def valid?(env); true; end
|
8
|
+
|
9
|
+
def on_request(env)
|
10
|
+
pp env
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
use HTTPTracker::Manager
|
15
|
+
|
16
|
+
get "/foo" do
|
17
|
+
":-)"
|
18
|
+
end
|
19
|
+
|
20
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module HTTPTracker
|
2
|
+
module ClassMethods
|
3
|
+
def add(label, klass = nil, &block)
|
4
|
+
if label.is_a?(Class) || (klass.nil? && !block_given?)
|
5
|
+
raise ArgumentError,
|
6
|
+
"A class or a block should be passed along with the tracker label."
|
7
|
+
end
|
8
|
+
|
9
|
+
klass ||= Class.new
|
10
|
+
if block_given?
|
11
|
+
klass.class_eval(&block)
|
12
|
+
end
|
13
|
+
|
14
|
+
tracker = klass.new
|
15
|
+
|
16
|
+
if !tracker.respond_to?(:on_request) && !tracker.respond_to?(:on_response)
|
17
|
+
raise ArgumentError,
|
18
|
+
"You should implement one of the following methods: on_response, on_request."
|
19
|
+
end
|
20
|
+
|
21
|
+
trackers[label] = klass
|
22
|
+
end
|
23
|
+
|
24
|
+
def trackers
|
25
|
+
@trackers ||= {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def clear!
|
29
|
+
@trackers = {}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module HTTPTracker
|
2
|
+
class Manager
|
3
|
+
extend ClassMethods
|
4
|
+
|
5
|
+
def initialize(app, options = {})
|
6
|
+
@app, @options = app, options
|
7
|
+
initialize_trackers
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
run_on_request_callbacks!(env)
|
12
|
+
|
13
|
+
status, headers, body = @app.call(env)
|
14
|
+
|
15
|
+
run_on_response_callbacks!(env, status, headers, body)
|
16
|
+
|
17
|
+
[status, headers, body]
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def initialize_trackers
|
22
|
+
trackers.each_pair do |label, tracker_klass|
|
23
|
+
trackers[label] = tracker_klass.new
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def trackers
|
28
|
+
self.class.trackers
|
29
|
+
end
|
30
|
+
|
31
|
+
def run_on_request_callbacks!(env)
|
32
|
+
run_callbacks(:request, env)
|
33
|
+
end
|
34
|
+
|
35
|
+
def run_on_response_callbacks!(env, status, headers, body)
|
36
|
+
run_callbacks(:response, env, status, headers, body)
|
37
|
+
end
|
38
|
+
|
39
|
+
def run_callbacks(name, *args)
|
40
|
+
env = args.first
|
41
|
+
method = "on_#{name}"
|
42
|
+
|
43
|
+
trackers.each_pair do |label, tracker|
|
44
|
+
if tracker.valid?(env) && tracker.respond_to?(method)
|
45
|
+
tracker.send(method, *args)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/http_tracker.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module HTTPTracker::Spec
|
2
|
+
module Helpers
|
3
|
+
|
4
|
+
# Stolen from Warden http://github.com/hassox/warden
|
5
|
+
def env_with_params(path = "/", params = {}, env = {})
|
6
|
+
method = params.delete(:method) || "GET"
|
7
|
+
env = { 'HTTP_VERSION' => '1.1', 'REQUEST_METHOD' => "#{method}" }.merge(env)
|
8
|
+
Rack::MockRequest.env_for("#{path}?#{Rack::Utils.build_query(params)}", env)
|
9
|
+
end
|
10
|
+
|
11
|
+
def basic_app
|
12
|
+
lambda do |env|
|
13
|
+
[200, { "Content-Type" => "text/html" }, "yes!"]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def setup_rack(middleware_class, options = {}, &block)
|
18
|
+
app ||= block_given? ? block : basic_app
|
19
|
+
Rack::Builder.new do
|
20
|
+
use middleware_class, options
|
21
|
+
run app
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Manager do
|
4
|
+
after do
|
5
|
+
HTTPTracker::Manager.clear!
|
6
|
+
end
|
7
|
+
|
8
|
+
context "when adding new trackers" do
|
9
|
+
it "should be able to add trackers passing blocks" do
|
10
|
+
HTTPTracker::Manager.add(:foo) do
|
11
|
+
def valid?; end
|
12
|
+
def on_request; end
|
13
|
+
def on_response; end
|
14
|
+
end
|
15
|
+
|
16
|
+
HTTPTracker::Manager.trackers.should have(1).trackers
|
17
|
+
klass = HTTPTracker::Manager.trackers[:foo]
|
18
|
+
|
19
|
+
tracker = klass.new
|
20
|
+
tracker.respond_to?(:valid?).should be_true
|
21
|
+
tracker.respond_to?(:on_request).should be_true
|
22
|
+
tracker.respond_to?(:on_response).should be_true
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be able to add trackers using classes" do
|
26
|
+
klass = Class.new do
|
27
|
+
def valid?; end
|
28
|
+
def on_request; end
|
29
|
+
def on_response; end
|
30
|
+
end
|
31
|
+
HTTPTracker::Manager.add(:foo, klass)
|
32
|
+
|
33
|
+
klass = HTTPTracker::Manager.trackers[:foo]
|
34
|
+
|
35
|
+
tracker = klass.new
|
36
|
+
tracker.respond_to?(:valid?).should be_true
|
37
|
+
tracker.respond_to?(:on_request).should be_true
|
38
|
+
tracker.respond_to?(:on_response).should be_true
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should raise an error if a name and a class aren't provided" do
|
42
|
+
lambda {
|
43
|
+
HTTPTracker::Manager.add(Class.new)
|
44
|
+
}.should raise_error
|
45
|
+
|
46
|
+
lambda {
|
47
|
+
HTTPTracker::Manager.add("foo")
|
48
|
+
}.should raise_error
|
49
|
+
end
|
50
|
+
|
51
|
+
it "it should make the #valid? method obligatory" do
|
52
|
+
lambda {
|
53
|
+
HTTPTracker::Manager.add(:foo) do
|
54
|
+
def valid?; end
|
55
|
+
end
|
56
|
+
}.should raise_error
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should be obligatory to implement on of the following methods: #on_request, #on_response" do
|
60
|
+
lambda {
|
61
|
+
HTTPTracker::Manager.add(:foo) do
|
62
|
+
def valid?; end
|
63
|
+
def on_request; end
|
64
|
+
end
|
65
|
+
}.should_not raise_error
|
66
|
+
|
67
|
+
lambda {
|
68
|
+
HTTPTracker::Manager.add(:foo) do
|
69
|
+
def valid?; end
|
70
|
+
def on_response; end
|
71
|
+
end
|
72
|
+
}.should_not raise_error
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when processing a request" do
|
78
|
+
before do
|
79
|
+
HTTPTracker::Manager.add(:foo) do
|
80
|
+
def valid?(env)
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
def on_request(env)
|
85
|
+
@x = 5
|
86
|
+
end
|
87
|
+
|
88
|
+
def on_response(env, status, headers, body)
|
89
|
+
@y = 10
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
HTTPTracker::Manager.add(:invalid) do
|
94
|
+
def valid?(env)
|
95
|
+
false
|
96
|
+
end
|
97
|
+
|
98
|
+
def on_request(env)
|
99
|
+
@NOT = 666
|
100
|
+
end
|
101
|
+
|
102
|
+
def on_response(env, status, headers, body)
|
103
|
+
@SHOULD_NOT_BE_SET = "SERIOUSLY"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
@app = setup_rack(HTTPTracker::Manager)
|
108
|
+
end
|
109
|
+
|
110
|
+
context "when in middle of resquests" do
|
111
|
+
it "should initialize its trackers before processing the request" do
|
112
|
+
foo_tracker = HTTPTracker::Manager.trackers[:foo]
|
113
|
+
|
114
|
+
[:valid?, :on_request, :on_response].each do |method|
|
115
|
+
foo_tracker.respond_to?(method).should be_false
|
116
|
+
end
|
117
|
+
|
118
|
+
@app.call(env_with_params)
|
119
|
+
|
120
|
+
foo_tracker = HTTPTracker::Manager.trackers[:foo]
|
121
|
+
[:valid?, :on_request, :on_response].each do |method|
|
122
|
+
foo_tracker.respond_to?(method).should be_true
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should never initialize its trackers more than once"
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should should run its before callbacks before processing the request" do
|
131
|
+
@app.call(env_with_params)
|
132
|
+
foo_tracker = HTTPTracker::Manager.trackers[:foo]
|
133
|
+
foo_tracker.instance_variable_get("@x").should == 5
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should should run its after callbacks before processing the request" do
|
137
|
+
@app.call(env_with_params)
|
138
|
+
foo_tracker = HTTPTracker::Manager.trackers[:foo]
|
139
|
+
foo_tracker.instance_variable_get("@y").should == 10
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should only execute the callbacks if the tracker is valid the environment" do
|
143
|
+
@app.call(env_with_params)
|
144
|
+
invalid_tracker = HTTPTracker::Manager.trackers[:invalid]
|
145
|
+
invalid_tracker.instance_variable_get("@SHOULD_NOT_BE_SET").should be_nil
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
|
3
|
+
|
4
|
+
require "rubygems"
|
5
|
+
require "http_tracker"
|
6
|
+
require "rspec"
|
7
|
+
require "rack"
|
8
|
+
require "pp"
|
9
|
+
|
10
|
+
Dir[File.join(File.dirname(__FILE__), "helpers", "**/*.rb")].each do |f|
|
11
|
+
require f
|
12
|
+
end
|
13
|
+
|
14
|
+
include HTTPTracker
|
15
|
+
|
16
|
+
Rspec.configure do |config|
|
17
|
+
config.include(HTTPTracker::Spec::Helpers)
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: http_tracker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Dalto Curvelano Junior
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-04-07 00:00:00 -03:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rack
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 3
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
version: "0"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: rspec
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 3
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id002
|
49
|
+
description:
|
50
|
+
email:
|
51
|
+
executables: []
|
52
|
+
|
53
|
+
extensions: []
|
54
|
+
|
55
|
+
extra_rdoc_files: []
|
56
|
+
|
57
|
+
files:
|
58
|
+
- lib/http_tracker/class_methods.rb
|
59
|
+
- lib/http_tracker/manager.rb
|
60
|
+
- lib/http_tracker.rb
|
61
|
+
- spec/helpers/request_helper.rb
|
62
|
+
- spec/http_tracker/manager_spec.rb
|
63
|
+
- spec/spec_helper.rb
|
64
|
+
- examples/mongodb.rb
|
65
|
+
- examples/simple_tracker.rb
|
66
|
+
has_rdoc: true
|
67
|
+
homepage: http://github.com/dlt/request_tracker
|
68
|
+
licenses:
|
69
|
+
- MIT
|
70
|
+
post_install_message:
|
71
|
+
rdoc_options: []
|
72
|
+
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
hash: 3
|
81
|
+
segments:
|
82
|
+
- 0
|
83
|
+
version: "0"
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
hash: 3
|
90
|
+
segments:
|
91
|
+
- 0
|
92
|
+
version: "0"
|
93
|
+
requirements: []
|
94
|
+
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 1.5.2
|
97
|
+
signing_key:
|
98
|
+
specification_version: 3
|
99
|
+
summary: A simple and modular rack middleware to track http requests
|
100
|
+
test_files:
|
101
|
+
- spec/helpers/request_helper.rb
|
102
|
+
- spec/http_tracker/manager_spec.rb
|
103
|
+
- spec/spec_helper.rb
|
104
|
+
- examples/mongodb.rb
|
105
|
+
- examples/simple_tracker.rb
|