lib/ruby_wolf/connection.rb in ruby_wolf-0.2.0 vs lib/ruby_wolf/connection.rb in ruby_wolf-0.3.0
- old
+ new
@@ -1,45 +1,81 @@
module RubyWolf
class Connection
- attr_reader :socket, :read_data, :write_data
+ attr_reader :socket, :read_chunk, :write_chunk, :headers, :body, :path, :query, :method
def initialize(socket)
@socket = socket
- @read_data = ''
- @write_data = ''
-
+ @read_chunk = ''
+ @write_chunk = ''
@reading = true
+
+ @headers = {}
end
def need_to_read?
@reading
end
def read
- @read_data << socket.read_nonblock(RubyWolf::READ_SIZE)
- @reading = false if @read_data.end_with?(RubyWolf::CRLF)
+ @read_chunk << socket.read_nonblock(RubyWolf::READ_SIZE)
+ if @content_length.nil?
+ read_headers
+ else
+ read_body
+ end
rescue EOFError
@reading = false
end
def enqueue_write(data)
- @write_data += data
+ @write_chunk += data
end
def write
- writen = socket.write_nonblock(@write_data)
- @write_data[0..writen] = ''
+ writen = socket.write_nonblock(@write_chunk)
+ @write_chunk = @write_chunk.byteslice(writen, @write_chunk.bytesize)
end
def need_to_write?
- !@write_data.length.zero?
+ !@write_chunk.bytesize.zero?
end
def to_io
@socket
end
def close
@socket.close
+ end
+
+ private
+
+ def read_headers
+ header_ending = @read_chunk.index(RubyWolf::HEADER_ENDING)
+ return if header_ending.nil?
+
+ headers_chunk = @read_chunk.slice!(
+ 0, header_ending + RubyWolf::HEADER_ENDING.size
+ )
+ parse_headers(headers_chunk)
+ @content_length = @headers['Content-Length'].to_i
+ read_body
+ end
+
+ def parse_headers(headers_chunk)
+ parser = Http::Parser.new
+ parser.on_headers_complete = proc do
+ @headers = parser.headers
+ @method = parser.http_method
+ uri = URI.parse(parser.request_url)
+ @path = uri.path
+ @query = uri.query
+ :stop
+ end
+ parser << headers_chunk
+ end
+
+ def read_body
+ @reading = false if @read_chunk.bytesize >= @content_length
end
end
end