excon 0.62.0 → 0.85.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. checksums.yaml +5 -5
  2. data/LICENSE.md +1 -1
  3. data/README.md +6 -5
  4. data/data/cacert.pem +939 -1720
  5. data/excon.gemspec +17 -2
  6. data/lib/excon.rb +25 -17
  7. data/lib/excon/connection.rb +206 -139
  8. data/lib/excon/constants.rb +38 -13
  9. data/lib/excon/error.rb +15 -0
  10. data/lib/excon/headers.rb +4 -3
  11. data/lib/excon/instrumentors/logging_instrumentor.rb +4 -15
  12. data/lib/excon/instrumentors/standard_instrumentor.rb +2 -9
  13. data/lib/excon/middlewares/base.rb +6 -0
  14. data/lib/excon/middlewares/capture_cookies.rb +1 -1
  15. data/lib/excon/middlewares/decompress.rb +2 -2
  16. data/lib/excon/middlewares/expects.rb +7 -1
  17. data/lib/excon/middlewares/idempotent.rb +20 -3
  18. data/lib/excon/middlewares/instrumentor.rb +8 -0
  19. data/lib/excon/middlewares/mock.rb +12 -3
  20. data/lib/excon/middlewares/redirect_follower.rb +25 -3
  21. data/lib/excon/middlewares/response_parser.rb +3 -0
  22. data/lib/excon/pretty_printer.rb +1 -8
  23. data/lib/excon/response.rb +12 -9
  24. data/lib/excon/socket.rb +51 -33
  25. data/lib/excon/ssl_socket.rb +33 -13
  26. data/lib/excon/test/plugin/server/exec.rb +2 -2
  27. data/lib/excon/test/server.rb +1 -1
  28. data/lib/excon/unix_socket.rb +1 -0
  29. data/lib/excon/utils.rb +58 -5
  30. data/lib/excon/version.rb +1 -1
  31. metadata +27 -98
  32. data/.document +0 -5
  33. data/.gitignore +0 -13
  34. data/.rspec +0 -3
  35. data/.travis.yml +0 -29
  36. data/Gemfile +0 -19
  37. data/Rakefile +0 -41
  38. data/benchmarks/class_vs_lambda.rb +0 -50
  39. data/benchmarks/concat_vs_insert.rb +0 -21
  40. data/benchmarks/concat_vs_interpolate.rb +0 -22
  41. data/benchmarks/cr_lf.rb +0 -21
  42. data/benchmarks/downcase-eq-eq_vs_casecmp.rb +0 -169
  43. data/benchmarks/excon.rb +0 -69
  44. data/benchmarks/excon_vs.rb +0 -165
  45. data/benchmarks/for_vs_array_each.rb +0 -27
  46. data/benchmarks/for_vs_hash_each.rb +0 -27
  47. data/benchmarks/has_key-vs-lookup.rb +0 -177
  48. data/benchmarks/headers_case_sensitivity.rb +0 -83
  49. data/benchmarks/headers_split_vs_match.rb +0 -34
  50. data/benchmarks/implicit_block-vs-explicit_block.rb +0 -98
  51. data/benchmarks/merging.rb +0 -21
  52. data/benchmarks/single_vs_double_quotes.rb +0 -21
  53. data/benchmarks/string_ranged_index.rb +0 -87
  54. data/benchmarks/strip_newline.rb +0 -115
  55. data/benchmarks/vs_stdlib.rb +0 -82
  56. data/changelog.txt +0 -1083
  57. data/spec/excon/error_spec.rb +0 -139
  58. data/spec/excon/test/server_spec.rb +0 -28
  59. data/spec/excon_spec.rb +0 -7
  60. data/spec/helpers/file_path_helpers.rb +0 -22
  61. data/spec/requests/basic_spec.rb +0 -40
  62. data/spec/requests/eof_requests_spec.rb +0 -36
  63. data/spec/requests/unix_socket_spec.rb +0 -46
  64. data/spec/spec_helper.rb +0 -24
  65. data/spec/support/shared_contexts/test_server_context.rb +0 -83
  66. data/spec/support/shared_examples/shared_example_for_clients.rb +0 -218
  67. data/spec/support/shared_examples/shared_example_for_streaming_clients.rb +0 -20
  68. data/spec/support/shared_examples/shared_example_for_test_servers.rb +0 -16
  69. data/tests/authorization_header_tests.rb +0 -29
  70. data/tests/bad_tests.rb +0 -47
  71. data/tests/basic_tests.rb +0 -351
  72. data/tests/batch_requests.rb +0 -133
  73. data/tests/complete_responses.rb +0 -31
  74. data/tests/data/127.0.0.1.cert.crt +0 -20
  75. data/tests/data/127.0.0.1.cert.key +0 -27
  76. data/tests/data/excon.cert.crt +0 -20
  77. data/tests/data/excon.cert.key +0 -27
  78. data/tests/data/xs +0 -1
  79. data/tests/error_tests.rb +0 -145
  80. data/tests/header_tests.rb +0 -119
  81. data/tests/middlewares/canned_response_tests.rb +0 -34
  82. data/tests/middlewares/capture_cookies_tests.rb +0 -34
  83. data/tests/middlewares/decompress_tests.rb +0 -157
  84. data/tests/middlewares/escape_path_tests.rb +0 -36
  85. data/tests/middlewares/idempotent_tests.rb +0 -206
  86. data/tests/middlewares/instrumentation_tests.rb +0 -315
  87. data/tests/middlewares/mock_tests.rb +0 -304
  88. data/tests/middlewares/redirect_follower_tests.rb +0 -112
  89. data/tests/pipeline_tests.rb +0 -40
  90. data/tests/proxy_tests.rb +0 -306
  91. data/tests/query_string_tests.rb +0 -87
  92. data/tests/rackups/basic.rb +0 -41
  93. data/tests/rackups/basic.ru +0 -3
  94. data/tests/rackups/basic_auth.ru +0 -14
  95. data/tests/rackups/deflater.ru +0 -4
  96. data/tests/rackups/proxy.ru +0 -18
  97. data/tests/rackups/query_string.ru +0 -13
  98. data/tests/rackups/redirecting.ru +0 -23
  99. data/tests/rackups/redirecting_with_cookie.ru +0 -40
  100. data/tests/rackups/request_headers.ru +0 -15
  101. data/tests/rackups/request_methods.ru +0 -21
  102. data/tests/rackups/response_header.ru +0 -18
  103. data/tests/rackups/ssl.ru +0 -16
  104. data/tests/rackups/ssl_mismatched_cn.ru +0 -15
  105. data/tests/rackups/ssl_verify_peer.ru +0 -16
  106. data/tests/rackups/streaming.ru +0 -30
  107. data/tests/rackups/thread_safety.ru +0 -17
  108. data/tests/rackups/timeout.ru +0 -14
  109. data/tests/rackups/webrick_patch.rb +0 -34
  110. data/tests/request_headers_tests.rb +0 -21
  111. data/tests/request_method_tests.rb +0 -47
  112. data/tests/request_tests.rb +0 -59
  113. data/tests/response_tests.rb +0 -197
  114. data/tests/servers/bad.rb +0 -20
  115. data/tests/servers/eof.rb +0 -17
  116. data/tests/servers/error.rb +0 -20
  117. data/tests/servers/good.rb +0 -350
  118. data/tests/test_helper.rb +0 -306
  119. data/tests/thread_safety_tests.rb +0 -39
  120. data/tests/timeout_tests.rb +0 -12
  121. data/tests/utils_tests.rb +0 -81
