rest-client 1.8.0-x86-mingw32 → 2.0.0.rc1-x86-mingw32
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.
- checksums.yaml +4 -4
- data/.rspec +2 -1
- data/.rubocop-disables.yml +375 -0
- data/.rubocop.yml +3 -0
- data/.travis.yml +3 -4
- data/AUTHORS +11 -1
- data/README.rdoc +84 -16
- data/Rakefile +16 -0
- data/bin/restclient +3 -5
- data/history.md +61 -0
- data/lib/restclient.rb +19 -2
- data/lib/restclient/abstract_response.rb +107 -42
- data/lib/restclient/exceptions.rb +44 -44
- data/lib/restclient/payload.rb +2 -2
- data/lib/restclient/platform.rb +19 -0
- data/lib/restclient/raw_response.rb +4 -0
- data/lib/restclient/request.rb +141 -38
- data/lib/restclient/resource.rb +3 -3
- data/lib/restclient/response.rb +61 -5
- data/lib/restclient/utils.rb +93 -0
- data/lib/restclient/version.rb +2 -1
- data/rest-client.gemspec +6 -5
- data/spec/helpers.rb +14 -0
- data/spec/integration/_lib.rb +1 -0
- data/spec/integration/httpbin_spec.rb +72 -0
- data/spec/integration/integration_spec.rb +79 -1
- data/spec/integration/request_spec.rb +24 -1
- data/spec/spec_helper.rb +21 -1
- data/spec/unit/_lib.rb +1 -0
- data/spec/unit/abstract_response_spec.rb +22 -8
- data/spec/unit/exceptions_spec.rb +9 -17
- data/spec/unit/payload_spec.rb +10 -10
- data/spec/unit/raw_response_spec.rb +1 -1
- data/spec/unit/request2_spec.rb +6 -6
- data/spec/unit/request_spec.rb +234 -43
- data/spec/unit/resource_spec.rb +1 -1
- data/spec/unit/response_spec.rb +72 -28
- data/spec/unit/restclient_spec.rb +3 -3
- data/spec/unit/utils_spec.rb +71 -0
- data/spec/unit/windows/root_certs_spec.rb +1 -1
- metadata +41 -14
| @@ -26,7 +26,7 @@ module RestClient | |
| 26 26 | 
             
                          401 => 'Unauthorized',
         | 
| 27 27 | 
             
                          402 => 'Payment Required',
         | 
| 28 28 | 
             
                          403 => 'Forbidden',
         | 
| 29 | 
            -
                          404 => ' | 
| 29 | 
            +
                          404 => 'Not Found',
         | 
| 30 30 | 
             
                          405 => 'Method Not Allowed',
         | 
| 31 31 | 
             
                          406 => 'Not Acceptable',
         | 
| 32 32 | 
             
                          407 => 'Proxy Authentication Required',
         | 
| @@ -66,18 +66,6 @@ module RestClient | |
| 66 66 | 
             
                          511 => 'Network Authentication Required', # RFC6585
         | 
| 67 67 | 
             
              }
         | 
| 68 68 |  | 
| 69 | 
            -
              # Compatibility : make the Response act like a Net::HTTPResponse when needed
         | 
| 70 | 
            -
              module ResponseForException
         | 
| 71 | 
            -
                def method_missing symbol, *args
         | 
| 72 | 
            -
                  if net_http_res.respond_to? symbol
         | 
| 73 | 
            -
                    warn "[warning] The response contained in an RestClient::Exception is now a RestClient::Response instead of a Net::HTTPResponse, please update your code"
         | 
| 74 | 
            -
                    net_http_res.send symbol, *args
         | 
| 75 | 
            -
                  else
         | 
| 76 | 
            -
                    super
         | 
| 77 | 
            -
                  end
         | 
| 78 | 
            -
                end
         | 
| 79 | 
            -
              end
         | 
| 80 | 
            -
             | 
| 81 69 | 
             
              # This is the base RestClient exception class. Rescue it if you want to
         | 
| 82 70 | 
             
              # catch any exception that your request might raise
         | 
| 83 71 | 
             
              # You can get the status code by e.http_code, or see anything about the
         | 
| @@ -86,15 +74,13 @@ module RestClient | |
| 86 74 | 
             
              # probably an HTML error page) is e.response.
         | 
| 87 75 | 
             
              class Exception < RuntimeError
         | 
| 88 76 | 
             
                attr_accessor :response
         | 
| 77 | 
            +
                attr_accessor :original_exception
         | 
| 89 78 | 
             
                attr_writer :message
         | 
| 90 79 |  | 
| 91 80 | 
             
                def initialize response = nil, initial_response_code = nil
         | 
