@@ -12,6 +12,7 @@ def initialize(client, sock)
1212
1313 def read_response_buffer
1414 @buff = String . new
15+ @part_offset = 0
1516 catch :eof do
1617 while true
1718 read_line
@@ -29,21 +30,32 @@ def read_response_buffer
2930 attr_reader :buff , :literal_size
3031
3132 def bytes_read = buff . bytesize
33+ def part_size = bytes_read - @part_offset
3234 def empty? = buff . empty?
3335 def done? = line_done? && !get_literal_size
34- def line_done? = buff . end_with? ( CRLF )
36+ def line_done? = line_query? && @buff . end_with? ( "\r \n " )
37+ def line_expecting_LF? = line_query? && @buff . end_with? ( "\r " )
38+ def line_query? = literal_size ? part_size . zero? : part_size >= 2
3539 def get_literal_size = /\{ (\d +)\} \r \n \z /n =~ buff && $1. to_i
40+ def literal_remaining = literal_size &.- part_size
41+ def literal_remaining? = literal_size &.> part_size
3642
3743 def read_line
38- buff << gets
39- max_response_remaining! unless line_done?
44+ @part_offset = bytes_read
45+ until line_done?
46+ buff << gets
47+ # peek one byte beyond CR, to look for CRLF
48+ buff << read ( 1 ) while line_expecting_LF?
49+ end
4050 end
4151
4252 def read_literal
53+ @part_offset = bytes_read
4354 # check before allocating memory for literal
4455 max_response_remaining!
4556 literal = String . new ( capacity : literal_size )
4657 buff << read ( literal_size , literal )
58+ buff << read ( literal_remaining ) while literal_remaining?
4759 ensure
4860 @literal_size = nil
4961 end
@@ -57,7 +69,7 @@ def read(limit = nil, into = nil)
5769 end
5870
5971 def read_limit ( limit = nil )
60- [ limit , max_response_remaining! ] . compact . min
72+ [ limit , socket_read_limit! , max_response_remaining! ] . compact . min
6173 end
6274
6375 def max_response_size = client . max_response_size
@@ -66,7 +78,7 @@ def response_too_large? = max_response_size &.< min_response_size
6678 def min_response_size = bytes_read + min_response_remaining
6779
6880 def min_response_remaining
69- empty? ? 3 : done? ? 0 : ( literal_size || 0 ) + 2
81+ empty? ? 3 : done? ? 0 : line_expecting_LF? ? 1 : ( literal_remaining || 0 ) + 2
7082 end
7183
7284 def max_response_remaining!
@@ -76,6 +88,11 @@ def max_response_remaining!
7688 )
7789 end
7890
91+ # TODO: configurable socket_read_limit (currently hardcoded to 4KiB)
92+ def socket_read_limit!
93+ 4096
94+ end
95+
7996 end
8097 end
8198end
0 commit comments