https://github.com/openresty/lua-nginx-module#status
nil(Null) 체크
Lua nil은 값이 없다는것을 의미한다.
if keys ~= nil then ngx.log(ngx.INFO, "nil이 아니다.") end
if keys == nil then ngx.log(ngx.INFO, "nil이다") end |
타입변환
tonumber("10") -- 10 tostring(10) -- "10" |
타입 구하기
공유 메모리의 키를 가져오는데, 어떤 형태인지 알아볼때 사용한다.
ngx.log(ngx.INFO), type(ngx.shared.shared_dict:get_keys()))
|
For Loop
공유 메모리의 키를 모두 가져와서 For Loop를 돌릴 수 있다.
-- k : 인덱스, v : 키 문자열
for k , v in pairs(ngx.shared.shared_dict:get_keys()) do ngx.log(ngx.INFO, v) -- 각 키 값들이 출력됨. end |
문자열
string.len("abcdefg") -- 7
-- sprintf처럼 포맷 지정 string.format(%s/AAA', 'BBB') -- BBB/AAA
-- 문자열 찾기 local str = "This is a string." if string.matchh(str, "This") then -- 찾음 end
-- 문자열 치환 string.gsub(ngx.var.request_url, "?.*", "") -- >?부터 제거 |
날짜 / 시간
lua 공식 사이트 연결
시간 포맷
os.time() -- 1490167184 os.date("%c", os.time()) -- Wed Mar 22 16:20:06 2017 (KST 또는 시스템 설정에 따름) os.date("!%c", os.time()) -- Wed Mar 22 07:20:47 2017 (UTC) |
Table
-- 카운팅 table.getn(ngx.shared.shared_dict) |
Logging
ngx.log(ngx.INFO, "Log") ngx.log(ngx.DEBUG, "Log") ngx.log(ngx.WARN, "Log") ngx.log(ngx.ERR, "Log")
|
모듈화
모듈화를 위해서 다음과 같은 형태로 파일을 만들어서 사용할 수 있다.
-- mymodule.lua
local _M = {}
function _M.main(ctx)
ctx.foo = "bar"
end
return _M
|
이렇게 작성한 모듈은 다음과 같이 사용할 수 있다.
|
local Mymodule = require 'mymodule';
Mymodule.main({foo: "foo"})
|
팁
스크립트 경로 가져오기
script_path()를 호출하는 파일의 경로를 구할 수 있다. 해당 파일을 기준으로 다른 파일 경로를 가져올 때 유용하다.
|
function script_path()
local str = debug.getinfo(2, "S").source:sub(2)
return str:match("(.*/)")
end
script_path() -- /home/luascript/access.lua
|
동적으로 모듈 호출
|
local pcall = pcall
local ok, upstream = pcall(require, "ngx.upstream")
if not ok then
error("ngx_upstream_lua module required")
end
|
Nginx Lua Module 전용
ngx_http_lua_module
Nginx에 Lua 코드를 끼워넣어 사용할 수 있는 모듈로 기본적으로 nginx에서 제공되지 않고, 직접 설치해야 한다.
공식사이트
출력
원하는 단계에 넣으면 중간에 다른 결과를 출력할 수 있다.
|
ngx.header.content_type = 'text/html';
ngx.print("hello")
ngx.exit(200)
|
버전 정보
|
ngx.config.nginx_version -- nginx 버전
ngx.config.ngx_lua_version -- nginx lua 버전 9015
|
http 요청
ngx.location.capture는 nginx 워커에서 특정 uri에 추가 요청을 할 수 있다.
|
local res = ngx.location.capture("/auth")
if res then
ngx.say("status: ", res.status)
ngx.say("body:")
ngx.print(res.body)
end
|
redirect
특정 페이지로 리다이렉트할 수 있다.
|
-- redirect
ngx.redirect("http://"..ngx.req.get_headers()["Host"].."/page")
-- exec
ngx.exec("@bar", "a=goodbye");
|
exec는 redirect와 다르게, 내부 리다이렉트를 하고, 새로운 외부 HTTP트래픽과 관련이 없다.
Header 관련
|
-- upstream으로 전달
ngx.req.set_header("X-Epoch", ngx.time())
-- 응답 헤더에 추가한다. phase간 값을 공유할 수도 있다. 예 : access phse -> header_filter phase
ngx.header['X-Epoch'] = ngx.time()
ngx.header['Content-Type'] = "text/html"
ngx.header['Set-Cookie'] = 'Foo=abc; path=/'
|
nginx에서 설정한 변수 사용하기
nginx.conf:
|
map "${http_host}${request_uri}" $value_in_lua {
default "default_value";
# 정규식 사용 가능. ~ : case-sensitive, ~* : case-insensitive
~*^(.+\.)?hostname/path "value";
}
|
주소가 설정한 값과 일치하면 그 값을 lua에서 다음과 같이 사용할 수 있다.
|
ngx.var.value_in_lua -- value
|
3rd party module
LIP – ini Parser
LIP는 Lua INI Parser다. ini 파일을 불러오고, 저장할 수 있다.
|
-- ini 불러오기
local LIP = require 'LIP';
local config = LIP.load('/home/luascript/config.ini');
|
CJSON
CJSON은 LUA에서 JSON을 지원하는 모듈이다.
설치하기
다음 페이지 다른 JSON 모듈을 비교한다.
JSON 모듈 비교
에러
a temporary file while reading upstream
lua에서 다음 에러가 발생한다.
|
a temporary file /path/file while reading upstream, client: 000.000.000.000, server: localhost, request: "GET /file.php HTTP/1.1", upstream: "http://127.0.0.1:10000/file.php", host: "domain"
|
문제 생기는 부분을 확인하니 다음과 같이 이미지를 base64로 출력하는 부분의 사이즈가 설정한 값보다 커서 생긴 문제였다. 이미지 사이즈에 맞게 프록시 버퍼의 크기를 늘려줬다.
|
<?php
<img src='data:image/jpeg;base64, <?php echo $image?>' width="100%">
|
nginx 설정을 변경했다.
예제 프로그램이라서 base64로 이미지를 출력했지만, 버퍼를 늘리는 것보다 이미지는 static 서버를 통해 제공하는 것이 좋다.
https://blog.kichul.co.kr/2017/03/13/2017-03-13-lua-note/