class Excon::Response

def self.parse(socket, params={})

def self.parse(socket, params={})
  response = new(:status => socket.read(12)[9, 11].to_i)
  socket.readline # read the rest of the status line and CRLF
  until ((data = socket.readline).chop!).empty?
    key, value = data.split(/:\s*/, 2)
    response.headers[key] = ([*response.headers[key]] << value).compact.join(', ')
    if key.casecmp('Content-Length') == 0
      content_length = value.to_i
    elsif (key.casecmp('Transfer-Encoding') == 0) && (value.casecmp('chunked') == 0)
      transfer_encoding_chunked = true
    end
  end
  unless (params[:method].to_s.casecmp('HEAD') == 0) || NO_ENTITY.include?(response.status)
    # check to see if expects was set and matched
    expected_status = !params.has_key?(:expects) || [*params[:expects]].include?(response.status)
    # if expects matched and there is a block, use it
    if expected_status && params.has_key?(:response_block)
      if transfer_encoding_chunked
        # 2 == "/r/n".length
        while (chunk_size = socket.readline.chop!.to_i(16)) > 0
          params[:response_block].call(socket.read(chunk_size + 2).chop!, nil, nil)
        end
        socket.read(2)
      elsif remaining = content_length
        while remaining > 0
          params[:response_block].call(socket.read([CHUNK_SIZE, remaining].min), [remaining - CHUNK_SIZE, 0].max, content_length)
          remaining -= CHUNK_SIZE
        end
      else
        while remaining = socket.read(CHUNK_SIZE)
          params[:response_block].call(remaining, remaining.length, content_length)
        end
      end
    else # no block or unexpected status
      if transfer_encoding_chunked
        while (chunk_size = socket.readline.chop!.to_i(16)) > 0
          response.body << socket.read(chunk_size + 2).chop! # 2 == "/r/n".length
        end
        socket.read(2) # 2 == "/r/n".length
      elsif remaining = content_length
        while remaining > 0
          response.body << socket.read([CHUNK_SIZE, remaining].min)
          remaining -= CHUNK_SIZE
        end
      else
        response.body << socket.read
      end
    end
  end
  response
end