pauldix-typhoeus 0.0.24 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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