| 92 81 | 
             
                  @response = response
         | 
| 93 82 | 
             
                  @message = nil
         | 
| 94 83 | 
             
                  @initial_response_code = initial_response_code
         | 
| 95 | 
            -
             | 
| 96 | 
            -
                  # compatibility: this make the exception behave like a Net::HTTPResponse
         | 
| 97 | 
            -
                  response.extend ResponseForException if response
         | 
| 98 84 | 
             
                end
         | 
| 99 85 |  | 
| 100 86 | 
             
                def http_code
         | 
| @@ -106,6 +92,10 @@ module RestClient | |
| 106 92 | 
             
                  end
         | 
| 107 93 | 
             
                end
         | 
| 108 94 |  | 
| 95 | 
            +
                def http_headers
         | 
| 96 | 
            +
                  @response.headers if @response
         | 
| 97 | 
            +
                end
         | 
| 98 | 
            +
             | 
| 109 99 | 
             
                def http_body
         | 
| 110 100 | 
             
                  @response.body if @response
         | 
| 111 101 | 
             
                end
         | 
| @@ -119,9 +109,12 @@ module RestClient | |
| 119 109 | 
             
                end
         | 
| 120 110 |  | 
| 121 111 | 
             
                def message
         | 
| 122 | 
            -
                  @message || self.class. | 
| 112 | 
            +
                  @message || self.class.default_message
         | 
| 123 113 | 
             
                end
         | 
| 124 114 |  | 
| 115 | 
            +
                def self.default_message
         | 
| 116 | 
            +
                  self.name
         | 
| 117 | 
            +
                end
         | 
| 125 118 | 
             
              end
         | 
| 126 119 |  | 
| 127 120 | 
             
              # Compatibility
         | 
| @@ -140,10 +133,41 @@ module RestClient | |
| 140 133 | 
             
                end
         | 
| 141 134 | 
             
              end
         | 
| 142 135 |  | 
| 143 | 
            -
              #  | 
| 136 | 
            +
              # RestClient exception classes. TODO: move all exceptions into this module.
         | 
| 137 | 
            +
              #
         | 
| 138 | 
            +
              # We will a create an exception for each status code, see
         | 
| 139 | 
            +
              # http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
         | 
| 140 | 
            +
              #
         | 
| 144 141 | 
             
              module Exceptions
         | 
| 145 142 | 
             
                # Map http status codes to the corresponding exception class
         | 
| 146 143 | 
             
                EXCEPTIONS_MAP = {}
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                # Base class for request timeouts.
         | 
| 146 | 
            +
                # NB: Previous releases of rest-client would raise RequestTimeout both for
         | 
| 147 | 
            +
                # HTTP 408 responses and for actual connection timeouts.
         | 
| 148 | 
            +
                class Timeout < RestClient::Exception
         | 
| 149 | 
            +
                  def initialize(message=nil, original_exception=nil)
         | 
| 150 | 
            +
                    super(nil, nil)
         | 
| 151 | 
            +
                    self.message = message if message
         | 
| 152 | 
            +
                    self.original_exception = original_exception if original_exception
         | 
| 153 | 
            +
                  end
         | 
| 154 | 
            +
                end
         | 
| 155 | 
            +
             | 
| 156 | 
            +
                # Timeout when connecting to a server. Typically wraps Net::OpenTimeout (in
         | 
| 157 | 
            +
                # ruby 2.0 or greater).
         | 
| 158 | 
            +
                class OpenTimeout < Timeout
         | 
| 159 | 
            +
                  def self.default_message
         | 
| 160 | 
            +
                    'Timed out connecting to server'
         | 
| 161 | 
            +
                  end
         | 
| 162 | 
            +
                end
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                # Timeout when reading from a server. Typically wraps Net::ReadTimeout (in
         | 
| 165 | 
            +
                # ruby 2.0 or greater).
         | 
| 166 | 
            +
                class ReadTimeout < Timeout
         | 
| 167 | 
            +
                  def self.default_message
         | 
| 168 | 
            +
                    'Timed out reading data from server'
         | 
| 169 | 
            +
                  end
         | 
| 170 | 
            +
                end
         | 
| 147 171 | 
             
              end
         | 
| 148 172 |  | 
| 149 173 | 
             
              STATUSES.each_pair do |code, message|
         | 
| @@ -157,25 +181,8 @@ module RestClient | |
| 157 181 | 
             
                Exceptions::EXCEPTIONS_MAP[code] = klass_constant
         | 
| 158 182 | 
             
              end
         | 
| 159 183 |  | 
| 160 | 
            -
              #  | 
| 161 | 
            -
               | 
| 162 | 
            -
             | 
