excon 0.8.0 → 0.9.0

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/Rakefile CHANGED
@@ -56,7 +56,7 @@ task :coverage do
56
56
  sh "open coverage/index.html"
57
57
  end
58
58
 
59
- require 'rake/rdoctask'
59
+ require 'rdoc/task'
60
60
  Rake::RDocTask.new do |rdoc|
61
61
  rdoc.rdoc_dir = 'rdoc'
62
62
  rdoc.title = "#{name} #{version}"
@@ -1,3 +1,10 @@
1
+ 0.9.0 12/14/11
2
+ ==============
3
+
4
+ * add ability to do instrumentation
5
+ * misc cleanup
6
+ * deprecate retry_limit accessor in favor of passing as a param
7
+
1
8
  0.8.0 12/12/11
2
9
  ==============
3
10
 
@@ -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.8.0'
17
- s.date = '2011-12-12'
16
+ s.version = '0.9.0'
17
+ s.date = '2011-12-14'
18
18
  s.rubyforge_project = 'excon'
19
19
 
20
20
  ## Make sure your summary is short. The description may be as long
@@ -57,6 +57,8 @@ Gem::Specification.new do |s|
57
57
  s.add_development_dependency('rake')
58
58
  s.add_development_dependency('shindo', '0.2.0')
59
59
  s.add_development_dependency('sinatra')
60
+ s.add_development_dependency('activesupport', '~>3.1.3')
61
+ s.add_development_dependency('delorean')
60
62
 
61
63
  ## Leave this section as-is. It will be automatically generated from the
62
64
  ## contents of your Git repository via the gemspec task. DO NOT REMOVE
@@ -96,6 +98,7 @@ Gem::Specification.new do |s|
96
98
  tests/basic_tests.rb
97
99
  tests/header_tests.rb
98
100
  tests/idempotent_tests.rb
101
+ tests/instrumentation_tests.rb
99
102
  tests/proxy_tests.rb
100
103
  tests/query_string_tests.rb
101
104
  tests/rackups/basic.ru
@@ -2,10 +2,6 @@ module Excon
2
2
  class Connection
3
3
  attr_reader :connection, :proxy
4
4
 
5
- CR_NL = "\r\n"
6
- HTTP_1_1 = " HTTP/1.1\r\n"
7
- FORCE_ENC = CR_NL.respond_to?(:force_encoding)
8
-
9
5
  # Initializes a new Connection instance
10
6
  # @param [String] url The destination URL
11
7
  # @param [Hash<Symbol, >] params One or more optional params
@@ -18,19 +14,23 @@ module Excon
18
14
  # @option params [String] :scheme The protocol; 'https' causes OpenSSL to be used
19
15
  # @option params [String] :proxy Proxy server; e.g. 'http://myproxy.com:8888'
20
16
  # @option params [Fixnum] :retry_limit Set how many times we'll retry a failed request. (Default 4)
17
+ # @option params [Class] :instrumentor Responds to #instrument as in ActiveSupport::Notifications
18
+ # @option params [String] :instrumentor_name Name prefix for #instrument events. Defaults to 'excon'
21
19
  def initialize(url, params = {})
22
20
  uri = URI.parse(url)
23
21
  @connection = {
24
- :connect_timeout => 60,
25
- :headers => {},
26
- :host => uri.host,
27
- :mock => Excon.mock,
28
- :path => uri.path,
29
- :port => uri.port.to_s,
30
- :query => uri.query,
31
- :read_timeout => 60,
32
- :scheme => uri.scheme,
33
- :write_timeout => 60
22
+ :connect_timeout => 60,
23
+ :headers => {},
24
+ :host => uri.host,
25
+ :instrumentor_name => 'excon',
26
+ :mock => Excon.mock,
27
+ :path => uri.path,
28
+ :port => uri.port.to_s,
29
+ :query => uri.query,
30
+ :read_timeout => 60,
31
+ :retry_limit => DEFAULT_RETRY_LIMIT,
32
+ :scheme => uri.scheme,
33
+ :write_timeout => 60
34
34
  }.merge!(params)
