Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_gzip_filter.c @ 177:4db54fdbcbe7
nginx-0.0.1-2003-11-10-20:17:31 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 10 Nov 2003 17:17:31 +0000 |
parents | 389d7ee9fa60 |
children | 574bea0142be |
comparison
equal
deleted
inserted
replaced
176:c0552e5ab567 | 177:4db54fdbcbe7 |
---|---|
32 char *free_mem; | 32 char *free_mem; |
33 int allocated; | 33 int allocated; |
34 | 34 |
35 unsigned flush:4; | 35 unsigned flush:4; |
36 unsigned redo:1; | 36 unsigned redo:1; |
37 unsigned done:1; | |
38 | |
39 size_t zin; | |
40 size_t zout; | |
37 | 41 |
38 u_int crc32; | 42 u_int crc32; |
39 z_stream zstream; | 43 z_stream zstream; |
40 ngx_http_request_t *request; | 44 ngx_http_request_t *request; |
41 } ngx_http_gzip_ctx_t; | 45 } ngx_http_gzip_ctx_t; |
44 static void *ngx_http_gzip_filter_alloc(void *opaque, u_int items, | 48 static void *ngx_http_gzip_filter_alloc(void *opaque, u_int items, |
45 u_int size); | 49 u_int size); |
46 static void ngx_http_gzip_filter_free(void *opaque, void *address); | 50 static void ngx_http_gzip_filter_free(void *opaque, void *address); |
47 | 51 |
48 ngx_inline static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx); | 52 ngx_inline static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx); |
53 | |
54 static char *ngx_http_gzip_log_ratio(ngx_http_request_t *r, char *buf, | |
55 uintptr_t data); | |
56 | |
57 static int ngx_http_gzip_pre_conf(ngx_conf_t *cf); | |
49 static int ngx_http_gzip_filter_init(ngx_cycle_t *cycle); | 58 static int ngx_http_gzip_filter_init(ngx_cycle_t *cycle); |
50 static void *ngx_http_gzip_create_conf(ngx_conf_t *cf); | 59 static void *ngx_http_gzip_create_conf(ngx_conf_t *cf); |
51 static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf, | 60 static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf, |
52 void *parent, void *child); | 61 void *parent, void *child); |
53 static char *ngx_http_gzip_set_window(ngx_conf_t *cf, void *post, void *data); | 62 static char *ngx_http_gzip_set_window(ngx_conf_t *cf, void *post, void *data); |
112 ngx_null_command | 121 ngx_null_command |
113 }; | 122 }; |
114 | 123 |
115 | 124 |
116 static ngx_http_module_t ngx_http_gzip_filter_module_ctx = { | 125 static ngx_http_module_t ngx_http_gzip_filter_module_ctx = { |
126 ngx_http_gzip_pre_conf, /* pre conf */ | |
127 | |
117 NULL, /* create main configuration */ | 128 NULL, /* create main configuration */ |
118 NULL, /* init main configuration */ | 129 NULL, /* init main configuration */ |
119 | 130 |
120 NULL, /* create server configuration */ | 131 NULL, /* create server configuration */ |
121 NULL, /* merge server configuration */ | 132 NULL, /* merge server configuration */ |
131 ngx_http_gzip_filter_commands, /* module directives */ | 142 ngx_http_gzip_filter_commands, /* module directives */ |
132 NGX_HTTP_MODULE, /* module type */ | 143 NGX_HTTP_MODULE, /* module type */ |
133 ngx_http_gzip_filter_init, /* init module */ | 144 ngx_http_gzip_filter_init, /* init module */ |
134 NULL /* init child */ | 145 NULL /* init child */ |
135 }; | 146 }; |
147 | |
148 | |
149 static ngx_http_log_op_name_t ngx_http_gzip_log_fmt_ops[] = { | |
150 { ngx_string("gzip_ratio"), NGX_INT32_LEN + 3, ngx_http_gzip_log_ratio }, | |
151 { ngx_null_string, 0, NULL } | |
152 }; | |
153 | |
136 | 154 |
137 | 155 |
138 static u_char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 }; | 156 static u_char gzheader[10] = { 0x1f, 0x8b, Z_DEFLATED, 0, 0, 0, 0, 0, 0, 3 }; |
139 | 157 |
140 #if (HAVE_LITTLE_ENDIAN) | 158 #if (HAVE_LITTLE_ENDIAN) |
213 } | 231 } |
214 | 232 |
215 | 233 |
216 static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | 234 static int ngx_http_gzip_body_filter(ngx_http_request_t *r, ngx_chain_t *in) |
217 { | 235 { |
218 int rc, wbits, memlevel, zin, zout, last; | 236 int rc, wbits, memlevel, last; |
219 struct gztrailer *trailer; | 237 struct gztrailer *trailer; |
220 ngx_hunk_t *h; | 238 ngx_hunk_t *h; |
221 ngx_chain_t *cl; | 239 ngx_chain_t *cl; |
222 ngx_http_gzip_ctx_t *ctx; | 240 ngx_http_gzip_ctx_t *ctx; |
223 ngx_http_gzip_conf_t *conf; | 241 ngx_http_gzip_conf_t *conf; |
224 | 242 |
225 if (!(ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module))) { | 243 if (!(ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module))) { |
244 return ngx_http_next_body_filter(r, in); | |
245 } | |
246 | |
247 if (ctx->done) { | |
226 return ngx_http_next_body_filter(r, in); | 248 return ngx_http_next_body_filter(r, in); |
227 } | 249 } |
228 | 250 |
229 conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module); | 251 conf = ngx_http_get_module_loc_conf(r, ngx_http_gzip_filter_module); |
230 | 252 |
398 | 420 |
399 } else if (ctx->flush == Z_FINISH) { | 421 } else if (ctx->flush == Z_FINISH) { |
400 | 422 |
401 /* rc == Z_STREAM_END */ | 423 /* rc == Z_STREAM_END */ |
402 | 424 |
403 zin = ctx->zstream.total_in; | 425 ctx->zin = ctx->zstream.total_in; |
404 zout = 10 + ctx->zstream.total_out + 8; | 426 ctx->zout = 10 + ctx->zstream.total_out + 8; |
405 | 427 |
406 rc = deflateEnd(&ctx->zstream); | 428 rc = deflateEnd(&ctx->zstream); |
407 if (rc != Z_OK) { | 429 if (rc != Z_OK) { |
408 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 430 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, |
409 "deflateEnd() failed: %d", rc); | 431 "deflateEnd() failed: %d", rc); |
439 h->last += 8; | 461 h->last += 8; |
440 } | 462 } |
441 | 463 |
442 #if (HAVE_LITTLE_ENDIAN) | 464 #if (HAVE_LITTLE_ENDIAN) |
443 trailer->crc32 = ctx->crc32; | 465 trailer->crc32 = ctx->crc32; |
444 trailer->zlen = zin; | 466 trailer->zlen = ctx->zin; |
445 #else | 467 #else |
446 /* STUB */ | 468 /* STUB */ |
447 #endif | 469 #endif |
448 | 470 |
449 ctx->zstream.avail_in = 0; | 471 ctx->zstream.avail_in = 0; |
450 ctx->zstream.avail_out = 0; | 472 ctx->zstream.avail_out = 0; |
451 | 473 |
474 ctx->done = 1; | |
475 | |
476 #if 0 | |
452 ngx_http_delete_ctx(r, ngx_http_gzip_filter_module); | 477 ngx_http_delete_ctx(r, ngx_http_gzip_filter_module); |
478 #endif | |
453 | 479 |
454 break; | 480 break; |
455 | 481 |
456 } else if (conf->no_buffer && ctx->in == NULL) { | 482 } else if (conf->no_buffer && ctx->in == NULL) { |
457 ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool, | 483 ngx_alloc_link_and_set_hunk(cl, ctx->out_hunk, r->pool, |
529 ngx_log_debug(ctx->request->connection->log, "FREE: %08X" _ address); | 555 ngx_log_debug(ctx->request->connection->log, "FREE: %08X" _ address); |
530 #endif | 556 #endif |
531 } | 557 } |
532 | 558 |
533 | 559 |
560 static char *ngx_http_gzip_log_ratio(ngx_http_request_t *r, char *buf, | |
561 uintptr_t data) | |
562 { | |
563 int zint, zfrac; | |
564 ngx_http_gzip_ctx_t *ctx; | |
565 | |
566 ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module); | |
567 | |
568 if (ctx == NULL || ctx->zout == 0) { | |
569 *buf = '-'; | |
570 return buf + 1; | |
571 } | |
572 | |
573 #if 0 | |
574 return buf + ngx_snprintf(buf, NGX_INT32_LEN + 4, "%.2f", | |
575 (float) ctx->zin / ctx->zout); | |
576 #endif | |
577 | |
578 /* we prefer do not use FPU */ | |
579 | |
580 zint = ctx->zin / ctx->zout; | |
581 zfrac = (ctx->zin * 100 / ctx->zout) % 100; | |
582 | |
583 if ((ctx->zin * 1000 / ctx->zout) %10 > 4) { | |
584 if (++zfrac > 99) { | |
585 zint++; | |
586 zfrac = 0; | |
587 } | |
588 } | |
589 | |
590 return buf + ngx_snprintf(buf, NGX_INT32_LEN + 4, "%d.%02d", zint, zfrac); | |
591 } | |
592 | |
593 | |
534 ngx_inline static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx) | 594 ngx_inline static int ngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx) |
535 { | 595 { |
536 deflateEnd(&ctx->zstream); | 596 deflateEnd(&ctx->zstream); |
537 | 597 |
538 ngx_pfree(ctx->request->pool, ctx->preallocated); | 598 ngx_pfree(ctx->request->pool, ctx->preallocated); |
539 | 599 |
540 ctx->zstream.avail_in = 0; | 600 ctx->zstream.avail_in = 0; |
541 ctx->zstream.avail_out = 0; | 601 ctx->zstream.avail_out = 0; |
542 | 602 |
543 return NGX_ERROR; | 603 return NGX_ERROR; |
604 } | |
605 | |
606 | |
607 static int ngx_http_gzip_pre_conf(ngx_conf_t *cf) | |
608 { | |
609 ngx_http_log_op_name_t *op; | |
610 | |
611 for (op = ngx_http_gzip_log_fmt_ops; op->name.len; op++) { /* void */ } | |
612 op->op = NULL; | |
613 | |
614 op = ngx_http_log_fmt_ops; | |
615 | |
616 for (op = ngx_http_log_fmt_ops; op->op; op++) { | |
617 if (op->name.len == 0) { | |
618 op = (ngx_http_log_op_name_t *) op->op; | |
619 } | |
620 } | |
621 | |
622 op->op = (ngx_http_log_op_pt) ngx_http_gzip_log_fmt_ops; | |
623 | |
624 return NGX_OK; | |
544 } | 625 } |
545 | 626 |
546 | 627 |
547 static int ngx_http_gzip_filter_init(ngx_cycle_t *cycle) | 628 static int ngx_http_gzip_filter_init(ngx_cycle_t *cycle) |
548 { | 629 { |