Skip to content

Offer to run JS code at the rewrite phase #770

Closed
@TPXP

Description

@TPXP

Is your feature request related to a problem? Please describe

I'm trying to implement a reverse proxy with NJS, however each backend I can send the request to needs a different header value. So far, I can define a backend and get nginx to forward requests to it with proxy_pass like this (I need to use a proxy directive since the backend server can return large files):

js_set $upstream myCode.getUpstream;
js_set $freshHeader myCode.getFreshHeader;

proxy_pass $upstream;
proxy_set_header X-Custom-Fresh-Header $freshHeader;

I'd like to handle upstream server errors and get Javascript code to run when that happens, to determine a new upstream to try (and compute the new header). To that extent, I'm performing an internal redirect on error. (Cannot use upstream since headers need to change, also I need to have control on the order in which servers are tried).

location / {
  js_set $upstream myCode.getUpstream;

  proxy_pass $upstream;

  # If something goes wrong, start over
  proxy_intercept_errors on;
  recursive_error_pages on;
  error_page 502 503 504 = /;
}

I hoped to be able to use a variable like upstream_addr to determine the amount of servers tried and adapt the value returned by js_set. However, since js_set and js_var return a cached variable, the get handler will never be called again and nginx will reuse its value for every round of processing. So $upstream does not change for every attempt.

Describe the solution you'd like

I'd like to be able to explicitely state I want some JS code to run at a certain phase (here, I think the rewrite would be great) to be able to run code in a more predictable way.

Describe alternatives you've considered

OpenResty/nginx-lua seems to handle this with the rewrite_by_lua directive. We can possibly take some inspiration.

Additional context

Nothing special, thanks for bringing JS to nginx. It makes it quite fun to script nginx behaviour!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions