static ngx_int_t ngx_http_sub_header_filter(ngx_http_request_t *r) { ngx_http_sub_ctx_t *ctx; ngx_http_sub_loc_conf_t *slcf; slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module); if (slcf->match.len == 0 || r->headers_out.content_length_n == 0 || ngx_http_test_content_type(r, &slcf->types) == NULL) { return ngx_http_next_header_filter(r); } ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module); ctx->match = slcf->match; ctx->last_out = &ctx->out; r->filter_need_in_memory = 1; if (r == r->main) { ngx_http_clear_content_length(r); ngx_http_clear_last_modified(r); } return ngx_http_next_header_filter(r); }
static ngx_int_t ngx_http_xslt_send(ngx_http_request_t *r, ngx_http_xslt_filter_ctx_t *ctx, ngx_buf_t *b) { ngx_int_t rc; ngx_chain_t out; ngx_pool_cleanup_t *cln; ngx_http_xslt_filter_loc_conf_t *conf; ctx->done = 1; if (b == NULL) { return ngx_http_filter_finalize_request(r, &ngx_http_xslt_filter_module, NGX_HTTP_INTERNAL_SERVER_ERROR); } cln = ngx_pool_cleanup_add(r->pool, 0); if (cln == NULL) { ngx_free(b->pos); return ngx_http_filter_finalize_request(r, &ngx_http_xslt_filter_module, NGX_HTTP_INTERNAL_SERVER_ERROR); } if (r == r->main) { r->headers_out.content_length_n = b->last - b->pos; if (r->headers_out.content_length) { r->headers_out.content_length->hash = 0; r->headers_out.content_length = NULL; } ngx_http_clear_etag(r); conf = ngx_http_get_module_loc_conf(r, ngx_http_xslt_filter_module); if (!conf->last_modified) { ngx_http_clear_last_modified(r); } } rc = ngx_http_next_header_filter(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { ngx_free(b->pos); return rc; } cln->handler = ngx_http_xslt_cleanup; cln->data = b->pos; out.buf = b; out.next = NULL; return ngx_http_next_body_filter(r, &out); }
static ngx_int_t ngx_http_subs_header_filter(ngx_http_request_t *r) { ngx_http_subs_loc_conf_t *slcf; slcf = ngx_http_get_module_loc_conf(r, ngx_http_subs_filter_module); if (slcf->sub_pairs->nelts == 0 || r->header_only || r->headers_out.content_type.len == 0 || r->headers_out.content_length_n == 0 || r->headers_out.status != NGX_HTTP_OK) { return ngx_http_next_header_filter(r); } if (ngx_http_test_content_type(r, &slcf->types) == NULL) { return ngx_http_next_header_filter(r); } /* Don't do substitution with the compressed content */ if (r->headers_out.content_encoding && r->headers_out.content_encoding->value.len) { ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, "http subs filter header ignored, this may be a " "compressed response."); return ngx_http_next_header_filter(r); } ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http subs filter header \"%V\"", &r->uri); if (ngx_http_subs_init_context(r) == NGX_ERROR) { return NGX_ERROR; } r->filter_need_in_memory = 1; if (r == r->main) { ngx_http_clear_content_length(r); ngx_http_clear_last_modified(r); } return ngx_http_next_header_filter(r); }
static ngx_int_t ngx_http_sub_header_filter(ngx_http_request_t *r) { ngx_http_sub_ctx_t *ctx; ngx_http_sub_loc_conf_t *slcf; slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module); if (!slcf->wm_struct || r->headers_out.content_length_n == 0 || ngx_http_test_content_type(r, &slcf->types) == NULL) { return ngx_http_next_header_filter(r); } ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } ctx->tmp.data = ngx_pnalloc(r->pool, slcf->tmp_buf_size); if (ctx->tmp.data == NULL) { return NGX_ERROR; } ctx->tmp.len = slcf->tmp_buf_size; ctx->repl = ngx_pcalloc(r->pool, slcf->values->nelts * sizeof(ngx_str_t)); ctx->wm_struct = slcf->wm_struct; ctx->values = slcf->values->elts; ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module); ctx->last_out = &ctx->out; r->filter_need_in_memory = 1; if (r == r->main) { ngx_http_clear_content_length(r); ngx_http_clear_last_modified(r); ngx_http_clear_etag(r); } return ngx_http_next_header_filter(r); }
static ngx_int_t ngx_http_send_refresh(ngx_http_request_t *r) { u_char *p, *location; size_t len, size; uintptr_t escape; ngx_int_t rc; ngx_buf_t *b; ngx_chain_t out; len = r->headers_out.location->value.len; location = r->headers_out.location->value.data; escape = 2 * ngx_escape_uri(NULL, location, len, NGX_ESCAPE_REFRESH); size = sizeof(ngx_http_msie_refresh_head) - 1 + escape + len + sizeof(ngx_http_msie_refresh_tail) - 1; r->err_status = NGX_HTTP_OK; r->headers_out.content_type_len = sizeof("text/html") - 1; ngx_str_set(&r->headers_out.content_type, "text/html"); r->headers_out.content_type_lowcase = NULL; r->headers_out.location->hash = 0; r->headers_out.location = NULL; r->headers_out.content_length_n = size; if (r->headers_out.content_length) { r->headers_out.content_length->hash = 0; r->headers_out.content_length = NULL; } ngx_http_clear_accept_ranges(r); ngx_http_clear_last_modified(r); ngx_http_clear_etag(r); rc = ngx_http_send_header(r); if (rc == NGX_ERROR || r->header_only) { return rc; } b = ngx_create_temp_buf(r->pool, size); if (b == NULL) { return NGX_ERROR; } p = ngx_cpymem(b->pos, ngx_http_msie_refresh_head, sizeof(ngx_http_msie_refresh_head) - 1); if (escape == 0) { p = ngx_cpymem(p, location, len); } else { p = (u_char *) ngx_escape_uri(p, location, len, NGX_ESCAPE_REFRESH); } b->last = ngx_cpymem(p, ngx_http_msie_refresh_tail, sizeof(ngx_http_msie_refresh_tail) - 1); b->last_buf = 1; b->last_in_chain = 1; out.buf = b; out.next = NULL; return ngx_http_output_filter(r, &out); }
static ngx_int_t ngx_http_send_special_response(ngx_http_request_t *r, ngx_http_core_loc_conf_t *clcf, ngx_uint_t err) { u_char *tail; size_t len; ngx_int_t rc; ngx_buf_t *b; ngx_uint_t msie_padding; ngx_chain_t out[3]; if (clcf->server_tokens) { len = sizeof(ngx_http_error_full_tail) - 1; tail = ngx_http_error_full_tail; } else { len = sizeof(ngx_http_error_tail) - 1; tail = ngx_http_error_tail; } msie_padding = 0; if (ngx_http_error_pages[err].len) { r->headers_out.content_length_n = ngx_http_error_pages[err].len + len; if (clcf->msie_padding && (r->headers_in.msie || r->headers_in.chrome) && r->http_version >= NGX_HTTP_VERSION_10 && err >= NGX_HTTP_OFF_4XX) { r->headers_out.content_length_n += sizeof(ngx_http_msie_padding) - 1; msie_padding = 1; } r->headers_out.content_type_len = sizeof("text/html") - 1; ngx_str_set(&r->headers_out.content_type, "text/html"); r->headers_out.content_type_lowcase = NULL; } else { r->headers_out.content_length_n = 0; } if (r->headers_out.content_length) { r->headers_out.content_length->hash = 0; r->headers_out.content_length = NULL; } ngx_http_clear_accept_ranges(r); ngx_http_clear_last_modified(r); ngx_http_clear_etag(r); rc = ngx_http_send_header(r); if (rc == NGX_ERROR || r->header_only) { return rc; } if (ngx_http_error_pages[err].len == 0) { return ngx_http_send_special(r, NGX_HTTP_LAST); } b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_ERROR; } b->memory = 1; b->pos = ngx_http_error_pages[err].data; b->last = ngx_http_error_pages[err].data + ngx_http_error_pages[err].len; out[0].buf = b; out[0].next = &out[1]; b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_ERROR; } b->memory = 1; b->pos = tail; b->last = tail + len; out[1].buf = b; out[1].next = NULL; if (msie_padding) { b = ngx_calloc_buf(r->pool); if (b == NULL) { return NGX_ERROR; } b->memory = 1; b->pos = ngx_http_msie_padding; b->last = ngx_http_msie_padding + sizeof(ngx_http_msie_padding) - 1; out[1].next = &out[2]; out[2].buf = b; out[2].next = NULL; } if (r == r->main) { b->last_buf = 1; } b->last_in_chain = 1; return ngx_http_output_filter(r, &out[0]); }
static ngx_int_t ngx_http_replace_header_filter(ngx_http_request_t *r) { size_t size; ngx_str_t skip; ngx_pool_cleanup_t *cln; ngx_http_replace_ctx_t *ctx; ngx_http_replace_loc_conf_t *rlcf; rlcf = ngx_http_get_module_loc_conf(r, ngx_http_replace_filter_module); dd("replace header filter"); if (rlcf->regexes.nelts == 0 || r->headers_out.content_length_n == 0 || (r->headers_out.content_encoding && r->headers_out.content_encoding->value.len) || ngx_http_test_content_type(r, &rlcf->types) == NULL) { return ngx_http_next_header_filter(r); } dd("skip: %p", rlcf->skip); if (rlcf->skip != NULL) { if (ngx_http_complex_value(r, rlcf->skip, &skip) != NGX_OK) { return NGX_ERROR; } if (skip.len && (skip.len != 1 || skip.data[0] != '0')) { return ngx_http_next_header_filter(r); } } ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_replace_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } ctx->last_special = &ctx->special; ctx->last_pending = &ctx->pending; ctx->last_pending2 = &ctx->pending2; ctx->last_captured = &ctx->captured; ctx->sub = ngx_pcalloc(r->pool, rlcf->multi_replace.nelts * sizeof(ngx_str_t)); if (ctx->sub == NULL) { return NGX_ERROR; } ctx->ovector = ngx_palloc(r->pool, rlcf->ovecsize); if (ctx->ovector == NULL) { return NGX_ERROR; } size = ngx_align(rlcf->regexes.nelts, 8) / 8; ctx->disabled = ngx_pcalloc(r->pool, size); if (ctx->disabled == NULL) { return NGX_ERROR; } ctx->vm_pool = sre_create_pool(1024); if (ctx->vm_pool == NULL) { return NGX_ERROR; } dd("created vm pool %p", ctx->vm_pool); cln = ngx_pool_cleanup_add(r->pool, 0); if (cln == NULL) { sre_destroy_pool(ctx->vm_pool); return NGX_ERROR; } cln->data = ctx->vm_pool; cln->handler = ngx_http_replace_cleanup_pool; ctx->vm_ctx = sre_vm_pike_create_ctx(ctx->vm_pool, rlcf->program, ctx->ovector, rlcf->ovecsize); if (ctx->vm_ctx == NULL) { return NGX_ERROR; } ngx_http_set_ctx(r, ctx, ngx_http_replace_filter_module); ctx->last_out = &ctx->out; r->filter_need_in_memory = 1; if (r == r->main) { ngx_http_clear_content_length(r); if (rlcf->last_modified == NGX_HTTP_REPLACE_CLEAR_LAST_MODIFIED) { ngx_http_clear_last_modified(r); } } return ngx_http_next_header_filter(r); }
static ngx_int_t ngx_http_sub_header_filter(ngx_http_request_t *r) { ngx_str_t *m; ngx_uint_t i, j, n; ngx_http_sub_ctx_t *ctx; ngx_http_sub_pair_t *pairs; ngx_http_sub_match_t *matches; ngx_http_sub_loc_conf_t *slcf; slcf = ngx_http_get_module_loc_conf(r, ngx_http_sub_filter_module); if (slcf->pairs == NULL || r->headers_out.content_length_n == 0 || ngx_http_test_content_type(r, &slcf->types) == NULL) { return ngx_http_next_header_filter(r); } ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } if (slcf->dynamic == 0) { ctx->tables = slcf->tables; ctx->matches = slcf->matches; } else { pairs = slcf->pairs->elts; n = slcf->pairs->nelts; matches = ngx_pcalloc(r->pool, sizeof(ngx_http_sub_match_t) * n); if (matches == NULL) { return NGX_ERROR; } j = 0; for (i = 0; i < n; i++) { matches[j].value = &pairs[i].value; if (pairs[i].match.lengths == NULL) { matches[j].match = pairs[i].match.value; j++; continue; } m = &matches[j].match; if (ngx_http_complex_value(r, &pairs[i].match, m) != NGX_OK) { return NGX_ERROR; } if (m->len == 0) { continue; } ngx_strlow(m->data, m->data, m->len); j++; } if (j == 0) { return ngx_http_next_header_filter(r); } ctx->matches = ngx_palloc(r->pool, sizeof(ngx_array_t)); if (ctx->matches == NULL) { return NGX_ERROR; } ctx->matches->elts = matches; ctx->matches->nelts = j; ctx->tables = ngx_palloc(r->pool, sizeof(ngx_http_sub_tables_t)); if (ctx->tables == NULL) { return NGX_ERROR; } ngx_http_sub_init_tables(ctx->tables, ctx->matches->elts, ctx->matches->nelts); } ngx_http_set_ctx(r, ctx, ngx_http_sub_filter_module); ctx->saved.data = ngx_pnalloc(r->pool, ctx->tables->max_match_len - 1); if (ctx->saved.data == NULL) { return NGX_ERROR; } ctx->looked.data = ngx_pnalloc(r->pool, ctx->tables->max_match_len - 1); if (ctx->looked.data == NULL) { return NGX_ERROR; } ctx->offset = ctx->tables->min_match_len - 1; ctx->last_out = &ctx->out; r->filter_need_in_memory = 1; if (r == r->main) { ngx_http_clear_content_length(r); if (!slcf->last_modified) { ngx_http_clear_last_modified(r); ngx_http_clear_etag(r); } else { ngx_http_weak_etag(r); } } return ngx_http_next_header_filter(r); }