class Excon::Connection

def request_call(datum)

def request_call(datum)
  begin
    if datum.has_key?(:response)
      # we already have data from a middleware, so bail
      return datum
    else
      socket.data = datum
      # start with "METHOD /path"
      request = datum[:method].to_s.upcase << ' '
      if datum[:proxy] && datum[:scheme] != HTTPS
        request << datum[:scheme] << '://' << datum[:host] << port_string(datum)
      end
      request << datum[:path]
      # add query to path, if there is one
      request << query_string(datum)
      # finish first line with "HTTP/1.1\r\n"
      request << HTTP_1_1
      if datum.has_key?(:request_block)
        datum[:headers]['Transfer-Encoding'] = 'chunked'
      else
        body = datum[:body].is_a?(String) ? StringIO.new(datum[:body]) : datum[:body]
        # The HTTP spec isn't clear on it, but specifically, GET requests don't usually send bodies;
        # if they don't, sending Content-Length:0 can cause issues.
        unless datum[:method].to_s.casecmp('GET') == 0 && body.nil?
          unless datum[:headers].has_key?('Content-Length')
            datum[:headers]['Content-Length'] = detect_content_length(body)
          end
        end
      end
      if datum[:response_block]
        datum[:headers]['TE'] = 'trailers'
      else
        datum[:headers]['TE'] = 'trailers, deflate, gzip'
      end
      datum[:headers]['Connection'] = datum[:persistent] ? 'TE' : 'TE, close'
      # add headers to request
      datum[:headers].each do |key, values|
        [values].flatten.each do |value|
          request << key.to_s << ': ' << value.to_s << CR_NL
        end
      end
      # add additional "\r\n" to indicate end of headers
      request << CR_NL
      socket.write(request) # write out request + headers
      if datum.has_key?(:request_block)
        while true # write out body with chunked encoding
          chunk = datum[:request_block].call
          if FORCE_ENC
            chunk.force_encoding('BINARY')
          end
          if chunk.length > 0
            socket.write(chunk.length.to_s(16) << CR_NL << chunk << CR_NL)
          else
            socket.write('0' << CR_NL << CR_NL)
            break
          end
        end
      elsif !body.nil? # write out body
        if body.respond_to?(:binmode)
          body.binmode
        end
        if body.respond_to?(:pos=)
          body.pos = 0
        end
        while chunk = body.read(datum[:chunk_size])
          socket.write(chunk)
        end
      end
    end
  rescue => error
    case error
    when Excon::Errors::StubNotFound, Excon::Errors::Timeout
      raise(error)
    else
      raise(Excon::Errors::SocketError.new(error))
    end
  end
  datum
end