em-http-request 1.0.0.beta.3 → 1.0.0.beta.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of em-http-request might be problematic. Click here for more details.
- data/.gemtest +0 -0
- data/Gemfile +12 -1
- data/README.md +2 -2
- data/Rakefile +2 -1
- data/benchmarks/clients.rb +156 -0
- data/benchmarks/em-excon.rb +87 -0
- data/benchmarks/em-profile.gif +0 -0
- data/benchmarks/em-profile.txt +65 -0
- data/benchmarks/server.rb +48 -0
- data/em-http-request.gemspec +2 -1
- data/examples/.gitignore +1 -0
- data/examples/fibered-http.rb +10 -6
- data/examples/oauth-tweet.rb +22 -37
- data/lib/em-http.rb +3 -2
- data/lib/em-http/client.rb +52 -37
- data/lib/em-http/decoders.rb +1 -1
- data/lib/em-http/http_client_options.rb +56 -0
- data/lib/em-http/http_connection.rb +97 -41
- data/lib/em-http/http_connection_options.rb +23 -0
- data/lib/em-http/http_encoding.rb +1 -1
- data/lib/em-http/middleware/cookie_jar.rb +38 -0
- data/lib/em-http/middleware/json_response.rb +15 -0
- data/lib/em-http/middleware/oauth.rb +21 -0
- data/lib/em-http/multi.rb +18 -18
- data/lib/em-http/request.rb +7 -29
- data/lib/em-http/version.rb +1 -1
- data/spec/client_spec.rb +39 -0
- data/spec/external_spec.rb +17 -1
- data/spec/helper.rb +12 -0
- data/spec/middleware_spec.rb +85 -7
- data/spec/multi_spec.rb +77 -22
- data/spec/pipelining_spec.rb +1 -1
- data/spec/redirect_spec.rb +86 -0
- data/spec/socksify_proxy_spec.rb +14 -14
- data/spec/stallion.rb +33 -2
- metadata +28 -6
- data/lib/em-http/http_options.rb +0 -53
data/.gemtest
ADDED
File without changes
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -11,8 +11,8 @@ Async (EventMachine) HTTP client, with support for:
|
|
11
11
|
- HTTP proxy and SOCKS5 support
|
12
12
|
- Basic Auth & OAuth
|
13
13
|
- Connection-level & Global middleware support
|
14
|
-
-
|
15
|
-
- Works wherever EventMachine runs
|
14
|
+
- HTTP parser via [http_parser.rb](https://github.com/tmm1/http_parser.rb)
|
15
|
+
- Works wherever EventMachine runs: Rubinius, JRuby, MRI
|
16
16
|
|
17
17
|
## Getting started
|
18
18
|
|
data/Rakefile
CHANGED
@@ -0,0 +1,156 @@
|
|
1
|
+
$: << './benchmarks'
|
2
|
+
require 'server'
|
3
|
+
|
4
|
+
require 'excon'
|
5
|
+
require 'httparty'
|
6
|
+
require 'net/http'
|
7
|
+
require 'open-uri'
|
8
|
+
require 'rest_client'
|
9
|
+
require 'tach'
|
10
|
+
require 'typhoeus'
|
11
|
+
|
12
|
+
url = 'http://127.0.0.1/10k.html'
|
13
|
+
|
14
|
+
with_server do
|
15
|
+
Tach.meter(100) do
|
16
|
+
|
17
|
+
tach('curb (persistent)') do |n|
|
18
|
+
curb = Curl::Easy.new
|
19
|
+
|
20
|
+
n.times do
|
21
|
+
curb.url = url
|
22
|
+
curb.http_get
|
23
|
+
curb.body_str
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
tach('em-http-request') do |n|
|
28
|
+
EventMachine.run {
|
29
|
+
count = 0
|
30
|
+
error = 0
|
31
|
+
|
32
|
+
n.times do
|
33
|
+
http = EventMachine::HttpRequest.new(url).get
|
34
|
+
|
35
|
+
http.callback {
|
36
|
+
count += 1
|
37
|
+
if count == n
|
38
|
+
p [count, error]
|
39
|
+
EM.stop
|
40
|
+
end
|
41
|
+
}
|
42
|
+
|
43
|
+
http.errback {
|
44
|
+
count += 1
|
45
|
+
error += 1
|
46
|
+
if count == n
|
47
|
+
p [count, error]
|
48
|
+
EM.stop
|
49
|
+
end
|
50
|
+
}
|
51
|
+
end
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
tach('em-http-request (persistent)') do |n|
|
56
|
+
EventMachine.run {
|
57
|
+
count = 0
|
58
|
+
error = 0
|
59
|
+
|
60
|
+
conn = EventMachine::HttpRequest.new(url)
|
61
|
+
|
62
|
+
n.times do
|
63
|
+
http = conn.get :keepalive => true
|
64
|
+
http.callback {
|
65
|
+
count += 1
|
66
|
+
if count == n
|
67
|
+
p [count, error]
|
68
|
+
EM.stop
|
69
|
+
end
|
70
|
+
}
|
71
|
+
|
72
|
+
http.errback {
|
73
|
+
count += 1
|
74
|
+
error += 1
|
75
|
+
if count == n
|
76
|
+
p [count, error]
|
77
|
+
EM.stop
|
78
|
+
end
|
79
|
+
}
|
80
|
+
end
|
81
|
+
}
|
82
|
+
end
|
83
|
+
|
84
|
+
tach('Excon') do
|
85
|
+
Excon.get(url).body
|
86
|
+
end
|
87
|
+
|
88
|
+
excon = Excon.new(url)
|
89
|
+
tach('Excon (persistent)') do
|
90
|
+
excon.request(:method => 'get').body
|
91
|
+
end
|
92
|
+
|
93
|
+
tach('HTTParty') do
|
94
|
+
HTTParty.get(url).body
|
95
|
+
end
|
96
|
+
|
97
|
+
uri = Addressable::URI.parse(url)
|
98
|
+
tach('Net::HTTP') do
|
99
|
+
Net::HTTP.start(uri.host, uri.port) {|http| http.get(uri.path).body }
|
100
|
+
end
|
101
|
+
|
102
|
+
uri = Addressable::URI.parse(url)
|
103
|
+
Net::HTTP.start(uri.host, uri.port) do |http|
|
104
|
+
tach('Net::HTTP (persistent)') do
|
105
|
+
http.get(uri.path).body
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
tach('open-uri') do
|
110
|
+
open(url).read
|
111
|
+
end
|
112
|
+
|
113
|
+
tach('RestClient') do
|
114
|
+
RestClient.get(url)
|
115
|
+
end
|
116
|
+
|
117
|
+
streamly = StreamlyFFI::Connection.new
|
118
|
+
tach('StreamlyFFI (persistent)') do
|
119
|
+
streamly.get(url)
|
120
|
+
end
|
121
|
+
|
122
|
+
tach('Typhoeus') do
|
123
|
+
Typhoeus::Request.get(url).body
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
|
130
|
+
# +------------------------------+----------+
|
131
|
+
# | tach | total |
|
132
|
+
# +------------------------------+----------+
|
133
|
+
# | em-http-request (persistent) | 0.016779 |
|
134
|
+
# +------------------------------+----------+
|
135
|
+
# | Excon (persistent) | 0.019606 |
|
136
|
+
# +------------------------------+----------+
|
137
|
+
# | curb (persistent) | 0.022034 |
|
138
|
+
# +------------------------------+----------+
|
139
|
+
# | Typhoeus | 0.027276 |
|
140
|
+
# +------------------------------+----------+
|
141
|
+
# | Excon | 0.034482 |
|
142
|
+
# +------------------------------+----------+
|
143
|
+
# | StreamlyFFI (persistent) | 0.036474 |
|
144
|
+
# +------------------------------+----------+
|
145
|
+
# | em-http-request | 0.041866 |
|
146
|
+
# +------------------------------+----------+
|
147
|
+
# | Net::HTTP (persistent) | 0.098379 |
|
148
|
+
# +------------------------------+----------+
|
149
|
+
# | Net::HTTP | 0.103786 |
|
150
|
+
# +------------------------------+----------+
|
151
|
+
# | RestClient | 0.111841 |
|
152
|
+
# +------------------------------+----------+
|
153
|
+
# | HTTParty | 0.118632 |
|
154
|
+
# +------------------------------+----------+
|
155
|
+
# | open-uri | 0.170172 |
|
156
|
+
# +------------------------------+----------+
|
@@ -0,0 +1,87 @@
|
|
1
|
+
$: << './benchmarks'
|
2
|
+
require 'server'
|
3
|
+
|
4
|
+
url = 'http://127.0.0.1/10k.html'
|
5
|
+
|
6
|
+
with_server do
|
7
|
+
Tach.meter(100) do
|
8
|
+
|
9
|
+
excon = Excon.new(url)
|
10
|
+
tach('Excon (persistent)') do
|
11
|
+
excon.request(:method => 'get').body
|
12
|
+
end
|
13
|
+
|
14
|
+
tach('Excon') do
|
15
|
+
Excon.get(url).body
|
16
|
+
end
|
17
|
+
|
18
|
+
tach('em-http-request') do |n|
|
19
|
+
EventMachine.run {
|
20
|
+
count = 0
|
21
|
+
error = 0
|
22
|
+
n.times do
|
23
|
+
EM.next_tick do
|
24
|
+
http = EventMachine::HttpRequest.new(url, :connect_timeout => 1).get
|
25
|
+
|
26
|
+
http.callback {
|
27
|
+
count += 1
|
28
|
+
if count == n
|
29
|
+
p [count, error]
|
30
|
+
EM.stop
|
31
|
+
end
|
32
|
+
}
|
33
|
+
|
34
|
+
http.errback {
|
35
|
+
count += 1
|
36
|
+
error += 1
|
37
|
+
if count == n
|
38
|
+
p [count, error]
|
39
|
+
EM.stop
|
40
|
+
end
|
41
|
+
}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
tach('em-http-request (persistent)') do |n|
|
48
|
+
EventMachine.run {
|
49
|
+
count = 0
|
50
|
+
error = 0
|
51
|
+
conn = EventMachine::HttpRequest.new(url)
|
52
|
+
|
53
|
+
n.times do
|
54
|
+
http = conn.get :keepalive => true
|
55
|
+
http.callback {
|
56
|
+
count += 1
|
57
|
+
if count == n
|
58
|
+
p [count, error]
|
59
|
+
EM.stop
|
60
|
+
end
|
61
|
+
}
|
62
|
+
|
63
|
+
http.errback {
|
64
|
+
count += 1
|
65
|
+
error += 1
|
66
|
+
if count == n
|
67
|
+
p [count, error]
|
68
|
+
EM.stop
|
69
|
+
end
|
70
|
+
}
|
71
|
+
end
|
72
|
+
}
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# +------------------------------+----------+
|
78
|
+
# | tach | total |
|
79
|
+
# +------------------------------+----------+
|
80
|
+
# | em-http-request (persistent) | 0.018133 |
|
81
|
+
# +------------------------------+----------+
|
82
|
+
# | Excon (persistent) | 0.023975 |
|
83
|
+
# +------------------------------+----------+
|
84
|
+
# | Excon | 0.032877 |
|
85
|
+
# +------------------------------+----------+
|
86
|
+
# | em-http-request | 0.042891 |
|
87
|
+
# +------------------------------+----------+
|
Binary file
|
@@ -0,0 +1,65 @@
|
|
1
|
+
Total: 143 samples
|
2
|
+
67 46.9% 46.9% 109 76.2% Kernel#gem_original_require
|
3
|
+
17 11.9% 58.7% 17 11.9% garbage_collector
|
4
|
+
12 8.4% 67.1% 12 8.4% EventMachine.connect_server
|
5
|
+
11 7.7% 74.8% 11 7.7% Dir.[]
|
6
|
+
11 7.7% 82.5% 11 7.7% File.file?
|
7
|
+
4 2.8% 85.3% 4 2.8% Kernel#eval
|
8
|
+
3 2.1% 87.4% 16 11.2% Enumerable#find
|
9
|
+
3 2.1% 89.5% 3 2.1% Regexp#initialize
|
10
|
+
2 1.4% 90.9% 16 11.2% EventMachine.run_machine
|
11
|
+
2 1.4% 92.3% 2 1.4% Regexp#match
|
12
|
+
1 0.7% 93.0% 1 0.7% FFI::DynamicLibrary.open
|
13
|
+
1 0.7% 93.7% 1 0.7% Hash#values
|
14
|
+
1 0.7% 94.4% 7 4.9% Kernel#load
|
15
|
+
1 0.7% 95.1% 3 2.1% MIME::Type#initialize
|
16
|
+
1 0.7% 95.8% 1 0.7% MatchData#captures
|
17
|
+
1 0.7% 96.5% 13 9.1% Module#bind_connect
|
18
|
+
1 0.7% 97.2% 17 11.9% Module#searcher
|
19
|
+
1 0.7% 97.9% 1 0.7% String#downcase
|
20
|
+
1 0.7% 98.6% 1 0.7% String#scan
|
21
|
+
1 0.7% 99.3% 1 0.7% String#strip
|
22
|
+
1 0.7% 100.0% 1 0.7% TCPSocket#initialize
|
23
|
+
0 0.0% 100.0% 1 0.7% Array#map
|
24
|
+
0 0.0% 100.0% 14 9.8% Array#reverse_each
|
25
|
+
0 0.0% 100.0% 14 9.8% Class#from_gems_in
|
26
|
+
0 0.0% 100.0% 14 9.8% Class#from_installed_gems
|
27
|
+
0 0.0% 100.0% 14 9.8% Class#load
|
28
|
+
0 0.0% 100.0% 1 0.7% Class#parse
|
29
|
+
0 0.0% 100.0% 1 0.7% Class#simplified
|
30
|
+
0 0.0% 100.0% 6 4.2% Enumerable#each_with_index
|
31
|
+
0 0.0% 100.0% 1 0.7% Excon::Connection#connect
|
32
|
+
0 0.0% 100.0% 1 0.7% Excon::Connection#request
|
33
|
+
0 0.0% 100.0% 1 0.7% Excon::Connection#socket
|
34
|
+
0 0.0% 100.0% 1 0.7% FFI::Library#ffi_lib
|
35
|
+
0 0.0% 100.0% 10 7.0% Gem::GemPathSearcher#find
|
36
|
+
0 0.0% 100.0% 1 0.7% Gem::GemPathSearcher#find_active
|
37
|
+
0 0.0% 100.0% 16 11.2% Gem::GemPathSearcher#init_gemspecs
|
38
|
+
0 0.0% 100.0% 16 11.2% Gem::GemPathSearcher#initialize
|
39
|
+
0 0.0% 100.0% 11 7.7% Gem::GemPathSearcher#matching_file?
|
40
|
+
0 0.0% 100.0% 11 7.7% Gem::GemPathSearcher#matching_files
|
41
|
+
0 0.0% 100.0% 14 9.8% Gem::SourceIndex#load_gems_in
|
42
|
+
0 0.0% 100.0% 14 9.8% Gem::SourceIndex#refresh!
|
43
|
+
0 0.0% 100.0% 1 0.7% Gem::SourceIndex#search
|
44
|
+
0 0.0% 100.0% 1 0.7% HttpOptions#initialize
|
45
|
+
0 0.0% 100.0% 1 0.7% HttpOptions#set_uri
|
46
|
+
0 0.0% 100.0% 14 9.8% Integer#times
|
47
|
+
0 0.0% 100.0% 1 0.7% Kernel#loop
|
48
|
+
0 0.0% 100.0% 109 76.2% Kernel#require
|
49
|
+
0 0.0% 100.0% 1 0.7% Module#activate
|
50
|
+
0 0.0% 100.0% 13 9.1% Module#connect
|
51
|
+
0 0.0% 100.0% 1 0.7% Module#get
|
52
|
+
0 0.0% 100.0% 2 1.4% Module#load_full_rubygems_library
|
53
|
+
0 0.0% 100.0% 5 3.5% Module#loaded_path?
|
54
|
+
0 0.0% 100.0% 16 11.2% Module#meter
|
55
|
+
0 0.0% 100.0% 16 11.2% Module#run
|
56
|
+
0 0.0% 100.0% 16 11.2% Module#source_index
|
57
|
+
0 0.0% 100.0% 30 21.0% Module#try_activate
|
58
|
+
0 0.0% 100.0% 17 11.9% Object#with_server
|
59
|
+
0 0.0% 100.0% 2 1.4% Regexp.union
|
60
|
+
0 0.0% 100.0% 1 0.7% TCPSocket.open
|
61
|
+
0 0.0% 100.0% 16 11.2% Tach::Meter#initialize
|
62
|
+
0 0.0% 100.0% 16 11.2% Tach::Meter#run_tach
|
63
|
+
0 0.0% 100.0% 1 0.7% URI::Parser#initialize
|
64
|
+
0 0.0% 100.0% 1 0.7% URI::Parser#initialize_regexp
|
65
|
+
0 0.0% 100.0% 7 4.9% YAML::EngineManager#yamler=
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'excon'
|
2
|
+
require 'httparty'
|
3
|
+
require 'net/http'
|
4
|
+
require 'open-uri'
|
5
|
+
require 'rest_client'
|
6
|
+
require 'tach'
|
7
|
+
require 'typhoeus'
|
8
|
+
require 'sinatra/base'
|
9
|
+
require 'streamly_ffi'
|
10
|
+
require 'curb'
|
11
|
+
|
12
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib', 'em-http')
|
13
|
+
|
14
|
+
module Benchmark
|
15
|
+
class Server < Sinatra::Base
|
16
|
+
|
17
|
+
def self.run
|
18
|
+
Rack::Handler::WEBrick.run(
|
19
|
+
Benchmark::Server.new,
|
20
|
+
:Port => 9292,
|
21
|
+
:AccessLog => [],
|
22
|
+
:Logger => WEBrick::Log.new(nil, WEBrick::Log::ERROR)
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
get '/data/:amount' do |amount|
|
27
|
+
'x' * amount.to_i
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def with_server(&block)
|
34
|
+
pid = Process.fork do
|
35
|
+
# Benchmark::Server.run
|
36
|
+
end
|
37
|
+
loop do
|
38
|
+
sleep(1)
|
39
|
+
begin
|
40
|
+
# Excon.get('http://localhost:9292/api/foo')
|
41
|
+
break
|
42
|
+
rescue
|
43
|
+
end
|
44
|
+
end
|
45
|
+
yield
|
46
|
+
ensure
|
47
|
+
Process.kill(9, pid)
|
48
|
+
end
|
data/em-http-request.gemspec
CHANGED
@@ -14,7 +14,7 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.description = s.summary
|
15
15
|
s.rubyforge_project = "em-http-request"
|
16
16
|
|
17
|
-
s.add_dependency "eventmachine"
|
17
|
+
s.add_dependency "eventmachine", ">= 1.0.0.beta.3"
|
18
18
|
s.add_dependency "addressable", ">= 2.2.3"
|
19
19
|
s.add_dependency "http_parser.rb", ">= 0.5.1"
|
20
20
|
s.add_dependency "em-socksify"
|
@@ -23,6 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_development_dependency "rake"
|
24
24
|
s.add_development_dependency "rack"
|
25
25
|
s.add_development_dependency "yajl-ruby"
|
26
|
+
s.add_development_dependency "cookiejar"
|
26
27
|
s.add_development_dependency "mongrel", "~> 1.2.0.pre2"
|
27
28
|
|
28
29
|
s.files = `git ls-files`.split("\n")
|
data/examples/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
twitter_auth.rb
|
data/examples/fibered-http.rb
CHANGED
@@ -9,17 +9,21 @@ def async_fetch(url)
|
|
9
9
|
f = Fiber.current
|
10
10
|
http = EventMachine::HttpRequest.new(url).get :timeout => 10
|
11
11
|
|
12
|
-
http.
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
if http.error.empty?
|
13
|
+
http.callback { f.resume(http) }
|
14
|
+
http.errback { f.resume(http) }
|
15
|
+
|
16
|
+
Fiber.yield
|
17
|
+
else
|
18
|
+
http
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
22
|
EventMachine.run do
|
19
23
|
Fiber.new{
|
20
24
|
|
21
25
|
puts "Setting up HTTP request #1"
|
22
|
-
data = async_fetch('http://www.google.
|
26
|
+
data = async_fetch('http://www.google.moo/')
|
23
27
|
puts "Fetched page #1: #{data.response_header.status}"
|
24
28
|
|
25
29
|
puts "Setting up HTTP request #2"
|
@@ -36,4 +40,4 @@ puts "Done"
|
|
36
40
|
# Fetched page #1: 302
|
37
41
|
# Setting up HTTP request #2
|
38
42
|
# Fetched page #2: 200
|
39
|
-
# Done
|
43
|
+
# Done
|