Openresty: Make an http call with lua and return its parsed result
Asked Answered
P

2

11

My problem

I am using openresty to build a simple server.

Upon calling this server, it should make another call to a different server, fetch a JSON result, process it and return the parsed result.

The server should be implemented in openresty for reasons beyond the scope if this question.


Code

error_log /dev/stdout info;

events {
    worker_connections  14096;
}

http {
    access_log off;
    lua_package_path ";;/usr/local/openresty/nginx/?.lua;";

    server {
        keepalive_requests 100000;
        proxy_http_version 1.1;
        keepalive_timeout 10;

        location / {
        content_by_lua_block {
                res = ngx.location.capture('http://localhost:8080/functions.json')
                ngx.say(res.body)
            }
        }

        location /functions {
            root /usr/local/openresty/nginx/html/;
        }

        listen 0.0.0.0:80 default_server;
    }
}

Error log

2017/09/11 08:27:49 [error] 7#7: *1 open() "/usr/local/openresty/nginx/htmlhttp://localhost:8080/functions.json" failed (2: No such file or directory), client: 172.17.0.1, server: , request: "GET / HTTP/1.1", subrequest: "http://localhost:8080/functions.json", host: "localhost:8080"

My question

How can I make an HTTP GET request from within a Lua content block in nginx openresty?

Pacheco answered 11/9, 2017 at 8:46 Comment(0)
V
9

Capture will allow you to capture internal nginx locations and not absolute urls

error_log /dev/stdout info;

events {
    worker_connections  14096;
}

http {
    access_log off;
    lua_package_path ";;/usr/local/openresty/nginx/?.lua;";

    server {
        keepalive_requests 100000;
        proxy_http_version 1.1;
        keepalive_timeout 10;

        location / {
        content_by_lua_block {
                res = ngx.location.capture('/functions.json')
                ngx.say(res.body)
            }
        }
        location /functions.json {
            proxy_pass http://localhost:8080/functions.json;
        }

        location /functions {
            root /usr/local/openresty/nginx/html/;
        }

        listen 0.0.0.0:80 default_server;
    }
}
Vhf answered 11/9, 2017 at 9:9 Comment(4)
I tried capture in my code, but it was treated as a local file (see logs).Pacheco
Earlier or now? also try using location = /functions.json { instead if mine didn't work for youVhf
Thanks, I solved it using a third-party http library: github.com/pintsized/lua-resty-httpPacheco
Yes you can do that, but this is recommended method from the author of the nginx lua module. See issue github.com/openresty/lua-nginx-module/issues/160Vhf
P
8

Solved using the lua-resty-http package. Copied the library to the nginx openresty root, and :

local http = require "resty.http"
local httpc = http.new()

local res, err = httpc:request_uri("http://127.0.0.1/functions.json", { method = "GET" })
// Use res.body to access the response
Pacheco answered 11/9, 2017 at 16:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.