em-http-request 0.2.10 → 0.2.11
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/LICENSE +58 -58
- data/README.md +157 -0
- data/Rakefile +110 -106
- data/VERSION +1 -1
- data/em-http-request.gemspec +5 -4
- data/examples/fetch.rb +30 -30
- data/examples/fibered-http.rb +38 -38
- data/examples/oauth-tweet.rb +49 -49
- data/examples/websocket-handler.rb +28 -28
- data/examples/websocket-server.rb +8 -8
- data/ext/buffer/extconf.rb +53 -53
- data/ext/http11_client/ext_help.h +14 -14
- data/ext/http11_client/extconf.rb +6 -6
- data/ext/http11_client/http11_client.c +328 -328
- data/ext/http11_client/http11_parser.c +418 -418
- data/ext/http11_client/http11_parser.h +48 -48
- data/ext/http11_client/http11_parser.rl +170 -170
- data/lib/em-http-request.rb +1 -1
- data/lib/em-http.rb +2 -1
- data/lib/em-http/client.rb +58 -26
- data/lib/em-http/core_ext/bytesize.rb +5 -5
- data/lib/em-http/core_ext/hash.rb +53 -53
- data/lib/em-http/decoders.rb +122 -122
- data/lib/em-http/http_options.rb +33 -31
- data/lib/em-http/mock.rb +90 -50
- data/lib/em-http/multi.rb +21 -17
- data/lib/em-http/request.rb +1 -0
- data/spec/fixtures/google.ca +20 -21
- data/spec/hash_spec.rb +24 -24
- data/spec/helper.rb +3 -2
- data/spec/mock_spec.rb +79 -34
- data/spec/multi_spec.rb +27 -10
- data/spec/request_spec.rb +198 -65
- data/spec/spec.opts +7 -0
- data/spec/stallion.rb +59 -2
- data/spec/stub_server.rb +22 -22
- metadata +6 -5
- data/README.rdoc +0 -138
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.11
|
data/em-http-request.gemspec
CHANGED
@@ -5,22 +5,22 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{em-http-request}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.11"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Ilya Grigorik"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-08-16}
|
13
13
|
s.description = %q{EventMachine based, async HTTP Request interface}
|
14
14
|
s.email = %q{ilya@igvita.com}
|
15
15
|
s.extensions = ["ext/buffer/extconf.rb", "ext/http11_client/extconf.rb"]
|
16
16
|
s.extra_rdoc_files = [
|
17
17
|
"LICENSE",
|
18
|
-
"README.
|
18
|
+
"README.md"
|
19
19
|
]
|
20
20
|
s.files = [
|
21
21
|
".gitignore",
|
22
22
|
"LICENSE",
|
23
|
-
"README.
|
23
|
+
"README.md",
|
24
24
|
"Rakefile",
|
25
25
|
"VERSION",
|
26
26
|
"em-http-request.gemspec",
|
@@ -53,6 +53,7 @@ Gem::Specification.new do |s|
|
|
53
53
|
"spec/mock_spec.rb",
|
54
54
|
"spec/multi_spec.rb",
|
55
55
|
"spec/request_spec.rb",
|
56
|
+
"spec/spec.opts",
|
56
57
|
"spec/stallion.rb",
|
57
58
|
"spec/stub_server.rb"
|
58
59
|
]
|
data/examples/fetch.rb
CHANGED
@@ -1,30 +1,30 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'eventmachine'
|
3
|
-
require '../lib/em-http'
|
4
|
-
|
5
|
-
urls = ARGV
|
6
|
-
if urls.size < 1
|
7
|
-
puts "Usage: #{$0} <url> <url> <...>"
|
8
|
-
exit
|
9
|
-
end
|
10
|
-
|
11
|
-
pending = urls.size
|
12
|
-
|
13
|
-
EM.run do
|
14
|
-
urls.each do |url|
|
15
|
-
http = EM::HttpRequest.new(url).get
|
16
|
-
http.callback {
|
17
|
-
puts "#{url}\n#{http.response_header.status} - #{http.response.length} bytes\n"
|
18
|
-
puts http.response
|
19
|
-
|
20
|
-
pending -= 1
|
21
|
-
EM.stop if pending < 1
|
22
|
-
}
|
23
|
-
http.errback {
|
24
|
-
puts "#{url}\n" + http.error
|
25
|
-
|
26
|
-
pending -= 1
|
27
|
-
EM.stop if pending < 1
|
28
|
-
}
|
29
|
-
end
|
30
|
-
end
|
1
|
+
require 'rubygems'
|
2
|
+
require 'eventmachine'
|
3
|
+
require '../lib/em-http'
|
4
|
+
|
5
|
+
urls = ARGV
|
6
|
+
if urls.size < 1
|
7
|
+
puts "Usage: #{$0} <url> <url> <...>"
|
8
|
+
exit
|
9
|
+
end
|
10
|
+
|
11
|
+
pending = urls.size
|
12
|
+
|
13
|
+
EM.run do
|
14
|
+
urls.each do |url|
|
15
|
+
http = EM::HttpRequest.new(url).get
|
16
|
+
http.callback {
|
17
|
+
puts "#{url}\n#{http.response_header.status} - #{http.response.length} bytes\n"
|
18
|
+
puts http.response
|
19
|
+
|
20
|
+
pending -= 1
|
21
|
+
EM.stop if pending < 1
|
22
|
+
}
|
23
|
+
http.errback {
|
24
|
+
puts "#{url}\n" + http.error
|
25
|
+
|
26
|
+
pending -= 1
|
27
|
+
EM.stop if pending < 1
|
28
|
+
}
|
29
|
+
end
|
30
|
+
end
|
data/examples/fibered-http.rb
CHANGED
@@ -1,39 +1,39 @@
|
|
1
|
-
require 'eventmachine'
|
2
|
-
require 'em-http'
|
3
|
-
require 'fiber'
|
4
|
-
|
5
|
-
# Using Fibers in Ruby 1.9 to simulate blocking IO / IO scheduling
|
6
|
-
# while using the async EventMachine API's
|
7
|
-
|
8
|
-
def async_fetch(url)
|
9
|
-
f = Fiber.current
|
10
|
-
http = EventMachine::HttpRequest.new(url).get :timeout => 10
|
11
|
-
|
12
|
-
http.callback { f.resume(http) }
|
13
|
-
http.errback { f.resume(http) }
|
14
|
-
|
15
|
-
return Fiber.yield
|
16
|
-
end
|
17
|
-
|
18
|
-
EventMachine.run do
|
19
|
-
Fiber.new{
|
20
|
-
|
21
|
-
puts "Setting up HTTP request #1"
|
22
|
-
data = async_fetch('http://www.google.com/')
|
23
|
-
puts "Fetched page #1: #{data.response_header.status}"
|
24
|
-
|
25
|
-
puts "Setting up HTTP request #2"
|
26
|
-
data = async_fetch('http://www.yahoo.com/')
|
27
|
-
puts "Fetched page #2: #{data.response_header.status}"
|
28
|
-
|
29
|
-
EventMachine.stop
|
30
|
-
}.resume
|
31
|
-
end
|
32
|
-
|
33
|
-
puts "Done"
|
34
|
-
|
35
|
-
# Setting up HTTP request #1
|
36
|
-
# Fetched page #1: 302
|
37
|
-
# Setting up HTTP request #2
|
38
|
-
# Fetched page #2: 200
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'em-http'
|
3
|
+
require 'fiber'
|
4
|
+
|
5
|
+
# Using Fibers in Ruby 1.9 to simulate blocking IO / IO scheduling
|
6
|
+
# while using the async EventMachine API's
|
7
|
+
|
8
|
+
def async_fetch(url)
|
9
|
+
f = Fiber.current
|
10
|
+
http = EventMachine::HttpRequest.new(url).get :timeout => 10
|
11
|
+
|
12
|
+
http.callback { f.resume(http) }
|
13
|
+
http.errback { f.resume(http) }
|
14
|
+
|
15
|
+
return Fiber.yield
|
16
|
+
end
|
17
|
+
|
18
|
+
EventMachine.run do
|
19
|
+
Fiber.new{
|
20
|
+
|
21
|
+
puts "Setting up HTTP request #1"
|
22
|
+
data = async_fetch('http://www.google.com/')
|
23
|
+
puts "Fetched page #1: #{data.response_header.status}"
|
24
|
+
|
25
|
+
puts "Setting up HTTP request #2"
|
26
|
+
data = async_fetch('http://www.yahoo.com/')
|
27
|
+
puts "Fetched page #2: #{data.response_header.status}"
|
28
|
+
|
29
|
+
EventMachine.stop
|
30
|
+
}.resume
|
31
|
+
end
|
32
|
+
|
33
|
+
puts "Done"
|
34
|
+
|
35
|
+
# Setting up HTTP request #1
|
36
|
+
# Fetched page #1: 302
|
37
|
+
# Setting up HTTP request #2
|
38
|
+
# Fetched page #2: 200
|
39
39
|
# Done
|
data/examples/oauth-tweet.rb
CHANGED
@@ -1,50 +1,50 @@
|
|
1
|
-
# Courtesy of Darcy Laycock:
|
2
|
-
# http://gist.github.com/265261
|
3
|
-
#
|
4
|
-
|
5
|
-
require 'rubygems'
|
6
|
-
|
7
|
-
require 'em-http'
|
8
|
-
require 'oauth'
|
9
|
-
|
10
|
-
# At a minimum, require 'oauth/request_proxy/em_http_request'
|
11
|
-
# for this example, we'll use Net::HTTP like support.
|
12
|
-
require 'oauth/client/em_http'
|
13
|
-
|
14
|
-
# You need two things: an oauth consumer and an access token.
|
15
|
-
# You need to generate an access token, I suggest looking elsewhere how to do that or wait for a full tutorial.
|
16
|
-
# For a consumer key / consumer secret, signup for an app at:
|
17
|
-
# http://twitter.com/apps/new
|
18
|
-
|
19
|
-
# Edit in your details.
|
20
|
-
CONSUMER_KEY = ""
|
21
|
-
CONSUMER_SECRET = ""
|
22
|
-
ACCESS_TOKEN = ""
|
23
|
-
ACCESS_TOKEN_SECRET = ""
|
24
|
-
|
25
|
-
def twitter_oauth_consumer
|
26
|
-
@twitter_oauth_consumer ||= OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET, :site => "http://twitter.com")
|
27
|
-
end
|
28
|
-
|
29
|
-
def twitter_oauth_access_token
|
30
|
-
@twitter_oauth_access_token ||= OAuth::AccessToken.new(twitter_oauth_consumer, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
|
31
|
-
end
|
32
|
-
|
33
|
-
EM.run do
|
34
|
-
|
35
|
-
request = EventMachine::HttpRequest.new('http://twitter.com/statuses/update.json')
|
36
|
-
http = request.post(:body => {'status' => 'Hello Twitter from em-http-request with OAuth'}, :head => {"Content-Type" => "application/x-www-form-urlencoded"}) do |client|
|
37
|
-
twitter_oauth_consumer.sign!(client, twitter_oauth_access_token)
|
38
|
-
end
|
39
|
-
|
40
|
-
http.callback do
|
41
|
-
puts "Response: #{http.response} (Code: #{http.response_header.status})"
|
42
|
-
EM.stop_event_loop
|
43
|
-
end
|
44
|
-
|
45
|
-
http.errback do
|
46
|
-
puts "Failed to post"
|
47
|
-
EM.stop_event_loop
|
48
|
-
end
|
49
|
-
|
1
|
+
# Courtesy of Darcy Laycock:
|
2
|
+
# http://gist.github.com/265261
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
|
7
|
+
require 'em-http'
|
8
|
+
require 'oauth'
|
9
|
+
|
10
|
+
# At a minimum, require 'oauth/request_proxy/em_http_request'
|
11
|
+
# for this example, we'll use Net::HTTP like support.
|
12
|
+
require 'oauth/client/em_http'
|
13
|
+
|
14
|
+
# You need two things: an oauth consumer and an access token.
|
15
|
+
# You need to generate an access token, I suggest looking elsewhere how to do that or wait for a full tutorial.
|
16
|
+
# For a consumer key / consumer secret, signup for an app at:
|
17
|
+
# http://twitter.com/apps/new
|
18
|
+
|
19
|
+
# Edit in your details.
|
20
|
+
CONSUMER_KEY = ""
|
21
|
+
CONSUMER_SECRET = ""
|
22
|
+
ACCESS_TOKEN = ""
|
23
|
+
ACCESS_TOKEN_SECRET = ""
|
24
|
+
|
25
|
+
def twitter_oauth_consumer
|
26
|
+
@twitter_oauth_consumer ||= OAuth::Consumer.new(CONSUMER_KEY, CONSUMER_SECRET, :site => "http://twitter.com")
|
27
|
+
end
|
28
|
+
|
29
|
+
def twitter_oauth_access_token
|
30
|
+
@twitter_oauth_access_token ||= OAuth::AccessToken.new(twitter_oauth_consumer, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
|
31
|
+
end
|
32
|
+
|
33
|
+
EM.run do
|
34
|
+
|
35
|
+
request = EventMachine::HttpRequest.new('http://twitter.com/statuses/update.json')
|
36
|
+
http = request.post(:body => {'status' => 'Hello Twitter from em-http-request with OAuth'}, :head => {"Content-Type" => "application/x-www-form-urlencoded"}) do |client|
|
37
|
+
twitter_oauth_consumer.sign!(client, twitter_oauth_access_token)
|
38
|
+
end
|
39
|
+
|
40
|
+
http.callback do
|
41
|
+
puts "Response: #{http.response} (Code: #{http.response_header.status})"
|
42
|
+
EM.stop_event_loop
|
43
|
+
end
|
44
|
+
|
45
|
+
http.errback do
|
46
|
+
puts "Failed to post"
|
47
|
+
EM.stop_event_loop
|
48
|
+
end
|
49
|
+
|
50
50
|
end
|
@@ -1,28 +1,28 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'lib/em-http'
|
3
|
-
|
4
|
-
module KBHandler
|
5
|
-
include EM::Protocols::LineText2
|
6
|
-
|
7
|
-
def receive_line(data)
|
8
|
-
p "Want to send: #{data}"
|
9
|
-
p "Error status: #{$http.error?}"
|
10
|
-
$http.send(data)
|
11
|
-
p "After send"
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
EventMachine.run {
|
16
|
-
$http = EventMachine::HttpRequest.new("ws://localhost:8080/").get :timeout => 0
|
17
|
-
|
18
|
-
$http.disconnect { puts 'oops' }
|
19
|
-
$http.callback {
|
20
|
-
puts "WebSocket connected!"
|
21
|
-
}
|
22
|
-
|
23
|
-
$http.stream { |msg|
|
24
|
-
puts "Recieved: #{msg}"
|
25
|
-
}
|
26
|
-
|
27
|
-
EM.open_keyboard(KBHandler)
|
28
|
-
}
|
1
|
+
require 'rubygems'
|
2
|
+
require 'lib/em-http'
|
3
|
+
|
4
|
+
module KBHandler
|
5
|
+
include EM::Protocols::LineText2
|
6
|
+
|
7
|
+
def receive_line(data)
|
8
|
+
p "Want to send: #{data}"
|
9
|
+
p "Error status: #{$http.error?}"
|
10
|
+
$http.send(data)
|
11
|
+
p "After send"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
EventMachine.run {
|
16
|
+
$http = EventMachine::HttpRequest.new("ws://localhost:8080/").get :timeout => 0
|
17
|
+
|
18
|
+
$http.disconnect { puts 'oops' }
|
19
|
+
$http.callback {
|
20
|
+
puts "WebSocket connected!"
|
21
|
+
}
|
22
|
+
|
23
|
+
$http.stream { |msg|
|
24
|
+
puts "Recieved: #{msg}"
|
25
|
+
}
|
26
|
+
|
27
|
+
EM.open_keyboard(KBHandler)
|
28
|
+
}
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'em-websocket'
|
3
|
-
|
4
|
-
EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |ws|
|
5
|
-
ws.onopen { ws.send "Hello Client!"}
|
6
|
-
ws.onmessage { |msg| p "got: #{msg}"; ws.send "Pong: #{msg}" }
|
7
|
-
ws.onclose { puts "WebSocket closed" }
|
8
|
-
end
|
1
|
+
require 'rubygems'
|
2
|
+
require 'em-websocket'
|
3
|
+
|
4
|
+
EventMachine::WebSocket.start(:host => "0.0.0.0", :port => 8080) do |ws|
|
5
|
+
ws.onopen { ws.send "Hello Client!"}
|
6
|
+
ws.onmessage { |msg| p "got: #{msg}"; ws.send "Pong: #{msg}" }
|
7
|
+
ws.onclose { puts "WebSocket closed" }
|
8
|
+
end
|
data/ext/buffer/extconf.rb
CHANGED
@@ -1,53 +1,53 @@
|
|
1
|
-
require 'mkmf'
|
2
|
-
|
3
|
-
libs = []
|
4
|
-
|
5
|
-
$defs << "-DRUBY_VERSION_CODE=#{RUBY_VERSION.gsub(/\D/, '')}"
|
6
|
-
|
7
|
-
if have_func('rb_thread_blocking_region')
|
8
|
-
$defs << '-DHAVE_RB_THREAD_BLOCKING_REGION'
|
9
|
-
end
|
10
|
-
|
11
|
-
if have_func('rb_str_set_len')
|
12
|
-
$defs << '-DHAVE_RB_STR_SET_LEN'
|
13
|
-
end
|
14
|
-
|
15
|
-
if have_header('sys/select.h')
|
16
|
-
$defs << '-DEV_USE_SELECT'
|
17
|
-
end
|
18
|
-
|
19
|
-
if have_header('poll.h')
|
20
|
-
$defs << '-DEV_USE_POLL'
|
21
|
-
end
|
22
|
-
|
23
|
-
if have_header('sys/epoll.h')
|
24
|
-
$defs << '-DEV_USE_EPOLL'
|
25
|
-
end
|
26
|
-
|
27
|
-
if have_header('sys/event.h') and have_header('sys/queue.h')
|
28
|
-
$defs << '-DEV_USE_KQUEUE'
|
29
|
-
end
|
30
|
-
|
31
|
-
if have_header('port.h')
|
32
|
-
$defs << '-DEV_USE_PORT'
|
33
|
-
end
|
34
|
-
|
35
|
-
if have_header('openssl/ssl.h')
|
36
|
-
$defs << '-DHAVE_OPENSSL_SSL_H'
|
37
|
-
libs << '-lssl -lcrypto'
|
38
|
-
end
|
39
|
-
|
40
|
-
# ncpu detection specifics
|
41
|
-
case RUBY_PLATFORM
|
42
|
-
when /linux/
|
43
|
-
$defs << '-DHAVE_LINUX_PROCFS'
|
44
|
-
else
|
45
|
-
if have_func('sysctlbyname', ['sys/param.h', 'sys/sysctl.h'])
|
46
|
-
$defs << '-DHAVE_SYSCTLBYNAME'
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
$LIBS << ' ' << libs.join(' ')
|
51
|
-
|
52
|
-
dir_config('em_buffer')
|
53
|
-
create_makefile('em_buffer')
|
1
|
+
require 'mkmf'
|
2
|
+
|
3
|
+
libs = []
|
4
|
+
|
5
|
+
$defs << "-DRUBY_VERSION_CODE=#{RUBY_VERSION.gsub(/\D/, '')}"
|
6
|
+
|
7
|
+
if have_func('rb_thread_blocking_region')
|
8
|
+
$defs << '-DHAVE_RB_THREAD_BLOCKING_REGION'
|
9
|
+
end
|
10
|
+
|
11
|
+
if have_func('rb_str_set_len')
|
12
|
+
$defs << '-DHAVE_RB_STR_SET_LEN'
|
13
|
+
end
|
14
|
+
|
15
|
+
if have_header('sys/select.h')
|
16
|
+
$defs << '-DEV_USE_SELECT'
|
17
|
+
end
|
18
|
+
|
19
|
+
if have_header('poll.h')
|
20
|
+
$defs << '-DEV_USE_POLL'
|
21
|
+
end
|
22
|
+
|
23
|
+
if have_header('sys/epoll.h')
|
24
|
+
$defs << '-DEV_USE_EPOLL'
|
25
|
+
end
|
26
|
+
|
27
|
+
if have_header('sys/event.h') and have_header('sys/queue.h')
|
28
|
+
$defs << '-DEV_USE_KQUEUE'
|
29
|
+
end
|
30
|
+
|
31
|
+
if have_header('port.h')
|
32
|
+
$defs << '-DEV_USE_PORT'
|
33
|
+
end
|
34
|
+
|
35
|
+
if have_header('openssl/ssl.h')
|
36
|
+
$defs << '-DHAVE_OPENSSL_SSL_H'
|
37
|
+
libs << '-lssl -lcrypto'
|
38
|
+
end
|
39
|
+
|
40
|
+
# ncpu detection specifics
|
41
|
+
case RUBY_PLATFORM
|
42
|
+
when /linux/
|
43
|
+
$defs << '-DHAVE_LINUX_PROCFS'
|
44
|
+
else
|
45
|
+
if have_func('sysctlbyname', ['sys/param.h', 'sys/sysctl.h'])
|
46
|
+
$defs << '-DHAVE_SYSCTLBYNAME'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
$LIBS << ' ' << libs.join(' ')
|
51
|
+
|
52
|
+
dir_config('em_buffer')
|
53
|
+
create_makefile('em_buffer')
|