diff --git a/samples/hello_config.lua b/samples/hello_config.lua
index 6924341..42c8b42 100644
--- a/samples/hello_config.lua
+++ b/samples/hello_config.lua
@@ -1,9 +1,10 @@
isolated = false
local app = dofile(docroot .. "/hello.lua")
+local wsx = require "wsapi.xavante"
rules = {
{
match = { "^/app$", "^/app/" },
- with = wsapi.xavante.makeHandler(app, "/app", docroot, docroot)
+ with = wsx.makeHandler(app, "/app", docroot, docroot)
},
}
diff --git a/src/launcher/wsapi b/src/launcher/wsapi
index f87f466..abe1e52 100755
--- a/src/launcher/wsapi
+++ b/src/launcher/wsapi
@@ -123,17 +123,17 @@ addrule{ -- wsapihandler example
}
if opts.cgilua then
- require "xavante.cgiluahandler"
+ local hcgi = require "xavante.cgiluahandler"
addrule{
match = {"%.lp$", "%.lp/.*$", "%.cgi$", "%.cgi/.*$" },
- with = xavante.cgiluahandler.makeHandler (config.docroot, launcher_params)
+ with = hcgi.makeHandler (config.docroot, launcher_params)
}
end
if opts.op then
- require "orbit.ophandler"
+ local hop = require "orbit.ophandler"
addrule{
match = {"%.op$", "%.op/.*$" },
- with = orbit.ophandler.makeHandler (config.docroot, launcher_params)
+ with = hop.makeHandler (config.docroot, launcher_params)
}
end
diff --git a/src/wsapi/common.lua b/src/wsapi/common.lua
index 589626f..6245f4f 100644
--- a/src/wsapi/common.lua
+++ b/src/wsapi/common.lua
@@ -6,20 +6,26 @@
--
-----------------------------------------------------------------------------
+local os = require "os"
+local string = require "string"
+local io = require "io"
+local table = require "table"
+local debug = require "debug"
+
local wsapi = require "wsapi"
local lfs = require "lfs"
+
+local tostring, tonumber, pairs, ipairs, error, type, pcall, xpcall, setmetatable, dofile, rawget, rawset, assert, loadfile =
+ tostring, tonumber, pairs, ipairs, error, type, pcall, xpcall, setmetatable, dofile, rawget, rawset, assert, loadfile
+
+local package = package
+
local _, ringer = pcall(require, "wsapi.ringer")
-local _G = _G
-if _VERSION == "Lua 5.2" then
- _ENV = setmetatable({}, { __index = _G })
-else
- module(..., package.seeall)
- _ENV = _M
-end
+local _M = {}
-- HTTP status codes
-status_codes = {
+_M.status_codes = {
[100] = "Continue",
[101] = "Switching Protocols",
[200] = "OK",
@@ -68,7 +74,7 @@ status_codes = {
-- environment, and provides the invariant the the WSAPI
-- environment returns the empty string instead of nil for
-- variables that do not exist
-function sv_index(func)
+function _M.sv_index(func)
if type(func) == "table" then
return function (env, n)
local v = func[n]
@@ -86,9 +92,9 @@ end
-- Makes an wsapi_env.input object from a low-level input
-- object and the name of the method to read from this object
-function input_maker(obj, read_method)
+function _M.input_maker(obj, read_method)
local input = {}
- read = obj[read_method or "read"]
+ local read = obj[read_method or "read"]
function input:read(n)
n = n or self.length or 0
@@ -99,7 +105,7 @@ end
-- Windows only: sets stdin and stdout to binary mode so
-- sending and receiving binary data works with CGI
-function setmode()
+function _M.setmode()
pcall(lfs.setmode, io.stdin, "binary")
pcall(lfs.setmode, io.stdout, "binary")
end
@@ -107,7 +113,7 @@ end
-- Returns the actual WSAPI handler (a function) for the
-- WSAPI application, whether it is a table, the name of a Lua
-- module, a Lua script, or the function itself
-function normalize_app(app_run, is_file)
+function _M.normalize_app(app_run, is_file)
local t = type(app_run)
if t == "function" then
return app_run
@@ -115,9 +121,9 @@ function normalize_app(app_run, is_file)
return app_run.run
elseif t == "string" then
if is_file then
- return normalize_app(dofile(app_run))
+ return _M.normalize_app(dofile(app_run))
else
- return normalize_app(require(app_run))
+ return _M.normalize_app(require(app_run))
end
else
error("not a valid WSAPI application")
@@ -127,7 +133,7 @@ end
-- Sends the respose body through the "out" pipe, using
-- the provided write method. Gets the body from the
-- response iterator
-function send_content(out, res_iter, write_method)
+function _M.send_content(out, res_iter, write_method)
local write = out[write_method or "write"]
local flush = out.flush
local ok, res = xpcall(res_iter, debug.traceback)
@@ -145,10 +151,10 @@ end
-- Sends the complete response through the "out" pipe,
-- using the provided write method
-function send_output(out, status, headers, res_iter, write_method, res_line)
+function _M.send_output(out, status, headers, res_iter, write_method, res_line)
local write = out[write_method or "write"]
if type(status) == "number" or status:match("^%d+$") then
- status = status .. " " .. status_codes[tonumber(status)]
+ status = status .. " " .. _M.status_codes[tonumber(status)]
end
if res_line then
write(out, "HTTP/1.1 " .. (status or "500 Internal Server Error") .. "\r\n")
@@ -165,11 +171,11 @@ function send_output(out, status, headers, res_iter, write_method, res_line)
end
end
write(out, "\r\n")
- send_content(out, res_iter, write_method)
+ _M.send_content(out, res_iter, write_method)
end
-- Formats the standard error message for WSAPI applications
-function error_html(msg)
+function _M.error_html(msg)
return string.format([[
WSAPI Error in Application
@@ -185,12 +191,12 @@ function error_html(msg)
end
-- Body for a 500 response
-function status_500_html(msg)
- return error_html(msg)
+function _M.status_500_html(msg)
+ return _M.error_html(msg)
end
-- Body for a 404 response
-function status_404_html(msg)
+function _M.status_404_html(msg)
return string.format([[
Resource not found
@@ -201,7 +207,7 @@ function status_404_html(msg)
]], tostring(msg))
end
-function status_200_html(msg)
+function _M.status_200_html(msg)
return string.format([[
Resource not found
@@ -226,36 +232,36 @@ end
-- Sends an error response through the "out" pipe, replicated
-- to the "err" pipe (for logging, for example)
-- msg is the error message
-function send_error(out, err, msg, out_method, err_method, http_response)
+function _M.send_error(out, err, msg, out_method, err_method, http_response)
local write = out[out_method or "write"]
local write_err = err[err_method or "write"]
write_err(err, "WSAPI error in application: " .. tostring(msg) .. "\n")
- local msg = error_html(msg)
+ local msg = _M.error_html(msg)
local status, headers, res_iter = "500 Internal Server Error", {
["Content-Type"] = "text/html",
["Content-Length"] = #msg
}, make_iterator(msg)
- send_output(out, status, headers, res_iter, out_method, http_response)
+ _M.send_output(out, status, headers, res_iter, out_method, http_response)
return status, headers
end
-- Sends a 404 response to the "out" pipe, "msg" is the error
-- message
-function send_404(out, msg, out_method, http_response)
+function _M.send_404(out, msg, out_method, http_response)
local write = out[out_method or "write"]
- local msg = status_404_html(msg)
+ local msg = _M.status_404_html(msg)
local status, headers, res_iter = "404 Not Found", {
["Content-Type"] = "text/html",
["Content-Length"] = #msg
}, make_iterator(msg)
- send_output(out, status, headers, res_iter, out_method, http_response)
+ _M.send_output(out, status, headers, res_iter, out_method, http_response)
return status, headers
end
-- Runs the application in the provided WSAPI environment, catching errors and
-- returning the appropriate error repsonses
-function run_app(app, env)
- return xpcall(function () return (normalize_app(app))(env) end,
+function _M.run_app(app, env)
+ return xpcall(function () return (_M.normalize_app(app))(env) end,
function (msg)
if type(msg) == "table" then
env.STATUS = msg[1]
@@ -267,10 +273,10 @@ function run_app(app, env)
end
-- Builds an WSAPI environment from the configuration table "t"
-function wsapi_env(t)
+function _M.wsapi_env(t)
local env = {}
- setmetatable(env, { __index = sv_index(t.env) })
- env.input = input_maker(t.input, t.read_method)
+ setmetatable(env, { __index = _M.sv_index(t.env) })
+ env.input = _M.input_maker(t.input, t.read_method)
env.error = t.error
env.input.length = tonumber(env.CONTENT_LENGTH) or 0
if env.PATH_INFO == "" then env.PATH_INFO = "/" end
@@ -279,10 +285,10 @@ end
-- Runs an application with data from the configuration table "t",
-- sending the WSAPI error/not found responses in case of errors
-function run(app, t)
- local env = wsapi_env(t)
+function _M.run(app, t)
+ local env = _M.wsapi_env(t)
local ok, status, headers, res_iter =
- run_app(app, env)
+ _M.run_app(app, env)
if ok then
if not headers["Content-Length"] then
if t.http_response then
@@ -296,23 +302,23 @@ function run(app, t)
end
end
end
- send_output(t.output, status, headers, res_iter, t.write_method, t.http_response)
+ _M.send_output(t.output, status, headers, res_iter, t.write_method, t.http_response)
else
if env.STATUS == 404 then
- return send_404(t.output, status, t.write_method, t.http_response)
+ return _M.send_404(t.output, status, t.write_method, t.http_response)
else
- return send_error(t.output, t.error, status, t.write_method, t.err_method, t.http_response)
+ return _M.send_error(t.output, t.error, status, t.write_method, t.err_method, t.http_response)
end
end
return status, headers
end
-function splitpath(filename)
+function _M.splitpath(filename)
local path, file = string.match(filename, "^(.*)[/\\]([^/\\]*)$")
return path, file
end
-function splitext(filename)
+function _M.splitext(filename)
local modname, ext = string.match(filename, "^(.+)%.([^%.]+)$")
if not modname then modname, ext = filename, "" end
return modname, ext
@@ -323,17 +329,17 @@ end
-- and modification time. If "filename" is a directory it assumes
-- that the actual file is a .lua file in this directory with
-- the same name as the directory (for example, "/foo/bar/bar.lua")
-function find_file(filename)
+function _M.find_file(filename)
local mode = assert(lfs.attributes(filename, "mode"))
local path, file, modname, ext
if mode == "directory" then
- path, modname = splitpath(filename)
+ path, modname = _M.splitpath(filename)
path = path .. "/" .. modname
file = modname .. ".lua"
ext = "lua"
elseif mode == "file" then
- path, file = splitpath(filename)
- modname, ext = splitext(file)
+ path, file = _M.splitpath(filename)
+ modname, ext = _M.splitext(file)
else
return nil
end
@@ -343,7 +349,7 @@ end
-- IIS appends the PATH_INFO to PATH_TRANSLATED, this function
-- corrects for that
-function adjust_iis_path(wsapi_env, filename)
+function _M.adjust_iis_path(wsapi_env, filename)
local script_name, ext =
wsapi_env.SCRIPT_NAME:match("([^/%.]+)%.([^%.]+)$")
if script_name then
@@ -377,7 +383,7 @@ end
-- Corrects PATH_INFO and SCRIPT_NAME, so SCRIPT_NAME will be
-- /cgi-bin/wsapi.cgi/bar/baz.lua and PATH_INFO will be /foo
-- for the previous example
-function adjust_non_wrapped(wsapi_env, filename, launcher)
+function _M.adjust_non_wrapped(wsapi_env, filename, launcher)
if filename == "" or not_compatible(wsapi_env, filename) or
(launcher and filename:match(launcher:gsub("%.", "%.") .. "$")) then
local path_info = wsapi_env.PATH_INFO
@@ -413,15 +419,15 @@ end
-- Tries to guess the correct path for the WSAPI application script,
-- correcting for misbehaving web servers (IIS), non-wrapped launchers
-- and (http://server/cgi-bin/wsapi.cgi/bar/baz.lua/foo)
-function normalize_paths(wsapi_env, filename, launcher, vars)
+function _M.normalize_paths(wsapi_env, filename, launcher, vars)
vars = vars or { "SCRIPT_FILENAME", "PATH_TRANSLATED" }
if not filename or filename == "" then
for _, var in ipairs(vars) do
filename = wsapi_env[var]
if filename ~= "" then break end
end
- filename = adjust_non_wrapped(wsapi_env, filename, launcher)
- filename = adjust_iis_path(wsapi_env, filename)
+ filename = _M.adjust_non_wrapped(wsapi_env, filename, launcher)
+ filename = _M.adjust_iis_path(wsapi_env, filename)
wsapi_env.PATH_TRANSLATED = filename
wsapi_env.SCRIPT_FILENAME = filename
else
@@ -436,13 +442,13 @@ function normalize_paths(wsapi_env, filename, launcher, vars)
end
-- Tries to find the correct script to launch for the WSAPI application
-function find_module(wsapi_env, filename, launcher, vars)
- normalize_paths(wsapi_env, filename or "", launcher, vars)
- return find_file(wsapi_env.PATH_TRANSLATED)
+function _M.find_module(wsapi_env, filename, launcher, vars)
+ _M.normalize_paths(wsapi_env, filename or "", launcher, vars)
+ return _M.find_file(wsapi_env.PATH_TRANSLATED)
end
-- Version of require skips searching package.path
-function require_file(filename, modname)
+function _M.require_file(filename, modname)
package.loaded[modname] = true
local res = loadfile(filename)(modname)
if res then
@@ -455,15 +461,15 @@ end
-- a .lua script and dofile'ing it in case of other extensions),
-- returning the WSAPI handler function for this application
-- also moves the current directory to the application's path
-function load_wsapi(path, file, modname, ext)
+function _M.load_wsapi(path, file, modname, ext)
lfs.chdir(path)
local app
if ext == "lua" then
- app = require_file(file, modname)
+ app = _M.require_file(file, modname)
else
app = dofile(file)
end
- return normalize_app(app)
+ return _M.normalize_app(app)
end
-- Local state and helper functions for the loader if isolated applications,
@@ -519,19 +525,19 @@ do
-- and runs the application in the provided WSAPI environment
local function wsapi_loader_isolated_helper(wsapi_env, params)
local path, file, modname, ext, mtime =
- find_module(wsapi_env, params.filename, params.launcher, params.vars)
+ _M.find_module(wsapi_env, params.filename, params.launcher, params.vars)
if params.reload then mtime = nil end
if not path then
error({ 404, "Resource " .. wsapi_env.SCRIPT_NAME .. " not found"})
end
- local app = load_wsapi_isolated(path, file, modname, ext, mtime)
+ local app = _M.load_wsapi_isolated(path, file, modname, ext, mtime)
wsapi_env.APP_PATH = path
return app(wsapi_env)
end
-- Loads a WSAPI application isolated in its own Lua state and returns
-- the application handler (reusing an existing state if one is free)
- function load_wsapi_isolated(path, file, modname, ext, mtime)
+ function _M.load_wsapi_isolated(path, file, modname, ext, mtime)
local filename = path .. "/" .. file
lfs.chdir(path)
local app, data
@@ -564,7 +570,7 @@ do
-- Makes an WSAPI application that launches isolated WSAPI applications
-- scripts with the provided parameters - see wsapi.fcgi for the
-- parameters and their descriptions
- function make_isolated_loader(params)
+ function _M.make_isolated_loader(params)
params = params or {}
return function (wsapi_env)
collect_states(params.period, params.ttl)
@@ -572,11 +578,11 @@ do
end
end
- function wsapi_loader_isolated(wsapi_env)
+ function _M.wsapi_loader_isolated(wsapi_env)
return wsapi_loader_isolated_helper(wsapi_env, {})
end
- function wsapi_loader_isolated_reload(wsapi_env)
+ function _M.wsapi_loader_isolated_reload(wsapi_env)
return wsapi_loader_isolated_helper(wsapi_env, { reload = true })
end
@@ -628,10 +634,10 @@ do
-- Loads a WSAPI application isolated in its own Lua state and returns
-- the application handler (reusing an existing state if one is free)
- function load_isolated_launcher(filename, app_modname, bootstrap, reload)
+ function _M.load_isolated_launcher(filename, app_modname, bootstrap, reload)
local app, data
local app_state = app_states[filename]
- local path, _ = splitpath(filename)
+ local path, _ = _M.splitpath(filename)
local mtime = lfs.attributes(filename, "modification")
if not reload and app_state.mtime == mtime then
for _, state in ipairs(app_state.states) do
@@ -659,12 +665,12 @@ do
-- Makes an WSAPI application that launches an isolated WSAPI launcher
-- with the provided parameters - see op.fcgi in the Orbit sources for the
-- parameters and their descriptions
- function make_isolated_launcher(params)
+ function _M.make_isolated_launcher(params)
params = params or {}
return function (wsapi_env)
collect_states(params.period, params.ttl)
- normalize_paths(wsapi_env, params.filename, params.launcher, params.vars)
- local app = load_isolated_launcher(wsapi_env.PATH_TRANSLATED, params.modname, params.bootstrap, params.reload)
+ _M.normalize_paths(wsapi_env, params.filename, params.launcher, params.vars)
+ local app = _M.load_isolated_launcher(wsapi_env.PATH_TRANSLATED, params.modname, params.bootstrap, params.reload)
return app(wsapi_env)
end
end
@@ -682,7 +688,7 @@ do
-- Bootstraps a Lua state (using rings) with the provided WSAPI application
local function bootstrap_app(path, file, modname, ext)
- return load_wsapi(path, file, modname, ext)
+ return _M.load_wsapi(path, file, modname, ext)
end
-- "Garbage-collect" stale Lua states
@@ -722,7 +728,7 @@ do
-- loads and runs the application in the provided WSAPI environment
local function wsapi_loader_persistent_helper(wsapi_env, params)
local path, file, modname, ext, mtime =
- find_module(wsapi_env, params.filename, params.launcher, params.vars)
+ _M.find_module(wsapi_env, params.filename, params.launcher, params.vars)
if params.reload then mtime = nil end
if not path then
error({ 404, "Resource " .. wsapi_env.SCRIPT_NAME .. " not found"})
@@ -735,7 +741,7 @@ do
-- Makes an WSAPI application that launches persistent WSAPI applications
-- scripts with the provided parameters - see wsapi.fcgi for the
-- parameters and their descriptions
- function make_persistent_loader(params)
+ function _M.make_persistent_loader(params)
params = params or {}
return function (wsapi_env)
collect_states(params.period, params.ttl)
@@ -744,13 +750,13 @@ do
end
end
-function make_loader(params)
+function _M.make_loader(params)
params = params or { isolated = true }
if params.isolated then
- return make_isolated_loader(params)
+ return _M.make_isolated_loader(params)
else
- return make_persistent_loader(params)
+ return _M.make_persistent_loader(params)
end
end
-return _ENV
+return _M