Pregunta

Sólo tengo que descargar los primeros kilobytes de un archivo a través de HTTP.

He intentado

require 'open-uri'
url = 'http://example.com/big-file.dat'
file = open(url)
content = file.read(limit)

Pero en realidad descarga el archivo completo.

¿Fue útil?

Solución

Esto parece funcionar cuando se utilizan enchufes:

require 'socket'                  
host = "download.thinkbroadband.com"                 
path = "/1GB.zip" # get 1gb sample file
request = "GET #{path} HTTP/1.0\r\n\r\n"
socket = TCPSocket.open(host,80) 
socket.print(request)        

# find beginning of response body
buffer = ""                    
while !buffer.match("\r\n\r\n") do
  buffer += socket.read(1)  
end           

response = socket.read(100) #read first 100 bytes of body
puts response

Tengo curiosidad por si hay un "camino de rubí".

Otros consejos

Este es un hilo viejo, pero sigue siendo una pregunta sin respuesta que parece en su mayoría de acuerdo a mi investigación. He aquí una solución que se me ocurrió por Net mono-parches :: HTTP un poco:

require 'net/http'

# provide access to the actual socket
class Net::HTTPResponse
  attr_reader :socket
end

uri = URI("http://www.example.com/path/to/file")
begin
  Net::HTTP.start(uri.host, uri.port) do |http|
    request = Net::HTTP::Get.new(uri.request_uri)
    # calling request with a block prevents body from being read
    http.request(request) do |response|
      # do whatever limited reading you want to do with the socket
      x = response.socket.read(100);
    end
  end
rescue IOError
  # ignore
end

El rescate atrapa el IOError que se inicia cuando se llama a HTTP.finish prematuramente.

Para su información, la toma de corriente dentro del objeto HTTPResponse no es un verdadero objeto IO (que es una clase llamada BufferedIO interna), pero es bastante fácil de mono-parche que, también, para imitar los métodos IO que necesita. Por ejemplo, otra biblioteca que estaba usando (exifr) necesita el método readchar, que era fácil de añadir:

class Net::BufferedIO
  def readchar
    read(1)[0].ord
  end
end

Confirmar " OpenURI devuelve dos objetos diferentes ". Es posible que pueda abusar de los métodos en que hay que interrumpir la descarga / tirar el resto del resultado después de un límite preestablecido.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top