16. januar 2003 - 03:05
Der er
3 kommentarer og
1 løsning
Komprimering af HTTP-data med zlib?
Jeg søger et fungerende eksempel på hvordan man fra et CGI-program kan generere komprimeret indhold med zlib-funktioner, f.eks. noget i stil med et "Hello world!" CGI-program, blot med den forskel at data skal sendes komprimeret til browseren.
16. januar 2003 - 23:33
#1
OK, efter 1½ døgn og med firkantede øjne har jeg gennem studier af RFC 1951/1952 og utallige eksperimenter fundet ud af det.
Her er et eksempel:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <zlib.h>
#include "template.h"
#define MY_HDR "HTTP/1.1 200 OK\n"\
"Content-Length: %d\n"\
"Content-Type: text/html\n"\
"Content-Encoding: gzip\n"\
"Vary: Accept-Encoding\n\n"
#define PRINT_HDR(len) printf(MY_HDR, len)
inline int gzip_alloc(char **pbuf, int src_len)
{
int buf_len = (int)((double)src_len * 1.001) + 28;
*pbuf = new char[buf_len];
return buf_len;
}
inline void gzip_free(char *pbuf)
{
delete [] pbuf;
}
inline int gzip(char *dst, int *dst_len, const char *src, int src_len)
{
int res = compress2((Bytef*)dst+8, (uLongf*)dst_len, (const Bytef*)src, src_len, 6);
if (res == Z_OK)
{
dst[0] = '\037'; // ID1
dst[1] = '\213'; // ID2
dst[2] = Z_DEFLATED; // CM
dst[3] = 0; // FLAGS
dst[4] = 0; // 4 zeros for MTIME
dst[5] = 0;
dst[6] = 0;
dst[7] = 0;
dst[8] = 0; // XFLAGS
dst[9] = 0x03; // OS
int *trailer = (int*)(dst+4+*dst_len);
trailer[0] = crc32(0, (const Bytef*)src, src_len);
trailer[1] = src_len;
*dst_len += 12;
}
return res;
}
int main(void)
{
const char msg[] = "dong dong dong, 3 gange - sagde dronningen... Jeg siger bare bla bla bla bla bla bla bla bla\n";
char *dst;
int msg_len = strlen(msg);
int dst_len = gzip_alloc(&dst, msg_len);
if (gzip(dst, &dst_len, msg, msg_len) == Z_OK)
{
PRINT_HDR(dst_len);
fflush(stdout);
write(1, dst, dst_len);
}
gzip_free(dst);
return 0;
}