35
35
 
36
36
  # use proxy from the environment if present
@@ -40,9 +40,7 @@ module Excon
40
40
  @proxy = setup_proxy(params[:proxy])
41
41
  end
42
42
 
43
- self.retry_limit = params[:retry_limit] || DEFAULT_RETRY_LIMIT
44
-
45
- if @connection[:scheme] == 'https'
43
+ if @connection[:scheme] == HTTPS
46
44
  # use https_proxy if that has been specified
47
45
  if ENV.has_key?('https_proxy')
48
46
  @proxy = setup_proxy(ENV['https_proxy'])
@@ -68,24 +66,84 @@ module Excon
68
66
  # @option params [Hash] :query appended to the 'scheme://host:port/path/' in the form of '?key=value'
69
67
  # @option params [String] :scheme The protocol; 'https' causes OpenSSL to be used
70
68
  def request(params, &block)
71
- begin
72
- # connection has defaults, merge in new params to override
73
- params = @connection.merge(params)
74
- params[:headers] = @connection[:headers].merge(params[:headers] || {})
75
- params[:headers]['Host'] ||= '' << params[:host] << ':' << params[:port]
69
+ # connection has defaults, merge in new params to override
70
+ params = @connection.merge(params)
71
+ params[:headers] = @connection[:headers].merge(params[:headers] || {})
72
+ params[:headers]['Host'] ||= '' << params[:host] << ':' << params[:port]
73
+
74
+ # if path is empty or doesn't start with '/', insert one
75
+ unless params[:path][0, 1] == '/'
76
+ params[:path].insert(0, '/')
77
+ end
76
78
 
77
- # if path is empty or doesn't start with '/', insert one
78
- unless params[:path][0, 1] == '/'
79
- params[:path].insert(0, '/')
79
+ if params.has_key?(:instrumentor)
80
+ if (retries_remaining ||= params[:retry_limit]) < params[:retry_limit]
81
+ event_name = "#{params[:instrumentor_name]}.retry"
82
+ else
83
+ event_name = "#{params[:instrumentor_name]}.request"
80
84
  end
81
-
82
- unless params[:mock]
83
- socket.params = params
85
+ params[:instrumentor].instrument(event_name, params) do
86
+ request_kernel(params, &block)
87
+ end
88
+ else
89
+ request_kernel(params, &block)
90
+ end
91
+ rescue => request_error
92
+ if params[:idempotent] && [Excon::Errors::SocketError,
93
+ Excon::Errors::HTTPStatusError].any? {|ex| request_error.kind_of? ex }
94
+ retries_remaining ||= params[:retry_limit]
95
+ retries_remaining -= 1
96
+ if retries_remaining > 0
97
+ if params[:body].respond_to?(:pos=)
98
+ params[:body].pos = 0
99
+ end
100
+ retry
84
101
  else
