openlogic-resourceful 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +45 -0
- data/MIT-LICENSE +21 -0
- data/Manifest +46 -0
- data/README.markdown +92 -0
- data/Rakefile +91 -0
- data/lib/resourceful.rb +27 -0
- data/lib/resourceful/abstract_form_data.rb +30 -0
- data/lib/resourceful/authentication_manager.rb +107 -0
- data/lib/resourceful/cache_manager.rb +242 -0
- data/lib/resourceful/exceptions.rb +34 -0
- data/lib/resourceful/header.rb +355 -0
- data/lib/resourceful/http_accessor.rb +103 -0
- data/lib/resourceful/memcache_cache_manager.rb +75 -0
- data/lib/resourceful/multipart_form_data.rb +46 -0
- data/lib/resourceful/net_http_adapter.rb +84 -0
- data/lib/resourceful/promiscuous_basic_authenticator.rb +18 -0
- data/lib/resourceful/request.rb +235 -0
- data/lib/resourceful/resource.rb +179 -0
- data/lib/resourceful/response.rb +221 -0
- data/lib/resourceful/simple.rb +36 -0
- data/lib/resourceful/stubbed_resource_proxy.rb +47 -0
- data/lib/resourceful/urlencoded_form_data.rb +19 -0
- data/lib/resourceful/util.rb +6 -0
- data/openlogic-resourceful.gemspec +51 -0
- data/resourceful.gemspec +51 -0
- data/spec/acceptance/authorization_spec.rb +16 -0
- data/spec/acceptance/caching_spec.rb +190 -0
- data/spec/acceptance/header_spec.rb +24 -0
- data/spec/acceptance/redirecting_spec.rb +12 -0
- data/spec/acceptance/resource_spec.rb +84 -0
- data/spec/acceptance/resourceful_spec.rb +56 -0
- data/spec/acceptance_shared_specs.rb +44 -0
- data/spec/caching_spec.rb +89 -0
- data/spec/old_acceptance_specs.rb +378 -0
- data/spec/resourceful/header_spec.rb +153 -0
- data/spec/resourceful/http_accessor_spec.rb +56 -0
- data/spec/resourceful/multipart_form_data_spec.rb +84 -0
- data/spec/resourceful/promiscuous_basic_authenticator_spec.rb +30 -0
- data/spec/resourceful/resource_spec.rb +20 -0
- data/spec/resourceful/response_spec.rb +51 -0
- data/spec/resourceful/urlencoded_form_data_spec.rb +64 -0
- data/spec/resourceful_spec.rb +79 -0
- data/spec/simple_sinatra_server.rb +74 -0
- data/spec/simple_sinatra_server_spec.rb +98 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +31 -0
- metadata +192 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/spec_helper.rb"
|
2
|
+
|
3
|
+
|
4
|
+
describe Resourceful do
|
5
|
+
it "should have a default accessor" do
|
6
|
+
Resourceful.default_accessor.should be_kind_of Resourceful::HttpAccessor
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should delegate request making (minimal)" do
|
10
|
+
stub_resource = mock(:resource)
|
11
|
+
Resourceful.default_accessor.should_receive(:resource).with( 'http://foo.invalid/bar').and_return(stub_resource)
|
12
|
+
stub_resource.should_receive(:request).with(:get, nil, {})
|
13
|
+
|
14
|
+
Resourceful.request(:get, 'http://foo.invalid/bar')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should delegate request making (with header)" do
|
18
|
+
stub_resource = mock(:resource)
|
19
|
+
Resourceful.default_accessor.should_receive(:resource).with( 'http://foo.invalid/bar').and_return(stub_resource)
|
20
|
+
stub_resource.should_receive(:request).with(:get, nil, {:accept => :json})
|
21
|
+
|
22
|
+
Resourceful.request(:get, 'http://foo.invalid/bar', :accept => :json)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should delegate request making (with body)" do
|
26
|
+
stub_resource = mock(:resource)
|
27
|
+
Resourceful.default_accessor.should_receive(:resource).with( 'http://foo.invalid/bar').and_return(stub_resource)
|
28
|
+
stub_resource.should_receive(:request).with(:get, 'body', {})
|
29
|
+
|
30
|
+
Resourceful.request(:get, 'http://foo.invalid/bar', {}, 'body')
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should allow convenient get requests" do
|
34
|
+
stub_resource = mock(:resource)
|
35
|
+
Resourceful.default_accessor.should_receive(:resource).with( 'http://foo.invalid/bar').and_return(stub_resource)
|
36
|
+
stub_resource.should_receive(:request).with(:get, nil, :header_marker)
|
37
|
+
|
38
|
+
Resourceful.get 'http://foo.invalid/bar', :header_marker
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should allow convenient head requests" do
|
42
|
+
stub_resource = mock(:resource)
|
43
|
+
Resourceful.default_accessor.should_receive(:resource).with( 'http://foo.invalid/bar').and_return(stub_resource)
|
44
|
+
stub_resource.should_receive(:request).with(:head, nil, :header_marker)
|
45
|
+
|
46
|
+
Resourceful.head 'http://foo.invalid/bar', :header_marker
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should allow convenient delete requests" do
|
50
|
+
stub_resource = mock(:resource)
|
51
|
+
Resourceful.default_accessor.should_receive(:resource).with( 'http://foo.invalid/bar').and_return(stub_resource)
|
52
|
+
stub_resource.should_receive(:request).with(:delete, nil, :header_marker)
|
53
|
+
|
54
|
+
Resourceful.delete 'http://foo.invalid/bar', :header_marker
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should allow convenient post requests" do
|
58
|
+
stub_resource = mock(:resource)
|
59
|
+
Resourceful.default_accessor.should_receive(:resource).with( 'http://foo.invalid/bar').and_return(stub_resource)
|
60
|
+
stub_resource.should_receive(:request).with(:post, :body_marker, :header_marker)
|
61
|
+
|
62
|
+
Resourceful.post 'http://foo.invalid/bar', :body_marker, :header_marker
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should allow convenient put requests" do
|
66
|
+
stub_resource = mock(:resource)
|
67
|
+
Resourceful.default_accessor.should_receive(:resource).with( 'http://foo.invalid/bar').and_return(stub_resource)
|
68
|
+
stub_resource.should_receive(:request).with(:put, :body_marker, :header_marker)
|
69
|
+
|
70
|
+
Resourceful.put 'http://foo.invalid/bar', :body_marker, :header_marker
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
it "should allow new authenticators to be added to default accessor" do
|
75
|
+
Resourceful.default_accessor.should_receive(:add_authenticator).with(:my_authentcator_marker)
|
76
|
+
|
77
|
+
Resourceful.add_authenticator(:my_authentcator_marker)
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
|
2
|
+
require 'sinatra'
|
3
|
+
|
4
|
+
def any(path, opts={}, &blk)
|
5
|
+
%w[head get post put delete].each do |verb|
|
6
|
+
send verb, path, opts, &blk
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def set_request_params_as_response_header!
|
11
|
+
params.each { |k,v| response[k] = v }
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_request_header_in_body!
|
15
|
+
response['Content-Type'] ||= "application/yaml"
|
16
|
+
headers = request.env.reject { |k,v| !v.is_a?(String) }
|
17
|
+
headers.to_yaml
|
18
|
+
end
|
19
|
+
|
20
|
+
get '/' do
|
21
|
+
"Hello, world!"
|
22
|
+
end
|
23
|
+
|
24
|
+
post '/' do
|
25
|
+
request.body
|
26
|
+
end
|
27
|
+
|
28
|
+
put '/' do
|
29
|
+
request.body
|
30
|
+
end
|
31
|
+
|
32
|
+
delete '/' do
|
33
|
+
"Deleted"
|
34
|
+
end
|
35
|
+
|
36
|
+
# Responds with the method used for the request
|
37
|
+
any '/method' do
|
38
|
+
request.env['REQUEST_METHOD']
|
39
|
+
end
|
40
|
+
|
41
|
+
# Responds with the response code in the url
|
42
|
+
any '/code/:code' do
|
43
|
+
status params[:code]
|
44
|
+
set_request_params_as_response_header!
|
45
|
+
set_request_header_in_body!
|
46
|
+
end
|
47
|
+
|
48
|
+
# Sets the response header from the query string, and
|
49
|
+
# dumps the request header into the body as yaml for inspection
|
50
|
+
any '/header' do
|
51
|
+
set_request_params_as_response_header!
|
52
|
+
set_request_header_in_body!
|
53
|
+
end
|
54
|
+
|
55
|
+
# Takes a modified=httpdate as a query param, and a If-Modified-Since header,
|
56
|
+
# and responds 304 if they're the same
|
57
|
+
get '/cached' do
|
58
|
+
set_request_params_as_response_header!
|
59
|
+
set_request_header_in_body!
|
60
|
+
|
61
|
+
response['Last-Modified'] = params[:modified]
|
62
|
+
|
63
|
+
modtime = params[:modified]
|
64
|
+
imstime = request.env['HTTP_IF_MODIFIED_SINCE']
|
65
|
+
|
66
|
+
if modtime && imstime && modtime == imstime
|
67
|
+
status 304
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
Sinatra::Default.set(
|
72
|
+
:port => 42682
|
73
|
+
)
|
74
|
+
|
@@ -0,0 +1,98 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'sinatra'
|
4
|
+
require 'sinatra/test/rspec'
|
5
|
+
|
6
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
7
|
+
|
8
|
+
describe "GET /" do
|
9
|
+
it 'should render "Hello, world!"' do
|
10
|
+
get '/'
|
11
|
+
@response.should be_ok
|
12
|
+
@response.body.should == "Hello, world!"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "POST /" do
|
17
|
+
it 'should be 201 with no body' do
|
18
|
+
post '/'
|
19
|
+
@response.should be_ok
|
20
|
+
@response.body.should == ""
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should return the request body as the response body' do
|
24
|
+
body = "Some text"
|
25
|
+
post '/', body
|
26
|
+
@response.should be_ok
|
27
|
+
@response.body.should == body
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "PUT /" do
|
32
|
+
it 'should be 200 with no body' do
|
33
|
+
put '/'
|
34
|
+
@response.should be_ok
|
35
|
+
@response.body.should == ""
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should return the request body as the response body' do
|
39
|
+
body = "Some text"
|
40
|
+
put '/', body
|
41
|
+
@response.should be_ok
|
42
|
+
@response.body.should == body
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "DELETE /" do
|
47
|
+
it 'should render "Deleted"' do
|
48
|
+
delete '/'
|
49
|
+
@response.should be_ok
|
50
|
+
@response.body.should == "Deleted"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "/method" do
|
55
|
+
it 'should respond with the method used to make the request' do
|
56
|
+
%w[get post put delete].each do |verb|
|
57
|
+
send verb, '/method'
|
58
|
+
@response.body.should == verb.upcase
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "/code/nnn" do
|
64
|
+
it 'should respond with the code provided in the url' do
|
65
|
+
# Just try a handful
|
66
|
+
[200, 201, 301, 302, 304, 403, 404, 500].each do |code|
|
67
|
+
get "/code/#{code}"
|
68
|
+
@response.status.should == code
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "/header" do
|
74
|
+
it 'should set response headers from the query string' do
|
75
|
+
get "/header", "X-Foo" => "Bar"
|
76
|
+
@response['X-Foo'].should == "Bar"
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should dump the request headers into the body as yaml' do
|
80
|
+
get '/header', {}, "X-Foo" => "Bar"
|
81
|
+
body = YAML.load(@response.body)
|
82
|
+
body['X-Foo'].should == "Bar"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "/cache" do
|
87
|
+
it 'should be normal 200 if the modified query param and the ims header dont match' do
|
88
|
+
now = Time.now
|
89
|
+
get '/cached', {"modified" => now.httpdate}, {"HTTP_IF_MODIFIED_SINCE" => (now - 3600).httpdate}
|
90
|
+
@response.should be_ok
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should be 304 if the modified query param and the ims header are the same' do
|
94
|
+
now = Time.now
|
95
|
+
get '/cached', {"modified" => now.httpdate}, {"HTTP_IF_MODIFIED_SINCE" => now.httpdate}
|
96
|
+
@response.status.should == 304
|
97
|
+
end
|
98
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
require 'pp'
|
4
|
+
|
5
|
+
__DIR__ = File.dirname(__FILE__)
|
6
|
+
|
7
|
+
$LOAD_PATH << File.join(__DIR__, "..", "lib")
|
8
|
+
require 'resourceful'
|
9
|
+
|
10
|
+
$LOAD_PATH << __DIR__ # ./spec
|
11
|
+
|
12
|
+
# Spawn the server in another process
|
13
|
+
|
14
|
+
@server = Thread.new do
|
15
|
+
|
16
|
+
require 'simple_sinatra_server'
|
17
|
+
Sinatra::Default.set(
|
18
|
+
:run => true,
|
19
|
+
:logging => false
|
20
|
+
)
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
# Kill the server process when rspec finishes
|
25
|
+
at_exit { @server.exit }
|
26
|
+
|
27
|
+
|
28
|
+
# Give the app a change to initialize
|
29
|
+
$stderr.puts "Waiting for thin to initialize..."
|
30
|
+
sleep 0.2
|
31
|
+
|
metadata
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: openlogic-resourceful
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- OpenLogic
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-04-13 00:00:00 -06:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: addressable
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 2.1.0
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: httpauth
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: options
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.1.1
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: thin
|
47
|
+
type: :development
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: yard
|
57
|
+
type: :development
|
58
|
+
version_requirement:
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: sinatra
|
67
|
+
type: :development
|
68
|
+
version_requirement:
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
version:
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rspec
|
77
|
+
type: :development
|
78
|
+
version_requirement:
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: "0"
|
84
|
+
version:
|
85
|
+
description: An HTTP library for Ruby that takes advantage of everything HTTP has to offer.
|
86
|
+
email: engteam@openlogic.com
|
87
|
+
executables: []
|
88
|
+
|
89
|
+
extensions: []
|
90
|
+
|
91
|
+
extra_rdoc_files:
|
92
|
+
- README.markdown
|
93
|
+
- lib/resourceful.rb
|
94
|
+
- lib/resourceful/abstract_form_data.rb
|
95
|
+
- lib/resourceful/authentication_manager.rb
|
96
|
+
- lib/resourceful/cache_manager.rb
|
97
|
+
- lib/resourceful/exceptions.rb
|
98
|
+
- lib/resourceful/header.rb
|
99
|
+
- lib/resourceful/http_accessor.rb
|
100
|
+
- lib/resourceful/memcache_cache_manager.rb
|
101
|
+
- lib/resourceful/multipart_form_data.rb
|
102
|
+
- lib/resourceful/net_http_adapter.rb
|
103
|
+
- lib/resourceful/promiscuous_basic_authenticator.rb
|
104
|
+
- lib/resourceful/request.rb
|
105
|
+
- lib/resourceful/resource.rb
|
106
|
+
- lib/resourceful/response.rb
|
107
|
+
- lib/resourceful/simple.rb
|
108
|
+
- lib/resourceful/stubbed_resource_proxy.rb
|
109
|
+
- lib/resourceful/urlencoded_form_data.rb
|
110
|
+
- lib/resourceful/util.rb
|
111
|
+
files:
|
112
|
+
- History.txt
|
113
|
+
- MIT-LICENSE
|
114
|
+
- Manifest
|
115
|
+
- README.markdown
|
116
|
+
- Rakefile
|
117
|
+
- lib/resourceful.rb
|
118
|
+
- lib/resourceful/abstract_form_data.rb
|
119
|
+
- lib/resourceful/authentication_manager.rb
|
120
|
+
- lib/resourceful/cache_manager.rb
|
121
|
+
- lib/resourceful/exceptions.rb
|
122
|
+
- lib/resourceful/header.rb
|
123
|
+
- lib/resourceful/http_accessor.rb
|
124
|
+
- lib/resourceful/memcache_cache_manager.rb
|
125
|
+
- lib/resourceful/multipart_form_data.rb
|
126
|
+
- lib/resourceful/net_http_adapter.rb
|
127
|
+
- lib/resourceful/promiscuous_basic_authenticator.rb
|
128
|
+
- lib/resourceful/request.rb
|
129
|
+
- lib/resourceful/resource.rb
|
130
|
+
- lib/resourceful/response.rb
|
131
|
+
- lib/resourceful/simple.rb
|
132
|
+
- lib/resourceful/stubbed_resource_proxy.rb
|
133
|
+
- lib/resourceful/urlencoded_form_data.rb
|
134
|
+
- lib/resourceful/util.rb
|
135
|
+
- openlogic-resourceful.gemspec
|
136
|
+
- resourceful.gemspec
|
137
|
+
- spec/acceptance/authorization_spec.rb
|
138
|
+
- spec/acceptance/caching_spec.rb
|
139
|
+
- spec/acceptance/header_spec.rb
|
140
|
+
- spec/acceptance/redirecting_spec.rb
|
141
|
+
- spec/acceptance/resource_spec.rb
|
142
|
+
- spec/acceptance/resourceful_spec.rb
|
143
|
+
- spec/acceptance_shared_specs.rb
|
144
|
+
- spec/caching_spec.rb
|
145
|
+
- spec/old_acceptance_specs.rb
|
146
|
+
- spec/resourceful/header_spec.rb
|
147
|
+
- spec/resourceful/http_accessor_spec.rb
|
148
|
+
- spec/resourceful/multipart_form_data_spec.rb
|
149
|
+
- spec/resourceful/promiscuous_basic_authenticator_spec.rb
|
150
|
+
- spec/resourceful/resource_spec.rb
|
151
|
+
- spec/resourceful/response_spec.rb
|
152
|
+
- spec/resourceful/urlencoded_form_data_spec.rb
|
153
|
+
- spec/resourceful_spec.rb
|
154
|
+
- spec/simple_sinatra_server.rb
|
155
|
+
- spec/simple_sinatra_server_spec.rb
|
156
|
+
- spec/spec.opts
|
157
|
+
- spec/spec_helper.rb
|
158
|
+
has_rdoc: true
|
159
|
+
homepage: http://github.com/paul/resourceful
|
160
|
+
licenses: []
|
161
|
+
|
162
|
+
post_install_message:
|
163
|
+
rdoc_options:
|
164
|
+
- --line-numbers
|
165
|
+
- --inline-source
|
166
|
+
- --title
|
167
|
+
- Openlogic-resourceful
|
168
|
+
- --main
|
169
|
+
- README.markdown
|
170
|
+
require_paths:
|
171
|
+
- lib
|
172
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
173
|
+
requirements:
|
174
|
+
- - ">="
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: "0"
|
177
|
+
version:
|
178
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
179
|
+
requirements:
|
180
|
+
- - ">="
|
181
|
+
- !ruby/object:Gem::Version
|
182
|
+
version: "1.2"
|
183
|
+
version:
|
184
|
+
requirements: []
|
185
|
+
|
186
|
+
rubyforge_project: openlogic-resourceful
|
187
|
+
rubygems_version: 1.3.5
|
188
|
+
signing_key:
|
189
|
+
specification_version: 3
|
190
|
+
summary: An HTTP library for Ruby that takes advantage of everything HTTP has to offer.
|
191
|
+
test_files: []
|
192
|
+
|