decode_chunk

in lib/puma/client.rb [415:492]


    def decode_chunk(chunk)
      if @partial_part_left > 0
        if @partial_part_left <= chunk.size
          if @partial_part_left > 2
            @body << chunk[0..(@partial_part_left-3)] 
          end
          chunk = chunk[@partial_part_left..-1]
          @partial_part_left = 0
        else
          @body << chunk if @partial_part_left > 2 
          @partial_part_left -= chunk.size
          return false
        end
      end

      if @prev_chunk.empty?
        io = StringIO.new(chunk)
      else
        io = StringIO.new(@prev_chunk+chunk)
        @prev_chunk = ""
      end

      while !io.eof?
        line = io.gets
        if line.end_with?("\r\n")
          len = line.strip.to_i(16)
          if len == 0
            @in_last_chunk = true
            @body.rewind
            rest = io.read
            last_crlf_size = "\r\n".bytesize
            if rest.bytesize < last_crlf_size
              @buffer = nil
              @partial_part_left = last_crlf_size - rest.bytesize
              return false
            else
              @buffer = rest[last_crlf_size..-1]
              @buffer = nil if @buffer.empty?
              set_ready
              return true
            end
          end

          len += 2

          part = io.read(len)

          unless part
            @partial_part_left = len
            next
          end

          got = part.size

          case
          when got == len
            @body << part[0..-3] 
          when got <= len - 2
            @body << part
            @partial_part_left = len - part.size
          when got == len - 1 
            @body << part[0..-2]
            @partial_part_left = len - part.size
          end
        else
          @prev_chunk = line
          return false
        end
      end

      if @in_last_chunk
        set_ready
        true
      else
        false
      end
    end