85
- mocked_response = invoke_stub(params, &block)
86
- return mocked_response unless mocked_response.nil?
102
+ if params.has_key?(:instrumentor)
103
+ params[:instrumentor].instrument("#{params[:instrumentor_name]}.error", :error => request_error)
104
+ end
105
+ raise(request_error)
106
+ end
107
+ else
108
+ if params.has_key?(:instrumentor)
109
+ params[:instrumentor].instrument("#{params[:instrumentor_name]}.error", :error => request_error)
110
+ end
111
+ raise(request_error)
112
+ end
113
+ end
114
+
115
+ def reset
116
+ (old_socket = sockets.delete(@socket_key)) && old_socket.close
117
+ end
118
+
119
+ # Generate HTTP request verb methods
120
+ Excon::HTTP_VERBS.each do |method|
121
+ eval <<-DEF
122
+ def #{method}(params={}, &block)
123
+ request(params.merge!(:method => :#{method}), &block)
124
+ end
125
+ DEF
126
+ end
127
+
128
+ def retry_limit=(new_retry_limit)
129
+ puts("Excon::Connection#retry_limit= is deprecated, pass :retry_limit to the initializer (#{caller.first})")
130
+ @connection[:retry_limit] = new_retry_limit
131
+ end
132
+
133
+ def retry_limit
134
+ puts("Excon::Connection#retry_limit is deprecated, pass :retry_limit to the initializer (#{caller.first})")
135
+ @connection[:retry_limit] ||= DEFAULT_RETRY_LIMIT
136
+ end
137
+
138
+ private
139
+
140
+ def request_kernel(params, &block)
141
+ begin
142
+ if params[:mock]
143
+ return invoke_stub(params, &block)
87
144
  end
88
145
 
146
+ socket.params = params
89
147
  # start with "METHOD /path"
90
148
  request = params[:method].to_s.upcase << ' '
91
149
  if @proxy
@@ -175,24 +233,8 @@ module Excon
175
233
  else
176
234
  response
177
235
  end
178
-
179
- rescue => request_error
180
- if params[:idempotent] && [Excon::Errors::SocketError, Excon::Errors::HTTPStatusError].any? {|ex| request_error.kind_of? ex }
181
- retries_remaining ||= retry_limit
182
- retries_remaining -= 1
183
- if retries_remaining > 0
184
- if params[:body].respond_to?(:pos=)
185
- params[:body].pos = 0
186
- end
187
- retry
188
- else
189
- raise(request_error)
190
- end
191
- else
192
- raise(request_error)
193
- end
194
236
  end
195
-
237
+
196
238
  def invoke_stub(params)
197
239
  for stub, response in Excon.stubs
198
240
  # all specified non-headers params match and no headers were specified or all specified headers match
@@ -221,29 +263,8 @@ module Excon
221
263
  raise(Excon::Errors::StubNotFound.new('no stubs matched ' << params.inspect))
222
264
  end
223
265
 
224
- def reset
225
- (old_socket = sockets.delete(@socket_key)) && old_socket.close
226
- end
227
-
228
- # Generate HTTP request verb methods
229
- Excon::HTTP_VERBS.each do |method|
230
- eval <<-DEF
231
- def #{method}(params={}, &block)
232
- request(params.merge!(:method => :#{method}), &block)
233
- end
234
- DEF
235
- end
236
-
237
- attr_writer :retry_limit
238
-
239
- def retry_limit
240
- @retry_limit ||= DEFAULT_RETRY_LIMIT
241
- end
242
-
243
- private
244
-
245
266
  def socket
246
- sockets[@socket_key] ||= if @connection[:scheme] == 'https'
267
+ sockets[@socket_key] ||= if @connection[:scheme] == HTTPS
247
268
  Excon::SSLSocket.new(@connection, @proxy)
248
269
  else
249
270
  Excon::Socket.new(@connection, @proxy)
@@ -1,20 +1,36 @@
1
1
  module Excon
2
2
  unless const_defined?(:VERSION)
3
- VERSION = '0.8.0'
3
+ VERSION = '0.9.0'
4
4
  end
5
5
 
6
6
  unless const_defined?(:CHUNK_SIZE)
7
7
  CHUNK_SIZE = 1048576 # 1 megabyte
8
8
  end
9
9
 
10
- unless const_defined?(:HTTP_VERBS)
11
- HTTP_VERBS = %w{connect delete get head options post put trace}
10
+ unless const_defined?(:CR_NL)
11
+ CR_NL = "\r\n"
12
12
  end
13
13
 
14
14
  unless const_defined?(:DEFAULT_RETRY_LIMIT)
15
15
  DEFAULT_RETRY_LIMIT = 4
16
16
  end
17
17
 
18
+ unless const_defined?(:FORCE_ENC)
19
+ FORCE_ENC = CR_NL.respond_to?(:force_encoding)
20
+ end
21
+
22
+ unless const_defined?(:HTTP_1_1)
23
+ HTTP_1_1 = " HTTP/1.1\r\n"
24
+ end
25
+
26
+ unless const_defined?(:HTTP_VERBS)
27
+ HTTP_VERBS = %w{connect delete get head options post put trace}
28
+ end
29
+
30
+ unless const_defined?(:HTTPS)
31
+ HTTPS = 'https'
32
+ end
33
+
18
34
  unless ::IO.const_defined?(:WaitReadable)
19
35
  class ::IO
20
36
  module WaitReadable; end
@@ -64,8 +64,7 @@ Shindo.tests('Excon request idempotencey') do
64
64
  end
65
65
  }
66
66
 
67
- connection = Excon.new('http://127.0.0.1:9292')
68
- connection.retry_limit = 2
67
+ connection = Excon.new('http://127.0.0.1:9292', :retry_limit => 2)
69
68
  response = connection.request(:method => :get, :idempotent => true, :path => '/some-path')
70
69
  response.status
71
70
  end
@@ -81,8 +80,7 @@ Shindo.tests('Excon request idempotencey') do
81
80
  end
82
81
  }
83
82
 
84
- connection = Excon.new('http://127.0.0.1:9292')
85
- connection.retry_limit = 2
83
+ connection = Excon.new('http://127.0.0.1:9292', :retry_limit => 2)
86
84
  response = connection.request(:method => :get, :idempotent => true, :path => '/some-path')
87
85
  response.status
88
86
  end
@@ -98,8 +96,7 @@ Shindo.tests('Excon request idempotencey') do
98
96
  end
99
97
  }
100
98
 
101
- connection = Excon.new('http://127.0.0.1:9292')
102
- connection.retry_limit = 8
99
+ connection = Excon.new('http://127.0.0.1:9292', :retry_limit => 8)
103
100
  response = connection.request(:method => :get, :idempotent => true, :path => '/some-path')
104
101
  response.status
105
102
  end
@@ -115,8 +112,7 @@ Shindo.tests('Excon request idempotencey') do
115
112
  end
116
113
  }
117
114
 
118
- connection = Excon.new('http://127.0.0.1:9292')
119
- connection.retry_limit = 8
115
+ connection = Excon.new('http://127.0.0.1:9292', :retry_limit => 8)
120
116
  response = connection.request(:method => :get, :idempotent => true, :path => '/some-path')
121
117
  response.status
122
118
  end
@@ -125,9 +121,6 @@ Shindo.tests('Excon request idempotencey') do
125
121
  run_count = 0
126
122
 
127
123
  connection = Excon.new('http://127.0.0.1:9292', :retry_limit => 6)
128
- tests("setter sets").returns(6) do
129
- connection.retry_limit
130
- end
131
124
 
132
125
  Excon.stub({:method => :get}) { |params|
133
126
  run_count += 1
@@ -0,0 +1,192 @@
1
+ require 'active_support/notifications'
2
+
3
+ class SimpleInstrumentor
4
+ class << self
5
+ attr_accessor :events
6
+
7
+ def instrument(name, params = {}, &block)
8
+ @events ||= []
9
+ @events << name
10
+ yield if block_given?
11
+ end
12
+ end
13
+ end
14
+
15
+ Shindo.tests('Excon instrumentation') do
16
+ before do
17
+ Excon.mock = true
18
+ end
19
+
20
+ after do
21
+ ActiveSupport::Notifications.unsubscribe("excon")
22
+ ActiveSupport::Notifications.unsubscribe("excon.request")
23
+ ActiveSupport::Notifications.unsubscribe("excon.retry")
24
+ ActiveSupport::Notifications.unsubscribe("excon.error")
25
+ ActiveSupport::Notifications.unsubscribe("gug")
26
+ Delorean.back_to_the_present
27
+ Excon.stubs.clear
28
+ Excon.mock = false
29
+ end
30
+
31
+ def subscribe(match)
32
+ @events = []
33
+ ActiveSupport::Notifications.subscribe(match) do |*args|
34
+ @events << ActiveSupport::Notifications::Event.new(*args)
35
+ end
36
+ end
37
+
38
+ def make_request(idempotent = false, params = {})
39
+ connection = Excon.new('http://127.0.0.1:9292',
40
+ :instrumentor => ActiveSupport::Notifications)
41
+ if idempotent
42
+ params[:idempotent] = :true
43
+ end
44
+ connection.get(params)
45
+ end
46
+
47
+ REQUEST_DELAY_SECONDS = 30
48
+ def stub_success
49
+ Excon.stub({:method => :get}) { |params|
50
+ Delorean.jump REQUEST_DELAY_SECONDS
51
+ {:body => params[:body], :headers => params[:headers], :status => 200}
52
+ }
53
+ end
54
+
55
+ def stub_retries
56
+ run_count = 0
57
+ Excon.stub({:method => :get}) { |params|
58
+ run_count += 1
59
+ if run_count <= 3 # First 3 calls fail.
60
+ raise Excon::Errors::SocketError.new(Exception.new "Mock Error")
61
+ else
62
+ {:body => params[:body], :headers => params[:headers], :status => 200}
63
+ end
64
+ }
65
+ end
66
+
67
+ def stub_failure
68
+ Excon.stub({:method => :get}) { |params|
69
+ raise Excon::Errors::SocketError.new(Exception.new "Mock Error")
70
+ }
71
+ end
72
+
73
+ tests('basic notification').returns('excon.request') do
74
+ subscribe(/excon/)
75
+ stub_success
76
+ make_request
77
+ @events.first.name
78
+ end
79
+
80
+ tests('captures scheme, host, port, and path').returns([:host, :path, :port, :scheme]) do
81
+ subscribe(/excon/)
82
+ stub_success
83
+ make_request
84
+ [:host, :path, :port, :scheme].select {|k| @events.first.payload.has_key? k}
85
+ end
86
+
87
+ tests('params in request overwrite those in construcor').returns('cheezburger') do
88
+ subscribe(/excon/)
89
+ stub_success
90
+ make_request(false, :host => 'cheezburger')
91
+ @events.first.payload[:host]
92
+ end
93
+
94
+ tests('notify on retry').returns(3) do
95
+ subscribe(/excon/)
96
+ stub_retries
97
+ make_request(true)
98
+ @events.count{|e| e.name =~ /retry/}
99
+ end
100
+
101
+ tests('notify on error').returns(true) do
102
+ subscribe(/excon/)
103
+ stub_failure
104
+ raises(Excon::Errors::SocketError) do
105
+ make_request
106
+ end
107
+
108
+ @events.any?{|e| e.name =~ /error/}
109
+ end
110
+
111
+ tests('filtering').returns(['excon.request', 'excon.error']) do
112
+ subscribe(/excon.request/)
113
+ subscribe(/excon.error/)
114
+ stub_failure
115
+ raises(Excon::Errors::SocketError) do
116
+ make_request(true)
117
+ end
118
+
119
+ @events.map(&:name)
120
+ end
121
+
122
+ tests('more filtering').returns(['excon.retry', 'excon.retry', 'excon.retry']) do
123
+ subscribe(/excon.retry/)
124
+ stub_failure
125
+ raises(Excon::Errors::SocketError) do
126
+ make_request(true)
127
+ end
128
+
129
+ @events.map(&:name)
130
+ end
131
+
132
+ tests('indicates duration').returns(true) do
133
+ subscribe(/excon/)
134
+ stub_success
135
+ make_request
136
+ (@events.first.duration/1000 - REQUEST_DELAY_SECONDS).abs < 1
137
+ end
138
+
139
+ tests('use our own instrumentor').returns(
140
+ ['excon.request', 'excon.retry', 'excon.retry', 'excon.retry', 'excon.error']) do
141
+ stub_failure
142
+ connection = Excon.new('http://127.0.0.1:9292',
143
+ :instrumentor => SimpleInstrumentor)
144
+ raises(Excon::Errors::SocketError) do
145
+ connection.get(:idempotent => true)
146
+ end
147
+
148
+ SimpleInstrumentor.events
149
+ end
150
+
151
+ tests('does not generate events when not provided').returns(0) do
152
+ subscribe(/excon/)
153
+ stub_success
154
+ connection = Excon.new('http://127.0.0.1:9292')
155
+ connection.get(:idempotent => true)
156
+ @events.count
157
+ end
158
+
159
+ tests('allows setting the prefix').returns(
160
+ ['gug.request', 'gug.retry', 'gug.retry','gug.retry', 'gug.error']) do
161
+ subscribe(/gug/)
162
+ stub_failure
163
+ connection = Excon.new('http://127.0.0.1:9292',
164
+ :instrumentor => ActiveSupport::Notifications, :instrumentor_name => 'gug')
165
+ raises(Excon::Errors::SocketError) do
166
+ connection.get(:idempotent => true)
167
+ end
168
+ @events.map(&:name)
169
+ end
170
+
171
+ tests('allows setting the prefix when not idempotent', 'foo').returns(
172
+ ['gug.request', 'gug.error']) do
173
+ subscribe(/gug/)
174
+ stub_failure
175
+ connection = Excon.new('http://127.0.0.1:9292',
176
+ :instrumentor => ActiveSupport::Notifications, :instrumentor_name => 'gug')
177
+ raises(Excon::Errors::SocketError) do
178
+ connection.get()
179
+ end
180
+ @events.map(&:name)
181
+ end
182
+
183
+ with_rackup('basic.ru') do
184
+ tests('works unmocked').returns('excon.request') do
185
+ Excon.mock = false
186
+ subscribe(/excon/)
187
+ make_request
188
+ @events.first.name
189
+ end
190
+ end
191
+ end
192
+
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.8.0
4
+ version: 0.9.0
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: 2011-12-12 00:00:00.000000000Z
14
+ date: 2011-12-14 00:00:00.000000000Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: open4
18
- requirement: &5046310 !ruby/object:Gem::Requirement
18
+ requirement: &70338621231260 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ! '>='
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: '0'
24
24
  type: :development
25
25
  prerelease: false
26
- version_requirements: *5046310
26
+ version_requirements: *70338621231260
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
- requirement: &5046020 !ruby/object:Gem::Requirement
29
+ requirement: &70338621230800 !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: *5046020
37
+ version_requirements: *70338621230800
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: shindo
40
- requirement: &5045670 !ruby/object:Gem::Requirement
40
+ requirement: &70338621230300 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - =
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: 0.2.0
46
46
  type: :development
47
47
  prerelease: false
48
- version_requirements: *5045670
48
+ version_requirements: *70338621230300
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: sinatra
51
- requirement: &5045400 !ruby/object:Gem::Requirement
51
+ requirement: &70338621229880 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ! '>='
@@ -56,7 +56,29 @@ dependencies:
56
56
  version: '0'
57
57
  type: :development
58
58
  prerelease: false
59
- version_requirements: *5045400
59
+ version_requirements: *70338621229880
60
+ - !ruby/object:Gem::Dependency
61
+ name: activesupport
62
+ requirement: &70338621220620 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: 3.1.3
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: *70338621220620
71
+ - !ruby/object:Gem::Dependency
72
+ name: delorean
73
+ requirement: &70338621220200 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: *70338621220200
60
82
  description: EXtended http(s) CONnections
61
83
  email: geemus@gmail.com
62
84
  executables: []
@@ -97,6 +119,7 @@ files:
97
119
  - tests/basic_tests.rb
98
120
  - tests/header_tests.rb
99
121
  - tests/idempotent_tests.rb
122
+ - tests/instrumentation_tests.rb
100
123
  - tests/proxy_tests.rb
101
124
  - tests/query_string_tests.rb
102
125
  - tests/rackups/basic.ru
@@ -132,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
132
155
  version: '0'
133
156
  requirements: []
134
157
  rubyforge_project: excon
135
- rubygems_version: 1.8.6
158
+ rubygems_version: 1.8.10
136
159
  signing_key:
137
160
  specification_version: 2
138
161
  summary: speed, persistence, http(s)