번역서 정보 | 번역서 질문&의견 | 번역 이야기 | 문서 창고 | 방명록

아파치 웹서버 mod_lua 팁 몇 가지

류광, 2014/08/29 01:20
Apache 웹 서버의 mod_lua를 사용해 보고 얻은 팁 몇 가지.

mod_lua는 Apache 웹 서버(이하 그냥 아파치)에서 프로그래밍 언어 루아(Lua)를 사용할 수 있게 해주는 모듈입니다. 아파치 2.4부터는 이 모듈이 아파치 배포본에 기본으로 포함되어 있으로 따로 구해서 설치할 필요가 없습니다. 게다가 PHP처럼 그냥 웹 내용(HTML 페이지 등)을 생성하는 능력은 물론, 아파치의 작동 방식 자체에 좀 더 깊숙하게 관여할 수 있는 능력을 가지고 있습니다. 예를 들어 예전에는 mod_rewrite로 하던 URL 매핑 작업도 mod_lua를 통해서 루아 스크립트로 수행할 수 있습니다. 본격적인 프로그래밍 언어로 매핑 논리를 짤 수 있으므로 예전보다 훨씬 복잡하고 지능적인 처리가 가능합니다. 이런 점으로 볼 때 루아가 아파치의 '일급시민' 언어(구현용 언어는 아니고 최종 사용자를 위한)로 자리잡고 있다고 할 수 있겠습니다. 언젠가는 httpd.conf나 .htaccess 같은 설정 파일들까지도 루아 스크립트가 대신하게 될 거라는 예상도 가능합니다.

저는 주로 내용 생성을 목적으로 mod_lua를 사용해 보았는데요. 그 과정에서 알게 된 사항 몇 가지를 써 보겠습니다.

r:parsebody()의 기본 처리 용량

버전 2.4의 mod_lua 문서화의 첫 번째 루아 예제에 이런 부분이 있습니다.

function handle(r)

... 중략 ...

    elseif r.method == 'POST' then
        r:puts("Hello Lua World!n")
        for k, v in pairs( r:parsebody() ) do
            r:puts( string.format("%s: %sn", k, v) )
        end


... 후략 ...

이 부분은 POST 요청에 담긴 자료, 즉 사용자가 HTML 양식을 통해 제출한 자료를 추출하는 방법을 보여 줍니다. r:parsebody()는 HTML 양식으로 제출된 키-값 쌍들의 배열을 돌려줍니다.

간단한 텍스트 변환 스크립트를 만들면서 저는 딱 위의 예만 참고해서 입력 텍스트를 얻는 코드를 작성했습니다. 그런데 이상하게도 입력 텍스트가 일정 분량 이상이면 끝이 잘리는 현상이 일어났습니다. 한참 동안 원인을 못 찾고 있다가 매뉴얼 페이지를 다시 자세히 보니,

r:parsebody([sizeLimit]) -- parse the request body as a POST and return two lua tables,
                         -- just like r:parseargs().
                         -- An optional number may be passed to specify the maximum number
                         -- of bytes to parse. Default is 8192 bytes:

local POST, POSTMULTI = r:parsebody(1024*1024)

sizeLimit 인수를 생략하면 8192바이트만 읽는다는 것이었습니다. 더 많은 내용을 얻으려면 예제 코드처럼 더 큰 수를 인수로 지정해야 합니다.

Sqlite3 연동

mod_lua는 데이터베이스 연결 기능을 제공합니다만 데이터베이스 기능을 직접 구현하고 있는 것은 아니고, 데이터베이스 기능을 가진/또는 실제 데이터베이스 시스템과 연동하는 개별적인 아파치 모듈이 활성화되어 있어야 합니다. 저는 따로 데이터베이스 시스템을 돌릴 필요가 없는 Sqlite3을 사용하기로 했습니다.

