在閱讀網頁正文時,似乎Ruby的Net :: HTTP的方法全是或全無。我怎樣才能讀取身體的前100個字節?如何使用Net :: HTTP只讀取身體的x個字節?
我試圖從在響應的身體返回短錯誤消息,如果請求的文件不可用內容服務器來讀取。我需要閱讀足夠的內容才能確定文件是否存在。這些文件是巨大的,所以我不想讓整個機構檢查文件是否可用。
在閱讀網頁正文時,似乎Ruby的Net :: HTTP的方法全是或全無。我怎樣才能讀取身體的前100個字節?如何使用Net :: HTTP只讀取身體的x個字節?
我試圖從在響應的身體返回短錯誤消息,如果請求的文件不可用內容服務器來讀取。我需要閱讀足夠的內容才能確定文件是否存在。這些文件是巨大的,所以我不想讓整個機構檢查文件是否可用。
你不能。但爲什麼你需要?當然,如果頁面只是說文件不可用,那麼它不會是一個巨大的頁面(即根據定義,文件不會在那裏)?
確定的內容服務器只返回一個簡短的錯誤頁面?
不還設置HTTPResponse
適當的像404的東西在這種情況下你可以捕獲HTTPClientError
派生的異常(最有可能HTTPNotFound
)的訪問時Net::HTTP.value()
提高。
如果你得到一個錯誤,那麼如果你得到200文件開始下載,你可以關閉連接您的文件是不存在。
要讀取的塊HTTP請求的身體,你需要使用Net::HTTPResponse#read_body
這樣的:
http.request_get('/large_resource') do |response|
response.read_body do |segment|
print segment
end
end
試過這個。 request_get仍然希望在處理該塊之前下載整個文件。 – bvanderw 2008-09-17 13:36:14
這對我的分塊響應(使用`Transfer-Encoding:chunked`)有效,如果我在兩個塊(在兩個「end」之前)都添加一個「break」以在獲得第一個塊之後停止。在這種情況下,使用帶有`read_body`的塊使Ruby不會讀取完整的響應(甚至不會等待它)。但是,再次說明:我的回答大致是從一開始,而這些都是小塊。我懷疑HTTP允許客戶端明確請求分塊響應,也不允許它建議最大塊大小;如果服務器不返回(小)塊,似乎應該使用`Range`頭。 – Arjan 2015-05-01 12:49:09
你不應該只使用一個HTTP請求HEAD
(紅寶石Net::HTTP::Head
方法),看是否資源是否存在,並且只有在獲得2xx或3xx響應時纔會繼續?這假定您的服務器配置爲在文檔不可用時返回4xx錯誤代碼。我會認爲這是正確的解決方案。
另一種方法是請求HTTP頭並查看結果中的content-length
標頭值:如果您的服務器配置正確,您應該能夠輕鬆地分辨出短消息和長文檔之間的長度差異。另一種方法是:在請求中設置content-range
標頭字段(它再次假定服務器的行爲正確WRT HTTP規範)。
我不認爲解決客戶端之後之後發送GET請求的問題是一條可行之路:到那時,網絡已經完成了繁重的工作,而且您不會真的節省浪費的資源。
試過,服務器發送一個OK響應和一個0的內容長度。這是Perforce的P4Web服務器。 – bvanderw 2008-09-17 13:34:43
嗯。如果你的供應商發送200 OK,當它真的意味着404沒有找到時,你應該提高優先級bugrep! – 2008-09-17 14:49:35
我想做這一次,我能想到的唯一的事情就是猴子修補Net::HTTP#read_body
和Net::HTTP#read_body_0
方法接受一個長度參數,然後在前者只是通過長度參數寫入read_body_0
方法,其中只能讀取長度字節。
這是一個古老的線程,但如何通過Ruby的HTTP只讀文件的一部分的問題仍然是根據我的研究大多是沒有答案的。這是我想出了一個解決方案由猴子修補的Net :: HTTP一點:
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);
# be sure to call finish before exiting the block
http.finish
end
end
rescue IOError
# ignore
end
救援捕捉,當你調用過早那HTTP.finish拋出真實的IO錯誤。
僅供參考,HTTPResponse
對象中的插座是不是一個真正的IO
對象(這就是所謂的一個內部類),但它很容易猴補丁,也模仿你所需要的IO
方法。例如,我正在使用的另一個庫(exifr)需要readchar
方法,該方法很容易添加:
class Net::BufferedIO
def readchar
read(1)[0].ord
end
end
這不是一個答案。這是你無法想象的東西可能是必要/有用/可取的,因爲你個人還沒有遇到過。誰在乎他爲什麼需要?誰在乎,如果你有這個問題的最終結果?問題是「如何使用Net :: HTTP只讀取身體的x個字節?」 「。你知不知道怎麼?如果不是,你爲什麼要浪費每個人的帶寬? – 2017-03-10 07:48:03