excon 0.9.5 → 0.9.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of excon might be problematic. Click here for more details.
- data/README.md +55 -1
- data/benchmarks/single_vs_double_quotes.rb +21 -0
- data/changelog.txt +10 -0
- data/excon.gemspec +3 -2
- data/lib/excon.rb +48 -16
- data/lib/excon/connection.rb +7 -10
- data/lib/excon/constants.rb +1 -1
- data/lib/excon/errors.rb +1 -1
- data/lib/excon/ssl_socket.rb +6 -4
- data/tests/idempotent_tests.rb +1 -1
- data/tests/stub_tests.rb +2 -2
- data/tests/test_helper.rb +7 -1
- metadata +19 -18
data/README.md
CHANGED
@@ -56,6 +56,12 @@ Both one-off and persistent connections support many other options. Here are a f
|
|
56
56
|
|
57
57
|
These options can be combined to make pretty much any request you might need.
|
58
58
|
|
59
|
+
Excon can also expect one or more HTTP status code in response, raising an exception if the response does not meet the criteria.
|
60
|
+
|
61
|
+
If you need to accept as response one or more HTTP status codes you can declare them in an array:
|
62
|
+
|
63
|
+
connection.request(expects => [200, 201], :method => :get, :path => path, :query => {})
|
64
|
+
|
59
65
|
Streaming Responses
|
60
66
|
-------------------
|
61
67
|
|
@@ -76,7 +82,7 @@ You can specify a proxy URL that Excon will use with both HTTP and HTTPS connect
|
|
76
82
|
connection = Excon.new('http://geemus.com', :proxy => 'http://my.proxy:3128')
|
77
83
|
connection.request(:method => 'GET')
|
78
84
|
|
79
|
-
The proxy URL must be fully specified, including scheme (e.g. "http://") and port.
|
85
|
+
The proxy URL must be fully specified, including scheme (e.g. "http://") and port.
|
80
86
|
|
81
87
|
Proxy support must be set when establishing a connection object and cannot be overridden in individual requests. Because of this it is unavailable in one-off requests (Excon.get, etc.)
|
82
88
|
|
@@ -107,6 +113,16 @@ Alternatively you can pass a block instead of `response_attributes` and it will
|
|
107
113
|
{:body => params[:body], :status => 200}
|
108
114
|
end
|
109
115
|
|
116
|
+
In order to clear previously defined stubs you can use:
|
117
|
+
|
118
|
+
Excon.stubs.clear
|
119
|
+
|
120
|
+
For example, if using RSpec for your test suite you can clear stubs after running each example:
|
121
|
+
|
122
|
+
config.after(:each) do
|
123
|
+
Excon.stubs.clear
|
124
|
+
end
|
125
|
+
|
110
126
|
HTTPS/SSL Issues
|
111
127
|
----------------
|
112
128
|
|
@@ -122,6 +138,44 @@ Failing that, you can turn off peer verification (less secure):
|
|
122
138
|
|
123
139
|
Either of these should allow you to work around the socket error and continue with your work.
|
124
140
|
|
141
|
+
Instrumentation
|
142
|
+
---------------
|
143
|
+
|
144
|
+
Excon calls can be timed using the [ActiveSupport::Notifications](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) API.
|
145
|
+
|
146
|
+
connection = Excon.new('http://geemus.com',
|
147
|
+
:instrumentor => ActiveSupport::Notifications)
|
148
|
+
|
149
|
+
Excon will then instrument each request, retry, and error. The corresponding events are named excon.request, excon.retry, and excon.error respectively.
|
150
|
+
|
151
|
+
ActiveSupport::Notifications.subscribe(/excon/) do |*args|
|
152
|
+
puts "Excon did stuff!"
|
153
|
+
end
|
154
|
+
|
155
|
+
If you prefer to label each event with something other than "excon," you may specify
|
156
|
+
an alternate name in the constructor:
|
157
|
+
|
158
|
+
connection = Excon.new('http://geemus.com',
|
159
|
+
:instrumentor => ActiveSupport::Notifications,
|
160
|
+
:instrumentor_name => 'my_app')
|
161
|
+
|
162
|
+
If you don't want to add activesupport to your application, simply define a class which implements the same #instrument method like so:
|
163
|
+
|
164
|
+
class SimpleInstrumentor
|
165
|
+
class << self
|
166
|
+
attr_accessor :events
|
167
|
+
|
168
|
+
def instrument(name, params = {}, &block)
|
169
|
+
puts "#{name} just happened."
|
170
|
+
yield if block_given?
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
The #instrument method will be called for each HTTP request, retry, and error.
|
176
|
+
|
177
|
+
See [the documentation for ActiveSupport::Notifications](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) for more detail on using the subscription interface. See excon's instrumentation_test.rb for more examples of instrumenting excon.
|
178
|
+
|
125
179
|
Copyright
|
126
180
|
---------
|
127
181
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'tach'
|
3
|
+
|
4
|
+
Tach.meter(1_000_000) do
|
5
|
+
tach('double') do
|
6
|
+
"path"
|
7
|
+
end
|
8
|
+
tach('single') do
|
9
|
+
'path'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# [double, single]
|
14
|
+
#
|
15
|
+
# +--------+----------+
|
16
|
+
# | tach | total |
|
17
|
+
# +--------+----------+
|
18
|
+
# | single | 0.416340 |
|
19
|
+
# +--------+----------+
|
20
|
+
# | double | 0.416570 |
|
21
|
+
# +--------+----------+
|
data/changelog.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
0.9.6 02/22/12
|
2
|
+
==============
|
3
|
+
|
4
|
+
* add support for setting ca_file. Thanks mattmatt!
|
5
|
+
* add docs for Excon.stubs.clear and expects. Thanks masterkain!
|
6
|
+
* add class level defaults
|
7
|
+
* fix ruby warnings. Thanks foca!
|
8
|
+
* improve instrumentation docs. Thanks mkb!
|
9
|
+
* fix for empty body and SSL sockets. Thanks pweldon!
|
10
|
+
|
1
11
|
0.9.5 01/16/12
|
2
12
|
==============
|
3
13
|
|
data/excon.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
|
|
13
13
|
## If your rubyforge_project name is different, then edit it and comment out
|
14
14
|
## the sub! line in the Rakefile
|
15
15
|
s.name = 'excon'
|
16
|
-
s.version = '0.9.
|
17
|
-
s.date = '2012-
|
16
|
+
s.version = '0.9.6'
|
17
|
+
s.date = '2012-02-22'
|
18
18
|
s.rubyforge_project = 'excon'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
@@ -83,6 +83,7 @@ Gem::Specification.new do |s|
|
|
83
83
|
benchmarks/headers_split_vs_match.rb
|
84
84
|
benchmarks/implicit_block-vs-explicit_block.rb
|
85
85
|
benchmarks/merging.rb
|
86
|
+
benchmarks/single_vs_double_quotes.rb
|
86
87
|
benchmarks/string_ranged_index.rb
|
87
88
|
benchmarks/strip_newline.rb
|
88
89
|
benchmarks/vs_stdlib.rb
|
data/lib/excon.rb
CHANGED
@@ -17,27 +17,65 @@ require 'excon/ssl_socket'
|
|
17
17
|
|
18
18
|
module Excon
|
19
19
|
class << self
|
20
|
-
# @return [String] The filesystem path to the SSL Certificate Authority
|
21
|
-
attr_accessor :ssl_ca_path
|
22
20
|
|
23
|
-
# @return [
|
24
|
-
|
21
|
+
# @return [Hash] defaults for Excon connections
|
22
|
+
def defaults
|
23
|
+
@defaults ||= {
|
24
|
+
:connect_timeout => 60,
|
25
|
+
:headers => {},
|
26
|
+
:instrumentor_name => 'excon',
|
27
|
+
:mock => false,
|
28
|
+
:read_timeout => 60,
|
29
|
+
:retry_limit => DEFAULT_RETRY_LIMIT,
|
30
|
+
:ssl_verify_peer => RbConfig::CONFIG['host_os'] !~ /mswin|win32|dos|cygwin|mingw/i,
|
31
|
+
:write_timeout => 60
|
32
|
+
}
|
33
|
+
end
|
25
34
|
|
26
|
-
#
|
27
|
-
@
|
35
|
+
# Change defaults for Excon connections
|
36
|
+
# @return [Hash] defaults for Excon connections
|
37
|
+
def defaults=(new_defaults)
|
38
|
+
self.defaults = new_defaults
|
39
|
+
end
|
28
40
|
|
29
41
|
# Status of mocking
|
30
42
|
def mock
|
31
|
-
puts("Excon#mock is deprecated, pass :mock
|
32
|
-
|
43
|
+
puts("Excon#mock is deprecated, pass Excon.defaults[:mock] instead (#{caller.first})")
|
44
|
+
self.defaults[:mock]
|
33
45
|
end
|
34
46
|
|
35
47
|
# Change the status of mocking
|
36
48
|
# false is the default and works as expected
|
37
49
|
# true returns a value from stubs or raises
|
38
50
|
def mock=(new_mock)
|
39
|
-
puts("Excon#mock
|
40
|
-
|
51
|
+
puts("Excon#mock is deprecated, pass Excon.defaults[:mock]= instead (#{caller.first})")
|
52
|
+
self.defaults[:mock] = new_mock
|
53
|
+
end
|
54
|
+
|
55
|
+
# @return [String] The filesystem path to the SSL Certificate Authority
|
56
|
+
def ssl_ca_path
|
57
|
+
puts("Excon#ssl_ca_path is deprecated, use Excon.defaults[:ssl_ca_path] instead (#{caller.first})")
|
58
|
+
self.defaults[:ssl_ca_path]
|
59
|
+
end
|
60
|
+
|
61
|
+
# Change path to the SSL Certificate Authority
|
62
|
+
# @return [String] The filesystem path to the SSL Certificate Authority
|
63
|
+
def ssl_ca_path=(new_ssl_ca_path)
|
64
|
+
puts("Excon#ssl_ca_path= is deprecated, use Excon.defaults[:ssl_ca_path]= instead (#{caller.first})")
|
65
|
+
self.defaults[:ssl_ca_path] = new_ssl_ca_path
|
66
|
+
end
|
67
|
+
|
68
|
+
# @return [true, false] Whether or not to verify the peer's SSL certificate / chain
|
69
|
+
def ssl_verify_peer
|
70
|
+
puts("Excon#ssl_verify_peer= is deprecated, use Excon.defaults[:ssl_verify_peer]= instead (#{caller.first})")
|
71
|
+
self.defaults[:ssl_verify_peer]
|
72
|
+
end
|
73
|
+
|
74
|
+
# Change the status of ssl peer verification
|
75
|
+
# @see Excon#ssl_verify_peer (attr_reader)
|
76
|
+
def ssl_verify_peer=(new_ssl_verify_peer)
|
77
|
+
puts("Excon#ssl_verify_peer is deprecated, use Excon.defaults[:ssl_verify_peer] instead (#{caller.first})")
|
78
|
+
self.defaults[:ssl_verify_peer] = new_ssl_verify_peer
|
41
79
|
end
|
42
80
|
|
43
81
|
# @see Connection#initialize
|
@@ -49,12 +87,6 @@ module Excon
|
|
49
87
|
Excon::Connection.new(url, params)
|
50
88
|
end
|
51
89
|
|
52
|
-
# Change the status of ssl peer verification
|
53
|
-
# @see Excon#ssl_verify_peer (attr_reader)
|
54
|
-
def ssl_verify_peer=(new_ssl_verify_peer)
|
55
|
-
@ssl_verify_peer = new_ssl_verify_peer && true || false
|
56
|
-
end
|
57
|
-
|
58
90
|
# push an additional stub onto the list to check for mock requests
|
59
91
|
# @param [Hash<Symbol, >] request params to match against, omitted params match all
|
60
92
|
# @param [Hash<Symbol, >] response params to return from matched request or block to call with params
|
data/lib/excon/connection.rb
CHANGED
@@ -18,20 +18,17 @@ module Excon
|
|
18
18
|
# @option params [String] :instrumentor_name Name prefix for #instrument events. Defaults to 'excon'
|
19
19
|
def initialize(url, params = {})
|
20
20
|
uri = URI.parse(url)
|
21
|
-
@connection = {
|
22
|
-
:connect_timeout => 60,
|
23
|
-
:headers => {},
|
21
|
+
@connection = Excon.defaults.merge({
|
24
22
|
:host => uri.host,
|
25
|
-
:instrumentor_name => 'excon',
|
26
|
-
:mock => Excon.instance_variable_get(:@mock),
|
27
23
|
:path => uri.path,
|
28
24
|
:port => uri.port.to_s,
|
29
25
|
:query => uri.query,
|
30
|
-
:read_timeout => 60,
|
31
|
-
:retry_limit => DEFAULT_RETRY_LIMIT,
|
32
26
|
:scheme => uri.scheme,
|
33
|
-
|
34
|
-
|
27
|
+
}).merge!(params)
|
28
|
+
# merge does not deep-dup, so make sure headers is not the original
|
29
|
+
@connection[:headers] = @connection[:headers].dup
|
30
|
+
|
31
|
+
@proxy = nil
|
35
32
|
|
36
33
|
# use proxy from the environment if present
|
37
34
|
if ENV.has_key?('http_proxy')
|
@@ -201,7 +198,7 @@ module Excon
|
|
201
198
|
socket.write(request)
|
202
199
|
|
203
200
|
# write out the body
|
204
|
-
if params[:
|
201
|
+
if params[:headers]['Content-Length'] != 0
|
205
202
|
if params[:body].is_a?(String)
|
206
203
|
socket.write(params[:body])
|
207
204
|
else
|
data/lib/excon/constants.rb
CHANGED
data/lib/excon/errors.rb
CHANGED
@@ -8,7 +8,7 @@ module Excon
|
|
8
8
|
|
9
9
|
def initialize(socket_error=nil)
|
10
10
|
if socket_error.message =~ /certificate verify failed/
|
11
|
-
super('Unable to verify certificate, please set `Excon.ssl_ca_path = path_to_certs` or `Excon.ssl_verify_peer = false` (less secure).')
|
11
|
+
super('Unable to verify certificate, please set `Excon.defaults[:ssl_ca_path] = path_to_certs`, `Excon.defaults[:ssl_ca_file] = path_to_file`, or `Excon.defaults[:ssl_verify_peer] = false` (less secure).')
|
12
12
|
else
|
13
13
|
super(socket_error.message)
|
14
14
|
end
|
data/lib/excon/ssl_socket.rb
CHANGED
@@ -23,12 +23,14 @@ module Excon
|
|
23
23
|
# create ssl context
|
24
24
|
ssl_context = OpenSSL::SSL::SSLContext.new
|
25
25
|
|
26
|
-
if Excon.ssl_verify_peer
|
26
|
+
if Excon.defaults[:ssl_verify_peer]
|
27
27
|
# turn verification on
|
28
28
|
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
29
29
|
|
30
|
-
if Excon.ssl_ca_path
|
31
|
-
ssl_context.ca_path = Excon.ssl_ca_path
|
30
|
+
if Excon.defaults[:ssl_ca_path]
|
31
|
+
ssl_context.ca_path = Excon.defaults[:ssl_ca_path]
|
32
|
+
elsif Excon.defaults[:ssl_ca_file]
|
33
|
+
ssl_context.ca_file = Excon.defaults[:ssl_ca_file]
|
32
34
|
else
|
33
35
|
# use default cert store
|
34
36
|
store = OpenSSL::X509::Store.new
|
@@ -62,7 +64,7 @@ module Excon
|
|
62
64
|
@socket.connect
|
63
65
|
|
64
66
|
# verify connection
|
65
|
-
if Excon.ssl_verify_peer
|
67
|
+
if Excon.defaults[:ssl_verify_peer]
|
66
68
|
@socket.post_connection_check(@params[:host])
|
67
69
|
end
|
68
70
|
|
data/tests/idempotent_tests.rb
CHANGED
@@ -20,7 +20,7 @@ Shindo.tests('Excon request idempotencey') do
|
|
20
20
|
end
|
21
21
|
}
|
22
22
|
|
23
|
-
|
23
|
+
@connection.request(:method => :get, :path => '/some-path')
|
24
24
|
end
|
25
25
|
|
26
26
|
tests("Idempotent request with socket erroring first 3 times").returns(200) do
|
data/tests/stub_tests.rb
CHANGED
@@ -2,7 +2,7 @@ Shindo.tests('Excon stubs') do
|
|
2
2
|
|
3
3
|
tests("missing stub").raises(Excon::Errors::StubNotFound) do
|
4
4
|
connection = Excon.new('http://127.0.0.1:9292', :mock => true)
|
5
|
-
|
5
|
+
connection.request(:method => :get, :path => '/content-length/100')
|
6
6
|
end
|
7
7
|
|
8
8
|
tests("stub({})").raises(ArgumentError) do
|
@@ -116,7 +116,7 @@ Shindo.tests('Excon stubs') do
|
|
116
116
|
|
117
117
|
test("with block") do
|
118
118
|
chunks = []
|
119
|
-
|
119
|
+
connection.request(:method => :get, :path => '/content-length/100') do |chunk, remaining_bytes, total_bytes|
|
120
120
|
chunks << chunk
|
121
121
|
end
|
122
122
|
chunks == ['x' * Excon::CHUNK_SIZE, 'x']
|
data/tests/test_helper.rb
CHANGED
@@ -6,6 +6,7 @@ Bundler.require(:default, :development)
|
|
6
6
|
def basic_tests(url = 'http://127.0.0.1:9292')
|
7
7
|
tests('GET /content-length/100') do
|
8
8
|
|
9
|
+
Excon.defaults[:ssl_verify_peer] = false
|
9
10
|
connection = Excon.new(url)
|
10
11
|
response = connection.request(:method => :get, :path => '/content-length/100')
|
11
12
|
|
@@ -54,9 +55,14 @@ def basic_tests(url = 'http://127.0.0.1:9292')
|
|
54
55
|
tests('POST /body-sink') do
|
55
56
|
|
56
57
|
connection = Excon.new(url)
|
57
|
-
response = connection.request(:method => :post, :path => '/body-sink', :headers => { 'Content-Type' => 'text/plain' }, :body => 'x' * 5_000_000)
|
58
58
|
|
59
59
|
tests('response.body').returns("5000000") do
|
60
|
+
response = connection.request(:method => :post, :path => '/body-sink', :headers => { 'Content-Type' => 'text/plain' }, :body => 'x' * 5_000_000)
|
61
|
+
response.body
|
62
|
+
end
|
63
|
+
|
64
|
+
tests('empty body').returns('0') do
|
65
|
+
response = connection.request(:method => :post, :path => '/body-sink', :headers => { 'Content-Type' => 'text/plain' }, :body => '')
|
60
66
|
response.body
|
61
67
|
end
|
62
68
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: excon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.6
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,11 +11,11 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-02-22 00:00:00.000000000Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activesupport
|
18
|
-
requirement: &
|
18
|
+
requirement: &9166800 !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
@@ -23,10 +23,10 @@ dependencies:
|
|
23
23
|
version: 3.1.3
|
24
24
|
type: :development
|
25
25
|
prerelease: false
|
26
|
-
version_requirements: *
|
26
|
+
version_requirements: *9166800
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: delorean
|
29
|
-
requirement: &
|
29
|
+
requirement: &9166610 !ruby/object:Gem::Requirement
|
30
30
|
none: false
|
31
31
|
requirements:
|
32
32
|
- - ! '>='
|
@@ -34,10 +34,10 @@ dependencies:
|
|
34
34
|
version: '0'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
|
-
version_requirements: *
|
37
|
+
version_requirements: *9166610
|
38
38
|
- !ruby/object:Gem::Dependency
|
39
39
|
name: open4
|
40
|
-
requirement: &
|
40
|
+
requirement: &9166380 !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
43
|
- - ! '>='
|
@@ -45,10 +45,10 @@ dependencies:
|
|
45
45
|
version: '0'
|
46
46
|
type: :development
|
47
47
|
prerelease: false
|
48
|
-
version_requirements: *
|
48
|
+
version_requirements: *9166380
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
name: rake
|
51
|
-
requirement: &
|
51
|
+
requirement: &9166170 !ruby/object:Gem::Requirement
|
52
52
|
none: false
|
53
53
|
requirements:
|
54
54
|
- - ! '>='
|
@@ -56,10 +56,10 @@ dependencies:
|
|
56
56
|
version: '0'
|
57
57
|
type: :development
|
58
58
|
prerelease: false
|
59
|
-
version_requirements: *
|
59
|
+
version_requirements: *9166170
|
60
60
|
- !ruby/object:Gem::Dependency
|
61
61
|
name: rdoc
|
62
|
-
requirement: &
|
62
|
+
requirement: &9165960 !ruby/object:Gem::Requirement
|
63
63
|
none: false
|
64
64
|
requirements:
|
65
65
|
- - ! '>='
|
@@ -67,10 +67,10 @@ dependencies:
|
|
67
67
|
version: '0'
|
68
68
|
type: :development
|
69
69
|
prerelease: false
|
70
|
-
version_requirements: *
|
70
|
+
version_requirements: *9165960
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
72
|
name: shindo
|
73
|
-
requirement: &
|
73
|
+
requirement: &9165750 !ruby/object:Gem::Requirement
|
74
74
|
none: false
|
75
75
|
requirements:
|
76
76
|
- - ! '>='
|
@@ -78,10 +78,10 @@ dependencies:
|
|
78
78
|
version: '0'
|
79
79
|
type: :development
|
80
80
|
prerelease: false
|
81
|
-
version_requirements: *
|
81
|
+
version_requirements: *9165750
|
82
82
|
- !ruby/object:Gem::Dependency
|
83
83
|
name: sinatra
|
84
|
-
requirement: &
|
84
|
+
requirement: &9165510 !ruby/object:Gem::Requirement
|
85
85
|
none: false
|
86
86
|
requirements:
|
87
87
|
- - ! '>='
|
@@ -89,7 +89,7 @@ dependencies:
|
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
|
-
version_requirements: *
|
92
|
+
version_requirements: *9165510
|
93
93
|
description: EXtended http(s) CONnections
|
94
94
|
email: geemus@gmail.com
|
95
95
|
executables: []
|
@@ -114,6 +114,7 @@ files:
|
|
114
114
|
- benchmarks/headers_split_vs_match.rb
|
115
115
|
- benchmarks/implicit_block-vs-explicit_block.rb
|
116
116
|
- benchmarks/merging.rb
|
117
|
+
- benchmarks/single_vs_double_quotes.rb
|
117
118
|
- benchmarks/string_ranged_index.rb
|
118
119
|
- benchmarks/strip_newline.rb
|
119
120
|
- benchmarks/vs_stdlib.rb
|
@@ -160,7 +161,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
160
161
|
version: '0'
|
161
162
|
segments:
|
162
163
|
- 0
|
163
|
-
hash:
|
164
|
+
hash: -511600863
|
164
165
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
165
166
|
none: false
|
166
167
|
requirements:
|
@@ -169,7 +170,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
169
170
|
version: '0'
|
170
171
|
requirements: []
|
171
172
|
rubyforge_project: excon
|
172
|
-
rubygems_version: 1.8.
|
173
|
+
rubygems_version: 1.8.6
|
173
174
|
signing_key:
|
174
175
|
specification_version: 2
|
175
176
|
summary: speed, persistence, http(s)
|