excon 0.7.6 → 0.7.7
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.rdoc +10 -8
- data/excon.gemspec +4 -2
- data/lib/excon/constants.rb +1 -1
- data/lib/excon/errors.rb +1 -1
- data/lib/excon/socket.rb +14 -6
- data/tests/bad_tests.rb +35 -0
- data/tests/header_tests.rb +13 -13
- data/tests/idempotent_tests.rb +6 -5
- data/tests/rackups/thread_safety.ru +2 -0
- data/tests/request_method_tests.rb +8 -8
- data/tests/servers/bad.rb +20 -0
- data/tests/stub_tests.rb +1 -0
- data/tests/test_helper.rb +14 -0
- metadata +54 -83
data/README.rdoc
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
Http(s) EXtended CONnections
|
4
4
|
|
5
|
+
{<img src="https://secure.travis-ci.org/geemus/excon.png" />}[http://travis-ci.org/geemus/excon]
|
6
|
+
|
5
7
|
== Getting Started
|
6
8
|
|
7
9
|
Install the gem.
|
@@ -17,9 +19,9 @@ The simplest way to use excon is with one-off requests:
|
|
17
19
|
|
18
20
|
response = Excon.get('http://geemus.com')
|
19
21
|
|
20
|
-
Supported one-off request methods are #connect, #delete, #get, #head, #options, #post, #put, and #trace.
|
22
|
+
Supported one-off request methods are #connect, #delete, #get, #head, #options, #post, #put, and #trace.
|
21
23
|
|
22
|
-
The returned response object has #body, #headers and #status attributes.
|
24
|
+
The returned response object has #body, #headers and #status attributes.
|
23
25
|
|
24
26
|
Alternately you can create a connection object which is reusable across multiple requests (more performant!).
|
25
27
|
|
@@ -27,7 +29,7 @@ Alternately you can create a connection object which is reusable across multiple
|
|
27
29
|
response_one = connection.get
|
28
30
|
response_two = connection.post(:path => '/foo')
|
29
31
|
response_three = connection.delete(:path => '/bar')
|
30
|
-
|
32
|
+
|
31
33
|
Sometimes it is more convenient to specify the request type as an argument:
|
32
34
|
|
33
35
|
response_four = connection.request(:method => :get, :path => '/more')
|
@@ -37,14 +39,14 @@ Both one-off and persistent connections support many other options. Here are a f
|
|
37
39
|
# Custom headers
|
38
40
|
Excon.get('http://geemus.com', :headers => {'Authorization' => 'Basic 0123456789ABCDEF'})
|
39
41
|
connection.get(:headers => {'Authorization' => 'Basic 0123456789ABCDEF'})
|
40
|
-
|
42
|
+
|
41
43
|
# Changing query strings
|
42
44
|
connection = Excon.new('http://geemus.com/')
|
43
45
|
connection.get(:query => {:foo => 'bar'})
|
44
|
-
|
46
|
+
|
45
47
|
# POST body
|
46
48
|
Excon.post('http://geemus.com', :body => 'language=ruby&class=fog')
|
47
|
-
|
49
|
+
|
48
50
|
# request accepts either symbols or strings
|
49
51
|
connection.request(:method => :get)
|
50
52
|
connection.request(:method => 'GET')
|
@@ -59,7 +61,7 @@ You can stream responses by passing a block that will receive each chunk.
|
|
59
61
|
puts chunk
|
60
62
|
puts "Remaining: #{remaining_bytes.to_f / total_bytes}%"
|
61
63
|
end
|
62
|
-
|
64
|
+
|
63
65
|
Iterating over each chunk will allow you to do work on the response incrementally without buffering the entire response first. For very large responses this can lead to significant memory savings.
|
64
66
|
|
65
67
|
== Proxy Support
|
@@ -71,7 +73,7 @@ You can specify a proxy URL that Excon will use with both HTTP and HTTPS connect
|
|
71
73
|
|
72
74
|
The proxy URL must be fully specified, including scheme (e.g. "http://") and port.
|
73
75
|
|
74
|
-
Excon will also use the environment variables "http_proxy" and "https_proxy" if they are present.
|
76
|
+
Excon will also use the environment variables "http_proxy" and "https_proxy" if they are present.
|
75
77
|
|
76
78
|
If "https_proxy" is not set, the value of "http_proxy" will be used for both HTTP and HTTPS connections.
|
77
79
|
|
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.7.
|
17
|
-
s.date = '2011-
|
16
|
+
s.version = '0.7.7'
|
17
|
+
s.date = '2011-11-24'
|
18
18
|
s.rubyforge_project = 'excon'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
@@ -92,6 +92,7 @@ Gem::Specification.new do |s|
|
|
92
92
|
lib/excon/response.rb
|
93
93
|
lib/excon/socket.rb
|
94
94
|
lib/excon/ssl_socket.rb
|
95
|
+
tests/bad_tests.rb
|
95
96
|
tests/basic_tests.rb
|
96
97
|
tests/header_tests.rb
|
97
98
|
tests/idempotent_tests.rb
|
@@ -105,6 +106,7 @@ Gem::Specification.new do |s|
|
|
105
106
|
tests/rackups/ssl.ru
|
106
107
|
tests/rackups/thread_safety.ru
|
107
108
|
tests/request_method_tests.rb
|
109
|
+
tests/servers/bad.rb
|
108
110
|
tests/stub_tests.rb
|
109
111
|
tests/test_helper.rb
|
110
112
|
tests/thread_safety_tests.rb
|
data/lib/excon/constants.rb
CHANGED
data/lib/excon/errors.rb
CHANGED
@@ -76,7 +76,7 @@ module Excon
|
|
76
76
|
|
77
77
|
# Messages for nicer exceptions, from rfc2616
|
78
78
|
def self.status_error(request, response)
|
79
|
-
@errors ||= {
|
79
|
+
@errors ||= {
|
80
80
|
100 => [Excon::Errors::Continue, 'Continue'],
|
81
81
|
101 => [Excon::Errors::SwitchingProtocols, 'Switching Protocols'],
|
82
82
|
200 => [Excon::Errors::OK, 'OK'],
|
data/lib/excon/socket.rb
CHANGED
@@ -8,17 +8,22 @@ module Excon
|
|
8
8
|
def_delegators(:@socket, :close, :close)
|
9
9
|
def_delegators(:@socket, :readline, :readline)
|
10
10
|
|
11
|
-
def initialize(params = {}, proxy =
|
11
|
+
def initialize(params = {}, proxy = nil)
|
12
12
|
@params, @proxy = params, proxy
|
13
13
|
@read_buffer, @write_buffer = '', ''
|
14
|
+
@eof = false
|
14
15
|
|
15
|
-
|
16
|
-
::Socket.
|
16
|
+
addrinfo = if @proxy
|
17
|
+
::Socket.getaddrinfo(@proxy[:host], @proxy[:port].to_i, nil, ::Socket::Constants::SOCK_STREAM)
|
17
18
|
else
|
18
|
-
::Socket.
|
19
|
-
end
|
19
|
+
::Socket.getaddrinfo(@params[:host], @params[:port].to_i, nil, ::Socket::Constants::SOCK_STREAM)
|
20
|
+
end.first
|
21
|
+
|
22
|
+
_, port, _, ip, a_family, s_type = addrinfo
|
20
23
|
|
21
|
-
@
|
24
|
+
@sockaddr = ::Socket.sockaddr_in(port, ip)
|
25
|
+
|
26
|
+
@socket = ::Socket.new(a_family, s_type, 0)
|
22
27
|
|
23
28
|
connect
|
24
29
|
|
@@ -39,6 +44,8 @@ module Excon
|
|
39
44
|
end
|
40
45
|
|
41
46
|
def read(max_length=nil)
|
47
|
+
return nil if @eof
|
48
|
+
|
42
49
|
begin
|
43
50
|
if max_length
|
44
51
|
until @read_buffer.length >= max_length
|
@@ -64,6 +71,7 @@ module Excon
|
|
64
71
|
raise(Excon::Errors::Timeout.new("read timeout reached"))
|
65
72
|
end
|
66
73
|
rescue EOFError
|
74
|
+
@eof = true
|
67
75
|
end
|
68
76
|
if max_length
|
69
77
|
@read_buffer.slice!(0, max_length)
|
data/tests/bad_tests.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
Shindo.tests('Excon bad server interaction') do
|
2
|
+
|
3
|
+
with_server('bad') do
|
4
|
+
|
5
|
+
tests('bad server: causes EOFError') do
|
6
|
+
|
7
|
+
tests('with no content length and no chunking') do
|
8
|
+
tests('without a block') do
|
9
|
+
tests('response.body').returns('hello') do
|
10
|
+
connection = Excon.new('http://127.0.0.1:9292')
|
11
|
+
|
12
|
+
connection.request(:method => :get, :path => '/eof/no_content_length_and_no_chunking').body
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
tests('with a block') do
|
17
|
+
tests('body from chunks').returns('hello') do
|
18
|
+
connection = Excon.new('http://127.0.0.1:9292')
|
19
|
+
|
20
|
+
body = ""
|
21
|
+
block = lambda {|chunk, remaining, total| body << chunk }
|
22
|
+
|
23
|
+
connection.request(:method => :get, :path => '/eof/no_content_length_and_no_chunking', &block)
|
24
|
+
|
25
|
+
body
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
data/tests/header_tests.rb
CHANGED
@@ -3,45 +3,45 @@ Shindo.tests('Excon response header support') do
|
|
3
3
|
with_rackup('response_header.ru') do
|
4
4
|
|
5
5
|
tests('Response#get_header') do
|
6
|
-
connection = Excon.new('http://foo.com:8080', :proxy => 'http://
|
6
|
+
connection = Excon.new('http://foo.com:8080', :proxy => 'http://127.0.0.1:9292')
|
7
7
|
response = connection.request(:method => :get, :path => '/foo')
|
8
8
|
|
9
9
|
tests('with variable header capitalization') do
|
10
|
-
|
10
|
+
|
11
11
|
tests('response.get_header("mixedcase-header")').returns('MixedCase') do
|
12
12
|
response.get_header("mixedcase-header")
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
tests('response.get_header("uppercase-header")').returns('UPPERCASE') do
|
16
16
|
response.get_header("uppercase-header")
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
tests('response.get_header("lowercase-header")').returns('lowercase') do
|
20
20
|
response.get_header("lowercase-header")
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
tests('when provided key capitalization varies') do
|
26
|
-
|
26
|
+
|
27
27
|
tests('response.get_header("MIXEDCASE-HEADER")').returns('MixedCase') do
|
28
28
|
response.get_header("MIXEDCASE-HEADER")
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
tests('response.get_header("MiXeDcAsE-hEaDeR")').returns('MixedCase') do
|
32
32
|
response.get_header("MiXeDcAsE-hEaDeR")
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
tests('when header is unavailable') do
|
38
|
-
|
38
|
+
|
39
39
|
tests('response.get_header("missing")').returns(nil) do
|
40
40
|
response.get_header("missing")
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
end
|
46
46
|
|
47
47
|
end
|
data/tests/idempotent_tests.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
Shindo.tests('Excon request idempotencey') do
|
2
2
|
Excon.mock = true
|
3
3
|
|
4
|
+
after do
|
5
|
+
# flush any existing stubs after each test
|
6
|
+
Excon.stubs.clear
|
7
|
+
end
|
8
|
+
|
4
9
|
tests("Non-idempotent call with an erroring socket").raises(Excon::Errors::SocketError) do
|
10
|
+
run_count = 0
|
5
11
|
Excon.stub({:method => :get}) { |params|
|
6
12
|
run_count += 1
|
7
13
|
if run_count < 4 # First 3 calls fail.
|
@@ -15,8 +21,6 @@ Shindo.tests('Excon request idempotencey') do
|
|
15
21
|
response = connection.request(:method => :get, :path => '/some-path')
|
16
22
|
end
|
17
23
|
|
18
|
-
Excon.stubs.pop
|
19
|
-
|
20
24
|
tests("Idempotent request with socket erroring first 3 times").returns(200) do
|
21
25
|
run_count = 0
|
22
26
|
Excon.stub({:method => :get}) { |params|
|
@@ -33,8 +37,6 @@ Shindo.tests('Excon request idempotencey') do
|
|
33
37
|
response.status
|
34
38
|
end
|
35
39
|
|
36
|
-
Excon.stubs.pop
|
37
|
-
|
38
40
|
tests("Idempotent request with socket erroring first 5 times").raises(Excon::Errors::SocketError) do
|
39
41
|
run_count = 0
|
40
42
|
Excon.stub({:method => :get}) { |params|
|
@@ -51,6 +53,5 @@ Shindo.tests('Excon request idempotencey') do
|
|
51
53
|
response.status
|
52
54
|
end
|
53
55
|
|
54
|
-
Excon.stubs.pop
|
55
56
|
Excon.mock = false
|
56
57
|
end
|
@@ -3,29 +3,29 @@ Shindo.tests('Excon request methods') do
|
|
3
3
|
with_rackup('request_methods.ru') do
|
4
4
|
|
5
5
|
tests 'one-offs' do
|
6
|
-
|
6
|
+
|
7
7
|
tests('Excon.get').returns('GET') do
|
8
8
|
Excon.get('http://127.0.0.1:9292').body
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
tests('Excon.post').returns('POST') do
|
12
12
|
Excon.post('http://127.0.0.1:9292').body
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
tests 'with a connection object' do
|
18
|
-
|
18
|
+
|
19
19
|
connection = Excon.new('http://127.0.0.1:9292')
|
20
|
-
|
20
|
+
|
21
21
|
tests('connection.get').returns('GET') do
|
22
22
|
connection.get.body
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
tests('connection.post').returns('POST') do
|
26
26
|
connection.post.body
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
end
|
30
30
|
|
31
31
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "eventmachine"
|
4
|
+
|
5
|
+
module BadServer
|
6
|
+
def receive_data(data)
|
7
|
+
case data
|
8
|
+
when %r{^GET /eof/no_content_length_and_no_chunking\s}
|
9
|
+
send_data "HTTP/1.1 200 OK\r\n"
|
10
|
+
send_data "\r\n"
|
11
|
+
send_data "hello"
|
12
|
+
close_connection(true)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
EM.run do
|
18
|
+
EM.start_server("127.0.0.1", 9292, BadServer)
|
19
|
+
$stderr.puts "ready"
|
20
|
+
end
|
data/tests/stub_tests.rb
CHANGED
data/tests/test_helper.rb
CHANGED
@@ -73,3 +73,17 @@ def with_rackup(name)
|
|
73
73
|
ensure
|
74
74
|
Process.kill(9, pid)
|
75
75
|
end
|
76
|
+
|
77
|
+
def server_path(*parts)
|
78
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'servers', *parts))
|
79
|
+
end
|
80
|
+
|
81
|
+
def with_server(name)
|
82
|
+
GC.disable
|
83
|
+
pid, w, r, e = Open4.popen4(server_path("#{name}.rb"))
|
84
|
+
until e.gets =~ /ready/; end
|
85
|
+
yield
|
86
|
+
ensure
|
87
|
+
GC.enable
|
88
|
+
Process.kill(9, pid)
|
89
|
+
end
|
metadata
CHANGED
@@ -1,89 +1,67 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: excon
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.7.7
|
5
5
|
prerelease:
|
6
|
-
segments:
|
7
|
-
- 0
|
8
|
-
- 7
|
9
|
-
- 6
|
10
|
-
version: 0.7.6
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- geemus (Wesley Beary)
|
14
9
|
autorequire:
|
15
10
|
bindir: bin
|
16
11
|
cert_chain: []
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-11-24 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
21
15
|
name: open4
|
22
|
-
|
23
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
16
|
+
requirement: &70352462409660 !ruby/object:Gem::Requirement
|
24
17
|
none: false
|
25
|
-
requirements:
|
26
|
-
- -
|
27
|
-
- !ruby/object:Gem::Version
|
28
|
-
|
29
|
-
segments:
|
30
|
-
- 0
|
31
|
-
version: "0"
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
32
22
|
type: :development
|
33
|
-
version_requirements: *id001
|
34
|
-
- !ruby/object:Gem::Dependency
|
35
|
-
name: rake
|
36
23
|
prerelease: false
|
37
|
-
|
24
|
+
version_requirements: *70352462409660
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rake
|
27
|
+
requirement: &70352462407680 !ruby/object:Gem::Requirement
|
38
28
|
none: false
|
39
|
-
requirements:
|
40
|
-
- -
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
|
43
|
-
segments:
|
44
|
-
- 0
|
45
|
-
version: "0"
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
46
33
|
type: :development
|
47
|
-
version_requirements: *id002
|
48
|
-
- !ruby/object:Gem::Dependency
|
49
|
-
name: shindo
|
50
34
|
prerelease: false
|
51
|
-
|
35
|
+
version_requirements: *70352462407680
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: shindo
|
38
|
+
requirement: &70352462405960 !ruby/object:Gem::Requirement
|
52
39
|
none: false
|
53
|
-
requirements:
|
54
|
-
- -
|
55
|
-
- !ruby/object:Gem::Version
|
56
|
-
hash: 23
|
57
|
-
segments:
|
58
|
-
- 0
|
59
|
-
- 2
|
60
|
-
- 0
|
40
|
+
requirements:
|
41
|
+
- - =
|
42
|
+
- !ruby/object:Gem::Version
|
61
43
|
version: 0.2.0
|
62
44
|
type: :development
|
63
|
-
version_requirements: *id003
|
64
|
-
- !ruby/object:Gem::Dependency
|
65
|
-
name: sinatra
|
66
45
|
prerelease: false
|
67
|
-
|
46
|
+
version_requirements: *70352462405960
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: sinatra
|
49
|
+
requirement: &70352462404780 !ruby/object:Gem::Requirement
|
68
50
|
none: false
|
69
|
-
requirements:
|
70
|
-
- -
|
71
|
-
- !ruby/object:Gem::Version
|
72
|
-
|
73
|
-
segments:
|
74
|
-
- 0
|
75
|
-
version: "0"
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
76
55
|
type: :development
|
77
|
-
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70352462404780
|
78
58
|
description: EXtended http(s) CONnections
|
79
59
|
email: geemus@gmail.com
|
80
60
|
executables: []
|
81
|
-
|
82
61
|
extensions: []
|
83
|
-
|
84
|
-
extra_rdoc_files:
|
62
|
+
extra_rdoc_files:
|
85
63
|
- README.rdoc
|
86
|
-
files:
|
64
|
+
files:
|
87
65
|
- Gemfile
|
88
66
|
- README.rdoc
|
89
67
|
- Rakefile
|
@@ -113,6 +91,7 @@ files:
|
|
113
91
|
- lib/excon/response.rb
|
114
92
|
- lib/excon/socket.rb
|
115
93
|
- lib/excon/ssl_socket.rb
|
94
|
+
- tests/bad_tests.rb
|
116
95
|
- tests/basic_tests.rb
|
117
96
|
- tests/header_tests.rb
|
118
97
|
- tests/idempotent_tests.rb
|
@@ -126,41 +105,33 @@ files:
|
|
126
105
|
- tests/rackups/ssl.ru
|
127
106
|
- tests/rackups/thread_safety.ru
|
128
107
|
- tests/request_method_tests.rb
|
108
|
+
- tests/servers/bad.rb
|
129
109
|
- tests/stub_tests.rb
|
130
110
|
- tests/test_helper.rb
|
131
111
|
- tests/thread_safety_tests.rb
|
132
112
|
homepage: https://github.com/geemus/excon
|
133
113
|
licenses: []
|
134
|
-
|
135
114
|
post_install_message:
|
136
|
-
rdoc_options:
|
115
|
+
rdoc_options:
|
137
116
|
- --charset=UTF-8
|
138
|
-
require_paths:
|
117
|
+
require_paths:
|
139
118
|
- lib
|
140
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
120
|
none: false
|
142
|
-
requirements:
|
143
|
-
- -
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
|
146
|
-
|
147
|
-
- 0
|
148
|
-
version: "0"
|
149
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
126
|
none: false
|
151
|
-
requirements:
|
152
|
-
- -
|
153
|
-
- !ruby/object:Gem::Version
|
154
|
-
|
155
|
-
segments:
|
156
|
-
- 0
|
157
|
-
version: "0"
|
127
|
+
requirements:
|
128
|
+
- - ! '>='
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
158
131
|
requirements: []
|
159
|
-
|
160
132
|
rubyforge_project: excon
|
161
|
-
rubygems_version: 1.8.
|
133
|
+
rubygems_version: 1.8.10
|
162
134
|
signing_key:
|
163
135
|
specification_version: 2
|
164
136
|
summary: speed, persistence, http(s)
|
165
137
|
test_files: []
|
166
|
-
|