Decompress the gzip data in the HTTP packet from the zlib library
[This blog contains images] (11:27:20)
Reprinted token
Tags:
Zlib
HTTP
Gzip
Extract
It
Classification: Laboratory
When capturing the HTTP packet, it is found that the response packets of many websites are gzip compressed data and stored in one or more chunks (see chunked in the HTTP response packet ). The gzip data is unreadable and needs to be decompressed. At first, I found a copy on the Internet that can run normally.Code, Paste it out:
Http://hi.baidu.com/xzq2000/blog/item/c5429f2fd6a646301f308991.html/cmtid/332e72f08f0b53a2a40f5237
Char * ungzip (char * Source, int Len)
{
Int err;
Z_stream d_stream;
Byte compr [segment_size] = {0}, uncompr [segment_size * 4] = {0 };
Memcpy (compr, (byte *) source, Len );
Ulong comprlen, uncomprlen;
Comprlen = sizeof (compr)/sizeof (compr [0]);
Uncomprlen = 4 * comprlen;
Strcpy (char *) uncompr, "garbage ");
D_stream.zarloc = (alloc_func) 0;
D_stream.zfree = (free_func) 0;
D_stream.opaque = (voidpf) 0;
d_stream.next_in = compr;
d_stream.avail_in = 0;
d_stream.next_out = uncompr;
err = inflateinit2 (& d_stream, 47);
If (Err! = Z_ OK)
{< br> printf ("inflateinit2 error: % d", err);
return NULL;
}< br> while (d_stream.total_out rows = d_stream.avail_out = 1;
err = inflate (& d_stream, z_no_flush);
If (ERR = z_stream_end) break;
If (Err! = Z_ OK)
{< br> printf ("inflate error: % d", err);
return NULL;
}< BR >}< br> err = inflateend (& d_stream);
If (Err! = Z_ OK)
{< br> printf ("inflateend error: % d", err);
return NULL;
}< br> char * B = new char [d_stream.total_out + 1];
memset (B, 0, d_stream.total_out + 1);
memcpy (B, (char *) uncompr, d_stream.total_out);
return B;
}< br> later, I checked zlib usage example (see zlib examples ), after imitating and writing a piece of code, it can run normally and feels faster than the above Code, because the above Code sets z_stream's avail_in and avail_out to 1, it can only be decompressed one byte at a time, which is very slow.
# Include <stdio. h>
# Include <string. h>
# Include <assert. h>
# Include <zlib. h>
# Define segment_size 1460 // largest TCP Data Segment
Int ungzip (char * Source, int Len, char * des)
{
Int ret, have;
Int offset = 0;
Z_stream d_stream;
Byte compr [segment_size] = {0}, uncompr [segment_size * 4] = {0 };
Memcpy (compr, (byte *) source, Len );
Ulong comprlen, uncomprlen;
Comprlen = Len; // It was written as comprlen = sizeof (compr) and comprlen = strlen (compr) at the beginning. later it was found that none of them were correct.
// Sizeof (compr) is always segment_size. Obviously not, strlen (compr) is also incorrect, because strlen is counted only before \ 0,
// But \ 0 is much in gzip or zlib data.
Uncomprlen = segment_size * 4;
Strcpy (char *) uncompr, "garbage ");
D_stream.zarloc = z_null;
D_stream.zfree = z_null;
D_stream.opaque = z_null;
D_stream.next_in = z_null; // both inflateinit and inflateinit2 must initialize next_in and avail_in.
D_stream.avail_in = 0; // deflateinit and deflateinit2 are not required.
Ret = inflateinit2 (& d_stream, 47 );
If (Ret! = Z_ OK)
{
Printf ("inflateinit2 error: % d", RET );
Return ret;
}
D_stream.next_in = compr;
D_stream.avail_in = comprlen;
Do
{
D_stream.next_out = uncompr;
D_stream.avail_out = uncomprlen;
Ret = inflate (& d_stream, z_no_flush );
Assert (Ret! = Z_stream_error );
Switch (RET)
{
Case z_need_dict:
Ret = z_data_error;
Case z_data_error:
Case z_mem_error:
(Void) inflateend (& d_stream );
Return ret;
}
Have = uncomprLen-d_stream.avail_out;
Memcpy (des + offset, uncompr, have); // At the beginning, I wrote memcpy (des + offset, d_stream.next_out, have );
// It was later found that this is incorrect, because next_out points to the next output, and now points to the memory with no meaningful data. See
Offset + = have;
} While (d_stream.avail_out = 0 );
Inflateend (& d_stream );
Memcpy (des + offset, "\ 0", 1 );
Return ret;
}
Decompress the gzip data in the HTTP packet from the zlib library