excon 0.32.1 → 0.33.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.

checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjhlZWY0ODAzZTA3MjhjOWE5ZWQwY2Y1ZWY5MmYzMTBmODEyMDBjZg==
4
+ Y2YwNTZjYTAxYWZmNGIwNjc1NTZiN2EzNTkzYTgzM2YyNGFiYzZiMw==
5
5
  data.tar.gz: !binary |-
6
- MWE0YmVlNmJiNmM2ZjYyYWVmMGYyNzJhZGRiOGU0MjFlMTgwNzk2ZQ==
6
+ NjkwYzY3MDg3NzIwNzZmNzU3MTRiMzQxMjc5MjliMTBlYzNlNGMwNQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZTJiNzg1Zjc1YmIzZmViZDhmYjFhYmIzM2QwYjllM2E0YmY1ZWJlMzNjNDY2
10
- N2E2ZGUwYjJmNjQzOTNhYTg3NjVjYWNkNWRkNGQ3YTZlZjM3ZDFjMDIzZjEw
11
- YWQ5ZmUxYzdlZmNlNTA2MzBmMDRlZDEyODc0N2Q1MmQyYjIwMjM=
9
+ YzZmM2U5MmIxNjRjMzQ0OWI3Yjg1ODE4ODBmN2IzM2RjYjcyNzRjYjlkOGVi
10
+ YTE1OWJkNTBiNTgwYzUyMjY1NzUxOTIyN2U5NjY1MTNiMzRhYjU1ZDEyOGVi
11
+ ZTY1YTQ3NWE1MjBmNGFiNzgwMWMxNjdhM2NjOTI1NTA2YjMyODY=
12
12
  data.tar.gz: !binary |-
13
- NzE1MTI2MmFhYWU4MTczZGUwNzZhZTAyMTcwNjAwM2NiM2ZmN2E2ZGIxMjQ5
14
- YzYxM2JjZjU3NDE3NDhhNzlmYjRhMjY1ZGNiNGRlN2IxN2E0NjcyOWU0N2U0
15
- MzRlNzk1Yjk5NmNhYjQ0NGQwOTBhOGRmYzc2MDhjYjE2ODRmMWY=
13
+ MTlhYzI2Y2Y0NWM2Y2ViZTAyM2MzNTdjN2YzMmIwOGQ1MTgzNzQwNDE1ODlj
14
+ OThhZTg1NDRkYTRhNWUzNzE2NGU5NTRiMjY2Y2Y2MjVkN2E5ZWQzYzUwYjY2
15
+ NTI3ZmJjYjA1MjA1MzBhZWZiYmU5YTY0YWRmZGM2YTcwOGFhYzI=
data/CONTRIBUTORS.md CHANGED
@@ -1,6 +1,8 @@
1
1
  * Andrew Katz <andrew.katz@outright.com>
2
2
  * Anshul Khandelwal <anshul@anshulkhandelwal.com>
3
+ * Ash Wilson <smashwilson@gmail.com>
3
4
  * Ben Burkert <ben@benburkert.com>
5
+ * Bo Jeanes <me@bjeanes.com>
4
6
  * Brandur <brandur@mutelight.org>
5
7
  * Brian D. Burns <iosctr@gmail.com>
6
8
  * Brian Hartsock <brian.hartsock@gmail.com>
@@ -29,6 +31,7 @@
29
31
  * Jonas Pfenniger <jonas@pfenniger.name>
30
32
  * Jonathan Dance <github@wuputah.com>
31
33
  * Jonathan Dance <jd@wuputah.com>
34
+ * Jonathan Roes <jroes@jroes.net>
32
35
  * Joshua Mckinney <joshmckin@gmail.com>
33
36
  * Joshua Napoli <jnapoli@swipely-napoli.home>
34
37
  * Joshua Napoli <jnapoli@swipely-napoli.local>
@@ -86,5 +89,6 @@
86
89
  * rin_ne <rinrin.ne@gmail.com>
87
90
  * rinrinne <rinrin.ne@gmail.com>
88
91
  * rkyrychuk <ruslan.kyrychuk@gmail.com>
92
+ * sshaw <skye.shaw@gmail.com>
89
93
  * twrodriguez <tw.rodriguez@gmail.com>
90
94
  * zimbatm <zimbatm@zimbatm.com>
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- excon (0.32.1)
4
+ excon (0.33.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/README.md CHANGED
@@ -137,6 +137,11 @@ connection = Excon.new('http://geemus.com/', :connect_timeout => 360)
137
137
 
138
138
  # opt-out of nonblocking operations for performance and/or as a workaround
139
139
  connection = Excon.new('http://geemus.com/', :nonblock => false)
140
+
141
+ # use basic authentication by supplying credentials in the URL or as parameters
142
+ connection = Excon.new('http://username:password@secure.geemus.com')
143
+ connection = Excon.new('http://secure.geemus.com',
144
+ :user => 'username', :password => 'password')
140
145
  ```
141
146
 
142
147
  ## Chunked Requests
@@ -274,7 +279,7 @@ config.after(:each) do
274
279
  end
275
280
  ```
276
281
 
277
- You can also modify 'Excon.defaults` to set a stub for all requests, so for a test suite you might do this:
282
+ You can also modify `Excon.defaults` to set a stub for all requests, so for a test suite you might do this:
278
283
 
279
284
  ```ruby
280
285
  # Mock by default and stub any request as success
data/changelog.txt CHANGED
@@ -1,3 +1,9 @@
1
+ 0.33.0 05/15/2014
2
+ =================
3
+
4
+ README clarifications around defaults and basic auth
5
+ case insensitive headers
6
+
1
7
  0.32.1 03/13/2014
2
8
  =================
3
9
 
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.32.1'
17
- s.date = '2014-03-13'
16
+ s.version = '0.33.0'
17
+ s.date = '2014-04-15'
18
18
  s.rubyforge_project = 'excon'
19
19
 
20
20
  ## Make sure your summary is short. The description may be as long
@@ -100,6 +100,7 @@ Gem::Specification.new do |s|
100
100
  lib/excon/connection.rb
101
101
  lib/excon/constants.rb
102
102
  lib/excon/errors.rb
103
+ lib/excon/headers.rb
103
104
  lib/excon/middlewares/base.rb
104
105
  lib/excon/middlewares/decompress.rb
105
106
  lib/excon/middlewares/escape_path.rb
data/lib/excon.rb CHANGED
@@ -71,6 +71,7 @@ require 'excon/middlewares/mock'
71
71
  require 'excon/middlewares/redirect_follower'
72
72
  require 'excon/middlewares/response_parser'
73
73
  require 'excon/response'
74
+ require 'excon/headers'
74
75
  require 'excon/socket'
75
76
  require 'excon/ssl_socket'
76
77
  require 'excon/unix_socket'
@@ -83,6 +83,10 @@ module Excon
83
83
 
84
84
  if ENV.has_key?('EXCON_DEBUG') || ENV.has_key?('EXCON_STANDARD_INSTRUMENTOR')
85
85
  @data[:instrumentor] = Excon::StandardInstrumentor
86
+
87
+ if ENV.has_key?('EXCON_DEBUG')
88
+ @data[:debug_request] = @data[:debug_reponse] = true
89
+ end
86
90
  end
87
91
 
88
92
  # Use Basic Auth if url contains a login
@@ -1,6 +1,6 @@
1
1
  module Excon
2
2
 
3
- VERSION = '0.32.1'
3
+ VERSION = '0.33.0'
4
4
 
5
5
  CR_NL = "\r\n"
6
6
 
@@ -0,0 +1,117 @@
1
+ module Excon
2
+ class Headers < Hash
3
+
4
+ SENTINEL = {}
5
+
6
+ alias_method :raw_writer, :[]=
7
+ alias_method :raw_reader, :[]
8
+ if SENTINEL.respond_to?(:assoc)
9
+ alias_method :raw_assoc, :assoc
10
+ end
11
+ alias_method :raw_delete, :delete
12
+ alias_method :raw_fetch, :fetch
13
+ alias_method :raw_has_key?, :has_key?
14
+ alias_method :raw_include?, :include?
15
+ alias_method :raw_key?, :key?
16
+ alias_method :raw_member?, :member?
17
+ alias_method :raw_rehash, :rehash
18
+ alias_method :raw_store, :store
19
+ alias_method :raw_values_at, :values_at
20
+
21
+ def [](key)
22
+ if should_delegate?(key)
23
+ @downcased[key.downcase]
24
+ else
25
+ raw_reader(key)
26
+ end
27
+ end
28
+
29
+ alias_method :[]=, :store
30
+ def []=(key, value)
31
+ raw_writer(key, value)
32
+ unless @downcased.nil?
33
+ @downcased[key.downcase] = value
34
+ end
35
+ end
36
+
37
+ if SENTINEL.respond_to? :assoc
38
+ def assoc(obj)
39
+ if should_delegate?(obj)
40
+ @downcased.assoc(obj.downcase)
41
+ else
42
+ raw_assoc(obj)
43
+ end
44
+ end
45
+ end
46
+
47
+ def delete(key, &proc)
48
+ if should_delegate?(key)
49
+ @downcased.delete(key.downcase, &proc)
50
+ else
51
+ raw_delete(key, &proc)
52
+ end
53
+ end
54
+
55
+ def fetch(key, default = nil, &proc)
56
+ if should_delegate?(key)
57
+ if proc
58
+ @downcased.fetch(key.downcase, &proc)
59
+ else
60
+ @downcased.fetch(key.downcase, default)
61
+ end
62
+ else
63
+ if proc
64
+ raw_fetch(key, &proc)
65
+ else
66
+ raw_fetch(key, default)
67
+ end
68
+ end
69
+ end
70
+
71
+ alias_method :has_key?, :key?
72
+ alias_method :has_key?, :member?
73
+ def has_key?(key)
74
+ raw_has_key?(key) || begin
75
+ index_case_insensitive
76
+ @downcased.has_key?(key.downcase)
77
+ end
78
+ end
79
+
80
+ def rehash
81
+ raw_rehash
82
+ if @downcased
83
+ @downcased.rehash
84
+ end
85
+ end
86
+
87
+ def values_at(*keys)
88
+ raw_values_at(*keys).zip(keys).map do |v, k|
89
+ if v.nil?
90
+ index_case_insensitive
91
+ @downcased[k.downcase]
92
+ end
93
+ end
94
+ end
95
+
96
+ private
97
+
98
+ def should_delegate?(key)
99
+ if raw_has_key?(key)
100
+ false
101
+ else
102
+ index_case_insensitive
103
+ true
104
+ end
105
+ end
106
+
107
+ def index_case_insensitive
108
+ if @downcased.nil?
109
+ @downcased = {}
110
+ each_pair do |key, value|
111
+ @downcased[key.downcase] = value
112
+ end
113
+ end
114
+ end
115
+
116
+ end
117
+ end
@@ -42,7 +42,7 @@ module Excon
42
42
 
43
43
  datum[:response] = {
44
44
  :body => '',
45
- :headers => {},
45
+ :headers => Excon::Headers.new,
46
46
  :status => status,
47
47
  :remote_ip => socket.respond_to?(:remote_ip) && socket.remote_ip,
48
48
  :local_port => socket.respond_to?(:local_port) && socket.local_port,
@@ -132,7 +132,7 @@ module Excon
132
132
  def initialize(params={})
133
133
  @data = {
134
134
  :body => '',
135
- :headers => {}
135
+ :headers => Excon::Headers.new
136
136
  }.merge(params)
137
137
  @body = @data[:body]
138
138
  @headers = @data[:headers]
@@ -154,12 +154,7 @@ module Excon
154
154
  # Retrieve a specific header value. Header names are treated case-insensitively.
155
155
  # @param [String] name Header name
156
156
  def get_header(name)
157
- headers.each do |key,value|
158
- if key.casecmp(name) == 0
159
- return value
160
- end
161
- end
162
- nil
157
+ headers[name]
163
158
  end
164
159
 
165
160
  end # class Response
@@ -1,6 +1,71 @@
1
1
  Shindo.tests('Excon response header support') do
2
2
  env_init
3
3
 
4
+ tests('Excon::Headers storage') do
5
+ headers = Excon::Headers.new
6
+ headers['Exact-Case'] = 'expected'
7
+ headers['Another-Fixture'] = 'another'
8
+
9
+ tests('stores and retrieves as received').returns('expected') do
10
+ headers['Exact-Case']
11
+ end
12
+
13
+ tests('enumerates keys as received') do
14
+ ks = headers.keys
15
+ tests('contains Exact-Case').returns(true) { ks.include? 'Exact-Case' }
16
+ tests('contains Another-Fixture').returns(true) { ks.include? 'Another-Fixture' }
17
+ end
18
+
19
+ tests('supports case-insensitive access').returns('expected') do
20
+ headers['EXACT-CASE']
21
+ end
22
+
23
+ tests('but still returns nil for missing keys').returns(nil) do
24
+ headers['Missing-Header']
25
+ end
26
+
27
+ tests('Hash methods that should support case-insensitive access') do
28
+ if {}.respond_to? :assoc
29
+ tests('#assoc').returns(%w{exact-case expected}) do
30
+ headers.assoc('exact-Case')
31
+ end
32
+ end
33
+
34
+ tests('#delete') do
35
+ tests('with just a key').returns('yes') do
36
+ headers['Extra'] = 'yes'
37
+ headers.delete('extra')
38
+ end
39
+
40
+ tests('with a proc').returns('called with notpresent') do
41
+ headers.delete('notpresent') { |k| "called with #{k}" }
42
+ end
43
+ end
44
+
45
+ tests('#fetch') do
46
+ tests('when present').returns('expected') { headers.fetch('exact-CASE') }
47
+ tests('with a default value').returns('default') { headers.fetch('missing', 'default') }
48
+ tests('with a default proc').returns('got missing') do
49
+ headers.fetch('missing') { |k| "got #{k}" }
50
+ end
51
+ end
52
+
53
+ tests('#has_key?') do
54
+ tests('when present').returns(true) { headers.has_key?('EXACT-case') }
55
+ tests('when absent').returns(false) { headers.has_key?('missing') }
56
+ end
57
+
58
+ tests('#values_at') do
59
+ tests('all present').returns(%w{expected another}) do
60
+ headers.values_at('exACT-cASE', 'anotheR-fixturE')
61
+ end
62
+ tests('some missing').returns(['expected', nil]) do
63
+ headers.values_at('exact-case', 'missing-header')
64
+ end
65
+ end
66
+ end
67
+ end
68
+
4
69
  with_rackup('response_header.ru') do
5
70
 
6
71
  tests('Response#get_header') do
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.32.1
4
+ version: 0.33.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dpiddy (Dan Peterson)
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2014-03-13 00:00:00.000000000 Z
13
+ date: 2014-04-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -163,6 +163,7 @@ files:
163
163
  - lib/excon/connection.rb
164
164
  - lib/excon/constants.rb
165
165
  - lib/excon/errors.rb
166
+ - lib/excon/headers.rb
166
167
  - lib/excon/middlewares/base.rb
167
168
  - lib/excon/middlewares/decompress.rb
168
169
  - lib/excon/middlewares/escape_path.rb