Module: EventParsers::Http11Parser
Overview
Implement this by including it in a class and call receive_data on every read event. Callbacks available:
upon_new_request(request) (request, ) (request) process_request(request)
Defined Under Namespace
Modules: BasicAuth, ClassMethods
Classes: HeaderAndEntityStateStore, Request
Constant Summary
collapse
- HttpResponseRE =
/\AHTTP\/(1.[01]) ([\d]{3})/i
- HttpRequestRE =
/^(GET|POST|PUT|DELETE) (\/.*) HTTP\/([\d\.]+)[\r\n]?$/i
- BlankLineRE =
/^[\n\r]+$/
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Instance Attribute Details
#socket ⇒ Object
Returns the value of attribute socket.
407
408
409
|
# File 'bin/httphere', line 407
def socket
@socket
end
|
Class Method Details
.included(base) ⇒ Object
398
399
400
|
# File 'bin/httphere', line 398
def self.included(base)
base.extend ClassMethods
end
|
Instance Method Details
#current_request ⇒ Object
413
414
415
|
# File 'bin/httphere', line 413
def current_request
request_backlog.first
end
|
#parsing_request ⇒ Object
416
417
418
|
# File 'bin/httphere', line 416
def parsing_request
request_backlog.last
end
|
#process_request(request) ⇒ Object
505
506
507
|
# File 'bin/httphere', line 505
def process_request(request)
warn "STUB - overwrite process_request in a subclass of Http11Parser to process this #{request.inspect}"
end
|
#receive_data(data) ⇒ Object
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
|
# File 'bin/httphere', line 424
def receive_data(data)
return unless (data and data.size > 0)
@last_activity = Time.now
case parser.state
when :init
if ix = data.index("\n")
parser.linebuffer << data[0...ix+1]
ln = parser.linebuffer.join
parser.linebuffer.clear
log "[#{parser.state}]: #{ln}" if $DEBUG
if ln =~ HttpRequestRE
request_backlog << self.class.request_klass.new
parsing_request.connection = self
method, resource_uri, http_version = parse_init_line(ln)
parsing_request.method = method
parsing_request.resource_uri = resource_uri
parsing_request.query_params = parse_query_string(resource_uri.index('?') ? resource_uri[(resource_uri.index('?')+1)..-1] : '')
parsing_request.http_version = http_version
upon_new_request(parsing_request) if respond_to?(:upon_new_request)
parser.state = :headers
else
parser.bogus_line!(ln)
end
receive_data(data[(ix+1)..-1])
else
parser.linebuffer << data
end
when :headers
if ix = data.index("\n")
parser.linebuffer << data[0...ix+1]
ln = parser.linebuffer.join
parser.linebuffer.clear
if ln =~ BlankLineRE
(parsing_request) if respond_to?(:upon_headers_finished)
if parser.entity?
parser.state = :entity
else
receive_full_request
end
else
= (ln)
log "\t[#{parser.state}]: #{.inspect}\n" if $DEBUG
(parsing_request, .to_a[0]) if respond_to?(:receive_header)
parsing_request..merge!()
end
receive_data(data[(ix+1)..-1])
else
parser.linebuffer << data
end
when :entity
if parser.entity_size
chars_yet_needed = parser.entity_size - parser.entity_pos
taking_this_many = [chars_yet_needed, data.size].sort.first
parser.textbuffer << data[0...taking_this_many]
leftover_data = data[taking_this_many..-1]
parser.entity_pos += taking_this_many
if parser.entity_pos >= parser.entity_size
entity_data = parser.textbuffer.join
parser.textbuffer.clear
parsing_request.entity << entity_data
log "[#{parser.state}]: #{entity_data}\n" if $DEBUG
receive_full_request
end
receive_data(leftover_data)
else
raise "TODO!"
end
else
raise "Shouldn't be here!"
end
end
|
#request_backlog ⇒ Object
409
410
411
|
# File 'bin/httphere', line 409
def request_backlog
@request_backlog ||= []
end
|
#send_response!(http_response) ⇒ Object
509
510
511
512
513
514
515
|
# File 'bin/httphere', line 509
def send_response!(http_response)
log "Sending Response: #{http_response.inspect}\n" if $DEBUG
socket.write(http_response)
request_backlog.shift
process_request(current_request) if current_request && current_request.ready?
end
|