Setting or clearing request->args

Hello,

I try to write a nginx http module which decides to enable or forbid a
HTTP request sent in the request parameters (r->args). At the end of
decision I would like to clear the whole args or just a part of it, so
won’t appear in access.log of the origin server.

Is this solution correct without freeing args before?

static ngx_int_t
ngx_http_leki_test_handler(ngx_http_request_t *r)
{

r->args.len = 0;
r->args.data = NULL;
ngx_log_error(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, “OK”, 0);
return NGX_OK;
}

Config example:

location / {
leki_test on;
http://test;
}

Thanks in advance,
Leki

Posted at Nginx Forum:

On Tue, Sep 22, 2009 at 04:21:51AM -0400, leki75 wrote:

r->args.len  = 0;
r->args.data = NULL;
ngx_log_error(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "OK", 0);
return NGX_OK;

}

Yes.

I missed proxy_pass before http://test so the correct line is

proxy_pass http://test

Posted at Nginx Forum:

Hello Igor,

I run some tests but it seems that after setting r->args.len=0 and
r->args.data=NULL and returning NGX_OK the request arrives at the origin
server untouched.

Logs on the original server:
172.27.134.40 - - [22/Sep/2009:14:17:42 +0200] “GET
/index.html?test=4ab8c062 HTTP/1.0” 404 169 “-” “-”

Expected result:
172.27.134.40 - - [22/Sep/2009:14:17:42 +0200] “GET /index.html
HTTP/1.0” 404 169 “-” “-”

Regards,
Leki

Posted at Nginx Forum:

On Tue, Sep 22, 2009 at 08:25:49AM -0400, leki75 wrote:

Hello Igor,

I run some tests but it seems that after setting r->args.len=0 and r->args.data=NULL and returning NGX_OK the request arrives at the origin server untouched.

Logs on the original server:
172.27.134.40 - - [22/Sep/2009:14:17:42 +0200] “GET /index.html?test=4ab8c062 HTTP/1.0” 404 169 “-” “-”

Expected result:
172.27.134.40 - - [22/Sep/2009:14:17:42 +0200] “GET /index.html HTTP/1.0” 404 169 “-” “-”

The you should replace “$request” with “$request_method $uri” in
log_format.

Hello!

On Tue, Sep 22, 2009 at 04:21:51AM -0400, leki75 wrote:

r->args.len  = 0;
r->args.data = NULL;
  • r->valid_unparsed_uri = 0;
    
ngx_log_error(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "OK", 0);
return NGX_OK;

}

Config example:

location / {
leki_test on;
http://test;

I suppose you mean “proxy_pass http://test;” here.

As it’s proxy_pass without uri component - it uses original uri
with arguments (r->unparsed_uri, available as $request_uri
variable) if it’s valid instead of reconstructing it from r->uri
and r->args. That’s why still see original arguments on backend
with your code.

Maxim D.

Dear Igor,

I think you misunderstand me. Not the log output is the problem if I
want to use eg. proxy_cache than I need to remove the query parameters
before caching the content.

The request flow should be (so the origin server wont get any query
parameters):
GET /uri?params HTTP/1.x → nginx → GET /uri HTTP/1.x → origin server

More on this, is it possible to modify the request flow programmatically
without internal_redirect? Like:
GET /uri?param1=value1&param2=value2 HTTP/1.x → nginx → GET
/uri?my_param=value3 HTTP/1.x → origin server

My temporary workaround:
location / {
root /emptydir
leki_test on;
error_page 404 = /FETCH$uri;
}
location /FETCH/ {
internal;
proxy_pass http://test/;
proxy_cache test;
proxy_cache_min_uses 1;
proxy_cache_valid 1d;
proxy_cache_methods GET HEAD;
proxy_cache_use_stale error timeout;
}

But a better solution would be like this, which does not work at the
moment:
location / {
leki_test on;
proxy_pass http://test;
proxy_cache test;
proxy_cache_min_uses 1;
proxy_cache_valid 1d;
proxy_cache_methods GET HEAD;
proxy_cache_use_stale error timeout;
}

Posted at Nginx Forum:

Dear Maxim,

It works! Thanks very much for your and Igor’s help.

Posted at Nginx Forum: