2008-09-25 42 views
6

我有一個客戶端/服務器系統,使用通過Apache使用Perl的LWP和運行Perl的CGI.pm的服務器使用HTTP請求和客戶端響應來執行通信。此外,使用SSL爲服務器和所有客戶端使用證書對流進行加密。使用LWP,Apache和mod_deflate壓縮HTTP請求

除了客戶端需要定期發送大量數據外,該系統運行良好。一個明顯的解決方案是壓縮客戶端的數據,發送並在服務器上解壓。我不是自己實現這個,而是希望使用Apache的mod_deflate的「輸入解壓縮」,如here所述。

說明警告:

如果自己評估請求主體,不信任的Content-Length頭! Content-Length標題反映了來自客戶端的傳入數據的長度,而不是解壓縮數據流的字節數。

因此,如果我提供與壓縮數據大小相匹配的Content-Length值,則會截斷數據。這是因爲mod_deflate解壓縮流,但CGI.pm只讀取Content-Length限制。或者,如果我試圖超越它並且用解壓縮的數據大小覆蓋Content-Length頭部,LWP會抱怨並將值重置爲壓縮長度,這使我面臨同樣的問題。

最後,我試圖破解修正的LWP的一部分。原來的代碼是:

# 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

我不知道我是否跟着你想要什麼,但我有一個自定義的get/post模塊,我用它來做一些非標準的東西。下面的代碼將讀取通過郵件或STDIN發送的任何內容。

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

而不是使用$ ENV的值使用你的。我希望這會有所幫助,如果沒有,我會很抱歉。

1

我不認爲你可以像這樣改變Content-Length。這會混淆Apache,因爲mod_deflate不知道要讀取多少壓縮數據。如何讓客戶端添加一個X-Uncompressed-Length頭,然後使用修改後的CGI.pm版本,該版本使用X-Uncompressed-Length(如果存在)而不是Content-Length? (實際上,您可能不需要修改CGI.pm.只需在初始化CGI對象或調用任何CGI函數之前將$ENV{'CONTENT_LENGTH'}設置爲適當的值。)

或者,使用使用存儲桶的低級模塊旅告訴讀多少數據。

1

雖然你說你不想自己做壓縮,但有很多perl模塊可以爲你做雙方,例如Compress::Zlib

我有一個作弊(與公司的.net部分),我作爲一個單獨的參數傳遞XML作爲一個單獨的參數,然後可以處理它,就像它是一個字符串,而不是像SOAP的東西一樣氾濫。