1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>WSAPI</title>
<link rel="stylesheet" href="http://www.keplerproject.org/doc.css" type="text/css"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
</head>
<body>
<div id="container">
<div id="product">
<div id="product_logo">
<a href="http://wsapi.luaforge.net">
<img alt="WSAPI" src="wsapi.png"/>
</a>
</div>
<div id="product_name"><big><strong>WSAPI</strong></big></div>
<div id="product_description">Lua Web Server API</div>
</div> <!-- id="product" -->
<div id="main">
<div id="navigation">
<h1>WSAPI</h1>
<ul>
<li><a href="index.html">Home</a></li>
<li><strong>Manual</strong></li>
<li><a href="libraries.html">Libraries</a></li>
<li><a href="license.html">License</a></li>
</ul>
</div> <!-- id="navigation" -->
<div id="content">
<h2>Installation</h2>
<p>The easiest way to install WSAPI is from <a href="http://luarocks.org">LuaRocks</a>. Just
install the <code>wsapi</code> package. If you want FastCGI
support you need to have the <a href="http://www.fastcgi.com/#TheDevKit">FastCGI dev kit</a>
installed, and use the <code>wsapi-fcgi</code> LuaRocks package.</p>
<p>The WSAPI rock copies samples, docs and support files to it's path inside your
local Rocks repository.</p>
<p>If you do not want to use LuaRocks follow the installation instructions below.</p>
<h3>UNIX-based building</h3>
<p>To build and install WSAPI you are going to need to have Lua 5.1 installed,
as well as a C compiler and the development files for
<a href="http://www.fastcgi.com/#TheDevKit">libfcgi</a>.
Run the included configure script, passing the name of your Lua interpreter's executable
(usually <em>lua</em>, <em>lua51</em> or <em>lua5.1</em>). Then run <em>make all</em> and finally <em>make install</em>.
This last step will probably need root privileges.</p>
<h3>Windows building</h3>
<p>To build the Windows binaries you will need the Lua 5.1 interpreter and a version
of Visual C++ 2005 (the freely available Express edition works fine). Edit <em>Makefile.win</em>
according to the instructions there, then run <em>nmake -f Makefile.win all</em> and finally
<em>nmake -f Makefile.win install</em>.</p>
<p>If you are building the FastCGI connector in Windows but using LuaRocks, you
need to pass the FastCGI installation variables as in (do not use line breaks):</p>
<pre class="example">
luarocks make rockspec/wsapi-fcgi-1.0-1.rockspec
FASTCGI_INCDIR=C:\work\fcgi-2.4.0\include
FASTCGI_LIB=C:\work\fcgi-2.4.0\libfcgi\Release\libfcgi.lib
</pre>
<h3>About web servers</h3>
<p>To run WSAPI applications you will also need a web server such as Apache, Lighttpd,
or IIS (available only for Windows).
If you want to use the Xavante connector you will need to have Xavante installed; the
easiest way to do that is to install <a href="http://www.keplerproject.org">Kepler</a>.</p>
<h2>A Simple WSAPI Application</h2>
<p>WSAPI applications are Lua functions that take an <em>environment</em> and return
the status code, response headers and an output iterator. A very simple
application is the following:</p>
<pre class="example">
function hello(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
</pre>
<p>If you have some experience with web development the example code above should be self-explanatory.</p>
<p>Applications usually are not implemented as naked functions, though, but packaged
inside Lua modules with a <code>run</code> function that is the entry point for WSAPI. This <code>run</code> function
is then passed to your server's WSAPI connector. The generic application launchers
provided with WSAPI respect this pattern.</p>
<p>This is how the above example would look package this way (for example, in a <em>hello.lua</em> file:</p>
<pre class="example">
#!/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
</pre>
<p>The first line tells the UNIX-based web servers such as Apache to run WSAPI's
generic CGI launcher when executing this file as a CGI script.</p>
<h2>Running the application</h2>
<p>This step depends on your server and the connector you want to use.</p>
<h3>UNIX-like (Apache, Lighty, etc.) CGI/FastCGI</h3>
<p>You can run <em>hello.lua</em> directly as a CGI script, through the generic CGI launcher
<em>wsapi</em>. Just give execute permission <em>hello.lua</em> and put it in a URL-accessible path with
execute permission. You should then see something like this when accessing the corresponding
<em>hello.lua</em> URL:</p>
<pre><code> Hello Wsapi!
PATH\_INFO: /
SCRIPT\_NAME: /cgi-bin/hello.lua
</code></pre>
<p>The generic FastCGI launcher <em>wsapi-fcgi</em> can also run the <em>hello.lua</em> file
directly. Configuration depends on your web server, but you should tell it to run
<em>.lua</em> files as FastCGI scripts with <em>wsapi-fcgi</em> as the wrapper (the configuration
is analogous to the necessary for running PHP scripts with FastCGI). As an example,
this are the changes in <code>httpd.conf</code> for using Apache's *mod_fcgid*:</p>
<pre><code> AddHandler fcgid-script .lua
FCGIWrapper /usr/bin/wsapi-fcgi .lua
</code></pre>
<p>You can also run <em>hello.lua</em> through a launcher script specially tailored to it. The driver
script is very similar for both connectors. For CGI it can be this one (<em>hello.cgi</em>):</p>
<pre class="example">
#!/usr/bin/env lua
require "wsapi.cgi"
require "hello"
wsapi.cgi.run(hello.run)
</pre>
<p>For FastCGI (<em>hello.fcgi</em>):</p>
<pre class="example">
#!/usr/bin/env lua
require "wsapi.fastcgi"
require "hello"
wsapi.fastcgi.run(hello.run)
</pre>
<p>You may need to change <em>lua</em> to the name or your Lua interpreter executable.
Now flag the launcher as executable and put it in a URL-accessible path that has
execute permissions. You should see something like this when accessing the corresponding URL:</p>
<pre><code> Hello Wsapi!
PATH\_INFO: /
SCRIPT\_NAME: /cgi-bin/hello.cgi
</code></pre>
<h3>Windows IIS CGI/FastCGI</h3>
<p>The generic launchers on Windows are called <em>wsapi.exe</em> and <em>wsapi-fcgi.exe</em>. You
should associate the <em>.lua</em> file extension with one of them on IIS' management console.
Then copy <em>hello.lua</em> to some URL-accessible path.</p>
<p>For CGI there is also a <em>launcher.exe</em> that you can rename to <em>hello.exe</em> and it
will run the <em>hello.cgi</em> application launcher (<strong>not</strong> the <em>hello.lua</em> application!).
Both should be in the same path, and it should be URL-accessible and have execute
permissions on IIS. You should point your browser to <em>hello.exe</em>.</p>
<h3>Xavante</h3>
<p>The easiest way to run WSAPI applications in a standard Xavante install (via Kepler)
is to give the extension .ws to the application. In the previous example you would
call the file <code>hello.ws</code>, and put it somewhere in Xavante's docroot. See Xavante's
config.lua that Kepler installs for more information on how to configure it.</p>
<h2>Writing WSAPI connectors</h2>
<p>A WSAPI connector builds the environment from information passed by the web server
and calls a WSAPI application, sending the response back to the web server.
The first thing a connector needs is a way to specify which application to run,
and this is highly connector specific. Most connectors receive the application
entry point as a parameter (but WSAPI provides special applications called
<em>generic launchers</em> as a convenience).</p>
<p>The environment is a Lua table containing the CGI metavariables (at minimum
the RFC3875 ones) plus any server-specific metainformation. It also contains
an <em>input</em> field, a stream for the request's data, and an <em>error</em> field,
a stream for the server's error log. The input field answers to the <em>read([n])</em>
method, where <em>n</em> is the number of bytes you want to read (or nil if you want
the whole input). The error field answers to the <em>write(...)</em> method.</p>
<p>The environment should return the empty string instead of nil for undefined
metavariables, and the <code>PATH\_INFO</code> variable should return "/" even if the path
is empty. Behavior among the connectors should be uniform: <code>SCRIPT\_NAME</code> should
hold the URI up to the part where you identify which application you are serving,
if applicable (again, this is highly connector specific), while <code>PATH\_INFO</code>
should hold the rest of the URL.</p>
<p>After building the environment the connector calls the application passing the environment
to it, and collecting three return values: the HTTP status code, a table with headers, and
the output iterator. The connector sends the status and headers right away to the server,
as WSAPI does not guarantee any buffering itself. After that it begins calling the iterator
and sending output to the server until it returns nil.</p>
<p>The connectors are careful to treat errors gracefully: if they occur before sending the
status and headers they return an "Error 500" page instead, if they occur while
iterating over the response they append the error message to the response.</p>
<h2>Conveniences for application writers</h2>
<p>WSAPI is very low-level and just lets your application pretend that web servers
and gateway interfaces are similar, but it does not do any kind of processing/parsing
on the request, nor any buffering on the output. Most web applications need these
features, so we provide helper libraries to do it.</p>
<p>The first library is <em>wsapi.request</em>. This library encapsulates the environment,
parsing the request data (GET and POST) and also handling file uploads and incoming
cookies.</p>
<p>The other helper is <em>wsapi.response</em>, which offers a simpler interface (along with
buffering) for output instead of the inversion of control of the iterator. It also
lets you easily send cookies back to the browser.</p>
<p>Finally there is <em>wsapi.util</em>, which provides URI encoding/decoding functions.</p>
<h2>WSAPI frameworks</h2>
<p>The facilities above make it easier to write applications, but still are very basic.
For more advanced web programming there are also frameworks built on top of WSAPI.
Examples would be <strong><a href="http://orbit.luaforge.net">Orbit</a></strong>, which adds niceties as dispatch based on
pattern matching over the PATH_INFO, easy serving of static content, easy access
to databases, and easy page caching, and <strong>SAPI</strong>, included in the WSAPI package as the
<em>wsapi.sapi</em> application, for running <strong><a href="http://www.keplerproject.org/cgilua/">CGILua</a></strong>
scripts and Lua pages.</p>
</div> <!-- id="content" -->
</div> <!-- id="main" -->
<div id="about">
<p><a href="http://validator.w3.org/check?uri=referer">Valid XHTML 1.0!</a></p>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
</body>
</html>
|