4

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;
    }
}
D.Bugger
  • 193
  • 1
  • 2
  • 8

3 Answers3

7

"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

map $upstream_http_x_xsplocation $m_replaceme {
    ""  "";
    "~^.*/page.xsp/(.*)$" "/$1";
    "~.*" "";
}

location / {
      proxy_pass   http://localhost:81/database.nsf/page.xsp/;
      proxy_hide_header X-XspLocation;
      add_header X-XspLocation  $m_replaceme;
}

Tested with nginx/1.14.2

Gerard H. Pille
  • 2,469
  • 1
  • 12
  • 10
  • It's always money, isn't it... :-( – D.Bugger May 21 '20 at 11:56
  • Nope, doesn't work. The header X-XspLocation disappears but the new one isn't created. I *forgot* to mention that most of it works if I add a header, but not for the original header. I'll modify the question. – D.Bugger May 21 '20 at 12:04
  • 1
    Did I forget to mention that I tested it? "Its value is then something like:". It might help to show us an exact value. – Gerard H. Pille May 21 '20 at 12:18
  • Nope. The chances of anything coming from Mars... and still it doesn't work here. I even left out the hide, and changed the header name to X-XspLocation2: no dice. – D.Bugger May 21 '20 at 12:19
  • I can see if I can anonymize the whole configuration file and post that. – D.Bugger May 21 '20 at 12:26
  • 1
    You did replace "$sent_http_x..." by "$upstream_http_x..." ? – Gerard H. Pille May 21 '20 at 12:26
  • Of course, nothing happened. The map I used on $sent_http_x_xsplocation works. It seems to be the proxy_hide_header that doesn't work. Or works too well... – D.Bugger May 21 '20 at 12:34
  • Without the hide, the replacement gets appended to the original value, as expected. – Gerard H. Pille May 21 '20 at 12:35
  • Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/108291/discussion-between-d-bugger-and-gerard-h-pille). – D.Bugger May 21 '20 at 12:48
  • And with the hide both headers disappear... – D.Bugger May 21 '20 at 13:06
  • Most likely the Ubuntu installation is somehow corrupt. Our short term workaround: instead of using the standard XPages call _redirectTo_, I used _getResponse().setHeader_ with a name of my own and set that to the value I want in X-XspLocation. I added some rules to the nginx config file to move that header to the desired header. – D.Bugger May 26 '20 at 14:20
  • Nog een weekje, en we trekken weer zuidwaarts. – Gerard H. Pille Jun 17 '21 at 13:55
  • Het is nu al 34°C hier, niet normaal voor half juni. Goede reis, en houd de neus proper! – D.Bugger Jun 17 '21 at 14:23
  • De météo ziet er bijzonder slecht uit bij jullie, donderdag. Het zal geen plezierritje worden. – Gerard H. Pille Jun 22 '21 at 18:04
  • Deze site is redelijk betrouwbaar: https://www.meteorama.fr en ik zie niets wat ik echt slecht zou moeten noemen. Vab – D.Bugger Jun 22 '21 at 18:11
  • Oeps... Vannacht was vreselijk, onweer, 20mm water, storm, rukwinden, zowat het einde der tijden... – D.Bugger Jun 22 '21 at 18:13
  • Jullie maken er daar wel een gewoonte van. Wegens een fysisch akkefietje vervroegd teruggekeerd, tussen Vienne en Lyon daar een hoeveelheid water over ons gekregen, nog nooit zelf ervaren. Woog natuurlijk niet op tegen wat ze in de Ardennen en Duitsland over zich heen kregen. – Gerard H. Pille Jul 21 '21 at 11:51
  • Dat was een paar dagen geleden zeker. Het is hier ook wel nat geweest, iets van 30mm op een dag, maar bij Lyon kan het inderdaad flink spoken soms. Hoop dat de terugreis verder zonder incidenten was. – D.Bugger Jul 21 '21 at 15:27
  • Nul incidenten, en een plezier om eens niet in de blakende zon te moeten rijden - geen liefhebber van airco. – Gerard H. Pille Jul 21 '21 at 16:05
  • Da's mooi! Dus een goede vakantie geweest. Nu nog de Covid weg en de tijgermuggen... Ik weet intussen niet meer hoe ik bovenstaand probleem heb opgelost. Fijne zomer verder! – D.Bugger Jul 23 '21 at 18:02
2

Added always works for me

proxy_hide_header X-XspLocation;
add_header X-XspLocation  $m_replaceme always;
ashedrin
  • 21
  • 1
0

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.

noonex
  • 228
  • 1
  • 10