Opened 12 years ago

Closed 8 years ago

#283 closed enhancement (fixed)

proxy_method does not support variable dereferencing

Reported by: gcnovus.myopenid.com Owned by:
Priority: minor Milestone:
Component: nginx-module Version: 1.3.x
Keywords: proxy Cc:
uname -a: Darwin MyMachine.local 11.4.2 Darwin Kernel Version 11.4.2: Thu Aug 23 16:25:48 PDT 2012; root:xnu-1699.32.7~1/RELEASE_X86_64 x86_64
nginx -V: nginx: nginx version: nginx/1.0.4
nginx: TLS SNI support enabled
nginx: configure arguments: --prefix=/Users/me/Cellar/nginx/1.0.4 --with-http_ssl_module --with-pcre --conf-path=/Users/me/etc/nginx/nginx.conf --pid-path=/Users/me/var/run/nginx.pid --lock-path=/Users/me/var/nginx/nginx.lock

Description

See this email from five years ago.

The following doesn't work:

location /proxy {
  internal;
  set $proxy_to_url $upstream_http_x_proxy_to_url
  set $proxy_to_host $upstream_http_x_proxy_to_host
  set $proxy_to_method $upstream_http_x_proxy_to_method
  proxy_set_header Host $proxy_to_host;
  proxy_pass $proxy_to_url;
  proxy_method $proxy_to_method;
}

The other directives interpret the arguments as variables to dereference, but proxy_method does not. This is particularly important for the case where a request is from a browser that doesn't support PUT or DELETE, so the upstream server has to calculate the verb.

Change History (8)

comment:1 by Valentin V. Bartenev, 12 years ago

Type: defectenhancement

There are many directives that do not support variables. It's usually noted in the documentation if a directive supports variables. And I don't see such note about proxy_method.

comment:2 by Maxim Dounin, 12 years ago

Resolution: wontfix
Status: newclosed

I don't think that proxy_method should support variables. It's more or less trivial to write configuration with distinct methods used in distinct locations, and variables will only complicate things.

comment:3 by Casey Bisson, 12 years ago

Actually, I can imagine a number of reasons to change this that are unrelated to location. One example is allowing only GET requests for anonymous users, but supporting POST requests for logged in users (users who have a cookie suggesting a valid login status).

comment:4 by dilaz03@…, 8 years ago

This problem is actual for me after switch to nginx with canonical converting HTTP-methods on X-Accel-Redirect. My usecase:

// Main entry, proxy request to connected servers over VPN. Upstream may make http
// request to connected server or return X-Accel-Redirect with server IP.
location /teleport {
    proxy_pass upstream_api;
}

location ~* ^/internal-redirect-get/(.+)/(.+) {
    internal;
    set $ip $1;
    set $uri $2;
    proxy_pass http://$ip/$uri$is_args$args;
    proxy_method GET;
}

// Duplicate config for each supported HTTP verb
location ~* ^/internal-redirect-post/(.+)/(.+) {
    // ...
    proxy_method POST;
}
location ~* ^/internal-redirect-put/(.+)/(.+) {
    // ...
    proxy_method PUT;
}
location ~* ^/internal-redirect-delete/(.+)/(.+) {
    // ...
    proxy_method DELETE;
}

I found simple solution for this problem only with lua module:

location ~* ^/internal-redirect/(.+)/(.+) {
    // Extract method from header after X-Accel-Redirect and set it for request
    rewrite_by_lua_block {
        ngx.req.set_method(ngx['HTTP_' .. ngx.var['upstream_http_x_http_method']])
    }

    // ...
}

I think this is too complicated for simple task (even with lua).

Some questions on stackoverflow:

I will try send patch for this enhancement and tests.

Last edited 8 years ago by dilaz03@… (previous) (diff)

comment:7 by Maxim Dounin, 8 years ago

Resolution: wontfix
Status: closedreopened

comment:8 by Maxim Dounin, 8 years ago

Resolution: fixed
Status: reopenedclosed

Path by Dmitry committed, ca27074f8f0f.

Note: See TracTickets for help on using tickets.