2008-09-25 11 views
6

के साथ HTTP अनुरोध को संपीड़ित करना मेरे पास एक क्लाइंट/सर्वर सिस्टम है जो HTTP अनुरोधों का उपयोग करके एक्सएमएल का उपयोग करके ट्रांसफर करता है और क्लाइंट के साथ पर्ल के एलडब्लूपी का उपयोग करके प्रतिक्रिया करता है और सर्वर अपाचे के माध्यम से पर्ल के CGI.pm चला रहा है। इसके अलावा स्ट्रीम सर्वर और सभी क्लाइंट दोनों के लिए प्रमाण पत्र के साथ SSL का उपयोग करके एन्क्रिप्ट किया गया है।एलडब्ल्यूपी, अपाचे, और mod_deflate

यह प्रणाली अच्छी तरह से काम करती है, सिवाय इसके कि समय-समय पर क्लाइंट को बड़ी मात्रा में डेटा भेजने की आवश्यकता होती है। एक स्पष्ट समाधान क्लाइंट पक्ष पर डेटा को संपीड़ित करना, इसे भेजना, और सर्वर पर इसे डिकंप्रेस करना होगा। इसे स्वयं लागू करने के बजाय, मैं here वर्णित अपाचे के mod_deflate के "इनपुट डिकंप्रेशन" का उपयोग करने की उम्मीद कर रहा था।

वर्णन चेतावनी देते हैं:

यदि आप अनुरोध शरीर खुद का मूल्यांकन, सामग्री-लंबाई हेडर पर भरोसा नहीं करते! सामग्री-लंबाई शीर्षलेख क्लाइंट से आने वाले डेटा की लंबाई को दर्शाता है, न कि डिकंप्रेस्ड डेटा स्ट्रीम की बाइट गिनती।

तो यदि मैं एक सामग्री-लंबाई मान प्रदान करता हूं जो संपीड़ित डेटा आकार से मेल खाता है, तो डेटा छोटा कर दिया जाता है। ऐसा इसलिए है क्योंकि mod_deflate स्ट्रीम को डिक्रप्रेस करता है, लेकिन CGI.pm केवल सामग्री-लंबाई सीमा को पढ़ता है।

वैकल्पिक रूप से, यदि मैं इसे बाहर निकालने का प्रयास करता हूं और सामग्री-लंबाई शीर्षलेख को डिकंप्रेस्ड डेटा आकार के साथ ओवरराइड करता हूं, तो एलडब्ल्यूपी संकुचित लंबाई में मान को शिकायत करता है और रीसेट करता है, जिससे मुझे एक ही समस्या होती है।

अंत में, मैंने एलडब्लूपी के हिस्से को हैक करने का प्रयास किया जो सुधार करता है। मूल कोड है:

# Set (or override) Content-Length header 
    my $clen = $request_headers->header('Content-Length'); 
    if (defined($$content_ref) && length($$content_ref)) { 
     $has_content = length($$content_ref); 
     if (!defined($clen) || $clen ne $has_content) { 
      if (defined $clen) { 
       warn "Content-Length header value was wrong, fixed"; 
       hlist_remove(\@h, 'Content-Length'); 
      } 
      push(@h, 'Content-Length' => $has_content); 
     } 
    } 
    elsif ($clen) { 
     warn "Content-Length set when there is no content, fixed"; 
     hlist_remove(\@h, 'Content-Length'); 
    } 

और मैं करने के लिए धक्का लाइन बदल:

push(@h, 'Content-Length' => $clen); 

दुर्भाग्य से यह कुछ समस्या जहां सामग्री (छोटा कर दिया है या नहीं) का कारण बनता है यहां तक ​​कि मेरी CGI स्क्रिप्ट को नहीं मिलता है।

क्या किसी ने यह काम किया है? मुझे this मिला जो अपलोड करने से पहले फ़ाइल पर संपीड़न करता है, लेकिन सामान्य अनुरोध को संपीड़ित नहीं करता है।

उत्तर

-1

मुझे यकीन नहीं है कि मैं आपको जो चाहता हूं उसके साथ आपका अनुसरण कर रहा हूं, लेकिन मेरे पास एक कस्टम गेट/पोस्ट मॉड्यूल है, जिसका उपयोग मैं कुछ गैर मानक सामान करने के लिए करता हूं। नीचे कोड पोस्ट, या एसटीडीआईएन के माध्यम से भेजे गए किसी भी चीज़ में पढ़ा जाएगा।

read(STDIN, $query_string, $ENV{'CONTENT_LENGTH'}); 

$ ENV के मूल्य का उपयोग करने के बजाय आपके उपयोग का उपयोग करने के बजाय। मुझे उम्मीद है कि यह मदद करता है, और खेद है अगर यह नहीं करता है।

1

मुझे नहीं लगता कि आप इस तरह की सामग्री-लंबाई बदल सकते हैं। यह अपाचे को भ्रमित करेगा, क्योंकि mod_deflate नहीं जानता कि कितना संकुचित डेटा पढ़ने के लिए। क्लाइंट को एक्स-असंपीड़ित-लंबाई शीर्षलेख जोड़ने के बारे में क्या है, और फिर CGI.pm के एक संशोधित संस्करण का उपयोग करें जो सामग्री-लंबाई के बजाय एक्स-असम्पीडित-लंबाई (यदि मौजूद है) का उपयोग करता है? (दरअसल, आपको शायद CGI.pm को संशोधित करने की आवश्यकता नहीं है। CGI ऑब्जेक्ट को प्रारंभ करने या किसी भी CGI फ़ंक्शंस को कॉल करने से पहले उपयुक्त मान पर $ENV{'CONTENT_LENGTH'} सेट करें।)

या, बाल्टी का उपयोग करने वाले निम्न-स्तर वाले मॉड्यूल का उपयोग करें ब्रिगेड यह बताने के लिए कि कितना डेटा पढ़ना है।

1

यद्यपि आपने कहा था कि आप स्वयं संपीड़न नहीं करना चाहते हैं, ऐसे में कई पेर्ल मॉड्यूल हैं जो आपके लिए दोनों तरफ करेंगे, Compress::Zlib उदाहरण के लिए।

मेरे पास धोखा है (कंपनी के एक .NET भाग के साथ) जहां मैं एक अलग पैरामीटर के रूप में एक्सएमएल पास करता हूं, फिर इसे संभाल सकता है जैसे कि यह एसओएपी जैसी चीजों के साथ फफिंग करने की बजाए स्ट्रिंग था।

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