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

📄 mod_deflate.c

📁 Apache官方在今天放出产品系列2.2的最新版本2.2.11的源码包 最流行的HTTP服务器软件之一
💻 C
📖 第 1 页 / 共 4 页
字号:
        if (apr_table_get(r->headers_out, "Content-Range") != NULL) {            ap_remove_output_filter(f);            return ap_pass_brigade(f->next, bb);        }        /*         * Let's see what our current Content-Encoding is.         * Only inflate if gzipped.         */        if (check_gzip(r, r->headers_out, r->err_headers_out) == 0) {            ap_remove_output_filter(f);            return ap_pass_brigade(f->next, bb);        }        /* No need to inflate HEAD or 204/304 */        if (APR_BUCKET_IS_EOS(APR_BRIGADE_FIRST(bb))) {            ap_remove_output_filter(f);            return ap_pass_brigade(f->next, bb);        }        f->ctx = ctx = apr_pcalloc(f->r->pool, sizeof(*ctx));        ctx->bb = apr_brigade_create(r->pool, f->c->bucket_alloc);        ctx->buffer = apr_palloc(r->pool, c->bufferSize);        ctx->libz_end_func = inflateEnd;        ctx->validation_buffer = NULL;        ctx->validation_buffer_length = 0;        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);            /*             * Remove ourselves as it does not make sense to return:             * We are not able to init libz and pass data down the chain             * compressed.             */            ap_remove_output_filter(f);            return ap_pass_brigade(f->next, bb);        }        /*         * Register a cleanup function to ensure that we cleanup the internal         * libz resources.         */        apr_pool_cleanup_register(r->pool, ctx, deflate_ctx_cleanup,                                  apr_pool_cleanup_null);        /* these are unlikely to be set anyway, but ... */        apr_table_unset(r->headers_out, "Content-Length");        apr_table_unset(r->headers_out, "Content-MD5");        deflate_check_etag(r, "gunzip");        /* initialize inflate output buffer */        ctx->stream.next_out = ctx->buffer;        ctx->stream.avail_out = c->bufferSize;        ctx->inflate_init = 0;    }    while (!APR_BRIGADE_EMPTY(bb))    {        const char *data;        apr_bucket *b;        apr_size_t len;        e = APR_BRIGADE_FIRST(bb);        if (APR_BUCKET_IS_EOS(e)) {            /*             * We are really done now. Ensure that we never return here, even             * if a second EOS bucket falls down the chain. Thus remove             * ourselves.             */            ap_remove_output_filter(f);            /* should be zero already anyway */            ctx->stream.avail_in = 0;            /*             * Flush the remaining data from the zlib buffers. It is correct             * to use Z_SYNC_FLUSH in this case and not Z_FINISH as in the             * deflate case. In the inflate case Z_FINISH requires to have a             * large enough output buffer to put ALL data in otherwise it             * fails, whereas in the deflate case you can empty a filled output             * buffer and call it again until no more output can be created.             */            flush_libz_buffer(ctx, c, f->c->bucket_alloc, inflate, Z_SYNC_FLUSH,                              UPDATE_CRC);            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                          "Zlib: Inflated %ld to %ld : URL %s",                          ctx->stream.total_in, ctx->stream.total_out, r->uri);            if (ctx->validation_buffer_length == VALIDATION_SIZE) {                unsigned long compCRC, compLen;                compCRC = getLong(ctx->validation_buffer);                if (ctx->crc != compCRC) {                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                                  "Zlib: Checksum of inflated stream invalid");                    return APR_EGENERAL;                }                ctx->validation_buffer += VALIDATION_SIZE / 2;                compLen = getLong(ctx->validation_buffer);                if (ctx->stream.total_out != compLen) {                    ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                                  "Zlib: Length of inflated stream invalid");                    return APR_EGENERAL;                }            }            else {                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                              "Zlib: Validation bytes not present");                return APR_EGENERAL;            }            inflateEnd(&ctx->stream);            /* No need for cleanup any longer */            apr_pool_cleanup_kill(r->pool, ctx, deflate_ctx_cleanup);            /* 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_status_t rv;            /* flush the remaining data from the zlib buffers */            zRC = flush_libz_buffer(ctx, c, f->c->bucket_alloc, inflate,                                    Z_SYNC_FLUSH, UPDATE_CRC);            if (zRC != Z_OK) {                return APR_EGENERAL;            }            /* Remove flush bucket from old brigade anf insert into the new. */            APR_BUCKET_REMOVE(e);            APR_BRIGADE_INSERT_TAIL(ctx->bb, e);            rv = ap_pass_brigade(f->next, ctx->bb);            if (rv != APR_SUCCESS) {                return rv;            }            continue;        }        if (APR_BUCKET_IS_METADATA(e)) {            /*             * Remove meta data bucket from old brigade and insert into the             * new.             */            APR_BUCKET_REMOVE(e);            APR_BRIGADE_INSERT_TAIL(ctx->bb, e);            continue;        }        /* read */        apr_bucket_read(e, &data, &len, APR_BLOCK_READ);        /* first bucket contains zlib header */        if (!ctx->inflate_init++) {            if (len < 10) {                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                              "Insufficient data for inflate");                return APR_EGENERAL;            }            else  {                zlib_method = data[2];                zlib_flags = data[3];                if (zlib_method != Z_DEFLATED) {                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                                  "inflate: data not deflated!");                    ap_remove_output_filter(f);                    return ap_pass_brigade(f->next, bb);                }                if (data[0] != deflate_magic[0] ||                    data[1] != deflate_magic[1] ||                    (zlib_flags & RESERVED) != 0) {                        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                                      "inflate: bad header");                    return APR_EGENERAL ;                }                data += 10 ;                len -= 10 ;           }           if (zlib_flags & EXTRA_FIELD) {               unsigned int bytes = (unsigned int)(data[0]);               bytes += ((unsigned int)(data[1])) << 8;               bytes += 2;               if (len < bytes) {                   ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,                                 "inflate: extra field too big (not "                                 "supported)");                   return APR_EGENERAL;               }               data += bytes;               len -= bytes;           }           if (zlib_flags & ORIG_NAME) {               while (len-- && *data++);           }           if (zlib_flags & COMMENT) {               while (len-- && *data++);           }           if (zlib_flags & HEAD_CRC) {                len -= 2;                data += 2;           }        }        /* pass through zlib inflate. */        ctx->stream.next_in = (unsigned char *)data;        ctx->stream.avail_in = len;        if (ctx->validation_buffer) {            if (ctx->validation_buffer_length < VALIDATION_SIZE) {                apr_size_t copy_size;                copy_size = VALIDATION_SIZE - ctx->validation_buffer_length;                if (copy_size > ctx->stream.avail_in)                    copy_size = ctx->stream.avail_in;                memcpy(ctx->validation_buffer + ctx->validation_buffer_length,                       ctx->stream.next_in, copy_size);                /* Saved copy_size bytes */                ctx->stream.avail_in -= copy_size;                ctx->validation_buffer_length += copy_size;            }            if (ctx->stream.avail_in) {                ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                              "Zlib: %d bytes of garbage at the end of "                              "compressed stream.", ctx->stream.avail_in);                /*                 * There is nothing worth consuming for zlib left, because it is                 * either garbage data or the data has been copied to the                 * validation buffer (processing validation data is no business                 * for zlib). So set ctx->stream.avail_in to zero to indicate                 * this to the following while loop.                 */                ctx->stream.avail_in = 0;            }        }        zRC = Z_OK;        while (ctx->stream.avail_in != 0) {            if (ctx->stream.avail_out == 0) {                ctx->stream.next_out = ctx->buffer;                len = c->bufferSize - ctx->stream.avail_out;                ctx->crc = crc32(ctx->crc, (const Bytef *)ctx->buffer, len);                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 = inflate(&ctx->stream, Z_NO_FLUSH);            if (zRC == Z_STREAM_END) {                /*                 * We have inflated all data. Now try to capture the                 * validation bytes. We may not have them all available                 * right now, but capture what is there.                 */                ctx->validation_buffer = apr_pcalloc(f->r->pool,                                                     VALIDATION_SIZE);                if (ctx->stream.avail_in > VALIDATION_SIZE) {                    ctx->validation_buffer_length = VALIDATION_SIZE;                    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,                                  "Zlib: %d bytes of garbage at the end of "                                  "compressed stream.",                                  ctx->stream.avail_in - VALIDATION_SIZE);                } else if (ctx->stream.avail_in > 0) {                           ctx->validation_buffer_length = ctx->stream.avail_in;                }                if (ctx->validation_buffer_length)                    memcpy(ctx->validation_buffer, ctx->stream.next_in,                           ctx->validation_buffer_length);                break;            }            if (zRC != Z_OK) {                return APR_EGENERAL;            }        }        apr_bucket_delete(e);    }    apr_brigade_cleanup(bb);    return APR_SUCCESS;}#define PROTO_FLAGS AP_FILTER_PROTO_CHANGE|AP_FILTER_PROTO_CHANGE_LENGTHstatic void register_hooks(apr_pool_t *p){    ap_register_output_filter(deflateFilterName, deflate_out_filter, NULL,                              AP_FTYPE_CONTENT_SET);    ap_register_output_filter("INFLATE", inflate_out_filter, NULL,                              AP_FTYPE_RESOURCE-1);    ap_register_input_filter(deflateFilterName, deflate_in_filter, NULL,                              AP_FTYPE_CONTENT_SET);}static const command_rec deflate_filter_cmds[] = {    AP_INIT_TAKE12("DeflateFilterNote", deflate_set_note, NULL, RSRC_CONF,                  "Set a note to report on compression ratio"),    AP_INIT_TAKE1("DeflateWindowSize", deflate_set_window_size, NULL,                  RSRC_CONF, "Set the Deflate window size (1-15)"),    AP_INIT_TAKE1("DeflateBufferSize", deflate_set_buffer_size, NULL, RSRC_CONF,                  "Set the Deflate Buffer Size"),    AP_INIT_TAKE1("DeflateMemLevel", deflate_set_memlevel, NULL, RSRC_CONF,                  "Set the Deflate Memory Level (1-9)"),    AP_INIT_TAKE1("DeflateCompressionLevel", deflate_set_compressionlevel, NULL, RSRC_CONF,                  "Set the Deflate Compression Level (1-9)"),    {NULL}};module AP_MODULE_DECLARE_DATA deflate_module = {    STANDARD20_MODULE_STUFF,    NULL,                         /* dir config creater */    NULL,                         /* dir merger --- default is to override */    create_deflate_server_config, /* server config */    NULL,                         /* merge server config */    deflate_filter_cmds,          /* command table */    register_hooks                /* register hooks */};

⌨️ 快捷键说明

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