📄 util_filter.c
字号:
if (INSERT_BEFORE(f, *outf)) { f->next = *outf; if (*outf) { ap_filter_t *first = NULL; if (r) { /* If we are adding our first non-connection filter, * Then don't try to find the right location, it is * automatically first. */ if (*r_filters != *c_filters) { first = *r_filters; while (first && (first->next != (*outf))) { first = first->next; } } } if (first && first != (*outf)) { first->next = f; } } *outf = f; } else { ap_filter_t *fscan = *outf; while (!INSERT_BEFORE(f, fscan->next)) fscan = fscan->next; f->next = fscan->next; fscan->next = f; } if (frec->ftype < AP_FTYPE_CONNECTION && (*r_filters == *c_filters)) { *r_filters = *p_filters; } return f;}static ap_filter_t *add_any_filter(const char *name, void *ctx, request_rec *r, conn_rec *c, const filter_trie_node *reg_filter_set, ap_filter_t **r_filters, ap_filter_t **p_filters, ap_filter_t **c_filters){ if (reg_filter_set) { const char *n; const filter_trie_node *node; node = reg_filter_set; for (n = name; *n; n++) { int start, end; start = 0; end = node->nchildren - 1; while (end >= start) { int middle = (end + start) / 2; char ch = node->children[middle].c; if (*n == ch) { node = node->children[middle].child; break; } else if (*n < ch) { end = middle - 1; } else { start = middle + 1; } } if (end < start) { node = NULL; break; } } if (node && node->frec) { return add_any_filter_handle(node->frec, ctx, r, c, r_filters, p_filters, c_filters); } } ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "an unknown filter was not added: %s", name); return NULL;}AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx, request_rec *r, conn_rec *c){ return add_any_filter(name, ctx, r, c, registered_input_filters, r ? &r->input_filters : NULL, r ? &r->proto_input_filters : NULL, &c->input_filters);}AP_DECLARE(ap_filter_t *) ap_add_input_filter_handle(ap_filter_rec_t *f, void *ctx, request_rec *r, conn_rec *c){ return add_any_filter_handle(f, ctx, r, c, r ? &r->input_filters : NULL, r ? &r->proto_input_filters : NULL, &c->input_filters);}AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx, request_rec *r, conn_rec *c){ return add_any_filter(name, ctx, r, c, registered_output_filters, r ? &r->output_filters : NULL, r ? &r->proto_output_filters : NULL, &c->output_filters);}AP_DECLARE(ap_filter_t *) ap_add_output_filter_handle(ap_filter_rec_t *f, void *ctx, request_rec *r, conn_rec *c){ return add_any_filter_handle(f, ctx, r, c, r ? &r->output_filters : NULL, r ? &r->proto_output_filters : NULL, &c->output_filters);}static void remove_any_filter(ap_filter_t *f, ap_filter_t **r_filt, ap_filter_t **p_filt, ap_filter_t **c_filt){ ap_filter_t **curr = r_filt ? r_filt : c_filt; ap_filter_t *fscan = *curr; if (p_filt && *p_filt == f) *p_filt = (*p_filt)->next; if (*curr == f) { *curr = (*curr)->next; return; } while (fscan->next != f) { if (!(fscan = fscan->next)) { return; } } fscan->next = f->next;}AP_DECLARE(void) ap_remove_input_filter(ap_filter_t *f){ remove_any_filter(f, f->r ? &f->r->input_filters : NULL, f->r ? &f->r->proto_input_filters : NULL, &f->c->input_filters);}AP_DECLARE(void) ap_remove_output_filter(ap_filter_t *f){ remove_any_filter(f, f->r ? &f->r->output_filters : NULL, f->r ? &f->r->proto_output_filters : NULL, &f->c->output_filters);}/* * Read data from the next filter in the filter stack. Data should be * modified in the bucket brigade that is passed in. The core allocates the * bucket brigade, modules that wish to replace large chunks of data or to * save data off to the side should probably create their own temporary * brigade especially for that use. */AP_DECLARE(apr_status_t) ap_get_brigade(ap_filter_t *next, apr_bucket_brigade *bb, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes){ if (next) { return next->frec->filter_func.in_func(next, bb, mode, block, readbytes); } return AP_NOBODY_READ;}/* Pass the buckets to the next filter in the filter stack. If the * current filter is a handler, we should get NULL passed in instead of * the current filter. At that point, we can just call the first filter in * the stack, or r->output_filters. */AP_DECLARE(apr_status_t) ap_pass_brigade(ap_filter_t *next, apr_bucket_brigade *bb){ if (next) { apr_bucket *e; if ((e = APR_BRIGADE_LAST(bb)) && APR_BUCKET_IS_EOS(e) && next->r) { /* This is only safe because HTTP_HEADER filter is always in * the filter stack. This ensures that there is ALWAYS a * request-based filter that we can attach this to. If the * HTTP_FILTER is removed, and another filter is not put in its * place, then handlers like mod_cgi, which attach their own * EOS bucket to the brigade will be broken, because we will * get two EOS buckets on the same request. */ next->r->eos_sent = 1; /* remember the eos for internal redirects, too */ if (next->r->prev) { request_rec *prev = next->r->prev; while (prev) { prev->eos_sent = 1; prev = prev->prev; } } } return next->frec->filter_func.out_func(next, bb); } return AP_NOBODY_WROTE;}AP_DECLARE(apr_status_t) ap_save_brigade(ap_filter_t *f, apr_bucket_brigade **saveto, apr_bucket_brigade **b, apr_pool_t *p){ apr_bucket *e; apr_status_t rv, srv = APR_SUCCESS; /* If have never stored any data in the filter, then we had better * create an empty bucket brigade so that we can concat. */ if (!(*saveto)) { *saveto = apr_brigade_create(p, f->c->bucket_alloc); } APR_RING_FOREACH(e, &(*b)->list, apr_bucket, link) { rv = apr_bucket_setaside(e, p); /* If the bucket type does not implement setaside, then * (hopefully) morph it into a bucket type which does, and set * *that* aside... */ if (rv == APR_ENOTIMPL) { const char *s; apr_size_t n; rv = apr_bucket_read(e, &s, &n, APR_BLOCK_READ); if (rv == APR_SUCCESS) { rv = apr_bucket_setaside(e, p); } } if (rv != APR_SUCCESS) { srv = rv; /* Return an error but still save the brigade if * ->setaside() is really not implemented. */ if (rv != APR_ENOTIMPL) { return rv; } } } APR_BRIGADE_CONCAT(*saveto, *b); return srv;}AP_DECLARE_NONSTD(apr_status_t) ap_filter_flush(apr_bucket_brigade *bb, void *ctx){ ap_filter_t *f = ctx; return ap_pass_brigade(f, bb);}AP_DECLARE(apr_status_t) ap_fflush(ap_filter_t *f, apr_bucket_brigade *bb){ apr_bucket *b; b = apr_bucket_flush_create(f->c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(bb, b); return ap_pass_brigade(f, bb);}AP_DECLARE_NONSTD(apr_status_t) ap_fputstrs(ap_filter_t *f, apr_bucket_brigade *bb, ...){ va_list args; apr_status_t rv; va_start(args, bb); rv = apr_brigade_vputstrs(bb, ap_filter_flush, f, args); va_end(args); return rv;}AP_DECLARE_NONSTD(apr_status_t) ap_fprintf(ap_filter_t *f, apr_bucket_brigade *bb, const char *fmt, ...){ va_list args; apr_status_t rv; va_start(args, fmt); rv = apr_brigade_vprintf(bb, ap_filter_flush, f, fmt, args); va_end(args); return rv;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -