簡體   English   中英

帶標題的Sinatra流式響應

[英]Sinatra streaming response with headers

我想通過Sinatra應用程序代理遠程文件。 這需要將來自遠程源頭的HTTP響應流式傳輸回客戶端,但我無法弄清楚如何在Net::HTTP#get_response提供的塊內使用流API時設置響應的頭。

例如,這不會設置響應標頭:

get '/file' do
  stream do |out|
    uri = URI("http://manuals.info.apple.com/en/ipad_user_guide.pdf")
    Net::HTTP.get_response(uri) do |file|
      headers 'Content-Type' => file.header['Content-Type']

      file.read_body { |chunk| out << chunk }
    end
  end
end

這會導致錯誤: Net::HTTPOK#read_body called twice (IOError)

get '/file' do
  response = nil
  uri = URI("http://manuals.info.apple.com/en/ipad_user_guide.pdf")
  Net::HTTP.get_response(uri) do |file|
    headers 'Content-Type' => file.header['Content-Type']

    response = stream do |out|
      file.read_body { |chunk| out << chunk }
    end
  end
  response
end

我可能錯了,但在考慮了一下之后,在我看來,當從stream幫助程序塊內部設置響應頭時,這些頭不會被應用到響應中,因為該塊的執行實際上是延遲的 因此,可能會對塊進行評估,並在開始執行之前設置響應頭。

一種可能的解決方法是在流式傳輸文件內容之前發出HEAD請求。

例如:

get '/file' do
  uri = URI('http://manuals.info.apple.com/en/ipad_user_guide.pdf')

  # get only header data
  head = Net::HTTP.start(uri.host, uri.port) do |http|
    http.head(uri.request_uri)
  end

  # set headers accordingly (all that apply)
  headers 'Content-Type' => head['Content-Type']

  # stream back the contents
  stream do |out|
    Net::HTTP.get_response(uri) do |f| 
      f.read_body { |ch| out << ch }
    end
  end
end

由於附加請求,它可能不適合您的用例,但它應該足夠小,不會出現太多問題(延遲),並且它會增加您的應用程序可能會在發送回請求失敗之前做出反應的好處任何數據。

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM