HyperFastCgi
HyperFastCgi copied to clipboard
exception on every request if duplicate param in fastcgi_params
If you have a duplicate parameter in /etc/nginx/fastcgi_params, then HFC outputs an exception with every web request inserting duplicate header into dictionary
Note that HFC uses the first value set for the param, not the last one as expected. (I think this is incorrect?) Otherwise technically harmless but very annoying. It should either fail entirely (if this is a real error) or quietly continue.
(I am not a FASTCGI expert but) I think correct behavior would be to overwrite the previously supplied value, and log an info- or debug-level warning. I will gladly create a fix and submit a pull request if someone can confirm that this is correct behavior.
This is nginx configuration issue. You have to remove duplicated params from the configuration files.
I don't think that overwriting the param with last value is a good choice because it hides the cause of the issue and makes it very hard to diagnose it. For example, you want to override the access method for the site always using "POST" instead of "GET", "PUT" etc. In this case you can add
server {
....
location / {
....
fastcgi_param REQUEST_METHOD $request_method;
include /etc/nginx/fastcgi_params;
}
}
/etc/nginx/fastcgi_params
also has got the definition of REQUEST_METHOD. In case of overwriting values you won't be able to diagnose why the parameter in config don't work as expected, and the only chance to do it search through all configs and find it redifinition in other place.
What I think, HyperFastCgi should show the warning in the log with meaningful explanation, something like "Duplicate fastcgi_param "REQUEST_METHOD"" instead of throwing hard-to-understand exception.
Yes, meaningful error messages would be great. Although if this is a hard error I feel like it should return a hard error instead of continuing. "Log an error but keep going using a probably wrong value" is a failure mode that has cost me many days of debugging time over the years. We can add another 3 hours to that total as of yesterday-- it wasn't until I checked out the source and looked at the code that I realized that my configuration was not being used. (It wasn't even what was causing the problem, sadly!)
The real problem here is that nginx now officially leaves behavior up to the application and passes all values through in the order found, but previously the behavior was officially defined as "Directives set in current level clear any previously defined directives for the current level." As this is the behavior of most external modules, people will expect this and you will want to educate them to the error of their ways as quickly as possible when setting up a new configuration.
This is why I recommend immediate feedback in the form of a hard failure. But... hey it's not my project! I'd settle for a good error message!
References:
-
People expect the use-last-found behavior, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=718639.
-
http://wiki.nginx.org/HttpFastcgiModule#fastcgi_param
-
I see many examples specifically recommending including an external file then overrides values in it, such as this:
include /etc/nginx/fastcgi_params; fastcgi_param PATH_INFO $fastcgi_path_info; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
"Directives set in current level clear any previously defined directives for the current level". This means that nginx should overwrite the value was previously set but it adds another one record to the params array, so fastcgi server gets two records with the same key instead of one and it's impossible to know which one is appeared first in the nginx config (even if I take the fastcgi_param order for specific version of nginx, it might be changed in future implementations of nginx and HFC won't work with it like with previous versions). Also there are other front-end servers, i. e. lighthttpd which might have other logic working with fastcgi_params. FastCgi specification states about FCGI_PARAMS that "The name-value pairs are sent down the stream one after the other, in no specified order." So I can't be sure on HFC end which record of the key is the correct one (if several keys with the same name were found in the stream). Maybe you're right that the best behaviour would be to stop processing in this case and send error back to the front-end.
By the way, which version of nginx do you use? The nginx issue you've linked above looks to be resolved in v1.6, maybe there is no duplicate keys issue in the latest versions of nginx (I have not checked it yet)
I'm using the latest nginx. Yes, that documentation is old--and the new documentation does not say this about overwriting the values. The only real problem is confusion of the end users who have certain expectations (ie because of its CGI history where env variables always take the last value sent). I dunno, overanalyzing everything is normal for me. :)
By the way, which version of nginx do you use? The nginx issue you've linked above looks to be resolved in v1.6, maybe there is no duplicate keys issue in the latest versions of nginx (I have not checked it yet)
Running latest nginx, duplicate params issue is still there.
@deluvas remove duplicating FCGI_PARAMS from nginx config. The issue was mentioned above about param ordering not about duplicating.