data/tests/test_helper.rb DELETED
@@ -1,306 +0,0 @@
1
- require 'rubygems' if RUBY_VERSION < '1.9'
2
- require 'bundler/setup'
3
- require 'excon'
4
- require 'delorean'
5
- require 'open4'
6
-
7
- Excon.defaults.merge!(
8
- :connect_timeout => 5,
9
- :read_timeout => 5,
10
- :write_timeout => 5
11
- )
12
-
13
- def basic_tests(url = 'http://127.0.0.1:9292', options = {})
14
- ([true, false] * 2).combination(2).to_a.uniq.each do |nonblock, persistent|
15
- connection = nil
16
- test do
17
- options = options.merge({:ssl_verify_peer => false, :nonblock => nonblock, :persistent => persistent })
18
- connection = Excon.new(url, options)
19
- true
20
- end
21
-
22
- tests("nonblock => #{nonblock}, persistent => #{persistent}") do
23
-
24
- tests('GET /content-length/100') do
25
- response = nil
26
-
27
- tests('response.status').returns(200) do
28
- response = connection.request(:method => :get, :path => '/content-length/100')
29
-
30
- response.status
31
- end
32
-
33
- tests('response[:status]').returns(200) do
34
- response[:status]
35
- end
36
-
37
- tests("response.headers['Content-Length']").returns('100') do
38
- response.headers['Content-Length']
39
- end
40
-
41
- tests("response.headers['Content-Type']").returns('text/html;charset=utf-8') do
42
- response.headers['Content-Type']
43
- end
44
-
45
- test("Time.parse(response.headers['Date']).is_a?(Time)") do
46
- pending if connection.data[:scheme] == Excon::UNIX
47
- Time.parse(response.headers['Date']).is_a?(Time)
48
- end
49
-
50
- test("!!(response.headers['Server'] =~ /^WEBrick/)") do
51
- pending if connection.data[:scheme] == Excon::UNIX
52
- !!(response.headers['Server'] =~ /^WEBrick/)
53
- end
54
-
55
- tests("response.headers['Custom']").returns("Foo: bar") do
56
- response.headers['Custom']
57
- end
58
-
59
- tests("response.remote_ip").returns("127.0.0.1") do
60
- pending if connection.data[:scheme] == Excon::UNIX
61
- response.remote_ip
62
- end
63
-
64
- tests("response.body").returns('x' * 100) do
65
- response.body
66
- end
67
-
68
- tests("deprecated block usage").returns(['x' * 100, 0, 100]) do
69
- data = []
70
- silence_warnings do
71
- connection.request(:method => :get, :path => '/content-length/100') do |chunk, remaining_length, total_length|
72
- data = [chunk, remaining_length, total_length]
73
- end
74
- end
75
- data
76
- end
77
-
78
- tests("response_block usage").returns(['x' * 100, 0, 100]) do
79
- data = []
80
- response_block = lambda do |chunk, remaining_length, total_length|
81
- data = [chunk, remaining_length, total_length]
82
- end
83
- connection.request(:method => :get, :path => '/content-length/100', :response_block => response_block)
84
- data
85
- end
86
-
87
- end
88
-
89
- tests('POST /body-sink') do
90
-
91
- tests('response.body').returns("5000000") do
92
- response = connection.request(:method => :post, :path => '/body-sink', :headers => { 'Content-Type' => 'text/plain' }, :body => 'x' * 5_000_000)
93
- response.body
94
- end
95
-
96
- tests('empty body').returns('0') do
97
- response = connection.request(:method => :post, :path => '/body-sink', :headers => { 'Content-Type' => 'text/plain' }, :body => '')
98
- response.body
99
- end
100
-
101
- end
102
-
103
- tests('POST /echo') do
104
-
105
- tests('with file').returns('x' * 100 + "\n") do
106
- file_path = File.join(File.dirname(__FILE__), "data", "xs")
107
- response = connection.request(:method => :post, :path => '/echo', :body => File.open(file_path))
108
- response.body
109
- end
110
-
111
- tests('without request_block').returns('x' * 100) do
112
- response = connection.request(:method => :post, :path => '/echo', :body => 'x' * 100)
113
- response.body
114
- end
115
-
116
- tests('with request_block').returns('x' * 100) do
117
- data = ['x'] * 100
118
- request_block = lambda do
119
- data.shift.to_s
120
- end
121
- response = connection.request(:method => :post, :path => '/echo', :request_block => request_block)
122
- response.body
123
- end
124
-
125
- tests('with multi-byte strings') do
126
- body = "\xC3\xBC" * 100
127
- headers = { 'Custom' => body.dup }
128
- if RUBY_VERSION >= '1.9'
129
- body.force_encoding('BINARY')
130
- headers['Custom'].force_encoding('UTF-8')
131
- end
132
-
133
- returns(body, 'properly concatenates request+headers and body') do
134
- response = connection.request(:method => :post, :path => '/echo', :headers => headers, :body => body)
135
- response.body
136
- end
137
- end
138
-
139
- end
140
-
141
- tests('PUT /echo') do
142
-
143
- tests('with file').returns('x' * 100 + "\n") do
144
- file_path = File.join(File.dirname(__FILE__), "data", "xs")
145
- response = connection.request(:method => :put, :path => '/echo', :body => File.open(file_path))
146
- response.body
147
- end
148
-
149
- tests('without request_block').returns('x' * 100) do
150
- response = connection.request(:method => :put, :path => '/echo', :body => 'x' * 100)
151
- response.body
152
- end
153
-
154
- tests('request_block usage').returns('x' * 100) do
155
- data = ['x'] * 100
156
- request_block = lambda do
157
- data.shift.to_s
158
- end
159
- response = connection.request(:method => :put, :path => '/echo', :request_block => request_block)
160
- response.body
161
- end
162
-
163
- tests('with multi-byte strings') do
164
- body = "\xC3\xBC" * 100
165
- headers = { 'Custom' => body.dup }
166
- if RUBY_VERSION >= '1.9'
167
- body.force_encoding('BINARY')
168
- headers['Custom'].force_encoding('UTF-8')
169
- end
170
-
171
- returns(body, 'properly concatenates request+headers and body') do
172
- response = connection.request(:method => :put, :path => '/echo', :headers => headers, :body => body)
173
- response.body
174
- end
175
- end
176
-
177
- end
178
-
179
- tests('should succeed with tcp_nodelay').returns(200) do
180
- options = options.merge(:ssl_verify_peer => false, :nonblock => nonblock, :tcp_nodelay => true)
181
- connection = Excon.new(url, options)
182
- response = connection.request(:method => :get, :path => '/content-length/100')
183
- response.status
184
- end
185
-
186
- end
187
- end
188
- end
189
-
190
-
191
- PROXY_ENV_VARIABLES = %w{http_proxy https_proxy no_proxy} # All lower-case
192
-
193
- def env_init(env={})
194
- current = {}
195
- PROXY_ENV_VARIABLES.each do |key|
196
- current[key] = ENV.delete(key)
197
- current[key.upcase] = ENV.delete(key.upcase)
198
- end
199
- env_stack << current
200
-
201
- env.each do |key, value|
202
- ENV[key] = value
203
- end
204
- end
205
-
206
- def env_restore
207
- ENV.update(env_stack.pop)
208
- end
209
-
210
- def env_stack
211
- @env_stack ||= []
212
- end
213
-
214
- def silence_warnings
215
- orig_verbose = $VERBOSE
216
- $VERBOSE = nil
217
- yield
218
- ensure
219
- $VERBOSE = orig_verbose
220
- end
221
-
222
- def capture_response_block
223
- captures = []
224
- yield lambda {|chunk, remaining_bytes, total_bytes|
225
- captures << [chunk, remaining_bytes, total_bytes]
226
- }
227
- captures
228
- end
229
-
230
- def rackup_path(*parts)
231
- File.expand_path(File.join(File.dirname(__FILE__), 'rackups', *parts))
232
- end
233
-
234
- def with_rackup(name, host="127.0.0.1")
235
- unless RUBY_PLATFORM == 'java'
236
- GC.disable if RUBY_VERSION < '1.9'
237
- pid, w, r, e = Open4.popen4("rackup", "-s", "webrick", "--host", host, rackup_path(name))
238
- else
239
- pid, w, r, e = IO.popen4("rackup", "-s", "webrick", "--host", host, rackup_path(name))
240
- end
241
- until e.gets =~ /HTTPServer#start:/; end
242
- yield
243
- ensure
244
- Process.kill(9, pid)
245
- unless RUBY_PLATFORM == 'java'
246
- GC.enable if RUBY_VERSION < '1.9'
247
- Process.wait(pid)
248
- end
249
-
250
- # dump server errors
251
- lines = e.read.split($/)
252
- while line = lines.shift
253
- case line
254
- when /(ERROR|Error)/
255
- unless line =~ /(null cert chain|did not return a certificate|SSL_read:: internal error)/
256
- in_err = true
257
- puts
258
- end
259
- when /^(127|localhost)/
260
- in_err = false
261
- end
262
- puts line if in_err
263
- end
264
- end
265
-
266
- def with_unicorn(name, listen='127.0.0.1:9292')
267
- unless RUBY_PLATFORM == 'java'
268
- GC.disable if RUBY_VERSION < '1.9'
269
- unix_socket = listen.sub('unix://', '') if listen.start_with? 'unix://'
270
- pid, w, r, e = Open4.popen4("unicorn", "--no-default-middleware","-l", listen, rackup_path(name))
271
- until e.gets =~ /worker=0 ready/; end
272
- else
273
- # need to find suitable server for jruby
274
- end
275
- yield
276
- ensure
277
- unless RUBY_PLATFORM == 'java'
278
- Process.kill(9, pid)
279
- GC.enable if RUBY_VERSION < '1.9'
280
- Process.wait(pid)
281
- end
282
- if not unix_socket.nil? and File.exist?(unix_socket)
283
- File.delete(unix_socket)
284
- end
285
- end
286
-
287
- def server_path(*parts)
288
- File.expand_path(File.join(File.dirname(__FILE__), 'servers', *parts))
289
- end
290
-
291
- def with_server(name)
292
- unless RUBY_PLATFORM == 'java'
293
- GC.disable if RUBY_VERSION < '1.9'
294
- pid, w, r, e = Open4.popen4(server_path("#{name}.rb"))
295
- else
296
- pid, w, r, e = IO.popen4(server_path("#{name}.rb"))
297
- end
298
- until e.gets =~ /ready/; end
299
- yield
300
- ensure
301
- Process.kill(9, pid)
302
- unless RUBY_PLATFORM == 'java'
303
- GC.enable if RUBY_VERSION < '1.9'
304
- Process.wait(pid)
305
- end
306
- end
@@ -1,39 +0,0 @@
1
- Shindo.tests('Excon thread safety') do
2
-
3
- tests('thread_safe_sockets configuration') do
4
- tests('thread_safe_sockets default').returns(true) do
5
- connection = Excon.new('http://foo.com')
6
- connection.data[:thread_safe_sockets]
7
- end
8
-
9
- tests('with thread_safe_sockets set false').returns(false) do
10
- connection = Excon.new('http://foo.com', :thread_safe_sockets => false)
11
- connection.data[:thread_safe_sockets]
12
- end
13
- end
14
-
15
- with_rackup('thread_safety.ru') do
16
- connection = Excon.new('http://127.0.0.1:9292')
17
-
18
- long_thread = Thread.new {
19
- response = connection.request(:method => 'GET', :path => '/id/1/wait/2')
20
- Thread.current[:success] = response.body == '1'
21
- }
22
-
23
- short_thread = Thread.new {
24
- response = connection.request(:method => 'GET', :path => '/id/2/wait/1')
25
- Thread.current[:success] = response.body == '2'
26
- }
27
-
28
- test('long_thread') do
29
- long_thread.join
30
- short_thread.join
31
-
32
- long_thread[:success]
33
- end
34
-
35
- test('short_thread') do
36
- short_thread[:success]
37
- end
38
- end
39
- end
@@ -1,12 +0,0 @@
1
- Shindo.tests('read should timeout') do
2
- with_rackup('timeout.ru') do
3
-
4
- [false, true].each do |nonblock|
5
- tests("nonblock => #{nonblock} hits read_timeout").raises(Excon::Errors::Timeout) do
6
- connection = Excon.new('http://127.0.0.1:9292', :nonblock => nonblock)
7
- connection.request(:method => :get, :path => '/timeout', :read_timeout => 1)
8
- end
9
- end
10
-
11
- end
12
- end
data/tests/utils_tests.rb DELETED
@@ -1,81 +0,0 @@
1
- Shindo.tests('Excon::Utils') do
2
-
3
- tests('#connection_uri') do
4
-
5
- expected_uri = 'unix:///tmp/some.sock'
6
- tests('using UNIX scheme').returns(expected_uri) do
7
- connection = Excon.new('unix:///some/path', :socket => '/tmp/some.sock')
8
- Excon::Utils.connection_uri(connection.data)
9
- end
10
-
11
- tests('using HTTP scheme') do
12
-
13
- expected_uri = 'http://foo.com:80'
14
- tests('with default port').returns(expected_uri) do
15
- connection = Excon.new('http://foo.com/some/path')
16
- Excon::Utils.connection_uri(connection.data)
17
- end
18
-
19
- expected_uri = 'http://foo.com'
20
- tests('without default port').returns(expected_uri) do
21
- connection = Excon.new('http://foo.com/some/path', :omit_default_port => true)
22
- Excon::Utils.connection_uri(connection.data)
23
- end
24
-
25
- end
26
-
27
- end
28
-
29
- tests('#request_uri') do
30
-
31
- tests('using UNIX scheme') do
32
-
33
- expected_uri = 'unix:///tmp/some.sock/some/path'
34
- tests('without query').returns(expected_uri) do
35
- connection = Excon.new('unix:/', :socket => '/tmp/some.sock')
36
- params = { :path => '/some/path' }
37
- Excon::Utils.request_uri(connection.data.merge(params))
38
- end
39
-
40
- expected_uri = 'unix:///tmp/some.sock/some/path?bar=that&foo=this'
41
- tests('with query').returns(expected_uri) do
42
- connection = Excon.new('unix:/', :socket => '/tmp/some.sock')
43
- params = { :path => '/some/path', :query => { :foo => 'this', :bar => 'that' } }
44
- Excon::Utils.request_uri(connection.data.merge(params))
45
- end
46
-
47
- end
48
-
49
- tests('using HTTP scheme') do
50
-
51
- expected_uri = 'http://foo.com:80/some/path'
52
- tests('without query').returns(expected_uri) do
53
- connection = Excon.new('http://foo.com')
54
- params = { :path => '/some/path' }
55
- Excon::Utils.request_uri(connection.data.merge(params))
56
- end
57
-
58
- expected_uri = 'http://foo.com:80/some/path?bar=that&foo=this'
59
- tests('with query').returns(expected_uri) do
60
- connection = Excon.new('http://foo.com')
61
- params = { :path => '/some/path', :query => { :foo => 'this', :bar => 'that' } }
62
- Excon::Utils.request_uri(connection.data.merge(params))
63
- end
64
-
65
- end
66
-
67
- end
68
-
69
- tests('#escape_uri').returns('/hello%20excon') do
70
- Excon::Utils.escape_uri('/hello excon')
71
- end
72
-
73
- tests('#unescape_uri').returns('/hello excon') do
74
- Excon::Utils.unescape_uri('/hello%20excon')
75
- end
76
-
77
- tests('#unescape_form').returns('message=We love excon!') do
78
- Excon::Utils.unescape_form('message=We+love+excon!')
79
- end
80
-
81
- end