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

📄 ngx_http_sub_filter_module.c

📁 Nginx是一个高性能的HTTP和反向代理服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
                    cl = ngx_alloc_chain_link(r->pool);                    if (cl == NULL) {                        return NGX_ERROR;                    }                    cl->buf = b;                }                b->sync = 1;                cl->next = NULL;                *ctx->last_out = cl;                ctx->last_out = &cl->next;            }            b->last_buf = ctx->buf->last_buf;            b->shadow = ctx->buf;            b->recycled = ctx->buf->recycled;        }        ctx->buf = NULL;        ctx->saved = ctx->looked;    }    if (ctx->out == NULL && ctx->busy == NULL) {        return NGX_OK;    }    return ngx_http_sub_output(r, ctx);}static ngx_int_tngx_http_sub_output(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx){    ngx_int_t     rc;    ngx_buf_t    *b;    ngx_chain_t  *cl;#if 1    b = NULL;    for (cl = ctx->out; cl; cl = cl->next) {        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,                       "sub out: %p %p", cl->buf, cl->buf->pos);        if (cl->buf == b) {            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,                          "the same buf was used in sub");            ngx_debug_point();            return NGX_ERROR;        }        b = cl->buf;    }#endif    rc = ngx_http_next_body_filter(r, ctx->out);    if (ctx->busy == NULL) {        ctx->busy = ctx->out;    } else {        for (cl = ctx->busy; cl->next; cl = cl->next) { /* void */ }        cl->next = ctx->out;    }    ctx->out = NULL;    ctx->last_out = &ctx->out;    while (ctx->busy) {        cl = ctx->busy;        b = cl->buf;        if (ngx_buf_size(b) != 0) {            break;        }#if (NGX_HAVE_WRITE_ZEROCOPY)        if (b->zerocopy_busy) {            break;        }#endif        if (b->shadow) {            b->shadow->pos = b->shadow->last;        }        ctx->busy = cl->next;        if (ngx_buf_in_memory(b) || b->in_file) {            /* add data bufs only to the free buf chain */            cl->next = ctx->free;            ctx->free = cl;        }    }    if (ctx->in || ctx->buf) {        r->buffered |= NGX_HTTP_SUB_BUFFERED;    } else {        r->buffered &= ~NGX_HTTP_SUB_BUFFERED;    }    return rc;}static ngx_int_tngx_http_sub_parse(ngx_http_request_t *r, ngx_http_sub_ctx_t *ctx){    u_char                *p, *last, *copy_end, ch, match;    size_t                 looked;    ngx_http_sub_state_e   state;    if (ctx->once) {        ctx->copy_start = ctx->pos;        ctx->copy_end = ctx->buf->last;        ctx->pos = ctx->buf->last;        ctx->looked = 0;        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "once");        return NGX_AGAIN;    }    state = ctx->state;    looked = ctx->looked;    last = ctx->buf->last;    copy_end = ctx->copy_end;    for (p = ctx->pos; p < last; p++) {        ch = *p;        ch = ngx_tolower(ch);        if (state == sub_start_state) {            /* the tight loop */            match = ctx->match.data[0];            for ( ;; ) {                if (ch == match) {                    copy_end = p;                    looked = 1;                    state = sub_match_state;                    goto match_started;                }                if (++p == last) {                    break;                }                ch = *p;                ch = ngx_tolower(ch);            }            ctx->state = state;            ctx->pos = p;            ctx->looked = looked;            ctx->copy_end = p;            if (ctx->copy_start == NULL) {                ctx->copy_start = ctx->buf->pos;            }            return NGX_AGAIN;        match_started:            continue;        }        /* state == sub_match_state */        if (ch == ctx->match.data[looked]) {            looked++;            if (looked == ctx->match.len) {                if ((size_t) (p - ctx->pos) < looked) {                    ctx->saved = 0;                }                ctx->state = sub_start_state;                ctx->pos = p + 1;                ctx->looked = 0;                ctx->copy_end = copy_end;                if (ctx->copy_start == NULL && copy_end) {                    ctx->copy_start = ctx->buf->pos;                }                return NGX_OK;            }        } else if (ch == ctx->match.data[0]) {            copy_end = p;            looked = 1;        } else {            copy_end = p;            looked = 0;            state = sub_start_state;        }    }    ctx->state = state;    ctx->pos = p;    ctx->looked = looked;    ctx->copy_end = (state == sub_start_state) ? p : copy_end;    if (ctx->copy_start == NULL && ctx->copy_end) {        ctx->copy_start = ctx->buf->pos;    }    return NGX_AGAIN;}static char *ngx_http_sub_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){    ngx_http_sub_loc_conf_t *slcf = conf;    ngx_str_t                  *value;    ngx_int_t                   n;    ngx_uint_t                  i;    ngx_http_script_compile_t   sc;    if (slcf->match.len) {        return "is duplicate";    }    value = cf->args->elts;    slcf->match = value[1];    for (i = 0; i < value[1].len; i++) {        value[1].data[i] = ngx_tolower(value[1].data[i]);    }    n = ngx_http_script_variables_count(&value[2]);    if (n == 0) {        slcf->sub = value[2];        return NGX_CONF_OK;    }    ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));    sc.cf = cf;    sc.source = &value[2];    sc.lengths = &slcf->sub_lengths;    sc.values = &slcf->sub_values;    sc.variables = n;    sc.complete_lengths = 1;    sc.complete_values = 1;    if (ngx_http_script_compile(&sc) != NGX_OK) {        return NGX_CONF_ERROR;    }    return NGX_CONF_OK;}static char *ngx_http_sub_types(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){    ngx_http_sub_loc_conf_t *slcf = conf;    ngx_str_t   *value, *type;    ngx_uint_t   i;    if (slcf->types == NULL) {        slcf->types = ngx_array_create(cf->pool, 4, sizeof(ngx_str_t));        if (slcf->types == NULL) {            return NGX_CONF_ERROR;        }        type = ngx_array_push(slcf->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(slcf->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 void *ngx_http_sub_create_conf(ngx_conf_t *cf){    ngx_http_sub_loc_conf_t  *slcf;    slcf = ngx_pcalloc(cf->pool, sizeof(ngx_http_sub_loc_conf_t));    if (slcf == NULL) {        return NGX_CONF_ERROR;    }    /*     * set by ngx_pcalloc():     *     *     conf->match.len = 0;     *     conf->match.data = NULL;     *     conf->sub.len = 0;     *     conf->sub.data = NULL;     *     conf->sub_lengths = NULL;     *     conf->sub_values = NULL;     *     conf->types = NULL;     */    slcf->once = NGX_CONF_UNSET;    return slcf;}static char *ngx_http_sub_merge_conf(ngx_conf_t *cf, void *parent, void *child){    ngx_http_sub_loc_conf_t *prev = parent;    ngx_http_sub_loc_conf_t *conf = child;    ngx_str_t  *type;    ngx_conf_merge_value(conf->once, prev->once, 1);    ngx_conf_merge_str_value(conf->match, prev->match, "");    if (conf->sub.data == NULL && conf->sub_lengths == NULL) {        conf->sub = prev->sub;        conf->sub_lengths = prev->sub_lengths;        conf->sub_values = prev->sub_values;    }    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_sub_filter_init(ngx_conf_t *cf){    ngx_http_next_header_filter = ngx_http_top_header_filter;    ngx_http_top_header_filter = ngx_http_sub_header_filter;    ngx_http_next_body_filter = ngx_http_top_body_filter;    ngx_http_top_body_filter = ngx_http_sub_body_filter;    return NGX_OK;}

⌨️ 快捷键说明

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