how to force Nginx to override header?
You can't actually set the Content-Type
header for proxy_passed content using plain nginx. You need to compile it with headers-more-nginx-module for that functionality. After you got that module, setting headers is as easy as:
location ~ \.xml$ {
... your config ...
more_set_headers "Content-Type: application/xml";
... proxy_pass settings ...
}
Alternatively, if those sitemap files of yours are not actually generated by backend server on the fly and they actually exists in your website folder you don't really need to use proxy_pass
. Try serving them directly by nginx instead with:
location ~ \.xml$ {
try_files $uri =404;
}
If you don't know how to compile your nginx with external module on Ubuntu 18, just follow this simple steps:
-
Become superuser with this command so we can skip typing
sudo
every time:sudo su
-
Install prerequisites for building nginx by using the following command:
apt install -y build-essential git tree libpcre3-dev libssl-dev zlib1g-dev libxslt1-dev libgd-dev libgeoip-dev
-
Download latest nginx source from http://nginx.org/en/download.html
wget http://nginx.org/download/nginx-1.15.8.tar.gz
-
Unpack it & enter the source tree directory
tar xzfv nginx-1.15.8.tar.gz && cd nginx-1.15.8
-
Get the
headers-more-nginx-module
:git clone https://github.com/openresty/headers-more-nginx-module
-
Get the configuration arguments of your installed nginx (by running
nginx -V
), add the--add-module=/path/to/headers-more-nginx-module
option to them or just configure with the following command:./configure --with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --user=www-data --group=www-data --prefix=/etc/nginx --conf-path=/etc/nginx/nginx.conf --sbin-path=/usr/sbin/nginx --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-mail=dynamic --with-mail_ssl_module --add-module=./headers-more-nginx-module
make && make install
Now you have
headers-more-nginx-module
in your system & full support for those config directives, I mentioned earlier.
Related videos on Youtube
![Hasan Tıngır](https://i.stack.imgur.com/ULL1u.jpg?s=256&g=1)
Hasan Tıngır
Updated on September 18, 2022Comments
-
Hasan Tıngır almost 2 years
I'm trying to display my sitemaps. Browsers display my sitemap index as xml but treat post sitemaps as plain text.
I tried to override content type with below configuration but it didn't help.
location ~ \.xml$ { proxy_hide_header Content-Type; add_header Content-Type "application/xml"; }
How do I force nginx to set content type as "application/xml" ?
Btw sitemaps in nutshell..
sitemap index
<?xml version="1.0" encoding="UTF-8"?> <sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> <sitemap> <loc>http://www.example.com/sitemaps/sitemap-1.xml</loc> <lastmod>2019-02-10T12:22:18+00:00</lastmod> </sitemap> .... </sitemapindex>
and one of posts sitemaps
<loc>http://www.example.com/en</loc> <xhtml:link rel="alternate" hreflang="en" href="http://example.com/en" /> <xhtml:link rel="alternate" hreflang="fr" href="http://example.com/fr" /> <lastmod>2019-02-10T00:00:00+00:00</lastmod> <changefreq>daily</changefreq> <priority>1</priority> </url> <url> .....
I use default laravel nginx configuration
-
Michael Hampton over 5 yearsAre you proxying connections upstream for static files? Why is
proxy_hide_header
in here? -
Hasan Tıngır over 5 years@MichaelHampton I don't actually. I tried with only "add_header" at first. But it didn't work then I saw that on nginx forum, someone advice that for my situation.
-
Michael Hampton over 5 yearsWhat is the content type that was returned in the response? What was the URL?
-
Michael Hampton over 5 yearsThat's definitely the unexpected content-type. Please post the complete
server
block. -
Hasan Tıngır over 5 years@MichaelHampton I updated my question and added server bock
-
Michael Hampton over 5 yearsEh? That
server
block doesn't even have thelocation
to add the header! It won't work if it's not there! -
Michael Hampton over 5 yearsYou have shown a
location
block that was meant to add a response header. But it isn't actually in theserver
block so it can't do anything! Did you delete it? You need to put it back in. -
Hasan Tıngır over 5 years@MichaelHampton Yes I deleted it after I had tried, it didn't work you know..
-
-
Hasan Tıngır over 5 yearsit throws unknown directive "more_set_headers" error
-
Anubioz over 5 years@HasanTıngır Are you sure you've followed the installation procedure described on the github page? What distro do you use?
-
Hasan Tıngır over 5 yearsI'm using ubuntu 18.04 and I used digital ocean documents while install lemp digitalocean.com/community/tutorials/…
-
Tero Kilkanen over 5 yearsThat version does not include the headers-more nginx module. You need to install that module by using the instructions indicated above.
-
Anubioz over 5 years@HasanTıngır I added a step-by-step tutorial in case you don't know how to compile the module in...