| 163 | 
            -
                def message
         | 
| 164 | 
            -
                  'Redirect'
         | 
| 165 | 
            -
                end
         | 
| 166 | 
            -
             | 
| 167 | 
            -
                attr_accessor :url
         | 
| 168 | 
            -
             | 
| 169 | 
            -
                def initialize(url)
         | 
| 170 | 
            -
                  @url = url
         | 
| 171 | 
            -
                end
         | 
| 172 | 
            -
              end
         | 
| 173 | 
            -
             | 
| 174 | 
            -
              class MaxRedirectsReached < Exception
         | 
| 175 | 
            -
                def message
         | 
| 176 | 
            -
                  'Maximum number of redirect reached'
         | 
| 177 | 
            -
                end
         | 
| 178 | 
            -
              end
         | 
| 184 | 
            +
              # Backwards compatibility. "Not Found" is the actual text in the RFCs.
         | 
| 185 | 
            +
              ResourceNotFound = NotFound
         | 
| 179 186 |  | 
| 180 187 | 
             
              # The server broke the connection prior to the request completing.  Usually
         | 
| 181 188 | 
             
              # this means it crashed, or sometimes that your network connection was
         | 
| @@ -194,10 +201,3 @@ module RestClient | |
| 194 201 | 
             
                end
         | 
| 195 202 | 
             
              end
         | 
| 196 203 | 
             
            end
         | 
| 197 | 
            -
             | 
| 198 | 
            -
            class RestClient::Request
         | 
| 199 | 
            -
              # backwards compatibility
         | 
| 200 | 
            -
              Redirect = RestClient::Redirect
         | 
| 201 | 
            -
              Unauthorized = RestClient::Unauthorized
         | 
| 202 | 
            -
              RequestFailed = RestClient::RequestFailed
         | 
| 203 | 
            -
            end
         | 
    
        data/lib/restclient/payload.rb
    CHANGED
    
    
    
        data/lib/restclient/platform.rb
    CHANGED
    
    | @@ -1,3 +1,5 @@ | |
| 1 | 
            +
            require 'rbconfig'
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module RestClient
         | 
| 2 4 | 
             
              module Platform
         | 
| 3 5 | 
             
                # Return true if we are running on a darwin-based Ruby platform. This will
         | 
| @@ -26,5 +28,22 @@ module RestClient | |
| 26 28 | 
             
                  # defined on mri >= 1.9
         | 
| 27 29 | 
             
                  RUBY_ENGINE == 'jruby'
         | 
| 28 30 | 
             
                end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                def self.architecture
         | 
| 33 | 
            +
                  "#{RbConfig::CONFIG['host_os']} #{RbConfig::CONFIG['host_cpu']}"
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                def self.ruby_agent_version
         | 
| 37 | 
            +
                  case RUBY_ENGINE
         | 
| 38 | 
            +
                  when 'jruby'
         | 
| 39 | 
            +
                    "jruby/#{JRUBY_VERSION} (#{RUBY_VERSION}p#{RUBY_PATCHLEVEL})"
         | 
| 40 | 
            +
                  else
         | 
| 41 | 
            +
                    "#{RUBY_ENGINE}/#{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
         | 
| 42 | 
            +
                  end
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                def self.default_user_agent
         | 
| 46 | 
            +
                  "rest-client/#{VERSION} (#{architecture}) #{ruby_agent_version}"
         | 
| 47 | 
            +
                end
         | 
| 29 48 | 
             
              end
         | 
| 30 49 | 
             
            end
         | 
| @@ -15,6 +15,10 @@ module RestClient | |
| 15 15 |  | 
| 16 16 | 
             
                attr_reader :file, :request
         | 
| 17 17 |  | 
| 18 | 
            +
                def inspect
         | 
| 19 | 
            +
                  "<RestClient::RawResponse @code=#{code.inspect}, @file=#{file.inspect}, @request=#{request.inspect}>"
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
             | 
| 18 22 | 
             
                def initialize(tempfile, net_http_res, args, request)
         | 
| 19 23 | 
             
                  @net_http_res = net_http_res
         | 
| 20 24 | 
             
                  @args = args
         | 
    
        data/lib/restclient/request.rb
    CHANGED
    
    | @@ -21,29 +21,40 @@ module RestClient | |
| 21 21 | 
             
              # * :block_response call the provided block with the HTTPResponse as parameter
         | 
| 22 22 | 
             
              # * :raw_response return a low-level RawResponse instead of a Response
         | 
| 23 23 | 
             
              # * :max_redirects maximum number of redirections (default to 10)
         | 
| 24 | 
            +
              # * :proxy An HTTP proxy URI to use for this request. Any value here
         | 
