clzola
clzola

Reputation: 2025

Why Lua+Nginx says it cannot call global function?

I have two simple functions that detects browser and operating system based on user agent and they are stored in file useragent.lua.

function detect_browser_platform(user_agent)
    -- Here goes some string matching and similar stuff
    return browser_platform
end

function detect_os_platform(user_agent)
    -- Here goes some string matching and similar stuff
    return os_platform
end

function detect_env_pattern(user_agent)
    return detect_operating_system_platform(user_agent) .. "-" .. detect_browser_platform(user_agent) .. "-" .. ngx.var.geoip2_data_country_code
end

In virtual host configuration file, there is a line that says when request looks like /lua execute lua script: /var/www/default/test.lua.

In test.lua I have this code:

local posix = require('posix')
local redis = require('redis')
require('useragent')

-- Some code goes here

local user_agent = ngx.req.get_headers()['User-Agent']
local pattern_string = detect_env_pattern(user_agent)

ngx.say(pattern_string)
ngx.exit(200)

But for some reason when I reload nginx nginx -s reload, this codes works only first time. When I make another request it says this error:

2016/09/19 12:30:08 [error] 19201#0: *125956 lua entry thread aborted: runtime error: /var/www/default/test.lua:199: attempt to call global 'detect_env_pattern' (a nil value)

And I have no idea what is happening here. I have just started programming in Lua and don't have time to go deep with language understandings... So why am I getting this error?

Upvotes: 1

Views: 1295

Answers (1)

Vyacheslav
Vyacheslav

Reputation: 27211

Wrap it by a table:

local M={};



function detect_browser_platform(user_agent)
    -- Here goes some string matching and similar stuff
    return browser_platform
end

function detect_os_platform(user_agent)
    -- Here goes some string matching and similar stuff
    return os_platform
end

function detect_env_pattern(user_agent)
    return detect_operating_system_platform(user_agent) .. "-" .. detect_browser_platform(user_agent) .. "-" .. ngx.var.geoip2_data_country_code
end

M.detect_env_pattern = detect_env_pattern
return M

in base lua file:

  local useragent = require('useragent')
    --.....
    local user_agent = ngx.req.get_headers()['User-Agent']
local pattern_string = useragent.detect_env_pattern(user_agent)

ngx.say(pattern_string)
ngx.exit(200)

Upvotes: 4

Related Questions