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 CHANGED
@@ -1,6 +1,6 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__)) unless $LOAD_PATH.include?(File.dirname(__FILE__))
2
2
 
3
- require 'cgi'
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.24"
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| CGI.escape("#{k}[#{sk}]") + "=" + CGI.escape(value[sk].to_s)}
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 = CGI.escape(k.to_s)
110
- value.collect { |v| "#{key}=#{CGI.escape(v.to_s)}" }.join('&')
109
+ key = Rack::Utils.escape(k.to_s)
110
+ value.collect { |v| "#{key}=#{Rack::Utils.escape(v.to_s)}" }.join('&')
111
111
  else
112
- "#{CGI.escape(k.to_s)}=#{CGI.escape(params[k].to_s)}"
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
@@ -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 = params[:code]
9
- @headers = params[:headers]
10
- @body = params[:body]
11
- @time = params[:time]
12
- @requested_url = params[:requested_url]
13
- @requested_http_method = params[:requested_http_method]
14
- @start_time = params[: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.24
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