I've got a backend server that, for various reasons, only processes GET requests. This server is located behind nginx proxy (i.e. all access is done to nginx, which proxies it to the backend with proxy_pass
). Is it possible to make nginx rewrite POST requests into GET requests, i.e. so that POST /foo
with body content type application/x-www-form-urlencoded
and body foo=bar
would be proxied to GET /foo?foo=bar
?
2 Answers
The small example is working for me with nginx 1.10.x at ubuntu 16.04 with nginx-extras (contains lua). It doesnt respect query arguments from the request, to merge them with the post body.
server {
...
server_name ...;
client_max_body_size 4k; # prevent too long post bodies
location / {
if ($request_method = POST ) {
access_by_lua '
ngx.req.read_body()
local data = ngx.req.get_body_data()
ngx.req.set_uri_args(data)
';
}
proxy_pass http://yourupstreamdestination;
proxy_method GET; # change method
include /etc/nginx/proxy_params.inc; # include some params
}
}
-
stackoverflow.com/a/51139521/1707015 (not exactly to the question, but maybe helpful).– uavCommented Jul 2, 2018 at 15:37
Improving Falk Nisius's original answer, but without the caveat:
It doesnt respect query arguments from the request, to merge them with the post body.
You can switch to using get_post_args
instead of get_body_data
, which returns a table instead of a string.
set_uri_args
can take a string OR a table, so in this case, you can combine it with the table from get_post_args
.
Combining the 2 tables will get you all arguments, as per example:
server {
...
server_name ...;
client_max_body_size 4k; # prevent too long post bodies
location / {
if ($request_method = POST ) {
access_by_lua '
ngx.req.read_body()
local post_data = ngx.req.get_post_args()
local get_data = ngx.req.get_uri_args()
for k,v in pairs(get_data) do post_data[k] = v end
ngx.req.set_uri_args(post_data)
';
}
proxy_pass http://yourupstreamdestination;
proxy_method GET; # change method
include /etc/nginx/proxy_params.inc; # include some params
}
}
proxy_method
maybe?