2009-11-23 9 views
7

डब्लूएसजीआई में, पोस्ट डेटा को फाइल-जैसी ऑब्जेक्ट environ['wsgi.input'] पढ़कर उपभोग किया जाता है। यदि स्टैक में दूसरा तत्व भी पोस्ट डेटा पढ़ना चाहता है तो यह पढ़ने के लिए और कुछ भी नहीं होने पर प्रोग्राम को पढ़कर लटका सकता है।यदि मैं POST डेटा को एक से अधिक बार संसाधित करना चाहता हूं तो मैं wsgi.input कैसे कॉपी करूं?

मुझे POST डेटा की प्रतिलिपि कैसे बनाना चाहिए ताकि इसे कई बार संसाधित किया जा सके?

उत्तर

7

गो WebOb पैकेज पर एक नज़र डालें। यह कार्यक्षमता प्रदान करता है जो किसी को यह निर्दिष्ट करने की अनुमति देता है कि wsgi.input को खोजने योग्य बनाया जाना चाहिए। इसका प्रभाव आपको इनपुट स्ट्रीम को रिवाइंड करने की इजाजत देता है जैसे सामग्री को विभिन्न हैंडलर के माध्यम से फिर से चलाया जा सकता है। यहां तक ​​कि यदि आप WebOb का उपयोग नहीं करते हैं, तो यह जिस तरह से करता है वह निर्देशक होना चाहिए क्योंकि इयान पर यह उचित तरीके से किया जाएगा। प्रलेखन में खोज परिणामों के लिए here पर जाएं।

1

यदि आप कर रहे हैं वाला एक ही बार में इसे पढ़ा, तो आप हमेशा यह, में पढ़ सकता है सामान है कि आपने एक CStringIO फ़ाइल जैसी वस्तु बना सकते हैं और फिर इसे वापस असाइन करते हैं, इस तरह:

import cStringIO 
import copy 
lines = [] 
for line in environ['wsgi.input']: 
    lines.append(line) 
newlines = copy.copy(lines) 
environ['wsgi.input'] = cStringIO.StringIO(''.join(newlines)) 

वहाँ सबसे अधिक संभावना यह करने के लिए एक अधिक कुशल तरीका सामान्य खोज WSGI पद सामान में बहुत भंगुर अगर आप कुछ भी गैर तुच्छ (जैसे पद डेटा muptiple बार पढ़ा) क्या करना चाहते है, लेकिन मैं ...

+0

और, bobince _is_ ऐसा करने का अधिक प्रभावी तरीका :) –

+0

wsgi.input पर एक/लूप का उपयोग करना जैसे कि बहुत स्मृति/समय अक्षम हो सकता है। ऐसा इसलिए है क्योंकि यदि सबसे बुरी स्थिति में आपके पास एक बड़ी फ़ाइल थी जहां सभी डेटा खाली लाइनों से युक्त होते हैं, तो आप एक बहुत बड़ी सूची बनाते हैं जहां प्रत्येक प्रविष्टि एक ही वर्ण होता है। यह भी सुनिश्चित नहीं है कि आप copy.copy() से परेशान क्यों हैं, फिर भी आप इसे सीधे एक साथ वापस जोड़ते हैं। –

10

आप कर सकते थे पर्यावरण में वापस स्ट्रीम की फ़ाइल जैसी प्रतिकृति डालने का प्रयास करें:

from cStringIO import StringIO 

length = int(environ.get('CONTENT_LENGTH', '0')) 
body = StringIO(environ['wsgi.input'].read(length)) 
environ['wsgi.input'] = body 

ऐसा करने की आवश्यकता कुछ गंध है, हालांकि। आदर्श रूप से कोड का केवल एक टुकड़ा क्वेरी स्ट्रिंग और पोस्ट बॉडी को पार्स करना और अन्य घटकों को परिणाम देना चाहिए।

+0

आपको डिफ़ॉल्ट सामग्री लंबाई -1 तक सक्षम होने पर भरोसा नहीं करना चाहिए। डब्लूएसजीआई विनिर्देश में कुछ भी नहीं है जो कहता है कि कार्यान्वयन को सभी इनपुट को पढ़ने के लिए पढ़ने के लिए तर्क() को तर्क के रूप में स्वीकार करना चाहिए। एक कार्यान्वयन उस परिस्थिति में अपवाद बढ़ाने का फैसला कर सकता है। असल में विनिर्देश शायद यह भी कहता है कि यदि CONTENT_LENGTH मौजूद नहीं है या खाली है, तो इसका अर्थ '0', या इनपुट उपलब्ध नहीं होना चाहिए। –

+0

आह ये ... मुझे यकीन नहीं है कि मैंने इसे क्यों रखा है, मेरा अपना वास्तविक कोड 0 :-) का उपयोग करता है, हालांकि, इस व्यवहार को डब्लूएसजीआई में बदलने का आपका इरादा है, है ना? – bobince

+0

मुझे कुछ हद तक संदेह है कि डब्लूएसजीआई में अब कोई बदलाव दिखाई देगा। –

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

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