安装软件

需要安装三个lua 库:  xavante wsapi cgilua

luarocks install xavante

http://keplerproject.github.io/xavante/manual.html#install

Xavante is a Lua HTTP 1.1 Web server that uses a modular architecture based on URI mapped handlers. Xavante currently offers a file handler, a redirect handler and a WSAPI handler. Those are used for general files, URI remapping and WSAPI applications respectively.

luarocks install wsapi-xavante

http://keplerproject.github.io/wsapi/index.html

WSAPI is an API that abstracts the web server from Lua web applications. By coding against WSAPI your application can run on any of the supported servers and interfaces (currently CGI, FastCGI and Xavante, on Windows and UNIX-based systems).

https://github.com/keplerproject/wsapi

cgilua

luarocks install cgilua

https://github.com/keplerproject/cgilua

CGILua is a tool for creating dynamic Web pages and manipulating input data from Web forms. CGILua allows the separation of logic and data handling from the generation of pages, making it easy to develop web applications with Lua.

运行脚本

切换到cgilua样例目录

root@fqs:/home/share/cgilua-master/cgilua-master/examples# lua xavante_cgilua.lua
[2016-06-22 22:16:50] Xavante started on port(s) 8080

脚本内容 laucher:

xavante = require "xavante"
xavante.filehandler = require "xavante.filehandler"
xavante.cgiluahandler = require "xavante.cgiluahandler"
xavante.redirecthandler = require "xavante.redirecthandler"

-- Define here where Xavante HTTP documents scripts are located
local webDir = "."

local simplerules = {

{ -- URI remapping example
      match = "^[^%./]*/$",
      with = xavante.redirecthandler,
      params = {"index.lp"}
   },

{ -- cgiluahandler example
      match = {"%.lp$", "%.lp/.*$", "%.lua$", "%.lua/.*$" },
      with = xavante.cgiluahandler.makeHandler (webDir)
   },
   
   { -- filehandler example
      match = ".",
      with = xavante.filehandler,
      params = {baseDir = webDir}
   },
}

xavante.HTTP{
   server = {host = "*", port = 8080},
   
   defaultHost = {
      rules = simplerules
   },
}

-- Displays a message in the console with the used ports
xavante.start_message(function (ports)
    local date = os.date("[%Y-%m-%d %H:%M:%S]")
    print(string.format("%s Xavante started on port(s) %s",
                date, table.concat(ports, ", ")))
end)

xavante.start()

WSAPI Xavante 安装后自带launcher

http://keplerproject.github.io/wsapi/manual.html

Xavante

If you installed the wsapi-xavante package you already have a Xavante launcher with WSAPI support. Just run the wsapi script in the path you want as your document root, and point your browser either to the hello.lua or hello.ws script (both extensions are treated as WSAPI applications). See wsapi --help for the launcher's configuration options.

launcher:

root@fqs:/usr/local/bin# cat wsapi
#!/bin/sh

exec '/usr/bin/lua5.1' -e 'package.path="/root/.luarocks/share/lua/5.1/?.lua;/root/.luarocks/share/lua/5.1/?/init.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;"..package.path; package.cpath="/root/.luarocks/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/?.so;"..package.cpath' -e 'local k,l,_=pcall(require,"luarocks.loader") _=k and l.add_context("wsapi-xavante","1.6.1-1")' '/usr/local/lib/luarocks/rocks/wsapi-xavante/1.6.1-1/bin/wsapi' "$@"

root@fqs:/usr/local/bin#

主要实现在 '/usr/local/lib/luarocks/rocks/wsapi/1.6.1-1/bin/wsapi'

此内容,与运行脚本章节的 launcher 功能角色上相同, 但是其比较完善。

root@fqs:/usr/local/bin# cat /usr/local/lib/luarocks/rocks/wsapi-xavante/1.6.1-1/bin/wsapi
#!/usr/bin/env lua

local lfs = require "lfs"
local util = require "wsapi.util"
local wsx = require "wsapi.xavante"
local xavante = require "xavante"
local filehandler = require "xavante.filehandler"
local redirecthandler = require "xavante.redirecthandler"

local usage = [[
Usage: wsapi [options] [document root]

Starts a Xavante instance to serve static files and WSAPI applications.
Treats .lua and .ws files as WSAPI applications, and everything else as
static (but see the --cgilua and --op options, below).

The default document root is the current path.

Options:

-c<file>, --config=<file>   Runs the specified file for additional
                            configuration before starting the server
-l<file>, --log=<file>      Logs all output to the file (default stdout
                            and stderr)
-p<port>, --port=<port>     Binds to the specified port (default 8080)
--cgilua                    Adds .lp and .cgi rules for CGILua pages and
                            scripts
--op                        Adds an .op rule that for Orbit pages
-r, --reload                Reloads applications on every request
-h, --help                  Shows this help screen

]]

