Class: Reel::Connection
- Inherits:
-
Object
- Object
- Reel::Connection
- Defined in:
- lib/reel/connection.rb
Overview
A connection to the HTTP server
Defined Under Namespace
Classes: StateError
Constant Summary collapse
- BUFFER_SIZE =
Attempt to read this much data
4096
Instance Attribute Summary collapse
-
#request ⇒ Object
readonly
Returns the value of attribute request.
Instance Method Summary collapse
-
#alive? ⇒ Boolean
Is the connection still active?.
-
#initialize(socket) ⇒ Connection
constructor
A new instance of Connection.
- #read_request ⇒ Object
- #readpartial(size = BUFFER_SIZE) ⇒ Object
- #reset ⇒ Object
- #respond(response, body = nil) ⇒ Object
Constructor Details
#initialize(socket) ⇒ Connection
Returns a new instance of Connection.
11 12 13 14 15 16 17 18 19 |
# File 'lib/reel/connection.rb', line 11 def initialize(socket) @socket = socket @keepalive = true @parser = Request::Parser.new reset @response_state = :header @body_remaining = nil end |
Instance Attribute Details
#request ⇒ Object (readonly)
Returns the value of attribute request.
6 7 8 |
# File 'lib/reel/connection.rb', line 6 def request @request end |
Instance Method Details
#alive? ⇒ Boolean
Is the connection still active?
22 |
# File 'lib/reel/connection.rb', line 22 def alive?; @keepalive; end |
#read_request ⇒ Object
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 |
# File 'lib/reel/connection.rb', line 24 def read_request raise StateError, "can't read header" unless @request_state == :header begin until @parser.headers @parser << @socket.readpartial(BUFFER_SIZE) end rescue IOError, Errno::ECONNRESET, Errno::EPIPE @keepalive = false @socket.close unless @socket.closed? return end @request_state = :body headers = {} @parser.headers.each do |header, value| headers[Http.canonicalize_header(header)] = value end if headers['Connection'] @keepalive = false if headers['Connection'] == 'close' elsif @parser.http_version == "1.0" @keepalive = false end @body_remaining = Integer(headers['Content-Length']) if headers['Content-Length'] @request = Request.new(@parser.http_method, @parser.url, @parser.http_version, headers, self) end |
#readpartial(size = BUFFER_SIZE) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/reel/connection.rb', line 54 def readpartial(size = BUFFER_SIZE) if @body_remaining and @body_remaining > 0 chunk = @parser.chunk unless chunk @parser << @socket.readpartial(size) chunk = @parser.chunk return unless chunk end @body_remaining -= chunk.length @body_remaining = nil if @body_remaining < 1 chunk end end |
#reset ⇒ Object
98 99 100 101 102 |
# File 'lib/reel/connection.rb', line 98 def reset @request_state = :header @request = nil @parser.reset end |
#respond(response, body = nil) ⇒ Object
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/reel/connection.rb', line 70 def respond(response, body = nil) if @keepalive headers = {'Connection' => 'Keep-Alive'} else headers = {'Connection' => 'close'} end case response when Symbol response = Response.new(response, headers, body) when Response else raise TypeError, "invalid response: #{response.inspect}" end response.render(@socket) rescue IOError, Errno::ECONNRESET, Errno::EPIPE # The client disconnected early @keepalive = false ensure if @keepalive reset @request_state = :header else @socket.close unless @socket.closed? @request_state = :closed end end |