I'm trying to configure nginx as a reverse proxy server for a web application on a back-end Domino server. We have 99.9% working, but that last 0.1% is really bugging me.
I'll explain. In some cases, the application returns a partial refresh with a special response header called X-XspLocation
. If it exists, it contains a url to be redirected to by the client. It's a header generated and used by the XPages environment, my code itself doesn't set or read it. Its value is then:
http://localhost:81/database.nsf/page.xsp/ThankYou
and I want it to be just this: /ThankYou
I tried in a million ways, but it seems impossible to alter its value. As soon as I use proxy_hide_header X-XspLocation;
no new headers can be added using add_header
! If I leave the hide out, I get double values in the header, so I know my replacement value is correct. Here's my latest attempt that failed:
map $sent_http_x_xsplocation $xsplocation_new {
"~http://localhost:81/database.nsf/page.xsp/(.*)" "/$1";
}
server {
...
location / {
proxy_pass http://localhost:81/database.nsf/page.xsp/;
# redirect X-XspLocation
proxy_hide_header X-XspLocation;
add_header X-XspLocation $xsplocation_new;
#add_header X-XspLocation2 $xsplocation_new;
}
}
I even tried with njs to change the header, it probably failed because I don't know how to use js_set or js_content to call a function that doesn't return anything.
Why is it so darned difficult to modify a response header??
The real question is of course: how can I make this work?? Thanks for your assistance!!
More info
In order to prove that the map works, I tested with the following:
location / {
proxy_pass http://localhost:81/database.nsf/page.xsp/;
# redirect X-XspLocation
# proxy_hide_header X-XspLocation;
# add_header X-XspLocation $xsplocation_new;
add_header X-XspLocation2 $xsplocation_new;
}
The result is now that the original header plus the new header X-XspLocation2
are present, and the 2nd one is exactly what I need in X-XspLocation
.
By the way, nginx version: nginx/1.18.0 on Ubuntu 16.04.6 LTS (My client's provider's system, not mine...)
The full censored config file
map $sent_http_x_xsplocation $xsplocation_new {
"~http://localhost:81/database.nsf/page.xsp/(.*)" "/$1";
}
server {
listen 4443 ssl;
server_name www.myclient.nl;
ssl_certificate /etc/nginx/ssl/www.myclient.nl.pem;
ssl_certificate_key /etc/nginx/ssl/www.myclient.nl.pem;
# do not allow google to index this website
# TODO: remove when going to production
add_header X-Robots-Tag "noindex, nofollow, nosnippet, noarchive";
# replace redirects in response header fields Location and Refresh
proxy_redirect http://localhost:81/database.nsf/page.xsp/ https://www.myclient.nl:4443/;
proxy_redirect http://localhost:81/ https://www.myclient.nl:4443/;
# tell domino not to encode the response so we can use sub_filter
proxy_set_header Accept-Encoding "";
# substitute response content
sub_filter 'localhost:81' 'www.myclient.nl:4443';
sub_filter 'www.myclient.nl' 'www.myclient.nl:4443'; #TODO: remove when going production
sub_filter '/database.nsf/page.xsp/' '/';
sub_filter '/database.nsf/' '/other/';
sub_filter_once off;
# Domino
location = /favicon.ico {
access_log off; log_not_found off;
proxy_pass http://localhost:81/database.nsf/Images/favicon.ico/%24file/favicon.ico;
}
# root / homepage
location = / { proxy_pass http://localhost:81/database.nsf/page.xsp/HomePage; }
#login
location /names.nsf { proxy_pass http://localhost:81/names.nsf; }
# XPages
location /xsp/ { proxy_pass http://localhost:81/xsp/; }
location /domjava/ { proxy_pass http://localhost:81/domjava/; }
# training
location ~* ^/.*-training/(.*) {
proxy_pass http://localhost:81/database.nsf/page.xsp/training/$1;
}
location ~* ^/(.*)-training$ {
proxy_pass http://localhost:81/database.nsf/page.xsp/$1;
}
# IMAGES
# image resources - any case insensitive match with 'images'
location ~* '/images/(.*)$' {
proxy_pass 'http://localhost:81/database.nsf/Images/$1';
}
# images referenced from css in file.xsp have this url, redirect to backend correctly
location ~* '/file.xsp/images/(.*)$' {
proxy_pass 'http://localhost:81/database.nsf/Images/$1';
}
# file resources
location /file.xsp/ { proxy_pass http://localhost:81/database.nsf/file.xsp/; }
# other resources
location /other/ { proxy_pass http://localhost:81/database.nsf/; }
# all other urls
location / {
proxy_pass http://localhost:81/database.nsf/page.xsp/;
# redirect X-XspLocation
#add_header X-XspLocation $xsplocation_new always;
proxy_hide_header X-XspLocation;
add_header X-XspLocation $xsplocation_new;
}
}
"Why is it so darned difficult to modify a response header??"
Some people need to make a living too!
Ah, that wasn't the real question. Damn. Try this
Tested with nginx/1.14.2
Added always works for me
Apparently adding header to proxy response from backend is a bit problematic in nginx without recompilation.
add_header
will add header to the request from proxy to backend server. It will achieve the goal only if the backend returns the same header without modification in own response. Which may happen, but is not guaranteed of course. Thus, if that doesn't happen - you can try to configure your backend to allow such behavior.