local config = {}

local opts, args = util.getopt({ ... }, "clp")

if opts.h or opts.help then
  print(usage)
  os.exit()
end

local config = {
  docroot = args[1] or lfs.currentdir(),
  logfile = opts.l or opts.log,
  port = tonumber(opts.p or opts.port) or 8080,
  start_message = function (ports)
                     local date = os.date("[%Y-%m-%d %H:%M:%S]")
                     print(string.format("%s Xavante started on port(s) %s",
                                         date, table.concat(ports, ", ")))
                  end,
  rules = {},
  is_finished = function() return false end,
  reload = opts.r or opts.reload,
  isolated = true
}

local config_file = opts.c or opts.config

if config_file then
  local f, err = util.loadfile(config_file, setmetatable(config, { __index = _G }))
  if not f then
    io.stderr:write("Cannot load config file " .. config_file .. ":\n\n" .. err .. "\n")
    os.exit()
  end
  local res, err = pcall(f)
  if not res then
    io.stderr:write("Error in config file:\n\n" .. err .. "\n")
    os.exit()
  end
  setmetatable(config, nil)
end

if config.logfile then
  local tostring = tostring
  local log = io.open(config.logfile, "a+")
  if not log then
    error("Could not open log file. Please check the write permissions for: " .. config.logfile)
  end
  io.stdout = log
  io.stderr = log
  print = function (...)
    local nargs = select('#', ...)
    for i = 1, nargs-1 do
      log:write(tostring((select(i, ...))))
      log:write("\t")
    end
    log:write(tostring(select(nargs, ...)))
    log:write("\n")
  end
end

local ONE_HOUR = 60 * 60
local ONE_DAY = 24 * ONE_HOUR

local launcher_params = {
  isolated = config.isolated,
  reload = config.reload,
  period = config.period or ONE_HOUR,
  ttl = config.ttl or ONE_DAY
}

config.rules = config.rules or {}

