16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
# File 'lib/excon/connection.rb', line 16
def request(params, &block)
begin
params[:path] ||= @connection[:path]
unless params[:path][0..0] == '/'
params[:path] = "/#{params[:path]}"
end
request = "#{params[:method].upcase} #{params[:path]}?"
for key, values in (params[:query] || @connection[:query] || {})
for value in [*values]
request << "#{key}#{value && "=#{CGI.escape(value.to_s)}"}&"
end
end
request.chop!
request << " HTTP/1.1\r\n"
params[:headers] ||= @connection[:headers]
params[:headers]['Host'] ||= params[:host] || @connection[:host]
params[:body] ||= @connection[:body]
params[:headers]['Content-Length'] = case params[:body]
when File
params[:body].binmode
File.size(params[:body].path)
when String
if params[:body].respond_to?(:force_encoding)
params[:body].force_encoding('BINARY')
end
params[:body].length
else
0
end
for key, value in params[:headers]
request << "#{key}: #{value}\r\n"
end
request << "\r\n"
socket.write(request)
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
response = Excon::Response.parse(socket, params, &block)
if response.['Connection'] == 'close'
reset
end
response
rescue => socket_error
reset
raise(socket_error)
end
if params[:expects] && ![*params[:expects]].include?(response.status)
reset
raise(Excon::Errors.status_error(params, response))
else
response
end
rescue => request_error
if params[:idempotent] &&
(!request_error.is_a?(Excon::Errors::Error) || response.status != 404)
retries_remaining ||= 4
retries_remaining -= 1
if retries_remaining > 0
retry
else
raise(request_error)
end
else
raise(request_error)
end
end
|