class Excon::Connection
def request_kernel(params, &block)
def request_kernel(params, &block) begin response = if params[:mock] invoke_stub(params, &block) else socket.params = params # start with "METHOD /path" request = params[:method].to_s.upcase << ' ' if @proxy request << params[:scheme] << '://' << params[:host] << ':' << params[:port] end request << params[:path] # add query to path, if there is one case params[:query] when String request << '?' << params[:query] when Hash request << '?' for key, values in params[:query] if values.nil? request << key.to_s << '&' else for value in [*values] request << key.to_s << '=' << CGI.escape(value.to_s) << '&' end end end request.chop! # remove trailing '&' end # finish first line with "HTTP/1.1\r\n" request << HTTP_1_1 # calculate content length and set to handle non-ascii unless params[:headers].has_key?('Content-Length') params[:headers]['Content-Length'] = case params[:body] when File params[:body].binmode File.size(params[:body]) when String if FORCE_ENC params[:body].force_encoding('BINARY') end params[:body].length else 0 end end # add headers to request for key, values in params[:headers] for value in [*values] request << key.to_s << ': ' << value.to_s << CR_NL end end # add additional "\r\n" to indicate end of headers request << CR_NL # write out the request, sans body socket.write(request) # write out the body if params[:body] if params[:body].is_a?(String) socket.write(params[:body]) else while chunk = params[:body].read(CHUNK_SIZE) socket.write(chunk) end end end # read the response response = Excon::Response.parse(socket, params, &block) if response.headers['Connection'] == 'close' reset end response end rescue Excon::Errors::StubNotFound => stub_not_found raise(stub_not_found) rescue => socket_error reset raise(Excon::Errors::SocketError.new(socket_error)) end if params.has_key?(:expects) && ![*params[:expects]].include?(response.status) reset raise(Excon::Errors.status_error(params, response)) else response end end