Class: Reel::Request
- Inherits:
-
Object
- Object
- Reel::Request
- Extended by:
- Forwardable
- Includes:
- RequestMixin
- Defined in:
- lib/reel/request.rb,
lib/reel/request/body.rb,
lib/reel/request/info.rb,
lib/reel/request/parser.rb,
lib/reel/request/state_machine.rb
Defined Under Namespace
Classes: Body, Info, Parser, StateMachine
Instance Attribute Summary collapse
-
#body ⇒ Object
readonly
Returns the value of attribute body.
Instance Method Summary collapse
-
#fill_buffer(chunk) ⇒ Object
Fill the request buffer with data as it becomes available.
-
#finish_reading! ⇒ Object
When HTTP Parser marks the message parsing as complete, this will be set.
-
#finish_response ⇒ Object
Finish the response and reset the response state to header.
-
#finished_reading? ⇒ Boolean
Returns true if request fully finished reading.
-
#initialize(request_info, connection = nil) ⇒ Request
constructor
request_info is a RequestInfo object including the headers and the url, method and http version.
-
#inspect ⇒ Object
Friendlier inspect.
-
#read(length = nil, buffer = nil) ⇒ Object
Read a number of bytes, looping until they are available or until readpartial returns nil, indicating there are no more bytes to read.
-
#readpartial(length = nil) ⇒ Object
Read a string up to the given number of bytes, blocking until some data is available but returning immediately if some data is available.
-
#websocket ⇒ Object
Return a Reel::WebSocket for this request, hijacking the socket from the underlying connection.
-
#websocket? ⇒ Boolean
Can the current request be upgraded to a WebSocket?.
-
#write(chunk) ⇒ Object
(also: #<<)
Write body chunks directly to the connection.
Methods included from RequestMixin
#[], #fragment, #headers, #method, #path, #query_string, #uri, #url, #version
Constructor Details
#initialize(request_info, connection = nil) ⇒ Request
request_info is a RequestInfo object including the headers and the url, method and http version.
Access it through the RequestMixin methods.
23 24 25 26 27 28 29 30 31 32 |
# File 'lib/reel/request.rb', line 23 def initialize(request_info, connection = nil) @request_info = request_info @connection = connection @finished = false @buffer = "" @finished_read = false @websocket = nil @body = Request::Body.new(self) @response_writer = Response::Writer.new(connection.socket) end |
Instance Attribute Details
#body ⇒ Object (readonly)
Returns the value of attribute body.
17 18 19 |
# File 'lib/reel/request.rb', line 17 def body @body end |
Instance Method Details
#fill_buffer(chunk) ⇒ Object
Fill the request buffer with data as it becomes available
44 45 46 |
# File 'lib/reel/request.rb', line 44 def fill_buffer(chunk) @buffer << chunk end |
#finish_reading! ⇒ Object
When HTTP Parser marks the message parsing as complete, this will be set.
38 39 40 41 |
# File 'lib/reel/request.rb', line 38 def finish_reading! raise StateError, "already finished" if @finished_read @finished_read = true end |
#finish_response ⇒ Object
Finish the response and reset the response state to header
102 103 104 105 106 |
# File 'lib/reel/request.rb', line 102 def finish_response raise StateError, "not in body state" if @connection.response_state != :chunked_body @response_writer.finish_response @connection.response_state = :headers end |
#finished_reading? ⇒ Boolean
Returns true if request fully finished reading
35 |
# File 'lib/reel/request.rb', line 35 def finished_reading?; @finished_read; end |
#inspect ⇒ Object
Friendlier inspect
121 122 123 |
# File 'lib/reel/request.rb', line 121 def inspect "#<#{self.class} #{method} #{url} HTTP/#{version} @headers=#{headers.inspect}>" end |
#read(length = nil, buffer = nil) ⇒ Object
Read a number of bytes, looping until they are available or until readpartial returns nil, indicating there are no more bytes to read
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/reel/request.rb', line 50 def read(length = nil, buffer = nil) raise ArgumentError, "negative length #{length} given" if length && length < 0 return '' if length == 0 res = buffer.nil? ? '' : buffer.clear chunk_size = length.nil? ? @connection.buffer_size : length begin while chunk_size > 0 chunk = readpartial(chunk_size) break unless chunk res << chunk chunk_size = length - res.length unless length.nil? end rescue EOFError end return length && res.length == 0 ? nil : res end |
#readpartial(length = nil) ⇒ Object
Read a string up to the given number of bytes, blocking until some data is available but returning immediately if some data is available
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/reel/request.rb', line 71 def readpartial(length = nil) if length.nil? && @buffer.length > 0 slice = @buffer @buffer = "" else unless finished_reading? || (length && length <= @buffer.length) @connection.readpartial(length ? length - @buffer.length : @connection.buffer_size) end if length slice = @buffer.slice!(0, length) else slice = @buffer @buffer = "" end end slice && slice.length == 0 ? nil : slice end |
#websocket ⇒ Object
Return a Reel::WebSocket for this request, hijacking the socket from the underlying connection
113 114 115 116 117 118 |
# File 'lib/reel/request.rb', line 113 def websocket @websocket ||= begin raise StateError, "can't upgrade this request to a websocket" unless websocket? WebSocket.new(@request_info, @connection.hijack_socket) end end |
#websocket? ⇒ Boolean
Can the current request be upgraded to a WebSocket?
109 |
# File 'lib/reel/request.rb', line 109 def websocket?; @request_info.websocket_request?; end |
#write(chunk) ⇒ Object Also known as: <<
Write body chunks directly to the connection
92 93 94 95 96 97 98 |
# File 'lib/reel/request.rb', line 92 def write(chunk) unless @connection.response_state == :chunked_body raise StateError, "not in chunked body mode" end @response_writer.write(chunk) end |