Mod magnet » History » Revision 7
« Previous |
Revision 7/119
(diff)
| Next »
jan, 2006-09-14 12:39
added a mod_cml migration
{{{
#!rst
==============
a power-magnet
==============
------------------
Module: mod_magnet
------------------
.. contents:: Table of Contents
Overview ========
mod_magnet is a module to control the request handling in lighty.
.. note:: Currently this page only describes the final syntax and some part might not work with the current svn-code.
Options =======
mod_magnet can attract a request in several stages in the request-handling.
- either at the same level as mod_rewrite, before any parsing of the URL is done
- or at a later stage, when the doc-root is known and the physical-path is already setup
It depends on the purpose of the script which stage you want to intercept. Usually you want to use
the 2nd stage where the physical-path which relates to your request is known. At this level you
can run checks against lighty.env["physical.path"].
::
magnet.attract-raw-url-to = ...
magnet.attract-physical-path-to = ...
Debugging =========
To easy debugging we overloaded the print()-function in lua and redirect the output of print() to the error-log. ::
print("Host: " .. lighty.request["Host"])
print("Request-URI: " .. lighty.env["request.uri"])
Examples ========
Sending text-files as HTML
--------------------------
This is a bit simplistic, but it illustrates the idea: Take a text-file and cover it in a
tag. Config-file :: magnet.attract-physical-path-to = server.docroot + "/readme.lua" readme.lua :: lighty.content = { "<pre>", { filename = "/README" }, "</pre>" } lighty.header["Content-Type"] = "text/html" return 200 Maintainance pages ------------------ Your side might be on maintainance from time to time. Instead of shutting down the server confusing all users, you can just send a maintainance page. Config-file :: magnet.attract-physical-path-to = server.docroot + "/maintainance.lua" maintainance.lua :: require "lfs" if (nil == lfs.attributes(lighty.env["physical.doc-root"] .. "/maintainance.html")) then lighty.content = ( lighty.env["physical.doc-root"] .. "/maintainance.html" ) lighty.header["Content-Type"] = "text/html" return 200 end mod_flv_streaming ----------------- Config-file :: magnet.attract-physical-path-to = server.docroot + "/flv-streaming.lua" flv-streaming.lua:: if (lighty.get["start"]) { lighty.content = { "FLV\x1\x1\0\0\0\x9\0\0\0\x9", { filename = lighty.env["physical.path"], offset = lighty.get["start"] } } lighty.header["Content-Type"] = "video/x-flv" return 200 } selecting a random file from a directory ---------------------------------------- Say, you want to send a random file (ad-content) from a directory. To simplify the code and to improve the performance we define: * all images have the same format (e.g. image/png) * all images use increasing numbers starting from 1 * a special index-file names the highest number Config :: server.modules += ( "mod_magnet" ) magnet.attract-physical-path-to = "random.lua" random.lua :: dir = lighty.env["physical.path"] f = assert(io.open(dir .. "/index", "r")) maxndx = f:read("*all") f:close() ndx = math.random(maxndx) lighty.content = { { filename = dir .. "/" .. ndx }} lighty.header["Content-Type"] = "image/png" return 200 denying illegal character sequences in the URL ---------------------------------------------- Instead of implementing mod_security, you might just want to apply filters on the content and deny special sequences that look like SQL injection. A common injection is using UNION to extend a query with another SELECT query. :: if (string.find(lighty.env["request.uri"], "UNION%s")) then return 400 end Complex rewrites ---------------- If you want to rewrite a URL depending on a complex condition, here you go: :: if (lfs.attributes(lighty.env["physical.path"])) then -- file exists, send it lighty.content = { { filename = lighty.env["physical.path"] } } fi -- path doesn't exist ... rewrite it lighty.env["request.uri"] = "/dispatch.fcgi" return RESTART_REQUEST Usertracking ------------ ... or how to store data globally in the script-context: Each script has its own script-context. When the script is started it only contains the lua-functions and the special lighty.* name-space. If you want to save data between script runs, you can use the global-script context: :: if (nil == _G["usertrack"]) then _G["usertrack"] = {} end if (nil == _G["usertrack"][lighty.request["Cookie"]]) then _G["usertrack"][lighty.request["Cookie"]] else _G["usertrack"][lighty.request["Cookie"]] = _G["usertrack"][lighty.request["Cookie"]] + 1 end print _G["usertrack"][lighty.request["Cookie"]] The global-context is per script. If you update the script without restarting the server, the context will still be maintained. Counters -------- mod_status support a global statistics page and mod_magnet allows to add and update values in the status page: Config :: status.statistics-url = "/server-counters" magnet.attract-raw-url-to = server.docroot + "/counter.lua" counter.lua :: lighty.status["core.connections"] = lighty.status["core.connections"] + 1 Result:: core.connections: 7 fastcgi.backend.php-foo.0.connected: 0 fastcgi.backend.php-foo.0.died: 0 fastcgi.backend.php-foo.0.disabled: 0 fastcgi.backend.php-foo.0.load: 0 fastcgi.backend.php-foo.0.overloaded: 0 fastcgi.backend.php-foo.1.connected: 0 fastcgi.backend.php-foo.1.died: 0 fastcgi.backend.php-foo.1.disabled: 0 fastcgi.backend.php-foo.1.load: 0 fastcgi.backend.php-foo.1.overloaded: 0 fastcgi.backend.php-foo.load: 0 Porting mod_cml scripts ----------------------- mod_cml got replaced by mod_magnet. A CACHE_HIT in mod_cml:: output_include = { "file1", "file2" } return CACHE_HIT becomes:: content = { { filename = "/path/to/file1" }, { filename = "/path/to/file2"} } return 200 while a CACHE_MISS like:: trigger_handler = "/index.php" return CACHE_MISS becomes:: lighty.env["request.uri"] = "/index.php" return RESTART_REQUEST }}}
Updated by jan about 18 years ago · 7 revisions