local function addrule(rule)
  config.rules[#config.rules+1] = rule
end

addrule{ -- URI remapping example
  match = "^/$",
  with = redirecthandler,
  params = {"index.html"}
}

addrule{ -- wsapihandler example
  match = {"%.lua$", "%.lua/" },
  with = wsx.makeGenericHandler (config.docroot, launcher_params)
}

addrule{ -- wsapihandler example
  match = {"%.ws$", "%.ws/" },
  with = wsx.makeGenericHandler (config.docroot, launcher_params)
}

if opts.cgilua then
  local hcgi = require "xavante.cgiluahandler"
  addrule{
    match = {"%.lp$", "%.lp/.*$", "%.cgi$", "%.cgi/.*$" },
    with = hcgi.makeHandler (config.docroot, launcher_params)
  }
end
if opts.op then
  local hop = require "orbit.ophandler"
  addrule{
    match = {"%.op$", "%.op/.*$" },
    with = hop.makeHandler (config.docroot, launcher_params)
  }
end

addrule{ -- filehandler example
  match = ".",
  with = filehandler,
  params = { baseDir = config.docroot }
}

-- Displays a message in the console with the used ports
xavante.start_message(config.start_message)

io.stdout:write("[Xavante launcher] Starting Xavante...\n")

xavante.HTTP{
    server = {host = "*", port = config.port},

defaultHost = {
        rules = config.rules
    },
}

res, err = pcall(xavante.start, function (...)
                                   io.stdout:flush()
                                   io.stderr:flush()
                                   return config.is_finished(...)
                                end, config.timeout)
if not res then
   io.stderr:write(err .. "\n")
else
   io.stderr:write("[Xavante launcher] Xavante stopped\n")
end
root@fqs:/usr/local/bin#

运行流程分析

1、 xavante 负责服务器的启动, 并制定 cgilua 请求处理的handler注册

{ -- cgiluahandler example
      match = {"%.lp$", "%.lp/.*$", "%.lua$", "%.lua/.*$" },
      with = xavante.cgiluahandler.makeHandler (webDir)
   },

2、xavante.cgiluahandler.makeHandler (webDir) , handler的构造

-------------------------------------------------------------------------------
-- Returns the CGILua handler
-------------------------------------------------------------------------------
function _M.makeHandler (diskpath, params)
   params = setmetatable(params or {}, { __index = { modname = "wsapi.sapi",
      bootstrap = bootstrap } })
   local sapi_loader = common.make_isolated_launcher(params)
   return xavante.makeHandler(sapi_loader, nil, diskpath)
end

其中,handler构造依赖了 xavante的wsapi, with的值可以是 function(req, res)

local xavante = require "wsapi.xavante"  --- 专门针对  xavante写的wsapi的适配

-- Makes a WSAPI handler for a single WSAPI application
function _M.makeHandler (app_func, app_prefix, docroot, app_path, extra_vars)
  return function (req, res)
    return wsapihandler(req, res, app_func, app_prefix, docroot, app_path, extra_vars)
  end
end

wsapi.xavante中存在 构造 cgivars 表。

make_handler 入参 wsapi_loader需要 wsapi.sapi文件支持

params = setmetatable(params or {}, { __index = { modname = "wsapi.sapi",
      bootstrap = bootstrap } })
   local sapi_loader = common.make_isolated_launcher(params)

此loader即加载 wsapi.sapi文件, 文件被rings包裹运行, 即 wsapi.sapi –> cgilua 都是在独立环境下运行

前面 “wsapi.xavante中存在 构造 cgivars 表” 也会传入 独立的运行环境。

wsapi.sapi 直接 调用 cgilua

local cgilua = require "cgilua"
  cgilua.main()
  return res:finish()
end

WSAPI Xavante 安装后自带 wsapi.cgi 程序

root@fqs:/usr/local/bin# ls
cgilua.cgi  cgilua.fcgi  summary.lua  wsapi  wsapi.cgi
root@fqs:/usr/local/bin#
root@fqs:/usr/local/bin#
root@fqs:/usr/local/bin# cat wsapi.cgi
#!/bin/sh

exec '/usr/bin/lua5.1' -e 'package.path="/root/.luarocks/share/lua/5.1/?.lua;/root/.luarocks/share/lua/5.1/?/init.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;"..package.path; package.cpath="/root/.luarocks/lib/lua/5.1/?.so;/usr/local/lib/lua/5.1/?.so;"..package.cpath' -e 'local k,l,_=pcall(require,"luarocks.loader") _=k and l.add_context("wsapi","1.6.1-1")' '/usr/local/lib/luarocks/rocks/wsapi/1.6.1-1/bin/wsapi.cgi' "$@"
root@fqs:/usr/local/bin#

实现文件:

root@fqs:/usr/local/bin# cat /usr/local/lib/luarocks/rocks/wsapi/1.6.1-1/bin/wsapi.cgi
#!/usr/bin/lua

-- Generic WSAPI CGI launcher, extracts application to launch
-- either from the command line (use #!wsapi in the script)
-- or from SCRIPT_FILENAME/PATH_TRANSLATED

local wsapi = require "wsapi"
local common = require "wsapi.common"
local cgi = require "wsapi.cgi"

local arg_filename = (...)

local function wsapi_loader(wsapi_env)
  local path, file, modname, ext =
      common.find_module(wsapi_env, arg_filename, "wsapi.cgi", { "SCRIPT_FILENAME", "PATH_TRANSLATED" })
  if not path then
    error({ 404, "Resource " .. wsapi_env.SCRIPT_NAME .. " not found" })
  end
  wsapi.app_path = path
  local app = common.load_wsapi(path, file, modname, ext)
  wsapi_env.APP_PATH = path
  return app(wsapi_env)
end

cgi.run(wsapi_loader)
root@fqs:/usr/local/bin#

此cgi程序用于运行 满足 wsapi接口的应用脚本, 例如:

http://keplerproject.github.io/wsapi/manual.html

#!/usr/bin/env wsapi.cgi

module(..., package.seeall)

function run(wsapi_env)
local headers = { ["Content-type"] = "text/html" } local function hello_text()
coroutine.yield("<html><body>")
coroutine.yield("<p>Hello Wsapi!</p>")
coroutine.yield("<p>PATH_INFO: " .. wsapi_env.PATH_INFO .. "</p>")
coroutine.yield("<p>SCRIPT_NAME: " .. wsapi_env.SCRIPT_NAME .. "</p>")
coroutine.yield("</body></html>")
end return 200, headers, coroutine.wrap(hello_text)
end

xavante运行cgilua流程的更多相关文章

  1. Servlet简介与Servlet和HttpServlet运行的流程

    1.Servlet      [1] Servlet简介         > Server + let         > 意为:运行在服务器端的小程序.         > Ser ...

  2. 老李推荐:第5章2节《MonkeyRunner源码剖析》Monkey原理分析-启动运行: 启动流程概览

    老李推荐:第5章2节<MonkeyRunner源码剖析>Monkey原理分析-启动运行: 启动流程概览   每个应用都会有一个入口方法来供操作系统调用执行,Monkey这个应用的入口方法就 ...

  3. SpringMVC生命周期,SpringMVC运行流流程

    SpringMVC详细运行流程图 SpringMVC运行原理 1. 客户端请求提交到DispatcherServlet2. 由DispatcherServlet控制器查询一个或多个HandlerMap ...

  4. coTurn 运行在Windows平台的方法及服务与客户端运行交互流程和原理

    coTurn是一个开源的STUN和TURN及ICE服务项目,只是不支持Windows.为了在window平台上使用coTurn源码,需要在windows平台下安装Cygwin环境,并编译coTurn源 ...

  5. 魔兽私服TrinityCore 运行调试流程

    配置参见上一篇:TrinityCore 魔兽世界私服11159 完整配置 (1)启动Web服务器 打开TC2_Web_Mysql目录,运行“启动Web服务器.exe” 自动弹出帐号注册界面,并启动Ap ...

  6. Spark源码分析之一:Job提交运行总流程概述

    Spark是一个基于内存的分布式计算框架,运行在其上的应用程序,按照Action被划分为一个个Job,而Job提交运行的总流程,大致分为两个阶段: 1.Stage划分与提交 (1)Job按照RDD之间 ...

  7. 【hadoop2.6.0】通过代码运行程序流程

    之前跑了一下hadoop里面自带的例子,现在顺一下如何通过源代码来运行程序. 我懒得装eclipse,就全部用命令行了. 整体参考官网上的:http://hadoop.apache.org/docs/ ...

  8. Mybaits 运行原理流程时序图

    1 .初始化sqlsessionFactory 2openSession 3.getMapper返回接口的代理对象 包含了SqlSession对象 4.查询流程

  9. php运行代码流程和性能优化方法

    ---恢复内容开始--- php文件->扫描->zd引擎去理解->opcodes->执行->输出 例子,用white随机循环20000数据进行性能测试,分别对比isset ...

随机推荐

  1. ACM 一种排序

    一种排序 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 现在有很多长方形,每一个长方形都有一个编号,这个编号可以重复:还知道这个长方形的宽和长,编号.长.宽都是整数 ...

  2. 关于jQuery的inArray 方法介绍

    例如: 代码如下: $.get('aaaaa.ashx',null,function(d){ // 假设d 返回 的值为 1,3,43,23,54,67 var arr = d.split(','); ...

  3. js的BOM对象完全解析

    BOM即浏览器对象模型,它包括如下一些对象! (一)screen对象,Screen 对象中存放着有关显示浏览器屏幕的信息. 常见的属性有: availHeight:返回显示屏幕的高度 availWid ...

  4. 【BZOJ】2277: [Poi2011]Strongbox

    题意 有一个密码箱,\(0\)到\(n-1\)中的某些整数是它的密码.如果\(a\)和\(b\)都是它的密码,那么\((a+b)%n\)也是它的密码(\(a,b\)可以相等).某人试了\(k\)次密码 ...

  5. linux命令之 top, free,ps

    linux终端查看cpu和内存使用情况 t一.op进入全屏实时系统资源使用信息查看 PID:进程的ID USER:进程所有者 PR:进程的优先级别,越小越优先被执行 NInice:值 VIRT:进程占 ...

  6. eclipse下启动tomcat出现Setting property 'source' to 'org.eclipse.jst.jee.server: '错误的解决办法

    在eclipse中启动tomcat时出现Setting property 'source' to 'org.eclipse.jst.jee.server:你的站点名'   did not find a ...

  7. dataTransfer.getData()在dragover,dragenter,dragleave中无法获取数据的问题

    做拖拽相关效果时,想在ondragover时给被拖拽元素添加一些样式,于是在dragover事件的函数中通过dataTransfer.getData()获取在dragstart中设置的数据,然而发现d ...

  8. 如何用PHP开发机器人。

    近段时间由于工作需要,需要写个QQ通知的功能,仔细百度了一下,发现了现有的码,现分享大家.特别应该注意的是腾讯公司并未提供过QQ直接通讯的API接口,不过很庆幸的是咋们还有个3g qq可以小小利用下, ...

  9. spring mvc 拦截器 拦截子目录

    项目中碰到这一个问题: 对于/user/loginpage,/user/login这一类的url,放行: 对于/user/{userId}/xxx(xxx不为空)的操作,需要拦截,url-patter ...

  10. HDU 2577

    How to Type Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...