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

📄 mod_deflate.c

📁 apache服务器源代码(版本号:2.2.2)
💻 C
📖 第 1 页 / 共 3 页
字号:
            return ap_pass_brigade(f->next, bb);        }        /* add immortal gzip header */        e = apr_bucket_immortal_create(gzip_header, sizeof gzip_header,                                       f->c->bucket_alloc);        APR_BRIGADE_INSERT_TAIL(ctx->bb, e);        /* If the entire Content-Encoding is "identity", we can replace it. */        if (!encoding || !strcasecmp(encoding, "identity")) {            apr_table_setn(r->headers_out, "Content-Encoding", "gzip");        }        else {            apr_table_mergen(r->headers_out, "Content-Encoding", "gzip");        }        apr_table_unset(r->headers_out, "Content-Length");        /* initialize deflate output buffer */        ctx->stream.next_out = ctx->buffer;        ctx->stream.avail_out = c->bufferSize;    }    while (!APR_BRIGADE_EMPTY(bb))    {        const char *data;        apr_bucket *b;        apr_size_t len;        int done = 0;        e = APR_BRIGADE_FIRST(bb);        if (APR_BUCKET_IS_EOS(e)) {            char *buf;            unsigned int deflate_len;            ctx->stream.avail_in = 0; /* should be zero already anyway */            for (;;) {                deflate_len = c->bufferSize - ctx->stream.avail_out;                if (deflate_len != 0) {                    b = apr_bucket_heap_create((char *)ctx->buffer,                                               deflate_len, NULL,                                               f->c->bucket_alloc);                    APR_BRIGADE_INSERT_TAIL(ctx->bb, b);                    ctx->stream.next_out = ctx->buffer;                    ctx->stream.avail_out = c->bufferSize;                }                if (done) {                    break;                }                zRC = deflate(&ctx->stream, Z_FINISH);                if (deflate_len == 0 && zRC == Z_BUF_ERROR) {                    zRC = Z_OK;                }                done = (ctx->stream.avail_out != 0 || zRC == Z_STREAM_END);                if (zRC != Z_OK && zRC != Z_STREAM_END) {                    break;                }            }            buf = apr_palloc(r->pool, 8);            putLong((unsigned char *)&buf[0], ctx->crc);            putLong((unsigned char *)&buf[4], ctx->stream.total_in);            b = apr_bucket_pool_create(buf, 8, r->pool, f->c->bucket_alloc);            APR_BRIGADE_INSERT_TAIL(ctx->bb, b);            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                          "Zlib: Compressed %ld to %ld : URL %s",                          ctx->stream.total_in, ctx->stream.total_out, r->uri);            /* leave notes for logging */            if (c->note_input_name) {                apr_table_setn(r->notes, c->note_input_name,                               (ctx->stream.total_in > 0)                                ? apr_off_t_toa(r->pool,                                                ctx->stream.total_in)                                : "-");            }            if (c->note_output_name) {                apr_table_setn(r->notes, c->note_output_name,                               (ctx->stream.total_in > 0)                                ? apr_off_t_toa(r->pool,                                                ctx->stream.total_out)                                : "-");            }            if (c->note_ratio_name) {                apr_table_setn(r->notes, c->note_ratio_name,                               (ctx->stream.total_in > 0)                                ? apr_itoa(r->pool,                                           (int)(ctx->stream.total_out                                                 * 100                                                 / ctx->stream.total_in))                                : "-");            }            deflateEnd(&ctx->stream);            /* Remove EOS from the old list, and insert into the new. */            APR_BUCKET_REMOVE(e);            APR_BRIGADE_INSERT_TAIL(ctx->bb, e);            /* Okay, we've seen the EOS.             * Time to pass it along down the chain.             */            return ap_pass_brigade(f->next, ctx->bb);        }        if (APR_BUCKET_IS_FLUSH(e)) {            apr_bucket *bkt;            apr_status_t rv;            apr_bucket_delete(e);            if (ctx->stream.avail_in > 0) {                zRC = deflate(&(ctx->stream), Z_SYNC_FLUSH);                if (zRC != Z_OK) {                    return APR_EGENERAL;                }            }            ctx->stream.next_out = ctx->buffer;            len = c->bufferSize - ctx->stream.avail_out;            b = apr_bucket_heap_create((char *)ctx->buffer, len,                                       NULL, f->c->bucket_alloc);            APR_BRIGADE_INSERT_TAIL(ctx->bb, b);            ctx->stream.avail_out = c->bufferSize;            bkt = apr_bucket_flush_create(f->c->bucket_alloc);            APR_BRIGADE_INSERT_TAIL(ctx->bb, bkt);            rv = ap_pass_brigade(f->next, ctx->bb);            if (rv != APR_SUCCESS) {                return rv;            }            continue;        }        /* read */        apr_bucket_read(e, &data, &len, APR_BLOCK_READ);        /* This crc32 function is from zlib. */        ctx->crc = crc32(ctx->crc, (const Bytef *)data, len);        /* write */        ctx->stream.next_in = (unsigned char *)data; /* We just lost const-ness,                                                      * but we'll just have to                                                      * trust zlib */        ctx->stream.avail_in = len;        while (ctx->stream.avail_in != 0) {            if (ctx->stream.avail_out == 0) {                apr_status_t rv;                ctx->stream.next_out = ctx->buffer;                len = c->bufferSize - ctx->stream.avail_out;                b = apr_bucket_heap_create((char *)ctx->buffer, len,                                           NULL, f->c->bucket_alloc);                APR_BRIGADE_INSERT_TAIL(ctx->bb, b);                ctx->stream.avail_out = c->bufferSize;                /* Send what we have right now to the next filter. */                rv = ap_pass_brigade(f->next, ctx->bb);                if (rv != APR_SUCCESS) {                    return rv;                }            }            zRC = deflate(&(ctx->stream), Z_NO_FLUSH);            if (zRC != Z_OK)                return APR_EGENERAL;        }        apr_bucket_delete(e);    }    apr_brigade_cleanup(bb);    return APR_SUCCESS;}/* This is the deflate input filter (inflates).  */static apr_status_t deflate_in_filter(ap_filter_t *f,                                      apr_bucket_brigade *bb,                                      ap_input_mode_t mode,                                      apr_read_type_e block,                                      apr_off_t readbytes){    apr_bucket *bkt;    request_rec *r = f->r;    deflate_ctx *ctx = f->ctx;    int zRC;    apr_status_t rv;    deflate_filter_config *c;    /* just get out of the way of things we don't want. */    if (mode != AP_MODE_READBYTES) {        return ap_get_brigade(f->next, bb, mode, block, readbytes);    }    c = ap_get_module_config(r->server->module_config, &deflate_module);    if (!ctx) {        int found = 0;        char *token, deflate_hdr[10];        const char *encoding;        apr_size_t len;        /* only work on main request/no subrequests */        if (!ap_is_initial_req(r)) {            ap_remove_input_filter(f);            return ap_get_brigade(f->next, bb, mode, block, readbytes);        }        /* Let's see what our current Content-Encoding is.         * If gzip is present, don't gzip again.  (We could, but let's not.)         */        encoding = apr_table_get(r->headers_in, "Content-Encoding");        if (encoding) {            const char *tmp = encoding;            token = ap_get_token(r->pool, &tmp, 0);            while (token && token[0]) {                if (!strcasecmp(token, "gzip")) {                    found = 1;                    break;                }                /* Otherwise, skip token */                tmp++;                token = ap_get_token(r->pool, &tmp, 0);            }        }        if (found == 0) {            ap_remove_input_filter(f);            return ap_get_brigade(f->next, bb, mode, block, readbytes);        }        f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));        ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);        ctx->proc_bb = apr_brigade_create(r->pool, f->c->bucket_alloc);        ctx->buffer = apr_palloc(r->pool, c->bufferSize);        rv = ap_get_brigade(f->next, ctx->bb, AP_MODE_READBYTES, block, 10);        if (rv != APR_SUCCESS) {            return rv;        }        len = 10;        rv = apr_brigade_flatten(ctx->bb, deflate_hdr, &len);        if (rv != APR_SUCCESS) {            return rv;        }        /* We didn't get the magic bytes. */        if (len != 10 ||            deflate_hdr[0] != deflate_magic[0] ||            deflate_hdr[1] != deflate_magic[1]) {            return APR_EGENERAL;        }        /* We can't handle flags for now. */        if (deflate_hdr[3] != 0) {            return APR_EGENERAL;        }        zRC = inflateInit2(&ctx->stream, c->windowSize);        if (zRC != Z_OK) {            f->ctx = NULL;            inflateEnd(&ctx->stream);            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                          "unable to init Zlib: "                          "inflateInit2 returned %d: URL %s",                          zRC, r->uri);            ap_remove_input_filter(f);            return ap_get_brigade(f->next, bb, mode, block, readbytes);        }        /* initialize deflate output buffer */        ctx->stream.next_out = ctx->buffer;        ctx->stream.avail_out = c->bufferSize;        apr_brigade_cleanup(ctx->bb);    }    if (APR_BRIGADE_EMPTY(ctx->proc_bb)) {        rv = ap_get_brigade(f->next, ctx->bb, mode, block, readbytes);        if (rv != APR_SUCCESS) {            /* What about APR_EAGAIN errors? */            inflateEnd(&ctx->stream);            return rv;        }        for (bkt = APR_BRIGADE_FIRST(ctx->bb);             bkt != APR_BRIGADE_SENTINEL(ctx->bb);             bkt = APR_BUCKET_NEXT(bkt))        {            const char *data;            apr_size_t len;            /* If we actually see the EOS, that means we screwed up! */            if (APR_BUCKET_IS_EOS(bkt)) {                inflateEnd(&ctx->stream);                return APR_EGENERAL;            }            if (APR_BUCKET_IS_FLUSH(bkt)) {                apr_bucket *tmp_heap;                zRC = inflate(&(ctx->stream), Z_SYNC_FLUSH);                if (zRC != Z_OK) {                    inflateEnd(&ctx->stream);                    return APR_EGENERAL;                }                ctx->stream.next_out = ctx->buffer;                len = c->bufferSize - ctx->stream.avail_out;                ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);                tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,                                                 NULL, f->c->bucket_alloc);                APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);                ctx->stream.avail_out = c->bufferSize;                /* Move everything to the returning brigade. */                APR_BUCKET_REMOVE(bkt);                APR_BRIGADE_CONCAT(bb, ctx->bb);                break;            }            /* read */            apr_bucket_read(bkt, &data, &len, APR_BLOCK_READ);            /* pass through zlib inflate. */            ctx->stream.next_in = (unsigned char *)data;            ctx->stream.avail_in = len;            zRC = Z_OK;            while (ctx->stream.avail_in != 0) {                if (ctx->stream.avail_out == 0) {                    apr_bucket *tmp_heap;                    ctx->stream.next_out = ctx->buffer;                    len = c->bufferSize - ctx->stream.avail_out;                    ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);                    tmp_heap = apr_bucket_heap_create((char *)ctx->buffer, len,                                                      NULL, f->c->bucket_alloc);                    APR_BRIGADE_INSERT_TAIL(ctx->proc_bb, tmp_heap);                    ctx->stream.avail_out = c->bufferSize;                }                zRC = inflate(&ctx->stream, Z_NO_FLUSH);                if (zRC == Z_STREAM_END) {                    break;                }                if (zRC != Z_OK) {                    inflateEnd(&ctx->stream);                    return APR_EGENERAL;                }            }            if (zRC == Z_STREAM_END) {                apr_bucket *tmp_heap, *eos;                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                              "Zlib: Inflated %ld to %ld : URL %s",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -