Ngx.location.capture_multi multiple posts

Hello,

I try to use ngx.location.capture_multi to send multiple post requests:

upstream _server1 {
server server1:80;
}

upstream _server2 {
server server2:80;
}

server {
listen 10.0.0.254:80;
server_name server.internal;

location / {
  content_by_lua '
    upstream_servers = {{"/server1", {copy_all_vars = true, method =

ngx.HTTP_POST}},
{"/server2", {copy_all_vars = true, method =
ngx.HTTP_POST}},
}
for i, v in ipairs(upstream_servers) do
upstream_servers[i][1] = upstream_servers[i][1] …
ngx.var.request_uri
end
results = {ngx.location.capture_multi(upstream_servers)}
status = 200
output = “”
for i, result in ipairs(results) do
output = output … result.body
if status < result.status then
status = result.status

      end
    end
    ngx.say({output})
    ngx.exit(status)
  ';
}

location /server1 {
  rewrite ^/[^/]*/(.*) /$1 break;
  proxy_pass http://_server1;
  proxy_set_header X-Forwarded-For $remote_addr;
}

location /server2 {
  rewrite ^/[^/]*/(.*) /$1 break;
  proxy_pass http://_server2;
  proxy_set_header X-Forwarded-For $remote_addr;
}

}

The post will be send to server1, but the second one won’t be send to
server2. Afer I while the request terminates with the timeout error 408.
When I switch the servers in the table uptream_servers, the request will
be passed to server2, but not to server1. Again, a timeout occurs. When
I replace ngx.HTTP_POST with ngx.HTTP_GET, both requests will be send.

Is it not possible to use ngx.location.capture_multi like that?

matthias

Hello!

On Tue, Jun 19, 2012 at 10:23 PM, Matthias R. [email protected]
wrote:

I try to use ngx.location.capture_multi to send multiple post requests:

[…]

content_by_lua ’
upstream_servers = {{"/server1", {copy_all_vars = true, method =
ngx.HTTP_POST}},
{"/server2", {copy_all_vars = true, method =
ngx.HTTP_POST}},
}

Here, you let the subrequests all inherit the request body of the
current request but one gotcha here is that the current request’s body
can be consumed only once. So you have the following options:

  1. Read the entire request body into memory or your custom file using
    ngx_lua’s ngx.req.get_body_data or ngx.req.get_body_file API, and then
    feed that to your subrequest by specifying the “body” option value.

  2. Read the request body in a streaming fashion by means of the
    “downstream cosocket” object returned by ngx.req.socket(), and send
    the data chunk received to multiple backend HTTP connections at the
    same time by means of the “upstream cosocket” returned by
    ngx.socket.tcp(). In this approach, you’ll no longer use ngx_proxy.

Best regards,
-agentzh