Hello community, here is the log from the commit of package rubygem-excon for openSUSE:Factory checked in at 2016-04-12 19:34:16 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-excon (Old) and /work/SRC/openSUSE:Factory/.rubygem-excon.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-excon" Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-excon/rubygem-excon.changes 2016-03-18 21:40:25.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.rubygem-excon.new/rubygem-excon.changes 2016-04-12 19:34:17.000000000 +0200 @@ -1,0 +2,16 @@ +Wed Apr 6 06:18:07 UTC 2016 - [email protected] + +- updated to version 0.49.0 + see installed changelog.txt + + 0.49.0 03/28/2016 + ================= + + fix nonblock ssl socket connect timeout handling + fix README debug example + make unique class for certificate errors + connection logic cleanup + change stubs back to global (with local option via defaults) + specific handling for set-cookie header exceptions + +------------------------------------------------------------------- Old: ---- excon-0.48.0.gem New: ---- excon-0.49.0.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-excon.spec ++++++ --- /var/tmp/diff_new_pack.c8B08A/_old 2016-04-12 19:34:18.000000000 +0200 +++ /var/tmp/diff_new_pack.c8B08A/_new 2016-04-12 19:34:18.000000000 +0200 @@ -24,7 +24,7 @@ # Name: rubygem-excon -Version: 0.48.0 +Version: 0.49.0 Release: 0 %define mod_name excon %define mod_full_name %{mod_name}-%{version} ++++++ excon-0.48.0.gem -> excon-0.49.0.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Gemfile.lock new/Gemfile.lock --- old/Gemfile.lock 2016-03-07 22:19:26.000000000 +0100 +++ new/Gemfile.lock 2016-03-28 22:32:51.000000000 +0200 @@ -1,7 +1,7 @@ PATH remote: . specs: - excon (0.48.0) + excon (0.49.0) GEM remote: http://rubygems.org/ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.md new/README.md --- old/README.md 2016-03-07 22:19:26.000000000 +0100 +++ new/README.md 2016-03-28 22:32:51.000000000 +0200 @@ -86,7 +86,7 @@ ```ruby # Output debug info, similar to ENV['EXCON_DEBUG'] -connection = Excon.new('http://geemus.com/', :debug => true) +connection = Excon.new('http://geemus.com/', :debug_request => true, :debug_response => true) # Custom headers Excon.get('http://geemus.com', :headers => {'Authorization' => 'Basic 0123456789ABCDEF'}) @@ -308,6 +308,8 @@ end ``` +By default stubs are shared globally, to make stubs unique to each thread, use `Excon.defaults[:stubs] = :local`. + ## Instrumentation Excon calls can be timed using the [ActiveSupport::Notifications](http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html) API. @@ -390,7 +392,7 @@ ## HTTPS/SSL Issues -By default excon will try to verify peer certificates when using SSL for HTTPS. Unfortunately on some operating systems the defaults will not work. This will likely manifest itself as something like `Excon::Errors::SocketError: SSL_connect returned=1 ...` +By default excon will try to verify peer certificates when using HTTPS. Unfortunately on some operating systems the defaults will not work. This will likely manifest itself as something like `Excon::Errors::CertificateError: SSL_connect returned=1 ...` If you have the misfortune of running into this problem you have a couple options. If you have certificates but they aren't being auto-discovered, you can specify the path to your certificates: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/changelog.txt new/changelog.txt --- old/changelog.txt 2016-03-07 22:19:26.000000000 +0100 +++ new/changelog.txt 2016-03-28 22:32:51.000000000 +0200 @@ -1,3 +1,13 @@ +0.49.0 03/28/2016 +================= + +fix nonblock ssl socket connect timeout handling +fix README debug example +make unique class for certificate errors +connection logic cleanup +change stubs back to global (with local option via defaults) +specific handling for set-cookie header exceptions + 0.48.0 03/07/2016 ================= Files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/excon.gemspec new/excon.gemspec --- old/excon.gemspec 2016-03-07 22:19:26.000000000 +0100 +++ new/excon.gemspec 2016-03-28 22:32:51.000000000 +0200 @@ -13,8 +13,8 @@ ## If your rubyforge_project name is different, then edit it and comment out ## the sub! line in the Rakefile s.name = 'excon' - s.version = '0.48.0' - s.date = '2016-03-07' + s.version = '0.49.0' + s.date = '2016-03-28' s.rubyforge_project = 'excon' ## Make sure your summary is short. The description may be as long diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/excon/connection.rb new/lib/excon/connection.rb --- old/lib/excon/connection.rb 2016-03-07 22:19:26.000000000 +0100 +++ new/lib/excon/connection.rb 2016-03-28 22:32:51.000000000 +0200 @@ -157,7 +157,7 @@ end elsif body.nil? socket.write(request) # write out request + headers - elsif !body.nil? # write out body + else # write out body if body.respond_to?(:binmode) body.binmode end @@ -189,7 +189,7 @@ when Excon::Errors::StubNotFound, Excon::Errors::Timeout raise(error) else - raise(Excon::Errors::SocketError.new(error)) + raise_socket_error(error) end end @@ -392,7 +392,7 @@ when Excon::Errors::HTTPStatusError, Excon::Errors::Timeout raise(error) else - raise(Excon::Errors::SocketError.new(error)) + raise_socket_error(error) end end @@ -415,6 +415,14 @@ end end + def raise_socket_error(error) + if error.message =~ /certificate verify failed/ + raise(Excon::Errors::CertificateError.new(error)) + else + raise(Excon::Errors::SocketError.new(error)) + end + end + def setup_proxy if @data[:disable_proxy] if @data[:proxy] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/excon/constants.rb new/lib/excon/constants.rb --- old/lib/excon/constants.rb 2016-03-07 22:19:26.000000000 +0100 +++ new/lib/excon/constants.rb 2016-03-28 22:32:51.000000000 +0200 @@ -1,6 +1,6 @@ module Excon - VERSION = '0.48.0' + VERSION = '0.49.0' CR_NL = "\r\n" @@ -133,6 +133,7 @@ :retry_limit => DEFAULT_RETRY_LIMIT, :ssl_verify_peer => true, :ssl_uri_schemes => [HTTPS], + :stubs => :global, :tcp_nodelay => false, :thread_safe_sockets => true, :uri_parser => URI, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/excon/errors.rb new/lib/excon/errors.rb --- old/lib/excon/errors.rb 2016-03-07 22:19:26.000000000 +0100 +++ new/lib/excon/errors.rb 2016-03-28 22:32:51.000000000 +0200 @@ -8,12 +8,29 @@ class SocketError < Error attr_reader :socket_error - def initialize(socket_error=Excon::Errors::Error.new) - if socket_error.message =~ /certificate verify failed/ - super("Unable to verify certificate, please set `Excon.defaults[:ssl_ca_path] = path_to_certs`, `ENV['SSL_CERT_DIR'] = path_to_certs`, `Excon.defaults[:ssl_ca_file] = path_to_file`, `ENV['SSL_CERT_FILE'] = path_to_file`, `Excon.defaults[:ssl_verify_callback] = callback` (see OpenSSL::SSL::SSLContext#verify_callback), or `Excon.defaults[:ssl_verify_peer] = false` (less secure).") + def initialize(socket_error = Excon::Errors::Error.new) + if is_a?(CertificateError) + super else super("#{socket_error.message} (#{socket_error.class})") + set_backtrace(socket_error.backtrace) + @socket_error = socket_error end + end + end + + class CertificateError < SocketError + def initialize(socket_error = Excon::Errors::Error.new) + msg = "Unable to verify certificate. This may be an issue with the remote host or with Excon." + + "Excon has certificates bundled, but these can be customized." + + "`Excon.defaults[:ssl_ca_path] = path_to_certs`, " + + "`ENV['SSL_CERT_DIR'] = path_to_certs`, " + + "`Excon.defaults[:ssl_ca_file] = path_to_file`, " + + "`ENV['SSL_CERT_FILE'] = path_to_file`, " + + "`Excon.defaults[:ssl_verify_callback] = callback` (see OpenSSL::SSL::SSLContext#verify_callback), or " + + "`Excon.defaults[:ssl_verify_peer] = false` (less secure)." + full_message = "#{socket_error.message} (#{socket_error.class})" + ' ' + msg + super(full_message) set_backtrace(socket_error.backtrace) @socket_error = socket_error end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/excon/response.rb new/lib/excon/response.rb --- old/lib/excon/response.rb 2016-03-07 22:19:26.000000000 +0100 +++ new/lib/excon/response.rb 2016-03-28 22:32:51.000000000 +0200 @@ -66,6 +66,7 @@ datum[:response] = { :body => '', + :cookies => [], :host => datum[:host], :headers => Excon::Headers.new, :path => datum[:path], @@ -184,6 +185,9 @@ raise Excon::Errors::ResponseParseError, 'malformed header' unless value # add key/value or append value to existing values datum[:response][:headers][key] = ([datum[:response][:headers][key]] << value.strip).compact.join(', ') + if key.casecmp('Set-Cookie') == 0 + datum[:response][:cookies] << value.strip + end last_key = key end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/excon/socket.rb new/lib/excon/socket.rb --- old/lib/excon/socket.rb 2016-03-07 22:19:26.000000000 +0100 +++ new/lib/excon/socket.rb 2016-03-28 22:32:51.000000000 +0200 @@ -44,19 +44,11 @@ begin buffer << @socket.read_nonblock(1) while buffer[-1] != "\n" buffer - rescue Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable - if timeout_reached('read') - raise_timeout_error('read') - else - retry - end + rescue Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable + select_with_timeout(@socket, :read) && retry rescue OpenSSL::SSL::SSLError => error if error.message == 'read would block' - if timeout_reached('read') - raise_timeout_error('read') - else - retry - end + select_with_timeout(@socket, :read) && retry else raise(error) end @@ -135,9 +127,7 @@ end @socket = socket rescue Errno::EINPROGRESS - unless IO.select(nil, [socket], nil, @data[:connect_timeout]) - raise(Excon::Errors::Timeout.new('connect timeout reached')) - end + select_with_timeout(socket, :connect_write) begin socket.connect_nonblock(sockaddr) @socket = socket @@ -174,22 +164,14 @@ end rescue OpenSSL::SSL::SSLError => error if error.message == 'read would block' - if timeout_reached('read') - raise_timeout_error('read') - else - retry - end + select_with_timeout(@socket, :read) && retry else raise(error) end rescue Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable if @read_buffer.empty? # if we didn't read anything, try again... - if timeout_reached('read') - raise_timeout_error('read') - else - retry - end + select_with_timeout(@socket, :read) && retry end rescue EOFError @eof = true @@ -211,21 +193,13 @@ @socket.read(max_length) rescue OpenSSL::SSL::SSLError => error if error.message == 'read would block' - if timeout_reached('read') - raise_timeout_error('read') - else - retry - end + select_with_timeout(@socket, :read) && retry else raise(error) end rescue Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable if @read_buffer.empty? - if timeout_reached('read') - raise_timeout_error('read') - else - retry - end + select_with_timeout(@socket, :read) && retry end rescue EOFError @eof = true @@ -253,11 +227,7 @@ if error.is_a?(OpenSSL::SSL::SSLError) && error.message != 'write would block' raise error else - if timeout_reached('write') - raise_timeout_error('write') - else - retry - end + select_with_timeout(@socket, :write) && retry end end @@ -278,25 +248,22 @@ if error.is_a?(OpenSSL::SSL::SSLError) && error.message != 'write would block' raise error else - if timeout_reached('write') - raise_timeout_error('write') - else - retry - end + select_with_timeout(@socket, :write) && retry end end - def timeout_reached(type) - if type == 'read' - args = [[@socket], nil, nil, @data[:read_timeout]] - else - args = [nil, [@socket], nil, @data[:write_timeout]] + def select_with_timeout(socket, type) + select = case type + when :connect_read + IO.select([socket], nil, nil, @data[:connect_timeout]) + when :connect_write + IO.select(nil, [socket], nil, @data[:connect_timeout]) + when :read + IO.select([socket], nil, nil, @data[:read_timeout]) + when :write + IO.select(nil, [socket], nil, @data[:write_timeout]) end - IO.select(*args) ? nil : true - end - - def raise_timeout_error(type) - fail Excon::Errors::Timeout.new("#{type} timeout reached") + select || raise(Excon::Errors::Timeout.new("#{type} timeout reached")) end def unpacked_sockaddr diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/excon/ssl_socket.rb new/lib/excon/ssl_socket.rb --- old/lib/excon/ssl_socket.rb 2016-03-07 22:19:26.000000000 +0100 +++ new/lib/excon/ssl_socket.rb 2016-03-28 22:32:51.000000000 +0200 @@ -119,11 +119,9 @@ begin @socket.connect_nonblock rescue Errno::EAGAIN, Errno::EWOULDBLOCK, IO::WaitReadable - IO.select([@socket]) - retry + select_with_timeout(@socket, :connect_read) && retry rescue IO::WaitWritable - IO.select(nil, [@socket]) - retry + select_with_timeout(@socket, :connect_write) && retry end else @socket.connect diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/excon.rb new/lib/excon.rb --- old/lib/excon.rb 2016-03-07 22:19:26.000000000 +0100 +++ new/lib/excon.rb 2016-03-28 22:32:51.000000000 +0200 @@ -210,9 +210,14 @@ nil end - # get a list of defined stubs for the current thread + # get a list of defined stubs def stubs - Thread.current[:_excon_stubs] ||= [] + case Excon.defaults[:stubs] + when :global + @stubs ||= [] + when :local + Thread.current[:_excon_stubs] ||= [] + end end # remove first/oldest stub matching request_params diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2016-03-07 22:19:26.000000000 +0100 +++ new/metadata 2016-03-28 22:32:51.000000000 +0200 @@ -1,7 +1,7 @@ --- !ruby/object:Gem::Specification name: excon version: !ruby/object:Gem::Version - version: 0.48.0 + version: 0.49.0 platform: ruby authors: - dpiddy (Dan Peterson) @@ -10,7 +10,7 @@ autorequire: bindir: bin cert_chain: [] -date: 2016-03-07 00:00:00.000000000 Z +date: 2016-03-28 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: activesupport diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tests/middlewares/mock_tests.rb new/tests/middlewares/mock_tests.rb --- old/tests/middlewares/mock_tests.rb 2016-03-07 22:19:26.000000000 +0100 +++ new/tests/middlewares/mock_tests.rb 2016-03-28 22:32:51.000000000 +0200 @@ -252,25 +252,41 @@ Excon.stubs.clear end - tests("thread-local stubs") do - q1, q2 = Queue.new, Queue.new + tests("global stubs") do connection = Excon.new('http://127.0.0.1:9292', :mock => true) Excon.stub({}, {:body => '1'}) t = Thread.new do Excon.stub({}, {:body => '2'}) - q1.push nil - q2.pop connection.request(:method => :get).body end - q1.pop - tests("get on a different thread").returns('1') do + tests("get on a different thread").returns('2') do + t.join.value + end + tests("get on main thread").returns('2') do + connection.request(:method => :get).body + end + Excon.stubs.clear + end + + tests("thread-local stubs") do + original_stubs_value = Excon.defaults[:stubs] + Excon.defaults[:stubs] = :local + + connection = Excon.new('http://127.0.0.1:9292', :mock => true) + Excon.stub({}, {:body => '1'}) + t = Thread.new do + Excon.stub({}, {:body => '2'}) connection.request(:method => :get).body end - q2.push nil tests("get on a different thread").returns('2') do t.join.value end + tests("get on main thread").returns('1') do + connection.request(:method => :get).body + end Excon.stubs.clear + + Excon.defaults[:stubs] = original_stubs_value end env_restore diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tests/response_tests.rb new/tests/response_tests.rb --- old/tests/response_tests.rb 2016-03-07 22:19:26.000000000 +0100 +++ new/tests/response_tests.rb 2016-03-28 22:32:51.000000000 +0200 @@ -151,6 +151,15 @@ end + tests('cookies') do + + tests('parses cookies into array').returns(['one, two', 'three, four']) do + resp = Excon.get('http://127.0.0.1:9292/unknown/cookies') + resp[:cookies] + end + + end + tests('header continuation') do tests('proper continuation').returns('one, two, three, four, five, six') do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/tests/servers/good.rb new/tests/servers/good.rb --- old/tests/servers/good.rb 2016-03-07 22:19:26.000000000 +0100 +++ new/tests/servers/good.rb 2016-03-28 22:32:51.000000000 +0200 @@ -139,6 +139,13 @@ when 'unknown' case path + when 'cookies' + start_response(:persistent => false) + send_data "Set-Cookie: one, two\r\n" + send_data "Set-Cookie: three, four\r\n" + send_data "\r\n" + send_data "hello world" + when 'simple' start_response(:persistent => false) send_data "\r\n"
