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 @data[:proxy] request << datum[:scheme] << '://' << @data[:host] << ':' << @data[:port].to_s end request << datum[:path] # add query to path, if there is one case datum[:query] when String request << '?' << datum[:query] when Hash request << '?' datum[:query].each do |key, values| if values.nil? request << key.to_s << '&' else [values].flatten.each do |value| 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 if datum.has_key?(:request_block) datum[:headers]['Transfer-Encoding'] = 'chunked' elsif ! (datum[:method].to_s.casecmp('GET') == 0 && datum[:body].nil?) # 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. datum[:headers]['Content-Length'] = detect_content_length(datum[:body]) end # 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 # write out the request, sans body socket.write(request) # write out the body if datum.has_key?(:request_block) while true 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 !datum[:body].nil? if datum[:body].is_a?(String) unless datum[:body].empty? socket.write(datum[:body]) end else if datum[:body].respond_to?(:binmode) datum[:body].binmode end if datum[:body].respond_to?(:pos=) datum[:body].pos = 0 end while chunk = datum[:body].read(datum[:chunk_size]) socket.write(chunk) end 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