📄 ngx_http_gzip_filter_module.c
字号:
rc); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "gzip in_buf:%p pos:%p", ctx->in_buf, ctx->in_buf->pos); if (ctx->zstream.next_in) { ctx->in_buf->pos = ctx->zstream.next_in; if (ctx->zstream.avail_in == 0) { ctx->zstream.next_in = NULL; } } ctx->out_buf->last = ctx->zstream.next_out; if (ctx->zstream.avail_out == 0) { /* zlib wants to output some more gzipped data */ cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { ngx_http_gzip_error(ctx); return NGX_ERROR; } cl->buf = ctx->out_buf; cl->next = NULL; *ctx->last_out = cl; ctx->last_out = &cl->next; ctx->redo = 1; continue; } ctx->redo = 0; if (ctx->flush == Z_SYNC_FLUSH) { ctx->zstream.avail_out = 0; ctx->out_buf->flush = 1; ctx->flush = Z_NO_FLUSH; cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { ngx_http_gzip_error(ctx); return NGX_ERROR; } cl->buf = ctx->out_buf; cl->next = NULL; *ctx->last_out = cl; ctx->last_out = &cl->next; break; } if (rc == Z_STREAM_END) { ctx->zin = ctx->zstream.total_in; ctx->zout = 10 + ctx->zstream.total_out + 8; rc = deflateEnd(&ctx->zstream); if (rc != Z_OK) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "deflateEnd() failed: %d", rc); ngx_http_gzip_error(ctx); return NGX_ERROR; } ngx_pfree(r->pool, ctx->preallocated); cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { ngx_http_gzip_error(ctx); return NGX_ERROR; } cl->buf = ctx->out_buf; cl->next = NULL; *ctx->last_out = cl; ctx->last_out = &cl->next; if (ctx->zstream.avail_out >= 8) { trailer = (struct gztrailer *) ctx->out_buf->last; ctx->out_buf->last += 8; ctx->out_buf->last_buf = 1; } else { b = ngx_create_temp_buf(r->pool, 8); if (b == NULL) { ngx_http_gzip_error(ctx); return NGX_ERROR; } b->last_buf = 1; cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { ngx_http_gzip_error(ctx); return NGX_ERROR; } cl->buf = b; cl->next = NULL; *ctx->last_out = cl; ctx->last_out = &cl->next; trailer = (struct gztrailer *) b->pos; b->last += 8; }#if (NGX_HAVE_LITTLE_ENDIAN && NGX_HAVE_NONALIGNED) trailer->crc32 = ctx->crc32; trailer->zlen = ctx->zin;#else trailer->crc32[0] = (u_char) (ctx->crc32 & 0xff); trailer->crc32[1] = (u_char) ((ctx->crc32 >> 8) & 0xff); trailer->crc32[2] = (u_char) ((ctx->crc32 >> 16) & 0xff); trailer->crc32[3] = (u_char) ((ctx->crc32 >> 24) & 0xff); trailer->zlen[0] = (u_char) (ctx->zin & 0xff); trailer->zlen[1] = (u_char) ((ctx->zin >> 8) & 0xff); trailer->zlen[2] = (u_char) ((ctx->zin >> 16) & 0xff); trailer->zlen[3] = (u_char) ((ctx->zin >> 24) & 0xff);#endif ctx->zstream.avail_in = 0; ctx->zstream.avail_out = 0; ctx->done = 1; r->connection->buffered &= ~NGX_HTTP_GZIP_BUFFERED; break; } if (conf->no_buffer && ctx->in == NULL) { cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { ngx_http_gzip_error(ctx); return NGX_ERROR; } cl->buf = ctx->out_buf; cl->next = NULL; *ctx->last_out = cl; ctx->last_out = &cl->next; break; } } if (ctx->out == NULL) { if (last == NGX_AGAIN) { return NGX_AGAIN; } if (ctx->busy == NULL) { return NGX_OK; } } last = ngx_http_next_body_filter(r, ctx->out); /* * we do not check NGX_AGAIN here because the downstream filters * may free some buffers and zlib may compress some data into them */ if (last == NGX_ERROR) { ngx_http_gzip_error(ctx); return NGX_ERROR; } ngx_chain_update_chains(&ctx->free, &ctx->busy, &ctx->out, (ngx_buf_tag_t) &ngx_http_gzip_filter_module); ctx->last_out = &ctx->out; if (ctx->done) { return last; } }}static void *ngx_http_gzip_filter_alloc(void *opaque, u_int items, u_int size){ ngx_http_gzip_ctx_t *ctx = opaque; void *p; ngx_uint_t alloc; alloc = items * size; if (alloc % 512 != 0) { /* * The zlib deflate_state allocation, it takes about 6K, * we allocate 8K. Other allocations are divisible by 512. */ alloc = (alloc + ngx_pagesize - 1) & ~(ngx_pagesize - 1); } if (alloc <= ctx->allocated) { p = ctx->free_mem; ctx->free_mem += alloc; ctx->allocated -= alloc; ngx_log_debug4(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0, "gzip alloc: n:%ud s:%ud a:%ud p:%p", items, size, alloc, p); return p; } ngx_log_error(NGX_LOG_ALERT, ctx->request->connection->log, 0, "gzip filter failed to use preallocated memory: %ud of %ud", items * size, ctx->allocated); p = ngx_palloc(ctx->request->pool, items * size); return p;}static voidngx_http_gzip_filter_free(void *opaque, void *address){#if 0 ngx_http_gzip_ctx_t *ctx = opaque; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ctx->request->connection->log, 0, "gzip free: %p", address);#endif}static voidngx_http_gzip_error(ngx_http_gzip_ctx_t *ctx){ deflateEnd(&ctx->zstream); if (ctx->preallocated) { ngx_pfree(ctx->request->pool, ctx->preallocated); } ctx->zstream.avail_in = 0; ctx->zstream.avail_out = 0; ctx->done = 1; return;}static ngx_int_tngx_http_gzip_add_variables(ngx_conf_t *cf){ ngx_http_variable_t *var; var = ngx_http_add_variable(cf, &ngx_http_gzip_ratio, NGX_HTTP_VAR_NOHASH); if (var == NULL) { return NGX_ERROR; } var->get_handler = ngx_http_gzip_ratio_variable; return NGX_OK;}static ngx_int_tngx_http_gzip_ratio_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data){ ngx_uint_t zint, zfrac; ngx_http_gzip_ctx_t *ctx; v->valid = 1; v->no_cacheable = 0; v->not_found = 0; ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module); if (ctx == NULL || ctx->zout == 0) { v->not_found = 1; return NGX_OK; } v->data = ngx_palloc(r->pool, NGX_INT32_LEN + 3); if (v->data == NULL) { return NGX_ERROR; } zint = (ngx_uint_t) (ctx->zin / ctx->zout); zfrac = (ngx_uint_t) ((ctx->zin * 100 / ctx->zout) % 100); if ((ctx->zin * 1000 / ctx->zout) % 10 > 4) { /* the rounding, e.g., 2.125 to 2.13 */ zfrac++; if (zfrac > 99) { zint++; zfrac = 0; } } v->len = ngx_sprintf(v->data, "%ui.%02ui", zint, zfrac) - v->data; return NGX_OK;}static void *ngx_http_gzip_create_conf(ngx_conf_t *cf){ ngx_http_gzip_conf_t *conf; conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_gzip_conf_t)); if (conf == NULL) { return NGX_CONF_ERROR; } /* * set by ngx_pcalloc(): * * conf->bufs.num = 0; * conf->types = NULL; */ conf->enable = NGX_CONF_UNSET; conf->no_buffer = NGX_CONF_UNSET; conf->level = NGX_CONF_UNSET; conf->wbits = (size_t) NGX_CONF_UNSET; conf->memlevel = (size_t) NGX_CONF_UNSET; conf->min_length = NGX_CONF_UNSET; return conf;}static char *ngx_http_gzip_merge_conf(ngx_conf_t *cf, void *parent, void *child){ ngx_http_gzip_conf_t *prev = parent; ngx_http_gzip_conf_t *conf = child; ngx_str_t *type; ngx_conf_merge_value(conf->enable, prev->enable, 0); ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 4, ngx_pagesize); ngx_conf_merge_value(conf->level, prev->level, 1); ngx_conf_merge_size_value(conf->wbits, prev->wbits, MAX_WBITS); ngx_conf_merge_size_value(conf->memlevel, prev->memlevel, MAX_MEM_LEVEL - 1); ngx_conf_merge_value(conf->min_length, prev->min_length, 20); ngx_conf_merge_value(conf->no_buffer, prev->no_buffer, 0); if (conf->types == NULL) { if (prev->types == NULL) { conf->types = ngx_array_create(cf->pool, 1, sizeof(ngx_str_t)); if (conf->types == NULL) { return NGX_CONF_ERROR; } type = ngx_array_push(conf->types); if (type == NULL) { return NGX_CONF_ERROR; } type->len = sizeof("text/html") - 1; type->data = (u_char *) "text/html"; } else { conf->types = prev->types; } } return NGX_CONF_OK;}static ngx_int_tngx_http_gzip_filter_init(ngx_conf_t *cf){ ngx_http_next_header_filter = ngx_http_top_header_filter; ngx_http_top_header_filter = ngx_http_gzip_header_filter; ngx_http_next_body_filter = ngx_http_top_body_filter; ngx_http_top_body_filter = ngx_http_gzip_body_filter; return NGX_OK;}static char *ngx_http_gzip_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){ ngx_http_gzip_conf_t *gcf = conf; ngx_str_t *value, *type; ngx_uint_t i; if (gcf->types == NULL) { gcf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t)); if (gcf->types == NULL) { return NGX_CONF_ERROR; } type = ngx_array_push(gcf->types); if (type == NULL) { return NGX_CONF_ERROR; } type->len = sizeof("text/html") - 1; type->data = (u_char *) "text/html"; } value = cf->args->elts; for (i = 1; i < cf->args->nelts; i++) { if (ngx_strcmp(value[i].data, "text/html") == 0) { continue; } type = ngx_array_push(gcf->types); if (type == NULL) { return NGX_CONF_ERROR; } type->len = value[i].len; type->data = ngx_palloc(cf->pool, type->len + 1); if (type->data == NULL) { return NGX_CONF_ERROR; } ngx_cpystrn(type->data, value[i].data, type->len + 1); } return NGX_CONF_OK;}static char *ngx_http_gzip_window(ngx_conf_t *cf, void *post, void *data){ int *np = data; int wbits, wsize; wbits = 15; for (wsize = 32 * 1024; wsize > 256; wsize >>= 1) { if (wsize == *np) { *np = wbits; return NGX_CONF_OK; } wbits--; } return "must be 512, 1k, 2k, 4k, 8k, 16k, or 32k";}static char *ngx_http_gzip_hash(ngx_conf_t *cf, void *post, void *data){ int *np = data; int memlevel, hsize; memlevel = 9; for (hsize = 128 * 1024; hsize > 256; hsize >>= 1) { if (hsize == *np) { *np = memlevel; return NGX_CONF_OK; } memlevel--; } return "must be 512, 1k, 2k, 4k, 8k, 16k, 32k, 64k, or 128k";}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -