2013-07-03 19 views
9

ile karşıdan yükleme yapmadan önce HTTP üstbilgileri nasıl edinilir Şu anda Ruby'de bir dosya indirmek için OpenURI kullanıyorum. Ne yazık ki, tam dosyayı indirmeden HTTP başlıklarını almak mümkün görünüyor: Yukarıdaki kodu KoşuRuby OpenUri

open(base_url, 
    :content_length_proc => lambda {|t| 
    if t && 0 < t 
     pbar = ProgressBar.create(:total => t) 
    end 
    }, 
    :progress_proc => lambda {|s| 
    pbar.progress = s if pbar 
    }) {|io| 
    puts io.size 
    puts io.meta['content-disposition'] 
    } 

ilk tam dosyasını indirir ve ancak o zaman ihtiyacım başlığını yazdırır olduğunu göstermektedir.

Tam dosya indirilmeden önce üstbilgileri almanın bir yolu var mı, bu nedenle, üstbilgileri beklediğim gibi değilse, indirme işlemini iptal edebilir miyim?

+0

yinelenen? http://stackoverflow.com/questions/13916046/display-http-headers-using-openuri?rq=1 – yeyo

+3

@Kira no, bağlantılı cevabı kullanarak ilk olarak tam dosyayı indireceğim, tam olarak ne yaptım _not_. – ePirat

cevap

4

İstediğim gibi, en azından değil, tüm dosyayı yüklemeden OpenURI kullanarak arşivlemek mümkün değil gibi görünüyor. gibi bir blok kullanırken bu sadece çalışır, bunu yaparken o

http.request_get('/largefile.jpg') {|response| 
    if (response['content-length'] < max_length) 
    response.read_body do |str| # read body now 
     # save to file 
    end 
    end 
} 

Not:

Ben Net :: HTTP en Burada request_get

bir örnek kullanarak istediğini yapmak başardı Vücut zaten okunmuş olacaktır.

+0

Doğru, OpenURI içeriği önceden okur, sonra blok formunu kullanıp kullanmama konusunda bir dosya tanıtıcısı döndürür. –

11

Örneğin, bu konuda net :: HTTP kullanabilirsiniz:

require 'net/http' 

http = Net::HTTP.start('stackoverflow.com') 

resp = http.head('/') 
resp.each { |k, v| puts "#{k}: #{v}" } 
http.finish 

başka örnek, harika kitabın başlığını ANSI-C ile Nesne Orient Programlama alma bu sefer:

require 'net/http' 

http = Net::HTTP.start('www.planetpdf.com') 

resp = http.head('/codecuts/pdfs/ooc.pdf') 
resp.each { |k, v| puts "#{k}: #{v}" } 
http.finish 
+1

"Start" blok formunu kullanmak daha temiz. [Dökümantasyon] 'daki örneğe bakın (http://ruby-doc.org/stdlib-2.0/libdoc/net/http/rdoc/Net/HTTP.html#method-i-head). –

+0

+1 @theTinMan. Temiz tutar (rdoc ile bağlantılar). – orde

+1

@theTinMan Pardon, ama bu, referansın bağlantısı olarak, bu formun varlığını bilmediğim anlamına gelmez. Evet, blok formunu kullanırsa daha temizdir, ancak "mükemmellik" anlamına gelmez, bazen girinti çok derin ya da basit olur, blok formu o kadar iyi uymaz, duruma bağlıdır. – yeyo

2

Kum kürek kullanarak sahilde bir havuz kazmak gibi olabilir Net :: HTTP kullanmak yerine, Ruby için HTTP istemcilerinden bir dizi kullanabilir ve kodu temizleyebilirsiniz.

require 'httparty' 

resp = HTTParty.head('http://example.org') 
resp.headers 
# => {"accept-ranges"=>["bytes"], "cache-control"=>["max-age=604800"], "content-type"=>["text/html"], "date"=>["Thu, 02 Mar 2017 18:52:42 GMT"], "etag"=>["\"359670651\""], "expires"=>["Thu, 09 Mar 2017 18:52:42 GMT"], "last-modified"=>["Fri, 09 Aug 2013 23:54:35 GMT"], "server"=>["ECS (oxr/83AB)"], "x-cache"=>["HIT"], "content-length"=>["1270"], "connection"=>["close"]} 

o belgenin boyutunu kontrol etmek kolaydır Bu noktada: Maalesef

resp.headers['content-length'] # => "1270" 

, nasıl bilmiyor olabilir konuştuğunuz HTTPd

İşte HTTParty kullanarak örnek verilmektedir içerik büyük olacak; Hızlı bir şekilde sunuculara yanıt vermek için, dinamik olarak üretilen çıktının büyüklüğünü hesaplamamak gerekir; bu, neredeyse uzun süren ve neredeyse gönderen yoğun CPU gibi, bu nedenle "içerik uzunluğu" değerine güvenerek buggy olabilir.

Net :: HTTP ile ilgili sorun, yönlendirmeleri otomatik olarak işlemez, bu nedenle ek kod eklemeniz gerekir. Bu kod, belgelerde sağlanmıştır, ancak başka bir http istemcisini (YAHC) yazmanıza kadar, daha fazla şey yapmanız gerektiğinde kod büyüyor. Bundan kaçın, mevcut bir tekerleği kullan.

+0

Kodu doğru bir şekilde anladım, bu aslında, bu özel durumda istediğim değil, bir HEAD isteği yapar. Bu, genel olarak bunu çözmek için genel olarak iyi bir yol olsa da, bu durumda bir GET talebi kullanmak zorunda kaldım. – ePirat

+0

A GET, her zaman tüm dosyayı almaya çalışır. İşlemin içine girmek ve bağlantıyı durdurmak mümkündür, ancak bu iyi bir ağ vatandaşı değildir. Ne olduğunu düşünün: Bir GET verirsiniz ve sunucu dosyayı göndermeye başlamak için yükler. Siz iptal edersiniz ve sunucuya, araya giren ağa ve sunucunuza fazladan yüklenmeye neden oldunuz. Bunu yapmak için HEAD'ın icat edilmesinin nedeni budur. –

+0

Dediğim gibi, bunun farkındayım, fakat özel durumda HEAD çalışmıyordu, bu yüzden tek seçenek GET'di. Ve tam dosyayı indirmekten kaçınmak istedim, böylece tüm dosyayı indirdikten sonra mümkün olduğunca erken iptal edebilmek için iyi bir şey olurdu. – ePirat