2012-09-11 37 views
5

Tôi muốn proxy tệp từ xa thông qua ứng dụng Sinatra. Điều này yêu cầu phát trực tuyến phản hồi HTTP với tiêu đề từ nguồn từ xa quay lại máy khách, nhưng tôi không thể tìm ra cách đặt tiêu đề phản hồi trong khi sử dụng API phát trực tiếp bên trong khối được cung cấp bởi Net::HTTP#get_response.Phản hồi trực tuyến Sinatra với tiêu đề

Ví dụ, điều này sẽ không đặt tiêu đề phản ứng:

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 

Và kết quả này trong các lỗi: 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 

Trả lời

3

Tôi có thể sai nhưng sau khi suy nghĩ một chút về vấn đề này nó xuất hiện với tôi rằng khi đặt tiêu đề phản hồi từ bên trong khối trợ giúp stream, các tiêu đề đó không được áp dụng vào phản hồi vì việc thực thi khối đó thực sự là bị trì hoãn. Vì vậy, có lẽ, khối được đánh giá và các tiêu đề phản hồi được đặt trước khi nó bắt đầu thực hiện.

Cách giải quyết có thể cho việc này là đưa ra yêu cầu HEAD trước khi phát lại nội dung của tệp.

Ví dụ:

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 

Nó có thể không được lý tưởng cho các trường hợp sử dụng của bạn bởi vì các yêu cầu bổ sung nhưng nó phải là đủ nhỏ để không nhiều của một vấn đề (chậm trễ) và nó cho biết thêm những lợi ích mà ứng dụng của bạn có thể phản ứng nếu yêu cầu đó không thành công trước khi gửi lại bất kỳ dữ liệu nào.

Hy vọng điều đó sẽ hữu ích.

Các vấn đề liên quan