2010-04-12 17 views
5

मैं किसी प्रकार का प्रॉक्सी बना रहा हूं।
जब मैं रैक एप्लिकेशन में कुछ यूआरएल कॉल करता हूं, तो मैं उस अनुरोध को किसी अन्य यूआरएल पर अग्रेषित करता हूं।body_stream और पैरामीटर के साथ पोस्ट अनुरोध

मैं जो अनुरोध अग्रेषित करता हूं वह एक फ़ाइल और कुछ पैरामीटर के साथ एक पोस्ट है।
मैं और पैरामीटर जोड़ना चाहता हूं।
लेकिन फ़ाइल काफी बड़ी हो सकती है। तो मैं इसे Net::HTTP#body के बजाय Net::HTTP#body_stream के साथ भेजता हूं।

मुझे Rack::Request ऑब्जेक्ट के रूप में मेरा अनुरोध मिलता है और मैं इसके साथ अपना नेट :: HTTP ऑब्जेक्ट बना देता हूं।

req = Net::HTTP::Post.new(request.path_info) 
req.body_stream = request.body 
req.content_type = request.content_type 
req.content_length = request.content_length 

http = Net::HTTP.new(@host, @port) 
res = http.request(req) 

मैंने प्रॉक्सी के पैरामीटर जोड़ने के कई तरीकों की कोशिश की है। लेकिन ऐसा लगता है कि नेट :: HTTP में कुछ भी बॉडी_स्ट्रीम अनुरोध में पैरामीटर जोड़ने की अनुमति देता है, केवल एक शरीर के लिए।

क्या इस तरह के रैक अनुरोध को प्रॉक्सी करने का कोई आसान तरीका है? या मेरे अनुरोध में मेरे पैरामीटर जोड़ने का एक साफ तरीका?

+0

'req.set_form_data (: कुछ => 'डेटा') क्यों काम नहीं करेगा? – mikezter

+0

क्योंकि यह '# body' को परिभाषित करता है और' body_stream' रीसेट करता है, इसलिए मैं पहले से परिभाषित डेटा खो देता हूं। –

उत्तर

3

अच्छा .. जैसा कि मैंने इसे देखा, यह एक सामान्य व्यवहार है। मैं समझाऊंगा क्यों। यदि आपके पास केवल रैक :: अनुरोध तक पहुंच है, (मुझे लगता है कि) आपका मिडलवेयर प्रतिक्रिया का विश्लेषण नहीं करता है (आप एक्शन कंट्रोलर :: पैराम्सपार्सर) जैसे कुछ शामिल नहीं करते हैं, इसलिए आपके पास हैश की पहुंच नहीं है पैरामीटर, लेकिन एक स्ट्रिंगआईओ के लिए। यह StringIO एक धारा like से मेल खाती है:

Content-Type: multipart/form-data; boundary=AaB03x 
--AaB03x 
Content-Disposition: form-data; name="param1" 
value1 
--AaB03x 
Content-Disposition: form-data; name="files"; filename="file1.txt" 
Content-Type: text/plain 
... contents of file1.txt ... 
--AaB03x-- 

क्या आप Net :: HTTP वर्ग के साथ क्या करने की कोशिश कर रहे हैं करने के लिए है: (1)। पैरामीटर के हैश में अनुरोध पार्स; (2)। अपने पैरामीटर के साथ पैरामीटर हैश मर्ज करें; (3)। अनुरोध दोबारा बनाएं। समस्या यह है कि नेट :: HTTP लाइब्रेरी (1) नहीं कर सकती है, क्योंकि यह क्लाइंट लाइब्रेरी है, सर्वर नहीं।

इसलिए, आप नए पैरामीटर जोड़ने से पहले आपके अनुरोध को पार्सिंग से बच नहीं सकते हैं।

संभावित समाधान:

  1. सम्मिलित ActionController :: अपने मिडलवेयर से पहले ParamsParser।

    RestClient.post ('' + request.path_info),: उसके बाद, आप की तरह कुछ करने के लिए उत्कृष्ट rest-client lib का उपयोग कर सकते पैरामीटर => params.merge (your_params)

  2. आप प्रयास कर सकते हैं स्ट्रिंगियो ऑब्जेक्ट पर एक रैपर बनाने के लिए, और स्ट्रीम के अंत में, अपने स्वयं के पैरामीटर जोड़ें। हालांकि, यह मामूली और सलाह नहीं है।

+0

हाँ मैंने दूसरे को हटा दिया। मैं पहले कोशिश करूंगा। धन्यवाद :) –

+0

आपका स्वागत है :) हालांकि, अनुरोध को इस तरह से पार्स करके, आपको प्रॉक्सी सर्वर पर पूरी सामग्री अपलोड करने की प्रतीक्षा करनी होगी। इसलिए, कुल_टाइम> time_to_upload_to_proxy + time_to_upload_to_real_server। –

0

एक साल बहुत देर हो सकती है, लेकिन मेरे पास पेपैल आईपीएन की पुष्टि करने वाला एक ही मुद्दा था। मैं सत्यापन के लिए पेपैल को आईपीएन अनुरोध वापस भेजना चाहता था लेकिन जोड़ने के लिए आवश्यक: cmd => '_notify-validate'।

इसके बजाय शरीर धारा, या शरीर को संशोधित करने की, मैं, URL पथ के भाग के रूप में यह संलग्न इसलिए की तरह:

reply_request = Net::HTTP::Post.new(url.path + '?cmd=_notify-validate') 

यह एक हैक का एक सा लगता है, लेकिन मुझे लगता है इसके लायक अगर आप है किसी और चीज के लिए इसका इस्तेमाल नहीं कर रहे हैं।

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