Skip to content

Commit

Permalink
add a directive to allow filter undesired parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
wandenberg committed Oct 13, 2015
1 parent 29efc88 commit a627143
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 3 deletions.
19 changes: 19 additions & 0 deletions README.md
Expand Up @@ -5,6 +5,8 @@ A module to order the querystring parameters in a variable to be used as cache k

Requests like /index.html?b=2&a=1&c=3, /index.html?b=2&c=3&a=1, /index.html?c=3&a=1&b=2, /index.html?c=3&b=2&a=1 will produce the same value for `$sorted_querystring_args` _'a=1&b=2&c=3'_.

It is also possible remove some undesired parameter defining its name with `sorted_querysting_filter_parameter`, like `sorted_querysting_filter_parameter b _ foo;` resulting in a `$sorted_querystring_args` as _'a=1&c=3'_

_This module is not distributed with the Nginx source. See [the installation instructions](#installation)._


Expand Down Expand Up @@ -46,6 +48,17 @@ An example:

access_log logs/nginx-http_access.log main;

location /filtered {
sorted_querysting_filter_parameter v _ time b;

proxy_set_header Host "static_files_server";
proxy_pass http://localhost:8081;

proxy_cache zone;
proxy_cache_key "$sorted_querystring_args";
proxy_cache_valid 200 1m;
}

location / {
proxy_pass http://localhost:8081;

Expand All @@ -71,6 +84,12 @@ Variables
* **$sorted_querystring_args** - just list the IP considered as remote IP on the connection


Directives
----------

* **sorted_querystring_filter_parameter** - list parameters to be filtered while using the `$sorted_querystring_args` variable.


<a id="installation"></a>Installation instructions
--------------------------------------------------

Expand Down
11 changes: 11 additions & 0 deletions nginx.conf
Expand Up @@ -34,6 +34,17 @@ http {

access_log logs/nginx-http_access.log main;

location /filtered {
sorted_querysting_filter_parameter v _ v time b;

proxy_set_header Host "static_files_server";
proxy_pass http://localhost:8081;

proxy_cache zone;
proxy_cache_key "$sorted_querystring_args";
proxy_cache_valid 200 1m;
}

location / {
proxy_pass http://localhost:8081;

Expand Down
116 changes: 113 additions & 3 deletions ngx_http_sorted_querystring_module.c
Expand Up @@ -5,9 +5,18 @@


ngx_int_t ngx_http_sorted_querystring_pre_config(ngx_conf_t *cf);
void *ngx_http_sorted_querystring_create_loc_conf(ngx_conf_t *cf);
char *ngx_http_sorted_querystring_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child);
char *ngx_conf_set_parameters_to_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
ngx_int_t ngx_http_sorted_querystring_args_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data);
ngx_int_t ngx_http_sorted_querystring_cmp_parameters(const ngx_queue_t *one, const ngx_queue_t *two);


typedef struct {
ngx_array_t *parameters_to_filter;
} ngx_http_sorted_querystring_loc_conf_t;


typedef struct {
ngx_queue_t args_queue;
} ngx_http_sorted_querystring_ctx_t;
Expand All @@ -31,6 +40,13 @@ static ngx_http_variable_t ngx_http_sorted_querystring_vars[] = {


static ngx_command_t ngx_http_sorted_querystring_commands[] = {
{ ngx_string("sorted_querysting_filter_parameter"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_1MORE,
ngx_conf_set_parameters_to_filter,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_sorted_querystring_loc_conf_t, parameters_to_filter),
NULL },

ngx_null_command
};

Expand All @@ -45,8 +61,8 @@ static ngx_http_module_t ngx_http_sorted_querystring_module_ctx = {
NULL, /* create server configuration */
NULL, /* merge server configuration */

NULL, /* create location configuration */
NULL /* merge location configuration */
ngx_http_sorted_querystring_create_loc_conf, /* create location configuration */
ngx_http_sorted_querystring_merge_loc_conf /* merge location configuration */
};


Expand Down Expand Up @@ -85,13 +101,92 @@ ngx_http_sorted_querystring_pre_config(ngx_conf_t *cf)
}


void *
ngx_http_sorted_querystring_create_loc_conf(ngx_conf_t *cf)
{
ngx_http_sorted_querystring_loc_conf_t *conf;

conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_sorted_querystring_loc_conf_t));
if (conf == NULL) {
return NULL;
}

conf->parameters_to_filter = NGX_CONF_UNSET_PTR;

return conf;
}


char *
ngx_http_sorted_querystring_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
ngx_http_sorted_querystring_loc_conf_t *prev = parent;
ngx_http_sorted_querystring_loc_conf_t *conf = child;

ngx_conf_merge_ptr_value(conf->parameters_to_filter, prev->parameters_to_filter, NULL);

return NGX_CONF_OK;
}


char *
ngx_conf_set_parameters_to_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
char *p = conf;

ngx_array_t **field;
ngx_str_t *value, *s;
ngx_uint_t i, j;
ngx_flag_t exists;

field = (ngx_array_t **) (p + cmd->offset);

if (*field != NGX_CONF_UNSET_PTR) {
return "is duplicate";
}

*field = ngx_array_create(cf->pool, cf->args->nelts, sizeof(ngx_str_t));
if (*field == NULL) {
return NGX_CONF_ERROR;
}

value = cf->args->elts;

for (i = 1; i < cf->args->nelts; i++) {
exists = 0;
s = (*field)->elts;
for (j = 0; j < (*field)->nelts; j++) {
if ((value[i].len == s[j].len) && ngx_strncasecmp(value[i].data, s[j].data, value[i].len) == 0) {
exists = 1;
break;
}
}

if (!exists) {
s = ngx_array_push(*field);
if (s == NULL) {
return NGX_CONF_ERROR;
}

*s = value[i];
}
}

return NGX_CONF_OK;
}


ngx_int_t
ngx_http_sorted_querystring_args_variable(ngx_http_request_t *r, ngx_http_variable_value_t *var, uintptr_t data)
{
ngx_http_sorted_querystring_loc_conf_t *sqlc = ngx_http_get_module_loc_conf(r, ngx_http_sorted_querystring_module);
ngx_http_sorted_querystring_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_sorted_querystring_module);
ngx_http_sorted_querystring_parameter_t *param;
u_char *p, *ampersand, *equal, *last;
ngx_queue_t *q;
ngx_flag_t filter;
ngx_str_t *value;
ngx_uint_t i;

if (r->args.len == 0) {
var->len = 0;
Expand Down Expand Up @@ -153,7 +248,22 @@ ngx_http_sorted_querystring_args_variable(ngx_http_request_t *r, ngx_http_variab
p = var->data;
for (q = ngx_queue_head(&ctx->args_queue); q != ngx_queue_sentinel(&ctx->args_queue); q = ngx_queue_next(q)) {
param = ngx_queue_data(q, ngx_http_sorted_querystring_parameter_t, queue);
p = ngx_sprintf(p, "%V&", &param->complete);

filter = 0;
if (sqlc->parameters_to_filter && (param->key.len > 0)) {
value = sqlc->parameters_to_filter->elts;
for (i = 0; i < sqlc->parameters_to_filter->nelts; i++) {
if ((param->key.len == value[i].len) && ngx_strncasecmp(param->key.data, value[i].data, param->key.len) == 0) {
filter = 1;
break;
}
}

}

if (!filter) {
p = ngx_sprintf(p, "%V&", &param->complete);
}
}

var->len = p - var->data - 1;
Expand Down

0 comments on commit a627143

Please sign in to comment.