typhoeus 0.1.6 → 0.2.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/.gitignore +3 -0
- data/CHANGELOG.markdown +31 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +30 -0
- data/README.textile +333 -0
- data/Rakefile +38 -0
- data/VERSION +1 -0
- data/benchmarks/profile.rb +25 -0
- data/benchmarks/vs_nethttp.rb +35 -0
- data/examples/twitter.rb +21 -0
- data/ext/typhoeus/.gitignore +6 -0
- data/ext/typhoeus/extconf.rb +3 -2
- data/ext/typhoeus/native.h +7 -0
- data/ext/typhoeus/typhoeus_multi.c +1 -2
- data/lib/typhoeus/.gitignore +1 -0
- data/lib/typhoeus/easy.rb +172 -42
- data/lib/typhoeus/hydra/callbacks.rb +24 -0
- data/lib/typhoeus/hydra/connect_options.rb +45 -0
- data/lib/typhoeus/hydra/stubbing.rb +52 -0
- data/lib/typhoeus/hydra.rb +85 -59
- data/lib/typhoeus/hydra_mock.rb +131 -0
- data/lib/typhoeus/multi.rb +4 -3
- data/lib/typhoeus/normalized_header_hash.rb +58 -0
- data/lib/typhoeus/remote_proxy_object.rb +6 -6
- data/lib/typhoeus/request.rb +118 -31
- data/lib/typhoeus/response.rb +61 -4
- data/lib/typhoeus/service.rb +20 -0
- data/lib/typhoeus/utils.rb +24 -0
- data/lib/typhoeus.rb +11 -8
- data/profilers/valgrind.rb +24 -0
- data/spec/fixtures/result_set.xml +60 -0
- data/spec/servers/app.rb +48 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/typhoeus/easy_spec.rb +126 -4
- data/spec/typhoeus/hydra_mock_spec.rb +300 -0
- data/spec/typhoeus/hydra_spec.rb +456 -0
- data/spec/typhoeus/normalized_header_hash_spec.rb +41 -0
- data/spec/typhoeus/remote_spec.rb +2 -2
- data/spec/typhoeus/request_spec.rb +247 -0
- data/spec/typhoeus/response_spec.rb +104 -1
- data/spec/typhoeus/utils_spec.rb +22 -0
- data/typhoeus.gemspec +123 -0
- metadata +145 -34
- data/ext/typhoeus/Makefile +0 -157
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Typhoeus::Request do
|
|
4
|
+
describe "#inspect" do
|
|
5
|
+
before(:each) do
|
|
6
|
+
@request = Typhoeus::Request.new('http://www.google.com/',
|
|
7
|
+
:body => "a=1&b=2",
|
|
8
|
+
:params => { :c => 'ok' },
|
|
9
|
+
:method => :get,
|
|
10
|
+
:headers => { 'Content-Type' => 'text/html' })
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should dump out the URI" do
|
|
14
|
+
@request.inspect.should =~ /http:\/\/www\.google\.com/
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it "should dump out the body" do
|
|
18
|
+
@request.inspect.should =~ /a=1&b=2/
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "should dump params" do
|
|
22
|
+
@request.inspect.should =~ /:c\s*=>\s*"ok"/
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it "should dump the method" do
|
|
26
|
+
@request.inspect.should =~ /:get/
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it "should dump out headers" do
|
|
30
|
+
@request.inspect.should =~ /"Content-Type"\s*=>\s*"text\/html"/
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "#localhost?" do
|
|
35
|
+
%w(localhost 127.0.0.1 0.0.0.0).each do |host|
|
|
36
|
+
it "should be true for the #{host} host" do
|
|
37
|
+
req = Typhoeus::Request.new("http://#{host}")
|
|
38
|
+
req.should be_localhost
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "should be false for other domains" do
|
|
43
|
+
req = Typhoeus::Request.new("http://google.com")
|
|
44
|
+
req.should_not be_localhost
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe "#params_string" do
|
|
49
|
+
it "should dump a sorted string" do
|
|
50
|
+
request = Typhoeus::Request.new(
|
|
51
|
+
"http://google.com",
|
|
52
|
+
:params => {
|
|
53
|
+
'b' => 'fdsa',
|
|
54
|
+
'a' => 'jlk',
|
|
55
|
+
'c' => '789'
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
request.params_string.should == "a=jlk&b=fdsa&c=789"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "should accept symboled keys" do
|
|
63
|
+
request = Typhoeus::Request.new('http://google.com',
|
|
64
|
+
:params => {
|
|
65
|
+
:b => 'fdsa',
|
|
66
|
+
:a => 'jlk',
|
|
67
|
+
:c => '789'
|
|
68
|
+
})
|
|
69
|
+
request.params_string.should == "a=jlk&b=fdsa&c=789"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should translate params with values that are arrays to the proper format" do
|
|
73
|
+
request = Typhoeus::Request.new('http://google.com',
|
|
74
|
+
:params => {
|
|
75
|
+
:a => ['789','2434']
|
|
76
|
+
})
|
|
77
|
+
request.params_string.should == "a[]=789&a[]=2434"
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
describe "quick request methods" do
|
|
82
|
+
it "can run a GET synchronously" do
|
|
83
|
+
response = Typhoeus::Request.get("http://localhost:3000", :params => {:q => "hi"}, :headers => {:foo => "bar"})
|
|
84
|
+
response.code.should == 200
|
|
85
|
+
JSON.parse(response.body)["REQUEST_METHOD"].should == "GET"
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
it "can run a POST synchronously" do
|
|
89
|
+
response = Typhoeus::Request.post("http://localhost:3000", :params => {:q => "hi"}, :headers => {:foo => "bar"})
|
|
90
|
+
response.code.should == 200
|
|
91
|
+
json = JSON.parse(response.body)
|
|
92
|
+
json["REQUEST_METHOD"].should == "POST"
|
|
93
|
+
json["rack.request.query_hash"]["q"].should == "hi"
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "can run a PUT synchronously" do
|
|
97
|
+
response = Typhoeus::Request.put("http://localhost:3000", :params => {:q => "hi"}, :headers => {:foo => "bar"})
|
|
98
|
+
response.code.should == 200
|
|
99
|
+
JSON.parse(response.body)["REQUEST_METHOD"].should == "PUT"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "can run a DELETE synchronously" do
|
|
103
|
+
response = Typhoeus::Request.delete("http://localhost:3000", :params => {:q => "hi"}, :headers => {:foo => "bar"})
|
|
104
|
+
response.code.should == 200
|
|
105
|
+
JSON.parse(response.body)["REQUEST_METHOD"].should == "DELETE"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it "takes url as the first argument" do
|
|
110
|
+
Typhoeus::Request.new("http://localhost:3000").url.should == "http://localhost:3000"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
it "should parse the host from the url" do
|
|
114
|
+
Typhoeus::Request.new("http://localhost:3000/whatever?hi=foo").host.should == "http://localhost:3000"
|
|
115
|
+
Typhoeus::Request.new("http://localhost:3000?hi=foo").host.should == "http://localhost:3000"
|
|
116
|
+
Typhoeus::Request.new("http://localhost:3000").host.should == "http://localhost:3000"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "takes method as an option" do
|
|
120
|
+
Typhoeus::Request.new("http://localhost:3000", :method => :get).method.should == :get
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "takes headers as an option" do
|
|
124
|
+
headers = {:foo => :bar}
|
|
125
|
+
request = Typhoeus::Request.new("http://localhost:3000", :headers => headers)
|
|
126
|
+
request.headers.should == headers
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
it "takes params as an option and adds them to the url" do
|
|
130
|
+
Typhoeus::Request.new("http://localhost:3000", :params => {:foo => "bar"}).url.should == "http://localhost:3000?foo=bar"
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "takes request body as an option" do
|
|
134
|
+
Typhoeus::Request.new("http://localhost:3000", :body => "whatever").body.should == "whatever"
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "takes timeout as an option" do
|
|
138
|
+
Typhoeus::Request.new("http://localhost:3000", :timeout => 10).timeout.should == 10
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
it "takes cache_timeout as an option" do
|
|
142
|
+
Typhoeus::Request.new("http://localhost:3000", :cache_timeout => 60).cache_timeout.should == 60
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
it "takes follow_location as an option" do
|
|
146
|
+
Typhoeus::Request.new("http://localhost:3000", :follow_location => true).follow_location.should == true
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "takes max_redirects as an option" do
|
|
150
|
+
Typhoeus::Request.new("http://localhost:3000", :max_redirects => 10).max_redirects.should == 10
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "has the associated response object" do
|
|
154
|
+
request = Typhoeus::Request.new("http://localhost:3000")
|
|
155
|
+
request.response = :foo
|
|
156
|
+
request.response.should == :foo
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "has an on_complete handler that is called when the request is completed" do
|
|
160
|
+
request = Typhoeus::Request.new("http://localhost:3000")
|
|
161
|
+
foo = nil
|
|
162
|
+
request.on_complete do |response|
|
|
163
|
+
foo = response
|
|
164
|
+
end
|
|
165
|
+
request.response = :bar
|
|
166
|
+
request.call_handlers
|
|
167
|
+
foo.should == :bar
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "has an on_complete setter" do
|
|
171
|
+
foo = nil
|
|
172
|
+
proc = Proc.new {|response| foo = response}
|
|
173
|
+
request = Typhoeus::Request.new("http://localhost:3000")
|
|
174
|
+
request.on_complete = proc
|
|
175
|
+
request.response = :bar
|
|
176
|
+
request.call_handlers
|
|
177
|
+
foo.should == :bar
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
it "stores the handled response that is the return value from the on_complete block" do
|
|
181
|
+
request = Typhoeus::Request.new("http://localhost:3000")
|
|
182
|
+
request.on_complete do |response|
|
|
183
|
+
"handled"
|
|
184
|
+
end
|
|
185
|
+
request.response = :bar
|
|
186
|
+
request.call_handlers
|
|
187
|
+
request.handled_response.should == "handled"
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
it "has an after_complete handler that recieves what on_complete returns" do
|
|
191
|
+
request = Typhoeus::Request.new("http://localhost:3000")
|
|
192
|
+
request.on_complete do |response|
|
|
193
|
+
"handled"
|
|
194
|
+
end
|
|
195
|
+
good = nil
|
|
196
|
+
request.after_complete do |object|
|
|
197
|
+
good = object == "handled"
|
|
198
|
+
end
|
|
199
|
+
request.call_handlers
|
|
200
|
+
good.should be_true
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
it "has an after_complete setter" do
|
|
204
|
+
request = Typhoeus::Request.new("http://localhost:3000")
|
|
205
|
+
request.on_complete do |response|
|
|
206
|
+
"handled"
|
|
207
|
+
end
|
|
208
|
+
good = nil
|
|
209
|
+
proc = Proc.new {|object| good = object == "handled"}
|
|
210
|
+
request.after_complete = proc
|
|
211
|
+
|
|
212
|
+
request.call_handlers
|
|
213
|
+
good.should be_true
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
describe "authentication" do
|
|
217
|
+
|
|
218
|
+
it "should allow to set username and password" do
|
|
219
|
+
auth = { :username => 'foo', :password => 'bar' }
|
|
220
|
+
e = Typhoeus::Request.get(
|
|
221
|
+
"http://localhost:3001/auth_basic/#{auth[:username]}/#{auth[:password]}",
|
|
222
|
+
auth
|
|
223
|
+
)
|
|
224
|
+
e.code.should == 200
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
it "should allow to set authentication method" do
|
|
228
|
+
auth = {
|
|
229
|
+
:username => 'username',
|
|
230
|
+
:password => 'password',
|
|
231
|
+
:auth_method => :ntlm
|
|
232
|
+
}
|
|
233
|
+
e = Typhoeus::Request.get(
|
|
234
|
+
"http://localhost:3001/auth_ntlm",
|
|
235
|
+
auth
|
|
236
|
+
)
|
|
237
|
+
e.code.should == 200
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
describe "retry" do
|
|
243
|
+
it "should take a retry option"
|
|
244
|
+
it "should count the number of times a request has failed"
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
end
|
|
@@ -2,9 +2,35 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe Typhoeus::Response do
|
|
4
4
|
describe "initialize" do
|
|
5
|
+
it "should store headers_hash" do
|
|
6
|
+
response = Typhoeus::Response.new(:headers_hash => {})
|
|
7
|
+
response.headers_hash.should == {}
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "allows header access using a different casing of the header key" do
|
|
11
|
+
response = Typhoeus::Response.new(:headers_hash => { 'content-type' => 'text/html' } )
|
|
12
|
+
response.headers_hash['Content-Type'].should == 'text/html'
|
|
13
|
+
end
|
|
14
|
+
|
|
5
15
|
it "should store response_code" do
|
|
6
16
|
Typhoeus::Response.new(:code => 200).code.should == 200
|
|
7
17
|
end
|
|
18
|
+
|
|
19
|
+
it "should store status_message" do
|
|
20
|
+
Typhoeus::Response.new(:status_message => 'Not Found').status_message.should == 'Not Found'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it "should return nil for status_message if none is given and no header is given" do
|
|
24
|
+
Typhoeus::Response.new.status_message.should be_nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it "should store http_version" do
|
|
28
|
+
Typhoeus::Response.new(:http_version => '1.1').http_version.should == '1.1'
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it "should return nil for http version if none is given and no header is given" do
|
|
32
|
+
Typhoeus::Response.new.http_version.should be_nil
|
|
33
|
+
end
|
|
8
34
|
|
|
9
35
|
it "should store response_headers" do
|
|
10
36
|
Typhoeus::Response.new(:headers => "a header!").headers.should == "a header!"
|
|
@@ -27,10 +53,87 @@ describe Typhoeus::Response do
|
|
|
27
53
|
response = Typhoeus::Response.new(:requested_http_method => :delete)
|
|
28
54
|
response.requested_http_method.should == :delete
|
|
29
55
|
end
|
|
30
|
-
|
|
56
|
+
|
|
31
57
|
it "should store an associated request object" do
|
|
32
58
|
response = Typhoeus::Response.new(:request => "whatever")
|
|
33
59
|
response.request.should == "whatever"
|
|
34
60
|
end
|
|
61
|
+
|
|
62
|
+
it "should not default to be a mock response" do
|
|
63
|
+
response = Typhoeus::Response.new
|
|
64
|
+
response.should_not be_mock
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe "#mock?" do
|
|
69
|
+
it "should be true if it's a mock response" do
|
|
70
|
+
response = Typhoeus::Response.new(:mock => true)
|
|
71
|
+
response.should be_mock
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
describe "headers" do
|
|
76
|
+
it 'should return an empty hash from #headers_hash when no headers string is given' do
|
|
77
|
+
response = Typhoeus::Response.new.headers_hash.should == {}
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe "basic parsing" do
|
|
81
|
+
before(:all) do
|
|
82
|
+
@response = Typhoeus::Response.new(:headers => "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nConnection: close\r\nStatus: 200\r\nX-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9\r\nX-Cache: miss\r\nX-Runtime: 184\r\nETag: e001d08d9354ab7bc7c27a00163a3afa\r\nCache-Control: private, max-age=0, must-revalidate\r\nContent-Length: 4725\r\nSet-Cookie: _some_session=BAh7CDoGciIAOg9zZXNzaW9uX2lkIiU1OTQ2OTcwMjljMWM5ZTQwODU1NjQwYTViMmQxMTkxMjoGcyIKL2NhcnQ%3D--b4c4663932243090c961bb93d4ad5e4327064730; path=/; HttpOnly\r\nServer: nginx/0.6.37 + Phusion Passenger 2.2.4 (mod_rails/mod_rack)\r\nSet-Cookie: foo=bar; path=/;\r\nP3P: CP=\"NOI DSP COR NID ADMa OPTa OUR NOR\"\r\n\r\n")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it "can be accessed with lowercase keys" do
|
|
86
|
+
@response.headers_hash['content-type'].should == 'text/html; charset=utf-8'
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it "can parse the headers into a hash" do
|
|
90
|
+
@response.headers_hash["Status"].should == "200"
|
|
91
|
+
@response.headers_hash["Set-Cookie"].should == ["_some_session=BAh7CDoGciIAOg9zZXNzaW9uX2lkIiU1OTQ2OTcwMjljMWM5ZTQwODU1NjQwYTViMmQxMTkxMjoGcyIKL2NhcnQ%3D--b4c4663932243090c961bb93d4ad5e4327064730; path=/; HttpOnly", "foo=bar; path=/;"]
|
|
92
|
+
@response.headers_hash["Content-Type"].should == "text/html; charset=utf-8"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it 'parses the status message' do
|
|
96
|
+
@response.status_message.should == 'OK'
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
it 'parses the HTTP version' do
|
|
100
|
+
@response.http_version.should == '1.1'
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it 'parses all header keys except HTTP version declaration' do
|
|
104
|
+
@response.headers_hash.keys.should =~ %w[
|
|
105
|
+
X-Powered-By
|
|
106
|
+
P3p
|
|
107
|
+
X-Cache
|
|
108
|
+
Etag
|
|
109
|
+
X-Runtime
|
|
110
|
+
Content-Type
|
|
111
|
+
Content-Length
|
|
112
|
+
Server
|
|
113
|
+
Set-Cookie
|
|
114
|
+
Cache-Control
|
|
115
|
+
Connection
|
|
116
|
+
Status
|
|
117
|
+
]
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "parses a header key that appears multiple times into an array" do
|
|
122
|
+
response = Typhoeus::Response.new(:headers => "HTTP/1.1 302 Found\r\nContent-Type: text/html; charset=utf-8\r\nConnection: close\r\nStatus: 302\r\nX-Powered-By: Phusion Passenger (mod_rails/mod_rack) 2.2.9\r\nLocation: http://mckenzie-greenholt1512.myshopify.com/cart\r\nX-Runtime: 22\r\nCache-Control: no-cache\r\nContent-Length: 114\r\nSet-Cookie: cart=8fdd6a828d9c89a737a52668be0cebaf; path=/; expires=Fri, 12-Mar-2010 18:30:19 GMT\r\nSet-Cookie: _session=BAh7CToPc2Vzc2lvbl9pZCIlZTQzMDQzMDg1YjI3MTQ4MzAzMTZmMWZmMWJjMTU1NmI6CWNhcnQiJThmZGQ2YTgyOGQ5Yzg5YTczN2E1MjY2OGJlMGNlYmFmOgZyIgA6BnMiDi9jYXJ0L2FkZA%3D%3D--6b0a699625caed9597580d8e9b6ca5f5e5954125; path=/; HttpOnly\r\nServer: nginx/0.6.37 + Phusion Passenger 2.2.4 (mod_rails/mod_rack)\r\nP3P: CP=\"NOI DSP COR NID ADMa OPTa OUR NOR\"\r\n\r\n")
|
|
123
|
+
response.headers_hash["Set-Cookie"].should include("cart=8fdd6a828d9c89a737a52668be0cebaf; path=/; expires=Fri, 12-Mar-2010 18:30:19 GMT")
|
|
124
|
+
response.headers_hash["Set-Cookie"].should include("_session=BAh7CToPc2Vzc2lvbl9pZCIlZTQzMDQzMDg1YjI3MTQ4MzAzMTZmMWZmMWJjMTU1NmI6CWNhcnQiJThmZGQ2YTgyOGQ5Yzg5YTczN2E1MjY2OGJlMGNlYmFmOgZyIgA6BnMiDi9jYXJ0L2FkZA%3D%3D--6b0a699625caed9597580d8e9b6ca5f5e5954125; path=/; HttpOnly")
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
describe "status checking" do
|
|
129
|
+
it "is successful if response code is 200-299" do
|
|
130
|
+
Typhoeus::Response.new(:code => 220).success?.should be
|
|
131
|
+
Typhoeus::Response.new(:code => 400).success?.should_not be
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
it "is not modified if the status code is 304" do
|
|
135
|
+
Typhoeus::Response.new(:code => 304).modified?.should_not be
|
|
136
|
+
Typhoeus::Response.new(:code => 200).modified?.should be
|
|
137
|
+
end
|
|
35
138
|
end
|
|
36
139
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Typhoeus::Utils do
|
|
4
|
+
# Taken from Rack 1.2.1
|
|
5
|
+
describe "#escape" do
|
|
6
|
+
it "should escape correctly" do
|
|
7
|
+
Typhoeus::Utils.escape("fo<o>bar").should == "fo%3Co%3Ebar"
|
|
8
|
+
Typhoeus::Utils.escape("a space").should == "a+space"
|
|
9
|
+
Typhoeus::Utils.escape("q1!2\"'w$5&7/z8)?\\").
|
|
10
|
+
should == "q1%212%22%27w%245%267%2Fz8%29%3F%5C"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "should escape correctly for multibyte characters" do
|
|
14
|
+
matz_name = "\xE3\x81\xBE\xE3\x81\xA4\xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsumoto
|
|
15
|
+
matz_name.force_encoding("UTF-8") if matz_name.respond_to? :force_encoding
|
|
16
|
+
Typhoeus::Utils.escape(matz_name).should == '%E3%81%BE%E3%81%A4%E3%82%82%E3%81%A8'
|
|
17
|
+
matz_name_sep = "\xE3\x81\xBE\xE3\x81\xA4 \xE3\x82\x82\xE3\x81\xA8".unpack("a*")[0] # Matsu moto
|
|
18
|
+
matz_name_sep.force_encoding("UTF-8") if matz_name_sep.respond_to? :force_encoding
|
|
19
|
+
Typhoeus::Utils.escape(matz_name_sep).should == '%E3%81%BE%E3%81%A4+%E3%82%82%E3%81%A8'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
data/typhoeus.gemspec
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Generated by jeweler
|
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
|
4
|
+
# -*- encoding: utf-8 -*-
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |s|
|
|
7
|
+
s.name = %q{typhoeus}
|
|
8
|
+
s.version = "0.2.0"
|
|
9
|
+
|
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
+
s.authors = ["Paul Dix"]
|
|
12
|
+
s.date = %q{2010-11-11}
|
|
13
|
+
s.description = %q{Like a modern code version of the mythical beast with 100 serpent heads, Typhoeus runs HTTP requests in parallel while cleanly encapsulating handling logic.}
|
|
14
|
+
s.email = %q{paul@pauldix.net}
|
|
15
|
+
s.extensions = ["ext/typhoeus/extconf.rb"]
|
|
16
|
+
s.extra_rdoc_files = [
|
|
17
|
+
"README.textile"
|
|
18
|
+
]
|
|
19
|
+
s.files = [
|
|
20
|
+
".gitignore",
|
|
21
|
+
"CHANGELOG.markdown",
|
|
22
|
+
"Gemfile",
|
|
23
|
+
"Gemfile.lock",
|
|
24
|
+
"README.textile",
|
|
25
|
+
"Rakefile",
|
|
26
|
+
"VERSION",
|
|
27
|
+
"benchmarks/profile.rb",
|
|
28
|
+
"benchmarks/vs_nethttp.rb",
|
|
29
|
+
"examples/twitter.rb",
|
|
30
|
+
"ext/typhoeus/.gitignore",
|
|
31
|
+
"ext/typhoeus/extconf.rb",
|
|
32
|
+
"ext/typhoeus/native.c",
|
|
33
|
+
"ext/typhoeus/native.h",
|
|
34
|
+
"ext/typhoeus/typhoeus_easy.c",
|
|
35
|
+
"ext/typhoeus/typhoeus_easy.h",
|
|
36
|
+
"ext/typhoeus/typhoeus_multi.c",
|
|
37
|
+
"ext/typhoeus/typhoeus_multi.h",
|
|
38
|
+
"lib/typhoeus.rb",
|
|
39
|
+
"lib/typhoeus/.gitignore",
|
|
40
|
+
"lib/typhoeus/easy.rb",
|
|
41
|
+
"lib/typhoeus/filter.rb",
|
|
42
|
+
"lib/typhoeus/hydra.rb",
|
|
43
|
+
"lib/typhoeus/hydra/callbacks.rb",
|
|
44
|
+
"lib/typhoeus/hydra/connect_options.rb",
|
|
45
|
+
"lib/typhoeus/hydra/stubbing.rb",
|
|
46
|
+
"lib/typhoeus/hydra_mock.rb",
|
|
47
|
+
"lib/typhoeus/multi.rb",
|
|
48
|
+
"lib/typhoeus/normalized_header_hash.rb",
|
|
49
|
+
"lib/typhoeus/remote.rb",
|
|
50
|
+
"lib/typhoeus/remote_method.rb",
|
|
51
|
+
"lib/typhoeus/remote_proxy_object.rb",
|
|
52
|
+
"lib/typhoeus/request.rb",
|
|
53
|
+
"lib/typhoeus/response.rb",
|
|
54
|
+
"lib/typhoeus/service.rb",
|
|
55
|
+
"lib/typhoeus/utils.rb",
|
|
56
|
+
"profilers/valgrind.rb",
|
|
57
|
+
"spec/fixtures/result_set.xml",
|
|
58
|
+
"spec/servers/app.rb",
|
|
59
|
+
"spec/spec.opts",
|
|
60
|
+
"spec/spec_helper.rb",
|
|
61
|
+
"spec/typhoeus/easy_spec.rb",
|
|
62
|
+
"spec/typhoeus/filter_spec.rb",
|
|
63
|
+
"spec/typhoeus/hydra_mock_spec.rb",
|
|
64
|
+
"spec/typhoeus/hydra_spec.rb",
|
|
65
|
+
"spec/typhoeus/multi_spec.rb",
|
|
66
|
+
"spec/typhoeus/normalized_header_hash_spec.rb",
|
|
67
|
+
"spec/typhoeus/remote_method_spec.rb",
|
|
68
|
+
"spec/typhoeus/remote_proxy_object_spec.rb",
|
|
69
|
+
"spec/typhoeus/remote_spec.rb",
|
|
70
|
+
"spec/typhoeus/request_spec.rb",
|
|
71
|
+
"spec/typhoeus/response_spec.rb",
|
|
72
|
+
"spec/typhoeus/utils_spec.rb",
|
|
73
|
+
"typhoeus.gemspec"
|
|
74
|
+
]
|
|
75
|
+
s.homepage = %q{http://github.com/pauldix/typhoeus}
|
|
76
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
|
77
|
+
s.require_paths = ["lib"]
|
|
78
|
+
s.rubygems_version = %q{1.3.7}
|
|
79
|
+
s.summary = %q{A library for interacting with web services (and building SOAs) at blinding speed.}
|
|
80
|
+
s.test_files = [
|
|
81
|
+
"spec/servers/app.rb",
|
|
82
|
+
"spec/spec_helper.rb",
|
|
83
|
+
"spec/typhoeus/easy_spec.rb",
|
|
84
|
+
"spec/typhoeus/filter_spec.rb",
|
|
85
|
+
"spec/typhoeus/hydra_mock_spec.rb",
|
|
86
|
+
"spec/typhoeus/hydra_spec.rb",
|
|
87
|
+
"spec/typhoeus/multi_spec.rb",
|
|
88
|
+
"spec/typhoeus/normalized_header_hash_spec.rb",
|
|
89
|
+
"spec/typhoeus/remote_method_spec.rb",
|
|
90
|
+
"spec/typhoeus/remote_proxy_object_spec.rb",
|
|
91
|
+
"spec/typhoeus/remote_spec.rb",
|
|
92
|
+
"spec/typhoeus/request_spec.rb",
|
|
93
|
+
"spec/typhoeus/response_spec.rb",
|
|
94
|
+
"spec/typhoeus/utils_spec.rb",
|
|
95
|
+
"examples/twitter.rb"
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
if s.respond_to? :specification_version then
|
|
99
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
100
|
+
s.specification_version = 3
|
|
101
|
+
|
|
102
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
103
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
|
104
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
|
105
|
+
s.add_development_dependency(%q<diff-lcs>, [">= 0"])
|
|
106
|
+
s.add_development_dependency(%q<sinatra>, [">= 0"])
|
|
107
|
+
s.add_development_dependency(%q<json>, [">= 0"])
|
|
108
|
+
else
|
|
109
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
|
110
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
111
|
+
s.add_dependency(%q<diff-lcs>, [">= 0"])
|
|
112
|
+
s.add_dependency(%q<sinatra>, [">= 0"])
|
|
113
|
+
s.add_dependency(%q<json>, [">= 0"])
|
|
114
|
+
end
|
|
115
|
+
else
|
|
116
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
|
117
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
|
118
|
+
s.add_dependency(%q<diff-lcs>, [">= 0"])
|
|
119
|
+
s.add_dependency(%q<sinatra>, [">= 0"])
|
|
120
|
+
s.add_dependency(%q<json>, [">= 0"])
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|