230 likes | 375 Views
mod_lua for beginners. Eric Covener, IBM covener@apache.org, November 2011. About Me. Eric Covener Apache HTTP Server and WebSphere Application Server Development at IBM. Contributor to Apache HTTP Server, Apache Portable Runtime, and Apache OpenWebBeans.
E N D
mod_lua for beginners Eric Covener, IBMcovener@apache.org, November 2011
About Me • Eric Covener • Apache HTTP Server and WebSphere Application Server Development at IBM. • Contributor to Apache HTTP Server, Apache Portable Runtime, and Apache OpenWebBeans. • Frequent supporter on freenode #httpd and the HTTPD users mailing list
Agenda • Introduction to Lua • Introduction to mod_lua • mod_lua recipes for familiar problems • The future • Wrap-up
What is Lua? • “Lua is a powerful, fast, lightweight, embeddable scripting language” • Basic syntax familiar to occasional users of C or interpreted languages such as JavaScript, PHP, PERL, … #!/usr/bin/luaio.write("What's your name? ")local name = io.read("*line")print("Hello, ", name)
More on Lua • Lua is used as the scripting engine many popular large applications • World of Warcraft, VLC, Wireshark, RPM • Extensions allow Lua scripts to exploit popular libraries such as memcached, mysql, GD, curl, expat, sockets. • The programs embedding Lua are expected to provide useful routines . • Basic Features: Simple syntax, C-like control structures, I/O, basic regex • Advanced Features: • Co-routines, closures, OOP
What is mod_lua? • mod_lua allows users to write Lua scripts to extend and modify the webserver • Handling the response in a Lua script • Changing request processing metadata (think SetEnvIf, RequestHeader, Header, and RewriteRule) • Implementation of Authentication, Authorization, Access Control • Much like a compiled Apache HTTP Server module, or scripts written in mod_perl.
Getting mod_lua • Part of Apache HTTP Server 2.3.x (and later) • Must be enabled during build (explicitly, or via –enable-mods-shared=[really]all) • Lua interpreter (and –dev counterpart) must be available at build time • Packaged with most Linux distributions • Source tarball is 200k and has no dependencies (doesn’t even use autoconf)
A simple mod_lua handler • The simplest way a traditional module (or a mod_lua script) can participate in a request is by acting as the “handler”, or generator, for the response. 1 function handle(r) 2 r.content_type = "text/html" 3 local query = r:parseargs() 4 if query.name == nil then 5 r:puts("What's your name? “, 6 “<form><input type=\"text\" name=\"name\"/>") 7 else 8 r:puts("Hello, ", r:escape_html(query.name)); 9 end 10 end
Invoking a Lua handler • A few different ways to teach mod_lua about our script • AddHandler lua-script .lua • LuaMapHandler • LuaMapHandler /hello /path/to/luascripts/hello.lua • LuaQuickHandler • <LuaQuickHandler> • No external script file required, lives in httpd.conf
Handler performance Crude performance test of a short “Hello, world” page.
Apache Module Primer • Traditional Apache modules can do more than just generate the response • The participate in designated “hooks” with other modules • Mapping a URI to the filesystem • Performing authentication • Setting mime-types • mod_lua allows Lua scripts to participate the same way
Noteworthy hooks • quick_handler • translate_name • URI -> filename • access_checker • user-independent access control • check_userid • authentication • auth_checker • authorization • fixups
Redirect to SSL <LuaHookTranslateName redirect_ssl> 1 require "apache2" 2 function redirect_ssl(r) 3 local https = r:ssl_var_lookup("HTTPS") 4 if (https == nil or https == "" or https == "off") then 5 r.err_headers_out['Location'] = string.gsub(r:construct_url(r.uri), "http://", "https://") 6 return apache2.HTTP_MOVED_TEMPORARILY 7 end 8 return apache2.DECLINED 9 end
Maintenance page <LuaQuickHandler maint> 1 require "apache2“ 2 require “posix" 3 4 function maint(r) 5 if posix.stat(“/tmp/maintenance”) ~= nil then 6 r:puts(“site temporarily unavailable") 7 r.status = 503; 8 return apache2.OK 9 else 10 return apache2.DECLINED 11 end 12 end </LuaQuickHandler>
Rewrite based on Query <LuaHookTranslateName rewrite_query> 1 function rewrite_query(r) 2 local query = r:parseargs() 3 if query.foo ~= nil and 4 query.bar ~= nil then 5 r.uri = r.uri .. 6 "/" .. query.foo .. 7 "/" .. query.bar 8 end 9 return apache2.DECLINED 10 end
mod_lua in place of mod_rewrite • Pros • Proper programming language with control structures, subroutines • Less baggage • Custom logging • Easier to unit test • Easier/less fragile to extend • Cons • Only basic regular expression by default • Less source material on the web • No htaccess for most recipes
Serving pre-compressed files • LuaHookMapToStorage ... • 1 require "apache2" • 2 require "posix" • 3 function gz(r) • 4 local acceptEncoding = • 5 r.headers_in['Accept-Encoding'] • 6 if (r.filename and acceptEncoding and • 7 string.find(acceptEncoding, "gzip")) then • 8 if posix.stat(r.filename .. ".gz") then • 9 r.filename = r.filename .. ".gz" • 10 r.headers_out['Vary'] = "Accept-Encoding" • 11 end • 12 end • 13 return apache2.DECLINED • 14 end
Check Authorization LuaHookAuthChecker /path/to/authz.lua authz … 1 require "apache2" 2 require "posix" 3 4 function authz(r) 5 if r.user == "bob" then 6 local hour = tonumber(os.date("%H")) 7 if hour > 8 and hour < 17 then 8 return 403 9 end 10 end 11 return apache2.DECLINED 12 end
Basic-if-no-cert LuaHookAuthCheckUserID /path/to/auth.lua \ authn early 1 function authn(r) 2 local user = 3 r:ssl_var_lookup("SSL_CLIENT_S_DN_CN") 4 if user == nil or user == "" then 5 return apache2.DECLINED 6 end 7 r.user = user 8 return apache2.OK 9 end
mod_lua's future • HTTP Request/Response filters • More Apache API access • Configuration in mod_lua • More mod_lua examples • Join in and help decide!
Conclusion • Flexible alternative to mod_setenvif/mod_rewrite/mod_headers recipes. • Lowers barriers to quickly interact with HTTP Server API in what would be short modules • Lightweight scripting language for handlers • Input needed from users, tell us what you want to write in Lua!
Sources • mod_lua manual • http://httpd.apache.org/docs/2.3/mod/mod_lua.html • The Apache Modules Book • http://www.apachetutor.org/ • Programming in Lua • http://www.lua.org/pil/
Contact • Eric Covener • covener@apache.org