2011-09-15 15 views
5

मैं अपने स्वयं के http सर्वर (मैं आईआईएस का उपयोग नहीं करता) के लिए एचटीपी लिस्टनर का उपयोग करता हूं। मैं gzip संपीड़न के आधार पर अपना OutputStream सेक करना चाहते हैं:सी # एचटीपी लिस्टनर प्रतिक्रिया + जीजेपीस्ट्रीम

byte[] refBuffer = Encoding.UTF8.GetBytes(...some data source...); 

var varByteStream = new MemoryStream(refBuffer); 

System.IO.Compression.GZipStream refGZipStream = new GZipStream(varByteStream, CompressionMode.Compress, false); 

refGZipStream.BaseStream.CopyTo(refHttpListenerContext.Response.OutputStream); 

refHttpListenerContext.Response.AddHeader("Content-Encoding", "gzip"); 

लेकिन मैं क्रोम में त्रुटि मिल रही है:

ERR_CONTENT_DECODING_FAILED

अगर मैं AddHeader निकालें, तब यह काम करता है, लेकिन के आकार प्रतिक्रिया संपीड़ित नहीं लग रहा है। मैं क्या गलत कर रहा हूं?

+0

हेडर की वजह से कुछ संपीड़ित नहीं होना असंभव है, यह देखते हुए कि आप वास्तव में संपीड़ित सामग्री को स्पष्ट रूप से लिख रहे हैं। क्या आप वाकई क्रोम को फाइल के * डिकंप्रेस्ड * आकार नहीं दे रहे हैं? – Ryan

+0

@minitech, अच्छे प्रश्न !!! मैं यातायात के वास्तविक आकार की जांच करने की कोशिश कर रहा हूँ। – Edward83

उत्तर

9

समस्या यह है कि आपका स्थानांतरण गलत दिशा में जा रहा है। क्या आप क्या करना चाहते Response.OutputStream को GZipStream देते हैं और फिर MemoryStream पर CopyTo फोन, GZipStream में गुजर, इसलिए की तरह है:

refHttpListenerContext.Response.AddHeader("Content-Encoding", "gzip"); 

byte[] refBuffer = Encoding.UTF8.GetBytes(...some data source...); 

var varByteStream = new MemoryStream(refBuffer); 

System.IO.Compression.GZipStream refGZipStream = new GZipStream(refHttpListenerContext.Response.OutputStream, CompressionMode.Compress, false); 

varByteStream.CopyTo(refGZipStream); 
refGZipStream.Flush(); 
4

पहली समस्या (के रूप में ब्रेंट एम वर्तनी ने उल्लेख किया) शीर्षक के गलत स्थिति है। दूसरा यह है कि आप ठीक से GZipStream का उपयोग नहीं करते हैं। इस स्ट्रीम को लिखने के लिए "शीर्ष" स्ट्रीम की आवश्यकता होती है, जिसका अर्थ है एक खाली स्ट्रीम (आप इसे अपने बफर से भरें)। खाली "शीर्ष" स्ट्रीम होने के बाद आपको बस अपने बफर GZipStream पर लिखना है। नतीजतन स्मृति स्ट्रीम संपीड़ित सामग्री से भरा जाएगा। तो आपको कुछ चाहिए:

byte[] buffer = ....; 

using (var ms = new MemoryStream()) 
{ 
    using (var zip = new GZipStream(ms, CompressionMode.Compress, true)) 
    zip.Write(buffer, 0, buffer.Length); 
    buffer = ms.ToArray(); 
} 

response.AddHeader("Content-Encoding", "gzip"); 
response.ContentLength64 = buffer.Length; 

response.OutputStream.Write(buffer, 0, buffer.Length);