set not add header in nginx - apache

Is there a way to set / replace / merge a header in nginx like its possible in apache?
regarding to this link http://nginx.org/en/docs/http/ngx_http_headers_module.html
it seems, that its only possible to add a header. This brings up some problems, if the header has already been set (e.g. through the php code) and should be replaced / changed to correct values.
For apache one can set / append / merge and add, http://httpd.apache.org/docs/2.2/mod/mod_headers.html
this is kinda basic feature, so it should be possible in nginx somehow, but i cant find out.

Take a look at HttpHeadersMoreModule.
This module allows you to add, set, or clear any output or input header that you specify.
This is an enhanced version of the standard headers module because it provides more utilities like resetting or clearing "builtin headers" like Content-Type, Content-Length, and Server.
It also allows you to specify an optional HTTP status code criteria using the -s option and an optional content type criteria using the -t option while modifying the output headers with the more_set_headers and more_clear_headers directives.
Source: http://wiki.nginx.org/HttpHeadersMoreModule

Actually the Nginx "add_header" directive will not overwrite the header but add the value to it if it exists.
It is not so clear from the docs however: http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header
But in the HttpHeadersMoreModule docs (https://github.com/openresty/headers-more-nginx-module#more_set_headers) it says:
"If you want to add headers incrementally, use the standard add_header directive instead."

Related

Get mod_proxy to pass a custom header to backend

I have a Python backend that is being reverse proxied by Apache/mod_proxy using fcgi (httpd 2.4 on rhel7).
I have a client that sets a custom header in the request, however mod_proxy does not appear to be sending that header on to the backend.
I know something similar exists for the host as ProxyPreserveHost - I would like to know how to do something similar for a custom header.
Can I do that with mod_proxy, or will I need to fall back on to mod_rewrite in some way?
TIA
It seems this line preserves the Header for reasons I don't quite understand:
SetEnvIf HTTP_MY_HEADER "(.*)" MY_HEADER=$0
The reason I don't understand this is that I am setting an Env var here, not a header -- are Env vars automatically turned into headers?
I though I might have to do this also, but was unnecessary:
RequestHeader set HTTP_MY_HEADER "${MY_HEADER}e"
I suppose this is an answer as "it works", although I would love to know why...

Can mod_headers change headers generated by uWSGI?

I have a uWSGI service running behing an apache front-end. The part of my apache conf handling that lools like:
<Location /myapp>
SetHandler uwsgi-handler
uWSGISocket /var/run/uwsgi/myapp.sock
Allow from all
</Location>
and I'd like to add a custom header to the responses of my app. I know I can do that by adding some code in the app, but I would prefer doing it with mod_headers, by adding the following line in the Location directive
Header set Custom-Header "hello world"
It does not seem to work, although mod_headers documentation states
This directive can replace, merge or remove HTTP response headers.
The header is modified just after the content handler and output filters are run,
allowing outgoing headers to be modified.
What do I do wrong, or understand wrong?
As stated in the docs mod_uwsgi is very raw and uses the 'assbackwards' mode, unless you enable the CGI mode. This mode (assbackwards) gives superior performance but breaks basically all of the filters. You should use mod_proxy_uwsgi (fully apache-friendly) or let uWSGI do the hard work for you using the internal routing:
http://uwsgi-docs.readthedocs.org/en/latest/InternalRouting.html
(or the --add-header more invasive option)

How to conditionally modify Apache response header 'Location'

I need to be able to test the URL string in a Location response header for a certain pattern and if it matches replace it with another.
e.g. if response is Location: http://wrongserver.com I need to change it to Location: http://rightserver.com
Seems mod_setenvif only operates on request headers so I haven't been able to combine this with a "Header set" directive to achieve what I want.
Content is not being proxied so using mod_proxy directives doesn't seem to be an option.
Thanks,
Bernie
You should be able to do this with mod_headers
Header edit Location ^http://wrongserver.com$ http://rightserver.com
More info here: https://httpd.apache.org/docs/current/mod/mod_headers.html#header

problems using mod_headers with php-fpm/mod_fastcgi

I'm trying to add HSTS headers to every response, across my app.
My first thought was to use mod_headers — I placed this directive in an .htaccess file at the documentroot:
Header set Strict-Transport-Security "max-age=7776000"
This works fine on my local setup using Apache 2.2 and mod_php. All resources respond with the appropriate HSTS header.
My deployment environment uses Apache 2.2 and mod_fastcgi and the above technique works for any resource except php files.
Another SO question had a similar problem, where incoming requests (?) had headers stripped — but I'm concerned about modifying headers of response leaving the server.
How can I add response headers to php resources in the context of an .htaccess file?
According to the docs for mod_headers you probably need to set the optional conditional flag for the header directive.
So in this case, it would become
Header always set Strict-Transport-Security "max-age=7776000"

.htaccess - how to set headers dynamically per domain?

I'm trying to get CORS functioning with multiple domains.
Header add Access-Control-Allow-Origin "http://localhost, http://multiplay.io"
However, it seems that most browsers only support one domain. I've been told that the solution is to set the header per incoming domain.
How do you do this using the .htaccess file?
If it's only two values you wish to alternate between, you can use SetEnvIf to differentiate between the two.
SetEnvIf Referer "^http://localhost/" is_localhost
Header add Access-Control-Allow-Origin http://localhost env=is_localhost
Header add Access-Control-Allow-Origin http://multiplay.io env!=is_localhost
There may be a more elegant solution, but something like the above (untested) directives should work.
(Note that it is trivial to forge a Referer header, so be aware of the security implications of forged Referer headers when using Referer headers for pretty much anything.)
Additionally, if you just want to allow all hosts, you can specify * instead of listing multiple hostnames:
Header add Access-Control-Allow-Origin *
But I assume you already knew that and don't want to be that permissive.