kronk 1.4.0 → 1.5.0
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.
- data/.gemtest +0 -0
- data/History.rdoc +22 -0
- data/Manifest.txt +15 -6
- data/README.rdoc +5 -6
- data/Rakefile +5 -5
- data/lib/kronk.rb +164 -194
- data/lib/kronk/cmd.rb +188 -74
- data/lib/kronk/constants.rb +90 -0
- data/lib/kronk/data_renderer.rb +146 -0
- data/lib/kronk/diff.rb +4 -92
- data/lib/kronk/path/transaction.rb +2 -0
- data/lib/kronk/player.rb +233 -0
- data/lib/kronk/player/benchmark.rb +261 -0
- data/lib/kronk/player/input_reader.rb +54 -0
- data/lib/kronk/player/output.rb +49 -0
- data/lib/kronk/player/request_parser.rb +24 -0
- data/lib/kronk/player/stream.rb +50 -0
- data/lib/kronk/player/suite.rb +123 -0
- data/lib/kronk/plist_parser.rb +4 -0
- data/lib/kronk/request.rb +265 -241
- data/lib/kronk/response.rb +330 -149
- data/lib/kronk/test/assertions.rb +2 -2
- data/lib/kronk/xml_parser.rb +7 -1
- data/test/mocks/cookies.yml +32 -0
- data/test/mocks/get_request.txt +6 -0
- data/test/test_assertions.rb +6 -6
- data/test/test_cmd.rb +708 -0
- data/test/test_diff.rb +210 -75
- data/test/test_helper.rb +140 -0
- data/test/test_helper_methods.rb +4 -4
- data/test/test_input_reader.rb +103 -0
- data/test/test_kronk.rb +142 -141
- data/test/test_player.rb +589 -0
- data/test/test_request.rb +147 -212
- data/test/test_request_parser.rb +31 -0
- data/test/test_response.rb +206 -15
- metadata +41 -74
- data/bin/yzma +0 -13
- data/lib/kronk/data_set.rb +0 -144
- data/lib/yzma.rb +0 -174
- data/lib/yzma/randomizer.rb +0 -54
- data/lib/yzma/report.rb +0 -47
- data/test/test_data_set.rb +0 -213
data/lib/kronk/plist_parser.rb
CHANGED
data/lib/kronk/request.rb
CHANGED
@@ -1,387 +1,411 @@
|
|
1
1
|
class Kronk
|
2
2
|
|
3
3
|
##
|
4
|
-
#
|
4
|
+
# Performs HTTP requests or retrieves HTTP responses.
|
5
5
|
|
6
6
|
class Request
|
7
7
|
|
8
|
-
#
|
9
|
-
class
|
8
|
+
# Raised by Request.parse when parsing invalid http request string.
|
9
|
+
class ParseError < Kronk::Exception; end
|
10
10
|
|
11
|
-
#
|
12
|
-
|
13
|
-
|
14
|
-
# Raised when HTTP times out.
|
15
|
-
class TimeoutError < Exception; end
|
11
|
+
# Matches the first line of an http request string.
|
12
|
+
REQUEST_LINE_MATCHER = %r{([A-Za-z]+)?(^|[\s'"])(/[^\s'";]+)[\s"']*}
|
16
13
|
|
17
14
|
##
|
18
|
-
#
|
19
|
-
# number of redirects left if it's an Integer.
|
20
|
-
|
21
|
-
def self.follow_redirect resp, options={}
|
22
|
-
Kronk::Cmd.verbose "Following redirect..."
|
15
|
+
# Creates a query string from data.
|
23
16
|
|
24
|
-
|
25
|
-
|
17
|
+
def self.build_query data, param=nil
|
18
|
+
return data.to_s unless param || Hash === data
|
26
19
|
|
27
|
-
|
28
|
-
|
20
|
+
case data
|
21
|
+
when Array
|
22
|
+
out = data.map do |value|
|
23
|
+
key = "#{param}[]"
|
24
|
+
build_query value, key
|
25
|
+
end
|
29
26
|
|
30
|
-
|
31
|
-
end
|
27
|
+
out.join "&"
|
32
28
|
|
29
|
+
when Hash
|
30
|
+
out = data.map do |key, value|
|
31
|
+
key = param.nil? ? key : "#{param}[#{key}]"
|
32
|
+
build_query value, key
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
# Check the rdir value to figure out if redirect should be followed.
|
35
|
+
out.join "&"
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
37
|
+
else
|
38
|
+
"#{param}=#{data}"
|
39
|
+
end
|
40
40
|
end
|
41
41
|
|
42
42
|
|
43
43
|
##
|
44
|
-
#
|
45
|
-
#
|
46
|
-
# :data:: Hash/String - the data to pass to the http request
|
47
|
-
# :query:: Hash/String - the data to append to the http request path
|
48
|
-
# :follow_redirects:: Integer/Bool - number of times to follow redirects
|
49
|
-
# :user_agent:: String - user agent string or alias; defaults to 'kronk'
|
50
|
-
# :auth:: Hash - must contain :username and :password; defaults to nil
|
51
|
-
# :headers:: Hash - extra headers to pass to the request
|
52
|
-
# :http_method:: Symbol - the http method to use; defaults to :get
|
53
|
-
# :proxy:: Hash/String - http proxy to use; defaults to nil
|
44
|
+
# Build the URI to use for the request from the given uri or
|
45
|
+
# path and options.
|
54
46
|
|
55
|
-
def self.
|
56
|
-
|
57
|
-
|
58
|
-
elsif File.file? uri
|
59
|
-
resp = retrieve_file uri, options
|
60
|
-
else
|
61
|
-
resp = retrieve_uri uri, options
|
62
|
-
Kronk.history << uri
|
63
|
-
end
|
47
|
+
def self.build_uri uri, options={}
|
48
|
+
uri ||= Kronk.config[:default_host]
|
49
|
+
suffix = options[:uri_suffix]
|
64
50
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
51
|
+
uri = "http://#{uri}" unless uri.to_s =~ %r{^(\w+://|/)}
|
52
|
+
uri = "#{uri}#{suffix}" if suffix
|
53
|
+
uri = URI.parse uri unless URI === uri
|
54
|
+
uri = URI.parse(Kronk.config[:default_host]) + uri unless uri.host
|
55
|
+
|
56
|
+
if options[:query]
|
57
|
+
query = build_query options[:query]
|
58
|
+
uri.query = [uri.query, query].compact.join "&"
|
71
59
|
end
|
72
60
|
|
73
|
-
|
61
|
+
uri
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
##
|
66
|
+
# Parses a raw HTTP request-like string into a Kronk::Request instance.
|
74
67
|
|
75
|
-
|
76
|
-
|
68
|
+
def self.parse str, opts={}
|
69
|
+
opts = parse_to_hash str, opts
|
70
|
+
raise ParseError unless opts
|
77
71
|
|
78
|
-
|
79
|
-
raise TimeoutError, "#{uri} took too long to respond"
|
72
|
+
new opts.delete(:host), opts
|
80
73
|
end
|
81
74
|
|
82
75
|
|
83
76
|
##
|
84
|
-
#
|
77
|
+
# Parses a raw HTTP request-like string into a Kronk::Request options hash.
|
78
|
+
# Also parses most single access log entries.
|
79
|
+
|
80
|
+
def self.parse_to_hash str, opts={}
|
81
|
+
lines = str.split("\n")
|
82
|
+
return if lines.empty?
|
85
83
|
|
86
|
-
|
87
|
-
Kronk::Cmd.verbose "Reading file: #{path}\n"
|
84
|
+
body_start = nil
|
88
85
|
|
89
|
-
|
90
|
-
resp = nil
|
86
|
+
opts[:headers] ||= {}
|
91
87
|
|
92
|
-
|
88
|
+
lines.shift.strip =~ REQUEST_LINE_MATCHER
|
89
|
+
opts[:http_method], opts[:uri_suffix] = $1, $3
|
93
90
|
|
94
|
-
|
95
|
-
|
96
|
-
|
91
|
+
lines.each_with_index do |line, i|
|
92
|
+
case line
|
93
|
+
when /^Host: /
|
94
|
+
opts[:host] = line.split(": ", 2)[1].strip
|
97
95
|
|
98
|
-
|
99
|
-
|
96
|
+
when "", "\r"
|
97
|
+
body_start = i+1
|
98
|
+
break
|
100
99
|
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
else
|
101
|
+
name, value = line.split(": ", 2)
|
102
|
+
opts[:headers][name] = value.strip if value
|
104
103
|
end
|
105
104
|
end
|
106
105
|
|
107
|
-
|
108
|
-
|
106
|
+
opts[:data] = lines[body_start..-1].join("\n") if body_start
|
107
|
+
|
108
|
+
opts.delete(:uri_suffix) if !opts[:uri_suffix]
|
109
|
+
opts.delete(:headers) if opts[:headers].empty?
|
110
|
+
opts.delete(:http_method) if !opts[:http_method]
|
111
|
+
opts.delete(:data) if opts[:data] && opts[:data].strip.empty?
|
109
112
|
|
110
|
-
|
113
|
+
return if opts.empty?
|
114
|
+
opts
|
111
115
|
end
|
112
116
|
|
113
117
|
|
114
118
|
##
|
115
|
-
#
|
119
|
+
# Parses a nested query. Stolen from Rack.
|
116
120
|
|
117
|
-
def self.
|
118
|
-
|
121
|
+
def self.parse_nested_query qs, d=nil
|
122
|
+
params = {}
|
123
|
+
d ||= "&;"
|
119
124
|
|
120
|
-
|
125
|
+
(qs || '').split(%r{[#{d}] *}n).each do |p|
|
126
|
+
k, v = CGI.unescape(p).split('=', 2)
|
127
|
+
normalize_params(params, k, v)
|
128
|
+
end
|
121
129
|
|
122
|
-
|
130
|
+
params
|
131
|
+
end
|
123
132
|
|
124
|
-
begin
|
125
|
-
resp = Response.read_new io
|
126
133
|
|
127
|
-
|
128
|
-
|
129
|
-
resp = HeadlessResponse.new io.read
|
130
|
-
end
|
134
|
+
##
|
135
|
+
# Stolen from Rack.
|
131
136
|
|
132
|
-
|
133
|
-
|
137
|
+
def self.normalize_params params, name, v=nil
|
138
|
+
name =~ %r(\A[\[\]]*([^\[\]]+)\]*)
|
139
|
+
k = $1 || ''
|
140
|
+
after = $' || ''
|
134
141
|
|
135
|
-
|
136
|
-
end
|
142
|
+
return if k.empty?
|
137
143
|
|
144
|
+
if after == ""
|
145
|
+
params[k] = v
|
138
146
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
# :follow_redirects:: Integer/Bool - number of times to follow redirects
|
145
|
-
# :user_agent:: String - user agent string or alias; defaults to 'kronk'
|
146
|
-
# :auth:: Hash - must contain :username and :password; defaults to nil
|
147
|
-
# :headers:: Hash - extra headers to pass to the request
|
148
|
-
# :http_method:: Symbol - the http method to use; defaults to :get
|
149
|
-
# :proxy:: Hash/String - http proxy to use; defaults to nil
|
150
|
-
#
|
151
|
-
# Note: if no http method is specified and data is given, will default
|
152
|
-
# to using a post request.
|
147
|
+
elsif after == "[]"
|
148
|
+
params[k] ||= []
|
149
|
+
raise TypeError,
|
150
|
+
"expected Array (got #{params[k].class.name}) for param `#{k}'" unless
|
151
|
+
params[k].is_a?(Array)
|
153
152
|
|
154
|
-
|
155
|
-
options = options.dup
|
156
|
-
http_method = options.delete(:http_method)
|
157
|
-
http_method ||= options[:data] ? :post : :get
|
153
|
+
params[k] << v
|
158
154
|
|
159
|
-
|
155
|
+
elsif after =~ %r(^\[\]\[([^\[\]]+)\]$) || after =~ %r(^\[\](.+)$)
|
156
|
+
child_key = $1
|
157
|
+
params[k] ||= []
|
158
|
+
raise TypeError,
|
159
|
+
"expected Array (got #{params[k].class.name}) for param `#{k}'" unless
|
160
|
+
params[k].is_a?(Array)
|
160
161
|
|
161
|
-
|
162
|
-
|
162
|
+
if params[k].last.is_a?(Hash) && !params[k].last.key?(child_key)
|
163
|
+
normalize_params(params[k].last, child_key, v)
|
164
|
+
else
|
165
|
+
params[k] << normalize_params({}, child_key, v)
|
166
|
+
end
|
163
167
|
|
164
|
-
|
168
|
+
else
|
169
|
+
params[k] ||= {}
|
170
|
+
raise TypeError,
|
171
|
+
"expected Hash (got #{params[k].class.name}) for param `#{k}'" unless
|
172
|
+
params[k].is_a?(Hash)
|
173
|
+
|
174
|
+
params[k] = normalize_params(params[k], after, v)
|
175
|
+
end
|
176
|
+
|
177
|
+
return params
|
165
178
|
end
|
166
179
|
|
167
180
|
|
181
|
+
attr_accessor :body, :headers, :response, :timeout
|
182
|
+
|
183
|
+
attr_reader :http_method, :uri, :use_cookies
|
184
|
+
|
168
185
|
##
|
169
|
-
#
|
186
|
+
# Build an http request to the given uri and return a Response instance.
|
170
187
|
# Supports the following options:
|
171
|
-
# :data:: Hash/String - the data to pass to the http request
|
188
|
+
# :data:: Hash/String - the data to pass to the http request
|
172
189
|
# :query:: Hash/String - the data to append to the http request path
|
190
|
+
# :follow_redirects:: Integer/Bool - number of times to follow redirects
|
173
191
|
# :user_agent:: String - user agent string or alias; defaults to 'kronk'
|
174
192
|
# :auth:: Hash - must contain :username and :password; defaults to nil
|
175
193
|
# :headers:: Hash - extra headers to pass to the request
|
176
194
|
# :http_method:: Symbol - the http method to use; defaults to :get
|
177
195
|
# :proxy:: Hash/String - http proxy to use; defaults to nil
|
196
|
+
#
|
197
|
+
# Note: if no http method is specified and data is given, will default
|
198
|
+
# to using a post request.
|
178
199
|
|
179
|
-
def
|
180
|
-
|
181
|
-
|
182
|
-
data = options[:data]
|
183
|
-
data &&= build_query data
|
200
|
+
def initialize uri, options={}
|
201
|
+
@HTTP = Net::HTTP
|
202
|
+
@auth = options[:auth]
|
184
203
|
|
185
|
-
|
186
|
-
options[:
|
204
|
+
@body = nil
|
205
|
+
@body = self.class.build_query options[:data] if options[:data]
|
187
206
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
end
|
207
|
+
@response = nil
|
208
|
+
@_req = nil
|
209
|
+
@_res = nil
|
192
210
|
|
193
|
-
|
211
|
+
@headers = options[:headers] || {}
|
212
|
+
@timeout = options[:timeout] || Kronk.config[:timeout]
|
194
213
|
|
195
|
-
|
196
|
-
if Hash === options[:proxy]
|
197
|
-
[options[:proxy][:address], options[:proxy]]
|
198
|
-
else
|
199
|
-
[options[:proxy], {}]
|
200
|
-
end
|
214
|
+
@uri = self.class.build_uri uri, options
|
201
215
|
|
202
|
-
|
216
|
+
self.user_agent ||= options[:user_agent]
|
203
217
|
|
204
|
-
|
205
|
-
req.use_ssl = true if uri.scheme =~ /^https$/
|
218
|
+
self.http_method = options[:http_method] || (@body ? "POST" : "GET")
|
206
219
|
|
207
|
-
|
208
|
-
|
220
|
+
self.use_cookies = options.has_key?(:no_cookies) ?
|
221
|
+
!options[:no_cookies] : Kronk.config[:use_cookies]
|
209
222
|
|
210
|
-
|
211
|
-
|
212
|
-
|
223
|
+
if Hash === options[:proxy]
|
224
|
+
self.use_proxy options[:proxy][:address], options[:proxy]
|
225
|
+
else
|
226
|
+
self.use_proxy options[:proxy]
|
227
|
+
end
|
228
|
+
end
|
213
229
|
|
214
|
-
req = VanillaRequest.new http_method.to_s.upcase,
|
215
|
-
uri.request_uri, options[:headers]
|
216
230
|
|
217
|
-
|
218
|
-
|
219
|
-
options[:auth][:password]
|
220
|
-
end
|
231
|
+
##
|
232
|
+
# Returns the basic auth credentials if available.
|
221
233
|
|
222
|
-
|
234
|
+
def auth
|
235
|
+
@auth ||= Hash.new
|
223
236
|
|
224
|
-
|
237
|
+
if !@auth[:username] && @headers['Authorization']
|
238
|
+
str = Base64.decode64 @headers['Authorization'].split[1]
|
239
|
+
username, password = str.split(":", 2)
|
240
|
+
@auth = {:username => username, :password => password}.merge @auth
|
225
241
|
end
|
226
242
|
|
227
|
-
|
228
|
-
use_cookies? options
|
229
|
-
|
230
|
-
resp.extend Response::Helpers
|
231
|
-
resp.set_helper_attribs socket_io
|
232
|
-
|
233
|
-
resp
|
243
|
+
@auth
|
234
244
|
end
|
235
245
|
|
236
246
|
|
237
247
|
##
|
238
|
-
#
|
239
|
-
# path and options.
|
248
|
+
# Assigns the cookie string.
|
240
249
|
|
241
|
-
def
|
242
|
-
|
243
|
-
|
244
|
-
uri = "http://#{uri}" unless uri =~ %r{^(\w+://|/)}
|
245
|
-
uri = "#{uri}#{suffix}" if suffix
|
246
|
-
uri = URI.parse uri unless URI === uri
|
247
|
-
uri = URI.parse(Kronk.config[:default_host]) + uri unless uri.host
|
248
|
-
|
249
|
-
if options[:query]
|
250
|
-
query = build_query options[:query]
|
251
|
-
uri.query = [uri.query, query].compact.join "&"
|
252
|
-
end
|
253
|
-
|
254
|
-
uri
|
250
|
+
def cookie= cookie_str
|
251
|
+
@headers['Cookie'] = cookie_str if @use_cookies
|
255
252
|
end
|
256
253
|
|
257
254
|
|
258
255
|
##
|
259
|
-
#
|
256
|
+
# Assigns the http method.
|
260
257
|
|
261
|
-
def
|
262
|
-
|
263
|
-
Kronk.config[:use_cookies]
|
258
|
+
def http_method= new_verb
|
259
|
+
@http_method = new_verb.to_s.upcase
|
264
260
|
end
|
265
261
|
|
266
262
|
|
267
263
|
##
|
268
|
-
#
|
264
|
+
# Returns the HTTP request object.
|
269
265
|
|
270
|
-
def
|
271
|
-
|
272
|
-
|
266
|
+
def http_request
|
267
|
+
req = VanillaRequest.new @http_method, @uri.request_uri, @headers
|
268
|
+
|
269
|
+
req.basic_auth @auth[:username], @auth[:password] if
|
270
|
+
@auth && @auth[:username]
|
271
|
+
|
272
|
+
req
|
273
273
|
end
|
274
274
|
|
275
275
|
|
276
276
|
##
|
277
|
-
#
|
277
|
+
# Assign the use of a proxy.
|
278
278
|
# The proxy_opts arg can be a uri String or a Hash with the :address key
|
279
279
|
# and optional :username and :password keys.
|
280
280
|
|
281
|
-
def
|
282
|
-
return Net::HTTP unless addr
|
281
|
+
def use_proxy addr, opts={}
|
282
|
+
return @HTTP = Net::HTTP unless addr
|
283
283
|
|
284
284
|
host, port = addr.split ":"
|
285
|
-
port ||=
|
285
|
+
port ||= opts[:port] || 8080
|
286
286
|
|
287
|
-
user =
|
288
|
-
pass =
|
287
|
+
user = opts[:username]
|
288
|
+
pass = opts[:password]
|
289
289
|
|
290
290
|
Kronk::Cmd.verbose "Using proxy #{addr}\n" if host
|
291
291
|
|
292
|
-
Net::HTTP::Proxy host, port, user, pass
|
292
|
+
@HTTP = Net::HTTP::Proxy host, port, user, pass
|
293
293
|
end
|
294
294
|
|
295
295
|
|
296
296
|
##
|
297
|
-
#
|
297
|
+
# Assign the uri and io based on if the uri is a file, io, or url.
|
298
298
|
|
299
|
-
def
|
300
|
-
|
301
|
-
|
302
|
-
case data
|
303
|
-
when Array
|
304
|
-
out = data.map do |value|
|
305
|
-
key = "#{param}[]"
|
306
|
-
build_query value, key
|
307
|
-
end
|
299
|
+
def uri= new_uri
|
300
|
+
@uri = self.class.build_uri new_uri
|
301
|
+
end
|
308
302
|
|
309
|
-
out.join "&"
|
310
303
|
|
311
|
-
|
312
|
-
|
313
|
-
key = param.nil? ? key : "#{param}[#{key}]"
|
314
|
-
build_query value, key
|
315
|
-
end
|
304
|
+
##
|
305
|
+
# Decide whether to use cookies or not.
|
316
306
|
|
317
|
-
|
307
|
+
def use_cookies= bool
|
308
|
+
if bool && (!@headers['Cookie'] || @headers['Cookie'].empty?)
|
309
|
+
cookie = Kronk.cookie_jar.get_cookie_header @uri.to_s
|
310
|
+
@headers['Cookie'] = cookie unless cookie.empty?
|
318
311
|
|
319
312
|
else
|
320
|
-
|
313
|
+
@headers.delete 'Cookie'
|
321
314
|
end
|
315
|
+
|
316
|
+
@use_cookies = bool
|
322
317
|
end
|
323
318
|
|
324
319
|
|
325
320
|
##
|
326
|
-
#
|
321
|
+
# Assign a User Agent header.
|
327
322
|
|
328
|
-
def
|
329
|
-
|
330
|
-
|
323
|
+
def user_agent= new_ua
|
324
|
+
@headers['User-Agent'] =
|
325
|
+
new_ua && Kronk.config[:user_agents][new_ua.to_s] ||
|
326
|
+
new_ua || Kronk.config[:user_agents]['kronk']
|
327
|
+
end
|
331
328
|
|
332
|
-
(qs || '').split(%r{[#{d}] *}n).each do |p|
|
333
|
-
k, v = CGI.unescape(p).split('=', 2)
|
334
|
-
normalize_params(params, k, v)
|
335
|
-
end
|
336
329
|
|
337
|
-
|
330
|
+
##
|
331
|
+
# Read the User Agent header.
|
332
|
+
|
333
|
+
def user_agent
|
334
|
+
@headers['User-Agent']
|
338
335
|
end
|
339
336
|
|
340
337
|
|
341
338
|
##
|
342
|
-
#
|
339
|
+
# Check if this is an SSL request.
|
343
340
|
|
344
|
-
def
|
345
|
-
|
346
|
-
|
347
|
-
after = $' || ''
|
341
|
+
def ssl?
|
342
|
+
@uri.scheme == "https"
|
343
|
+
end
|
348
344
|
|
349
|
-
return if k.empty?
|
350
345
|
|
351
|
-
|
352
|
-
|
346
|
+
##
|
347
|
+
# Assign whether to use ssl or not.
|
353
348
|
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
"expected Array (got #{params[k].class.name}) for param `#{k}'" unless
|
358
|
-
params[k].is_a?(Array)
|
349
|
+
def ssl= bool
|
350
|
+
@uri.scheme = bool ? "https" : "http"
|
351
|
+
end
|
359
352
|
|
360
|
-
params[k] << v
|
361
353
|
|
362
|
-
|
363
|
-
|
364
|
-
params[k] ||= []
|
365
|
-
raise TypeError,
|
366
|
-
"expected Array (got #{params[k].class.name}) for param `#{k}'" unless
|
367
|
-
params[k].is_a?(Array)
|
354
|
+
##
|
355
|
+
# Retrieve this requests' response.
|
368
356
|
|
369
|
-
|
370
|
-
|
371
|
-
else
|
372
|
-
params[k] << normalize_params({}, child_key, v)
|
373
|
-
end
|
357
|
+
def retrieve
|
358
|
+
@_req = @HTTP.new @uri.host, @uri.port
|
374
359
|
|
375
|
-
|
376
|
-
|
377
|
-
raise TypeError,
|
378
|
-
"expected Hash (got #{params[k].class.name}) for param `#{k}'" unless
|
379
|
-
params[k].is_a?(Hash)
|
360
|
+
@_req.read_timeout = @timeout if @timeout
|
361
|
+
@_req.use_ssl = true if @uri.scheme =~ /^https$/
|
380
362
|
|
381
|
-
|
363
|
+
elapsed_time = nil
|
364
|
+
socket = nil
|
365
|
+
socket_io = nil
|
366
|
+
|
367
|
+
@_res = @_req.start do |http|
|
368
|
+
socket = http.instance_variable_get "@socket"
|
369
|
+
socket.debug_output = socket_io = StringIO.new
|
370
|
+
|
371
|
+
start_time = Time.now
|
372
|
+
res = http.request self.http_request, @body
|
373
|
+
elapsed_time = Time.now - start_time
|
374
|
+
|
375
|
+
res
|
382
376
|
end
|
383
377
|
|
384
|
-
|
378
|
+
Kronk.cookie_jar.set_cookies_from_headers @uri.to_s, @_res.to_hash if
|
379
|
+
self.use_cookies
|
380
|
+
|
381
|
+
@response = Response.new socket_io, @_res, self
|
382
|
+
@response.time = elapsed_time
|
383
|
+
|
384
|
+
@response
|
385
|
+
end
|
386
|
+
|
387
|
+
|
388
|
+
##
|
389
|
+
# Returns the raw HTTP request String.
|
390
|
+
|
391
|
+
def to_s
|
392
|
+
out = "#{@http_method} #{@uri.request_uri} HTTP/1.1\r\n"
|
393
|
+
out << "host: #{@uri.host}:#{@uri.port}\r\n"
|
394
|
+
|
395
|
+
self.http_request.each do |name, value|
|
396
|
+
out << "#{name}: #{value}\r\n" unless name =~ /host/i
|
397
|
+
end
|
398
|
+
|
399
|
+
out << "\r\n"
|
400
|
+
out << @body.to_s
|
401
|
+
end
|
402
|
+
|
403
|
+
|
404
|
+
##
|
405
|
+
# Ruby inspect.
|
406
|
+
|
407
|
+
def inspect
|
408
|
+
"#<#{self.class}:#{self.http_method} #{self.uri}>"
|
385
409
|
end
|
386
410
|
|
387
411
|
|