#765 closed defect (wontfix)
should not perform consistent hash on empty string
Reported by: | openid.yandex.ru/wenzowski | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | |
Component: | nginx-module | Version: | 1.9.x |
Keywords: | Cc: | ||
uname -a: | Linux 21ec728a6488 3.19.0 #2 SMP Thu Mar 26 10:44:46 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux | ||
nginx -V: |
nginx version: nginx/1.9.0
built by gcc 4.9.2 (Debian 4.9.2-10) built with OpenSSL 1.0.1k 8 Jan 2015 (running with OpenSSL 1.0.1f 6 Jan 2014) TLS SNI support enabled configure arguments: --prefix=/opt/nginx --pid-path=/run/nginx.pid --with-debug --with-pcre-jit --with-ipv6 --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_spdy_module --with-http_sub_module --with-mail --with-mail_ssl_module --with-stream --add-module=/tmp/build/naxsi-0d53a64ed856e694fcb4038748c8cf6d5551a603/naxsi_src |
Description
When an upstream has consistent hashing enabled, eg.
upstream backend { hash $arg_a consistent; }
and a request comes in that does not contain the GET
argument a
then $arg_a
defaults to empty string and all requests are forwarded to the same upstream.
Consistent hashing should be disabled when provided an empty string.
Change History (4)
follow-up: 3 comment:1 by , 9 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
follow-up: 4 comment:2 by , 9 years ago
I'm missing something. How does hashing get disabled using a map?
The problem here is that empty string results in routing of all requests to the same upstream. I don't want to pin all empty strings to a specific remote address; if the hash function is operating on a falsey value it needs to be disabled entirely, otherwise traffic cripples whatever upstream empty string consistently hashes to.
Is this something that can be done without modification to the hash module? Thanks for your patience.
comment:3 by , 9 years ago
As a workaround I'm doing
set_random $prng 0 99; set_if_empty $arg_a $prng;
but this means I'm performing unnecessary overhead of consistent hashing a random number
Replying to Maxim Dounin:
I don't see why an empty string should be special, and this contradicts to the documented compatibility with Cache::Memcached / Cache::Memcached::Fast.
If you want nginx to do something special if there is no parameter provided, you may configure fallback to $remote_addr like this:
map $arg_a $foo { "" $remote_addr; default $arg_a; }
comment:4 by , 9 years ago
Replying to openid.yandex.ru/wenzowski:
I'm missing something. How does hashing get disabled using a map?
Hashing won't be disabled, but map
allows to effectively fallback to a different value to hash if a primary one is empty.
The problem here is that empty string results in routing of all requests to the same upstream. I don't want to pin all empty strings to a specific remote address; if the hash function is operating on a falsey value it needs to be disabled entirely, otherwise traffic cripples whatever upstream empty string consistently hashes to.
Is this something that can be done without modification to the hash module? Thanks for your patience.
Most trivial solution would be to route requests with an empty value to a different upstream.
I don't see why an empty string should be special, and this contradicts to the documented compatibility with Cache::Memcached / Cache::Memcached::Fast.
If you want nginx to do something special if there is no parameter provided, you may configure fallback to $remote_addr like this: