Class: EventMachine::HttpClient
- Inherits:
-
Connection
- Object
- Connection
- EventMachine::HttpClient
show all
- Includes:
- Deferrable, HttpEncoding
- Defined in:
- lib/em-http/client.rb
Constant Summary
collapse
- TRANSFER_ENCODING =
"TRANSFER_ENCODING"
- CONTENT_ENCODING =
"CONTENT_ENCODING"
- CONTENT_LENGTH =
"CONTENT_LENGTH"
- KEEP_ALIVE =
"CONNECTION"
- SET_COOKIE =
"SET_COOKIE"
- LOCATION =
"LOCATION"
- HOST =
"HOST"
- CRLF =
"\r\n"
EventMachine::HttpEncoding::BASIC_AUTH_ENCODING, EventMachine::HttpEncoding::FIELD_ENCODING, EventMachine::HttpEncoding::HTTP_REQUEST_HEADER
Instance Attribute Summary collapse
Instance Method Summary
collapse
#encode_basic_auth, #encode_cookies, #encode_field, #encode_headers, #encode_host, #encode_param, #encode_query, #encode_request, #escape, #munge_header_keys, #unescape
Instance Attribute Details
#errors ⇒ Object
Returns the value of attribute errors.
155
156
157
|
# File 'lib/em-http/client.rb', line 155
def errors
@errors
end
|
#method ⇒ Object
Returns the value of attribute method.
154
155
156
|
# File 'lib/em-http/client.rb', line 154
def method
@method
end
|
#options ⇒ Object
Returns the value of attribute options.
154
155
156
|
# File 'lib/em-http/client.rb', line 154
def options
@options
end
|
#response ⇒ Object
Returns the value of attribute response.
155
156
157
|
# File 'lib/em-http/client.rb', line 155
def response
@response
end
|
Returns the value of attribute response_header.
155
156
157
|
# File 'lib/em-http/client.rb', line 155
def
@response_header
end
|
#uri ⇒ Object
Returns the value of attribute uri.
154
155
156
|
# File 'lib/em-http/client.rb', line 154
def uri
@uri
end
|
Instance Method Details
#connection_completed ⇒ Object
start HTTP request once we establish connection to host
172
173
174
175
176
177
178
|
# File 'lib/em-http/client.rb', line 172
def connection_completed
ssl = @options[:tls] || @options[:ssl] || {}
start_tls(ssl) if @uri.scheme == "https" or @uri.port == 443
send_request_body
end
|
#dispatch ⇒ Object
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
|
# File 'lib/em-http/client.rb', line 272
def dispatch
while case @state
when :response_header
when :chunk_header
when :chunk_body
process_chunk_body
when :chunk_footer
when :response_footer
when :body
process_body
when :finished, :invalid
break
else raise RuntimeError, "invalid state: #{@state}"
end
end
end
|
#normalize_body ⇒ Object
196
197
198
199
200
201
202
|
# File 'lib/em-http/client.rb', line 196
def normalize_body
if @options[:body].is_a? Hash
@options[:body].to_params
else
@options[:body]
end
end
|
#on_body_data(data) ⇒ Object
Called when part of the body has been read
243
244
245
246
247
248
249
250
251
252
253
|
# File 'lib/em-http/client.rb', line 243
def on_body_data(data)
if @content_decoder
begin
@content_decoder << data
rescue HttpDecoders::DecoderError
on_error "Content-decoder error"
end
else
on_decoded_body_data(data)
end
end
|
#on_decoded_body_data(data) ⇒ Object
255
256
257
258
259
260
261
|
# File 'lib/em-http/client.rb', line 255
def on_decoded_body_data(data)
if (on_response = @options[:on_response])
on_response.call(data)
else
@response << data
end
end
|
#on_error(msg) ⇒ Object
request failed, invoke errback
191
192
193
194
|
# File 'lib/em-http/client.rb', line 191
def on_error(msg)
@errors = msg
unbind
end
|
#on_request_complete ⇒ Object
request is done, invoke the callback
181
182
183
184
185
186
187
188
|
# File 'lib/em-http/client.rb', line 181
def on_request_complete
begin
@content_decoder.finalize! if @content_decoder
rescue HttpDecoders::DecoderError
on_error "Content-decoder error"
end
unbind
end
|
341
342
343
344
345
346
347
348
349
|
# File 'lib/em-http/client.rb', line 341
def
return false unless (@chunk_header)
@bytes_remaining = @chunk_header.chunk_size
@chunk_header = HttpChunkHeader.new
@state = @bytes_remaining > 0 ? :chunk_body : :response_footer
true
end
|
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
|
# File 'lib/em-http/client.rb', line 293
def ()
return false if @data.empty?
begin
@parser_nbytes = @parser.execute(, @data.to_str, @parser_nbytes)
rescue EventMachine::HttpClientParserError
@state = :invalid
on_error "invalid HTTP format, parsing fails"
end
return false unless @parser.finished?
@data.read(@parser_nbytes)
@parser.reset
@parser_nbytes = 0
true
end
|
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
|
# File 'lib/em-http/client.rb', line 313
def
return false unless (@response_header)
unless @response_header.http_status and @response_header.http_reason
@state = :invalid
on_error "no HTTP response"
return false
end
if @response_header.chunked_encoding?
@state = :chunk_header
else
@state = :body
@bytes_remaining = @response_header.content_length
end
if @inflate.include?([CONTENT_ENCODING]) &&
decoder_class = HttpDecoders.decoder_for_encoding([CONTENT_ENCODING])
begin
@content_decoder = decoder_class.new do |s| on_decoded_body_data(s) end
rescue HttpDecoders::DecoderError
on_error "Content-decoder error"
end
end
true
end
|
#process_body ⇒ Object
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
|
# File 'lib/em-http/client.rb', line 397
def process_body
if @bytes_remaining.nil?
on_body_data @data.read
return false
end
if @bytes_remaining.zero?
@state = :finished
on_request_complete
return false
end
if @data.size < @bytes_remaining
@bytes_remaining -= @data.size
on_body_data @data.read
return false
end
on_body_data @data.read(@bytes_remaining)
@bytes_remaining = 0
if @response_header.keep_alive?
@data.clear @state = :finished
on_request_complete
else
if @data.empty?
@state = :finished
on_request_complete
else
@state = :invalid
on_error "garbage at end of body"
end
end
false
end
|
#process_chunk_body ⇒ Object
351
352
353
354
355
356
357
358
359
360
361
362
363
|
# File 'lib/em-http/client.rb', line 351
def process_chunk_body
if @data.size < @bytes_remaining
@bytes_remaining -= @data.size
on_body_data @data.read
return false
end
on_body_data @data.read(@bytes_remaining)
@bytes_remaining = 0
@state = :chunk_footer
true
end
|
365
366
367
368
369
370
371
372
373
374
375
376
|
# File 'lib/em-http/client.rb', line 365
def
return false if @data.size < 2
if @data.read(2) == CRLF
@state = :chunk_header
else
@state = :invalid
on_error "non-CRLF chunk footer"
end
true
end
|
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
|
# File 'lib/em-http/client.rb', line 378
def
return false if @data.size < 2
if @data.read(2) == CRLF
if @data.empty?
@state = :finished
on_request_complete
else
@state = :invalid
on_error "garbage at end of chunked response"
end
else
@state = :invalid
on_error "non-CRLF response footer"
end
false
end
|
#receive_data(data) ⇒ Object
237
238
239
240
|
# File 'lib/em-http/client.rb', line 237
def receive_data(data)
@data << data
dispatch
end
|
#send_request_body ⇒ Object
231
232
233
234
235
|
# File 'lib/em-http/client.rb', line 231
def send_request_body
return unless @options[:body]
body = normalize_body
send_data body
end
|
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
|
# File 'lib/em-http/client.rb', line 204
def
query = @options[:query]
head = @options[:head] ? (@options[:head]) : {}
body = normalize_body
head['host'] ||= encode_host
head['content-length'] = body.length if body
head['user-agent'] ||= "EventMachine HttpClient"
if head['accept-encoding']
@inflate = head['accept-encoding'].split(',').map {|t| t.strip}
end
= encode_request(@method, @uri.path, query)
<< (head)
<< CRLF
send_data
end
|
#unbind ⇒ Object
263
264
265
266
|
# File 'lib/em-http/client.rb', line 263
def unbind
(@state == :finished) ? succeed(self) : fail
close_connection
end
|