2009-07-13 3 views

Antwort

4

Dies scheint, wenn Sockets zu arbeiten:

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 

Ich bin gespannt, ob es ein "ruby Weg" ist.

+0

Hallo Michel, aus irgendeinem Grund, wenn ich eine Datei versuchen, wie 'http:// www.forcefieldpr.com/asdyoucantbealone.mp3', das im Browser funktioniert, bekomme ich immer eine 404 html Seite. Würde das mit der Anfrage zu tun haben? –

+0

Ich habe eine Bearbeitung eingereicht, die das Problem behebt, das @AaronMoodie hat. Einige Webserver benötigen den Header "Host", also habe ich einfach folgendes hinzugefügt: 'request =" GET # {Pfad} HTTP/1.1 \ r \ nHost: # {host} \ r \ n \ r \ n "' – inket

0

Auschecken "OpenURI returns two different objects". Sie können möglicherweise die darin enthaltenen Methoden missbrauchen, um den Download zu unterbrechen und den Rest des Ergebnisses nach einem voreingestellten Limit wegzuwerfen.

+0

Dank für das interessante Punkt – taro

3

Dies ist ein alter Thread, aber es ist immer noch eine Frage, die nach meinen Recherchen meist unbeantwortet bleibt. Hier ist eine Lösung, die ich mit von Affen-Patching Net kam :: HTTP ein bisschen:

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 

Die Rettung fängt den IOError, die ausgelöst wird, wenn Sie HTTP.finish vorzeitig rufen.

FYI, die Buchse innerhalb des HTTPResponse Objekts ist kein echtes IO Objekt (es ist eine interne Klasse BufferedIO genannt), aber es ist ziemlich leicht zu Affen-Patch, der auch die IO Methoden nachzuahmen Sie benötigen. Zum Beispiel habe ich eine andere Bibliothek wurde unter Verwendung (exifr) benötigt die readchar Methode, die hinzuzufügen war leicht zu:

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

Großartig! Du kannst übrigens auf den Socket zugreifen, ohne zu patchen, benutze einfach: 'response.instance_variable_get (: @ socket) .read (5120)' – inket

+0

Diese Lösung bleibt mit ruby-2.0.0p247 unter OS X 10.9 auf unbestimmte Zeit stecken. Konnte das Problem nicht eingrenzen, aber das Backtrace erwähnt Zeile 155 in 'net/protocol.rb'. – inket