typhoeus 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{CHANGELOG.markdown → CHANGELOG.md} +21 -12
- data/LICENSE +2 -0
- data/README.md +455 -0
- data/Rakefile +6 -26
- data/lib/typhoeus.rb +4 -6
- data/lib/typhoeus/curl.rb +453 -0
- data/lib/typhoeus/easy.rb +60 -358
- data/lib/typhoeus/easy/auth.rb +14 -0
- data/lib/typhoeus/easy/callbacks.rb +33 -0
- data/lib/typhoeus/easy/ffi_helper.rb +61 -0
- data/lib/typhoeus/easy/infos.rb +90 -0
- data/lib/typhoeus/easy/options.rb +115 -0
- data/lib/typhoeus/easy/proxy.rb +20 -0
- data/lib/typhoeus/easy/ssl.rb +82 -0
- data/lib/typhoeus/form.rb +30 -1
- data/lib/typhoeus/{normalized_header_hash.rb → header.rb} +2 -6
- data/lib/typhoeus/hydra.rb +9 -12
- data/lib/typhoeus/hydra_mock.rb +2 -2
- data/lib/typhoeus/multi.rb +118 -9
- data/lib/typhoeus/param_processor.rb +43 -0
- data/lib/typhoeus/request.rb +18 -21
- data/lib/typhoeus/response.rb +5 -4
- data/lib/typhoeus/utils.rb +14 -27
- data/lib/typhoeus/version.rb +1 -1
- metadata +155 -152
- data/Gemfile.lock +0 -37
- data/ext/typhoeus/.gitignore +0 -7
- data/ext/typhoeus/extconf.rb +0 -65
- data/ext/typhoeus/native.c +0 -12
- data/ext/typhoeus/native.h +0 -22
- data/ext/typhoeus/typhoeus_easy.c +0 -232
- data/ext/typhoeus/typhoeus_easy.h +0 -20
- data/ext/typhoeus/typhoeus_form.c +0 -59
- data/ext/typhoeus/typhoeus_form.h +0 -13
- data/ext/typhoeus/typhoeus_multi.c +0 -217
- data/ext/typhoeus/typhoeus_multi.h +0 -16
- data/lib/typhoeus/.gitignore +0 -1
- data/lib/typhoeus/service.rb +0 -20
- data/spec/fixtures/placeholder.gif +0 -0
- data/spec/fixtures/placeholder.txt +0 -1
- data/spec/fixtures/placeholder.ukn +0 -0
- data/spec/fixtures/result_set.xml +0 -60
- data/spec/servers/app.rb +0 -97
- data/spec/spec_helper.rb +0 -19
- data/spec/support/typhoeus_localhost_server.rb +0 -58
- data/spec/typhoeus/easy_spec.rb +0 -391
- data/spec/typhoeus/filter_spec.rb +0 -35
- data/spec/typhoeus/form_spec.rb +0 -117
- data/spec/typhoeus/hydra_mock_spec.rb +0 -300
- data/spec/typhoeus/hydra_spec.rb +0 -602
- data/spec/typhoeus/multi_spec.rb +0 -74
- data/spec/typhoeus/normalized_header_hash_spec.rb +0 -41
- data/spec/typhoeus/remote_method_spec.rb +0 -141
- data/spec/typhoeus/remote_proxy_object_spec.rb +0 -65
- data/spec/typhoeus/remote_spec.rb +0 -695
- data/spec/typhoeus/request_spec.rb +0 -387
- data/spec/typhoeus/response_spec.rb +0 -192
- data/spec/typhoeus/utils_spec.rb +0 -22
- data/typhoeus.gemspec +0 -33
@@ -1,5 +1,14 @@
|
|
1
|
+
0.4.0
|
2
|
+
-----
|
3
|
+
* Make a GET even when a body is given
|
4
|
+
* Deprecated User Agent setter removed
|
5
|
+
* Allow cache key basis overwrite (John Crepezzi, #147)
|
6
|
+
* FFI integration (Daniel Cavanagh, #151)
|
7
|
+
* Refactor upload code (Marnen Laibow-Koser, #152)
|
8
|
+
* Fix travis-ci build (Ezekiel Templin, #160)
|
9
|
+
|
1
10
|
0.3.3
|
2
|
-
|
11
|
+
-----
|
3
12
|
* Make sure to call the Easy::failure callback on all non-success http response codes, even invalid ones. [balexis]
|
4
13
|
* Use bytesize instead of length to determine Content-Length [dlamacchia]
|
5
14
|
* Added SSL version option to Easy/Request [michelbarbosa/dbalatero]
|
@@ -7,24 +16,24 @@
|
|
7
16
|
0.3.2
|
8
17
|
-----
|
9
18
|
* Fix array params to be consistent with HTTP spec [gridaphobe]
|
10
|
-
*
|
19
|
+
* traversal\_to\_params\_hash should use the escape option [itsmeduncan]
|
11
20
|
* Fix > 1024 open file descriptors [mschulkind]
|
12
21
|
* Fixed a bug with internally queued requests being dropped [mschulkind]
|
13
22
|
* Use gemspec in bundler to avoid duplication [mschulkind]
|
14
23
|
* Run internally queued requests in FIFO order [mschulkind]
|
15
|
-
* Moved Typhoeus::VERSION to a separate file, to fix rake
|
24
|
+
* Moved Typhoeus::VERSION to a separate file, to fix rake build\_native [mschulkind]
|
16
25
|
* Fixed problems related to put requests with empty bodies [skaes, GH-84]
|
17
|
-
* Added
|
26
|
+
* Added CURLOPT\_INTERFACE option via Request#interface=. [spiegela]
|
18
27
|
* Added Tempfile support to Form#process! [richievos]
|
19
28
|
* Hydra won't forget to accept gzip/deflate encoding [codesnik]
|
20
|
-
* Accept and convert strings to integers in Typhoeus::Request#initialize for timeout/
|
29
|
+
* Accept and convert strings to integers in Typhoeus::Request#initialize for timeout/cache\_timeout/connect\_timeout values when using ruby 1.9.x. [djnawara]
|
21
30
|
* Added interface for registering stub finders [myronmarston]
|
22
31
|
* Fixed header stubbing [myronmarston]
|
23
32
|
* Added PKCS12 support [jodell]
|
24
33
|
* Make a request with handlers marshallable [bernerdschaefer]
|
25
34
|
* Upgraded to RSpec 2 [bernerdschaefer]
|
26
35
|
* Fix HTTP status edge-case [balexis]
|
27
|
-
* Expose
|
36
|
+
* Expose primary\_ip to easy object [balexis]
|
28
37
|
|
29
38
|
0.2.4
|
30
39
|
-----
|
@@ -42,18 +51,18 @@
|
|
42
51
|
-----
|
43
52
|
* Added extended proxy support [Zapotek, GH-46]
|
44
53
|
* eliminated compile time warnings by using proper type declarations [skaes, GH-54]
|
45
|
-
* fixed broken calls to
|
54
|
+
* fixed broken calls to rb\_raise [skaes, GH-54]
|
46
55
|
* prevent leaking of curl easy handles when exceptions are raised (either from typhoeus itself or user callbacks) [skaes, GH-54]
|
47
|
-
* fixed Easy#
|
56
|
+
* fixed Easy#timed\_out? using curl return codes [skaes, GH-54]
|
48
57
|
* provide curl return codes and corresponding curl error messages on classes Easy and Request [skaes, GH-54]
|
49
58
|
* allow VCR to whitelist hosts in Typhoeus stubbing/mocking [myronmarston, GH-57]
|
50
|
-
* added
|
59
|
+
* added timed\_out? documentation, method to Response [dbalatero, GH-34]
|
51
60
|
* added abort to Hydra to prematurely stop a hydra.run [Zapotek]
|
52
61
|
* added file upload support for POST requests [jtarchie, GH-59]
|
53
62
|
|
54
63
|
0.2.0
|
55
64
|
------
|
56
|
-
* Fix warning in Request#headers from
|
65
|
+
* Fix warning in Request#headers from attr\_accessor
|
57
66
|
* Params with array values were not parsing into the format that rack expects
|
58
67
|
[GH-39, smartocci]
|
59
68
|
* Removed Rack as a dependency [GH-45]
|
@@ -66,11 +75,11 @@
|
|
66
75
|
|
67
76
|
0.1.30
|
68
77
|
-----------
|
69
|
-
* Exposed
|
78
|
+
* Exposed CURLOPT\_CONNECTTIMEOUT\_MS to Requests [balexis]
|
70
79
|
|
71
80
|
0.1.29
|
72
81
|
------
|
73
|
-
* Fixed a memory corruption with using
|
82
|
+
* Fixed a memory corruption with using CURLOPT\_POSTFIELDS [gravis,
|
74
83
|
32531d0821aecc4]
|
75
84
|
|
76
85
|
0.1.28
|
data/LICENSE
CHANGED
data/README.md
ADDED
@@ -0,0 +1,455 @@
|
|
1
|
+
# Typhoeus [![Build Status](https://secure.travis-ci.org/typhoeus/typhoeus.png?branch=master)](http://travis-ci.org/typhoeus/typhoeus)
|
2
|
+
|
3
|
+
[the mailing list](http://groups.google.com/group/typhoeus)
|
4
|
+
|
5
|
+
## Summary
|
6
|
+
|
7
|
+
Like a modern code version of the mythical beast with 100 serpent heads,
|
8
|
+
Typhoeus runs HTTP requests in parallel while cleanly encapsulating handling
|
9
|
+
logic. To be a little more specific, it’s a library for accessing web services
|
10
|
+
in Ruby. It’s specifically designed for building RESTful service oriented
|
11
|
+
architectures in Ruby that need to be fast enough to process calls to multiple
|
12
|
+
services within the client’s HTTP request/response life cycle.
|
13
|
+
|
14
|
+
Some of the awesome features are parallel request execution, memoization of
|
15
|
+
request responses (so you don’t make the same request multiple times in a
|
16
|
+
single group), built in support for caching responses to memcached (or
|
17
|
+
whatever), and mocking capability baked in. It uses libcurl and libcurl-multi
|
18
|
+
to work this speedy magic. I wrote the bindings myself so it’s yet another
|
19
|
+
Ruby libcurl library, but with some extra awesomeness added in. FFI is used to
|
20
|
+
interface with the library so it works with any Ruby implementation.
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Typhoeus requires you to have a current version of libcurl installed. The
|
25
|
+
easiest solution is to use your system’s package manager to install it. If
|
26
|
+
that doesn’t work, you can grab a package off of [the curl
|
27
|
+
website](http://curl.haxx.se/download.html) and manually install it following
|
28
|
+
the instructions given there. Typhoeus will work with version 7.19.4 or higher
|
29
|
+
(earlier versions might work but no guarantees are provided).
|
30
|
+
|
31
|
+
To install Typhoeus, simply run:
|
32
|
+
|
33
|
+
gem install typhoeus
|
34
|
+
|
35
|
+
If you’re on Debian or Ubuntu and getting errors while trying to install, it
|
36
|
+
could be because you don’t have the latest version of libcurl installed. Do
|
37
|
+
this to fix:
|
38
|
+
|
39
|
+
sudo apt-get install libcurl4-gnutls-dev
|
40
|
+
|
41
|
+
If you’re still having issues, please let me know on [the mailing
|
42
|
+
list](http://groups.google.com/group/typhoeus).
|
43
|
+
|
44
|
+
There’s one other thing you should know. The Easy object (which is just a
|
45
|
+
libcurl thing) allows you to set timeout values in milliseconds. However, for
|
46
|
+
this to work you need to build libcurl with c-ares support built in.
|
47
|
+
|
48
|
+
## Windows Support
|
49
|
+
|
50
|
+
Typhoeus runs perfectly on Windows. The tricky part is knowing how to install
|
51
|
+
libcurl in the absence of a package manager.
|
52
|
+
|
53
|
+
To install libcurl, simply grab [the latest libcurl
|
54
|
+
package](http://curl.haxx.se/download.html#Win32) off of the curl website,
|
55
|
+
extract the bin directory, and then add the path to the bin directory into the
|
56
|
+
PATH environment variable. Ruby with then be able to find libcurl properly and
|
57
|
+
everything will just work.
|
58
|
+
|
59
|
+
## Usage
|
60
|
+
|
61
|
+
The primary interface for Typhoeus is comprised of three classes: Request,
|
62
|
+
Response, and Hydra. Request represents an HTTP request object, response
|
63
|
+
represents an HTTP response, and Hydra manages making parallel HTTP
|
64
|
+
connections.
|
65
|
+
|
66
|
+
require 'rubygems'
|
67
|
+
require 'typhoeus'
|
68
|
+
require 'json'
|
69
|
+
|
70
|
+
# the request object
|
71
|
+
request = Typhoeus::Request.new("http://www.pauldix.net",
|
72
|
+
:body => "this is a request body",
|
73
|
+
:method => :post,
|
74
|
+
:headers => {:Accept => "text/html"},
|
75
|
+
:timeout => 100, # milliseconds
|
76
|
+
:cache_timeout => 60, # seconds
|
77
|
+
:params => {:field1 => "a field"})
|
78
|
+
# we can see from this that the first argument is the url. the second is a set of options.
|
79
|
+
# the options are all optional. The default for :method is :get. Timeout is measured in milliseconds.
|
80
|
+
# cache_timeout is measured in seconds.
|
81
|
+
|
82
|
+
# Run the request via Hydra.
|
83
|
+
hydra = Typhoeus::Hydra.new
|
84
|
+
hydra.queue(request)
|
85
|
+
hydra.run
|
86
|
+
|
87
|
+
# the response object will be set after the request is run
|
88
|
+
response = request.response
|
89
|
+
response.code # http status code
|
90
|
+
response.time # time in seconds the request took
|
91
|
+
response.headers # the http headers
|
92
|
+
response.headers_hash # http headers put into a hash
|
93
|
+
response.body # the response body
|
94
|
+
|
95
|
+
**Making Quick Requests**
|
96
|
+
|
97
|
+
The request object has some convenience methods for performing single HTTP
|
98
|
+
requests. The arguments are the same as those you pass into the request
|
99
|
+
constructor.
|
100
|
+
|
101
|
+
response = Typhoeus::Request.get("http://www.pauldix.net")
|
102
|
+
response = Typhoeus::Request.head("http://www.pauldix.net")
|
103
|
+
response = Typhoeus::Request.put("http://localhost:3000/posts/1", :body => "whoo, a body")
|
104
|
+
response = Typhoeus::Request.post("http://localhost:3000/posts", :params => {:title => "test post", :content => "this is my test"})
|
105
|
+
response = Typhoeus::Request.delete("http://localhost:3000/posts/1")
|
106
|
+
|
107
|
+
**Handling HTTP errors**
|
108
|
+
|
109
|
+
You can query the response object to figure out if you had a successful
|
110
|
+
request or not. Here’s some example code that you might use to handle errors.
|
111
|
+
|
112
|
+
request.on_complete do |response|
|
113
|
+
if response.success?
|
114
|
+
# hell yeah
|
115
|
+
elsif response.timed_out?
|
116
|
+
# aw hell no
|
117
|
+
log("got a time out")
|
118
|
+
elsif response.code == 0
|
119
|
+
# Could not get an http response, something's wrong.
|
120
|
+
log(response.curl_error_message)
|
121
|
+
else
|
122
|
+
# Received a non-successful http response.
|
123
|
+
log("HTTP request failed: " + response.code.to_s)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
This also works with serial (blocking) requests in the same fashion. Both
|
128
|
+
serial and parallel requests return a Response object.
|
129
|
+
|
130
|
+
**Handling file uploads**
|
131
|
+
|
132
|
+
A File object can be passed as a param for a POST request to handle uploading
|
133
|
+
files to the server. Typhoeus will upload the file as the original file name
|
134
|
+
and use Mime::Types to set the content type.
|
135
|
+
|
136
|
+
response = Typhoeus::Request.post("http://localhost:3000/posts",
|
137
|
+
:params => {
|
138
|
+
:title => "test post", :content => "this is my test",
|
139
|
+
:file => File.open("thesis.txt","r")
|
140
|
+
}
|
141
|
+
)
|
142
|
+
|
143
|
+
**Making Parallel Requests**
|
144
|
+
|
145
|
+
# Generally, you should be running requests through hydra. Here is how that looks
|
146
|
+
hydra = Typhoeus::Hydra.new
|
147
|
+
|
148
|
+
first_request = Typhoeus::Request.new("http://localhost:3000/posts/1.json")
|
149
|
+
first_request.on_complete do |response|
|
150
|
+
post = JSON.parse(response.body)
|
151
|
+
third_request = Typhoeus::Request.new(post.links.first) # get the first url in the post
|
152
|
+
third_request.on_complete do |response|
|
153
|
+
# do something with that
|
154
|
+
end
|
155
|
+
hydra.queue third_request
|
156
|
+
return post
|
157
|
+
end
|
158
|
+
second_request = Typhoeus::Request.new("http://localhost:3000/users/1.json")
|
159
|
+
second_request.on_complete do |response|
|
160
|
+
JSON.parse(response.body)
|
161
|
+
end
|
162
|
+
hydra.queue first_request
|
163
|
+
hydra.queue second_request
|
164
|
+
hydra.run # this is a blocking call that returns once all requests are complete
|
165
|
+
|
166
|
+
first_request.handled_response # the value returned from the on_complete block
|
167
|
+
second_request.handled_response # the value returned from the on_complete block (parsed JSON)
|
168
|
+
|
169
|
+
The execution of that code goes something like this. The first and second
|
170
|
+
requests are built and queued. When hydra is run the first and second requests
|
171
|
+
run in parallel. When the first request completes, the third request is then
|
172
|
+
built and queued up. The moment it is queued Hydra starts executing it.
|
173
|
+
Meanwhile the second request would continue to run (or it could have completed
|
174
|
+
before the first). Once the third request is done, hydra.run returns.
|
175
|
+
|
176
|
+
**Specifying Max Concurrency**
|
177
|
+
|
178
|
+
Hydra will also handle how many requests you can make in parallel. Things will
|
179
|
+
get flakey if you try to make too many requests at the same time. The built in
|
180
|
+
limit is 200. When more requests than that are queued up, hydra will save them
|
181
|
+
for later and start the requests as others are finished. You can raise or
|
182
|
+
lower the concurrency limit through the Hydra constructor.
|
183
|
+
|
184
|
+
hydra = Typhoeus::Hydra.new(:max_concurrency => 20) # keep from killing some servers
|
185
|
+
|
186
|
+
**Memoization**
|
187
|
+
|
188
|
+
Hydra memoizes requests within a single run call. You can also disable
|
189
|
+
memoization.
|
190
|
+
|
191
|
+
hydra = Typhoeus::Hydra.new
|
192
|
+
2.times do
|
193
|
+
r = Typhoeus::Request.new("http://localhost/3000/users/1")
|
194
|
+
hydra.queue r
|
195
|
+
end
|
196
|
+
hydra.run # this will result in a single request being issued. However, the on_complete handlers of both will be called.
|
197
|
+
hydra.disable_memoization
|
198
|
+
2.times do
|
199
|
+
r = Typhoeus::Request.new("http://localhost/3000/users/1")
|
200
|
+
hydra.queue r
|
201
|
+
end
|
202
|
+
hydra.run # this will result in a two requests.
|
203
|
+
|
204
|
+
**Caching**
|
205
|
+
|
206
|
+
Hydra includes built in support for creating cache getters and setters. In the
|
207
|
+
following example, if there is a cache hit, the cached object is passed to the
|
208
|
+
on\_complete handler of the request object.
|
209
|
+
|
210
|
+
hydra = Typhoeus::Hydra.new
|
211
|
+
hydra.cache_setter do |request|
|
212
|
+
@cache.set(request.cache_key, request.response, request.cache_timeout)
|
213
|
+
end
|
214
|
+
|
215
|
+
hydra.cache_getter do |request|
|
216
|
+
@cache.get(request.cache_key) rescue nil
|
217
|
+
end
|
218
|
+
|
219
|
+
**Direct Stubbing**
|
220
|
+
|
221
|
+
Hydra allows you to stub out specific urls and patterns to avoid hitting
|
222
|
+
remote servers while testing.
|
223
|
+
|
224
|
+
hydra = Typhoeus::Hydra.new
|
225
|
+
response = Response.new(:code => 200, :headers => "", :body => "{'name' : 'paul'}", :time => 0.3)
|
226
|
+
hydra.stub(:get, "http://localhost:3000/users/1").and_return(response)
|
227
|
+
|
228
|
+
request = Typhoeus::Request.new("http://localhost:3000/users/1")
|
229
|
+
request.on_complete do |response|
|
230
|
+
JSON.parse(response.body)
|
231
|
+
end
|
232
|
+
hydra.queue request
|
233
|
+
hydra.run
|
234
|
+
|
235
|
+
The queued request will hit the stub. The on\_complete handler will be called
|
236
|
+
and will be passed the response object. You can also specify a regex to match
|
237
|
+
urls.
|
238
|
+
|
239
|
+
hydra.stub(:get, /http\:\/\/localhost\:3000\/users\/.*/).and_return(response)
|
240
|
+
# any requests for a user will be stubbed out with the pre built response.
|
241
|
+
|
242
|
+
**The Singleton**
|
243
|
+
|
244
|
+
All of the quick requests are done using the singleton hydra object. If you
|
245
|
+
want to enable caching or stubbing on the quick requests, set those options on
|
246
|
+
the singleton.
|
247
|
+
|
248
|
+
hydra = Typhoeus::Hydra.hydra
|
249
|
+
hydra.stub(:get, "http://localhost:3000/users")
|
250
|
+
|
251
|
+
**Timeouts**
|
252
|
+
|
253
|
+
No exceptions are raised on HTTP timeouts. You can check whether a request
|
254
|
+
timed out with the following methods:
|
255
|
+
|
256
|
+
easy.timed_out? # for a raw Easy handle
|
257
|
+
response.timed_out? # for a Response handle
|
258
|
+
|
259
|
+
**Following Redirections**
|
260
|
+
|
261
|
+
Use `:follow_location => true`, eg:
|
262
|
+
|
263
|
+
Typhoeus::Request.new(“www.example.com”, :follow_location => true)
|
264
|
+
|
265
|
+
**Basic Authentication**
|
266
|
+
|
267
|
+
response = Typhoeus::Request.get("http://twitter.com/statuses/followers.json",
|
268
|
+
:username => username, :password => password)
|
269
|
+
|
270
|
+
**SSL**
|
271
|
+
|
272
|
+
SSL comes built in to libcurl so it’s in Typhoeus as well. If you pass in a
|
273
|
+
url with “https” it should just work assuming that you have your [cert
|
274
|
+
bundle](http://curl.haxx.se/docs/caextract.html) in order and the server is
|
275
|
+
verifiable. You must also have libcurl built with SSL support enabled. You can
|
276
|
+
check that by doing this:
|
277
|
+
|
278
|
+
Typhoeus::Easy.new.curl_version # output should include OpenSSL/...
|
279
|
+
|
280
|
+
Now, even if you have libcurl built with OpenSSL you may still have a messed
|
281
|
+
up cert bundle or if you’re hitting a non-verifiable SSL server then you’ll
|
282
|
+
have to disable peer verification to make SSL work. Like this:
|
283
|
+
|
284
|
+
Typhoeus::Request.get("https://mail.google.com/mail", :disable_ssl_peer_verification => true)
|
285
|
+
|
286
|
+
If you are getting “SSL: certificate subject name does not match target host
|
287
|
+
name” from curl (ex:- you are trying to access to b.c.host.com when the
|
288
|
+
certificate subject is \*.host.com). You can disable host verification. Like
|
289
|
+
this:
|
290
|
+
|
291
|
+
Typhoeus::Request.get("https://mail.google.com/mail", :disable_ssl_host_verification => true)
|
292
|
+
|
293
|
+
**LibCurl**
|
294
|
+
|
295
|
+
Typhoeus also has a more raw libcurl interface. These are the Easy and Multi
|
296
|
+
objects. If you’re into accessing just the raw libcurl style, those are your
|
297
|
+
best bet.
|
298
|
+
|
299
|
+
However, by using this raw interface, you do not get access to Hydra-specific
|
300
|
+
features, such as stubbing/mocking.
|
301
|
+
|
302
|
+
SSL Certs can be provided to the Easy interface:
|
303
|
+
|
304
|
+
e = Typhoeus::Easy.new
|
305
|
+
e.url = "https://example.com/action"
|
306
|
+
s.ssl_cacert = "ca_file.cer"
|
307
|
+
e.ssl_cert = "acert.crt"
|
308
|
+
e.ssl_key = "akey.key"
|
309
|
+
[...]
|
310
|
+
e.perform
|
311
|
+
|
312
|
+
or directly to a Typhoeus::Request :
|
313
|
+
|
314
|
+
e = Typhoeus::Request.get("https://example.com/action",
|
315
|
+
:ssl_cacert => "ca_file.cer",
|
316
|
+
:ssl_cert => "acert.crt",
|
317
|
+
:ssl_key => "akey.key",
|
318
|
+
[...]
|
319
|
+
end
|
320
|
+
|
321
|
+
## Advanced authentication
|
322
|
+
|
323
|
+
Thanks for the authentication piece and this description go to Oleg Ivanov
|
324
|
+
(morhekil). The major reason to start this fork was the need to perform NTLM
|
325
|
+
authentication in Ruby, and other libcurl’s authentications method were made
|
326
|
+
possible as a result. Now you can do it via Typhoeus::Easy interface using the
|
327
|
+
following API.
|
328
|
+
|
329
|
+
e = Typhoeus::Easy.new
|
330
|
+
e.auth = {
|
331
|
+
:username => 'username',
|
332
|
+
:password => 'password',
|
333
|
+
:method => Typhoeus::Easy::AUTH_TYPES[:CURLAUTH_NTLM]
|
334
|
+
}
|
335
|
+
e.url = "http://example.com/auth_ntlm"
|
336
|
+
e.method = :get
|
337
|
+
e.perform
|
338
|
+
|
339
|
+
**Other authentication types**
|
340
|
+
|
341
|
+
The following authentication types are available:
|
342
|
+
|
343
|
+
* CURLAUTH\_BASIC
|
344
|
+
* CURLAUTH\_DIGEST
|
345
|
+
* CURLAUTH\_GSSNEGOTIATE
|
346
|
+
* CURLAUTH\_NTLM
|
347
|
+
* CURLAUTH\_DIGEST\_IE
|
348
|
+
* CURLAUTH\_AUTO
|
349
|
+
|
350
|
+
The last one (CURLAUTH\_AUTO) is really a combination of all previous methods
|
351
|
+
and is provided by Typhoeus for convenience. When you set authentication to
|
352
|
+
auto, Typhoeus will retrieve the given URL first and examine it’s headers to
|
353
|
+
confirm what auth types are supported by the server. The it will select the
|
354
|
+
strongest of available auth methods and will send the second request using the
|
355
|
+
selected authentication method.
|
356
|
+
|
357
|
+
**Authentication via the quick request interface**
|
358
|
+
|
359
|
+
There’s also an easy way to perform any kind of authentication via the quick
|
360
|
+
request interface:
|
361
|
+
|
362
|
+
e = Typhoeus::Request.get("http://example.com",
|
363
|
+
:username => 'username',
|
364
|
+
:password => 'password',
|
365
|
+
:auth_method => :ntlm)
|
366
|
+
|
367
|
+
All methods listed above is available in a shorter form – :basic, :digest,
|
368
|
+
:gssnegotiate, :ntlm, :digest\_ie, :auto.
|
369
|
+
|
370
|
+
**Query of available auth types**
|
371
|
+
|
372
|
+
After the initial request you can get the authentication types available on
|
373
|
+
the server via Typhoues::Easy#auth\_methods call. It will return a number
|
374
|
+
|
375
|
+
that you’ll need to decode yourself, please refer to easy.rb source code to
|
376
|
+
see the numeric values of different auth types.
|
377
|
+
|
378
|
+
## Verbose debug output
|
379
|
+
|
380
|
+
Sometime it’s useful to see verbose output from curl. You may now enable it:
|
381
|
+
|
382
|
+
e = Typhoeus::Easy.new
|
383
|
+
e.verbose = 1
|
384
|
+
|
385
|
+
or using the quick request:
|
386
|
+
|
387
|
+
e = Typhoeus::Request.get("http://example.com", :verbose => true)
|
388
|
+
|
389
|
+
Just remember that libcurl prints it’s debug output to the console (to
|
390
|
+
STDERR), so you’ll need to run your scripts from the console to see it.
|
391
|
+
|
392
|
+
## Benchmarks
|
393
|
+
|
394
|
+
I set up a benchmark to test how the parallel performance works vs Ruby’s
|
395
|
+
built in NET::HTTP. The setup was a local evented HTTP server that would take
|
396
|
+
a request, sleep for 500 milliseconds and then issued a blank response. I set
|
397
|
+
up the client to call this 20 times. Here are the results:
|
398
|
+
|
399
|
+
net::http 0.030000 0.010000 0.040000 ( 10.054327)
|
400
|
+
typhoeus 0.020000 0.070000 0.090000 ( 0.508817)
|
401
|
+
|
402
|
+
We can see from this that NET::HTTP performs as expected, taking 10 seconds to
|
403
|
+
run 20 500ms requests. Typhoeus only takes 500ms (the time of the response
|
404
|
+
that took the longest.) One other thing to note is that Typhoeus keeps a pool
|
405
|
+
of libcurl Easy handles to use. For this benchmark I warmed the pool first. So
|
406
|
+
if you test this out it may be a bit slower until the Easy handle pool has
|
407
|
+
enough in it to run all the simultaneous requests. For some reason the easy
|
408
|
+
handles can take quite some time to allocate.
|
409
|
+
|
410
|
+
## Running the specs
|
411
|
+
|
412
|
+
Running the specs requires a couple of Sinatra servers to be booted. rake spec
|
413
|
+
will do this for you, but if you’re needing to run the specs a lot, spinning
|
414
|
+
up the servers manually and leaving them running should speed things up a bit.
|
415
|
+
Do this:
|
416
|
+
|
417
|
+
# Start up the test servers (in another terminal)
|
418
|
+
rake start_test_servers
|
419
|
+
|
420
|
+
# Run the specs
|
421
|
+
rake spec
|
422
|
+
|
423
|
+
|
424
|
+
## Next Steps
|
425
|
+
|
426
|
+
* Add in ability to keep-alive requests and reuse them within hydra.
|
427
|
+
* Add support for automatic retry, exponential back-off, and queuing for later.
|
428
|
+
|
429
|
+
## LICENSE
|
430
|
+
|
431
|
+
(The MIT License)
|
432
|
+
|
433
|
+
Copyright © 2009-2010 Paul Dix
|
434
|
+
|
435
|
+
Copyright © 2011 David Balatero
|
436
|
+
|
437
|
+
Copyright © 2012 [Hans Hasselberg](http://www.hans.io)
|
438
|
+
|
439
|
+
Permission is hereby granted, free of charge, to any person obtaining a
|
440
|
+
copy of this software and associated documentation files (the "Software"),
|
441
|
+
to deal in the Software without restriction, including without
|
442
|
+
limitation the rights to use, copy, modify, merge, publish, distribute,
|
443
|
+
sublicense, and/or sell copies of the Software, and to permit persons
|
444
|
+
to whom the Software is furnished to do so, subject to the following conditions:
|
445
|
+
|
446
|
+
The above copyright notice and this permission notice shall be included
|
447
|
+
in all copies or substantial portions of the Software.
|
448
|
+
|
449
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
450
|
+
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
451
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
452
|
+
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
453
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
454
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
455
|
+
OTHER DEALINGS IN THE SOFTWARE.
|