         # File lib/protocols/httpclient.rb, line 165
    165:   def receive_data data
    166:     while data and data.length > 0
    167:       case @read_state
    168:       when :base
    169:         # Perform any per-request initialization here and don't consume any data.
    170:         @data = ""
    171:         @headers = []
    172:         @content_length = nil # not zero
    173:         @content = ""
    174:         @status = nil
    175:         @read_state = :header
    176:         @connection_close = nil
    177:       when :header
    178:         ary = data.split( /\r?\n/m, 2 )
    179:         if ary.length == 2
    180:           data = ary.last
    181:           if ary.first == ""
    182:               if (@content_length and @content_length > 0) || @connection_close
    183:                   @read_state = :content
    184:               else
    185:                   dispatch_response
    186:                   @read_state = :base
    187:               end
    188:           else
    189:             @headers << ary.first
    190:             if @headers.length == 1
    191:               parse_response_line
    192:             elsif ary.first =~ /\Acontent-length:\s*/i
    193:               # Only take the FIRST content-length header that appears,
    194:               # which we can distinguish because @content_length is nil.
    195:               # TODO, it's actually a fatal error if there is more than one
    196:               # content-length header, because the caller is presumptively
    197:               # a bad guy. (There is an exploit that depends on multiple
    198:               # content-length headers.)
    199:               @content_length ||= $'.to_i
    200:             elsif ary.first =~ /\Aconnection:\s*close/i
    201:               @connection_close = true
    202:             end
    203:           end
    204:         else
    205:           @data << data
    206:           data = ""
    207:         end
    208:       when :content
    209:         # If there was no content-length header, we have to wait until the connection
    210:         # closes. Everything we get until that point is content.
    211:         # TODO: Must impose a content-size limit, and also must implement chunking.
    212:         # Also, must support either temporary files for large content, or calling
    213:         # a content-consumer block supplied by the user.
    214:         if @content_length
    215:           bytes_needed = @content_length - @content.length
    216:           @content += data[0, bytes_needed]
    217:           data = data[bytes_needed..-1] || ""
    218:           if @content_length == @content.length
    219:             dispatch_response
    220:             @read_state = :base
    221:           end
    222:         else
    223:           @content << data
    224:           data = ""
    225:         end
    226:       end
    227:     end
    228:   end