Click to See Complete Forum and Search --> : how corectly unzip GZipStream


IICuX
February 16th, 2010, 02:37 PM
hi all, i have trouble with my application, i writen my personal cache using sockets and streams, but i have big trouble with unpack GZip, this string int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length); is trouble, when i try read from stream, i have an Exception, that the GZip header magic number is not corrent. InvalidDataException. here is my code...


public long WriteURL()
{
long num1 = 0;
string host = new Uri(_url).Host;
IPHostEntry ipAddress = Dns.GetHostEntry(host);
IPEndPoint ip = new IPEndPoint(ipAddress.AddressList[0], 80);
using (Socket s = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
s.Connect(ip);
using (NetworkStream n = new NetworkStream(s))
{
if (HttpRequestType == "POST")
{
//
}
bool saveItAtCache = false;
bool existsAtCache = false;
byte[] cachedFile = null;
string ext = Path.GetExtension(_url).ToLower();
if (!_url.Contains(".php") && ".gif.jpg.swf.js.css.png.html".IndexOf(ext) != -1 && ext != "")
{
saveItAtCache = true;
cachedFile = cache.GetFile(_url);
existsAtCache = (cachedFile != null);
}
if (existsAtCache)
{
writeSuccess(cachedFile.Length, null);
socket.Send(cachedFile);
}
else
{
SendRequest(n, new[] { HttpQuery });
Dictionary<string, string> headers = new Dictionary<string, string>();
while (true)
{
string line = ReadLine(n);
if (Equals(line.Length, 0))
{
break;
}
int index = line.IndexOf(':');
if (!headers.ContainsKey(line.Substring(0, index)))
{
headers.Add(line.Substring(0, index), line.Substring(index + 2));
}
}
string str = "";
string contentEncoding;
if (headers.TryGetValue("Content-Encoding", out contentEncoding))
{
Stream responseStream = n;
if (contentEncoding.Equals("gzip"))
{
responseStream = new GZipStream(responseStream, CompressionMode.Decompress, true);
}
else if (contentEncoding.Equals("deflate"))
{
responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
}

var memStream = new MemoryStream();

var respBuffer = new byte[4096];
try
{
int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
while (bytesRead > 0)
{
memStream.Write(respBuffer, 0, bytesRead);
bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
}
}
finally
{
responseStream.Close();
}
str = encoding.GetString(memStream.ToArray());
ManageCookies(_headers["Set-Cookie"], _headers["Host"]);
cachedFile = encoding.GetBytes(str);
if (saveItAtCache)
{
cache.Store(_url, cachedFile);
}
num1 = str.Length;
}
else
{
while (true)
{
string line = ReadLine(n);
if (line == null)
{
str.Remove(str.Length - 1, 1);
break;
}
num1 += line.Length;
str += line;
}
}
ManageCookies(_headers["Set-Cookie"], _headers["Host"]);
byte[] buffer3 = encoding.GetBytes(str);
writeSuccess(buffer3.Length, _headers["Set-Cookie"]);
socket.Send(buffer3);
}
}
}

return num1;
}

void SendRequest(Stream stream, IEnumerable<string> request)
{
if (request != null)
{
foreach (var r in request)
{
byte[] data = encoding.GetBytes(r);
stream.Write(data, 0, data.Length);
stream.Write(LineTerminator, 0, 2);
}
stream.Write(LineTerminator, 0, 2);
// Eat response
string response = ReadLine(stream);
Console.WriteLine(response);
}
}

string ReadLine(Stream stream)
{
List<byte> lineBuffer = new List<byte>();
while (true)
{
try
{
int b = stream.ReadByte();
if (b == -1)
{
return null;
}
if (b == 10)
break;
if (b!=13)
lineBuffer.Add((byte)b);
}
catch (Exception)
{
return null;
}
}
return encoding.GetString(lineBuffer.ToArray());
}

memeloo
February 16th, 2010, 02:40 PM
you've forgotten the code tags... I'm not going to read it.