| 25 | 
            +
              #   (including nil) will override RestClient.proxy.
         | 
| 24 26 | 
             
              # * :verify_ssl enable ssl verification, possible values are constants from
         | 
| 25 27 | 
             
              #     OpenSSL::SSL::VERIFY_*, defaults to OpenSSL::SSL::VERIFY_PEER
         | 
| 26 | 
            -
              # * : | 
| 27 | 
            -
              #     open a connection, in seconds. Pass nil to disable the timeout.
         | 
| 28 | 
            +
              # * :read_timeout and :open_timeout are how long to wait for a response and
         | 
| 29 | 
            +
              #     to open a connection, in seconds. Pass nil to disable the timeout.
         | 
| 30 | 
            +
              # * :timeout can be used to set both timeouts
         | 
| 28 31 | 
             
              # * :ssl_client_cert, :ssl_client_key, :ssl_ca_file, :ssl_ca_path,
         | 
| 29 32 | 
             
              #     :ssl_cert_store, :ssl_verify_callback, :ssl_verify_callback_warnings
         | 
| 30 33 | 
             
              # * :ssl_version specifies the SSL version for the underlying Net::HTTP connection
         | 
| 31 34 | 
             
              # * :ssl_ciphers sets SSL ciphers for the connection. See
         | 
| 32 35 | 
             
              #     OpenSSL::SSL::SSLContext#ciphers=
         | 
| 36 | 
            +
              # * :before_execution_proc a Proc to call before executing the request. This
         | 
| 37 | 
            +
              #      proc, like procs from RestClient.before_execution_procs, will be
         | 
| 38 | 
            +
              #      called with the HTTP request and request params.
         | 
| 33 39 | 
             
              class Request
         | 
| 34 40 |  | 
| 35 | 
            -
                 | 
| 36 | 
            -
             | 
| 41 | 
            +
                # TODO: rename timeout to read_timeout
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                attr_reader :method, :url, :headers, :cookies, :payload, :proxy,
         | 
| 44 | 
            +
                            :user, :password, :read_timeout, :max_redirects,
         | 
| 37 45 | 
             
                            :open_timeout, :raw_response, :processed_headers, :args,
         | 
| 38 46 | 
             
                            :ssl_opts
         | 
| 39 47 |  | 
| 48 | 
            +
                # An array of previous redirection responses
         | 
| 49 | 
            +
                attr_accessor :redirection_history
         | 
| 50 | 
            +
             | 
| 40 51 | 
             
                def self.execute(args, & block)
         | 
| 41 52 | 
             
                  new(args).execute(& block)
         | 
| 42 53 | 
             
                end
         | 
| 43 54 |  | 
| 44 | 
            -
                # This is similar to the list now in ruby core, but adds HIGH  | 
| 45 | 
            -
                #  | 
| 46 | 
            -
                #  | 
| 55 | 
            +
                # This is similar to the list now in ruby core, but adds HIGH for better
         | 
| 56 | 
            +
                # compatibility (similar to Firefox) and moves AES-GCM cipher suites above
         | 
| 57 | 
            +
                # DHE/ECDHE CBC suites (similar to Chromium).
         | 
| 47 58 | 
             
                # https://github.com/ruby/ruby/commit/699b209cf8cf11809620e12985ad33ae33b119ee
         | 
| 48 59 | 
             
                #
         | 
| 49 60 | 
             
                # This list will be used by default if the Ruby global OpenSSL default
         | 
| @@ -91,7 +102,6 @@ module RestClient | |
| 91 102 |  | 
| 92 103 | 
             
                  HIGH
         | 
| 93 104 | 
             
                  +RC4
         | 
| 94 | 
            -
                  RC4-MD5
         | 
| 95 105 | 
             
                }.join(":")
         | 
| 96 106 |  | 
| 97 107 | 
             
                # A set of weak default ciphers that we will override by default.
         | 
| @@ -102,9 +112,13 @@ module RestClient | |
| 102 112 | 
             
                SSLOptionList = %w{client_cert client_key ca_file ca_path cert_store
         | 
| 103 113 | 
             
                                   version ciphers verify_callback verify_callback_warnings}
         | 
| 104 114 |  | 
| 115 | 
            +
                def inspect
         | 
| 116 | 
            +
                  "<RestClient::Request @method=#{@method.inspect}, @url=#{@url.inspect}>"
         | 
| 117 | 
            +
                end
         | 
| 118 | 
            +
             | 
| 105 119 | 
             
                def initialize args
         | 
| 106 120 | 
             
                  @method = args[:method] or raise ArgumentError, "must pass :method"
         | 
