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
data/spec/stallion.rb ADDED
@@ -0,0 +1,296 @@
1
+ # #--
2
+ # Includes portion originally Copyright (C)2008 Michael Fellinger
3
+ # license See file LICENSE for details
4
+ # #--
5
+
6
+ require 'rack'
7
+
8
+ module Stallion
9
+ class Mount
10
+ def initialize(name, *methods, &block)
11
+ @name, @methods, @block = name, methods, block
12
+ end
13
+
14
+ def ride
15
+ @block.call
16
+ end
17
+
18
+ def match?(request)
19
+ method = request['REQUEST_METHOD']
20
+ right_method = @methods.empty? or @methods.include?(method)
21
+ end
22
+ end
23
+
24
+ class Stable
25
+ attr_reader :request, :response
26
+
27
+ def initialize
28
+ @boxes = {}
29
+ end
30
+
31
+ def in(path, *methods, &block)
32
+ mount = Mount.new(path, *methods, &block)
33
+ @boxes[[path, methods]] = mount
34
+ mount
35
+ end
36
+
37
+ def call(request, response)
38
+ @request, @response = request, response
39
+ @boxes.each do |(path, methods), mount|
40
+ if mount.match?(request)
41
+ mount.ride
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ STABLES = {}
48
+
49
+ def self.saddle(name = nil)
50
+ STABLES[name] = stable = Stable.new
51
+ yield stable
52
+ end
53
+
54
+ def self.run(options = {})
55
+ options = {:Host => "127.0.0.1", :Port => 8090}.merge(options)
56
+ Rack::Handler.get(:puma).run(Rack::Lint.new(self), options)
57
+ end
58
+
59
+ def self.call(env)
60
+ request = Rack::Request.new(env)
61
+ response = Rack::Response.new
62
+
63
+ STABLES.each do |name, stable|
64
+ stable.call(request, response)
65
+ end
66
+
67
+ response.finish
68
+ end
69
+ end
70
+
71
+ Stallion.saddle :spec do |stable|
72
+ stable.in '/' do
73
+
74
+ if stable.request.path_info == '/fail'
75
+ stable.response.status = 404
76
+
77
+ elsif stable.request.path_info == '/fail_with_nonstandard_response'
78
+ stable.response.status = 420
79
+
80
+ elsif stable.request.query_string == 'q=test'
81
+ stable.response.write 'test'
82
+
83
+ elsif stable.request.path_info == '/echo_query'
84
+ stable.response["ETag"] = "abcdefg"
85
+ stable.response["Last-Modified"] = "Fri, 13 Aug 2010 17:31:21 GMT"
86
+ stable.response.write stable.request.query_string
87
+
88
+ elsif stable.request.path_info == '/echo_headers'
89
+ stable.response["Set-Cookie"] = "test=yes"
90
+ stable.response["X-Forward-Host"] = "proxy.local"
91
+ stable.response.write stable.request.query_string
92
+
93
+ elsif stable.request.path_info == '/echo_content_length'
94
+ stable.response.write stable.request.content_length
95
+
96
+ elsif stable.request.path_info == '/echo_content_length_from_header'
97
+ stable.response.write "content-length:#{stable.request.env["CONTENT_LENGTH"]}"
98
+
99
+ elsif stable.request.head? && stable.request.path_info == '/'
100
+ stable.response.status = 200
101
+
102
+ elsif stable.request.delete?
103
+ stable.response.status = 200
104
+
105
+ elsif stable.request.put?
106
+ stable.response.write stable.request.body.read
107
+
108
+ elsif stable.request.post? || stable.request.patch?
109
+ if stable.request.path_info == '/echo_content_type'
110
+ stable.response["Content-Type"] = stable.request.env["CONTENT_TYPE"] || 'text/html'
111
+ stable.response.write stable.request.env["CONTENT_TYPE"]
112
+ else
113
+ stable.response.write stable.request.body.read
114
+ end
115
+
116
+ elsif stable.request.path_info == '/set_cookie'
117
+ stable.response["Set-Cookie"] = "id=1; expires=Sat, 09 Aug 2031 17:53:39 GMT; path=/;"
118
+ stable.response.write "cookie set"
119
+
120
+ elsif stable.request.path_info == '/set_multiple_cookies'
121
+ stable.response["Set-Cookie"] = [
122
+ "id=1; expires=Sat, 09 Aug 2031 17:53:39 GMT; path=/;",
123
+ "id=2;"
124
+ ]
125
+ stable.response.write "cookies set"
126
+
127
+ elsif stable.request.path_info == '/echo_cookie'
128
+ stable.response.write stable.request.env["HTTP_COOKIE"]
129
+
130
+ elsif stable.request.path_info == '/timeout'
131
+ sleep(10)
132
+ stable.response.write 'timeout'
133
+
134
+ elsif stable.request.path_info == '/cookie_parrot'
135
+ stable.response.status = 200
136
+ stable.response["Set-Cookie"] = stable.request.env['HTTP_COOKIE']
137
+
138
+ elsif stable.request.path_info == '/redirect'
139
+ stable.response.status = 301
140
+ stable.response["Location"] = "/gzip"
141
+ stable.response.write 'redirect'
142
+
143
+ elsif stable.request.path_info == '/redirect/created'
144
+ stable.response.status = 201
145
+ stable.response["Location"] = "/"
146
+ stable.response.write 'Hello, World!'
147
+
148
+ elsif stable.request.path_info == '/redirect/multiple-with-cookie'
149
+ stable.response.status = 301
150
+ stable.response["Set-Cookie"] = "another_id=1; expires=Sat, 09 Aug 2031 17:53:39 GMT; path=/;"
151
+ stable.response["Location"] = "/redirect"
152
+ stable.response.write 'redirect'
153
+
154
+ elsif stable.request.path_info == '/redirect/bad'
155
+ stable.response.status = 301
156
+ stable.response["Location"] = "http://127.0.0.1:8090"
157
+
158
+ elsif stable.request.path_info == '/redirect/timeout'
159
+ stable.response.status = 301
160
+ stable.response["Location"] = "http://127.0.0.1:8090/timeout"
161
+
162
+ elsif stable.request.path_info == '/redirect/head'
163
+ stable.response.status = 301
164
+ stable.response["Location"] = "/"
165
+
166
+ elsif stable.request.path_info == '/redirect/middleware_redirects_1'
167
+ stable.response.status = 301
168
+ stable.response["EM-Middleware"] = stable.request.env["HTTP_EM_MIDDLEWARE"]
169
+ stable.response["Location"] = "/redirect/middleware_redirects_2"
170
+
171
+ elsif stable.request.path_info == '/redirect/middleware_redirects_2'
172
+ stable.response.status = 301
173
+ stable.response["EM-Middleware"] = stable.request.env["HTTP_EM_MIDDLEWARE"]
174
+ stable.response["Location"] = "/redirect/middleware_redirects_3"
175
+
176
+ elsif stable.request.path_info == '/redirect/middleware_redirects_3'
177
+ stable.response.status = 200
178
+ stable.response["EM-Middleware"] = stable.request.env["HTTP_EM_MIDDLEWARE"]
179
+
180
+ elsif stable.request.path_info == '/redirect/nohost'
181
+ stable.response.status = 301
182
+ stable.response["Location"] = "http:/"
183
+
184
+ elsif stable.request.path_info == '/redirect/badhost'
185
+ stable.response.status = 301
186
+ stable.response["Location"] = "http://$$$@$!%&^"
187
+
188
+ elsif stable.request.path_info == '/gzip'
189
+ io = StringIO.new
190
+ gzip = Zlib::GzipWriter.new(io)
191
+ gzip << "compressed"
192
+ gzip.close
193
+
194
+ stable.response.write io.string
195
+ stable.response["Content-Encoding"] = "gzip"
196
+
197
+ elsif stable.request.path_info == '/gzip-large'
198
+ contents = File.open(File.dirname(__FILE__) + "/fixtures/gzip-sample.gz", 'r') { |f| f.read }
199
+
200
+ stable.response.write contents
201
+ stable.response["Content-Encoding"] = "gzip"
202
+
203
+ elsif stable.request.path_info == '/deflate'
204
+ deflater = Zlib::Deflate.new(
205
+ Zlib::DEFAULT_COMPRESSION,
206
+ -Zlib::MAX_WBITS, # drop the zlib header which causes both Safari and IE to choke
207
+ Zlib::DEF_MEM_LEVEL,
208
+ Zlib::DEFAULT_STRATEGY
209
+ )
210
+ deflater.deflate("compressed")
211
+ stable.response.write deflater.finish
212
+ stable.response["Content-Encoding"] = "deflate"
213
+
214
+ elsif stable.request.env["HTTP_IF_NONE_MATCH"]
215
+ stable.response.status = 304
216
+
217
+ elsif stable.request.path_info == '/auth' && stable.request.env["HTTP_AUTHORIZATION"]
218
+ stable.response.status = 200
219
+ stable.response.write stable.request.env["HTTP_AUTHORIZATION"]
220
+ elsif stable.request.path_info == '/authtest'
221
+ auth = "Basic %s" % Base64.encode64(['user', 'pass'].join(':')).split.join
222
+ if auth == stable.request.env["HTTP_AUTHORIZATION"]
223
+ stable.response.status = 200
224
+ stable.response.write 'success'
225
+ else
226
+ stable.response.status = 401
227
+ end
228
+ elsif stable.request.path_info == '/relative-location'
229
+ stable.response.status = 301
230
+ stable.response["Location"] = '/forwarded'
231
+ elsif stable.request.path_info == '/echo-user-agent'
232
+ stable.response.write stable.request.env["HTTP_USER_AGENT"].inspect
233
+
234
+ elsif
235
+ stable.response.write 'Hello, World!'
236
+ end
237
+
238
+ end
239
+ end
240
+
241
+ puma = Thread.new do
242
+ begin
243
+ Stallion.run :Host => '127.0.0.1', :Port => 8090
244
+ rescue => e
245
+ print e
246
+ end
247
+ end
248
+
249
+ # Simple HTTP Proxy server
250
+
251
+ Thread.new do
252
+ server = TCPServer.new('127.0.0.1', 8083)
253
+ loop do
254
+ session = server.accept
255
+ request = ""
256
+ while (data = session.gets) != "\r\n"
257
+ request << data
258
+ end
259
+ parts = request.split("\r\n")
260
+ method, destination, http_version = parts.first.split(' ')
261
+ proxy = parts.find { |part| part =~ /Proxy-Authorization/ }
262
+ if destination =~ /^http:/
263
+ uri = Addressable::URI.parse(destination)
264
+ absolute_path = uri.path + (uri.query ? "?#{uri.query}" : "")
265
+ client = TCPSocket.open(uri.host, uri.port || 80)
266
+
267
+ client.write "#{method} #{absolute_path} #{http_version}\r\n"
268
+ parts[1..-1].each do |part|
269
+ client.write "#{part}\r\n"
270
+ end
271
+
272
+ client.write "\r\n"
273
+ client.flush
274
+ client.close_write
275
+
276
+ # Take the initial line from the upstream response
277
+ session.write client.gets
278
+
279
+ if proxy
280
+ session.write "X-Proxy-Auth: #{proxy}\r\n"
281
+ end
282
+
283
+ # What (absolute) uri was requested? Send it back in a header
284
+ session.write "X-The-Requested-URI: #{destination}\r\n"
285
+
286
+ while data = client.gets
287
+ session.write data
288
+ end
289
+ session.flush
290
+ client.close
291
+ end
292
+ session.close
293
+ end
294
+ end
295
+
296
+ sleep(1)
@@ -0,0 +1,42 @@
1
+ class StubServer
2
+ module Server
3
+ def receive_data(data)
4
+ if echo?
5
+ send_data("HTTP/1.0 200 OK\r\nContent-Length: #{data.bytesize}\r\nContent-Type: text/plain\r\n\r\n")
6
+ send_data(data)
7
+ else
8
+ send_data @response
9
+ end
10
+
11
+ close_connection_after_writing
12
+ end
13
+
14
+ def echo= flag
15
+ @echo = flag
16
+ end
17
+
18
+ def echo?
19
+ !!@echo
20
+ end
21
+
22
+ def response=(response)
23
+ @response = response
24
+ end
25
+ end
26
+
27
+ def initialize options = {}
28
+ options = {:response => options} if options.kind_of?(String)
29
+ options = {:port => 8081, :host => '127.0.0.1'}.merge(options)
30
+
31
+ host = options[:host]
32
+ port = options[:port]
33
+ @sig = ZMachine::start_server(host, port, Server) do |server|
34
+ server.response = options[:response]
35
+ server.echo = options[:echo]
36
+ end
37
+ end
38
+
39
+ def stop
40
+ ZMachine.stop_server @sig
41
+ end
42
+ end
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'z-http/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'z-http-request'
7
+ s.version = ZMachine::HttpRequest::VERSION
8
+
9
+ s.platform = Gem::Platform::RUBY
10
+ s.authors = ["Ilya Grigorik", "LiquidM, Inc."]
11
+ s.email = ['ilya@igvita.com', "opensource@liquidm.com"]
12
+ s.homepage = 'http://github.com/liquidm/z-http-request'
13
+ s.summary = 'ZMachine based, async HTTP Request client'
14
+ s.description = s.summary
15
+ s.license = 'MIT'
16
+ s.rubyforge_project = 'z-http-request'
17
+
18
+ s.add_dependency 'addressable', '>= 2.3.4'
19
+ s.add_dependency 'cookiejar'
20
+ s.add_dependency 'zmachine'
21
+ s.add_dependency 'http_parser.rb', '>= 0.6.0.beta.2'
22
+
23
+ s.add_development_dependency 'puma'
24
+ s.add_development_dependency 'multi_json'
25
+ s.add_development_dependency 'rack'
26
+ s.add_development_dependency 'rake'
27
+ s.add_development_dependency 'rspec'
28
+
29
+ s.files = `git ls-files`.split("\n")
30
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
31
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
32
+ s.require_paths = ['lib']
33
+ end
metadata ADDED
@@ -0,0 +1,248 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: z-http-request
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ilya Grigorik
8
+ - LiquidM, Inc.
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-11-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: addressable
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - '>='
19
+ - !ruby/object:Gem::Version
20
+ version: 2.3.4
21
+ requirement: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - '>='
24
+ - !ruby/object:Gem::Version
25
+ version: 2.3.4
26
+ prerelease: false
27
+ type: :runtime
28
+ - !ruby/object:Gem::Dependency
29
+ name: cookiejar
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - '>='
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - '>='
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ prerelease: false
41
+ type: :runtime
42
+ - !ruby/object:Gem::Dependency
43
+ name: zmachine
44
+ version_requirements: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ prerelease: false
55
+ type: :runtime
56
+ - !ruby/object:Gem::Dependency
57
+ name: http_parser.rb
58
+ version_requirements: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: 0.6.0.beta.2
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - '>='
66
+ - !ruby/object:Gem::Version
67
+ version: 0.6.0.beta.2
68
+ prerelease: false
69
+ type: :runtime
70
+ - !ruby/object:Gem::Dependency
71
+ name: puma
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ prerelease: false
83
+ type: :development
84
+ - !ruby/object:Gem::Dependency
85
+ name: multi_json
86
+ version_requirements: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ prerelease: false
97
+ type: :development
98
+ - !ruby/object:Gem::Dependency
99
+ name: rack
100
+ version_requirements: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ prerelease: false
111
+ type: :development
112
+ - !ruby/object:Gem::Dependency
113
+ name: rake
114
+ version_requirements: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ prerelease: false
125
+ type: :development
126
+ - !ruby/object:Gem::Dependency
127
+ name: rspec
128
+ version_requirements: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ prerelease: false
139
+ type: :development
140
+ description: ZMachine based, async HTTP Request client
141
+ email:
142
+ - ilya@igvita.com
143
+ - opensource@liquidm.com
144
+ executables: []
145
+ extensions: []
146
+ extra_rdoc_files: []
147
+ files:
148
+ - .gemtest
149
+ - .gitignore
150
+ - .rspec
151
+ - .ruby-version
152
+ - .travis.yml
153
+ - Gemfile
154
+ - README.md
155
+ - Rakefile
156
+ - benchmarks/clients.rb
157
+ - benchmarks/em-excon.rb
158
+ - benchmarks/em-profile.gif
159
+ - benchmarks/em-profile.txt
160
+ - benchmarks/server.rb
161
+ - examples/.gitignore
162
+ - examples/digest_auth/client.rb
163
+ - examples/digest_auth/server.rb
164
+ - examples/fetch.rb
165
+ - examples/fibered-http.rb
166
+ - examples/multi.rb
167
+ - examples/oauth-tweet.rb
168
+ - examples/socks5.rb
169
+ - lib/z-http-request.rb
170
+ - lib/z-http.rb
171
+ - lib/z-http/client.rb
172
+ - lib/z-http/core_ext/bytesize.rb
173
+ - lib/z-http/decoders.rb
174
+ - lib/z-http/http_client_options.rb
175
+ - lib/z-http/http_connection.rb
176
+ - lib/z-http/http_connection_options.rb
177
+ - lib/z-http/http_encoding.rb
178
+ - lib/z-http/http_header.rb
179
+ - lib/z-http/http_status_codes.rb
180
+ - lib/z-http/middleware/digest_auth.rb
181
+ - lib/z-http/middleware/json_response.rb
182
+ - lib/z-http/middleware/oauth.rb
183
+ - lib/z-http/middleware/oauth2.rb
184
+ - lib/z-http/multi.rb
185
+ - lib/z-http/request.rb
186
+ - lib/z-http/version.rb
187
+ - spec/client_spec.rb
188
+ - spec/digest_auth_spec.rb
189
+ - spec/dns_spec.rb
190
+ - spec/encoding_spec.rb
191
+ - spec/external_spec.rb
192
+ - spec/fixtures/google.ca
193
+ - spec/fixtures/gzip-sample.gz
194
+ - spec/gzip_spec.rb
195
+ - spec/helper.rb
196
+ - spec/middleware_spec.rb
197
+ - spec/multi_spec.rb
198
+ - spec/pipelining_spec.rb
199
+ - spec/redirect_spec.rb
200
+ - spec/socksify_proxy_spec.rb
201
+ - spec/spec_helper.rb
202
+ - spec/ssl_spec.rb
203
+ - spec/stallion.rb
204
+ - spec/stub_server.rb
205
+ - z-http-request.gemspec
206
+ homepage: http://github.com/liquidm/z-http-request
207
+ licenses:
208
+ - MIT
209
+ metadata: {}
210
+ post_install_message:
211
+ rdoc_options: []
212
+ require_paths:
213
+ - lib
214
+ required_ruby_version: !ruby/object:Gem::Requirement
215
+ requirements:
216
+ - - '>='
217
+ - !ruby/object:Gem::Version
218
+ version: '0'
219
+ required_rubygems_version: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - '>='
222
+ - !ruby/object:Gem::Version
223
+ version: '0'
224
+ requirements: []
225
+ rubyforge_project: z-http-request
226
+ rubygems_version: 2.1.9
227
+ signing_key:
228
+ specification_version: 4
229
+ summary: ZMachine based, async HTTP Request client
230
+ test_files:
231
+ - spec/client_spec.rb
232
+ - spec/digest_auth_spec.rb
233
+ - spec/dns_spec.rb
234
+ - spec/encoding_spec.rb
235
+ - spec/external_spec.rb
236
+ - spec/fixtures/google.ca
237
+ - spec/fixtures/gzip-sample.gz
238
+ - spec/gzip_spec.rb
239
+ - spec/helper.rb
240
+ - spec/middleware_spec.rb
241
+ - spec/multi_spec.rb
242
+ - spec/pipelining_spec.rb
243
+ - spec/redirect_spec.rb
244
+ - spec/socksify_proxy_spec.rb
245
+ - spec/spec_helper.rb
246
+ - spec/ssl_spec.rb
247
+ - spec/stallion.rb
248
+ - spec/stub_server.rb