2012-09-11 20 views
5

मैं सिनात्रा एप्लिकेशन के माध्यम से दूरस्थ फ़ाइलों को प्रॉक्सी करना चाहता हूं। इसके लिए एक रिमोट स्रोत से क्लाइंट को हेडर के साथ HTTP प्रतिक्रिया स्ट्रीमिंग की आवश्यकता होती है, लेकिन Net::HTTP#get_response द्वारा प्रदान किए गए ब्लॉक के अंदर स्ट्रीमिंग एपीआई का उपयोग करते समय प्रतिक्रिया के शीर्षकों को सेट करने का तरीका पता नहीं लगा सकता है।हेडर के साथ सिनात्रा स्ट्रीमिंग प्रतिक्रिया

उदाहरण के लिए, इस प्रतिक्रिया हेडर सेट हो जाएगा नहीं:

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 

उत्तर

3

मैं गलत हो सकता है लेकिन ऐसा लगता है इस बारे में थोड़ा सोच के बाद मेरे लिए 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 

यह क्योंकि अतिरिक्त अनुरोध के आपके उपयोग के मामले के लिए आदर्श नहीं हो सकता है, लेकिन यह काफी छोटा करने के लिए नहीं एक समस्या (देरी) के बहुत हो जाना चाहिए और यह लाभ कहते हैं कि यदि आपका अनुरोध किसी भी डेटा को वापस भेजने से पहले विफल हो जाता है तो आपका ऐप प्रतिक्रिया करने में सक्षम हो सकता है।

उम्मीद है कि यह मदद करता है।

संबंधित मुद्दे