| 107 | 
            -
                  @headers = args[:headers] || {}
         | 
| 121 | 
            +
                  @headers = (args[:headers] || {}).dup
         | 
| 108 122 | 
             
                  if args[:url]
         | 
| 109 123 | 
             
                    @url = process_url_params(args[:url], headers)
         | 
| 110 124 | 
             
                  else
         | 
| @@ -115,7 +129,11 @@ module RestClient | |
| 115 129 | 
             
                  @user = args[:user]
         | 
| 116 130 | 
             
                  @password = args[:password]
         | 
| 117 131 | 
             
                  if args.include?(:timeout)
         | 
| 118 | 
            -
                    @ | 
| 132 | 
            +
                    @read_timeout = args[:timeout]
         | 
| 133 | 
            +
                    @open_timeout = args[:timeout]
         | 
| 134 | 
            +
                  end
         | 
| 135 | 
            +
                  if args.include?(:read_timeout)
         | 
| 136 | 
            +
                    @read_timeout = args[:read_timeout]
         | 
| 119 137 | 
             
                  end
         | 
| 120 138 | 
             
                  if args.include?(:open_timeout)
         | 
| 121 139 | 
             
                    @open_timeout = args[:open_timeout]
         | 
| @@ -123,6 +141,8 @@ module RestClient | |
| 123 141 | 
             
                  @block_response = args[:block_response]
         | 
| 124 142 | 
             
                  @raw_response = args[:raw_response] || false
         | 
| 125 143 |  | 
| 144 | 
            +
                  @proxy = args.fetch(:proxy) if args.include?(:proxy)
         | 
| 145 | 
            +
             | 
| 126 146 | 
             
                  @ssl_opts = {}
         | 
| 127 147 |  | 
| 128 148 | 
             
                  if args.include?(:verify_ssl)
         | 
| @@ -169,11 +189,17 @@ module RestClient | |
| 169 189 | 
             
                  @max_redirects = args[:max_redirects] || 10
         | 
| 170 190 | 
             
                  @processed_headers = make_headers headers
         | 
| 171 191 | 
             
                  @args = args
         | 
| 192 | 
            +
             | 
| 193 | 
            +
                  @before_execution_proc = args[:before_execution_proc]
         | 
| 172 194 | 
             
                end
         | 
| 173 195 |  | 
| 174 196 | 
             
                def execute & block
         | 
| 175 197 | 
             
                  uri = parse_url_with_auth(url)
         | 
| 176 | 
            -
             | 
| 198 | 
            +
             | 
| 199 | 
            +
                  # With 2.0.0+, net/http accepts URI objects in requests and handles wrapping
         | 
| 200 | 
            +
                  # IPv6 addresses in [] for use in the Host request header.
         | 
| 201 | 
            +
                  request_uri = RUBY_VERSION >= "2.0.0" ? uri : uri.request_uri
         | 
| 202 | 
            +
                  transmit uri, net_http_request_class(method).new(request_uri, processed_headers), payload, & block
         | 
| 177 203 | 
             
                ensure
         | 
| 178 204 | 
             
                  payload.close if payload
         | 
| 179 205 | 
             
                end
         | 
| @@ -249,12 +275,44 @@ module RestClient | |
| 249 275 | 
             
                  ! Regexp.new('[\x0-\x1f\x7f,;]').match(value)
         | 
| 250 276 | 
             
                end
         | 
| 251 277 |  | 
| 252 | 
            -
                 | 
| 253 | 
            -
             | 
| 254 | 
            -
             | 
| 255 | 
            -
             | 
| 278 | 
            +
                # The proxy URI for this request. If `:proxy` was provided on this request,
         | 
| 279 | 
            +
                # use it over `RestClient.proxy`.
         | 
| 280 | 
            +
                #
         | 
| 281 | 
            +
                # Return false if a proxy was explicitly set and is falsy.
         | 
| 282 | 
            +
                #
         | 
| 283 | 
            +
                # @return [URI, false, nil]
         | 
| 284 | 
            +
                #
         | 
| 285 | 
            +
                def proxy_uri
         | 
| 286 | 
            +
                  if defined?(@proxy)
         | 
| 287 | 
            +
                    if @proxy
         | 
| 288 | 
            +
                      URI.parse(@proxy)
         | 
| 289 | 
            +
                    else
         | 
| 290 | 
            +
                      false
         | 
| 291 | 
            +
                    end
         | 
| 292 | 
            +
                  elsif RestClient.proxy_set?
         | 
| 293 | 
            +
                    if RestClient.proxy
         | 
| 294 | 
            +
                      URI.parse(RestClient.proxy)
         | 
| 295 | 
            +
                    else
         | 
| 296 | 
            +
                      false
         | 
| 297 | 
            +
                    end
         | 
| 256 298 | 
             
                  else
         | 
| 257 | 
            -
                     | 
| 299 | 
            +
                    nil
         | 
| 300 | 
            +
                  end
         | 
| 301 | 
            +
                end
         | 
| 302 | 
            +
             | 
| 303 | 
            +
                def net_http_object(hostname, port)
         | 
| 304 | 
            +
                  p_uri = proxy_uri
         | 
| 305 | 
            +
             | 
| 306 | 
            +
                  if p_uri.nil?
         | 
| 307 | 
            +
                    # no proxy set
         | 
| 308 | 
            +
                    Net::HTTP.new(hostname, port)
         | 
| 309 | 
            +
                  elsif !p_uri
         | 
| 310 | 
            +
                    # proxy explicitly set to none
         | 
| 311 | 
            +
                    Net::HTTP.new(hostname, port, nil, nil, nil, nil)
         | 
| 312 | 
            +
                  else
         | 
| 313 | 
            +
                    Net::HTTP.new(hostname, port,
         | 
| 314 | 
            +
                                  p_uri.hostname, p_uri.port, p_uri.user, p_uri.password)
         | 
| 315 | 
            +
             | 
| 258 316 | 
             
                  end
         | 
| 259 317 | 
             
                end
         | 
| 260 318 |  | 
| @@ -263,7 +321,7 @@ module RestClient | |
| 263 321 | 
             
                end
         | 
| 264 322 |  | 
| 265 323 | 
             
                def net_http_do_request(http, req, body=nil, &block)
         | 
| 266 | 
            -
                  if body  | 
| 324 | 
            +
                  if body && body.respond_to?(:read)
         | 
| 267 325 | 
             
                    req.body_stream = body
         | 
| 268 326 | 
             
                    return http.request(req, nil, &block)
         | 
| 269 327 | 
             
                  else
         | 
| @@ -271,8 +329,22 @@ module RestClient | |
| 271 329 | 
             
                  end
         | 
| 272 330 | 
             
                end
         | 
| 273 331 |  | 
| 332 | 
            +
                # Parse a string into a URI object. If the string has no HTTP-like scheme
         | 
| 333 | 
            +
                # (i.e. scheme followed by '//'), a scheme of 'http' will be added. This
         | 
| 334 | 
            +
                # mimics the behavior of browsers and user agents like cURL.
         | 
| 335 | 
            +
                #
         | 
| 336 | 
            +
                # @param url [String] A URL string.
         | 
| 337 | 
            +
                #
         | 
| 338 | 
            +
                # @return [URI]
         | 
| 339 | 
            +
                #
         | 
| 340 | 
            +
                # @raise URI::InvalidURIError on invalid URIs
         | 
| 341 | 
            +
                #
         | 
| 274 342 | 
             
                def parse_url(url)
         | 
| 275 | 
            -
                   | 
| 343 | 
            +
                  # Prepend http:// unless the string already contains an RFC 3986 scheme
         | 
| 344 | 
            +
                  # followed by two forward slashes. (The slashes are not part of the URI
         | 
| 345 | 
            +
                  # RFC, but specified by the URL RFC 1738.)
         | 
| 346 | 
            +
                  # https://tools.ietf.org/html/rfc3986#section-3.1
         | 
| 347 | 
            +
                  url = 'http://' + url unless url.match(%r{\A[a-z][a-z0-9+.-]*://}i)
         | 
| 276 348 | 
             
                  URI.parse(url)
         | 
| 277 349 | 
             
                end
         | 
| 278 350 |  | 
| @@ -281,7 +353,7 @@ module RestClient | |
| 281 353 | 
             
                  @user = CGI.unescape(uri.user) if uri.user
         | 
| 282 354 | 
             
                  @password = CGI.unescape(uri.password) if uri.password
         | 
| 283 355 | 
             
                  if !@user && !@password
         | 
| 284 | 
            -
                    @user, @password = Netrc.read[uri. | 
| 356 | 
            +
                    @user, @password = Netrc.read[uri.hostname]
         | 
| 285 357 | 
             
                  end
         | 
| 286 358 | 
             
                  uri
         | 
| 287 359 | 
             
                end
         | 
| @@ -347,9 +419,14 @@ module RestClient | |
| 347 419 | 
             
                end
         | 
| 348 420 |  | 
| 349 421 | 
             
                def transmit uri, req, payload, & block
         | 
| 422 | 
            +
             | 
| 423 | 
            +
                  # We set this to true in the net/http block so that we can distinguish
         | 
| 424 | 
            +
                  # read_timeout from open_timeout. This isn't needed in Ruby >= 2.0.
         | 
| 425 | 
            +
                  established_connection = false
         | 
| 426 | 
            +
             | 
| 350 427 | 
             
                  setup_credentials req
         | 
| 351 428 |  | 
| 352 | 
            -
                  net =  | 
| 429 | 
            +
                  net = net_http_object(uri.hostname, uri.port)
         | 
| 353 430 | 
             
                  net.use_ssl = uri.is_a?(URI::HTTPS)
         | 
| 354 431 | 
             
                  net.ssl_version = ssl_version if ssl_version
         | 
| 355 432 | 
             
                  net.ciphers = ssl_ciphers if ssl_ciphers
         | 
| @@ -388,16 +465,16 @@ module RestClient | |
| 388 465 | 
             
                    warn('Try passing :verify_ssl => false instead.')
         | 
| 389 466 | 
             
                  end
         | 
| 390 467 |  | 
| 391 | 
            -
                  if defined? @ | 
| 392 | 
            -
                    if @ | 
| 393 | 
            -
                      warn ' | 
| 394 | 
            -
                      @ | 
| 468 | 
            +
                  if defined? @read_timeout
         | 
| 469 | 
            +
                    if @read_timeout == -1
         | 
| 470 | 
            +
                      warn 'Deprecated: to disable timeouts, please use nil instead of -1'
         | 
| 471 | 
            +
                      @read_timeout = nil
         | 
| 395 472 | 
             
                    end
         | 
| 396 | 
            -
                    net.read_timeout = @ | 
| 473 | 
            +
                    net.read_timeout = @read_timeout
         | 
| 397 474 | 
             
                  end
         | 
| 398 475 | 
             
                  if defined? @open_timeout
         | 
| 399 476 | 
             
                    if @open_timeout == -1
         | 
| 400 | 
            -
                      warn ' | 
| 477 | 
            +
                      warn 'Deprecated: to disable timeouts, please use nil instead of -1'
         | 
| 401 478 | 
             
                      @open_timeout = nil
         | 
| 402 479 | 
             
                    end
         | 
| 403 480 | 
             
                    net.open_timeout = @open_timeout
         | 
| @@ -407,24 +484,45 @@ module RestClient | |
| 407 484 | 
             
                    before_proc.call(req, args)
         | 
| 408 485 | 
             
                  end
         | 
| 409 486 |  | 
| 487 | 
            +
                  if @before_execution_proc
         | 
| 488 | 
            +
                    @before_execution_proc.call(req, args)
         | 
| 489 | 
            +
                  end
         | 
| 490 | 
            +
             | 
| 410 491 | 
             
                  log_request
         | 
| 411 492 |  | 
| 412 493 |  | 
| 413 494 | 
             
                  net.start do |http|
         | 
| 495 | 
            +
                    established_connection = true
         | 
| 496 | 
            +
             | 
| 414 497 | 
             
                    if @block_response
         | 
| 415 | 
            -
                      net_http_do_request(http, req, payload  | 
| 416 | 
            -
                                          &@block_response)
         | 
| 498 | 
            +
                      net_http_do_request(http, req, payload, &@block_response)
         | 
| 417 499 | 
             
                    else
         | 
| 418 | 
            -
                      res = net_http_do_request(http, req, payload  | 
| 419 | 
            -
                         | 
| 500 | 
            +
                      res = net_http_do_request(http, req, payload) { |http_response|
         | 
| 501 | 
            +
                        fetch_body(http_response)
         | 
| 502 | 
            +
                      }
         | 
| 420 503 | 
             
                      log_response res
         | 
| 421 504 | 
             
                      process_result res, & block
         | 
| 422 505 | 
             
                    end
         | 
| 423 506 | 
             
                  end
         | 
| 424 507 | 
             
                rescue EOFError
         | 
| 425 508 | 
             
                  raise RestClient::ServerBrokeConnection
         | 
| 426 | 
            -
                rescue Timeout::Error, Errno::ETIMEDOUT
         | 
| 427 | 
            -
                   | 
| 509 | 
            +
                rescue Timeout::Error, Errno::ETIMEDOUT => err
         | 
| 510 | 
            +
                  # Net::HTTP has OpenTimeout, ReadTimeout in Ruby >= 2.0
         | 
| 511 | 
            +
                  if defined?(Net::OpenTimeout)
         | 
| 512 | 
            +
                    case err
         | 
| 513 | 
            +
                    when Net::OpenTimeout
         | 
| 514 | 
            +
                      raise RestClient::Exceptions::OpenTimeout.new(nil, err)
         | 
| 515 | 
            +
                    when Net::ReadTimeout
         | 
| 516 | 
            +
                      raise RestClient::Exceptions::ReadTimeout.new(nil, err)
         | 
| 517 | 
            +
                    end
         | 
| 518 | 
            +
                  end
         | 
| 519 | 
            +
             | 
| 520 | 
            +
                  # compatibility for Ruby 1.9.3, handling for non-Net::HTTP timeouts
         | 
| 521 | 
            +
                  if established_connection
         | 
| 522 | 
            +
                    raise RestClient::Exceptions::ReadTimeout.new(nil, err)
         | 
| 523 | 
            +
                  else
         | 
| 524 | 
            +
                    raise RestClient::Exceptions::OpenTimeout.new(nil, err)
         | 
| 525 | 
            +
                  end
         | 
| 428 526 |  | 
| 429 527 | 
             
                rescue OpenSSL::SSL::SSLError => error
         | 
| 430 528 | 
             
                  # TODO: deprecate and remove RestClient::SSLCertificateNotVerified and just
         | 
| @@ -449,7 +547,7 @@ module RestClient | |
| 449 547 | 
             
                end
         | 
| 450 548 |  | 
| 451 549 | 
             
                def setup_credentials(req)
         | 
| 452 | 
            -
                  req.basic_auth(user, password) if user
         | 
| 550 | 
            +
                  req.basic_auth(user, password) if user && !headers.has_key?("Authorization")
         | 
| 453 551 | 
             
                end
         | 
| 454 552 |  | 
| 455 553 | 
             
                def fetch_body(http_response)
         | 
| @@ -457,7 +555,7 @@ module RestClient | |
| 457 555 | 
             
                    # Taken from Chef, which as in turn...
         | 
| 458 556 | 
             
                    # Stolen from http://www.ruby-forum.com/topic/166423
         | 
| 459 557 | 
             
                    # Kudos to _why!
         | 
| 460 | 
            -
                    @tf = Tempfile.new( | 
| 558 | 
            +
                    @tf = Tempfile.new('rest-client.')
         | 
| 461 559 | 
             
                    @tf.binmode
         | 
| 462 560 | 
             
                    size, total = 0, http_response.header['Content-Length'].to_i
         | 
| 463 561 | 
             
                    http_response.read_body do |chunk|
         | 
| @@ -486,13 +584,14 @@ module RestClient | |
| 486 584 | 
             
                    # We don't decode raw requests
         | 
| 487 585 | 
             
                    response = RawResponse.new(@tf, res, args, self)
         | 
| 488 586 | 
             
                  else
         | 
| 489 | 
            -
                     | 
| 587 | 
            +
                    decoded = Request.decode(res['content-encoding'], res.body)
         | 
| 588 | 
            +
                    response = Response.create(decoded, res, args, self)
         | 
| 490 589 | 
             
                  end
         | 
| 491 590 |  | 
| 492 591 | 
             
                  if block_given?
         | 
| 493 592 | 
             
                    block.call(response, self, res, & block)
         | 
| 494 593 | 
             
                  else
         | 
| 495 | 
            -
                    response.return!( | 
| 594 | 
            +
                    response.return!(&block)
         | 
| 496 595 | 
             
                  end
         | 
| 497 596 |  | 
| 498 597 | 
             
                end
         | 
| @@ -552,7 +651,7 @@ module RestClient | |
| 552 651 | 
             
                def stringify_headers headers
         | 
| 553 652 | 
             
                  headers.inject({}) do |result, (key, value)|
         | 
| 554 653 | 
             
                    if key.is_a? Symbol
         | 
| 555 | 
            -
                      key = key.to_s.split(/_/).map | 
| 654 | 
            +
                      key = key.to_s.split(/_/).map(&:capitalize).join('-')
         | 
| 556 655 | 
             
                    end
         | 
| 557 656 | 
             
                    if 'CONTENT-TYPE' == key.upcase
         | 
| 558 657 | 
             
                      result[key] = maybe_convert_extension(value.to_s)
         | 
| @@ -574,7 +673,11 @@ module RestClient | |
| 574 673 | 
             
                end
         | 
| 575 674 |  | 
| 576 675 | 
             
                def default_headers
         | 
| 577 | 
            -
                  { | 
| 676 | 
            +
                  {
         | 
| 677 | 
            +
                    :accept => '*/*',
         | 
| 678 | 
            +
                    :accept_encoding => 'gzip, deflate',
         | 
| 679 | 
            +
                    :user_agent => RestClient::Platform.default_user_agent,
         | 
| 680 | 
            +
                  }
         | 
| 578 681 | 
             
                end
         | 
| 579 682 |  | 
| 580 683 | 
             
                private
         |