해당 도움말을 참고해서 코드를 짜는데, 제가 뭘 잘못했는지 아니면 mod_lua나 Sqlite3 모듈의 구현에 문제가 있는지 그냥 r:dbacquire("sqlite3", ... 으로는 잘 되지 않았습니다. 결국은 mod_dbd라는 모듈을 사용하는 것으로 해결을 봤습니다.

mod_dbd는 일종의 DB 추상층으로, 구체적인 데이터베이스 종류와 이름을 코드에 밖아 넣지 않고 외부 설정 파일에서 지정할 수 있게 하는 것입니다. 코드에서는 그냥

local db, err = r:dbacquire("mod_dbd")

로 데이터베이스와 연결을 하고, 대신 구체적인 설정을 httpd.conf에서 다음과 같이 지정해 둡니다.

# DB 구동기 종류
DBDriver sqlite3
# 연결 매개변수(Sqlite3의 경우 DB 파일 이름)
DBDParams "../../db/mydb.sqlite"
## 최대 연결 개수
DBDMax 10

이것이 작동하려면 mod_dbd용 Sqlite3 구동기인 apr_dbd_sqlite3-1.dll가 있어야 합니다. 그런데 이 파일은 표준적인 아파치 배포판의 일부가 아니라서 APR 프로젝트에서 소스를 받아서 직접 빌드해야 합니다. Windows 환경에서 오픈소스 라이브러리를 빌드하다 고생한 경험을 가진 분들이 있겠지만, 다행히 이 프로젝트는 Visual Studio용 빌드 파일들이 잘 갖추어져 있어서 빌드가 그리 어렵지 않습니다. 세 가지만 주의하면 별 문제 없이 apr_dbd_sqlite3-1.dll를 얻을 있을 것입니다.

첫째는, apr_dbd_sqlite3가 포함된 APR-util뿐만 아니라 APR과 APR-iconv도 함께 내려받아야 한다는 점입니다. 짐작하셨겠지만 의존성 때문입니다.

둘째는, 역시 프로젝트 간 의존성 때문에 위의 세 가지 프로젝트들의 디렉터리를 해당 문서에 나온 것처럼 같은 디렉터리 안에 병렬로 배치해야 합니다. 이런 식으로요.

C:\work\apr\
C:\work\apr-iconv\
C:\work\apr-util\

디렉터리 이름 역시 딱 apr, apr-iconv, apr-util이어야 합니다.

마지막으로, apr_dbd_sqlite3-1.dll을 만들려면 공식 sqlite3 라이브러리 자체가 필요한데 다행히 이 라이브러리는 모든 코드를 하나의 C 소스 파일로 통합한 sqlite3.c를 제공하기 때문에, 그냥 그 파일을 apr-util/dbd 에 넣고 해당 프로젝트에 추가하기만 하면 됩니다. sqlite3.c는 http://www.sqlite.org/에서 구할 수 있습니다.

JSON의 작은따옴표 탈출 문제

이것은 사실 mod_lua와는 상관 없는 사항이지만 mod_lua를 활용하면서 한참 헤맸던 부분이라 이야기합니다.

JSON.org의 오토마타 도식

에서 보듯이 역슬래시 탈출이 적용되는 문자들은 딱 정해져 있고, 작은따옴표는 거기에 포함되어 있지 않습니다. 그런대 제가 사용하던 한 JSON 루아 구현은 이를테면 "occam's Razor"라는 문자열을 JSON으로 변환할 때 "occam\'s Razor"로 탈출시켰습니다. 어쩌면 C나 C++, PHP와는 달리 루아에서는 작은따옴표(')와 큰따옴표(")의 구분이 없다는 게 그런 실수에 영향을 미쳤을지도 모르겠습니다.

어쨌든 "occam\'s Razor"는 잘못된 표기이고, 그런 문자열이 포함된 JSON 객체는 유효한 JSON이 아닙니다. 요즘 버전은 모르겠지만 당시 사용하던 버전의 크롬 브라우저는 그런 문자열이 포함된 JSON 객체를 (정당하게)거부했고, 그래서 제가 만들던 텍스트 변환 스크립트가 JSON 형태로 브라우저에게 보낸 내용이 제대로 표시되지 않는 오류가 생겼습니다.

지금은 그런 문제가 없는 dkjson을 사용하고 있습니다.


불특정 다수를 위한 웹 응용 프로그램에 사용하기에는 아직 어설픈 구석이 있고 보안상의 검증도 충분하지 않지만, 개인용 브라우저 앱을 만드는 데에는 아파치+mod_lua가 아주 쓸만해 보입니다. 물론 전통의 아파치+PHP 조합이나 요즘 많이 회자되는 node.js도 있지만, 루아를 좋아하는 사람에게는 mod_lua가 아주 매력적일 것입니다.

top
트랙백 0 : 의견 # + 0

근황 - 2014-07-28

류광, 2014/07/28 00:44
APUE 3 교정, Browser Hacker's Handbook 교정, 그리고 루아.

얼마 전부터 APUE 제3판 교정에 시간을 쏟고 있습니다. 이번 주말에 마무리 지을 예정이고요. 2학기 시작에 맞춰서 책이 나오면 좋겠습니다만 어찌 될지....

APUE 제3판 교정 다음에는 저번 근황에서 언급한 The Browser Hacker's Handbook의 교정이 기다리고 있습니다.

번역 외에는, 2009년에 잠깐 건드렸던(, ) '포터블 루아 웹 애플리케이션 서버'를 다시 살펴보고 있습니다. 조간만 아파치 httpd의 mod_lua를 다루면서 삽질했던 이야기를 써 볼 생각입니다.

top
트랙백 0 : 의견 # + 0

2014 FIFA 월드컵 32개국 선수단 정보를 담은 루아 테이블

류광, 2014/06/12 20:39
2014 FIFA 월드컵 32개국 선수단 정보를 담은 루아 테이블을 만들어서 GitHub에 올렸습니다.

영문 위키백과 2014 FIFA World Cup squads 페이지에서 32개국 선수단 정보를 추출해서 루아 테이블로 만들었습니다. GitHub에 올려 두었으니 혹시 필요하신 분 가져다 쓰세요. 사용권은 원본 페이지의 것과 동일한 CC-BY-SA입니다.

GitHub 저장소: https://github.com/ryugwang/wc2014squads

JSON을 원하시는 분도 있겠지만, 루아(Lua)를 좀 더 많은 사람이 배웠으면 해서 루아로만 배포합니다. 루아 테이블을 JSON 문자열로 변환하는 방법은 (너무)많습니다: http://lua-users.org/wiki/JsonModules. 저는 dkjson을 써봤습니다.


wc2014_squads_table.lua 에는 선수단 정보가 들어 있고 clubs_table.lua에는 소속 클럽들의 좀 더 자세한 정보가, flags_table.lua에는 국기 이미지 URL들이 있습니다.

wc2014_squads_table.lua 테이블에는 국가 이름들과 각 국가 이름을 키로 한 선수단 테이블들이 들어 있습니다. 국가 이름들은 정수 색인 1~32까지이고, 조별 순서로 되어 있습니다. 즉, 1번~4번은 A조, 5~8은 B조, 등등입니다(루아의 색인은 1번부터임을 명심하세요!).

하나의 선수단을 뜻하는 테이블(아래 예에서 squad)에는 nation, coach, players라는 속성들이 있습니다. 각각 국가 이름, 코치 정보, 그리고 23명의 선수들에 대한 정보입니다. 선수들은 등번호 순으로 나열되어 있습니다.

전체 선수단을 조별 순서로 훑는 루프는 다음과 같은 형태입니다.

local squads = require"wc2014_squads_table"

for _, nation in ipairs(squads) do
    local squad = squads[nation]

    -- 국가, 감독, 감독 국적
    print(squad.nation, squad.coach.name, squad.coach.nation)

    for _, player in ipairs(squad.players) do
        -- 여기서 player의 다양한 속성들을 활용 (아래 참고)
    end
end

개별 선수 테이블에는 다음과 같은 속성들이 있습니다.

  • player.name : 이름
  • player.number : 등번호
  • player.position : 위치(GK, DF, FW 등등)
  • player.wikipedia : 영문 위키백과 URL
  • player.caps : A 매치 출장 횟수
  • player.captain : 주장 여부(true 또는 nil)
  • player.club : 소속팀 이름

clubs_table.lua와 flags_table.lua는 다음처럼 활용하면 됩니다:

local squads = require"wc2014_squads_table"
local clubs = require"clubs_table"
local flags = require"flags_table"


local brazil_squad = squads['Brazil']

print(flags[brazil_squad.nation]) -- 위키백과 브라질 국기 이미지 URL

local p2 = brazil_squad.players[2]  -- 다니 아우베스

local club = clubs[p2.club] -- 바르셀로나

-- FC Barcelona   Spain   http://en.wikipedia.org/wiki/FC_Barcelona
print(club.fullname, club.nation, club.wikipedia)

top
TAG Lua, 축구
트랙백 0 : 의견 # + 0

The Performance of Open Source Applications 번역서 나왔습니다.

류광, 2014/05/22 00:23
The Performance of Open Source Applications 번역서 출간 소식과 APUE3 소식.

본문 열기

top
TAG 번역서
트랙백 0 : 의견 # + 0

근황 - 2014-03-27

류광, 2014/03/31 00:06
번역서 소식, 닥북 - epub 변환 도구.

본문 열기

top
트랙백 0 : 의견 # + 0

◀ PREV : [1] : [2] : [3] : [4] : [5] : ... [52] : NEXT ▶