# File lib/em/protocols/httpclient.rb, line 177
      def receive_data data
        while data and data.length > 0
          case @read_state
          when :base
            # Perform any per-request initialization here and don't consume any data.
            @data = ""
            @headers = []
            @content_length = nil # not zero
            @content = ""
            @status = nil
            @read_state = :header
            @connection_close = nil
          when :header
            ary = data.split( /\r?\n/m, 2 )
            if ary.length == 2
              data = ary.last
              if ary.first == ""
                if (@content_length and @content_length > 0) || @connection_close
                  @read_state = :content
                else
                  dispatch_response
                  @read_state = :base
                end
              else
                @headers << ary.first
                if @headers.length == 1
                  parse_response_line
                elsif ary.first =~ /\Acontent-length:\s*/i
                  # Only take the FIRST content-length header that appears,
                  # which we can distinguish because @content_length is nil.
                  # TODO, it's actually a fatal error if there is more than one
                  # content-length header, because the caller is presumptively
                  # a bad guy. (There is an exploit that depends on multiple
                  # content-length headers.)
                  @content_length ||= $'.to_i
                elsif ary.first =~ /\Aconnection:\s*close/i
                  @connection_close = true
                end
              end
            else
              @data << data
              data = ""
            end
          when :content
            # If there was no content-length header, we have to wait until the connection
            # closes. Everything we get until that point is content.
            # TODO: Must impose a content-size limit, and also must implement chunking.
            # Also, must support either temporary files for large content, or calling
            # a content-consumer block supplied by the user.
            if @content_length
              bytes_needed = @content_length - @content.length
              @content += data[0, bytes_needed]
              data = data[bytes_needed..-1] || ""
              if @content_length == @content.length
                dispatch_response
                @read_state = :base
              end
            else
              @content << data
              data = ""
            end
          end
        end
      end