/*
* Copyright (C) Joshua Zhu,
*/
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>
typedef struct {
ngx_flag_t enable;
} ngx_http_guolvqi_loc_conf_t;
static u_char post_str[] = " FIltered by \"guolvqi\"!";
static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
static void* ngx_http_guolvqi_create_loc_conf(ngx_conf_t *cf);
static char* ngx_http_guolvqi_merge_loc_conf(ngx_conf_t *cf,
void *parent, void *child);
static ngx_int_t
ngx_http_guolvqi_filter_init(ngx_conf_t *cf);
static ngx_command_t ngx_http_guolvqi_commands[] = {
{ ngx_string("enable_guolvqi"),
NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
0,
NULL },
ngx_null_command
};
static ngx_http_module_t ngx_http_guolvqi_module_ctx = {
NULL, /* preconfiguration */
ngx_http_guolvqi_filter_init, /* postconfiguration */
NULL, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
ngx_http_guolvqi_create_loc_conf, /* create location configuration */
ngx_http_guolvqi_merge_loc_conf /* merge location configuration */
};
ngx_module_t ngx_http_guolvqi_module = {
NGX_MODULE_V1,
&ngx_http_guolvqi_module_ctx, /* module context */
ngx_http_guolvqi_commands, /* module directives */
NGX_HTTP_MODULE, /* module type */
NULL, /* init master */
NULL, /* init module */
NULL, /* init process */
NULL, /* init thread */
NULL, /* exit thread */
NULL, /* exit process */
NULL, /* exit master */
NGX_MODULE_V1_PADDING
};
static ngx_int_t
ngx_http_guolvqi_header_filter(ngx_http_request_t *r)
{
// ngx_int_t rc;
ngx_http_guolvqi_loc_conf_t *conf;
conf = ngx_http_get_module_loc_conf(r, ngx_http_guolvqi_module);
// rc = ngx_http_discard_request_body(r);
if(conf->enable) {
r->headers_out.charset.len = sizeof("UTF-8") - 1;
r->headers_out.charset.data = (u_char *)"UTF-8";
/* set the 'Content-type' header */
r->headers_out.content_type_len = sizeof("text/html") - 1;
r->headers_out.content_type.len = sizeof("text/html") - 1;
r->headers_out.content_type.data = (u_char *) "text/html";
/* set the status line */
r->headers_out.status = NGX_HTTP_OK; // NGX_HTTP_NOT_MODIFIED
// r->headers_out.content_length_n = -1; // += sizeof(post_str) - 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_guolvqi_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
ngx_http_guolvqi_loc_conf_t *conf;
int has_last = 0;
ngx_buf_t b; // *b;
ngx_chain_t nc, *cc, *last;
if(in == NULL || r->header_only) {
return ngx_http_next_body_filter(r, in);
}
conf = ngx_http_get_module_loc_conf(r, ngx_http_guolvqi_module);
if(!conf->enable)
return ngx_http_next_body_filter(r, in);
for (cc = in; cc != NULL; cc = cc->next) {
last = cc;
if (cc->buf->last_buf) {
has_last = 1;
// cc->buf->sync = 1;
cc->buf->last_buf = 0;
// cc->buf->last_in_chain = 0;
// break;
}
}
if (!has_last)
return ngx_http_next_body_filter(r, in);
/*b = ngx_calloc_buf(r->pool);
if (b == NULL) {
return NGX_ERROR;
}*/
b.pos = post_str;
b.last = b.pos + sizeof(post_str) - 1;
b.memory = 1;
b.last_buf = 1;
// b.last_in_chain = 1;
nc.buf = &b;
nc.next = NULL;
last->next = &nc;
return ngx_http_next_body_filter(r, in);
}
static ngx_int_t
ngx_http_guolvqi_filter_init(ngx_conf_t *cf)
{
ngx_http_next_header_filter = ngx_http_top_header_filter;
ngx_http_top_header_filter = ngx_http_guolvqi_header_filter;
ngx_http_next_body_filter = ngx_http_top_body_filter;
ngx_http_top_body_filter = ngx_http_guolvqi_body_filter;
return NGX_OK;
}
static void *
ngx_http_guolvqi_create_loc_conf(ngx_conf_t *cf)
{
ngx_http_guolvqi_loc_conf_t *conf;
conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_guolvqi_loc_conf_t));
if (conf == NULL) {
return NGX_CONF_ERROR;
}
conf->enable = NGX_CONF_UNSET;
return conf;
}
static char *
ngx_http_guolvqi_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_http_guolvqi_loc_conf_t *prev = parent;
ngx_http_guolvqi_loc_conf_t *conf = child;
ngx_conf_merge_value(conf->enable, prev->enable, 0);
return NGX_CONF_OK;
}
|