Kakoon
February 16th, 2010, 04:19 PM
Using zlib, I wrote the following code to decompress a gzip compressed byte[] array msgData. Used it for my soulseek client, worked great. Maybe it's of use for you. You can google zlib i assume.

public bool decompress()
{
System.IO.MemoryStream instream = new System.IO.MemoryStream(msgData);
System.IO.MemoryStream outstream = new System.IO.MemoryStream();
zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outstream);

try
{
CopyStream(instream, outZStream);
}
catch (Exception e)
{
return false;
}
finally
{
instream.Close();
}

if (outstream.Length > 0)
{
outstream.Position = 0;
BinaryReader reader = new BinaryReader(outstream);
msgData = reader.ReadBytes((int)outstream.Length);
return true;
}
return false;
}

public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
{
byte[] buffer = new byte[2000];
int len;
while ((len = input.Read(buffer, 0, 2000)) > 0)
{
output.Write(buffer, 0, len);
}
output.Flush();
}

rliq
February 16th, 2010, 06:26 PM
So , do you still have a problem?

IICuX
February 17th, 2010, 04:06 AM
Using zlib, I wrote the following code to decompress a gzip compressed byte[] array msgData. Used it for my soulseek client, worked great. Maybe it's of use for you. You can google zlib i assume.

public bool decompress()
{
System.IO.MemoryStream instream = new System.IO.MemoryStream(msgData);
System.IO.MemoryStream outstream = new System.IO.MemoryStream();
zlib.ZOutputStream outZStream = new zlib.ZOutputStream(outstream);

try
{
CopyStream(instream, outZStream);
}
catch (Exception e)
{
return false;
}
finally
{
instream.Close();
}

if (outstream.Length > 0)
{
outstream.Position = 0;
BinaryReader reader = new BinaryReader(outstream);
msgData = reader.ReadBytes((int)outstream.Length);
return true;
}
return false;
}

public static void CopyStream(System.IO.Stream input, System.IO.Stream output)
{
byte[] buffer = new byte[2000];
int len;
while ((len = input.Read(buffer, 0, 2000)) > 0)
{
output.Write(buffer, 0, len);
}
output.Flush();
}

This method maybe true, but i have exception: inflating: unknown compression method

IICuX
February 17th, 2010, 04:08 AM
So , do you still have a problem?

Yes, I stiil still have problem with this...any ideas?

memeloo
February 17th, 2010, 09:54 AM
Yes, I stiil still have problem with this...any ideas?
what problem exacly? still the InvalidDataException or something new now?

I wanted to help but apparently you won't me/us to help you... I told you that I won't read your post until you edit it and add the code tags. and I'm not sure whether I'm still willing.

IICuX
February 17th, 2010, 09:57 AM
what problem exacly? still the InvalidDataException or something new now?

I wanted to help but apparently you won't me/us to help you... I told you that I won't read your post until you edit it and add the code tags. and I'm not sure whether I'm still willing.

I have problem, writen by me in subj, InvalidDataException....

