2009-07-13 6 views

risposta

4

Questo sembra funzionare quando si utilizzano i socket:

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 

Sono curioso di sapere se esiste un "modo ruby".

+0

Ciao Michel, per qualche motivo ogni volta che provo un file, ad esempio 'http:// www.forcefieldpr.com/asdyoucantbealone.mp3', che funziona nel browser, continuo a ricevere una pagina 404 html. Questo dovrebbe fare con la richiesta? –

+0

Ho inviato una modifica che corregge il problema @AaronMoodie. Alcuni server web hanno bisogno dell'intestazione "Host", quindi ho aggiunto solo: 'request =" GET # {percorso} HTTP/1.1 \ r \ nHost: # {host} \ r \ n \ r \ n "' – inket

0

Controllare "OpenURI returns two different objects". Potresti essere in grado di abusare dei metodi in là per interrompere il download/eliminare il resto del risultato dopo un limite preimpostato.

+0

Grazie per punto interessante – taro

3

Questo è un thread vecchio, ma è ancora una domanda che sembra per lo più senza risposta secondo la mia ricerca. Ecco una soluzione mi è venuta dalla scimmia-patching Net :: HTTP un po ':

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 

Il salvataggio cattura l'IOError che viene generata quando si chiama HTTP.finish prematuramente.

Cordiali saluti, il socket all'interno dell'oggetto HTTPResponse non è un vero IO oggetto (si tratta di una classe interna denominata BufferedIO), ma è abbastanza facile da scimmia-patch che, troppo, per imitare i metodi IO necessari. Ad esempio, un'altra libreria stavo usando (exifr) aveva bisogno il metodo readchar, che era facile da aggiungere:

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

Grande! È possibile accedere al socket senza patch a proposito, basta usare: 'response.instance_variable_get (: @ socket) .read (5120)' – inket

+0

Questa soluzione si blocca indefinitamente con ruby-2.0.0p247 sotto OS X 10.9. Non è possibile restringere il problema, ma il backtrace cita la riga 155 in 'net/protocol.rb'. – inket