]>
Commit | Line | Data |
---|---|---|
6d7bab8e | 1 | --- elinks/src/document/session.h Wed May 15 06:40:09 2002 |
2 | +++ elinks_with_gzip/src/document/session.h Mon May 13 13:55:41 2002 | |
3 | @@ -2,6 +2,15 @@ | |
4 | ||
5 | #ifndef EL__DOCUMENT_SESSION_H | |
6 | #define EL__DOCUMENT_SESSION_H | |
7 | +#ifdef HAVE_CONFIG_H | |
8 | +#include "config.h" | |
9 | +#endif | |
10 | +#ifdef HAVE_SSL | |
11 | +#include <openssl/ssl.h> | |
12 | +#endif | |
13 | +#ifdef HAVE_ZLIB_H | |
14 | +#include <zlib.h> | |
15 | +#endif | |
16 | ||
17 | /* We need to declare these first :/. Damn cross-dependencies. */ | |
18 | struct session; | |
19 | --- elinks/src/lowlevel/sched.c Wed May 15 06:40:15 2002 | |
20 | +++ elinks_with_gzip/src/lowlevel/sched.c Mon May 13 21:42:33 2002 | |
21 | @@ -5,10 +5,15 @@ | |
22 | #include "config.h" | |
23 | #endif | |
24 | ||
25 | + | |
26 | #include <string.h> | |
27 | #ifdef HAVE_SSL | |
28 | #include <openssl/ssl.h> | |
29 | #endif | |
30 | +#ifdef HAVE_ZLIB_H | |
31 | +#include <zlib.h> | |
32 | +#endif | |
33 | + | |
34 | #ifdef HAVE_UNISTD_H | |
35 | #include <unistd.h> | |
36 | #endif | |
37 | @@ -391,6 +396,12 @@ | |
38 | { | |
39 | del_from_list(c); | |
40 | send_connection_info(c); | |
41 | +#ifdef HAVE_ZLIB_H | |
42 | + if (c->z) { | |
43 | + inflateEnd(c->z); | |
44 | + mem_free(c->z); | |
45 | + } | |
46 | +#endif | |
47 | mem_free(c->url); | |
48 | mem_free(c); | |
49 | } | |
50 | --- elinks/src/lowlevel/sched.h Wed May 15 06:40:15 2002 | |
51 | +++ elinks_with_gzip/src/lowlevel/sched.h Mon May 13 13:41:12 2002 | |
52 | @@ -2,7 +2,15 @@ | |
53 | ||
54 | #ifndef EL__LOWLEVEL_SCHED_H | |
55 | #define EL__LOWLEVEL_SCHED_H | |
56 | - | |
57 | +#ifdef HAVE_CONFIG_H | |
58 | +#include "config.h" | |
59 | +#endif | |
60 | +#ifdef HAVE_SSL | |
61 | +#include <openssl/ssl.h> | |
62 | +#endif | |
63 | +#ifdef HAVE_ZLIB_H | |
64 | +#include <zlib.h> | |
65 | +#endif | |
66 | #include "links.h" /* tcount, list_head */ | |
67 | #include "document/cache.h" | |
68 | #include "lowlevel/ttime.h" | |
69 | @@ -74,6 +82,10 @@ | |
70 | SSL *ssl; | |
71 | int no_tsl; | |
72 | #endif | |
73 | +#ifdef HAVE_ZLIB_H | |
74 | + int gzip; | |
75 | + z_streamp z; | |
76 | +#endif | |
77 | }; | |
78 | ||
79 | #define S_WAIT 0 | |
80 | --- elinks/src/protocol/http/http.c Wed May 15 06:40:22 2002 | |
81 | +++ elinks_with_gzip/src/protocol/http/http.c Wed May 15 06:32:28 2002 | |
82 | @@ -8,6 +8,9 @@ | |
83 | #ifdef HAVE_SSL | |
84 | #include <openssl/ssl.h> | |
85 | #endif | |
86 | +#ifdef HAVE_ZLIB_H | |
87 | +#include <zlib.h> | |
88 | +#endif | |
89 | #include <stdlib.h> | |
90 | #include <string.h> | |
91 | ||
92 | @@ -29,6 +32,7 @@ | |
93 | #include "protocol/url.h" | |
94 | #include "util/base64.h" | |
95 | #include "util/blacklist.h" | |
96 | +#include "util/compress.h" | |
97 | ||
98 | struct http_connection_info { | |
99 | enum blacklist_flags bl_flags; | |
100 | @@ -121,6 +125,7 @@ | |
101 | #endif | |
102 | } | |
103 | } | |
104 | + | |
105 | if (c->info && !((struct http_connection_info *)c->info)->close | |
106 | #ifdef HAVE_SSL | |
107 | && (!c->ssl) /* We won't keep alive ssl connections */ | |
108 | @@ -401,7 +406,9 @@ | |
109 | } | |
110 | ||
111 | add_to_str(&hdr, &l, "Accept: */*\r\n"); | |
112 | - | |
113 | +#ifdef HAVE_ZLIB_H | |
114 | + add_to_str(&hdr, &l, "Accept-Encoding: gzip\r\n"); | |
115 | +#endif | |
116 | if (!accept_charset) { | |
117 | unsigned char *cs, *ac; | |
118 | int aclen = 0; | |
119 | @@ -558,9 +565,27 @@ | |
120 | int l = rb->len; | |
121 | if (info->length >= 0 && info->length < l) l = info->length; | |
122 | c->received += l; | |
123 | - if (add_fragment(c->cache, c->from, rb->data, l) == 1) c->tries = 0; | |
124 | + if (l) { | |
125 | +#ifdef HAVE_ZLIB_H | |
126 | + if (c->gzip) { | |
127 | + int dl; | |
128 | + unsigned char *data = decompress_gzip(&c->z, rb->data, l, &dl); | |
129 | + if (!data) { | |
130 | + setcstate(c, S_OUT_OF_MEM); | |
131 | + abort_connection(c); | |
132 | + return; | |
133 | + } | |
134 | + if (add_fragment(c->cache, c->from, data, dl) == 1) c->tries = 0; | |
135 | + mem_free(data); | |
136 | + c->from += dl; | |
137 | + } else | |
138 | +#endif | |
139 | + { | |
140 | + if (add_fragment(c->cache, c->from, rb->data, l) == 1) c->tries = 0; | |
141 | + c->from += l; | |
142 | + } | |
143 | + } | |
144 | if (info->length >= 0) info->length -= l; | |
145 | - c->from += l; | |
146 | kill_buffer_data(rb, l); | |
147 | if (!info->length && !rb->close) { | |
148 | setcstate(c, S_OK); | |
149 | @@ -604,9 +629,25 @@ | |
150 | int l = info->chunk_remaining; | |
151 | if (l > rb->len) l = rb->len; | |
152 | c->received += l; | |
153 | - if (add_fragment(c->cache, c->from, rb->data, l) == 1) c->tries = 0; | |
154 | info->chunk_remaining -= l; | |
155 | - c->from += l; | |
156 | +#ifdef HAVE_ZLIB_H | |
157 | + if (c->gzip) { | |
158 | + int dl; | |
159 | + unsigned char *data = decompress_gzip(&c->z, rb->data, l, &dl); | |
160 | + if (!data) { | |
161 | + setcstate(c, S_OUT_OF_MEM); | |
162 | + abort_connection(c); | |
163 | + return; | |
164 | + } | |
165 | + if (add_fragment(c->cache, c->from, data, dl) == 1) c->tries = 0; | |
166 | + mem_free(data); | |
167 | + c->from += dl; | |
168 | + } else | |
169 | +#endif | |
170 | + { | |
171 | + if (add_fragment(c->cache, c->from, rb->data, l) == 1) c->tries = 0; | |
172 | + c->from += l; | |
173 | + } | |
174 | kill_buffer_data(rb, l); | |
175 | if (!info->chunk_remaining && rb->len >= 1) { | |
176 | if (rb->data[0] == 10) kill_buffer_data(rb, 1); | |
36324c2e | 177 | @@ -846,6 +887,20 @@ |
6d7bab8e | 178 | if (!e->last_modified && (d = parse_http_header(e->head, "Date", NULL))) |
179 | e->last_modified = d; | |
180 | if (info->length == -1 || (version < 11 && info->close)) rb->close = 1; | |
181 | +#ifdef HAVE_ZLIB_H | |
182 | + d = parse_http_header(e->head, "Content-Encoding", NULL); | |
183 | + c->gzip = 0; | |
184 | + if (d) { | |
36324c2e | 185 | + if (!strcasecmp(d, "gzip") || !strcasecmp(d, "x-gzip")) { |
186 | + mem_free(d); | |
187 | + d = parse_http_header(e->head, "Content-Type", NULL); | |
188 | + if (d) { | |
189 | + if (!strncasecmp(d, "text", 4)) c->gzip = 1; | |
190 | + mem_free(d); | |
191 | + } | |
192 | + } | |
6d7bab8e | 193 | + } |
194 | +#endif | |
195 | read_http_data(c, rb); | |
196 | } | |
197 | ||
198 | --- elinks/src/util/compress.c Wed May 15 06:40:24 2002 | |
199 | +++ elinks_with_gzip/src/util/compress.c Wed May 15 06:37:29 2002 | |
200 | @@ -23,7 +23,6 @@ | |
201 | #include "util/compress.h" | |
202 | ||
203 | ||
204 | -#if 0 | |
205 | static void * | |
206 | z_mem_alloc(void *opaque, int items, int size) | |
207 | { | |
208 | @@ -35,7 +34,6 @@ | |
209 | { | |
210 | mem_free(address); | |
211 | } | |
212 | -#endif | |
213 | ||
214 | ||
215 | struct decoding_handlers { | |
216 | @@ -111,74 +109,162 @@ | |
217 | gzclose((gzFile *) stream->data); | |
218 | } | |
219 | ||
220 | -#if 0 | |
221 | -static unsigned char * | |
222 | -decompress_gzip(unsigned char *stream, int cur_size, int *new_size) | |
223 | -{ | |
224 | - z_stream z; | |
225 | - char *stream_pos = stream; | |
226 | - char method, flags; | |
227 | - char *output; | |
228 | - int size; | |
229 | - int ret; | |
230 | +struct decoding_handlers gzip_handlers = { | |
231 | + gzip_open, | |
232 | + gzip_read, | |
233 | + gzip_close, | |
234 | +}; | |
235 | ||
236 | - output = mem_alloc(cur_size * 4); | |
237 | - if (!output) return stream; | |
238 | +#define WMAXBITS 15 | |
239 | +#define ASCII_FLAG 0x01 | |
240 | +#define HEAD_CRC 0x02 | |
241 | +#define EXTRA_FIELD 0x04 | |
242 | +#define ORIG_NAME 0x08 | |
243 | +#define COMMENT 0x10 | |
244 | +#define RESERVED 0xE0 | |
245 | ||
246 | - z.opaque = NULL; | |
247 | - z.zalloc = (alloc_func) z_mem_alloc; | |
248 | - z.zfree = z_mem_free; | |
249 | - z.next_in = stream_pos; | |
250 | - z.next_out = output; | |
251 | - z.avail_out = size = cur_size * 4; | |
252 | - z.avail_in = cur_size + 1; | |
253 | +static z_streamp gzip_init(unsigned char *buf_old, int l) { | |
254 | + | |
255 | +/* check header */ | |
256 | +/* gzip magic */ | |
257 | + unsigned char method; | |
258 | + unsigned char flags; | |
259 | + unsigned char *buf = buf_old; | |
260 | + int len; | |
261 | + int ret; | |
262 | + z_streamp z; | |
263 | + | |
264 | + if (buf[0] != 0x1f || buf[1] != 0x8b) return NULL; | |
265 | + | |
266 | + method = buf[2]; | |
267 | + flags = buf[3]; | |
268 | + | |
269 | + if (method != Z_DEFLATED || (flags & RESERVED) != 0) return NULL; | |
270 | ||
271 | - /* XXX: Why -15? --pasky */ | |
272 | - ret = inflateInit2(&z, -15); | |
273 | +/* Comments are borrowed from gzio.c - zlib */ | |
274 | +/* Discard time, xflags and OS code: */ | |
275 | + buf += 10; | |
276 | + l -= 10; | |
277 | + | |
278 | + if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */ | |
279 | + len = 2 + buf[0] + (buf[1] << 8); | |
280 | + buf += len; | |
281 | + l -= len; | |
282 | + } | |
283 | + if (l <= 0) return NULL; | |
284 | + | |
285 | + if ((flags & ORIG_NAME) != 0) {/* skip the original file name */ | |
286 | + len = strlen(buf) + 1; | |
287 | + buf += len; | |
288 | + l -= len; | |
289 | + } | |
290 | + if (l <= 0) return NULL; | |
291 | + | |
292 | + if ((flags & COMMENT) != 0) {/* skip the .gz file comment */ | |
293 | + len = strlen(buf) + 1; | |
294 | + buf += len; | |
295 | + l -= len; | |
296 | + } | |
297 | + if (l <= 0) return NULL; | |
298 | ||
299 | - while (ret == Z_OK) { | |
300 | - char *output_new; | |
301 | + if ((flags & HEAD_CRC) != 0) { /* skip the header crc */ | |
302 | + buf += 2; | |
303 | + l -= 2; | |
304 | + } | |
305 | + if (l <= 0) return NULL; | |
306 | ||
307 | - ret = inflate(&z, Z_SYNC_FLUSH); | |
308 | +/* initialization of z_stream */ | |
309 | + z = (z_streamp)mem_alloc(sizeof(z_stream)); | |
310 | + if (!z) return NULL; | |
311 | + | |
312 | + z->opaque = NULL; | |
313 | + z->zalloc = (alloc_func)z_mem_alloc; | |
314 | + z->zfree = (free_func)z_mem_free; | |
315 | + z->avail_in = l; | |
316 | + z->next_in = buf; | |
317 | +/* windowBits is passed < 0 to tell that there is no zlib header. | |
318 | + * Note that in this case inflate *requires* an extra "dummy" byte | |
319 | + * after the compressed stream in order to complete decompression and | |
320 | + * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are | |
321 | + * present after the compressed stream. | |
322 | + */ | |
323 | + ret = inflateInit2(z, -WMAXBITS); | |
324 | + if (ret == Z_OK) return z; | |
325 | + | |
326 | + mem_free(z); | |
327 | + return NULL; | |
328 | +} | |
329 | ||
330 | - if (ret == Z_STREAM_END) { | |
331 | - mem_free(stream); | |
332 | - *new_size = (int) z.total_out; | |
333 | - output = mem_realloc(output, z.total_out); | |
334 | - inflateEnd(&z); | |
335 | - return output; | |
336 | - } | |
337 | +#define OUTPUT_BUFFER_SIZE 65536 | |
338 | ||
339 | - if (ret != Z_OK) { | |
340 | - inflateEnd(&z); | |
341 | - break; | |
342 | +unsigned char *decompress_gzip(z_streamp *z, unsigned char *buf, int l, int *dl) | |
343 | +{ | |
344 | + unsigned char *output; | |
345 | + int cur_size; | |
346 | + int new_size; | |
347 | + int ret; | |
348 | + | |
349 | + if (!*z) { | |
350 | + *z = gzip_init(buf, l); | |
351 | + if (!*z) { | |
352 | + *dl = -1; | |
353 | + return NULL; | |
354 | } | |
355 | + } | |
356 | + else { | |
357 | + (*z)->next_in = buf; | |
358 | + (*z)->avail_in = l; | |
359 | + } | |
360 | ||
361 | - size += cur_size * 4; | |
362 | - | |
363 | - output_new = mem_realloc(output, size); | |
364 | - if (!output_new) { | |
365 | - mem_free(output); | |
366 | - inflateEnd(&z); | |
367 | - return stream; | |
368 | + (*z)->total_out = 0L; | |
369 | + cur_size = OUTPUT_BUFFER_SIZE; | |
370 | + output = mem_alloc(cur_size); /* output will be freed in http_read_data */ | |
371 | + if (!output) { | |
372 | + inflateEnd(*z); | |
373 | + mem_free(*z); | |
374 | + *z = NULL; | |
375 | + *dl = -2; | |
376 | + return NULL; | |
377 | + } | |
378 | + | |
379 | + (*z)->next_out = output; | |
380 | + (*z)->avail_out = 65536; | |
381 | + | |
382 | + ret = inflate(*z, Z_SYNC_FLUSH); | |
383 | + while (ret == Z_OK) { | |
384 | + if (!(*z)->avail_in) { | |
385 | + *dl = (int)(*z)->total_out; | |
386 | + return output; | |
387 | } | |
388 | - | |
389 | - output = output_new; | |
390 | - z.avail_out += cur_size * 4; | |
391 | - z.next_out = output + z.total_out; | |
392 | + | |
393 | + new_size = cur_size + OUTPUT_BUFFER_SIZE; | |
394 | + output = mem_realloc(output, new_size); | |
395 | + if (!output) { | |
396 | + inflateEnd(*z); | |
397 | + mem_free(*z); | |
398 | + *z = NULL; | |
399 | + *dl = -3; | |
400 | + return NULL; | |
401 | + } | |
402 | + | |
403 | + (*z)->next_out = output + cur_size; /* assume that z->avail_out == 0 */ | |
404 | + (*z)->avail_out = OUTPUT_BUFFER_SIZE; | |
405 | + cur_size = new_size; | |
406 | + ret = inflate(*z, Z_SYNC_FLUSH); | |
407 | } | |
408 | ||
409 | - mem_free(output); | |
410 | + if (ret == Z_STREAM_END) *dl = (int)(*z)->total_out; | |
411 | + else { /* something went wrong */ | |
412 | + *dl = -4; | |
413 | + mem_free(output); | |
414 | + output = NULL; | |
415 | + } | |
416 | ||
417 | - return stream; | |
418 | + inflateEnd(*z); | |
419 | + mem_free(*z); | |
420 | + *z = NULL; | |
421 | + return output; | |
422 | } | |
423 | -#endif | |
424 | - | |
425 | -struct decoding_handlers gzip_handlers = { | |
426 | - gzip_open, | |
427 | - gzip_read, | |
428 | - gzip_close, | |
429 | -}; | |
430 | ||
431 | #endif | |
432 | ||
433 | --- elinks/src/util/compress.h Wed May 15 06:40:24 2002 | |
434 | +++ elinks_with_gzip/src/util/compress.h Wed May 15 01:35:11 2002 | |
435 | @@ -3,6 +3,13 @@ | |
436 | #ifndef EL__UTIL_COMPRESS_H | |
437 | #define EL__UTIL_COMPRESS_H | |
438 | ||
439 | +#ifdef HAVE_CONFIG_H | |
440 | +#include "config.h" | |
441 | +#endif | |
442 | +#ifdef HAVE_ZLIB_H | |
443 | +#include <zlib.h> | |
444 | +#endif | |
445 | + | |
446 | enum stream_encoding { | |
447 | ENCODING_NONE, | |
448 | ENCODING_GZIP, | |
449 | @@ -17,5 +24,8 @@ | |
450 | struct stream_encoded *open_encoded(int, enum stream_encoding); | |
451 | int read_encoded(struct stream_encoded *, unsigned char *, int); | |
452 | void close_encoded(struct stream_encoded *); | |
453 | +#ifdef HAVE_ZLIB_H | |
454 | +unsigned char *decompress_gzip(z_streamp *, unsigned char *, int, int *); | |
455 | +#endif | |
456 | ||
457 | #endif | |
458 |