4

Having trouble with file output in Nginx + Lua. I chosen LUA, because nginx logic is pretty complicated, based on referrer or subdomains, etc.

Having request like /img/am1/s/1.jpg I need to check if file exists in /somepath/am1/1.jpg. If it exists, then output it, otherwise proxy request to backend.

2 Answers 2

12

Ok, found it

content_by_lua '
    local file = "/path..."
    local f = io.open(file, "rb")
    local content = f:read("*all")
    f:close()
    ngx.print(content)
';
Sign up to request clarification or add additional context in comments.

5 Comments

It would be much more efficient to let nginx serve file using internal location and ngx.exec.
@chanux seems like you blog is dead:( could you republish this article somewhere please?
@scythargon Sorry for letting it die. I put it back up. I messed up redirection but here is it.
@chanux thanks for your blog,nginx internal redirect save me
@chanux thanks for the post, the last url is not valid, here is the most up to date path chanux.me/blog/post/lua-x-accel-redirect
3

If someone need to know how to output last n lines from file:

location /service-man/log {
            default_type 'text/plain';
            content_by_lua '

                    local log_path = "/path/to/log.log"
                    -- Opens a file in read
                    file = io.open(log_path, "r")
                    if file==nil
                    then
                        ngx.say(log_path .. " can\'t read or does not exists")
                        return
                    end

                    -- sets the default input file
                    io.input(file)

                    local lines = {}
                    -- read the lines in table lines
                    for line in io.lines() do
                        table.insert(lines, line)
                    end
                    io.close(file)

                    log_limit = 10
                    if #lines < log_limit then
                        log_start = 0
                    else
                        log_len = #lines
                        log_start = log_len - log_limit
                    end

                    local one_line = ""

                    for i, line in ipairs(lines) do

                        if i > log_start then
                            one_line = one_line .. line .. "\\n"
                        end

                    end

                    ngx.say(one_line)
            ';

}

Should be compatible with nginx/1.6.2 and Lua 5.3.

Please share if you know how to make it in more optimal way.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.