0

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;
    }
}
0

"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

| improve this answer | |
  • It's always money, isn't it... :-( – D.Bugger May 21 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 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 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 at 12:19
  • I can see if I can anonymize the whole configuration file and post that. – D.Bugger May 21 at 12:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.