z-http-request 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +10 -0
  4. data/.rspec +3 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +8 -0
  7. data/Gemfile +17 -0
  8. data/README.md +38 -0
  9. data/Rakefile +3 -0
  10. data/benchmarks/clients.rb +170 -0
  11. data/benchmarks/em-excon.rb +87 -0
  12. data/benchmarks/em-profile.gif +0 -0
  13. data/benchmarks/em-profile.txt +65 -0
  14. data/benchmarks/server.rb +48 -0
  15. data/examples/.gitignore +1 -0
  16. data/examples/digest_auth/client.rb +25 -0
  17. data/examples/digest_auth/server.rb +28 -0
  18. data/examples/fetch.rb +30 -0
  19. data/examples/fibered-http.rb +51 -0
  20. data/examples/multi.rb +25 -0
  21. data/examples/oauth-tweet.rb +35 -0
  22. data/examples/socks5.rb +23 -0
  23. data/lib/z-http/client.rb +318 -0
  24. data/lib/z-http/core_ext/bytesize.rb +6 -0
  25. data/lib/z-http/decoders.rb +254 -0
  26. data/lib/z-http/http_client_options.rb +51 -0
  27. data/lib/z-http/http_connection.rb +214 -0
  28. data/lib/z-http/http_connection_options.rb +44 -0
  29. data/lib/z-http/http_encoding.rb +142 -0
  30. data/lib/z-http/http_header.rb +83 -0
  31. data/lib/z-http/http_status_codes.rb +57 -0
  32. data/lib/z-http/middleware/digest_auth.rb +112 -0
  33. data/lib/z-http/middleware/json_response.rb +15 -0
  34. data/lib/z-http/middleware/oauth.rb +40 -0
  35. data/lib/z-http/middleware/oauth2.rb +28 -0
  36. data/lib/z-http/multi.rb +57 -0
  37. data/lib/z-http/request.rb +23 -0
  38. data/lib/z-http/version.rb +5 -0
  39. data/lib/z-http-request.rb +1 -0
  40. data/lib/z-http.rb +18 -0
  41. data/spec/client_spec.rb +892 -0
  42. data/spec/digest_auth_spec.rb +48 -0
  43. data/spec/dns_spec.rb +44 -0
  44. data/spec/encoding_spec.rb +49 -0
  45. data/spec/external_spec.rb +150 -0
  46. data/spec/fixtures/google.ca +16 -0
  47. data/spec/fixtures/gzip-sample.gz +0 -0
  48. data/spec/gzip_spec.rb +68 -0
  49. data/spec/helper.rb +30 -0
  50. data/spec/middleware_spec.rb +143 -0
  51. data/spec/multi_spec.rb +104 -0
  52. data/spec/pipelining_spec.rb +66 -0
  53. data/spec/redirect_spec.rb +321 -0
  54. data/spec/socksify_proxy_spec.rb +60 -0
  55. data/spec/spec_helper.rb +6 -0
  56. data/spec/ssl_spec.rb +20 -0
  57. data/spec/stallion.rb +296 -0
  58. data/spec/stub_server.rb +42 -0
  59. data/z-http-request.gemspec +33 -0
  60. metadata +248 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ab688a2d990741d66ecc79a6d7f7fcb5908e60ad
4
+ data.tar.gz: 81fc6baa002d22c532883c4a1f8986d1170ffc82
5
+ SHA512:
6
+ metadata.gz: 0aa272059eb771c1451b67ba9a85561cf54a0aa8b6dba3933afa0858d6b662f03d09b508b223fd62fa3af1b0d472514d5c7ee89b4458a7b4f835f649faf60ef2
7
+ data.tar.gz: a04b808c207ef7f2e34c80233b25d2d42f21b45cd8981ae5dac176cc661c27bd4867f746c0e0159dcf7f2db34e774cedbe9cb8ed5a49d5bbacfc2384e10c0d36
data/.gemtest ADDED
File without changes
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ *.bundle
2
+ *.o
3
+ .idea
4
+ .jbundler/
5
+ Gemfile.lock
6
+ Makefile
7
+ gems/
8
+ misc
9
+ mkmf.log
10
+ vendor/
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --format documentation
3
+ --require spec/spec_helper
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ jruby
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ rvm:
3
+ - jruby
4
+ notifications:
5
+ email: false
6
+ hipchat:
7
+ rooms:
8
+ secure: QEn6sr/TryfI6Kjy39oXnNwfFxvHXbWNk413X0Ocno7FVbddu1DpN3+8FgfUTL7GTCxKyV4cKni9Zp+hiLrlUO15zk3JDZKzLBW24Ie0VCmhhYQAQWuVYatdo2x16LzyyFijNpvNlIjoRoifzIfF7YMNszgy4FxJ4ThFPp34jIY=
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'ruby-debug'
6
+ gem 'liquid-ext'
7
+ gem 'zmachine', :path => '../zmachine'
8
+
9
+ group :benchmark do
10
+ gem 'excon'
11
+ gem 'httparty'
12
+ gem 'rest-client'
13
+ gem 'sinatra'
14
+ gem 'streamly_ffi'
15
+ gem 'tach', '>= 0.0.8'
16
+ gem 'typhoeus'
17
+ end
data/README.md ADDED
@@ -0,0 +1,38 @@
1
+ # Z-HTTP-Request
2
+
3
+ This is a fork of Ilya Gregoriks em-http-request, ported to
4
+ [ZMachine](https://github.com/liquidm/zmachine). Furthermore stuff like
5
+ socksify has been removed as it is not needed for our simple http client use
6
+ case.
7
+
8
+ [![Build Status](https://travis-ci.org/liquidm/z-http-request.png)](https://travis-ci.org/liquidm/z-http-request)
9
+ [![Code Climate](https://codeclimate.com/github/liquidm/z-http-request.png)](https://codeclimate.com/github/liquidm/z-http-request)
10
+ [![Dependency Status](https://gemnasium.com/liquidm/z-http-request.png)](https://gemnasium.com/liquidm/z-http-request)
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ gem 'z-http-request'
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install z-http-request
25
+
26
+ ## Usage
27
+
28
+ Z-HTTP-Request is mostly API compatible with em-http-request and EventMachine.
29
+ Replace `EM` / `EventMachine` with `ZMachine` in your code and it should work
30
+ out of the box.
31
+
32
+ ## Contributing
33
+
34
+ 1. Fork it
35
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
36
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
37
+ 4. Push to the branch (`git push origin my-new-feature`)
38
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,3 @@
1
+ require "bundler/setup"
2
+ require "bundler/gem_tasks"
3
+ require "liquid/tasks"
@@ -0,0 +1,170 @@
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:9292/data/10000'
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('z-http-request') do |n|
28
+ ZMachine.run {
29
+ count = 0
30
+ error = 0
31
+
32
+ n.times do
33
+ http = ZMachine::HttpRequest.new(url).get
34
+
35
+ http.callback {
36
+ count += 1
37
+ if count == n
38
+ p [count, error]
39
+ ZMachine.stop
40
+ end
41
+ }
42
+
43
+ http.errback {
44
+ count += 1
45
+ error += 1
46
+ if count == n
47
+ p [count, error]
48
+ ZMachine.stop
49
+ end
50
+ }
51
+ end
52
+ }
53
+ end
54
+
55
+ tach('z-http-request (persistent)') do |n|
56
+ ZMachine.run {
57
+ count = 0
58
+ error = 0
59
+
60
+ conn = ZMachine::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
+ ZMachine.stop
69
+ end
70
+ }
71
+
72
+ http.errback {
73
+ count += 1
74
+ error += 1
75
+ if count == n
76
+ p [count, error]
77
+ ZMachine.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 |n|
123
+ hydra = Typhoeus::Hydra.new( max_concurrency: 8 )
124
+ hydra.disable_memoization
125
+ count = 0
126
+ error = 0
127
+ n.times {
128
+ req = Typhoeus::Request.new( url )
129
+ req.on_complete do |res|
130
+ count += 1
131
+ error += 1 if !res.success?
132
+ p [count, error] if count == n
133
+
134
+ end
135
+ hydra.queue( req )
136
+ }
137
+ hydra.run
138
+ end
139
+
140
+ end
141
+ end
142
+
143
+
144
+ #+------------------------------+-----------+
145
+ #| tach | total |
146
+ #+------------------------------+-----------+
147
+ #| z-http-request (persistent) | 0.145512 |
148
+ #+------------------------------+-----------+
149
+ #| Excon | 0.181564 |
150
+ #+------------------------------+-----------+
151
+ #| RestClient | 0.253127 |
152
+ #+------------------------------+-----------+
153
+ #| Net::HTTP | 0.294412 |
154
+ #+------------------------------+-----------+
155
+ #| HTTParty | 0.305397 |
156
+ #+------------------------------+-----------+
157
+ #| open-uri | 0.307007 |
158
+ #+------------------------------+-----------+
159
+ #| Net::HTTP (persistent) | 0.313716 |
160
+ #+------------------------------+-----------+
161
+ #| Typhoeus | 0.514725 |
162
+ #+------------------------------+-----------+
163
+ #| curb (persistent) | 3.981700 |
164
+ #+------------------------------+-----------+
165
+ #| StreamlyFFI (persistent) | 3.989063 |
166
+ #+------------------------------+-----------+
167
+ #| Excon (persistent) | 4.018761 |
168
+ #+------------------------------+-----------+
169
+ #| z-http-request | 15.025291 |
170
+ #+------------------------------+-----------+
@@ -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('z-http-request') do |n|
19
+ ZMachine.run {
20
+ count = 0
21
+ error = 0
22
+ n.times do
23
+ ZMachine.next_tick do
24
+ http = ZMachine::HttpRequest.new(url, :connect_timeout => 1).get
25
+
26
+ http.callback {
27
+ count += 1
28
+ if count == n
29
+ p [count, error]
30
+ ZMachine.stop
31
+ end
32
+ }
33
+
34
+ http.errback {
35
+ count += 1
36
+ error += 1
37
+ if count == n
38
+ p [count, error]
39
+ ZMachine.stop
40
+ end
41
+ }
42
+ end
43
+ end
44
+ }
45
+ end
46
+
47
+ tach('z-http-request (persistent)') do |n|
48
+ ZMachine.run {
49
+ count = 0
50
+ error = 0
51
+ conn = ZMachine::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
+ ZMachine.stop
60
+ end
61
+ }
62
+
63
+ http.errback {
64
+ count += 1
65
+ error += 1
66
+ if count == n
67
+ p [count, error]
68
+ ZMachine.stop
69
+ end
70
+ }
71
+ end
72
+ }
73
+ end
74
+ end
75
+ end
76
+
77
+ # +------------------------------+----------+
78
+ # | tach | total |
79
+ # +------------------------------+----------+
80
+ # | z-http-request (persistent) | 0.018133 |
81
+ # +------------------------------+----------+
82
+ # | Excon (persistent) | 0.023975 |
83
+ # +------------------------------+----------+
84
+ # | Excon | 0.032877 |
85
+ # +------------------------------+----------+
86
+ # | z-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% ZMachine.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% ZMachine.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% GZMachine::GemPathSearcher#find
36
+ 0 0.0% 100.0% 1 0.7% GZMachine::GemPathSearcher#find_active
37
+ 0 0.0% 100.0% 16 11.2% GZMachine::GemPathSearcher#init_gemspecs
38
+ 0 0.0% 100.0% 16 11.2% GZMachine::GemPathSearcher#initialize
39
+ 0 0.0% 100.0% 11 7.7% GZMachine::GemPathSearcher#matching_file?
40
+ 0 0.0% 100.0% 11 7.7% GZMachine::GemPathSearcher#matching_files
41
+ 0 0.0% 100.0% 14 9.8% GZMachine::SourceIndex#load_gems_in
42
+ 0 0.0% 100.0% 14 9.8% GZMachine::SourceIndex#refresh!
43
+ 0 0.0% 100.0% 1 0.7% GZMachine::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', 'z-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
@@ -0,0 +1 @@
1
+ twitter_auth.rb
@@ -0,0 +1,25 @@
1
+ $: << 'lib' << '../../lib'
2
+
3
+ require 'z-http'
4
+ require 'z-http/middleware/digest_auth'
5
+
6
+ digest_config = {
7
+ :username => 'digest_username',
8
+ :password => 'digest_password'
9
+ }
10
+
11
+ ZMachine.run do
12
+
13
+ conn_handshake = ZMachine::HttpRequest.new('http://localhost:3000')
14
+ http_handshake = conn_handshake.get
15
+
16
+ http_handshake.callback do
17
+ conn = ZMachine::HttpRequest.new('http://localhost:3000')
18
+ conn.use ZMachine::Middleware::DigestAuth, http_handshake.response_header['WWW_AUTHENTICATE'], digest_config
19
+ http = conn.get
20
+ http.callback do
21
+ puts http.response
22
+ ZMachine.stop
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ require 'webrick'
2
+
3
+ include WEBrick
4
+
5
+ config = { :Realm => 'DigestAuth_REALM' }
6
+
7
+ htdigest = WEBrick::HTTPAuth::Htdigest.new 'my_password_file'
8
+ htdigest.set_passwd config[:Realm], 'digest_username', 'digest_password'
9
+ htdigest.flush
10
+
11
+ config[:UserDB] = htdigest
12
+
13
+ digest_auth = WEBrick::HTTPAuth::DigestAuth.new config
14
+
15
+ class TestServlet < HTTPServlet::AbstractServlet
16
+ def do_GET(req, res)
17
+ @options[0][:authenticator].authenticate req, res
18
+ res.body = "You are authenticated to see the super secret data\n"
19
+ end
20
+ end
21
+
22
+ s = HTTPServer.new(:Port => 3000)
23
+ s.mount('/', TestServlet, {:authenticator => digest_auth})
24
+ trap("INT") do
25
+ File.delete('my_password_file')
26
+ s.shutdown
27
+ end
28
+ s.start
data/examples/fetch.rb ADDED
@@ -0,0 +1,30 @@
1
+ require 'rubygems'
2
+ require 'ZMachine'
3
+ require '../lib/z-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
+ ZMachine.run do
14
+ urls.each do |url|
15
+ http = ZMachine::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
+ ZMachine.stop if pending < 1
22
+ }
23
+ http.errback {
24
+ puts "#{url}\n" + http.error
25
+
26
+ pending -= 1
27
+ ZMachine.stop if pending < 1
28
+ }
29
+ end
30
+ end
@@ -0,0 +1,51 @@
1
+ $: << 'lib' << '../lib'
2
+
3
+ require 'ZMachine'
4
+ require 'z-http'
5
+ require 'fiber'
6
+
7
+ # Using Fibers in Ruby 1.9 to simulate blocking IO / IO scheduling
8
+ # while using the async ZMachine API's
9
+
10
+ def async_fetch(url)
11
+ f = Fiber.current
12
+ http = ZMachine::HttpRequest.new(url, :connect_timeout => 10, :inactivity_timeout => 20).get
13
+
14
+ http.callback { f.resume(http) }
15
+ http.errback { f.resume(http) }
16
+
17
+ Fiber.yield
18
+
19
+ if http.error
20
+ p [:HTTP_ERROR, http.error]
21
+ end
22
+
23
+ http
24
+ end
25
+
26
+ ZMachine.run do
27
+ Fiber.new{
28
+
29
+ puts "Setting up HTTP request #1"
30
+ data = async_fetch('http://0.0.0.0/')
31
+ puts "Fetched page #1: #{data.response_header.status}"
32
+
33
+ puts "Setting up HTTP request #2"
34
+ data = async_fetch('http://www.yahoo.com/')
35
+ puts "Fetched page #2: #{data.response_header.status}"
36
+
37
+ puts "Setting up HTTP request #3"
38
+ data = async_fetch('http://non-existing.domain/')
39
+ puts "Fetched page #3: #{data.response_header.status}"
40
+
41
+ ZMachine.stop
42
+ }.resume
43
+ end
44
+
45
+ puts "Done"
46
+
47
+ # Setting up HTTP request #1
48
+ # Fetched page #1: 302
49
+ # Setting up HTTP request #2
50
+ # Fetched page #2: 200
51
+ # Done
data/examples/multi.rb ADDED
@@ -0,0 +1,25 @@
1
+ $: << '../lib' << 'lib'
2
+
3
+ require 'ZMachine'
4
+ require 'z-http'
5
+
6
+ ZMachine.run {
7
+ multi = ZMachine::MultiRequest.new
8
+
9
+ reqs = [
10
+ 'http://google.com/',
11
+ 'http://google.ca:81/'
12
+ ]
13
+
14
+ reqs.each_with_index do |url, idx|
15
+ http = ZMachine::HttpRequest.new(url, :connect_timeout => 1)
16
+ req = http.get
17
+ multi.add idx, req
18
+ end
19
+
20
+ multi.callback do
21
+ p multi.responses[:callback].size
22
+ p multi.responses[:errback].size
23
+ ZMachine.stop
24
+ end
25
+ }
@@ -0,0 +1,35 @@
1
+ $: << 'lib' << '../lib'
2
+
3
+ require 'z-http'
4
+ require 'z-http/middleware/oauth'
5
+ require 'z-http/middleware/json_response'
6
+
7
+ require 'pp'
8
+
9
+ OAuthConfig = {
10
+ :consumer_key => '',
11
+ :consumer_secret => '',
12
+ :access_token => '',
13
+ :access_token_secret => ''
14
+ }
15
+
16
+ ZMachine.run do
17
+ # automatically parse the JSON response into a Ruby object
18
+ ZMachine::HttpRequest.use ZMachine::Middleware::JSONResponse
19
+
20
+ # sign the request with OAuth credentials
21
+ conn = ZMachine::HttpRequest.new('http://api.twitter.com/1/statuses/home_timeline.json')
22
+ conn.use ZMachine::Middleware::OAuth, OAuthConfig
23
+
24
+ http = conn.get
25
+ http.callback do
26
+ pp http.response
27
+ ZMachine.stop
28
+ end
29
+
30
+ http.errback do
31
+ puts "Failed retrieving user stream."
32
+ pp http.response
33
+ ZMachine.stop
34
+ end
35
+ end