⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ngx_http_gzip_filter_module.c

📁 Nginx是一个高性能的HTTP和反向代理服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
                           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 + -