82
83
#define DEFAULT_MEMLEVEL 9
83
84
#define DEFAULT_BUFFERSIZE 8096
87
/* Check whether a request is gzipped, so we can un-gzip it.
88
* If a request has multiple encodings, we need the gzip
89
* to be the outermost non-identity encoding.
91
static int check_gzip(request_rec *r, apr_table_t *hdrs1, apr_table_t *hdrs2)
94
apr_table_t *hdrs = hdrs1;
95
const char *encoding = apr_table_get(hdrs, "Content-Encoding");
97
if (!encoding && (hdrs2 != NULL)) {
98
/* the output filter has two tables and a content_encoding to check */
99
encoding = apr_table_get(hdrs2, "Content-Encoding");
102
encoding = r->content_encoding;
106
if (encoding && *encoding) {
108
/* check the usual/simple case first */
109
if (!strcasecmp(encoding, "gzip")
110
|| !strcasecmp(encoding, "x-gzip")) {
113
apr_table_unset(hdrs, "Content-Encoding");
116
r->content_encoding = NULL;
119
else if (ap_strchr_c(encoding, ',') != NULL) {
120
/* If the outermost encoding isn't gzip, there's nowt
121
* we can do. So only check the last non-identity token
123
char *new_encoding = apr_pstrdup(r->pool, encoding);
126
char *token = ap_strrchr(new_encoding, ',');
127
if (!token) { /* gzip:identity or other:identity */
128
if (!strcasecmp(new_encoding, "gzip")
129
|| !strcasecmp(new_encoding, "x-gzip")) {
132
apr_table_unset(hdrs, "Content-Encoding");
135
r->content_encoding = NULL;
138
break; /* seen all tokens */
140
for (ptr=token+1; apr_isspace(*ptr); ++ptr);
141
if (!strcasecmp(ptr, "gzip")
142
|| !strcasecmp(ptr, "x-gzip")) {
145
apr_table_setn(hdrs, "Content-Encoding", new_encoding);
148
r->content_encoding = new_encoding;
152
else if (!ptr[0] || !strcasecmp(ptr, "identity")) {
154
continue; /* strip the token and find the next one */
156
break; /* found a non-identity token */
85
163
/* Outputs a long in LSB order to the given file
86
164
* only the bottom 4 bits are required for the deflate file format.
212
290
unsigned char *buffer;
213
291
unsigned long crc;
214
292
apr_bucket_brigade *bb, *proc_bb;
293
int (*libz_end_func)(z_streamp);
294
unsigned char *validation_buffer;
295
apr_size_t validation_buffer_length;
299
/* Number of validation bytes (CRC and length) after the compressed data */
300
#define VALIDATION_SIZE 8
301
/* Do not update ctx->crc, see comment in flush_libz_buffer */
302
#define NO_UPDATE_CRC 0
303
/* Do update ctx->crc, see comment in flush_libz_buffer */
306
static int flush_libz_buffer(deflate_ctx *ctx, deflate_filter_config *c,
307
struct apr_bucket_alloc_t *bucket_alloc,
308
int (*libz_func)(z_streamp, int), int flush,
313
unsigned int deflate_len;
317
deflate_len = c->bufferSize - ctx->stream.avail_out;
319
if (deflate_len != 0) {
321
* Do we need to update ctx->crc? Usually this is the case for
322
* inflate action where we need to do a crc on the output, whereas
323
* in the deflate case we need to do a crc on the input
326
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer,
329
b = apr_bucket_heap_create((char *)ctx->buffer,
332
APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
333
ctx->stream.next_out = ctx->buffer;
334
ctx->stream.avail_out = c->bufferSize;
340
zRC = libz_func(&ctx->stream, flush);
343
* We can ignore Z_BUF_ERROR because:
344
* When we call libz_func we can assume that
346
* - avail_in is zero (due to the surrounding code that calls
348
* - avail_out is non zero due to our actions some lines above
350
* So the only reason for Z_BUF_ERROR is that the internal libz
351
* buffers are now empty and thus we called libz_func one time
352
* too often. This does not hurt. It simply says that we are done.
354
if (zRC == Z_BUF_ERROR) {
359
done = (ctx->stream.avail_out != 0 || zRC == Z_STREAM_END);
361
if (zRC != Z_OK && zRC != Z_STREAM_END)
367
static apr_status_t deflate_ctx_cleanup(void *data)
369
deflate_ctx *ctx = (deflate_ctx *)data;
372
ctx->libz_end_func(&ctx->stream);
375
/* PR 39727: we're screwing up our clients if we leave a strong ETag
376
* header while transforming content. Henrik Nordstrom suggests
379
* Pending a more thorough review of our Etag handling, let's just
380
* implement his suggestion. It fixes the bug, or at least turns it
381
* from a showstopper to an inefficiency. And it breaks nothing that
382
* wasn't already broken.
384
static void deflate_check_etag(request_rec *r, const char *transform)
386
const char *etag = apr_table_get(r->headers_out, "ETag");
387
if (etag && (((etag[0] != 'W') && (etag[0] !='w')) || (etag[1] != '/'))) {
388
apr_table_set(r->headers_out, "ETag",
389
apr_pstrcat(r->pool, etag, "-", transform, NULL));
217
392
static apr_status_t deflate_out_filter(ap_filter_t *f,
218
393
apr_bucket_brigade *bb)
362
545
ctx = f->ctx = apr_pcalloc(r->pool, sizeof(*ctx));
363
546
ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);
364
547
ctx->buffer = apr_palloc(r->pool, c->bufferSize);
548
ctx->libz_end_func = deflateEnd;
366
550
zRC = deflateInit2(&ctx->stream, c->compressionlevel, Z_DEFLATED,
367
551
c->windowSize, c->memlevel,
368
552
Z_DEFAULT_STRATEGY);
370
554
if (zRC != Z_OK) {
555
deflateEnd(&ctx->stream);
372
556
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
373
557
"unable to init Zlib: "
374
558
"deflateInit2 returned %d: URL %s",
561
* Remove ourselves as it does not make sense to return:
562
* We are not able to init libz and pass data down the chain
565
ap_remove_output_filter(f);
376
566
return ap_pass_brigade(f->next, bb);
569
* Register a cleanup function to ensure that we cleanup the internal
572
apr_pool_cleanup_register(r->pool, ctx, deflate_ctx_cleanup,
573
apr_pool_cleanup_null);
379
575
/* add immortal gzip header */
380
576
e = apr_bucket_immortal_create(gzip_header, sizeof gzip_header,
400
598
const char *data;
405
602
e = APR_BRIGADE_FIRST(bb);
407
604
if (APR_BUCKET_IS_EOS(e)) {
409
unsigned int deflate_len;
411
607
ctx->stream.avail_in = 0; /* should be zero already anyway */
413
deflate_len = c->bufferSize - ctx->stream.avail_out;
415
if (deflate_len != 0) {
416
b = apr_bucket_heap_create((char *)ctx->buffer,
419
APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
420
ctx->stream.next_out = ctx->buffer;
421
ctx->stream.avail_out = c->bufferSize;
428
zRC = deflate(&ctx->stream, Z_FINISH);
430
if (deflate_len == 0 && zRC == Z_BUF_ERROR) {
434
done = (ctx->stream.avail_out != 0 || zRC == Z_STREAM_END);
436
if (zRC != Z_OK && zRC != Z_STREAM_END) {
441
buf = apr_palloc(r->pool, 8);
608
/* flush the remaining data from the zlib buffers */
609
flush_libz_buffer(ctx, c, f->c->bucket_alloc, deflate, Z_FINISH,
612
buf = apr_palloc(r->pool, VALIDATION_SIZE);
442
613
putLong((unsigned char *)&buf[0], ctx->crc);
443
614
putLong((unsigned char *)&buf[4], ctx->stream.total_in);
445
b = apr_bucket_pool_create(buf, 8, r->pool, f->c->bucket_alloc);
616
b = apr_bucket_pool_create(buf, VALIDATION_SIZE, r->pool,
446
618
APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
447
619
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
448
620
"Zlib: Compressed %ld to %ld : URL %s",
490
664
if (APR_BUCKET_IS_FLUSH(e)) {
494
apr_bucket_delete(e);
496
if (ctx->stream.avail_in > 0) {
497
zRC = deflate(&(ctx->stream), Z_SYNC_FLUSH);
667
/* flush the remaining data from the zlib buffers */
668
zRC = flush_libz_buffer(ctx, c, f->c->bucket_alloc, deflate,
669
Z_SYNC_FLUSH, NO_UPDATE_CRC);
503
ctx->stream.next_out = ctx->buffer;
504
len = c->bufferSize - ctx->stream.avail_out;
506
b = apr_bucket_heap_create((char *)ctx->buffer, len,
507
NULL, f->c->bucket_alloc);
508
APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
509
ctx->stream.avail_out = c->bufferSize;
511
bkt = apr_bucket_flush_create(f->c->bucket_alloc);
512
APR_BRIGADE_INSERT_TAIL(ctx->bb, bkt);
674
/* Remove flush bucket from old brigade anf insert into the new. */
675
APR_BUCKET_REMOVE(e);
676
APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
513
677
rv = ap_pass_brigade(f->next, ctx->bb);
514
678
if (rv != APR_SUCCESS) {
593
766
return ap_get_brigade(f->next, bb, mode, block, readbytes);
596
/* Let's see what our current Content-Encoding is.
597
* If gzip is present, don't gzip again. (We could, but let's not.)
769
/* We can't operate on Content-Ranges */
770
if (apr_table_get(r->headers_in, "Content-Range") != NULL) {
771
ap_remove_input_filter(f);
772
return ap_get_brigade(f->next, bb, mode, block, readbytes);
775
/* Check whether request body is gzipped.
777
* If it is, we're transforming the contents, invalidating
778
* some request headers including Content-Encoding.
780
* If not, we just remove ourself.
599
encoding = apr_table_get(r->headers_in, "Content-Encoding");
601
const char *tmp = encoding;
603
token = ap_get_token(r->pool, &tmp, 0);
604
while (token && token[0]) {
605
if (!strcasecmp(token, "gzip")) {
609
/* Otherwise, skip token */
611
token = ap_get_token(r->pool, &tmp, 0);
782
if (check_gzip(r, r->headers_in, NULL) == 0) {
616
783
ap_remove_input_filter(f);
617
784
return ap_get_brigade(f->next, bb, mode, block, readbytes);
857
1023
return ap_pass_brigade(f->next, bb);
860
/* Let's see what our current Content-Encoding is.
861
* If gzip is present, don't gzip again. (We could, but let's not.)
1026
/* We can't operate on Content-Ranges */
1027
if (apr_table_get(r->headers_out, "Content-Range") != NULL) {
1028
ap_remove_output_filter(f);
1029
return ap_pass_brigade(f->next, bb);
1033
* Let's see what our current Content-Encoding is.
1034
* Only inflate if gzipped.
863
encoding = apr_table_get(r->headers_out, "Content-Encoding");
865
const char *tmp = encoding;
867
token = ap_get_token(r->pool, &tmp, 0);
868
while (token && token[0]) {
869
if (!strcasecmp(token, "gzip")) {
873
/* Otherwise, skip token */
875
token = ap_get_token(r->pool, &tmp, 0);
1036
if (check_gzip(r, r->headers_out, r->err_headers_out) == 0) {
880
1037
ap_remove_output_filter(f);
881
1038
return ap_pass_brigade(f->next, bb);
883
apr_table_unset(r->headers_out, "Content-Encoding");
885
1041
/* No need to inflate HEAD or 204/304 */
886
1042
if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bb))) {
903
1060
"unable to init Zlib: "
904
1061
"inflateInit2 returned %d: URL %s",
1064
* Remove ourselves as it does not make sense to return:
1065
* We are not able to init libz and pass data down the chain
906
1068
ap_remove_output_filter(f);
907
1069
return ap_pass_brigade(f->next, bb);
910
/* initialize deflate output buffer */
1073
* Register a cleanup function to ensure that we cleanup the internal
1076
apr_pool_cleanup_register(r->pool, ctx, deflate_ctx_cleanup,
1077
apr_pool_cleanup_null);
1079
/* these are unlikely to be set anyway, but ... */
1080
apr_table_unset(r->headers_out, "Content-Length");
1081
apr_table_unset(r->headers_out, "Content-MD5");
1082
deflate_check_etag(r, "gunzip");
1084
/* initialize inflate output buffer */
911
1085
ctx->stream.next_out = ctx->buffer;
912
1086
ctx->stream.avail_out = c->bufferSize;
1088
ctx->inflate_init = 0;
917
for (bkt = APR_BRIGADE_FIRST(bb);
918
bkt != APR_BRIGADE_SENTINEL(bb);
919
bkt = APR_BUCKET_NEXT(bkt))
1091
while (!APR_BRIGADE_EMPTY(bb))
921
1093
const char *data;
924
/* If we actually see the EOS, that means we screwed up! */
925
/* no it doesn't - not in a HEAD or 204/304 */
926
if (APR_BUCKET_IS_EOS(bkt)) {
1097
e = APR_BRIGADE_FIRST(bb);
1099
if (APR_BUCKET_IS_EOS(e)) {
1101
* We are really done now. Ensure that we never return here, even
1102
* if a second EOS bucket falls down the chain. Thus remove
1105
ap_remove_output_filter(f);
1106
/* should be zero already anyway */
1107
ctx->stream.avail_in = 0;
1109
* Flush the remaining data from the zlib buffers. It is correct
1110
* to use Z_SYNC_FLUSH in this case and not Z_FINISH as in the
1111
* deflate case. In the inflate case Z_FINISH requires to have a
1112
* large enough output buffer to put ALL data in otherwise it
1113
* fails, whereas in the deflate case you can empty a filled output
1114
* buffer and call it again until no more output can be created.
1116
flush_libz_buffer(ctx, c, f->c->bucket_alloc, inflate, Z_SYNC_FLUSH,
1118
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
1119
"Zlib: Inflated %ld to %ld : URL %s",
1120
ctx->stream.total_in, ctx->stream.total_out, r->uri);
1122
if (ctx->validation_buffer_length == VALIDATION_SIZE) {
1123
unsigned long compCRC, compLen;
1124
compCRC = getLong(ctx->validation_buffer);
1125
if (ctx->crc != compCRC) {
1126
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1127
"Zlib: Checksum of inflated stream invalid");
1128
return APR_EGENERAL;
1130
ctx->validation_buffer += VALIDATION_SIZE / 2;
1131
compLen = getLong(ctx->validation_buffer);
1132
if (ctx->stream.total_out != compLen) {
1133
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1134
"Zlib: Length of inflated stream invalid");
1135
return APR_EGENERAL;
1139
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
1140
"Zlib: Validation bytes not present");
1141
return APR_EGENERAL;
927
1144
inflateEnd(&ctx->stream);
928
return ap_pass_brigade(f->next, bb);
1145
/* No need for cleanup any longer */
1146
apr_pool_cleanup_kill(r->pool, ctx, deflate_ctx_cleanup);
1148
/* Remove EOS from the old list, and insert into the new. */
1149
APR_BUCKET_REMOVE(e);
1150
APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
1153
* Okay, we've seen the EOS.
1154
* Time to pass it along down the chain.
1156
return ap_pass_brigade(f->next, ctx->bb);
931
if (APR_BUCKET_IS_FLUSH(bkt)) {
932
apr_bucket *tmp_heap;
933
zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH);
1159
if (APR_BUCKET_IS_FLUSH(e)) {
1162
/* flush the remaining data from the zlib buffers */
1163
zRC = flush_libz_buffer(ctx, c, f->c->bucket_alloc, inflate,
1164
Z_SYNC_FLUSH, UPDATE_CRC);
934
1165
if (zRC != Z_OK) {
935
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
936
"Inflate error %d on flush", zRC);
937
inflateEnd(&ctx->stream);
938
1166
return APR_EGENERAL;
941
ctx->stream.next_out = ctx->buffer;
942
len = c->bufferSize - ctx->stream.avail_out;
944
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
945
tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,
946
NULL, f->c->bucket_alloc);
947
APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);
948
ctx->stream.avail_out = c->bufferSize;
950
/* Move everything to the returning brigade. */
951
APR_BUCKET_REMOVE(bkt);
1169
/* Remove flush bucket from old brigade anf insert into the new. */
1170
APR_BUCKET_REMOVE(e);
1171
APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
1172
rv = ap_pass_brigade(f->next, ctx->bb);
1173
if (rv != APR_SUCCESS) {
1179
if (APR_BUCKET_IS_METADATA(e)) {
1181
* Remove meta data bucket from old brigade and insert into the
1184
APR_BUCKET_REMOVE(e);
1185
APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
956
apr_bucket_read(bkt, &data, &len, APR_BLOCK_READ);
1190
apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
958
1192
/* first bucket contains zlib header */
959
if (!deflate_init++) {
1193
if (!ctx->inflate_init++) {
961
1195
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
962
1196
"Insufficient data for inflate");
1010
1244
ctx->stream.next_in = (unsigned char *)data;
1011
1245
ctx->stream.avail_in = len;
1247
if (ctx->validation_buffer) {
1248
if (ctx->validation_buffer_length < VALIDATION_SIZE) {
1249
apr_size_t copy_size;
1251
copy_size = VALIDATION_SIZE - ctx->validation_buffer_length;
1252
if (copy_size > ctx->stream.avail_in)
1253
copy_size = ctx->stream.avail_in;
1254
memcpy(ctx->validation_buffer + ctx->validation_buffer_length,
1255
ctx->stream.next_in, copy_size);
1256
/* Saved copy_size bytes */
1257
ctx->stream.avail_in -= copy_size;
1258
ctx->validation_buffer_length += copy_size;
1260
if (ctx->stream.avail_in) {
1261
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
1262
"Zlib: %d bytes of garbage at the end of "
1263
"compressed stream.", ctx->stream.avail_in);
1265
* There is nothing worth consuming for zlib left, because it is
1266
* either garbage data or the data has been copied to the
1267
* validation buffer (processing validation data is no business
1268
* for zlib). So set ctx->stream.avail_in to zero to indicate
1269
* this to the following while loop.
1271
ctx->stream.avail_in = 0;
1015
1277
while (ctx->stream.avail_in != 0) {
1016
1278
if (ctx->stream.avail_out == 0) {
1017
apr_bucket *tmp_heap;
1018
1280
ctx->stream.next_out = ctx->buffer;
1019
1281
len = c->bufferSize - ctx->stream.avail_out;
1021
1283
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
1022
tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,
1023
NULL, f->c->bucket_alloc);
1024
APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);
1284
b = apr_bucket_heap_create((char *)ctx->buffer, len,
1285
NULL, f->c->bucket_alloc);
1286
APR_BRIGADE_INSERT_TAIL(ctx->bb, b);
1025
1287
ctx->stream.avail_out = c->bufferSize;
1288
/* Send what we have right now to the next filter. */
1289
rv = ap_pass_brigade(f->next, ctx->bb);
1290
if (rv != APR_SUCCESS) {
1028
1295
zRC = inflate(&ctx->stream, Z_NO_FLUSH);
1030
1297
if (zRC == Z_STREAM_END) {
1299
* We have inflated all data. Now try to capture the
1300
* validation bytes. We may not have them all available
1301
* right now, but capture what is there.
1303
ctx->validation_buffer = apr_pcalloc(f->r->pool,
1305
if (ctx->stream.avail_in > VALIDATION_SIZE) {
1306
ctx->validation_buffer_length = VALIDATION_SIZE;
1307
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
1308
"Zlib: %d bytes of garbage at the end of "
1309
"compressed stream.",
1310
ctx->stream.avail_in - VALIDATION_SIZE);
1311
} else if (ctx->stream.avail_in > 0) {
1312
ctx->validation_buffer_length = ctx->stream.avail_in;
1314
if (ctx->validation_buffer_length)
1315
memcpy(ctx->validation_buffer, ctx->stream.next_in,
1316
ctx->validation_buffer_length);
1034
1320
if (zRC != Z_OK) {
1035
inflateEnd(&ctx->stream);
1036
return APR_EGENERAL;
1039
if (zRC == Z_STREAM_END) {
1040
apr_bucket *tmp_heap, *eos;
1042
ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
1043
"Zlib: Inflated %ld to %ld : URL %s",
1044
ctx->stream.total_in, ctx->stream.total_out,
1047
len = c->bufferSize - ctx->stream.avail_out;
1049
ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);
1050
tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,
1051
NULL, f->c->bucket_alloc);
1052
APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);
1053
ctx->stream.avail_out = c->bufferSize;
1055
/* Is the remaining 8 bytes already in the avail stream? */
1056
if (ctx->stream.avail_in >= 8) {
1057
unsigned long compCRC, compLen;
1058
compCRC = getLong(ctx->stream.next_in);
1059
if (ctx->crc != compCRC) {
1060
inflateEnd(&ctx->stream);
1061
return APR_EGENERAL;
1063
ctx->stream.next_in += 4;
1064
compLen = getLong(ctx->stream.next_in);
1065
if (ctx->stream.total_out != compLen) {
1066
inflateEnd(&ctx->stream);
1067
return APR_EGENERAL;
1071
/* FIXME: We need to grab the 8 verification bytes
1073
inflateEnd(&ctx->stream);
1074
1321
return APR_EGENERAL;
1077
inflateEnd(&ctx->stream);
1079
eos = apr_bucket_eos_create(f->c->bucket_alloc);
1080
APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, eos);
1325
apr_bucket_delete(e);
1086
rv = ap_pass_brigade(f->next, ctx->proc_bb);
1087
apr_brigade_cleanup(ctx->proc_bb);
1328
apr_brigade_cleanup(bb);
1332
#define PROTO_FLAGS AP_FILTER_PROTO_CHANGE|AP_FILTER_PROTO_CHANGE_LENGTH
1091
1333
static void register_hooks(apr_pool_t *p)
1093
1335
ap_register_output_filter(deflateFilterName, deflate_out_filter, NULL,