configure nginx to make a background request

喜夏-厌秋 提交于 2019-12-06 08:54:33

As you correctly mentioned, post_action is not documented and has always been considered an unofficial directive.

Nginx provides a new "mirror" module since version 1.13.4, described here in the documentation. So I advise you to give it a try. In your case, it would look like this –

location /r/ {
    rewrite /r/(.*)$ http://localhost:3000/sample/route1/$1 redirect;
    mirror /stats;
}

location = /stats {
    internal;
    rewrite /sample/route1/(.*) /stats/$1;
    proxy_pass http://127.0.0.1:3000;
}

This will not work!

I've built a test configuration and unfortunately this will not work. It works for neither rewrite nor return. But it works for proxy_pass.

Why

The explanation follows. A HTTP request sequentially passes few "phases" during processing in Nginx. The thing is that mirror gets triggered in phase PRECONNECT which occurs later than phase REWRITE where rewrite/return end request processing. So, mirror does not even get triggered because its processing would happen later.

In case of serving files from the location or proxying via proxy_pass (or fastcgi_pass, etc), the processing will finally reach REWRITE phase and mirror will be executed.

Phases are described in Nginx documentation here.

Workarounds

I do not see any good solution without trade-offs. You could create an extra location (returning a redirect) and proxy your request from /r/, so that mirror gets triggered. Something like this, depending on the rest of your configuration:

location /r/ {
  # you may need setting Host to match `server_name` to make sure the
  # request will be caught by this `server`.
  # proxy_set_header Host $server_name;
  proxy_pass http://<ip from listen>:<port from listen>/redirect/;
  mirror /stats;
}

location = /redirect {
  rewrite /redirect(.*)$ http://localhost:3000/sample/route1$1 redirect;
}

Certainly this is suboptimal and has extra boilerplate.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!