static ngx_int_t ngx_http_breach_header_filter(ngx_http_request_t *r)
{
	ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,"BREACH HEADER FILTER Start!.");
	
	ngx_http_breach_conf_t  *conf;

	conf = ngx_http_get_module_loc_conf (r, ngx_http_breach_filter_module);

	if ((r->headers_out.status != NGX_HTTP_OK &&
		r->headers_out.status != NGX_HTTP_FORBIDDEN &&
		r->headers_out.status != NGX_HTTP_NOT_FOUND) ||
		r->header_only ||
		r->headers_out.content_type.len == 0 ||
		(r->headers_out.content_encoding &&
		r->headers_out.content_encoding->value.len) ||
		conf->enable == 0)
	{
			return ngx_http_next_header_filter(r);
	}

	if (ngx_strncasecmp(r->headers_out.content_type.data, (u_char *)"text/html", sizeof("text/html") - 1) != 0)
	{
		ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,"BREACH HEADER FILTER: this is not text/html content!.");
		return ngx_http_next_header_filter(r);
	}


	ngx_http_clear_content_length(r);
	ngx_http_clear_accept_ranges(r);

	ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,"BREACH HEADER FILTER: end!.");
	
	return ngx_http_next_header_filter(r);
}
static ngx_int_t ngx_http_dynamic_etags_header_filter(ngx_http_request_t *r) {

    ngx_http_dynamic_etags_module_ctx_t       *ctx;

    ctx = ngx_http_get_module_ctx(r, ngx_http_dynamic_etags_module);

    if (ctx) {
        return ngx_http_next_header_filter(r);
    }

    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_dynamic_etags_module_ctx_t));
    if (ctx == NULL) {
        return NGX_ERROR;
    }

    ngx_http_set_ctx(r, ctx, ngx_http_dynamic_etags_module);

    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);

    r->main_filter_need_in_memory = 1;
    r->filter_need_in_memory = 1;

    return NGX_OK;
}
ngx_int_t
ngx_http_lua_send_header_if_needed(ngx_http_request_t *r,
        ngx_http_lua_ctx_t *ctx)
{
    if ( ! ctx->headers_sent ) {
        if (r->headers_out.status == 0) {
            r->headers_out.status = NGX_HTTP_OK;
        }

        if (! ctx->headers_set && ngx_http_set_content_type(r) != NGX_OK) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        if (! ctx->headers_set) {
            ngx_http_clear_content_length(r);
            ngx_http_clear_accept_ranges(r);
        }

        if (r->http_version >= NGX_HTTP_VERSION_11) {
            /* Send response headers for HTTP version <= 1.0 elsewhere */
            ctx->headers_sent = 1;
            return ngx_http_send_header(r);
        }
    }

    return NGX_OK;
}
static ngx_int_t
ngx_http_foo_header_filter(ngx_http_request_t *r)
{
    ngx_log_error(NGX_LOG_NOTICE, r->connection->log, 0, "Header filter add header");
    ngx_table_elt_t  *h;

    /*
     * The filter handler adds "X-Foo: foo" header
     * to every HTTP 200 response
     */

    if (r->headers_out.status != NGX_HTTP_OK) {
        return ngx_http_next_header_filter(r);
    }

    h = ngx_list_push(&r->headers_out.headers);
    if (h == NULL) {
        return NGX_ERROR;
    }

    h->hash = 1;
    ngx_str_set(&h->key, "X-Foo");
    ngx_str_set(&h->value, "foo");

    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);
    ngx_http_weak_etag(r);

    return ngx_http_next_header_filter(r);
}
Exemplo n.º 5
0
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_charset_ctx(ngx_http_request_t *r, ngx_http_charset_t *charsets,
    ngx_int_t charset, ngx_int_t source_charset)
{
    ngx_http_charset_ctx_t  *ctx;

    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t));
    if (ctx == NULL) {
        return NGX_ERROR;
    }

    ngx_http_set_ctx(r, ctx, ngx_http_charset_filter_module);

    ctx->table = charsets[source_charset].tables[charset];
    ctx->charset = charset;
    ctx->charset_name = charsets[charset].name;
    ctx->length = charsets[charset].length;
    ctx->from_utf8 = charsets[source_charset].utf8;
    ctx->to_utf8 = charsets[charset].utf8;

    r->filter_need_in_memory = 1;

    if ((ctx->to_utf8 || ctx->from_utf8) && r == r->main) {
        ngx_http_clear_content_length(r);

    } else {
        r->filter_need_temporary = 1;
    }

    return ngx_http_next_header_filter(r);
}
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);

    return ngx_http_next_header_filter(r);
}
static ngx_int_t
ngx_http_range_not_satisfiable(ngx_http_request_t *r)
{
    ngx_table_elt_t  *content_range;

    r->headers_out.status = NGX_HTTP_RANGE_NOT_SATISFIABLE;

    content_range = ngx_list_push(&r->headers_out.headers);
    if (content_range == NULL) {
        return NGX_ERROR;
    }

    r->headers_out.content_range = content_range;

    content_range->hash = 1;
    ngx_str_set(&content_range->key, "Content-Range");

    content_range->value.data = ngx_pnalloc(r->pool,
                                       sizeof("bytes */") - 1 + NGX_OFF_T_LEN);
    if (content_range->value.data == NULL) {
        return NGX_ERROR;
    }

    content_range->value.len = ngx_sprintf(content_range->value.data,
                                           "bytes */%O",
                                           r->headers_out.content_length_n)
                               - content_range->value.data;

    ngx_http_clear_content_length(r);

    return NGX_HTTP_RANGE_NOT_SATISFIABLE;
}
ngx_int_t
ngx_http_echo_send_header_if_needed(ngx_http_request_t *r,
    ngx_http_echo_ctx_t *ctx)
{
    ngx_int_t                    rc;
    ngx_http_echo_loc_conf_t    *elcf;

    if (!r->header_sent && !ctx->header_sent) {
        elcf = ngx_http_get_module_loc_conf(r, ngx_http_echo_module);

        r->headers_out.status = (ngx_uint_t) elcf->status;

        if (ngx_http_set_content_type(r) != NGX_OK) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        ngx_http_clear_content_length(r);
        ngx_http_clear_accept_ranges(r);

        rc = ngx_http_send_header(r);
        ctx->header_sent = 1;
        return rc;
    }

    return NGX_OK;
}
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 ignore content encoding? */

    if (conf->enable == NGX_HTTP_GUNZIP_OFF
        || 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 (conf->enable == NGX_HTTP_GUNZIP_ON) {
        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);
        }

    } else if (conf->enable == NGX_HTTP_GUNZIP_ALWAYS
               && ngx_http_test_content_type(r, &conf->types) == NULL)
    {
               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_weak_etag(r);

    return ngx_http_next_header_filter(r);
}
Exemplo n.º 11
0
ngx_int_t
ngx_postgres_output_chain(ngx_http_request_t *r, ngx_chain_t *cl)
{
    ngx_http_upstream_t       *u = r->upstream;
    ngx_http_core_loc_conf_t  *clcf;
    ngx_postgres_loc_conf_t   *pglcf;
    ngx_postgres_ctx_t        *pgctx;
    ngx_int_t                  rc;

    dd("entering");

    if (!r->header_sent) {
        ngx_http_clear_content_length(r);

        pglcf = ngx_http_get_module_loc_conf(r, ngx_postgres_module);
        pgctx = ngx_http_get_module_ctx(r, ngx_postgres_module);

        r->headers_out.status = pgctx->status ? abs(pgctx->status)
                                              : NGX_HTTP_OK;

        if (pglcf->output_handler == &ngx_postgres_output_rds) {
            /* RDS for output rds */
            r->headers_out.content_type.data = (u_char *) rds_content_type;
            r->headers_out.content_type.len = rds_content_type_len;
            r->headers_out.content_type_len = rds_content_type_len;
        } else if (pglcf->output_handler != NULL) {
            /* default type for output value|row */
            clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

            r->headers_out.content_type = clcf->default_type;
            r->headers_out.content_type_len = clcf->default_type.len;
        }

        r->headers_out.content_type_lowcase = NULL;

        rc = ngx_http_send_header(r);
        if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
            dd("returning rc:%d", (int) rc);
            return rc;
        }
    }

    if (cl == NULL) {
        dd("returning NGX_DONE");
        return NGX_DONE;
    }

    rc = ngx_http_output_filter(r, cl);
    if (rc == NGX_ERROR || rc > NGX_OK) {
        dd("returning rc:%d", (int) rc);
        return rc;
    }

    ngx_chain_update_chains(&u->free_bufs, &u->busy_bufs, &cl, u->output.tag);

    dd("returning rc:%d", (int) rc);
    return rc;
}
static ngx_int_t
ngx_http_not_modified_header_filter(ngx_http_request_t *r)
{
    if (r->headers_out.status != NGX_HTTP_OK
        || r != r->main
        || r->disable_not_modified)
    {
        return ngx_http_next_header_filter(r);
    }

    if (r->headers_in.if_unmodified_since
        && !ngx_http_test_if_unmodified(r))
    {
        return ngx_http_filter_finalize_request(r, NULL,
                                                NGX_HTTP_PRECONDITION_FAILED);
    }

    if (r->headers_in.if_match
        && !ngx_http_test_if_match(r, r->headers_in.if_match, 0))
    {
        return ngx_http_filter_finalize_request(r, NULL,
                                                NGX_HTTP_PRECONDITION_FAILED);
    }

    if (r->headers_in.if_modified_since || r->headers_in.if_none_match) {

        if (r->headers_in.if_modified_since
            && ngx_http_test_if_modified(r))
        {
            return ngx_http_next_header_filter(r);
        }

        if (r->headers_in.if_none_match
            && !ngx_http_test_if_match(r, r->headers_in.if_none_match, 1))
        {
            return ngx_http_next_header_filter(r);
        }

        /* not modified */

        r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
        r->headers_out.status_line.len = 0;
        r->headers_out.content_type.len = 0;
        ngx_http_clear_content_length(r);
        ngx_http_clear_accept_ranges(r);

        if (r->headers_out.content_encoding) {
            r->headers_out.content_encoding->hash = 0;
            r->headers_out.content_encoding = NULL;
        }

        return ngx_http_next_header_filter(r);
    }

    return ngx_http_next_header_filter(r);
}
static ngx_int_t
ngx_http_charset_set_charset(ngx_http_request_t *r,
    ngx_http_charset_t *charsets, ngx_int_t charset, ngx_int_t source_charset)
{
    ngx_http_charset_ctx_t  *ctx;

    if (r->headers_out.status == NGX_HTTP_MOVED_PERMANENTLY
        || r->headers_out.status == NGX_HTTP_MOVED_TEMPORARILY)
    {
        /*
         * do not set charset for the redirect because NN 4.x
         * use this charset instead of the next page charset
         */

        r->headers_out.charset.len = 0;

        return ngx_http_next_header_filter(r);
    }

    r->headers_out.charset = charsets[charset].name;
    r->utf8 = charsets[charset].utf8;

    if (source_charset == NGX_CONF_UNSET || source_charset == charset) {
        return ngx_http_next_header_filter(r);
    }

    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_charset_ctx_t));
    if (ctx == NULL) {
        return NGX_ERROR;
    }

    ngx_http_set_ctx(r, ctx, ngx_http_charset_filter_module);

    ctx->table = charsets[source_charset].tables[charset];
    ctx->charset = charset;
    ctx->length = charsets[charset].length;
    ctx->from_utf8 = charsets[source_charset].utf8;
    ctx->to_utf8 = charsets[charset].utf8;

    r->filter_need_in_memory = 1;

    if ((ctx->to_utf8 || ctx->from_utf8) && r == r->main) {
        ngx_http_clear_content_length(r);

    } else {
        r->filter_need_temporary = 1;
    }

    return ngx_http_next_header_filter(r);
}
static ngx_int_t
ngx_http_not_modified_header_filter(ngx_http_request_t *r)
{
    time_t                     ims;
    ngx_http_core_loc_conf_t  *clcf;

    if (r->headers_out.status != NGX_HTTP_OK
        || r != r->main
        || r->headers_in.if_modified_since == NULL
        || r->headers_out.last_modified_time == -1)
    {
        return ngx_http_next_header_filter(r);
    }

    clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

    if (clcf->if_modified_since == NGX_HTTP_IMS_OFF) {
        return ngx_http_next_header_filter(r);
    }

    ims = ngx_http_parse_time(r->headers_in.if_modified_since->value.data,
                              r->headers_in.if_modified_since->value.len);

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "http ims:%d lm:%d", ims, r->headers_out.last_modified_time);

    if (ims != r->headers_out.last_modified_time) {

        if (clcf->if_modified_since == NGX_HTTP_IMS_EXACT
            || ims < r->headers_out.last_modified_time)
        {
            return ngx_http_next_header_filter(r);
        }
    }

    r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
    r->headers_out.status_line.len = 0;
    r->headers_out.content_type.len = 0;
    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);

    if (r->headers_out.content_encoding) {
        r->headers_out.content_encoding->hash = 0;
        r->headers_out.content_encoding = NULL;
    }

    return ngx_http_next_header_filter(r);
}
Exemplo n.º 15
0
static ngx_int_t
ngx_http_trim_header_filter(ngx_http_request_t *r)
{
    ngx_int_t                  rc;
    ngx_str_t                  flag;
    ngx_http_trim_ctx_t       *ctx;
    ngx_http_trim_loc_conf_t  *conf;

    conf = ngx_http_get_module_loc_conf(r, ngx_http_trim_filter_module);

    if (!conf->trim_enable
        || r->headers_out.status != NGX_HTTP_OK
        || (r->method & NGX_HTTP_HEAD)
        || 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, &conf->types) == NULL)
    {
        return ngx_http_next_header_filter(r);
    }

    rc = ngx_http_arg(r, (u_char *) NGX_HTTP_TRIM_FLAG,
                      sizeof(NGX_HTTP_TRIM_FLAG) - 1, &flag);

    if(rc == NGX_OK
       && flag.len == sizeof("off") - 1
       && ngx_strncmp(flag.data, "off", sizeof("off") - 1) == 0)
    {
        return ngx_http_next_header_filter(r);
    }

    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_trim_ctx_t));
    if (ctx == NULL) {
        return NGX_ERROR;
    }

    ctx->prev = ' ';
    ctx->first_line = 1;

    ngx_http_set_ctx(r, ctx, ngx_http_trim_filter_module);

    r->main_filter_need_in_memory = 1;

    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);

    return ngx_http_next_header_filter(r);
}
static ngx_int_t
ngx_http_srcache_send_not_modified(ngx_http_request_t *r)
{
    r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
    r->headers_out.status_line.len = 0;
    r->headers_out.content_type.len = 0;
    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);

    if (r->headers_out.content_encoding) {
        r->headers_out.content_encoding->hash = 0;
        r->headers_out.content_encoding = NULL;
    }

    return ngx_http_srcache_next_header_filter(r);
}
Exemplo n.º 17
0
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_echo_header_filter(ngx_http_request_t *r)
{
    ngx_http_echo_loc_conf_t    *conf;
    ngx_http_echo_ctx_t         *ctx;

    dd("We're in the header filter...");

    ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);

    /* XXX we should add option to insert contents for responses
     * of non-200 status code here... */
    /*
    if (r->headers_out.status != NGX_HTTP_OK) {
        if (ctx != NULL) {
            ctx->skip_filter = 1;
        }
        return ngx_http_echo_next_header_filter(r);
    }
    */

    conf = ngx_http_get_module_loc_conf(r, ngx_http_echo_module);
    if (conf->before_body_cmds == NULL && conf->after_body_cmds == NULL) {
        if (ctx != NULL) {
            ctx->skip_filter = 1;
        }
        return ngx_http_echo_next_header_filter(r);
    }

    if (ctx == NULL) {
        ctx = ngx_http_echo_create_ctx(r);
        if (ctx == NULL) {
            return NGX_ERROR;
        }

        ctx->headers_sent = 1;

        ngx_http_set_ctx(r, ctx, ngx_http_echo_module);
    }

    /* enable streaming here (use chunked encoding) */
    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);

    return ngx_http_echo_next_header_filter(r);
}
Exemplo n.º 19
0
static ngx_int_t
ngx_http_echo_header_filter(ngx_http_request_t *r)
{
    ngx_http_echo_loc_conf_t    *conf;
    ngx_http_echo_ctx_t         *ctx;

    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "echo header filter, uri \"%V?%V\"", &r->uri, &r->args);

    ctx = ngx_http_get_module_ctx(r, ngx_http_echo_module);

    /* XXX we should add option to insert contents for responses
     * of non-200 status code here... */
    /*
    if (r->headers_out.status != NGX_HTTP_OK) {
        if (ctx != NULL) {
            ctx->skip_filter = 1;
        }
        return ngx_http_echo_next_header_filter(r);
    }
    */

    conf = ngx_http_get_module_loc_conf(r, ngx_http_echo_module);
    if (conf->before_body_cmds == NULL && conf->after_body_cmds == NULL) {
        if (ctx != NULL) {
            ctx->skip_filter = 1;
        }
        return ngx_http_echo_next_header_filter(r);
    }

    if (ctx == NULL) {
        ctx = ngx_http_echo_create_ctx(r);
        if (ctx == NULL) {
            return NGX_ERROR;
        }

        ngx_http_set_ctx(r, ctx, ngx_http_echo_module);
    }

    /* enable streaming here (use chunked encoding) */
    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);

    return ngx_http_echo_next_header_filter(r);
}
Exemplo n.º 20
0
static ngx_int_t
ngx_http_iconv_header_filter(ngx_http_request_t *r)
{
    ngx_http_iconv_loc_conf_t       *ilcf;
    ngx_http_iconv_ctx_t            *ctx;

    ilcf = ngx_http_get_module_loc_conf(r, ngx_http_iconv_module);
    if (!ilcf->enabled) {
        return ngx_http_next_header_filter(r);
    }

    if (r->http_version < NGX_HTTP_VERSION_10) {
        ngx_log_error(NGX_LOG_WARN, r->connection->log, 0,
                      "iconv does not support HTTP < 1.0 yet");
        return ngx_http_next_header_filter(r);
    }

    if (r->http_version == NGX_HTTP_VERSION_10) {
        r->keepalive = 0;
    }

    iconv_buf_size = ilcf->buf_size;
    r->filter_need_in_memory = 1;

    ngx_http_clear_content_length(r);

    ctx = ngx_http_get_module_ctx(r, ngx_http_iconv_module);
    if (ctx == NULL) {
        dd("create new context");
        /*
         * set by ngx_pcalloc()
         *   ctx->uc->len = 0
         *   ctx->uc->data = NULL
         */
        ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_iconv_module));
        if (ctx == NULL) {
            return NGX_ERROR;
        }

        ngx_http_set_ctx(r, ctx, ngx_http_iconv_module);
    }

    return ngx_http_next_header_filter(r);
}
Exemplo n.º 21
0
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_echo_send_header_if_needed(ngx_http_request_t* r)
{

    if (!r->header_sent) {

        r->headers_out.status = 200;

        if (ngx_http_set_content_type(r) != NGX_OK) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        ngx_http_clear_content_length(r);
        ngx_http_clear_accept_ranges(r);

        return ngx_http_send_header(r);
    }

    return NGX_OK;
}
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_minify_header_filter(ngx_http_request_t *r)
{
    ngx_http_minify_conf_t  *conf;

    conf = ngx_http_get_module_loc_conf(r, ngx_http_minify_filter_module);

    if (!conf->enable
        || (r->headers_out.status != NGX_HTTP_OK
            && r->headers_out.status != NGX_HTTP_FORBIDDEN
            && r->headers_out.status != NGX_HTTP_NOT_FOUND)
        || (r->headers_out.content_encoding
            && r->headers_out.content_encoding->value.len)
        || ngx_http_test_content_type(r, &conf->types) == NULL
        || r->header_only)
    {
        return ngx_http_next_header_filter(r);
    }

    ngx_http_clear_content_length(r);
    return ngx_http_next_header_filter(r);
}
static ngx_int_t ngx_http_no_newlines_header_filter (ngx_http_request_t *r)
{
    ngx_http_no_newlines_ctx_t   *ctx;  /* to maintain state */
    ngx_http_no_newlines_conf_t  *conf; /* to check whether module is enabled or not */

    conf = ngx_http_get_module_loc_conf (r, ngx_http_no_newlines_module);

    /* step 1: decide whether to operate */
    if ((r->headers_out.status != NGX_HTTP_OK &&
            r->headers_out.status != NGX_HTTP_FORBIDDEN &&
            r->headers_out.status != NGX_HTTP_NOT_FOUND) ||
            r->header_only ||
            r->headers_out.content_type.len == 0 ||
            (r->headers_out.content_encoding &&
             r->headers_out.content_encoding->value.len) ||
            conf->enable == 0) {
        return ngx_http_next_header_filter(r);
    }

    if (ngx_strncasecmp(r->headers_out.content_type.data, (u_char *)"text/html", sizeof("text/html") - 1) != 0) {
        return ngx_http_next_header_filter(r);
    }

    /* step 2: operate on the header */
    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_no_newlines_ctx_t));
    if (ctx == NULL) {
        return NGX_ERROR;
    }

    ngx_http_set_ctx(r, ctx, ngx_http_no_newlines_module);

    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);
    r->main_filter_need_in_memory = 1;

    /* step 3: call the next filter */
    return ngx_http_next_header_filter(r);
}
ngx_int_t
ngx_http_echo_send_header_if_needed(ngx_http_request_t* r,
        ngx_http_echo_ctx_t *ctx) {
    /* ngx_int_t   rc; */

    if ( ! ctx->headers_sent ) {
        r->headers_out.status = NGX_HTTP_OK;

        if (ngx_http_set_content_type(r) != NGX_OK) {
            return NGX_HTTP_INTERNAL_SERVER_ERROR;
        }

        ngx_http_clear_content_length(r);
        ngx_http_clear_accept_ranges(r);

        if (r->http_version >= NGX_HTTP_VERSION_11) {
            ctx->headers_sent = 1;
            return ngx_http_send_header(r);
        }
    }

    return NGX_OK;
}
static ngx_int_t ngx_http_pb_msgpack_header_filter(ngx_http_request_t* r )
{
	if(r->headers_out.status != NGX_HTTP_OK)
	{
		return ngx_http_next_header_filter(r);
	}

	ngx_http_pb_msgpack_transfer_loc_conf_t* loc_conf = NULL;
	loc_conf = (ngx_http_pb_msgpack_transfer_loc_conf_t*) ngx_http_get_module_loc_conf(r, ngx_http_pb_msgpack_transfer_module);
	// flag is unset/0 , skip deal it
	if(0 == loc_conf->pbmsgpack_filter_flag || NGX_CONF_UNSET == loc_conf->pbmsgpack_filter_flag )
	{
		ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "output transfer flag is 0!");
		return ngx_http_next_header_filter(r);
	}

	if( r == r->main)
	{
		ngx_http_clear_content_length(r);
	}

	return ngx_http_next_header_filter(r);

}
static ngx_int_t
ngx_http_rds_json_header_filter(ngx_http_request_t *r)
{
    ngx_http_rds_json_ctx_t   *ctx;
    ngx_http_rds_json_conf_t  *conf;

    /* XXX maybe we can generate stub JSON strings like
     * {"errcode":403,"error":"Permission denied"}
     * for HTTP error pages? */
    if ((r->headers_out.status < NGX_HTTP_OK)
        || (r->headers_out.status >= NGX_HTTP_SPECIAL_RESPONSE)
        || (r->headers_out.status == NGX_HTTP_NO_CONTENT)
        || (r->headers_out.status == NGX_HTTP_RESET_CONTENT))
    {
        ngx_http_set_ctx(r, NULL, ngx_http_rds_json_filter_module);

        dd("status is not OK: %d, skipping", (int) r->headers_out.status);

        return ngx_http_rds_json_next_header_filter(r);
    }

    /* r->headers_out.status = 0; */

    conf = ngx_http_get_module_loc_conf(r, ngx_http_rds_json_filter_module);

    if ( ! conf->enabled) {
        return ngx_http_rds_json_next_header_filter(r);
    }

    if (ngx_http_rds_json_test_content_type(r) != NGX_OK) {
        return ngx_http_rds_json_next_header_filter(r);
    }

    r->headers_out.content_type = conf->content_type;
    r->headers_out.content_type_len = conf->content_type.len;

    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_rds_json_ctx_t));

    if (ctx == NULL) {
        return NGX_ERROR;
    }

    ctx->tag = (ngx_buf_tag_t) &ngx_http_rds_json_filter_module;

    ctx->state = state_expect_header;

    ctx->header_sent = 0;

    ctx->last_out = &ctx->out;

    /* set by ngx_pcalloc
     *      ctx->out       = NULL
     *      ctx->busy_bufs = NULL
     *      ctx->free_bufs = NULL
     *      ctx->cached = (ngx_buf_t) 0
     *      ctx->postponed = (ngx_buf_t) 0
     *      ctx->avail_out = 0
     *      ctx->col_names = NULL
     *      ctx->col_count = 0
     *      ctx->cur_col = 0
     *      ctx->field_offset = 0
     *      ctx->field_total = 0
     *      ctx->field_data_rest = 0
     */

    ngx_http_set_ctx(r, ctx, ngx_http_rds_json_filter_module);

    ngx_http_clear_content_length(r);

    r->filter_need_in_memory = 1;

    /* we do postpone the header sending to the body filter */
    return NGX_OK;
}
static ngx_int_t
ngx_http_brotli_header_filter(ngx_http_request_t *r)
{
    ngx_table_elt_t         *h;
    ngx_http_brotli_ctx_t   *ctx;
    ngx_http_brotli_conf_t  *conf;

    conf = ngx_http_get_module_loc_conf(r, ngx_http_brotli_filter_module);

    if (!conf->enable
        || (r->headers_out.status != NGX_HTTP_OK
            && r->headers_out.status != NGX_HTTP_FORBIDDEN
            && r->headers_out.status != NGX_HTTP_NOT_FOUND)
        || (r->headers_out.content_length_n != -1
            && r->headers_out.content_length_n < conf->min_length)
        || ngx_http_test_content_type(r, &conf->types) == NULL
        || r->header_only)
    {
        return ngx_http_next_header_filter(r);
    }

    if (r->headers_out.content_encoding
        && r->headers_out.content_encoding->value.len)
    {
        return ngx_http_next_header_filter(r);
    }

    /* Check that brotli is supported. We do not check possible q value
     * if brotli is supported it takes precendence over gzip if size >
     * brotli_min_length */
    if (accept_br(r->headers_in.accept_encoding) != NGX_OK) {
        return ngx_http_next_header_filter(r);
    }

    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_brotli_ctx_t));
    if (ctx == NULL) {
        return NGX_ERROR;
    }

#if (NGX_HTTP_GZIP)
    r->gzip_vary = 1;
    /* Make sure gzip does not execute */
    r->gzip_tested = 1;
    r->gzip_ok = 0;
#endif

    ngx_http_set_ctx(r, ctx, ngx_http_brotli_filter_module);

    ctx->request = r;

    h = ngx_list_push(&r->headers_out.headers);
    if (h == NULL) {
        return NGX_ERROR;
    }

    h->hash = 1;
    ngx_str_set(&h->key, "Content-Encoding");
    ngx_str_set(&h->value, "br");
    r->headers_out.content_encoding = h;

    r->main_filter_need_in_memory = 1;

    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);
    ngx_http_weak_etag(r);

    return ngx_http_next_header_filter(r);
}
static ngx_int_t
ngx_http_xss_header_filter(ngx_http_request_t *r)
{
    ngx_http_xss_ctx_t          *ctx;
    ngx_http_xss_loc_conf_t     *xlcf;
    ngx_str_t                    callback;
    u_char                      *p, *src, *dst;

    if (r != r->main) {
        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "xss skipped in subrequests");

        return ngx_http_next_header_filter(r);
    }

    xlcf = ngx_http_get_module_loc_conf(r, ngx_http_xss_filter_module);

    if (!xlcf->get_enabled) {
        return ngx_http_next_header_filter(r);
    }

    if (r->method != NGX_HTTP_GET) {
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "xss skipped due to the unmatched request method: %V",
                       &r->method_name);

        return ngx_http_next_header_filter(r);
    }

    if (xlcf->check_status) {

        if (r->headers_out.status != NGX_HTTP_OK
            && r->headers_out.status != NGX_HTTP_CREATED)
        {
            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "xss skipped due to unmatched response status "
                           "\"%ui\"", r->headers_out.status);

            return ngx_http_next_header_filter(r);
        }
    }

    if (xlcf->callback_arg.len == 0) {

        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "xss: xss_get is enabled but no xss_callback_arg "
                      "specified");

        return ngx_http_next_header_filter(r);
    }

    if (ngx_http_test_content_type(r, &xlcf->input_types) == NULL) {

        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "xss skipped due to unmatched Content-Type response "
                       "header");

        return ngx_http_next_header_filter(r);
    }

    if (ngx_http_arg(r, xlcf->callback_arg.data, xlcf->callback_arg.len,
                     &callback)
        != NGX_OK)
    {
        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                       "xss skipped: no GET argument \"%V\" specified in "
                       "the request", &xlcf->callback_arg);

        return ngx_http_next_header_filter(r);
    }

    p = ngx_palloc(r->pool, callback.len);
    if (p == NULL) {
        return NGX_ERROR;
    }

    src = callback.data; dst = p;

    ngx_unescape_uri(&dst, &src, callback.len, NGX_UNESCAPE_URI_COMPONENT);

    if (src != callback.data + callback.len) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "xss: unescape uri: input data not consumed completely");

        return NGX_ERROR;
    }

    callback.data = p;
    callback.len = dst - p;

    if (ngx_http_xss_test_callback(callback.data, callback.len) != NGX_OK) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "xss: bad callback argument: \"%V\"", &callback);

        return ngx_http_next_header_filter(r);
    }

    ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_xss_ctx_t));
    if (ctx == NULL) {
        return NGX_ERROR;
    }

    /*
     * set by ngx_pcalloc():
     *
     *     ctx->callback = { 0, NULL };
     *     ctx->before_body_sent = 0;
     */

    ctx->callback = callback;

    ngx_http_set_ctx(r, ctx, ngx_http_xss_filter_module);

    r->headers_out.content_type = xlcf->output_type;
    r->headers_out.content_type_len = xlcf->output_type.len;
    r->headers_out.content_type_lowcase = NULL;

    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "xss output Content-Type header \"%V\"",
                   &xlcf->output_type);

    ngx_http_clear_content_length(r);
    ngx_http_clear_accept_ranges(r);

    if (xlcf->override_status
        && r->headers_out.status >= NGX_HTTP_SPECIAL_RESPONSE)
    {
        r->headers_out.status = NGX_HTTP_OK;
    }

    return ngx_http_next_header_filter(r);
}