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 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
+ # +--------+----------+
@@ -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
 
@@ -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.5'
17
- s.date = '2012-01-16'
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
@@ -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 [true, false] Whether or not to verify the peer's SSL certificate / chain
24
- attr_reader :ssl_verify_peer
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
- # setup ssl defaults based on platform
27
- @ssl_verify_peer = RbConfig::CONFIG['host_os'] !~ /mswin|win32|dos|cygwin|mingw/i
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 to the initializer (#{caller.first})")
32
- @mock
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= is deprecated, pass :mock to the initializer (#{caller.first})")
40
- @mock = new_mock
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
@@ -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
- :write_timeout => 60
34
- }.merge!(params)
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[:body]
201
+ if params[:headers]['Content-Length'] != 0
205
202
  if params[:body].is_a?(String)
206
203
  socket.write(params[:body])
207
204
  else
@@ -1,6 +1,6 @@
1
1
  module Excon
2
2
  unless const_defined?(:VERSION)
3
- VERSION = '0.9.5'
3
+ VERSION = '0.9.6'
4
4
  end
5
5
 
6
6
  unless const_defined?(:CHUNK_SIZE)
@@ -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
@@ -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
 
@@ -20,7 +20,7 @@ Shindo.tests('Excon request idempotencey') do
20
20
  end
21
21
  }
22
22
 
23
- response = @connection.request(:method => :get, :path => '/some-path')
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
@@ -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
- response = connection.request(:method => :get, :path => '/content-length/100')
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
- response = connection.request(:method => :get, :path => '/content-length/100') do |chunk, remaining_bytes, total_bytes|
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']
@@ -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.5
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-01-16 00:00:00.000000000Z
14
+ date: 2012-02-22 00:00:00.000000000Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: activesupport
18
- requirement: &70238243324360 !ruby/object:Gem::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: *70238243324360
26
+ version_requirements: *9166800
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: delorean
29
- requirement: &70238243323780 !ruby/object:Gem::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: *70238243323780
37
+ version_requirements: *9166610
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: open4
40
- requirement: &70238243322680 !ruby/object:Gem::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: *70238243322680
48
+ version_requirements: *9166380
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: rake
51
- requirement: &70238243322040 !ruby/object:Gem::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: *70238243322040
59
+ version_requirements: *9166170
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: rdoc
62
- requirement: &70238243321160 !ruby/object:Gem::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: *70238243321160
70
+ version_requirements: *9165960
71
71
  - !ruby/object:Gem::Dependency
72
72
  name: shindo
73
- requirement: &70238243320420 !ruby/object:Gem::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: *70238243320420
81
+ version_requirements: *9165750
82
82
  - !ruby/object:Gem::Dependency
83
83
  name: sinatra
84
- requirement: &70238243319760 !ruby/object:Gem::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: *70238243319760
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: 1843710619352471147
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.10
173
+ rubygems_version: 1.8.6
173
174
  signing_key:
174
175
  specification_version: 2
175
176
  summary: speed, persistence, http(s)