IICuX
February 17th, 2010, 12:35 PM
public long WriteURL()
{
long num1 = 0;
string host = new Uri(_url).Host;
IPHostEntry ipAddress = Dns.GetHostEntry(host);
IPEndPoint ip = new IPEndPoint(ipAddress.AddressList[0], 80);
using (Socket s = new Socket(ip.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
{
s.Connect(ip);
using (NetworkStream n = new NetworkStream(s))
{
if (HttpRequestType == "POST")
{
//
}
bool saveItAtCache = false;
bool existsAtCache = false;
byte[] cachedFile = null;
string ext = Path.GetExtension(_url).ToLower();
if (!_url.Contains(".php") && ".gif.jpg.swf.js.css.png.html".IndexOf(ext) != -1 && ext != "")
{
saveItAtCache = true;
cachedFile = cache.GetFile(_url);
existsAtCache = (cachedFile != null);
}
if (existsAtCache)
{
writeSuccess(cachedFile.Length, null);
socket.Send(cachedFile);
}
else
{
SendRequest(n, new[] { HttpQuery });
Dictionary<string, string> headers = new Dictionary<string, string>();
while (true)
{
string line = ReadLine(n);
if (Equals(line.Length, 0))
{
break;
}
int index = line.IndexOf(':');
if (!headers.ContainsKey(line.Substring(0, index)))
{
headers.Add(line.Substring(0, index), line.Substring(index + 2));
}
}
string str = "";
string contentEncoding;
if (headers.TryGetValue("Content-Encoding", out contentEncoding))
{
Stream responseStream = n;
if (contentEncoding.Equals("gzip"))
{
responseStream = new GZipStream(responseStream, CompressionMode.Decompress, true);
}
else if (contentEncoding.Equals("deflate"))
{
responseStream = new DeflateStream(responseStream, CompressionMode.Decompress);
}

var memStream = new MemoryStream();

var respBuffer = new byte[4096];
try
{
int bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
while (bytesRead > 0)
{
memStream.Write(respBuffer, 0, bytesRead);
bytesRead = responseStream.Read(respBuffer, 0, respBuffer.Length);
}
}
finally
{
responseStream.Close();
}
str = encoding.GetString(memStream.ToArray());
ManageCookies(_headers["Set-Cookie"], _headers["Host"]);
cachedFile = encoding.GetBytes(str);
if (saveItAtCache)
{
cache.Store(_url, cachedFile);
}
num1 = str.Length;
}
else
{
while (true)
{
string line = ReadLine(n);
if (line == null)
{
str.Remove(str.Length - 1, 1);
break;
}
num1 += line.Length;
str += line;
}
}
ManageCookies(_headers["Set-Cookie"], _headers["Host"]);
byte[] buffer3 = encoding.GetBytes(str);
writeSuccess(buffer3.Length, _headers["Set-Cookie"]);
socket.Send(buffer3);
}
}
}

return num1;
}

void SendRequest(Stream stream, IEnumerable<string> request)
{
if (request != null)
{
foreach (var r in request)
{
byte[] data = encoding.GetBytes(r);
stream.Write(data, 0, data.Length);
stream.Write(LineTerminator, 0, 2);
}
stream.Write(LineTerminator, 0, 2);
// Eat response
string response = ReadLine(stream);
Console.WriteLine(response);
}
}

string ReadLine(Stream stream)
{
List<byte> lineBuffer = new List<byte>();
while (true)
{
try
{
int b = stream.ReadByte();
if (b == -1)
{
return null;
}
if (b == 10)
break;
if (b!=13)
lineBuffer.Add((byte)b);
}
catch (Exception)
{
return null;
}
}
return encoding.GetString(lineBuffer.ToArray());
}

memeloo
February 17th, 2010, 01:05 PM
I can't see anything strange in your code. is the stream that you try to decompress really a stream compressed with gzipstream and not a zip file? because gzipstream does not support multiple files.

IICuX
February 17th, 2010, 01:45 PM
i have exists code but using HttpWebResponse and WebRequest, there is all good unpack and decompress, with any extenitions, but using sockets and NetworkStream i can't get Response data...

IICuX
February 17th, 2010, 04:58 PM
any can help me ?

memeloo
February 17th, 2010, 11:03 PM
any can help me ?
do you think we're some kind of answering machines? :mad: there is no rule that anyone have to give you an answer within 5minutes. be patient and kind!

I suggest you save the source gzipstream into a file on the server as a copy then save the received stream on the client side into another file wihtout decompressing it and check if they are the same.

IICuX
February 18th, 2010, 09:30 AM
do you think we're some kind of answering machines? :mad: there is no rule that anyone have to give you an answer within 5minutes. be patient and kind!

I suggest you save the source gzipstream into a file on the server as a copy then save the received stream on the client side into another file wihtout decompressing it and check if they are the same.

I don't have acces to server, i must do this without server, only client side

IICuX
February 19th, 2010, 05:30 PM
any ideas?