static ngx_int_t ngx_http_addition_header_filter(ngx_http_request_t *r) { ngx_http_addition_ctx_t *ctx; ngx_http_addition_conf_t *conf; if (r->headers_out.status != NGX_HTTP_OK || r != r->main) { return ngx_http_next_header_filter(r); } conf = ngx_http_get_module_loc_conf(r, ngx_http_addition_filter_module); if (conf->before_body.len == 0 && conf->after_body.len == 0) { return ngx_http_next_header_filter(r); } if (ngx_http_test_content_type(r, &conf->types) == NULL) { return ngx_http_next_header_filter(r); } ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_addition_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } ngx_http_set_ctx(r, ctx, ngx_http_addition_filter_module); ngx_http_clear_content_length(r); ngx_http_clear_accept_ranges(r); ngx_http_clear_etag(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_gunzip_header_filter(ngx_http_request_t *r) { ngx_http_gunzip_ctx_t *ctx; ngx_http_gunzip_conf_t *conf; conf = ngx_http_get_module_loc_conf(r, ngx_http_gunzip_filter_module); /* TODO support multiple content-codings */ /* TODO always gunzip - due to configuration or module request */ /* TODO ignore content encoding? */ if (!conf->enable || r->headers_out.content_encoding == NULL || r->headers_out.content_encoding->value.len != 4 || ngx_strncasecmp(r->headers_out.content_encoding->value.data, (u_char *) "gzip", 4) != 0) { return ngx_http_next_header_filter(r); } r->gzip_vary = 1; if (!r->gzip_tested) { if (ngx_http_gzip_ok(r) == NGX_OK) { return ngx_http_next_header_filter(r); } } else if (r->gzip_ok) { return ngx_http_next_header_filter(r); } ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_gunzip_ctx_t)); if (ctx == NULL) { return NGX_ERROR; } ngx_http_set_ctx(r, ctx, ngx_http_gunzip_filter_module); ctx->request = r; r->filter_need_in_memory = 1; r->headers_out.content_encoding->hash = 0; r->headers_out.content_encoding = NULL; ngx_http_clear_content_length(r); ngx_http_clear_accept_ranges(r); ngx_http_clear_etag(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->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; } ctx->saved.data = ngx_pnalloc(r->pool, slcf->match.len); if (ctx->saved.data == NULL) { return NGX_ERROR; } ctx->looked.data = ngx_pnalloc(r->pool, slcf->match.len); if (ctx->looked.data == 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); 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); }
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); }
ngx_int_t ngx_http_secure_token_init_body_filter(ngx_http_request_t *r, ngx_str_t* token) { ngx_http_secure_token_loc_conf_t *conf; ngx_http_secure_token_ctx_t* ctx; body_processor_t* processor; conf = ngx_http_get_module_loc_conf(r, ngx_http_secure_token_filter_module); // Note: content_type_lowcase is already initialized since we called ngx_http_test_content_type processor = ngx_hash_find(&conf->processors_hash, r->headers_out.content_type_hash, r->headers_out.content_type_lowcase, r->headers_out.content_type_len); if (processor == NULL) { return NGX_DONE; } // add the token to all the URLs in the response ctx = ngx_pcalloc(r->pool, sizeof(*ctx)); if (ctx == NULL) { return NGX_ERROR; } ctx->token = *token; ctx->process = processor->process; ctx->processor_context_offset = processor->processor_context_offset; ctx->processor_params = processor->processor_params; ngx_http_set_ctx(r, ctx, ngx_http_secure_token_filter_module); ctx->last_out = &ctx->out; r->filter_need_in_memory = 1; ngx_http_clear_content_length(r); ngx_http_clear_accept_ranges(r); ngx_http_clear_etag(r); return NGX_OK; }
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_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); }