pauldix-typhoeus 0.0.24 → 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/lib/typhoeus.rb +4 -2
- data/lib/typhoeus/easy.rb +4 -4
- data/lib/typhoeus/hydra.rb +149 -0
- data/lib/typhoeus/request.rb +80 -0
- data/lib/typhoeus/response.rb +9 -7
- data/spec/typhoeus/response_spec.rb +5 -0
- metadata +14 -3
data/lib/typhoeus.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
$LOAD_PATH.unshift(File.dirname(__FILE__)) unless $LOAD_PATH.include?(File.dirname(__FILE__))
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'rack/utils'
|
4
4
|
require 'digest/sha2'
|
5
5
|
require 'typhoeus/easy'
|
6
6
|
require 'typhoeus/multi'
|
@@ -10,9 +10,11 @@ require 'typhoeus/remote_method'
|
|
10
10
|
require 'typhoeus/remote'
|
11
11
|
require 'typhoeus/remote_proxy_object'
|
12
12
|
require 'typhoeus/response'
|
13
|
+
require 'typhoeus/request'
|
14
|
+
require 'typhoeus/hydra'
|
13
15
|
|
14
16
|
module Typhoeus
|
15
|
-
VERSION = "0.0
|
17
|
+
VERSION = "0.1.0"
|
16
18
|
|
17
19
|
def self.easy_object_pool
|
18
20
|
@easy_objects ||= []
|
data/lib/typhoeus/easy.rb
CHANGED
@@ -104,12 +104,12 @@ module Typhoeus
|
|
104
104
|
params_string = params.keys.collect do |k|
|
105
105
|
value = params[k]
|
106
106
|
if value.is_a? Hash
|
107
|
-
value.keys.collect {|sk|
|
107
|
+
value.keys.collect {|sk| Rack::Utils.escape("#{k}[#{sk}]") + "=" + Rack::Utils.escape(value[sk].to_s)}
|
108
108
|
elsif value.is_a? Array
|
109
|
-
key =
|
110
|
-
value.collect { |v| "#{key}=#{
|
109
|
+
key = Rack::Utils.escape(k.to_s)
|
110
|
+
value.collect { |v| "#{key}=#{Rack::Utils.escape(v.to_s)}" }.join('&')
|
111
111
|
else
|
112
|
-
"#{
|
112
|
+
"#{Rack::Utils.escape(k.to_s)}=#{Rack::Utils.escape(params[k].to_s)}"
|
113
113
|
end
|
114
114
|
end.flatten.join("&")
|
115
115
|
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module Typhoeus
|
2
|
+
class Hydra
|
3
|
+
def initialize
|
4
|
+
@multi = Multi.new
|
5
|
+
@easy_pool = []
|
6
|
+
@mocks = []
|
7
|
+
@memoized_requests = {}
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.hydra
|
11
|
+
@hydra ||= new
|
12
|
+
end
|
13
|
+
|
14
|
+
def queue(request)
|
15
|
+
return if assign_to_mock(request)
|
16
|
+
|
17
|
+
if request.method == :get
|
18
|
+
if @memoized_requests.has_key? request.url
|
19
|
+
@memoized_requests[request.url] << request
|
20
|
+
else
|
21
|
+
@memoized_requests[request.url] = []
|
22
|
+
get_from_cache_or_queue(request)
|
23
|
+
end
|
24
|
+
else
|
25
|
+
get_from_cache_or_queue(request)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def run
|
30
|
+
@mocks.each do |m|
|
31
|
+
m.requests.each do |request|
|
32
|
+
m.response.request = request
|
33
|
+
handle_request(request, m.response)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
@multi.perform
|
37
|
+
@memoized_requests = {}
|
38
|
+
end
|
39
|
+
|
40
|
+
def cache_getter(&block)
|
41
|
+
@cache_getter = block
|
42
|
+
end
|
43
|
+
|
44
|
+
def cache_setter(&block)
|
45
|
+
@cache_setter = block
|
46
|
+
end
|
47
|
+
|
48
|
+
def on_complete(&block)
|
49
|
+
@on_complete = block
|
50
|
+
end
|
51
|
+
|
52
|
+
def mock(method, url)
|
53
|
+
@mocks << HydraMock.new(url, method)
|
54
|
+
@mocks.last
|
55
|
+
end
|
56
|
+
|
57
|
+
def assign_to_mock(request)
|
58
|
+
m = @mocks.detect {|mck| mck.method == request.method && mck.url == request.url}
|
59
|
+
m && m.add_request(request)
|
60
|
+
end
|
61
|
+
private :assign_to_mock
|
62
|
+
|
63
|
+
def get_from_cache_or_queue(request)
|
64
|
+
if @cache_getter
|
65
|
+
val = @cache_getter.call(request)
|
66
|
+
if val
|
67
|
+
request.response = val
|
68
|
+
request.call_handlers
|
69
|
+
else
|
70
|
+
@multi.add(get_easy_object(request))
|
71
|
+
end
|
72
|
+
else
|
73
|
+
@multi.add(get_easy_object(request))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
private :get_from_cache_or_queue
|
77
|
+
|
78
|
+
def get_easy_object(request)
|
79
|
+
easy = @easy_pool.pop || Easy.new
|
80
|
+
easy.url = request.url
|
81
|
+
easy.method = request.method
|
82
|
+
easy.headers = request.headers if request.headers
|
83
|
+
easy.request_body = request.body if request.body
|
84
|
+
easy.timeout = request.timeout if request.timeout
|
85
|
+
easy.on_success do |easy|
|
86
|
+
handle_request(request, response_from_easy(easy, request))
|
87
|
+
release_easy_object(easy)
|
88
|
+
end
|
89
|
+
easy.on_failure do |easy|
|
90
|
+
handle_request(request, response_from_easy(easy, request))
|
91
|
+
release_easy_object(easy)
|
92
|
+
end
|
93
|
+
easy.set_headers
|
94
|
+
easy
|
95
|
+
end
|
96
|
+
private :get_easy_object
|
97
|
+
|
98
|
+
def release_easy_object(easy)
|
99
|
+
easy.reset
|
100
|
+
@easy_pool.push easy
|
101
|
+
end
|
102
|
+
private :release_easy_object
|
103
|
+
|
104
|
+
def handle_request(request, response)
|
105
|
+
request.response = response
|
106
|
+
|
107
|
+
if (request.cache_timeout && @cache_setter)
|
108
|
+
@cache_setter.call(request)
|
109
|
+
end
|
110
|
+
@on_complete.call(response) if @on_complete
|
111
|
+
|
112
|
+
request.call_handlers
|
113
|
+
if requests = @memoized_requests[request.url]
|
114
|
+
requests.each do |r|
|
115
|
+
r.response = response
|
116
|
+
r.call_handlers
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
private :handle_request
|
121
|
+
|
122
|
+
def response_from_easy(easy, request)
|
123
|
+
Response.new(:code => easy.response_code,
|
124
|
+
:headers => easy.response_header,
|
125
|
+
:body => easy.response_body,
|
126
|
+
:time => easy.total_time_taken,
|
127
|
+
:request => request)
|
128
|
+
end
|
129
|
+
private :response_from_easy
|
130
|
+
end
|
131
|
+
|
132
|
+
class HydraMock
|
133
|
+
attr_reader :url, :method, :response, :requests
|
134
|
+
|
135
|
+
def initialize(url, method)
|
136
|
+
@url = url
|
137
|
+
@method = method
|
138
|
+
@requests = []
|
139
|
+
end
|
140
|
+
|
141
|
+
def add_request(request)
|
142
|
+
@requests << request
|
143
|
+
end
|
144
|
+
|
145
|
+
def and_return(val)
|
146
|
+
@response = val
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Typhoeus
|
2
|
+
class Request
|
3
|
+
attr_accessor :method, :params, :body, :headers, :timeout, :user_agent, :response, :cache_timeout
|
4
|
+
attr_reader :url
|
5
|
+
|
6
|
+
def initialize(url, options = {})
|
7
|
+
@method = options[:method] || :get
|
8
|
+
@params = options[:params]
|
9
|
+
@body = options[:body]
|
10
|
+
@timeout = options[:timeout]
|
11
|
+
@headers = options[:headers] || {}
|
12
|
+
@user_agent = options[:user_agent] || Typhoeus::USER_AGENT
|
13
|
+
@cache_timeout = options[:cache_timeout]
|
14
|
+
@url = @params ? "#{url}?#{params_string}" : url
|
15
|
+
@on_complete = nil
|
16
|
+
@after_complete = nil
|
17
|
+
@handled_response = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def host
|
21
|
+
slash_location = @url.index('/', 8)
|
22
|
+
if slash_location
|
23
|
+
@url.slice(0, slash_location)
|
24
|
+
else
|
25
|
+
query_string_location = @url.index('?')
|
26
|
+
return query_string_location ? @url.slice(0, query_string_location) : @url
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def headers
|
31
|
+
@headers["User-Agent"] = @user_agent
|
32
|
+
@headers
|
33
|
+
end
|
34
|
+
|
35
|
+
def params_string
|
36
|
+
params.keys.sort.collect do |k|
|
37
|
+
value = params[k]
|
38
|
+
if value.is_a? Hash
|
39
|
+
value.keys.collect {|sk| Rack::Utils.escape("#{k}[#{sk}]") + "=" + Rack::Utils.escape(value[sk].to_s)}
|
40
|
+
elsif value.is_a? Array
|
41
|
+
key = Rack::Utils.escape(k.to_s)
|
42
|
+
value.collect { |v| "#{key}=#{Rack::Utils.escape(v.to_s)}" }.join('&')
|
43
|
+
else
|
44
|
+
"#{Rack::Utils.escape(k.to_s)}=#{Rack::Utils.escape(params[k].to_s)}"
|
45
|
+
end
|
46
|
+
end.flatten.join("&")
|
47
|
+
end
|
48
|
+
|
49
|
+
def on_complete(&block)
|
50
|
+
@on_complete = block
|
51
|
+
end
|
52
|
+
|
53
|
+
def after_complete(&block)
|
54
|
+
@after_complete = block
|
55
|
+
end
|
56
|
+
|
57
|
+
def call_handlers
|
58
|
+
if @on_complete
|
59
|
+
@handled_response = @on_complete.call(response)
|
60
|
+
call_after_complete
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def call_after_complete
|
65
|
+
@after_complete.call(@handled_response) if @after_complete
|
66
|
+
end
|
67
|
+
|
68
|
+
def handled_response=(val)
|
69
|
+
@handled_response = val
|
70
|
+
end
|
71
|
+
|
72
|
+
def handled_response
|
73
|
+
@handled_response || response
|
74
|
+
end
|
75
|
+
|
76
|
+
def cache_key
|
77
|
+
Digest::SHA1.hexdigest(url)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/typhoeus/response.rb
CHANGED
@@ -1,17 +1,19 @@
|
|
1
1
|
module Typhoeus
|
2
2
|
class Response
|
3
|
+
attr_accessor :request
|
3
4
|
attr_reader :code, :headers, :body, :time,
|
4
5
|
:requested_url, :requested_remote_method,
|
5
6
|
:requested_http_method, :start_time
|
6
7
|
|
7
8
|
def initialize(params = {})
|
8
|
-
@code
|
9
|
-
@headers
|
10
|
-
@body
|
11
|
-
@time
|
12
|
-
@requested_url
|
13
|
-
@requested_http_method
|
14
|
-
@start_time
|
9
|
+
@code = params[:code]
|
10
|
+
@headers = params[:headers]
|
11
|
+
@body = params[:body]
|
12
|
+
@time = params[:time]
|
13
|
+
@requested_url = params[:requested_url]
|
14
|
+
@requested_http_method = params[:requested_http_method]
|
15
|
+
@start_time = params[:start_time]
|
16
|
+
@request = params[:request]
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -27,5 +27,10 @@ describe Typhoeus::Response do
|
|
27
27
|
response = Typhoeus::Response.new(:requested_http_method => :delete)
|
28
28
|
response.requested_http_method.should == :delete
|
29
29
|
end
|
30
|
+
|
31
|
+
it "should store an associated request object" do
|
32
|
+
response = Typhoeus::Response.new(:request => "whatever")
|
33
|
+
response.request.should == "whatever"
|
34
|
+
end
|
30
35
|
end
|
31
36
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pauldix-typhoeus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Dix
|
@@ -11,8 +11,17 @@ cert_chain: []
|
|
11
11
|
|
12
12
|
date: 2009-07-03 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rack
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.9.0
|
24
|
+
version:
|
16
25
|
description:
|
17
26
|
email: paul@pauldix.net
|
18
27
|
executables: []
|
@@ -38,6 +47,8 @@ files:
|
|
38
47
|
- lib/typhoeus/filter.rb
|
39
48
|
- lib/typhoeus/remote_method.rb
|
40
49
|
- lib/typhoeus/response.rb
|
50
|
+
- lib/typhoeus/hydra.rb
|
51
|
+
- lib/typhoeus/request.rb
|
41
52
|
- spec/spec.opts
|
42
53
|
- spec/spec_helper.rb
|
43
54
|
- spec/typhoeus/easy_spec.rb
|