pax_global_header00006660000000000000000000000064122011647720014514gustar00rootroot0000000000000052 comment=c4d372ff29d7a2f511d399bcf551b0300ea6765b lua-cgi-5.2~alpha2/000077500000000000000000000000001220116477200141715ustar00rootroot00000000000000lua-cgi-5.2~alpha2/Makefile000077500000000000000000000011731220116477200156360ustar00rootroot00000000000000# $Id: Makefile,v 1.49 2008/02/19 19:41:24 mascarenhas Exp $ # Default prefix PREFIX= /usr/local # System's lua directory (where Lua libraries are installed) LUA_DIR= $(PREFIX)/share/lua/5.1 CGILUA_DIR= $(LUA_DIR)/cgilua CGILUA_LUAS= src/cgilua/authentication.lua src/cgilua/cookies.lua src/cgilua/dispatcher.lua src/cgilua/loader.lua src/cgilua/lp.lua src/cgilua/mime.lua src/cgilua/post.lua src/cgilua/readuntil.lua src/cgilua/serialize.lua src/cgilua/session.lua src/cgilua/urlcode.lua ROOT_LUAS= src/cgilua/cgilua.lua all: install: mkdir -p $(CGILUA_DIR) cp $(CGILUA_LUAS) $(CGILUA_DIR) cp $(ROOT_LUAS) $(LUA_DIR) clean: lua-cgi-5.2~alpha2/Makefile.win000077500000000000000000000011721220116477200164310ustar00rootroot00000000000000# $Id: Makefile.win,v 1.11 2007/12/05 18:40:17 carregal Exp $ LUA_DIR= c:\lua5.1\lua CGILUA_DIR= $(LUA_DIR)\cgilua CGILUA_LUAS= src\cgilua\authentication.lua src\cgilua\cookies.lua src\cgilua\dispatcher.lua src\cgilua\loader.lua src\cgilua\lp.lua src\cgilua\mime.lua src\cgilua\post.lua src\cgilua\readuntil.lua src\cgilua\serialize.lua src\cgilua\session.lua src\cgilua\urlcode.lua ROOT_LUAS= src\cgilua\cgilua.lua install: IF NOT EXIST "$(LUA_DIR)" mkdir "$(LUA_DIR)" IF NOT EXIST "$(CGILUA_DIR)" mkdir "$(CGILUA_DIR)" FOR %F IN ($(CGILUA_LUAS)) DO copy %F "$(CGILUA_DIR)" FOR %F IN ($(ROOT_LUAS)) DO copy %F "$(LUA_DIR)" lua-cgi-5.2~alpha2/README000077500000000000000000000145461220116477200150660ustar00rootroot00000000000000CGILua 5.1.4 http://keplerproject.org/cgilua Overview 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. One of advantages of CGILua is its abstraction of the underlying Web server. CGILua can be used with a variety of Web servers and, for each server, with different launchers. A launcher is responsible for the interaction of CGILua and the Web server, for example using ISAPI on IIS or mod_lua on Apache. The reference implementation of CGILua launchers is Kepler. CGILua is free software and uses the same license as Lua 5.1. You can also install CGILua using LuaRocks: luarocks install cgilua History Version 5.1.4 [22/Mar/2010] * fixed file upload reentrancy * new launchers for cgilua that do not depend on kepler_init * Correction on mkurlpath Version 5.1.3 [9/Mar/2009] * Strips utf-8 BOM from templates in lp.include * Fixed reentrancy bug * Fixed reset of cgilua.urlpath Version 5.1.2 [19/May/2008] * Added the cgilua.authentication module * cgilua.print now separates arguments with tabs, like Lua print * Now print and write are aliases to cgilua.print and cgilua.put. * Now strips an eventual #! from top of Lua Pages files * CGILua can now process sequential requests in the same Lua state * Better error handling. Wraps error message in valid HTML * Bug fixed: CGILua was ignoring CGILUA_TMP in Windows * Corrected the URL handling for the dispatcher (bug found by Ronaldo Sugii) * Better URL handling for different locales * Handling multiple values in the generated URL (patch by Matt Campbell) * Fixed file handle leak in loader.lua * Fixed bug [#2630] - Including new files (bug found by Bruno Massa) Version 5.1.1 [21/Nov/2007] * Changed the security policy for scripts. Now scripts have access to all Lua globals, including the debug and os packages. It is up to the application developer to choose what policy to use * If you are using Kepler, it is strongly suggested that you replace your previous CGILua config.lua file with the new one installed by Kepler and then merge the differences * Added the cgilua.dispatcher module * Added default handlers for a set of MIME types. The default handlers return only the content-type and conten-lenght headers for the files. * Added functions cgilua.splitonfirst and cgilua.splitonlast * Added functions cgilua.tmpfile and cgilua.tmpname * Changed the use of "/test" for the session temporary directory checking (bug found by Yuri Takhteyev) * Corrected the use of cgilua.QUERY in the session handling (bug found by Jim Madsen) * Better handling of "application/xml" POST content types (patch by Ignacio Burgueño) * Fixed Bug [#1910] - Bug in byte accounting in post.lua (found by Greg Bell) Version 5.1.0 [23/Aug/2007] * Uses Lua 5.1 * Added function cgilua.print (that uses tostring on its parameters) * Added a generic dispatcher and the concept of CGILua Apps * Replaced the cgi table used until CGILua 5.0 by two others cgilua.QUERY and cgilua.POST) * Added fake "package" table to enable the user/programmer to create modules with global visibility * Bug fix: return of HTTP status code * Bug fix: close method was recreating the session file * Correcting how LP handles strings with CR characters (Lua 5.0 would not mind, but Lua 5.1 does) * Fixed a bug with lighttpd Version 5.0.1 [20/Sep/2006] * Uses Compat-5.1 Release 5. * Caches Lua Pages template strings. * New configuration examples. * Improvements in the Session library. * Removed the debug package from the user scripts environment. * POST handling bug fixes (related to the text/plain content type). Version 5.0 [23/Jul/2005] * CGILua distribution includes now only the Lua files, the launchers have been moved to Kepler. * The Stable library is now distributed with VEnv. * Fixed a file upload bug in the CGI and Xavante launchers. * cgilua.lp.include() now accepts an environment to run the preprocessed file in it. Version 5.0 beta 2 [23/Dec/2004] * Distribution bug fix: stable.lua was missing Version 5.0 beta [15/Dec/2004] * New ISAPI and Servlet Launchers. * New Error Handling features. * New persistent data feature (Stable). * Uses the package model for Lua 5.1. * Simpler User Session API. * Small bug corrections Version 5.0 alpha 3 [8/Jun/2004] Version 5.0 alpha [21/Apr/2004] Incompatibility with previous CGILua versions (5.0, 4.0 and 3.x) * CGILua 5.1 uses Lua 5.1. * The cgi table is now deprecated. See Receiving parameters for a more detailed explanation. * The template tags have changed. See Lua pages for a more detailed explanation. * The use of getenv calls to obtain CGI variables should be replaced by cgilua.servervariable calls. Credits CGILua 5.1 CGILua 5.1 is being maintained by André Carregal and Tomás Guisasola with contributions from Fábio Mascarenhas and others from the Kepler mailing list. CGILua 5.0 CGILua 5.0 was completely redesigned by Roberto Ierusalimschy, André Carregal and Tomás Guisasola as part of the Kepler Project. The implementation is compatible with Lua 5.0 and was coded by Tomás Guisasola with invaluable contributions by Ana Lúcia de Moura, Fábio Mascarenhas and Danilo Tuler. CGILua 5.0 development was sponsored by Fábrica Digital, FINEP and CNPq. CGILua 4.0 Ana Lúcia de Moura adapted CGILua 3.2 to Lua 4.0, reimplemented some code and added a few improvements but this version was not officially distributed. CGILua 3.x CGILua was born as the evolution of an early system developed by Renato Ferreira Borges and André Clínio at TeCGraf. At the time (circa 1995) there were no CGI tools available and everything was done with shell scripts! However, the main contribution to CGILua 3 was done by Anna Hester, who consolidated the whole tool and developed a consistent distribution with versions 3.1 and 3.2 (the number was an effort to follow Lua version numbers). This version was widely used on a great variety of systems. lua-cgi-5.2~alpha2/doc/000077500000000000000000000000001220116477200147365ustar00rootroot00000000000000lua-cgi-5.2~alpha2/doc/br/000077500000000000000000000000001220116477200153415ustar00rootroot00000000000000lua-cgi-5.2~alpha2/doc/br/cgi-128.gif000077500000000000000000000105641220116477200171130ustar00rootroot00000000000000GIF87arvz}~ mmmssstttyyy|||  !!%%""%%)))),,55116611::::>>BBDDBBHHJJMMLLPPTTQQWWYYZZ^^\\``bbggiijjoollqqvvttyy{{~~‰ÊŎƐǒȕʙ˙̟ϡϢѥҩөԭֱױصڻݼ,# H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0%2Is"j.3RO% @s "QJH@FQ0ᣤ P`O QECeܐ E$e !hsJ# 0 QSଁN'@@˗T᧥H9f$`rGTd!"},P>LPRʝDlB| 砃 O%)@PE " P#R$PNAE|| IN'qTaц!P#}q' %@mxP RD!EvGvutĈt ScNO 7&-fGˆ| _Q=Rd{=qQaqIpO $D4]|>(^FNq$lY6T@4bH!~bH#! 4! WЭ~8 c!C TAoTA 2!:ǘYFAk$N Eb&6ea @d:ntG$O:*4pw5˾ 1*x u /۠mQE$;P-2&sGaFpV !Qq<&ɰBf3 bXO!SaBҰEyU+50j8%82d?-D'pSw!'8#e%MOkG;{s2wQ7HBa 2!p-_=ę (1E`ۑ=>p*ha L <!KXFHv؞NE M;x ͼCq k'|2H8CZ0 |r$ G`_([|w%}-5$0 #^'`*e!.՝q5g$kx+/y[P :'$ Br H b ԉoHXo8 (@`@Dk3ZWՊgޝgAguD"11&9""6N(c%U@UF=ӥwڝz/\vPQ3lߩOwH?&F1' ^-*PqTDyO#և~WV=ඕCzfI-Aa%|gX4+}6Ucb QP@rG|XNYaAe/@)jX֧y]6'$lsynZ ?@uȁq FvA45 1Ѣ$TWG]uGEa2ubM =l4NueQ'(1W6u0z@rݓ1n"7}-I@{o6lP0O1'ԳS31PhSPQ(d "Ksڶm?Z4@"N\ 7AJ3["{OjPxh@4!N#`9vEz'g@!?* A@YPAfgsь eӥUP1]iPpdD ,(@jpT( oP ` TN&w&NwVd(rJ15Cb0)@~n K_"AF(VyX# `h VIM<#@1 &0@p0jt#q#&3) C) h2y3Њe }q3v`*ԘrsVpl@~ /XwEk7r8BW*!0i9sa΄lulv$ W( `atkVgH7pt ՝5F7&P(+aR\tBv=kPaiTdEb!PQb {P0"k?՝ZpXpr @\C;ZU@bp'Muix^EkeR# cǝycΉ-p3D:xMkNpQ, "i&1 _ ejq3: 3Tā'-qwgS5!;6#t@4qrAC7@, (:3W#P3W1F':<e&@P0x0`@P;i{PY8-+7W$ P|Q"nMg:drHMJKH֯A!N@7!h5nP r $AG0{LQ &@% k0gӪ, GM 1@1Ep@{bl;RmdJ"M>"G@( kSٵjl۶n;lua-cgi-5.2~alpha2/doc/br/index.html000077500000000000000000000213321220116477200173420ustar00rootroot00000000000000 CGILua: geração de scripts para a Web usando Lua
CGILua
Geração de scripts para a Web usando Lua

Visão geral

O CGILua é uma ferramenta que permite criar páginas Web dinâmicas e manipular a inserção de dados por meio de formulários Web. O CGILua permite separar o tratamento dos dados e a lógica do processo de geração de páginas, facilitando o desenvolvimento de aplicativos Web em Lua. Uma das vantagens do CGILua é sua capacidade de abstrair o servidor Web utilizado. Você pode desenvolver um aplicativo em CGILua para um servidor Web e executá-lo em qualquer outro servidor Web compatível com CGILua.

O CGILua é um software livre que usa a mesma licença da Lua 5.0.

Status

A versão atual é a 5.0.

Download

O download do CGILua pode ser feito em código fonte na sua página no LuaForge.

Histórico

Versão 5.0 [23 de julho de 2005]
  • A distribuição do CGILua passa a incluir apenas os arquivos Lua. Os disparadores foram movidos para o Kepler.
  • A biblioteca Stable passou a ser distribuída com VEnv.
  • Correção de um problema de upload de arquivo nos disparadores CGI e Xavante.
  • cgilua.lp.include() passa a aceitar um ambiente com o qual executa o arquivo preprocessado.
Versão 5.0 beta 2 [23 de dezembro de 2004]
  • Correção de problema de distribuição: stable.lua estava ausente
Versão 5.0 beta [15 de dezembro de 2004]
  • Novos disparadores ISAPI e Servlet.
  • Novos recursos de tratamento de erros.
  • Novo recurso de dados persistentes (Stable).
  • Uso do modelo de pacote de Lua 5.1.
  • API de usuário Session mais simples.
  • Correções de pequenos problemas
Versão 5.0 alfa 3 [8 de junho de 2004]
Versão 5.0 alfa [21 de abril de 2004]

Incompatibilidade com versões anteriores do CGILua (4.0 e 3.x)

  • O CGILua 5.0 usa o Lua 5.0.
  • A tabela cgi passou a permitir valores do tipo tabela. Consulte Recebimento de parâmetros para obter uma explicação detalhada.
  • As tags de templates foram alteradas. Consulte Lua Pages para obter uma explicação detalhada.
  • O uso de chamadas getenv para obter variáveis CGI deve ser substituído por chamadas cgilua.servervariable.

Créditos

CGILua 5.0
O CGILua 5.0 foi totalmente reelaborado por Roberto Ierusalimschy, André Carregal e Tomás Guisasola, como parte do Projeto Kepler. A implementação é compatível com a Lua 5.0 e foi codificada por Tomás Guisasola, com as valiosas contribuições de Ana Lúcia de Moura, Fábio Mascarenhas e Danilo Tuler. O desenvolvimento do CGILua 5.0 foi patrocinado pela Fábrica Digital, pela FINEP e pelo CNPq.
CGILua 4.0
Ana Lúcia de Moura adaptou o CGILua 3.2 para Lua 4.0, reimplementou alguns trechos do código e acrescentou alguns aperfeiçoamentos, mas essa versão não foi distribuída oficialmente.
CGILua 3.x
O CGILua surgiu como a evolução de um sistema originário desenvolvido por Renato Ferreira Borges e André Clínio no TeCGraf. Na época (circa 1995) não estavam disponíveis ferramentas em CGI e tudo era feito com scripts de shell!
Porém, a principal contribuição ao CGILua 3 foi dada por Anna Hester, que consolidou toda a ferramenta e desenvolveu uma distribuição consistente com as versões 3.1 e 3.2 (o número foi um esforço para seguir os números de versão da Lua). Essa versão foi amplamente utilizada em uma grande variedade de sistemas.

Fale conosco

Para obter mais informações, entre em contato. Seus comentários são importantes!

XHTML 1.0 válido!

$Id: index.html,v 1.3 2005/11/03 18:48:57 carregal Exp $

lua-cgi-5.2~alpha2/doc/br/libraries.html000077500000000000000000000205451220116477200202140ustar00rootroot00000000000000 CGILua: geração de scripts para a Web usando Lua
CGILua
Geração de scripts para a Web usando Lua

Visão geral

O CGILua inclui um conjunto de bibliotecas externas que permite o tratamento de cookies, dados serializados e sessões. Para usar essas bibliotecas, basta usar a instrução require para solicitá-las no arquivo config.lua do CGILua.

Cookies

cgilua.cookies.get (name)
Obtém o valor do cookie com o name fornecido.
Retorna uma string com o valor do cookie.
cgilua.cookies.set (name, value[, options])
Define o valor value do cookie com um name dado. Os nomes e valores de campos na tabela options são usados nos atributos do cookie. Esta função deve ser chamada antes do envio dos cabeçalhos HTTP e antes da geração de qualquer resultado.
Não retorna nada.
cgilua.cookies.sethtml (name, value[, options])
Define o valor value do cookie com um name dado. Esta função gera um elemento HTML <meta>, assim, ela deve ser chamada depois de produzida a tag HTML <head> e antes da tag </head> correspondente.
Não retorna nada.
cgilua.cookies.delete (name[, options])
Exclui um cookie com um name dado (define o valor como xxx).
Não retorna nada.

Serialize

cgilua.serialize (table, outfunc[, indent[, prefix]])
Serializa uma table usando outfunc como a função usada para gerar o resultado; indent como uma string opcional com o padrão de identação; prefix como uma string opcional com o prefixo de identação (usado para armazenar o recuo real entre as chamadas recursivas).
Observe que há algumas restrições: os valores dos tipos function e userdata não podem ser serializados; as tabelas que contêm ciclos também não podem ser serializadas.
Não retorna nada.

Session

cgilua.session.close ()
Fecha a sessão de usuário. Salva todos os dados em cgilua.session.data no sistema de armazenamento em uso (normalmente, o sistema de arquivos). Esta função deve ser chamada depois que o script terminar de ser executado. Para garantir que isso ocorra, recomenda-se usar a addclosefunction no arquivo de configuração.
Não retorna nada.
cgilua.session.data
Tabela que contém os dados sobre a sessão de usuário.
cgilua.session.delete (id)
Exclui uma sessão. O argumento id é o identificador da sessão.
Não retorna nada.
cgilua.session.load (id)
Carrega dados de uma sessão. O argumento id é o identificador da sessão.
Retorna uma tabela com os dados da sessão ou nil seguido de uma mensagem de erro.
cgilua.session.new ()
Cria um novo identificador de sessão.
Retorna o novo identificador de sessão.
cgilua.session.open ()
Abre a sessão de usuário. Cria a tabela cgilua.session.data. Esta função deve ser chamada imediatamente antes da execução do script, mas após o processamento dos cabeçalhos da solicitação. Para garantir que isso ocorra, recomenda-se usar a addopenfunction no arquivo de configuração.
Não retorna nada.
cgilua.session.save (id, data)
Salva data em uma sessão com um id.
Não retorna nada.
cgilua.session.setsessiondir (path)
Define o diretório temporário da sessão. O argumento path é uma string com o novo diretório.
Não retorna nada.

XHTML 1.0 válido!

$Id: libraries.html,v 1.3 2005/11/03 18:48:57 carregal Exp $

lua-cgi-5.2~alpha2/doc/br/license.html000077500000000000000000000140021220116477200176510ustar00rootroot00000000000000 CGILua: geração de scripts para a Web usando Lua
CGILua
Geração de scripts para a Web usando Lua

Licença

O CGILua é um software livre: ele pode ser usado com fins acadêmicos e comerciais sem custo algum. Não há royalties ou restrições do tipo "copyleft" da GNU. O CGILua é classificado como um software Open Source (código aberto). Suas licenças são compatíveis com GPL. O CGILua não é de domínio público e o Kepler Project mantém o seu direito autoral. Os detalhes legais estão listados abaixo.

A idéia da licença é a de que você fique livre para usar o CGILua com qualquer objetivo sem incorrer em despesas e sem ter que pedir autorização para isso. Nossa única exigência é que, caso você realmente use o CGILua, então, o devido crédito seja dado por meio da inclusão do aviso de copyright apropriado em seu produto ou na documentação correspondente.

A biblioteca do CGILua foi desenvolvida e implementada por Roberto Ierusalimschy, André Carregal e Tomás Guisasola. A implementação não deriva de softwares licenciados.


Copyright © 2003-2005 The Kepler Project.

Por meio deste, concede-se permissão gratuita a qualquer pessoa que obtenha uma cópia deste software e dos arquivos da documentação associada (o "Software") para trabalhar com o Software sem restrições, incluindo, sem limitação, os direitos de usar, copiar, modificar, mesclar, publicar, distribuir, sublicenciar e/ou vender cópias do Software, e de permitir a pessoas a quem o Software seja fornecido de assim fazê-lo, sujeitando-se às seguintes condições:

O aviso de copyright acima e esta permissão devem ser incluídos em todas as cópias ou em partes significativas do Software.

O SOFTWARE É FORNECIDO "NO ESTADO EM QUE ESTIVER", SEM GARANTIAS DE QUALQUER TIPO, EXPLÍCITAS OU IMPLÍCITAS, INCLUINDO, SEM LIMITAÇÃO, AS GARANTIAS DE COMERCIALIZAÇÃO, ADEQUAÇÃO A UM DETERMINADO OBJETIVO E NÃO INFRAÇÃO. EM CIRCUNSTÂNCIA ALGUMA OS AUTORES OU OS DETENTORES DO COPYRIGHT SERÃO CONSIDERADOS RESPONSÁVEIS POR QUAISQUER REIVINDICAÇÕES, DANOS OU OUTRAS RESPONSABILIDADES, POR MEIO DE CONTRATO, DANOS OU OUTROS RELACIONADOS OU EM DECORRÊNCIA DO USO DO SOFTWARE OU OUTRAS AÇÕES NO MESMO.

XHTML 1.0 válido!

$Id: license.html,v 1.3 2005/11/03 18:48:57 carregal Exp $

lua-cgi-5.2~alpha2/doc/br/manual.html000077500000000000000000000432211220116477200175110ustar00rootroot00000000000000 CGILua: geração de scripts para a Web usando Lua
CGILua
Geração de scripts para a Web usando Lua

Introdução

O CGILua usa Lua como a linguagem de scripts do servidor para criar páginas Web dinâmicas. O CGILua oferece suporte a Lua Scripts puros e a Lua Pages (.lp). Um Lua Script é, basicamente, um programa em Lua que cria todo o conteúdo de uma página Web e o retorna para o cliente. Uma Lua Page é um arquivo de texto com marcações (HTML, XML etc.) que incorpora código Lua usando algumas tags especiais. Essas tags são processadas pelo CGILua e a página resultante é retornada para o cliente.

Os Lua Scripts e as Lua Pages são igualmente fáceis de usar e a opção por um deles depende, primariamente, das características da página resultante. Enquanto as Lua Pages são mais convenientes para separar a lógica e o formato, os Lua Scripts são mais adequados para criar páginas de estrutura mais simples, mas que requeiram uma quantidade significativamente maior de processamento interno.

Ao permitir a combinação desses dois métodos, o CGILua dá aos desenvolvedores de aplicativos Web uma maior flexibilidade quando os dois requisitos estão presentes. Para obter uma descrição detalhada de ambos os métodos de criação de scripts e alguns exemplos práticos, consulte Lua Scripts e Lua Pages.

A arquitetura do CGILua é dividida em duas camadas. O nível inferior é representado pela API do servidor (SAPI) e o mais alto, pela API do próprio CGILua. SAPI é a interface entre o servidor Web e a API do CGILua, precisando portanto ser implementada em cada servidor Web e método de disparo empregado.

O CGILua e a API do CGILua são implementados usando-se apenas a SAPI e são totalmente transportáveis entre disparadores e os servidores Web compatíveis. Dessa maneira, qualquer Lua Script ou Lua Page pode ser usada por qualquer disparador.

Instalação

O CGILua segue o modelo de pacotes de Lua 5.1 e, conseqüentemente, precisa ser "instalado". Consulte a seção Configuração do Compat-5.1 para obter informações sobre como instalar corretamente o módulo.

Configuração

O CGILua 5.0 oferece um único arquivo de configuração, chamado config.lua, e um conjunto de funções para alterar a configuração padrão do CGILua. Esse arquivo pode ser colocado em qualquer lugar em LUA_PATH para facilitar a atualização do CGILua sem a substituição do config.lua existente.

Alguns usos do config.lua são:

Tratadores de scripts
Você pode adicionar novos tratadores de CGILua usando cgilua.addscripthandler (consulte também cgilua.buildplainhandler e cgilua.buildprocesshandler para obter as funções que criam tratadores simples).
Tamanhos de dados POST
Altere os limites de tamanho dos dados POST usando cgilua.setmaxinput e cgilua.setmaxfilesize.
Abertura e fechamento de funções
Você pode adicionar suas funções ao ciclo de vida útil do CGILua usando cgilua.addopenfunction e cgilua.addclosefunction. Essas funções são executadas imediatamente antes e depois da execução do script, mesmo quando ocorrer um erro no processamento do script.

Tratamento de erros

Há três funções para tratamento de erros no CGILua:

A função cgilua.seterrorhandler define o tratador de erro, uma função chamada pela Lua logo após ocorrer um erro. O tratador de erro tem acesso à pilha de execução antes da ocorrência do erro, assim, ele pode gerar uma mensagem de erro usando as informações da pilha. Lua também possui uma função para fazer isso: debug.traceback.

A função cgilua.seterroroutput define a função que decide o que deve ser feito com a mensagem de erro. Ele pode ser enviado para o cliente, gravado em um arquivo de log ou enviado para um endereço de email (com a ajuda do LuaSocket ou do LuaLogging, por exemplo).

A função cgilua.errorlog é fornecida para gravar diretamente no arquivo de log de erros do servidor HTTP.

Lua Scripts

Os Lua Scripts são arquivos de texto que contêm código Lua válido. Esse estilo de uso adota uma forma de programação para Web mais "rústica", na qual um programa é responsável pela geração da página resultante. Os Lua Scripts têm a extensão padrão .lua.

Para gerar um documento Web (HTML, XML, WML, CSS etc.) válido, o Lua Script deve obedecer a uma ordem esperada pelo HTTP para produzir a saída, primeiro enviando os cabeçalhos corretos e, depois, enviando o conteúdo real do documento.

O CGILua tem algumas funções que facilitam essas tarefas, por exemplo, cgilua.htmlheader para produzir o cabeçalho de um documento HTML e cgilua.put para enviar o conteúdo do documento (ou parte dele).

Por exemplo, um documento HTML que exiba a frase "Olá mundo!" pode ser gerado com este Lua Script:

cgilua.htmlheader()
cgilua.put([[
<html>
<head>
  <title>Olá mundo</title>
</head>
<body>
  <strong>Olá mundo!</strong>
</body>
</html>]])

Observe que o exemplo acima gera uma página "fixa": embora ela seja gerada no momento da execução, a página não contém informações "variáveis". Isso significa que o mesmo documento poderia ser gerado diretamente com um simples arquivo HTML estático. No entanto, os Lua Scripts são especialmente úteis quando o documento contém informações que não sejam conhecidas de antemão ou que mudem de acordo com os parâmetros passados. Nesse caso, é necessário gerar uma página "dinâmica".

Outro exemplo fácil pode ser mostrado, desta vez, usando uma estrutura de controle Lua, variáveis e o operador de concatenação:

cgilua.htmlheader()

if cgi.language == 'english' then
  greeting = 'Hello World!'
elseif cgi.language == 'portuguese' then
  greeting = 'Olá Mundo!'
else
  greeting = '[unknown language]'
end

cgilua.put('<html>')  
cgilua.put('<head>')
cgilua.put('  <title>'..greeting..'</title>')
cgilua.put('</head>')
cgilua.put('<body>')
cgilua.put('  <strong>'..greeting..'</strong>')
cgilua.put('</body>')
cgilua.put('</html>')

No exemplo acima, o uso de cgi.language indica que language foi passado para o Lua Script como um parâmetro do CGILua, oriundo de um campo de formulário HTML (via POST) ou da URL usada para ativá-lo (via GET). O CGILua decodifica automaticamente esses parâmetros para que você possa usá-los à vontade em Lua Scripts e Lua Pages.

Lua Pages

Uma Lua Page é um arquivo de modelo (template) com texto que será processado pelo CGILua antes de o servidor HTTP enviá-lo para o cliente. O CGILua não processa o texto, ele procura algumas marcações especiais que inserem o código Lua no arquivo. Depois que essas marcações são processadas e mescladas no arquivo de template, os resultados são enviados para o cliente.

As Lua Pages têm a extensão padrão .lp. Elas são uma maneira mais simples de criar uma página dinâmica porque eliminam a necessidade de enviar os cabeçalhos HTTP. Em geral, Lua Pages são páginas HTML, portanto, o CGILua envia automaticamente o cabeçalho HTML.

Como há algumas restrições quanto aos usos de cabeçalhos HTTP, ocasionalmente, será preciso usar um Lua Script em vez de uma Lua Page.

As marcações fundamentais de uma Lua Page são:

<?lua chunk ?>
Processa e mescla os resultados da execução do chunk Lua, no qual a marcação está localizada no template. A forma alternativa <% chunk %> também pode ser usada.
<?lua= expression ?>
Processa e mescla a avaliação de uma expression em Lua, na qual a marcação está localizada no template. A forma alternativa <%= expression %> também pode ser usada.

Observe que a marcação de término não pode estar dentro de um chunk de código ou uma expressão Lua, mesmo que esteja entre aspas. O pré-processador de Lua Pages apenas faz substituições globais no template, procurando um par correspondente de marcações e gerando o código Lua correspondente para obter o mesmo resultado que o Lua Script equivalente.

O segundo exemplo da seção anterior pode ser escrito usando uma Lua Page como esta:

<html>
<?lua
if cgi.language == 'english' then
  greeting = 'Hello World!'
elseif cgi.language == 'portuguese' then
  greeting = 'Olá Mundo!'
else
  greeting = '[unknown language]'
end
?>
<head>
  <title><%= greeting %></title>
</head>
<body>
  <>strong<%= greeting %></strong>
</body>
</html>

As tags HTML e as tags de Lua Page podem ser livremente intercambiadas. Porém, como ocorre em outras linguagens de template, considera-se uma boa prática não usar lógica Lua explícita em templates. A abordagem recomendada é usar apenas chamadas de funções que retornam chunks de conteúdo, dessa forma, nesse exemplo, pressupondo-se que a função getGreeting tenha sido definida em outro ponto como

function getGreeting()
  local greeting
  if cgi.language == 'english' then
    greeting = 'Hello World!'
  elseif cgi.language == 'portuguese' then
    greeting = 'Olá Mundo!'
  else
    greeting = '[unknown language]'
  end
  return greeting
end

a Lua Page poderia ser reescrita desta maneira:

<html>
<head>
  <title><%= getGreeting() %></title>
</head>
<body>
  <strong><%= getGreeting() %></strong>
</body>
</html>

Recebimento de parâmetros: a tabela cgi

O CGILua oferece uma maneira unificada de acessar dados passados para os scripts no método HTTP usado (GET ou POST). Independentemente do método usado no cliente, todos os parâmetros serão fornecidos dentro da tabela cgi.

Normalmente, todos os tipos de parâmetros estarão disponíveis como strings. Se o valor de um parâmetro for um número, ele será convertido na representação de string correspondente.

Há apenas duas exceções nas quais o valor será uma tabela Lua. O primeiro caso ocorre em uploads de arquivos, no qual a tabela correspondente terá estes campos:

filename
o nome do arquivo como fornecido pelo cliente.
filesize
o tamanho do arquivo em bytes.
file
o handler do arquivo temporário. O arquivo deve ser copiado porque o CGILua o removerá após a conclusão do script.

O outro caso que usa tabelas Lua ocorre quando há mais de um valor associado ao mesmo nome de parâmetro. Isso acontece no caso de uma lista de seleção com vários valores; mas também ocorre quando o formulário tiver dois ou mais elementos com o mesmo atributo name (possivelmente porque um estava em um formulário e o outro, na query string). Todos os valores serão inseridos em uma tabela indexada, na ordem em que foram tratados.

XHTML 1.0 válido!

$Id: manual.html,v 1.3 2005/11/03 18:48:57 carregal Exp $

lua-cgi-5.2~alpha2/doc/br/reference.html000077500000000000000000000470421220116477200201770ustar00rootroot00000000000000 CGILua: geração de scripts para a Web usando Lua
CGILua
Geração de scripts para a Web usando Lua

Cabeçalhos

As funções de cabeçalho são usadas para alterar os cabeçalhos de resposta HTTP e consistem em:

cgilua.contentheader (type, subtype)
Envia um cabeçalho Content-type com os valores dados de tipo e subtipo.
Ambos os argumentos são strings: type é o tipo do cabeçalho; subtype é o subtipo do cabeçalho.
Não retorna nada.
cgilua.header (header, value)
Envia um cabeçalho genérico. Esta função não deve ser usada para gerar um cabeçalho Content-type ou Location.
Ambos os argumentos são strings: header é o nome do cabeçalho e value, seu valor.
Não retorna nada.
cgilua.htmlheader ()
Envia o cabeçalho de um arquivo HTML (Content-type: text/html).
Não retorna nada.
cgilua.redirect (url, args)
Envia o cabeçalho para forçar o redirecionamento para a URL dada, adicionando os parâmetros na tabela args relativos à nova URL.
O primeiro argumento (url) é a URL à qual o navegador deve ser redirecionado; o segundo (args) é uma tabela opcional que pode conter pares nome = valor que serão codificados para formar um URL válido (consulte a função cgilua.urlcode.encodetable).
Não retorna nada.

Geração de conteúdo

As funções de geração de conteúdo são usadas para produzir texto para a resposta e gerar URLs no formato do CGILua. Elas consistem em:

cgilua.mkabsoluteurl (path)
Cria uma URL absoluta contendo path da URL dada.
Retorna a URL absoluta resultante.
cgilua.mkurlpath (script [, args])
Cria o caminho de uma URL a ser usado como link para um script CGILua usando a tabela opcional de argumentos (args). Os argumentos são usados na URL como parâmetros de string de consulta.
Retorna a URL resultante.
cgilua.put (string)
Envia a string dada para o cliente.
Não retorna nada.

Lua Pages

As funções de Lua Pages são usadas para processar templates Lua Pages e definir o comportamento desse processamento. Elas consistem em:

cgilua.handlelp (filename)
Equivale a cgilua.lp.include, mas envia o cabeçalho HTML antes do arquivo pré-processado.
Não retorna nada.
cgilua.lp.include (filename)
Pré-processa um template Lua Page (fornecido por filename) e envia o resultado para o cliente.
Não retorna nada.
cgilua.lp.setcompatmode (boolean)
Ativa e desativa o modo de compatibilidade. A ativação fará com que o pré-processador de Lua Pages entenda as estruturas de campos de expressão e campos de código usadas por versões anteriores do CGILua.
Não retorna nada.
cgilua.lp.setoutfunc (funcname)
Define o nome da função de resultado de templates. O pré-processador Lua Pages gera chamadas para a função com o funcname fornecido (uma string).
Não retorna nada.
cgilua.lp.translate (string)
Usa o pré-processador Lua Pages para gerar uma string correspondente ao código Lua que executa expressões e/ou chunks em Lua dentro da string fornecida.
Retorna uma string com o código Lua resultante.

Variáveis do CGILua

As variáveis do CGILua oferecem informações sobre o script em processamento e as variáveis de ambiente do CGI. Elas consistem em atributos e funções:

cgilua.script_file
O nome do arquivo do script em execução. Obtido de cgilua.script_path.
cgilua.script_path
O caminho completo do arquivo do script em execução. Esta variável normalmente é igual à variável de ambiente do CGI PATH_TRANSLATED.
cgilua.script_pdir
O diretório do script em execução. Obtido de cgilua.script_path.
cgilua.script_vdir
O diretório virtual do script em execução. Obtido de cgilua.script_vpath.
cgilua.script_vpath
O caminho virtual completo do arquivo do script em execução. Equivale à variável de ambiente do CGI PATH_INFO.
cgilua.servervariable (varname)
Retorna uma string com o valor da variável de ambiente do CGI que corresponde a varname. Para obter uma lista das variáveis do CGI, consulte SAPI.Request.servervariable.
cgilua.urlpath
O nome do script. Equivale à variável de ambiente do CGI SCRIPT_NAME.

Tratamento de erros

As funções de tratamento de erros do CGILua permitem a redefinição de como os erros são tratados e apresentados ao usuário. Elas consistem em:

cgilua.errorlog (string)
Envia a string dada para o arquivo de log de erros.
Não retorna nada.
cgilua.seterrorhandler (func)
Define a tratador de erros como func. Esta função é chamada pela Lua quando ocorre um erro. Ela recebe a mensagem de erro gerada pela Lua e é responsável por gerar e retornar o erro correto que deve ser usado pelo CGILua.
Não retorna nada.
cgilua.seterroroutput (func)
Define a função responsável pela apresentação de erros como func. Esta função é chamada pela Lua para gerar o resultado do erro.
Não retorna nada.

Comportamento do CGILua

O comportamento do CGILua pode ser configurado com o uso deste conjunto de funções:

cgilua.addclosefunction (func)
Define uma função (func) para ser chamada após a execução do CGILua.
Não retorna nada.
cgilua.addopenfunction (func)
Define uma função (func) para ser chamada antes da execução do CGILua.
Não retorna nada.
cgilua.addscripthandler (ext, func)
Define uma função (func) para pré-processar os arquivos com uma determinada extensão (ext). A configuração padrão usa cgilua.doscript para processar Lua Scripts (arquivos .lua) e cgilua.handlelp para processar Lua Pages (arquivos .lp).
Não retorna nada.
cgilua.buildplainhandler (type, subtype)
Cria um tratador de scripts que envia o cabeçalho fornecido e o arquivo sem formatação solicitado. O cabeçalho Content-type é formado pelos dois argumentos; a função criada recebe um nome de arquivo como único argumento e retorna o nome de arquivo dado sem alterações.
Retorna uma função.
cgilua.buildprocesshandler (type, subtype)
Cria um tratador de scripts que envia o cabeçalho fornecido e o arquivo processado solicitado. O cabeçalho Content-type é formado pelos dois argumentos; a função criada recebe um nome de arquivo como único argumento e retorna o nome de arquivo dado pré-processado pela função cgilua.lp.include.
Retorna uma função.
cgilua.setlibdir (dir)
Define o diretório de bibliotecas padrão do CGILua. Esse valor é usado para criar o LUA_PATH usado pela função require (require é redefinida pelo CGILua).
Não retorna nada.
cgilua.setmaxfilesize (size)
Define o tamanho máximo (em bytes) de cada arquivo cujo upload seja feito. Esse valor é limitado pelo tamanho máximo de entrada total (consulte cgilua.setmaxinput). Esta função só passa a vigorar se usada antes do processamento dos dados de POST, portanto, seu uso em scripts é irrelevante.
Não retorna nada.
cgilua.setmaxinput (size)
Define o tamanho de entrada total máxima permitido (em bytes). Esta função só passa a vigorar se usada antes do processamento dos dados de POST, portanto, seu uso em scripts é irrelevante.
Não retorna nada.

Funções de codificação de URL

As funções de codificação do CGILua permitem que o processamento de strings de URL seja feito de maneira simples:

cgilua.urlcode.encodetable (table)
Codifica em formato URL os elementos de uma tabela, criando uma string usada como URL para informar dados/parâmetros a outro script.
Retorna uma string representando a tabela de argumentos codificada.
cgilua.urlcode.escape (string)
Codifica em formato URL uma string.
Retorna a string codificada.
cgilua.urlcode.insertfield (args, name, value)
Adiciona o valor (value) fornecido ao campo indexado por um nome (nome) na tabela args. Se o campo já tiver um valor, será transformado em uma tabela com esse valor no índice 1 e o novo valor no índice 2. Outros valores serão acrescentados no final da parte array da tabela criada.
Não retorna nada.
cgilua.urlcode.parsequery (query, args)
Analisa os dados codificados em formato URL do pedido. Isso pode ser a parte query da URL do script ou dos dados POST codificados em URL. Cada par nome = valor codificado é inserido na tabela args.
Não retorna nada.
cgilua.urlcode.unescape (string)
Decodifica uma string que usa o formato URL.
Retorna a string decodificada.

Funções auxiliares

cgilua.doscript (filepath)
Executa um arquivo (dado por filepath). Gera um erro se ocorrer. Em caso de êxito, retorna os valores retornados pela execução.
cgilua.pack (...)
Retorna uma nova tabela que armazena todos os argumentos passados.
cgilua.splitpath (path)
Retorna duas strings com as partes "diretório" e "arquivo" do path fornecido.

Índice alfabético

addclosefunction
addopenfunction
addscripthandler
buildplainhandler
buildprocesshandler
contentheader
doscript
encodetable (urlcode)
errorlog
escape (urlcode)
header
htmlheader
include (lp)
insertfield (urlcode)
mkabsoluteurl
mkurlpath
pack
parsequery (urlcode)
handlelp
lp
put
redirect
script_file
script_path
script_pdir
script_vdir
script_vpath
servervariable
setcompatmode (lp)
seterrorhandler
seterroroutput
setlibdir
setmaxfilesize
setmaxinput
setoutfunc (lp)
splitpath
urlcode
unescape (urlcode)
urlpath

XHTML 1.0 válido!

$Id: reference.html,v 1.4 2005/11/03 18:48:57 carregal Exp $

lua-cgi-5.2~alpha2/doc/br/sapi.html000077500000000000000000000260371220116477200171760ustar00rootroot00000000000000 CGILua: geração de scripts para a Web usando Lua
CGILua
Geração de scripts para a Web usando Lua

API do servidor

A API do servidor (SAPI) é um conjunto de funções que abstrai o servidor Web e o disparador usado. Um disparador de SAPI é o mecanismo que permite a um servidor Web executar e comunicar-se com o CGILua e os aplicativos Web. A SAPI permite a abstração de uma série de detalhes internos, fazendo com que o CGILua seja muito mais portátil, já que transportar o CGILua para uma nova plataforma significa simplesmente escrever um disparador de SAPI para a plataforma de destino.

No momento, o CGILua oferece suporte a Apache, Microsoft IIS, Tomcat e Xavante como servidores Web, e a CGI, FastCGI, mod_lua, ISAPI e servlets como disparadores.

As funções são separadas em dois pacotes: SAPI.Request e SAPI.Response:

SAPI.Request.getpostdata ([n])
Obtém um bloco de dados de POST. O parâmetro opcional n é o número de bytes para ler (o tamanho de bloco padrão será usado se nenhum parâmetro for informado).
Retorna o bloco como uma string Lua.
SAPI.Request.servervariable (string)
Obtém o valor de uma variável de ambiente do servidor. O argumento pode ser uma das variáveis CGI definidas, embora nem todos os servidores implementem o conjunto completo de variáveis. O conjunto consiste em:
  • AUTH_TYPE - se o servidor suportar autenticação de usuário e o script estiver protegido, este é o método de autenticação específico ao protocolo usado para validar o usuário.
  • CONTENT_LENGTH - o tamanho do conteúdo como fornecido pelo cliente.
  • CONTENT_TYPE - para consultas que têm informações anexadas, por exemplo, HTTP POST e PUT, este é o tipo de conteúdo dos dados.
  • GATEWAY_INTERFACE - a revisão da especificação CGI com a qual esse servidor é compatível. Formato: CGI/revisão
  • PATH_INFO - informações adicionais sobre o caminho, conforme fornecidas pelo cliente. Em outras palavras, os scripts podem ser acessados por meio dos respectivos nomes de caminho virtual, seguidos de informações adicionais no final desse caminho. As informações adicionais são enviadas como PATH_INFO. Essas informações devem ser decodificadas pelo servidor se vierem de uma URL antes de serem passadas para o script CGI.
  • PATH_TRANSLATED - o servidor fornece uma versão convertida de PATH_INFO, que realiza quaisquer mapeamentos de virtual para físico no caminho.
  • QUERY_STRING - as informações inseridas após o "?" na URL que fez referência a esse script. Essas são as informações da consulta e não devem ser decodificadas. Esta variável deve ser sempre definida quando houver informações da consulta, qualquer que seja a decodificação da linha de comando.
  • REMOTE_ADDR - o endereço IP do host remoto que faz o pedido.
  • REMOTE_HOST - o nome do host que faz o pedido. Se o servidor não tiver essas informações, ele define REMOTE_ADDR e não define esta variável.
  • REMOTE_IDENT - se o servidor HTTP oferecer suporte à identificação RFC 931, esta variável será definida com o nome do usuário remoto recuperado do servidor. O uso desta variável deve ser limitado apenas à conexão.
  • REMOTE_USER - se o servidor oferecer suporte à autenticação de usuário e o script estiver protegido, este é o nome de usuário com o qual eles foram autenticados.
  • REQUEST_METHOD - o método com o qual o pedido foi feito. Para HTTP, isto equivale a "GET", "HEAD", "POST" etc.
  • SCRIPT_NAME - um caminho virtual para o script em execução, usado em URLs auto-referentes.
  • SERVER_NAME - o nome do host do servidor, o alias do DNS ou o endereço IP como exibido em URLs auto-referentes.
  • SERVER_PORT - o número da porta à qual o pedido foi enviado.
  • SERVER_PROTOCOL - o nome e a revisão do protocolo de informações com o qual este pedido foi enviado. Formato: protocolo/revisão
  • SERVER_SOFTWARE - o nome e a versão do software do servidor Web que responde ao pedido (e executa o gateway). Formato: nome/versão
Além desses, as linhas do cabeçalho recebidas do cliente, se houver, são colocadas no ambiente com o prefixo HTTP_ seguido do nome do cabeçalho. Quaisquer caracteres - (hífen) no nome do cabeçalho são alterados para caracteres _ (sublinhado). O servidor pode excluir quaisquer cabeçalhos que já tenha processado, por exemplo, Authorization, Content-type e Content-length. Se necessário, o servidor pode optar por excluir todos ou qualquer um desses cabeçalhos se a inclusão exceder algum limite do ambiente do sistema.
Retorna uma string.
SAPI.Response.contenttype (string)
Envia o cabeçalho Content-type para o cliente. A string fornecida está na forma "tipo/subtipo". Esta função deve ser chamada antes que qualquer saída seja enviada com o uso de SAPI.Response.write.
Não retorna nada.
SAPI.Response.errorlog (string)
Gera uma saída de erro usando a string fornecida.
Não retorna nada.
SAPI.Response.header (header, value)
Envia um cabeçalho genérico para o cliente. O primeiro argumento deve ser o nome do cabeçalho, por exemplo, "Set-Cookie". O segundo deve ser o valor. Esta função não deve ser usada em substituição às funções SAPI.Response.contenttype ou SAPI.Response.redirect.
Não retorna nada.
SAPI.Response.redirect (url)
Envia o cabeçalho Location para o cliente. A url fornecida deve ser uma string.
Não retorna nada.
SAPI.Response.write (string)
Gera uma saída usando a string fornecida.
Não retorna nada.

XHTML 1.0 válido!

$Id: sapi.html,v 1.3 2005/11/03 18:48:57 carregal Exp $

lua-cgi-5.2~alpha2/doc/us/000077500000000000000000000000001220116477200153655ustar00rootroot00000000000000lua-cgi-5.2~alpha2/doc/us/cgi-128.gif000077500000000000000000000105641220116477200171370ustar00rootroot00000000000000GIF87arvz}~ mmmssstttyyy|||  !!%%""%%)))),,55116611::::>>BBDDBBHHJJMMLLPPTTQQWWYYZZ^^\\``bbggiijjoollqqvvttyy{{~~‰ÊŎƐǒȕʙ˙̟ϡϢѥҩөԭֱױصڻݼ,# H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ˗0%2Is"j.3RO% @s "QJH@FQ0ᣤ P`O QECeܐ E$e !hsJ# 0 QSଁN'@@˗T᧥H9f$`rGTd!"},P>LPRʝDlB| 砃 O%)@PE " P#R$PNAE|| IN'qTaц!P#}q' %@mxP RD!EvGvutĈt ScNO 7&-fGˆ| _Q=Rd{=qQaqIpO $D4]|>(^FNq$lY6T@4bH!~bH#! 4! WЭ~8 c!C TAoTA 2!:ǘYFAk$N Eb&6ea @d:ntG$O:*4pw5˾ 1*x u /۠mQE$;P-2&sGaFpV !Qq<&ɰBf3 bXO!SaBҰEyU+50j8%82d?-D'pSw!'8#e%MOkG;{s2wQ7HBa 2!p-_=ę (1E`ۑ=>p*ha L <!KXFHv؞NE M;x ͼCq k'|2H8CZ0 |r$ G`_([|w%}-5$0 #^'`*e!.՝q5g$kx+/y[P :'$ Br H b ԉoHXo8 (@`@Dk3ZWՊgޝgAguD"11&9""6N(c%U@UF=ӥwڝz/\vPQ3lߩOwH?&F1' ^-*PqTDyO#և~WV=ඕCzfI-Aa%|gX4+}6Ucb QP@rG|XNYaAe/@)jX֧y]6'$lsynZ ?@uȁq FvA45 1Ѣ$TWG]uGEa2ubM =l4NueQ'(1W6u0z@rݓ1n"7}-I@{o6lP0O1'ԳS31PhSPQ(d "Ksڶm?Z4@"N\ 7AJ3["{OjPxh@4!N#`9vEz'g@!?* A@YPAfgsь eӥUP1]iPpdD ,(@jpT( oP ` TN&w&NwVd(rJ15Cb0)@~n K_"AF(VyX# `h VIM<#@1 &0@p0jt#q#&3) C) h2y3Њe }q3v`*ԘrsVpl@~ /XwEk7r8BW*!0i9sa΄lulv$ W( `atkVgH7pt ՝5F7&P(+aR\tBv=kPaiTdEb!PQb {P0"k?՝ZpXpr @\C;ZU@bp'Muix^EkeR# cǝycΉ-p3D:xMkNpQ, "i&1 _ ejq3: 3Tā'-qwgS5!;6#t@4qrAC7@, (:3W#P3W1F':<e&@P0x0`@P;i{PY8-+7W$ P|Q"nMg:drHMJKH֯A!N@7!h5nP r $AG0{LQ &@% k0gӪ, GM 1@1Ep@{bl;RmdJ"M>"G@( kSٵjl۶n;lua-cgi-5.2~alpha2/doc/us/index.html000077500000000000000000000331421220116477200173700ustar00rootroot00000000000000 CGILua: Building Web Scripts with Lua
CGILua
Building Web Scripts with Lua

Overview

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.

One of advantages of CGILua is its abstraction of the underlying Web server. CGILua can be used with a variety of Web servers and, for each server, with different launchers. A launcher is responsible for the interaction of CGILua and the Web server, for example using ISAPI on IIS or mod_lua on Apache. The reference implementation of CGILua launchers is Kepler.

CGILua is free software and uses the same license as Lua 5.1.

Status

Current version is 5.1.4

Download

CGILua source code can be downloaded from its LuaForge page

You can also install CGILua using LuaRocks:

luarocks install cgilua

History

Version 5.1.4 [22/Mar/2010]
  • Fixes file upload reentrancy
  • New launchers for cgilua that do not depend on kepler_init
  • Correction on mkurlpath
Version 5.1.3 [9/Mar/2009]
  • Strips utf-8 BOM from templates in lp.include
  • Fixed reentrancy bug
  • Fixed reset of cgilua.urlpath
Version 5.1.2 [19/May/2008]
  • Added the cgilua.authentication module
  • cgilua.print now separates arguments with tabs, like Lua print
  • Now print and write are aliases to cgilua.print and cgilua.put.
  • Now strips an eventual #! from top of Lua Pages files
  • CGILua can now process sequential requests in the same Lua state
  • Better error handling. Wraps error message in valid HTML
  • Bug fixed: CGILua was ignoring CGILUA_TMP in Windows
  • Corrected the URL handling for the dispatcher (bug found by Ronaldo Sugii)
  • Better URL handling for different locales
  • Handling multiple values in the generated URL (patch by Matt Campbell)
  • Fixed file handle leak in loader.lua
  • Fixed bug [#2630] - Including new files (bug found by Bruno Massa)
Version 5.1.1 [21/Nov/2007]
  • Changed the security policy for scripts. Now scripts have access to all Lua globals, including the debug and os packages. It is up to the application developer to choose what policy to use
  • If you are using Kepler, it is strongly suggested that you replace your previous CGILua config.lua file with the new one installed by Kepler and then merge the differences
  • Added the cgilua.dispatcher module
  • Added default handlers for a set of MIME types. The default handlers return only the content-type and conten-lenght headers for the files.
  • Added functions cgilua.splitonfirst and cgilua.splitonlast
  • Added functions cgilua.tmpfile and cgilua.tmpname
  • Changed the use of "/test" for the session temporary directory checking (bug found by Yuri Takhteyev)
  • Corrected the use of cgilua.QUERY in the session handling (bug found by Jim Madsen)
  • Better handling of "application/xml" POST content types (patch by Ignacio Burgueño)
  • Fixed Bug [#1910] - Bug in byte accounting in post.lua (found by Greg Bell)
Version 5.1.0 [23/Aug/2007]
  • Uses Lua 5.1
  • Added function cgilua.print (that uses tostring on its parameters)
  • Added a generic dispatcher and the concept of CGILua Apps
  • Replaced the cgi table used until CGILua 5.0 by two others cgilua.QUERY and cgilua.POST)
  • Added fake "package" table to enable the user/programmer to create modules with global visibility
  • Bug fix: return of HTTP status code
  • Bug fix: close method was recreating the session file
  • Correcting how LP handles strings with CR characters (Lua 5.0 would not mind, but Lua 5.1 does)
  • Fixed a bug with lighttpd
Version 5.0.1 [20/Sep/2006]
  • Uses Compat-5.1 Release 5.
  • Caches Lua Pages template strings.
  • New configuration examples.
  • Improvements in the Session library.
  • Removed the debug package from the user scripts environment.
  • POST handling bug fixes (related to the text/plain content type).
Version 5.0 [23/Jul/2005]
  • CGILua distribution includes now only the Lua files, the launchers have been moved to Kepler.
  • The Stable library is now distributed with VEnv.
  • Fixed a file upload bug in the CGI and Xavante launchers.
  • cgilua.lp.include() now accepts an environment to run the preprocessed file in it.
Version 5.0 beta 2 [23/Dec/2004]
  • Distribution bug fix: stable.lua was missing
Version 5.0 beta [15/Dec/2004]
  • New ISAPI and Servlet Launchers.
  • New Error Handling features.
  • New persistent data feature (Stable).
  • Uses the package model for Lua 5.1.
  • Simpler User Session API.
  • Small bug corrections
Version 5.0 alpha 3 [8/Jun/2004]
Version 5.0 alpha [21/Apr/2004]

Incompatibility with previous CGILua versions (5.0, 4.0 and 3.x)

  • CGILua 5.1 uses Lua 5.1.
  • The cgi table is now deprecated. See Receiving parameters for a more detailed explanation.
  • The template tags have changed. See Lua pages for a more detailed explanation.
  • The use of getenv calls to obtain CGI variables should be replaced by cgilua.servervariable calls.

Credits

CGILua 5.1
CGILua 5.1 is being maintained by André Carregal and Tomás Guisasola with contributions from Fábio Mascarenhas and others from the Kepler mailing list.
CGILua 5.0
CGILua 5.0 was completely redesigned by Roberto Ierusalimschy, André Carregal and Tomás Guisasola as part of the Kepler Project. The implementation is compatible with Lua 5.0 and was coded by Tomás Guisasola with invaluable contributions by Ana Lúcia de Moura, Fábio Mascarenhas and Danilo Tuler. CGILua 5.0 development was sponsored by Fábrica Digital, FINEP and CNPq.
CGILua 4.0
Ana Lúcia de Moura adapted CGILua 3.2 to Lua 4.0, reimplemented some code and added a few improvements but this version was not officially distributed.
CGILua 3.x
CGILua was born as the evolution of an early system developed by Renato Ferreira Borges and André Clínio at TeCGraf. At the time (circa 1995) there were no CGI tools available and everything was done with shell scripts!
However, the main contribution to CGILua 3 was done by Anna Hester, who consolidated the whole tool and developed a consistent distribution with versions 3.1 and 3.2 (the number was an effort to follow Lua version numbers). This version was widely used on a great variety of systems.

Contact us

For more information please contact us. Comments are welcome!

You can also reach other CGILua developers and users on the Kepler Project mailing list.

Valid XHTML 1.0!

$Id: index.html,v 1.68 2009/03/09 23:37:18 carregal Exp $

lua-cgi-5.2~alpha2/doc/us/libraries.html000077500000000000000000000271371220116477200202440ustar00rootroot00000000000000 CGILua: Building Web Scripts with Lua
CGILua
Building Web Scripts with Lua

Overview

CGILua includes a set of external libraries that allows the handling of authentication, cookies, dispatching, serialized data and sessions. To use these libraries just require them in your CGILua config.lua or script file.

Authentication

cgilua.authentication.check (username, passwd)
Checks if the pair username/passwd is authenticated by the configured method.
Returns true if succesfull or nil plus an error message if not.
cgilua.authentication.checkURL ()
Returns the URL for the checking script. The checking script receives the current URL as the ref parameter. It is up to the checking script to ask for user credentials, check if the user has the expected credentials (using cgilua.authentication.check (username, passwd) if implementing the checking script using CGILua), and redirect to the original URL (using the ref parameter or cgilua.authentication.refURL() if implementing the checking script using CGILua).
cgilua.authentication.configure (options, methods)
Configures the authentication framework (see /examples/authentication_conf.lua in CVS for more information).
cgilua.authentication.logoutURL ()
Returns the URL for the logout script.
cgilua.authentication.refURL ()
Returns the URL for the page that orignally required authentication. Used in checking scripts that use CGILua. Other checking scripts can use the ref parameter.
cgilua.authentication.username ()
Returns the authenticated user or nil if no user is currently authenticated.

Cookies

cgilua.cookies.get (name)
Gets the value of the cookie with the given name.
Returns a string with the value of the cookie.
cgilua.cookies.set (name, value[, options])
Sets the value of the cookie with a given name. The optional table options is used togive the values of the cookies attributes: expires, path, domain, secure. This function should be called before the HTTP headers are sent and before any output is generated, so it must not be used inside a Lua Page.
This function sends a cookie with the response. If you need to create a cookie inside the generated response or if the cookie needs to be set inside the client, use cgilua.cookies.sethtml instead.
Returns nothing.
cgilua.cookies.sethtml (name, value[, options])
Sets the value of the cookie with a given name. The optional table options is used to give the values of the cookies attributes: expires, path, domain, secure.
This function generates a <meta> HTML element so it should be called after the <head> HTML tag and before the corresponding </head>.
This function creates a cookie in the client, if you need to send the cookie with the response use cgilua.cookies.set instead.
Returns nothing.
cgilua.cookies.delete (name[, options])
Deletes a cookie with a given name (setting its value to xxx). This function should be called before the HTTP headers are sent and before any output is generated.
Returns nothing.

Dispatcher

cgilua.dispatch.route (urlmaps)
Defines the routing using a table of URLs maps or a single map. A map defines a URL mask using $name patterns to extract parameters, a function to be called with the extracted parameters and a name for the map when used with cgilua.dispatch.route_url.
cgilua.dispatch.route_url (mapname, parameters, query)
Returns an URL for a named route map. mapname defines the name associated with the map in the original routed URL table sent to cgilua.dispatch.route. params defines a table of named parameters used to fill the URL pattern. query defines an optional table of named parameters used for the QUERY part of the URL.

Serialize

cgilua.serialize (table, outfunc[, indent[, prefix]])
Serializes a table using outfunc as the function to be used to generate the output; indent as an optional string with the indentation pattern; prefix as an optional string with the indentation prefix (it is used to store the actual indentation between the recursion calls).
Some restrictions must be noted: values of types function and userdata are not serialized; tables with cycles are not serialized.
Returns nothing.

Session

cgilua.session.close ()
Closes the user session. Saves all data in cgilua.session.data to the storage system being used (usually the filesystem). This function should be called after the end of the script execution. A recommended way to ensure that is to use addclosefunction in the configuration file.
Returns nothing.
cgilua.session.data
Table which holds the user session data.
cgilua.session.delete (id)
Deletes a session. The argument id is the session identifier.
Returns nothing.
cgilua.session.destroy ()
Destroys the current session.
Returns nothing.
cgilua.session.load (id)
Loads data from a session. The argument id is the session identifier.
Returns a table with session data or nil followed by an error message.
cgilua.session.new ()
Creates a new session identifier.
Returns the new session identifier.
cgilua.session.open ()
Opens the user session. Creates the table cgilua.session.data. This function should be called just before the execution of the script, but after the processing of the request's headers. A recommended way to ensure that is to use addopenfunction in the configuration file.
Returns nothing.
cgilua.session.save (id, data)
Saves data to a session with an id.
Returns nothing.
cgilua.session.setsessiondir (path)
Defines the session temporary directory. Argument path is a string with the new directory.
Returns nothing.

Valid XHTML 1.0!

$Id: libraries.html,v 1.34 2007/12/05 19:41:13 carregal Exp $

lua-cgi-5.2~alpha2/doc/us/license.html000077500000000000000000000127701220116477200177070ustar00rootroot00000000000000 CGILua: Building Web Scripts with Lua
CGILua
Building Web Scripts with Lua

License

CGILua is free software: it can be used for both academic and commercial purposes at absolutely no cost. There are no royalties or GNU-like "copyleft" restrictions. CGILua qualifies as Open Source software. Its licenses are compatible with GPL. CGILua is not in the public domain and the Kepler Project keep its copyright. The legal details are below.

The spirit of the license is that you are free to use CGILua for any purpose at no cost without having to ask us. The only requirement is that if you do use CGILua, then you should give us credit by including the appropriate copyright notice somewhere in your product or its documentation.

The CGILua library is designed and implemented by Roberto Ierusalimschy, André Carregal and Tomás Guisasola. The implementation is not derived from licensed software.


Copyright © 2003 Kepler Project.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 

 

 

 

 

 

 

Valid XHTML 1.0!

$Id: license.html,v 1.23 2008/05/19 18:13:36 carregal Exp $

lua-cgi-5.2~alpha2/doc/us/manual.html000077500000000000000000000677551220116477200175570ustar00rootroot00000000000000 CGILua: Building Web Scripts with Lua
CGILua
Building Web Scripts with Lua

Introduction

CGILua uses Lua as a server-side scripting language for creating dynamic Web pages. Both pure Lua Scripts and Lua Pages (LP) are supported by CGILua. A Lua Script is essentially a Lua program that creates the whole contents of a web page and returns it to the client. A Lua Page is a conventional markup text (HTML, XML etc) file that embeds Lua code using some special tags. Those tags are processed by CGILua and resulting page is returned to the client.

Lua Scripts and Lua Pages are equally easy to use, and choosing one of them basically depends on the characteristics of the resulting page. While Lua Pages are more convenient for the separation of logic and format, Lua Scripts are more adequate for creating pages that are simpler in terms of its structure, but require a more significative amount of internal processing.

Allowing these two methods to be intermixed, CGILua provides Web applications developers with great flexibility when both requirements are present. For a detailed description of both scripting methods and some examples of their use see Lua Scripts and Lua Pages.

Architecture

CGILua architecture is divided in two layers. The lower level is represented by the Server API (SAPI) and the higher level is represented by the CGILua API itself. SAPI is the interface between the web server and the CGILua API, so it needs to be implemented for each Web server and launching method used.

A launcher is responsible for the interaction of CGILua and the Web server, implementing SAPI for example using ISAPI on IIS or mod_lua on Apache. The reference implementation of CGILua launchers is Kepler.

The CGILua API is implemented using only SAPI and is totally portable over different launchers and their supporting Web servers. This way any Lua Script or Lua Page can be used by any launcher.

Request life cycle

CGILua processes requests using a CGI metaphor (even if the launcher is not based on CGI) and requests have a life cycle that can be customized by the programmer. The CGILua request life cycle consists in the following sequence of steps for each request:

  1. Add default handlers such as LuaScripts and Lua Pages and commom file formats.
  2. Execute the config.lua file, allowing the customization of the next steps.
  3. Build the cgilua.POST and cgilua.QUERY tables (processing POST and QUERY data).
  4. Change to user script directory.
  5. Execute the registered open functions.
  6. Execute the requested script with the correct environment.
  7. Execute the registered close functions.
  8. Change back to the original directory

Editing the config.lua file one can customize the CGILua behaviour. One typical use would be registering the open and close functions in order to change the request processing behavior. With this customization it is possible to implement new features like session management and private library directories as shown in section Configuration, or even to implement new abstractions over the whole CGILua way of live, like MVC-frameworks such as Orbit.

Installation

CGILua follows the package model for Lua 5.1, therefore it should be "installed" in your package.path.

You can also install CGILua using LuaRocks:

luarocks install cgilua

Configuration

The Kepler distribution of CGILua 5.1 offers a single configuration file, called config.lua. This file can be used to alter the default CGILua behaviour and is located in the Kepler configuration directory.

Some of the uses of config.lua customization are:

Script Handlers
A handler is responsible for the response of a request. You can add new CGILua handlers using cgilua.addscripthandler (see also cgilua.buildplainhandler and cgilua.buildprocesshandler for functions that build simple handlers).
POST Data Sizes
You can change the POST data size limits using cgilua.setmaxinput and cgilua.setmaxfilesize.
Opening and Closing Functions
You can add your functions to the life cycle of CGILua using cgilua.addopenfunction and cgilua.addclosefunction. These functions are executed just before and just after the script execution, even when an error occurs in the script processing.

In particular, the opening and closing functions are useful for different things. Some examples of the use of such functions in config.lua are shown next.

Previous versions of CGILua loaded a env.lua file from the script directory before processing it. To emulate this with CGILua 5.1 you can use something like:

cgilua.addopenfunction (function ()
	cgilua.doif ("env.lua")
end)

If every script needs to load a module (such as the sessions library), you can do:

require"cgilua.session"
cgilua.session.setsessiondir(CGILUA_TMP)
cgilua.addopenfunction (cgilua.session.open)
cgilua.addclosefunction (cgilua.session.close)

Note that the function cgilua.addopenfunction must be used to call cgilua.session.open because this function needs to change the cgi table (see section Receiving parameters for more information on this special table) which is not yet available during the execution of the config.lua file (see the Request life cycle).

When some scripts may use the library but others may not, you could define an "enabling" function (which should be called at the very beginning of each script that needs to use sessions):

require"cgilua.session"
cgilua.session.setsessiondir(CGILUA_TMP)
cgilua.enablesession = function ()
	cgilua.session.open ()
	cgilua.addclosefunction (cgilua.session.close)
end

Sometimes you need to configure a private libraries directory for each application hosted in the server. This configuration allows the function require to find packages installed in the private directory and in the system directory but not in other application's private directory. To implement this you could do:

local app_lib_dir = {
	["/virtual/path/"] = "/absolute/path/lib/",
}
local package = package
cgilua.addopenfunction (function ()
	local app = app_lib_dir[cgilua.script_vdir]
	if app then
		package.path = app..'/?.lua'..';'..package.path
	end
end)

Lua Scripts

Lua Scripts are text files containing valid Lua code. This style of usage adopts a more "raw" form of web programming, where a program is responsible for the entire generation of the resulting page. Lua Scripts have a default .lua extension.

To generate a valid web document (HTML, XML, WML, CSS etc) the Lua Script must follow the expected HTTP order to produce its output, first sending the correct headers and then sending the actual document contents.

CGILua offers some functions to ease these tasks, such as cgilua.htmlheader to produce the header for a HTML document and cgilua.put to send the document contents (or part of it).

For example, a HTML document which displays the sentence "Hello World!" can be generated with the following Lua Script:

cgilua.htmlheader()
cgilua.put([[
<html>
<head>
  <title>Hello World</title>
</head>
<body>
  <strong>Hello World!</strong>
</body>
</html>]])

It should be noted that the above example generates a "fixed" page: even though the page is generated at execution time there is no "variable" information. That means that the very same document could be generated directly with a simple static HTML file. However, Lua Scripts become especially useful when the document contains information which is not known beforehand or changes according to passed parameters, and it is necessary to generate a "dynamic" page.

Another easy example can be shown, this time using a Lua control structure, variables, and the concatenation operator:

cgilua.htmlheader()  

if cgilua.QUERY.language == 'english' then
  greeting = 'Hello World!'
elseif cgilua.QUERY.language == 'portuguese' then
  greeting = 'Olá Mundo!'
else
  greeting = '[unknown language]'
end

cgilua.put('<html>')  
cgilua.put('<head>')
cgilua.put('  <title>'..greeting..'</title>')
cgilua.put('</head>')
cgilua.put('<body>')
cgilua.put('  <strong>'..greeting..'</strong>')
cgilua.put('</body>')
cgilua.put('</html>')

In the above example the use of cgilua.QUERY.language indicates that language was passed to the Lua Script as a CGILua parameter, coming from the URL used to activate it (via GET). If you were using a form, the parameter would be available in cgilua.POST.language. CGILua automatically decodes such QUERY and POST parameters so you can use them at will on your Lua Scripts and Lua Pages.

Lua Pages

A Lua Page is a text template file which will be processed by CGILua before the HTTP server sends it to the client. CGILua does not process the text itself but look for some special markups that include Lua code into the file. After all those markups are processed and merged with the template file, the results are sent to the client.

Lua Pages have a default .lp extension. They are a simpler way to make a dynamic page because there is no need to send the HTTP headers. Usually Lua Pages are HTML pages so CGILua sends the HTML header automatically.

Since there are some restrictions on the uses of HTTP headers sometimes a Lua Script will have to be used instead of a Lua Page.

The fundamental Lua Page markups are:

<?lua chunk ?>
Processes and merges the Lua chunk execution results where the markup is located in the template. The alternative form <% chunk %> can also be used.
<?lua= expression ?>
Processes and merges the Lua expression evaluation where the markup is located in the template. The alternative form <%= expression %> can also be used.

Note that the ending mark could not appear inside a Lua chunk or Lua expression even inside quotes. The Lua Pages pre-processor just makes global substitutions on the template, searching for a matching pair of markups and generating the corresponding Lua code to achieve the same result as the equivalent Lua Script.

The second example on the previous section could be written using a Lua Page like:

<html>
<?lua
if cgilua.QUERY.language == 'english' then
  greeting = 'Hello World!'
elseif cgilua.QUERY.language == 'portuguese' then
  greeting = 'Olá Mundo!'
else
  greeting = '[unknown language]'
end
?>
<head>
  <title><%= greeting %></title>
</head>
<body>
  <strong><%= greeting %></strong>
</body>
</html>

HTML tags and Lua Page tags can be freely intermixed. However, as on other template languages, it's considered a best practice to not use explicit Lua logic on templates. The recommended aproach is to use only function calls that returns content chunks, so in this example, assuming that function getGreeting was definied in file functions.lua as follows:

function getGreeting()
  local greeting
  if cgilua.QUERY.language == 'english' then
    greeting = 'Hello World!'
  elseif cgilua.QUERY.language == 'portuguese' then
    greeting = 'Olá Mundo!'
  else
    greeting = '[unknown language]'
  end
  return greeting
end

the Lua Page could be rewriten as:

<?lua
assert (loadfile"functions.lua")()
?>
<html>
<head>
  <title><%= getGreeting() %></title>
</head>
<body>
  <strong><%= getGreeting() %></strong>
</body>
</html>

Another interesting feature of Lua Pages is the intermixing of Lua and HTML. It is very usual to have a list of values in a table, iterate over the list and show the items on the page.

A Lua Script could do that using a loop like:

cgilua.put("<ul>")
for i, item in ipairs(list) do
    cgilua.put("<li>"..item.."</li>")
end
cgilua.put("</ul>")

The equivalent loop in Lua Page would be:

<ul>
    <% for i, item in ipairs(list) do %>
    <li><%= item %></li>
    <% end %>
</ul>

Receiving parameters: the QUERY and POST tables

CGILua offers both types of request parameters (QUERY strings and POST data) in the cgilua.QUERY and cgilua.POST tables.

Usually all types of parameters will be available as strings. If the value of a parameter is a number, it will be converted to its string representation.

There are only two exceptions where the value will be a Lua table. The first case occurs on file uploads, where the corresponding table will have the following fields:

filename
the file name as given by the client.
filesize
the file size in bytes.
file
the temporary file handle. The file must be copied because CGILua will remove it after the script ends.

The other case that uses Lua tables occurs when there is more than one value associated with the same parameter name. This happens in the case of a selection list with multiple values; but it also occurs when the form (of the referrer) had two or more elements with the same name attribute (maybe because one was on a form and another was in the query string). All values will be inserted in an indexed table in the order in which they are handled.

Dispatching

If you want to use more sophisticated URLs, the Kepler distribution includes a dispatching script called app.lua that can be used to handle URLs in the format .../app.lua/app_name/path_info in a standard way. URLs in this format are said to refer to CGILua spplications, which consists in a standard loading sequence for web applications using CGILua and app.lua as their dispatcher:

  • there is an app_name as the start of path_info
  • there is an init.lua file in CGILUA_APPS/app_name
  • changes the current directory to CGILUA_APPS/app_name
  • sets cgilua.app_name to app_name
  • adds CGILUA_APPS/app_name/lua to the start of package.path
  • executes init.lua

CGILua applications usually need to dispatch their actions using the remaining path_info and for that they can use cgilua.dispatcher as a helper library. The example below uses it to dispatch URLs that follow a convention similar to Rails. Let's assume that this is a init.lua file in the CGILUA_APPS/blog directory:

require"cgilua.dispatcher"
return cgilua.dispatcher.route{"/$controller/$action/$ID", handle, "rails"}

In this example URLs like .../app.lua/blog/post/edit/2 would result in the function handle being called as

handle({controller="post", action="edit", ID="2"})

the handle function would then decide how to proceed depending on the parameters received and generate the corresponding response using CGILua functions or a template engine like Lua Pages or Cosmo.

Note that this example does not include error handling for invalid URLs or default values.

Authentication

CGILua offers a simple but useful authentication mechanism that can be shared by different CGILua applications or even applications developed in other platforms. The authentication mechanism is based on HTTP redirections and assumes three different participants.

The first one is the controller script, which is responsible for centralizing the user authentication control and deciding if the application should continue depending on a user being logged in or not. An example of such controller would be the app.lua dispatcher script distributed with Kepler. As most of the controllers would do, it checks for the presence of an authenticated user and redirects to the checking script when that fails:

-- checks for authenticated users
if not cgilua.authentication.username() then
    cgilua.redirect(cgilua.authentication.checkURL())
else
    -- continues with the application flow
end

If your application is not handled by a single script like one using app.lua then you would need to repeat this check in every script that requires authenticated users.

The second participant in the authentication mechanism is the checking script. This script should ask for user credentials, check them using the adequate method and redirect back to the original URL if the user was succesfully authenticated.

One simple example of such a checking script is the one found in /examples/check.lua in CGILua CVS, but usually a checking script implemented in CGILua would do the following:

-- Checking script example
-- Assumes that the login form will use two fields called username and pass

local username = cgilua.POST.username
local pass = cgilua.POST.pass
local logged, err, logoutURL

if cgilua.authentication then
    logged, err = cgilua.authentication.check(username, pass)
    username = cgilua.authentication.username() or ""
    logoutURL = cgilua.authentication.logoutURL()
else
    logged = false
    err = "No authentication configured!"
    username = ""
end

if logged and username then
    -- goes back to the application
	cgilua.redirect(cgilua.authentication.refURL())
else
    err = err or ""
    -- displays the login form which submits to this same script
	cgilua.htmlheader()
	cgilua.lp.include ("login.lp", {
        logged = logged, errorMsg = err, username = username,
        cgilua = cgilua, logoutURL = logoutURL})
end

The login form for this example can be fount at /examples/login.lp in CGILua CVS and consists of:

<% if logged then %>
<p>User <%= username %> logged in</p>
<a href="<%= logoutURL %>">Logout</a>
<% else %>
<p style="color:#ff0000"><%= errorMsg %> </p>
<form method="post" action="" >
    User name: <input name="username" maxlength="20" size="20" value="<%= username %>" ><br />
    Password: <input name="pass" type="password" maxlength="20" size="20"><br />
    <input type="submit" value="Login">
    <input type="reset" value="Reset">
</form>
<% end %>

Finally the third participant in the authentication process is the configuration file. This file is used to set the authentication method and other details. Each method has it's set of parameters and defines a check callback used by CGILua during the authentication process. See /examples/authentication_conf.lua for configuration examples using database, LDAP and Web server authentication methods.

Error Handling

There are three functions for error handling in CGILua:

The function cgilua.seterrorhandler defines the error handler, a function called by Lua when an error has just occurred. The error handler has access to the execution stack before the error is thrown so it can build an error message using stack information. Lua also provides a function to do that: debug.traceback.

The function cgilua.seterroroutput defines the function that decides what to do with the error message. It could be sent to the client's browser, written to a log file or sent to an e-mail address (with the help of LuaSocket or LuaLogging for example).

The function cgilua.errorlog is provided to write directly to the http server error log file.

An useful example of its use could be handling unexpected errors. Customizing unexpected error messages to the end user but giving all the information to the application's developers is the goal of the following piece of code:

local ip = cgilua.servervariable"REMOTE_ADDR"
local developers_machines = {
	["192.168.0.20"] = true,
	["192.168.0.27"] = true,
	["192.168.0.30"] = true,
}
local function mail (s)
	require"cgilua.serialize"
	require"socket.smtp"
	-- Build the message
	local msg = {}
	table.insert (msg, tostring(s))
	-- Tries to obtain the REFERER URL
	table.insert (msg, tostring (cgilua.servervariable"HTTP_REFERER"))
	table.insert (msg, cgilua.servervariable"SERVER_NAME"..
		cgilua.servervariable"SCRIPT_NAME")
	-- CGI parameters
	table.insert (msg, "CGI")
	cgilua.serialize(cgi, function (s) table.insert (msg, s) end)
	table.insert (msg, tostring (os.date()))
	table.insert (msg, tostring (ip))
	table.insert (msg, "Cookies:")
	table.insert (msg, tostring (cgilua.servervariable"HTTP_COOKIE" or "no cookies"))
	-- Formats message according to LuaSocket-2.0b3
	local source = socket.smtp.message {
		headers = { subject = "Script Error", },
		body = table.concat (msg, '\n'),
	}
	-- Sends the message
	local r, e = socket.smtp.send {
		from = "sender@my.domain.net",
		rcpt = "developers@my.domain.net",
		source = source,
	}
end
if developers_machines[ip] then
	-- Developer's error treatment: write to the display
	cgilua.seterroroutput (function (msg)
		cgilua.errorlog (msg)
		cgilua.errorlog (cgilua.servervariable"REMOTE_ADDR")
		cgilua.errorlog (os.date())
		cgilua.htmlheader ()
		msg = string.gsub (string.gsub (msg, "\n", "<br>\n"), "\t", "  ")
		cgilua.put (msg)
	end)
else
	-- User's error treatment: shows a standard page and sends an e-mail to
	-- the developer
	cgilua.seterroroutput (function (s)
		cgilua.htmlheader ()
		cgilua.put"<h1>An error occurred</h1>\n"
		cgilua.put"The responsible is being informed."
		mail (s)
	end)
end

The message is written to the browser if the request comes from one of the developer's machines. If it is not the case, a simple polite message is given to the user and a message is sent to the developer's e-mail account containing all possible information to help reproduce the situation.

Valid XHTML 1.0!

$Id: manual.html,v 1.27 2008/05/19 18:13:36 carregal Exp $

lua-cgi-5.2~alpha2/doc/us/reference.html000077500000000000000000000521211220116477200202150ustar00rootroot00000000000000 CGILua: Building Web Scripts with Lua
CGILua
Building Web Scripts with Lua

Headers

Headers functions are used to change the HTTP response headers and consist of:

cgilua.contentheader (type, subtype)
Sends a Content-type header with the given values of type and sub-type.
Both arguments are strings: type is the header type; subtype is the header sub-type.
Returns nothing.
cgilua.header (header, value)
Sends a generic header. This function should not be used to generate a Content-type nor a Location header because some launchers/web-servers use different functions for this purpose.
Both arguments are strings: header is the name of the header; value is its value.
Returns nothing.
cgilua.htmlheader ()
Sends the header of an HTML file (Content-type: text/html).
Returns nothing.
cgilua.redirect (url, args)
Sends the header to force a redirection to the given URL adding the parameters in table args to the new URL.
The first argument (url) is the URL the browser should be redirected to; the second one (args) is an optional table which could have pairs name = value that will be encoded to form a valid URL (see function cgilua.urlcode.encodetable).
Returns nothing.

Content Generation

Content generation functions are used to output text to the response and to generate URLs in the CGILua format. They consist of:

cgilua.mkabsoluteurl (path)
Creates an absolute URL containing the given URL path.
Returns the resulting absolute URL.
cgilua.mkurlpath (script [, args])
Creates an URL path to be used as a link to a CGILua script using the optional table of arguments (args). The arguments are used in the URL as query string parameters.
Returns the resulting URL.
cgilua.print (...)
Sends the given arguments to the client. This function converts all its arguments to strings before sending them to the server thus it does not raises errors like cgilua.put.
Returns nothing.
cgilua.put (...)
Sends the given arguments to the client. This function should always be used; do not use Lua's print or io.write for output otherwise your script may not work for every launching method.
Returns nothing.

Lua Pages

Lua Pages functions are used to process Lua Pages templates and to define the behavior of this processing. They consist of:

cgilua.handlelp (filename[, env])
Equivalent to cgilua.lp.include but sends the HTML header before the pre-processed file.
Returns nothing.
cgilua.lp.compile (string)
Compile a piece of code given as a string into a Lua function. The string is translated with cgilua.lp.translate into another string which is transformed into a function with loadstring. The resulting function is cached internaly and reused if the same piece of code is given.
Returns a function.
cgilua.lp.include (filename[, env])
Pre-processes a Lua Page template (given by filename) and sends the results to the client. The file content is processed by cgilua.lp.compile and no headers are sent. If an optional environment table is passed, the file is executed with this environment instead of the global one. This can be used to sandbox your scripts.
Returns nothing.
cgilua.lp.setcompatmode (boolean)
Turns on or off the compatibility mode. Turning it on will make the Lua Pages preprocessor understand the expression fields and code fields structures used by previous versions of CGILua.
Default value: true
Returns nothing.
cgilua.lp.setoutfunc (funcname)
Defines the name of the output function for templates. The Lua Pages preprocessor will generate calls to the function with the given funcname (a string).
Returns nothing.
cgilua.lp.translate (string)
Uses the Lua Pages preprocessor to generate a string corresponding to the Lua code that executes the Lua chunks and/or expressions inside the given string.
Returns a string with the resulting Lua code.

CGILua Variables

CGILua Variables offers information about the script being processed and the CGI environment variables depending on the Web server and launcher used. They consist of both atributes and functions:

cgilua.script_file
The file name of the running script. Obtained from cgilua.script_path.
cgilua.script_path
The complete path of the running script. This variable is usually the same as the CGI environment variable PATH_TRANSLATED.
cgilua.script_pdir
The directory of the running script. Obtained from cgilua.script_path.
cgilua.script_vdir
The virtual directory of the running script. Obtained from cgilua.script_vpath.
cgilua.script_vpath
The complete virtual path of the running script. Equivalent to the CGI environment variable PATH_INFO.
cgilua.servervariable (varname)
Returns a string with the value of the CGI environment variable correspoding to varname. For a list of CGI variables please refer to SAPI.Request.servervariable
cgilua.tmp_path
The directory used by cgilua.tmpfile. Obtained by checking os.getenv("TEMP"), os.getenv ("TMP") and "/tmp" in that order.
cgilua.urlpath
The name of the script. Equivalent to the CGI environment variable SCRIPT_NAME.

Error Handling

CGILua error handling functions allow the redefinition of how errors are handled and presented to the user. The consist of:

cgilua.errorlog (string)
Sends the given string to the error log file.
Returns nothing.
cgilua.seterrorhandler (func)
Sets the error handler function to func. This function is called by Lua when an error occurs. It receives the error message generated by Lua and it is responsible for generating and returning the correct error message to be used by CGILua.
Returns nothing.
cgilua.seterroroutput (func)
Sets the error output function to func. This function is called by Lua to generate the error output itself.
Returns nothing.

CGILua behavior

The behavior of CGILua can be configured using this set of functions:

cgilua.addclosefunction (func)
Defines a function (func) to be called after the execution of the script requested.
Returns nothing.
cgilua.addopenfunction (func)
Defines a function (func) to be called before the execution of the script requested.
Returns nothing.
cgilua.addscripthandler (ext, func)
Defines a function (func) to pre-process files with a certain extension (ext). The default configuration uses cgilua.doscript to process Lua Scripts (.lua files) and cgilua.handlelp to process Lua Pages (.lp files).
Returns nothing.
cgilua.buildplainhandler (type, subtype)
Creates a script handler that sends the given header and the plain file requested. The Content-type header is formed by the two arguments; the created function will receive a filename as its only argument and will return the given filename untouched.
Returns a function.
cgilua.buildprocesshandler (type, subtype)
Creates a script handler that sends the given header and the processed file requested. The Content-type header is formed by the two arguments; the created function will receive a filename as its only argument and will return the given filename pre-processed by the function cgilua.lp.include.
Returns a function.
cgilua.setmaxfilesize (size)
Sets the maximum size (in bytes) for each uploaded file. This value is bounded by the maximum total input size (see cgilua.setmaxinput). This function only takes effect if used before POST data is processed, therefore its use in scripts are meaningless.
Returns nothing.
cgilua.setmaxinput (size)
Sets the maximum total input size allowed (in bytes). This function only takes efect if used before POST data is processed, therefore its use in scripts are meaningless.
Returns nothing.

URL encoding functions

CGILua enconding functions allow the processing of URL strings in a simple way:

cgilua.urlcode.encodetable (table)
URL-encode the elements of a table creating a string to be used as a URL for passing data/parameters to another script.
Returns a string representing the encoded argument table.
cgilua.urlcode.escape (string)
URL-encode a string.
Returns the encoded string.
cgilua.urlcode.insertfield (args, name, value)
Adds the given value to the field indexed by name in the args table. If the field already has a value, it is transformed into a table with this value at index 1 and the new value at index 2. Other values will be added at the end of the array-part of the created table.
Returns nothing.
cgilua.urlcode.parsequery (query, args)
Parse URL-encoded request data. This could be the query part of the script URL or URL-encoded POST data. Each decoded name = value pair is inserted into the args table.
Returns nothing.
cgilua.urlcode.unescape (string)
URL-decodes a string.
Returns the decoded string.

Auxiliar functions

cgilua.doif (filepath)
Executes a file (given by filepath) if it exists. Returns the values returned by the execution, or nil followed by an error message if the file does not exists.
cgilua.doscript (filepath)
Executes a file (given by filepath). Raises an error if it occurs. In case of success, returns the values returned by the execution.
cgilua.pack (...)
Returns a new table with all the passed arguments stored in it.
cgilua.splitfirst (path)
Returns two strings with the "first directory" and the "remaining paht" of the given path string splitted on the first separator ("/" or "\").
cgilua.splitonlast (path)
Returns two strings with the "directory path" and "file" parts of the given path string splitted on the last separator ("/" or "\"). This function used to be called cgilua.splitpath and still can be accessed by this name for compatibility reasons. cgilua.splitpath may be deprecated in future versions.
cgilua.tmpfile (dir[, namefunction])
Returns a temporary file in the cgilua.tmp_path directory using an optional name generator. If the name generator function is not passed, cgilua.tmpname is used. The file is removed by CGILua after the request has been processed.
cgilua.tmpname ()
Returns a temporary name using an adjusted version of os.tmpname.

Alphabetic Index

addclosefunction
addopenfunction
addscripthandler
buildplainhandler
buildprocesshandler
contentheader
doif
doscript
encodetable (urlcode)
errorlog
escape (urlcode)
header
htmlheader
include (lp)
insertfield (urlcode)
mkabsoluteurl
mkurlpath
pack
parsequery (urlcode)
handlelp
lp
print
put
redirect
script_file
script_path
script_pdir
script_vdir
script_vpath
servervariable
setcompatmode (lp)
seterrorhandler
seterroroutput
setlibdir
setmaxfilesize
setmaxinput
setoutfunc (lp)
splitonfirst
splitonlast
tmpfile
tmpname
tmp_path
urlcode
unescape (urlcode)
urlpath

Valid XHTML 1.0!

$Id: reference.html,v 1.46 2007/12/05 19:41:13 carregal Exp $

lua-cgi-5.2~alpha2/doc/us/sapi.html000077500000000000000000000243031220116477200172140ustar00rootroot00000000000000 CGILua: Building Web Scripts with Lua
CGILua
Building Web Scripts with Lua

Server API

The Server API (SAPI) allows the abstraction of a series of internal web server details and allows CGILua to be used over WSAPI. Kepler is the reference implementation of WSAPI and currently supports Apache, Microsoft IIS and Xavante as Web servers, and CGI, FastCGI, as WSAPI connectors. Xavante has a native WSAPI connector.

The SAPI API is separated into two packages: SAPI.Request and SAPI.Response.

The SAPI.Request package offers two functions:

SAPI.Request.getpostdata ([n])
Gets a block of POST data. The optional parameter n is the number of bytes to read (a default block size is used if no parameter is passed).
Returns the block as a Lua string.
SAPI.Request.servervariable (varname)
Gets the value of a server environment variable. The argument can be one of the defined CGI Variables, although not all servers implements the full set of variables. The set consists of:
  • AUTH_TYPE - If the server supports user authentication, and the script is protected, this is the protocol-specific authentication method used to validate the user.
  • CONTENT_LENGTH - The length of the content itself as given by the client.
  • CONTENT_TYPE - For queries which have attached information, such as HTTP POST and PUT, this is the content type of the data.
  • GATEWAY_INTERFACE - The revision of the CGI specification to which this server complies. Format: CGI/revision
  • PATH_INFO - The extra path information, as given by the client. In other words, scripts can be accessed by their virtual pathname, followed by extra information at the end of this path. The extra information is sent as PATH_INFO. This information should be decoded by the server if it comes from a URL before it is passed to the CGI script.
  • PATH_TRANSLATED - The server provides a translated version of PATH_INFO, which takes the path and does any virtual-to-physical mapping to it.
  • QUERY_STRING - The information which follows the "?" in the URL which referenced this script. This is the query information. It should not be decoded in any fashion. This variable should always be set when there is query information, regardless of command line decoding.
  • REMOTE_ADDR - The IP address of the remote host making the request.
  • REMOTE_HOST - The hostname making the request. If the server does not have this information, it should set REMOTE_ADDR and leave this unset.
  • REMOTE_IDENT - If the HTTP server supports RFC 931 identification, then this variable will be set to the remote user name retrieved from the server. Usage of this variable should be limited to logging only.
  • REMOTE_USER - If the server supports user authentication, and the script is protected, this is the username they have authenticated as.
  • REQUEST_METHOD - The method with which the request was made. For HTTP, this is "GET", "HEAD", "POST", etc.
  • SCRIPT_NAME - A virtual path to the script being executed, used for self-referencing URLs.
  • SERVER_NAME - The server's hostname, DNS alias, or IP address as it would appear in self-referencing URLs.
  • SERVER_PORT - The port number to which the request was sent.
  • SERVER_PROTOCOL - The name and revision of the information protcol this request came in with. Format: protocol/revision
  • SERVER_SOFTWARE - The name and version of the web server software answering the request (and running the gateway). Format: name/version
In addition to these, the header lines received from the client, if any, are placed into the environment with the prefix HTTP_ followed by the header name. Any - characters in the header name are changed to _ characters. The server may exclude any headers which it has already processed, such as Authorization, Content-type, and Content-length. If necessary, the server may choose to exclude any or all of these headers if including them would exceed any system environment limits.
Returns a string.

And the SAPI.Response package offers five functions:

SAPI.Response.contenttype (header)
Sends the Content-type header to the client. The given header should be in the form "type/subtype". This function must be called before any output is sent using SAPI.Response.write.
Returns nothing.
SAPI.Response.errorlog (message)
Generates error output using the given string or number.
Returns nothing.
SAPI.Response.header (header, value)
Sends a generic header to the client. The first argument must be the header name, such as "Set-Cookie". The second argument should be its value. This function should not be used to replace the SAPI.Response.contenttype nor the SAPI.Response.redirect functions.
Returns nothing.
SAPI.Response.redirect (url)
Sends the Location header to the client. The given url should be a string.
Returns nothing.
SAPI.Response.write (...)
Generates output using the given arguments. The arguments must be strings or numbers.
Returns nothing.

Valid XHTML 1.0!

$Id: sapi.html,v 1.33 2009/02/06 00:56:06 carregal Exp $

lua-cgi-5.2~alpha2/examples/000077500000000000000000000000001220116477200160075ustar00rootroot00000000000000lua-cgi-5.2~alpha2/examples/app.lua000077500000000000000000000021051220116477200172730ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi -- Basic application bootstraper local name, path_info = cgilua.splitonfirst(cgilua.script_vpath) if name == nil or name == "" then if io.open("index.lua") then cgilua.handle("index.lua") elseif io.open("index.lp") then cgilua.handle("index.lp") else error("No script defined") end else local appdir = CGILUA_APPS.."/"..name local appinit = "init.lua" lfs.chdir(appdir) if io.open(appinit) then -- checks for authentication if necessary if cgilua.authentication and not cgilua.authentication.username() then cgilua.redirect(cgilua.authentication.checkURL()) else -- prepares the application environment package.path = CGILUA_APPS.."/"..name.."/lua/?.lua;"..package.path cgilua.script_pdir = CGILUA_APPS.."/"..name cgilua.script_file = nil cgilua.script_vdir = "/" cgilua.urlpath = cgilua.urlpath.."/"..name cgilua.script_vpath = path_info cgilua.app_name = name cgilua.doif(appinit) end else cgilua.handle(cgilua.script_pdir..name..path_info) end end lua-cgi-5.2~alpha2/examples/authentication_conf.lua000077500000000000000000000066551220116477200225550ustar00rootroot00000000000000---------------------------- -- Authentication configuration file -- -- Defines the method and details of the authentication mechanism -- -- $Id: authentication_conf.lua,v 1.1 2007/12/05 18:40:17 carregal Exp $ ---------------------------- require"cgilua.authentication" local options = { -- Authentication method: "simpledatabase", "webserver", "ldap", "test" method = "test", -- How Authentication is stored on the client -- This directive can be "cookie" or "url" tokenPersistence="url", -- Name used for the token persitence tokenName = "userhash", -- The criptografic key to encode user information on cookies and URLs criptKey="sfdtdyedbbg", -- Where to redirect when authentication is needed -- checkURL="https://remotehost/sso/authenticate", -- absolute URL checkURL="check.lua", -- authentication controller used by app.lua } -- -- Simple database authentication parameters -- options.simpledatabase = { driver="mysql", -- "mysql","oracle","odbc" sourcename="users", dbusername="root", dbpassword="pass", passwd_hash_function=(require"md5") and md5.sumhexa, -- for MD5 encription -- passwd_hash_function = function(arg) return arg end , -- for no encription users_table="Users", user_name_field="Name", pass_field="Password", } -- -- Web Server authentication parameters -- options.webserver = { user_env_var="REMOTE_USER", -- if supports RFC 931 use "REMOTE_IDENT" } -- -- LDAP authentication parameters -- options.ldap = { host="127.0.0.1", -- accepts host:port usetls=false, --baseDN="ou=People,dc=example,dc=com", baseDN="dc=example,dc=com", RDNatributeName="cn", } local methods = { simpledatabase = {}, webserver = {}, ldap = {}, test = {}, } -- -- Simple database authentication method -- methods.simpledatabase.check = function(username,userpasswd) local simpledatabase = options.simpledatabase require ("luasql."..simpledatabase.driver) local query = "SELECT "..simpledatabase.pass_field.." FROM "..simpledatabase.users_table.." WHERE "..simpledatabase.user_name_field.." = '"..username.."'" local conn,err = luasql[simpledatabase.driver]:connect(simpledatabase.sourcename,simpledatabase.dbusername,simpledatabase.dbpassword) if conn == nil then return false, err end local cur=conn:execute(query) local row=cur:fetch() local retpasswd=row[simpledatabase.pass_field] local passwdhash=simpledatabase.passwd_hash_function(userpasswd) if retpasswd==passwdhash then return true end return false, "Username and password do not match." end -- -- Web Server authentication method -- methods.webserver.user = function () return cgilua.servervariable (options.webserver.user_env_var) end -- -- LDAP authentication method -- methods.ldap.check = function(username,userpasswd) require"lualdap" local ld,err = options.lualdap.open_simple (options.ldap.host, options.ldap.RDNatributeName.."="..username..","..options.ldap.baseDN, userpasswd, options.ldap.usetls) if ld~=nil then return true else return false, err end end -- -- Test authentication method -- methods.test.check = function(username,userpasswd) if (username == "admin") and (userpasswd == "admin") then return true else return false, "Wrong user/password combination!" end end cgilua.authentication.configure(options, methods)lua-cgi-5.2~alpha2/examples/cgilua/000077500000000000000000000000001220116477200172535ustar00rootroot00000000000000lua-cgi-5.2~alpha2/examples/cgilua/config.lua000077500000000000000000000021071220116477200212260ustar00rootroot00000000000000-- CGILua user configuration file -- $Id: config.lua,v 1.1 2008/06/30 14:30:00 carregal Exp $ -- Looks for a Lua script in the web directory with the same name as -- the executable -- Useful for shorter URLs, just be careful with an eventual name clashing -- when using this option -- cgilua.use_executable_name = true -- Enables CGILua authentication -- cgilua.doif (CGILUA_CONF.."/authentication_conf.lua") -- Emulating old behavior loading file "env.lua" from the script's directory --[[ cgilua.addopenfunction (function () cgilua.doif ("env.lua") end) --]] -- Basic configuration for using sessions --[[ require"cgilua.session" cgilua.session.setsessiondir (CGILUA_TMP) -- The following function must be called by every script that needs session. local already_enabled = false function cgilua.enablesession () if already_enabled then return else already_enabled = true end cgilua.session.open () cgilua.addclosefunction (cgilua.session.close) end --]] -- Optional compatibility values -- cgilua.preprocess = cgilua.handlelp -- cgilua.includehtml = cgilua.lp.include lua-cgi-5.2~alpha2/examples/check.lua000077500000000000000000000013711220116477200175740ustar00rootroot00000000000000-- Checking script example -- Assumes that the login form will use two fields called username and pass local username = cgilua.POST.username local pass = cgilua.POST.pass local logged, err, logoutURL if cgilua.authentication then logged, err = cgilua.authentication.check(username, pass) username = cgilua.authentication.username() or "" logoutURL = cgilua.authentication.logoutURL() else logged = false err = "No authentication configured!" username = "" end if logged and username then cgilua.redirect(cgilua.authentication.refURL()) else err = err or "" cgilua.htmlheader() cgilua.lp.include ("login.lp", { logged = logged, errorMsg = err, username = username, cgilua = cgilua, logoutURL = logoutURL}) end lua-cgi-5.2~alpha2/examples/css/000077500000000000000000000000001220116477200165775ustar00rootroot00000000000000lua-cgi-5.2~alpha2/examples/css/doc.css000066400000000000000000000074271220116477200200700ustar00rootroot00000000000000body { margin-left: 1em; margin-right: 1em; font-family: arial, helvetica, geneva, sans-serif; background-color:#ffffff; margin:0px; } code { font-family: "Andale Mono", monospace; } tt { font-family: "Andale Mono", monospace; } body, td, th { font-size: 11pt; } h1, h2, h3, h4 { margin-left: 0em; } textarea, pre, tt { font-size:10pt; } body, td, th { color:#000000; } small { font-size:0.85em; } h1 { font-size:1.5em; } h2 { font-size:1.25em; } h3 { font-size:1.15em; } h4 { font-size:1.06em; } a:link { font-weight:bold; color: #004080; text-decoration: none; } a:visited { font-weight:bold; color: #006699; text-decoration: none; } a:link:hover { text-decoration:underline; } hr { color:#cccccc } img { border-width: 0px; } h3 { padding-top: 1em; } p { margin-left: 1em; } p.name { font-family: "Andale Mono", monospace; padding-top: 1em; margin-left: 0em; } blockquote { margin-left: 3em; } .example { background-color: rgb(245, 245, 245); border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: silver; border-right-color: silver; border-bottom-color: silver; border-left-color: silver; padding: 1em; margin-left: 1em; margin-right: 1em; font-family: "Andale Mono", monospace; font-size: smaller; } hr { margin-left: 0em; background: #00007f; border: 0px; height: 1px; } ul { list-style-type: disc; } table.index { border: 1px #00007f; } table.index td { text-align: left; vertical-align: top; } table.index ul { padding-top: 0em; margin-top: 0em; } table { border: 1px solid black; border-collapse: collapse; margin-left: auto; margin-right: auto; } th { border: 1px solid black; padding: 0.5em; } td { border: 1px solid black; padding: 0.5em; } div.header, div.footer { margin-left: 0em; } #container { margin-left: 1em; margin-right: 1em; background-color: #f0f0f0; } #product { text-align: center; border-bottom: 1px solid #cccccc; background-color: #ffffff; } #product big { font-size: 2em; } #product_logo { } #product_name { } #product_description { } #main { background-color: #f0f0f0; border-left: 2px solid #cccccc; } #navigation { float: left; width: 12em; margin: 0; vertical-align: top; background-color: #f0f0f0; overflow:visible; } #navigation h1 { background-color:#e7e7e7; font-size:1.1em; color:#000000; text-align:left; margin:0px; padding:0.2em; border-top:1px solid #dddddd; border-bottom:1px solid #dddddd; } #navigation ul { font-size:1em; list-style-type: none; padding: 0; margin: 1px; } #navigation li { text-indent: -1em; margin: 0em 0em 0em 0.5em; display: block; padding: 3px 0px 0px 12px; } #navigation li li a { padding: 0px 3px 0px -1em; } #content { margin-left: 12em; padding: 1em; border-left: 2px solid #cccccc; border-right: 2px solid #cccccc; background-color: #ffffff; } #about { clear: both; margin: 0; padding: 5px; border-top: 2px solid #cccccc; background-color: #ffffff; } @media print { body { font: 10pt "Times New Roman", "TimeNR", Times, serif; } a { font-weight:bold; color: #004080; text-decoration: underline; } #main { background-color: #ffffff; border-left: 0px; } #container { margin-left: 2%; margin-right: 2%; background-color: #ffffff; } #content { margin-left: 0px; padding: 1em; border-left: 0px; border-right: 0px; background-color: #ffffff; } #navigation { display: none; } #product_logo { display: none; } #about img { display: none; } .example { font-family: "Andale Mono", monospace; font-size: 8pt; page-break-inside: avoid; } } lua-cgi-5.2~alpha2/examples/img/000077500000000000000000000000001220116477200165635ustar00rootroot00000000000000lua-cgi-5.2~alpha2/examples/img/keplerproject.gif000066400000000000000000000044051220116477200221260ustar00rootroot00000000000000GIF89a4@@@ ```000PPPppp((--ŤnnMM mmDDpp\\II((z˕))!,4pH,Ȥrl:ШtJZجvzxL.znA"~χNv}n;50 // 05;x\$;04::40;$M; ;m))E//b!҂!C:ɲV,#".1%%1."#,=ǰK20BcPxAƦNDGHEaʼn OBEETq 5x M2(ٓND AȧTt!´ACH +KlTIIKo[]IYw֑U\iQ;TeYX9f ,]h ЦS”; /݋F| 昵y/E5/eG;=$iBD A! mu(;늢 IF:4xHKcd3-©5"n$$hA}($MЮ,CW % BʐH&2n]9,)H=0Dq[xza"<;8'#tfDVr L΂GjNtP4|xk$فtș"C,ov V2.S:WNj y̵5d\E"fa X㚫uuR$Bn~z{$]ї;"ttف]7@@K!jhf{RZʝuML ء< a%C0 ji(sM'QpX)LQεBJxA"! dJF )2%! AC /_!&=8!rLXG;ymvsк9p<#WF5,f/ h2n]0)"h)ƝE" *xM fWVհgMZָB;lua-cgi-5.2~alpha2/examples/img/test.jpg000066400000000000000000000135701220116477200202520ustar00rootroot00000000000000JFIFHH XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222Rn"5!1A"Qa#2BqbR3r#!1AQ2q ?~W6yȲqY $=۾Jpc cۓQ5⚔_RpJ10(MSJ} ~Hʒs93K)0ڊH@}Fw&mN|lf+&.3KeR?Po?lXzr\}WYjĹYbʛ$ :(IY~O 1Ce P_aO+š]bb/;湿@Z|zsRIbv s$*2Z?a\2mABǫ1\rےYi‚Nm\drXjuc=w';g셦%}6ΨB!y=8ޑffd'Zm }M QXݥE -.1oӉ]+7 nO3]м =\7LKT=);>C5N]|89:Z6~^rcJR84,wxSJ )<?,-2OYޭe4un/}SqF`VU9;Wj5|_/ 6! 9987y W(1)dOE< u+M@#uWAiI]ZmI9眸?ӰC WJ5'2DR<%#a+Lgo_Wa2jˣZ\9h%a-#qVU6euzSPA9+ ,. ˱kjU-1P  ?{c@JYVcO]nN]+# Iq0d'm4I[9Li. B9 puNRGK-N8HK}{£J &HUP^ËR;j6ѮϽGzaJ$:g}m?oհ&G͍$'M olZ?O,[b]K |J֬a8&. OHeƂ*J9MXӞB geH{$2ʂG*?SPjw9c;/j* LeAb_8#6ly@.RmK{Aյ$ө2n碯MQm@Թ2B>A-Fڧ\:wZRQR8#^6x-Eۚo)/lv ڷ==I)qIrPOqj9p﹃+9HO-a&.Qԇ;ҹ>v=\f=E<9.9l%YVHZgIOݵ,U i9ƽ[ˀ6ǣ#qجeAxaҒ:ry߯{fؔ.Q*R';qU[3m^OQrGlsW W}=&` dK#''UTGT^ UK #M'W?5/Hesv$iԹU(RG4$zٽZtUU-[DSRRw'ޚ"PVϚbdttzNՙ#SIgBFNJUP$+0i~ uhiN9%G@Rqɣ,6)J':/mqy16,/<}kQjTBvcte3Ҿ Zղ"YR܁iڢx6LÐ{hÛqe59ϯs K1u2Pۏ2]|' FZksTFqܓUI-ky6BPJh%IQJʨKyp[!/Җ!@C>|U5}=#w9aYvS垂xe}Ldi1VJOs^ZrBG>ĞX>cZ셏˅>7SN$:H95娺dppc6WK*rR~7Kth|~@˚T'Y?\\w1GN}Nj83#UkMpѾە$Nj *HTڎ3tݫ L0'%#a9v{ NSjD= ;uz] 9=2m#32?O^aZKԺfUJ*|R\sNJ+)' Welcome to Kepler!
Welcome page

Congratulations!

If you are reading this page, <%= cgilua.servervariable("SERVER_SOFTWARE") %> has been successfully configured for CGILua on your system using <%= SAPI.Info._VERSION %> and <%= _VERSION %>.

This is a page generated by CGILua that points to the installed modules documentation. It serves both as a documentation index and as a simple example of a dynamic Lua Page.

What now?

From here you can also run some tests.

Contact us

For more information on Kepler modules please contact us. Comments are welcome!

You can also reach other Kepler developers and users on the Kepler Project mailing list.

Copyright 2004-2007 - Kepler Project

Valid XHTML 1.0

$Id: index.lp,v 1.1 2008/06/30 14:29:59 carregal Exp $

lua-cgi-5.2~alpha2/examples/jquery/000077500000000000000000000000001220116477200173265ustar00rootroot00000000000000lua-cgi-5.2~alpha2/examples/jquery/jquery-1.2.3.min.js000066400000000000000000001514421220116477200224330ustar00rootroot00000000000000/* * jQuery 1.2.3 - New Wave Javascript * * Copyright (c) 2008 John Resig (jquery.com) * Dual licensed under the MIT (MIT-LICENSE.txt) * and GPL (GPL-LICENSE.txt) licenses. * * $Date: 2008/06/30 14:29:59 $ * $Rev: 4663 $ */ (function(){if(window.jQuery)var _jQuery=window.jQuery;var jQuery=window.jQuery=function(selector,context){return new jQuery.prototype.init(selector,context);};if(window.$)var _$=window.$;window.$=jQuery;var quickExpr=/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;var isSimple=/^.[^:#\[\.]*$/;jQuery.fn=jQuery.prototype={init:function(selector,context){selector=selector||document;if(selector.nodeType){this[0]=selector;this.length=1;return this;}else if(typeof selector=="string"){var match=quickExpr.exec(selector);if(match&&(match[1]||!context)){if(match[1])selector=jQuery.clean([match[1]],context);else{var elem=document.getElementById(match[3]);if(elem)if(elem.id!=match[3])return jQuery().find(selector);else{this[0]=elem;this.length=1;return this;}else selector=[];}}else return new jQuery(context).find(selector);}else if(jQuery.isFunction(selector))return new jQuery(document)[jQuery.fn.ready?"ready":"load"](selector);return this.setArray(selector.constructor==Array&&selector||(selector.jquery||selector.length&&selector!=window&&!selector.nodeType&&selector[0]!=undefined&&selector[0].nodeType)&&jQuery.makeArray(selector)||[selector]);},jquery:"1.2.3",size:function(){return this.length;},length:0,get:function(num){return num==undefined?jQuery.makeArray(this):this[num];},pushStack:function(elems){var ret=jQuery(elems);ret.prevObject=this;return ret;},setArray:function(elems){this.length=0;Array.prototype.push.apply(this,elems);return this;},each:function(callback,args){return jQuery.each(this,callback,args);},index:function(elem){var ret=-1;this.each(function(i){if(this==elem)ret=i;});return ret;},attr:function(name,value,type){var options=name;if(name.constructor==String)if(value==undefined)return this.length&&jQuery[type||"attr"](this[0],name)||undefined;else{options={};options[name]=value;}return this.each(function(i){for(name in options)jQuery.attr(type?this.style:this,name,jQuery.prop(this,options[name],type,i,name));});},css:function(key,value){if((key=='width'||key=='height')&&parseFloat(value)<0)value=undefined;return this.attr(key,value,"curCSS");},text:function(text){if(typeof text!="object"&&text!=null)return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(text));var ret="";jQuery.each(text||this,function(){jQuery.each(this.childNodes,function(){if(this.nodeType!=8)ret+=this.nodeType!=1?this.nodeValue:jQuery.fn.text([this]);});});return ret;},wrapAll:function(html){if(this[0])jQuery(html,this[0].ownerDocument).clone().insertBefore(this[0]).map(function(){var elem=this;while(elem.firstChild)elem=elem.firstChild;return elem;}).append(this);return this;},wrapInner:function(html){return this.each(function(){jQuery(this).contents().wrapAll(html);});},wrap:function(html){return this.each(function(){jQuery(this).wrapAll(html);});},append:function(){return this.domManip(arguments,true,false,function(elem){if(this.nodeType==1)this.appendChild(elem);});},prepend:function(){return this.domManip(arguments,true,true,function(elem){if(this.nodeType==1)this.insertBefore(elem,this.firstChild);});},before:function(){return this.domManip(arguments,false,false,function(elem){this.parentNode.insertBefore(elem,this);});},after:function(){return this.domManip(arguments,false,true,function(elem){this.parentNode.insertBefore(elem,this.nextSibling);});},end:function(){return this.prevObject||jQuery([]);},find:function(selector){var elems=jQuery.map(this,function(elem){return jQuery.find(selector,elem);});return this.pushStack(/[^+>] [^+>]/.test(selector)||selector.indexOf("..")>-1?jQuery.unique(elems):elems);},clone:function(events){var ret=this.map(function(){if(jQuery.browser.msie&&!jQuery.isXMLDoc(this)){var clone=this.cloneNode(true),container=document.createElement("div");container.appendChild(clone);return jQuery.clean([container.innerHTML])[0];}else return this.cloneNode(true);});var clone=ret.find("*").andSelf().each(function(){if(this[expando]!=undefined)this[expando]=null;});if(events===true)this.find("*").andSelf().each(function(i){if(this.nodeType==3)return;var events=jQuery.data(this,"events");for(var type in events)for(var handler in events[type])jQuery.event.add(clone[i],type,events[type][handler],events[type][handler].data);});return ret;},filter:function(selector){return this.pushStack(jQuery.isFunction(selector)&&jQuery.grep(this,function(elem,i){return selector.call(elem,i);})||jQuery.multiFilter(selector,this));},not:function(selector){if(selector.constructor==String)if(isSimple.test(selector))return this.pushStack(jQuery.multiFilter(selector,this,true));else selector=jQuery.multiFilter(selector,this);var isArrayLike=selector.length&&selector[selector.length-1]!==undefined&&!selector.nodeType;return this.filter(function(){return isArrayLike?jQuery.inArray(this,selector)<0:this!=selector;});},add:function(selector){return!selector?this:this.pushStack(jQuery.merge(this.get(),selector.constructor==String?jQuery(selector).get():selector.length!=undefined&&(!selector.nodeName||jQuery.nodeName(selector,"form"))?selector:[selector]));},is:function(selector){return selector?jQuery.multiFilter(selector,this).length>0:false;},hasClass:function(selector){return this.is("."+selector);},val:function(value){if(value==undefined){if(this.length){var elem=this[0];if(jQuery.nodeName(elem,"select")){var index=elem.selectedIndex,values=[],options=elem.options,one=elem.type=="select-one";if(index<0)return null;for(var i=one?index:0,max=one?index+1:options.length;i=0||jQuery.inArray(this.name,value)>=0);else if(jQuery.nodeName(this,"select")){var values=value.constructor==Array?value:[value];jQuery("option",this).each(function(){this.selected=(jQuery.inArray(this.value,values)>=0||jQuery.inArray(this.text,values)>=0);});if(!values.length)this.selectedIndex=-1;}else this.value=value;});},html:function(value){return value==undefined?(this.length?this[0].innerHTML:null):this.empty().append(value);},replaceWith:function(value){return this.after(value).remove();},eq:function(i){return this.slice(i,i+1);},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments));},map:function(callback){return this.pushStack(jQuery.map(this,function(elem,i){return callback.call(elem,i,elem);}));},andSelf:function(){return this.add(this.prevObject);},data:function(key,value){var parts=key.split(".");parts[1]=parts[1]?"."+parts[1]:"";if(value==null){var data=this.triggerHandler("getData"+parts[1]+"!",[parts[0]]);if(data==undefined&&this.length)data=jQuery.data(this[0],key);return data==null&&parts[1]?this.data(parts[0]):data;}else return this.trigger("setData"+parts[1]+"!",[parts[0],value]).each(function(){jQuery.data(this,key,value);});},removeData:function(key){return this.each(function(){jQuery.removeData(this,key);});},domManip:function(args,table,reverse,callback){var clone=this.length>1,elems;return this.each(function(){if(!elems){elems=jQuery.clean(args,this.ownerDocument);if(reverse)elems.reverse();}var obj=this;if(table&&jQuery.nodeName(this,"table")&&jQuery.nodeName(elems[0],"tr"))obj=this.getElementsByTagName("tbody")[0]||this.appendChild(this.ownerDocument.createElement("tbody"));var scripts=jQuery([]);jQuery.each(elems,function(){var elem=clone?jQuery(this).clone(true)[0]:this;if(jQuery.nodeName(elem,"script")){scripts=scripts.add(elem);}else{if(elem.nodeType==1)scripts=scripts.add(jQuery("script",elem).remove());callback.call(obj,elem);}});scripts.each(evalScript);});}};jQuery.prototype.init.prototype=jQuery.prototype;function evalScript(i,elem){if(elem.src)jQuery.ajax({url:elem.src,async:false,dataType:"script"});else jQuery.globalEval(elem.text||elem.textContent||elem.innerHTML||"");if(elem.parentNode)elem.parentNode.removeChild(elem);}jQuery.extend=jQuery.fn.extend=function(){var target=arguments[0]||{},i=1,length=arguments.length,deep=false,options;if(target.constructor==Boolean){deep=target;target=arguments[1]||{};i=2;}if(typeof target!="object"&&typeof target!="function")target={};if(length==1){target=this;i=0;}for(;i-1;}},swap:function(elem,options,callback){var old={};for(var name in options){old[name]=elem.style[name];elem.style[name]=options[name];}callback.call(elem);for(var name in options)elem.style[name]=old[name];},css:function(elem,name,force){if(name=="width"||name=="height"){var val,props={position:"absolute",visibility:"hidden",display:"block"},which=name=="width"?["Left","Right"]:["Top","Bottom"];function getWH(){val=name=="width"?elem.offsetWidth:elem.offsetHeight;var padding=0,border=0;jQuery.each(which,function(){padding+=parseFloat(jQuery.curCSS(elem,"padding"+this,true))||0;border+=parseFloat(jQuery.curCSS(elem,"border"+this+"Width",true))||0;});val-=Math.round(padding+border);}if(jQuery(elem).is(":visible"))getWH();else jQuery.swap(elem,props,getWH);return Math.max(0,val);}return jQuery.curCSS(elem,name,force);},curCSS:function(elem,name,force){var ret;function color(elem){if(!jQuery.browser.safari)return false;var ret=document.defaultView.getComputedStyle(elem,null);return!ret||ret.getPropertyValue("color")=="";}if(name=="opacity"&&jQuery.browser.msie){ret=jQuery.attr(elem.style,"opacity");return ret==""?"1":ret;}if(jQuery.browser.opera&&name=="display"){var save=elem.style.outline;elem.style.outline="0 solid black";elem.style.outline=save;}if(name.match(/float/i))name=styleFloat;if(!force&&elem.style&&elem.style[name])ret=elem.style[name];else if(document.defaultView&&document.defaultView.getComputedStyle){if(name.match(/float/i))name="float";name=name.replace(/([A-Z])/g,"-$1").toLowerCase();var getComputedStyle=document.defaultView.getComputedStyle(elem,null);if(getComputedStyle&&!color(elem))ret=getComputedStyle.getPropertyValue(name);else{var swap=[],stack=[];for(var a=elem;a&&color(a);a=a.parentNode)stack.unshift(a);for(var i=0;i]*?)\/>/g,function(all,front,tag){return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?all:front+">";});var tags=jQuery.trim(elem).toLowerCase(),div=context.createElement("div");var wrap=!tags.indexOf("",""]||!tags.indexOf("",""]||tags.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
"]||!tags.indexOf("",""]||(!tags.indexOf("",""]||!tags.indexOf("",""]||jQuery.browser.msie&&[1,"div
","
"]||[0,"",""];div.innerHTML=wrap[1]+elem+wrap[2];while(wrap[0]--)div=div.lastChild;if(jQuery.browser.msie){var tbody=!tags.indexOf(""&&tags.indexOf("=0;--j)if(jQuery.nodeName(tbody[j],"tbody")&&!tbody[j].childNodes.length)tbody[j].parentNode.removeChild(tbody[j]);if(/^\s/.test(elem))div.insertBefore(context.createTextNode(elem.match(/^\s*/)[0]),div.firstChild);}elem=jQuery.makeArray(div.childNodes);}if(elem.length===0&&(!jQuery.nodeName(elem,"form")&&!jQuery.nodeName(elem,"select")))return;if(elem[0]==undefined||jQuery.nodeName(elem,"form")||elem.options)ret.push(elem);else ret=jQuery.merge(ret,elem);});return ret;},attr:function(elem,name,value){if(!elem||elem.nodeType==3||elem.nodeType==8)return undefined;var fix=jQuery.isXMLDoc(elem)?{}:jQuery.props;if(name=="selected"&&jQuery.browser.safari)elem.parentNode.selectedIndex;if(fix[name]){if(value!=undefined)elem[fix[name]]=value;return elem[fix[name]];}else if(jQuery.browser.msie&&name=="style")return jQuery.attr(elem.style,"cssText",value);else if(value==undefined&&jQuery.browser.msie&&jQuery.nodeName(elem,"form")&&(name=="action"||name=="method"))return elem.getAttributeNode(name).nodeValue;else if(elem.tagName){if(value!=undefined){if(name=="type"&&jQuery.nodeName(elem,"input")&&elem.parentNode)throw"type property can't be changed";elem.setAttribute(name,""+value);}if(jQuery.browser.msie&&/href|src/.test(name)&&!jQuery.isXMLDoc(elem))return elem.getAttribute(name,2);return elem.getAttribute(name);}else{if(name=="opacity"&&jQuery.browser.msie){if(value!=undefined){elem.zoom=1;elem.filter=(elem.filter||"").replace(/alpha\([^)]*\)/,"")+(parseFloat(value).toString()=="NaN"?"":"alpha(opacity="+value*100+")");}return elem.filter&&elem.filter.indexOf("opacity=")>=0?(parseFloat(elem.filter.match(/opacity=([^)]*)/)[1])/100).toString():"";}name=name.replace(/-([a-z])/ig,function(all,letter){return letter.toUpperCase();});if(value!=undefined)elem[name]=value;return elem[name];}},trim:function(text){return(text||"").replace(/^\s+|\s+$/g,"");},makeArray:function(array){var ret=[];if(typeof array!="array")for(var i=0,length=array.length;i*",this).remove();while(this.firstChild)this.removeChild(this.firstChild);}},function(name,fn){jQuery.fn[name]=function(){return this.each(fn,arguments);};});jQuery.each(["Height","Width"],function(i,name){var type=name.toLowerCase();jQuery.fn[type]=function(size){return this[0]==window?jQuery.browser.opera&&document.body["client"+name]||jQuery.browser.safari&&window["inner"+name]||document.compatMode=="CSS1Compat"&&document.documentElement["client"+name]||document.body["client"+name]:this[0]==document?Math.max(Math.max(document.body["scroll"+name],document.documentElement["scroll"+name]),Math.max(document.body["offset"+name],document.documentElement["offset"+name])):size==undefined?(this.length?jQuery.css(this[0],type):null):this.css(type,size.constructor==String?size:size+"px");};});var chars=jQuery.browser.safari&&parseInt(jQuery.browser.version)<417?"(?:[\\w*_-]|\\\\.)":"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",quickChild=new RegExp("^>\\s*("+chars+"+)"),quickID=new RegExp("^("+chars+"+)(#)("+chars+"+)"),quickClass=new RegExp("^([#.]?)("+chars+"*)");jQuery.extend({expr:{"":function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},"#":function(a,i,m){return a.getAttribute("id")==m[2];},":":{lt:function(a,i,m){return im[3]-0;},nth:function(a,i,m){return m[3]-0==i;},eq:function(a,i,m){return m[3]-0==i;},first:function(a,i){return i==0;},last:function(a,i,m,r){return i==r.length-1;},even:function(a,i){return i%2==0;},odd:function(a,i){return i%2;},"first-child":function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},"last-child":function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},"only-child":function(a){return!jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},parent:function(a){return a.firstChild;},empty:function(a){return!a.firstChild;},contains:function(a,i,m){return(a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},visible:function(a){return"hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},hidden:function(a){return"hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},enabled:function(a){return!a.disabled;},disabled:function(a){return a.disabled;},checked:function(a){return a.checked;},selected:function(a){return a.selected||jQuery.attr(a,"selected");},text:function(a){return"text"==a.type;},radio:function(a){return"radio"==a.type;},checkbox:function(a){return"checkbox"==a.type;},file:function(a){return"file"==a.type;},password:function(a){return"password"==a.type;},submit:function(a){return"submit"==a.type;},image:function(a){return"image"==a.type;},reset:function(a){return"reset"==a.type;},button:function(a){return"button"==a.type||jQuery.nodeName(a,"button");},input:function(a){return/input|select|textarea|button/i.test(a.nodeName);},has:function(a,i,m){return jQuery.find(m[3],a).length;},header:function(a){return/h\d/i.test(a.nodeName);},animated:function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}}},parse:[/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,new RegExp("^([:.#]*)("+chars+"+)")],multiFilter:function(expr,elems,not){var old,cur=[];while(expr&&expr!=old){old=expr;var f=jQuery.filter(expr,elems,not);expr=f.t.replace(/^\s*,\s*/,"");cur=not?elems=f.r:jQuery.merge(cur,f.r);}return cur;},find:function(t,context){if(typeof t!="string")return[t];if(context&&context.nodeType!=1&&context.nodeType!=9)return[];context=context||document;var ret=[context],done=[],last,nodeName;while(t&&last!=t){var r=[];last=t;t=jQuery.trim(t);var foundToken=false;var re=quickChild;var m=re.exec(t);if(m){nodeName=m[1].toUpperCase();for(var i=0;ret[i];i++)for(var c=ret[i].firstChild;c;c=c.nextSibling)if(c.nodeType==1&&(nodeName=="*"||c.nodeName.toUpperCase()==nodeName))r.push(c);ret=r;t=t.replace(re,"");if(t.indexOf(" ")==0)continue;foundToken=true;}else{re=/^([>+~])\s*(\w*)/i;if((m=re.exec(t))!=null){r=[];var merge={};nodeName=m[2].toUpperCase();m=m[1];for(var j=0,rl=ret.length;j=0;if(!not&&pass||not&&!pass)tmp.push(r[i]);}return tmp;},filter:function(t,r,not){var last;while(t&&t!=last){last=t;var p=jQuery.parse,m;for(var i=0;p[i];i++){m=p[i].exec(t);if(m){t=t.substring(m[0].length);m[2]=m[2].replace(/\\/g,"");break;}}if(!m)break;if(m[1]==":"&&m[2]=="not")r=isSimple.test(m[3])?jQuery.filter(m[3],r,true).r:jQuery(r).not(m[3]);else if(m[1]==".")r=jQuery.classFilter(r,m[2],not);else if(m[1]=="["){var tmp=[],type=m[3];for(var i=0,rl=r.length;i=0)^not)tmp.push(a);}r=tmp;}else if(m[1]==":"&&m[2]=="nth-child"){var merge={},tmp=[],test=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(m[3]=="even"&&"2n"||m[3]=="odd"&&"2n+1"||!/\D/.test(m[3])&&"0n+"+m[3]||m[3]),first=(test[1]+(test[2]||1))-0,last=test[3]-0;for(var i=0,rl=r.length;i=0)add=true;if(add^not)tmp.push(node);}r=tmp;}else{var fn=jQuery.expr[m[1]];if(typeof fn=="object")fn=fn[m[2]];if(typeof fn=="string")fn=eval("false||function(a,i){return "+fn+";}");r=jQuery.grep(r,function(elem,i){return fn(elem,i,m,r);},not);}}return{r:r,t:t};},dir:function(elem,dir){var matched=[];var cur=elem[dir];while(cur&&cur!=document){if(cur.nodeType==1)matched.push(cur);cur=cur[dir];}return matched;},nth:function(cur,result,dir,elem){result=result||1;var num=0;for(;cur;cur=cur[dir])if(cur.nodeType==1&&++num==result)break;return cur;},sibling:function(n,elem){var r=[];for(;n;n=n.nextSibling){if(n.nodeType==1&&(!elem||n!=elem))r.push(n);}return r;}});jQuery.event={add:function(elem,types,handler,data){if(elem.nodeType==3||elem.nodeType==8)return;if(jQuery.browser.msie&&elem.setInterval!=undefined)elem=window;if(!handler.guid)handler.guid=this.guid++;if(data!=undefined){var fn=handler;handler=function(){return fn.apply(this,arguments);};handler.data=data;handler.guid=fn.guid;}var events=jQuery.data(elem,"events")||jQuery.data(elem,"events",{}),handle=jQuery.data(elem,"handle")||jQuery.data(elem,"handle",function(){var val;if(typeof jQuery=="undefined"||jQuery.event.triggered)return val;val=jQuery.event.handle.apply(arguments.callee.elem,arguments);return val;});handle.elem=elem;jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];handler.type=parts[1];var handlers=events[type];if(!handlers){handlers=events[type]={};if(!jQuery.event.special[type]||jQuery.event.special[type].setup.call(elem)===false){if(elem.addEventListener)elem.addEventListener(type,handle,false);else if(elem.attachEvent)elem.attachEvent("on"+type,handle);}}handlers[handler.guid]=handler;jQuery.event.global[type]=true;});elem=null;},guid:1,global:{},remove:function(elem,types,handler){if(elem.nodeType==3||elem.nodeType==8)return;var events=jQuery.data(elem,"events"),ret,index;if(events){if(types==undefined||(typeof types=="string"&&types.charAt(0)=="."))for(var type in events)this.remove(elem,type+(types||""));else{if(types.type){handler=types.handler;types=types.type;}jQuery.each(types.split(/\s+/),function(index,type){var parts=type.split(".");type=parts[0];if(events[type]){if(handler)delete events[type][handler.guid];else for(handler in events[type])if(!parts[1]||events[type][handler].type==parts[1])delete events[type][handler];for(ret in events[type])break;if(!ret){if(!jQuery.event.special[type]||jQuery.event.special[type].teardown.call(elem)===false){if(elem.removeEventListener)elem.removeEventListener(type,jQuery.data(elem,"handle"),false);else if(elem.detachEvent)elem.detachEvent("on"+type,jQuery.data(elem,"handle"));}ret=null;delete events[type];}}});}for(ret in events)break;if(!ret){var handle=jQuery.data(elem,"handle");if(handle)handle.elem=null;jQuery.removeData(elem,"events");jQuery.removeData(elem,"handle");}}},trigger:function(type,data,elem,donative,extra){data=jQuery.makeArray(data||[]);if(type.indexOf("!")>=0){type=type.slice(0,-1);var exclusive=true;}if(!elem){if(this.global[type])jQuery("*").add([window,document]).trigger(type,data);}else{if(elem.nodeType==3||elem.nodeType==8)return undefined;var val,ret,fn=jQuery.isFunction(elem[type]||null),event=!data[0]||!data[0].preventDefault;if(event)data.unshift(this.fix({type:type,target:elem}));data[0].type=type;if(exclusive)data[0].exclusive=true;if(jQuery.isFunction(jQuery.data(elem,"handle")))val=jQuery.data(elem,"handle").apply(elem,data);if(!fn&&elem["on"+type]&&elem["on"+type].apply(elem,data)===false)val=false;if(event)data.shift();if(extra&&jQuery.isFunction(extra)){ret=extra.apply(elem,val==null?data:data.concat(val));if(ret!==undefined)val=ret;}if(fn&&donative!==false&&val!==false&&!(jQuery.nodeName(elem,'a')&&type=="click")){this.triggered=true;try{elem[type]();}catch(e){}}this.triggered=false;}return val;},handle:function(event){var val;event=jQuery.event.fix(event||window.event||{});var parts=event.type.split(".");event.type=parts[0];var handlers=jQuery.data(this,"events")&&jQuery.data(this,"events")[event.type],args=Array.prototype.slice.call(arguments,1);args.unshift(event);for(var j in handlers){var handler=handlers[j];args[0].handler=handler;args[0].data=handler.data;if(!parts[1]&&!event.exclusive||handler.type==parts[1]){var ret=handler.apply(this,args);if(val!==false)val=ret;if(ret===false){event.preventDefault();event.stopPropagation();}}}if(jQuery.browser.msie)event.target=event.preventDefault=event.stopPropagation=event.handler=event.data=null;return val;},fix:function(event){var originalEvent=event;event=jQuery.extend({},originalEvent);event.preventDefault=function(){if(originalEvent.preventDefault)originalEvent.preventDefault();originalEvent.returnValue=false;};event.stopPropagation=function(){if(originalEvent.stopPropagation)originalEvent.stopPropagation();originalEvent.cancelBubble=true;};if(!event.target)event.target=event.srcElement||document;if(event.target.nodeType==3)event.target=originalEvent.target.parentNode;if(!event.relatedTarget&&event.fromElement)event.relatedTarget=event.fromElement==event.target?event.toElement:event.fromElement;if(event.pageX==null&&event.clientX!=null){var doc=document.documentElement,body=document.body;event.pageX=event.clientX+(doc&&doc.scrollLeft||body&&body.scrollLeft||0)-(doc.clientLeft||0);event.pageY=event.clientY+(doc&&doc.scrollTop||body&&body.scrollTop||0)-(doc.clientTop||0);}if(!event.which&&((event.charCode||event.charCode===0)?event.charCode:event.keyCode))event.which=event.charCode||event.keyCode;if(!event.metaKey&&event.ctrlKey)event.metaKey=event.ctrlKey;if(!event.which&&event.button)event.which=(event.button&1?1:(event.button&2?3:(event.button&4?2:0)));return event;},special:{ready:{setup:function(){bindReady();return;},teardown:function(){return;}},mouseenter:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseover",jQuery.event.special.mouseenter.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseover",jQuery.event.special.mouseenter.handler);return true;},handler:function(event){if(withinElement(event,this))return true;arguments[0].type="mouseenter";return jQuery.event.handle.apply(this,arguments);}},mouseleave:{setup:function(){if(jQuery.browser.msie)return false;jQuery(this).bind("mouseout",jQuery.event.special.mouseleave.handler);return true;},teardown:function(){if(jQuery.browser.msie)return false;jQuery(this).unbind("mouseout",jQuery.event.special.mouseleave.handler);return true;},handler:function(event){if(withinElement(event,this))return true;arguments[0].type="mouseleave";return jQuery.event.handle.apply(this,arguments);}}}};jQuery.fn.extend({bind:function(type,data,fn){return type=="unload"?this.one(type,data,fn):this.each(function(){jQuery.event.add(this,type,fn||data,fn&&data);});},one:function(type,data,fn){return this.each(function(){jQuery.event.add(this,type,function(event){jQuery(this).unbind(event);return(fn||data).apply(this,arguments);},fn&&data);});},unbind:function(type,fn){return this.each(function(){jQuery.event.remove(this,type,fn);});},trigger:function(type,data,fn){return this.each(function(){jQuery.event.trigger(type,data,this,true,fn);});},triggerHandler:function(type,data,fn){if(this[0])return jQuery.event.trigger(type,data,this[0],false,fn);return undefined;},toggle:function(){var args=arguments;return this.click(function(event){this.lastToggle=0==this.lastToggle?1:0;event.preventDefault();return args[this.lastToggle].apply(this,arguments)||false;});},hover:function(fnOver,fnOut){return this.bind('mouseenter',fnOver).bind('mouseleave',fnOut);},ready:function(fn){bindReady();if(jQuery.isReady)fn.call(document,jQuery);else jQuery.readyList.push(function(){return fn.call(this,jQuery);});return this;}});jQuery.extend({isReady:false,readyList:[],ready:function(){if(!jQuery.isReady){jQuery.isReady=true;if(jQuery.readyList){jQuery.each(jQuery.readyList,function(){this.apply(document);});jQuery.readyList=null;}jQuery(document).triggerHandler("ready");}}});var readyBound=false;function bindReady(){if(readyBound)return;readyBound=true;if(document.addEventListener&&!jQuery.browser.opera)document.addEventListener("DOMContentLoaded",jQuery.ready,false);if(jQuery.browser.msie&&window==top)(function(){if(jQuery.isReady)return;try{document.documentElement.doScroll("left");}catch(error){setTimeout(arguments.callee,0);return;}jQuery.ready();})();if(jQuery.browser.opera)document.addEventListener("DOMContentLoaded",function(){if(jQuery.isReady)return;for(var i=0;i=0){var selector=url.slice(off,url.length);url=url.slice(0,off);}callback=callback||function(){};var type="GET";if(params)if(jQuery.isFunction(params)){callback=params;params=null;}else{params=jQuery.param(params);type="POST";}var self=this;jQuery.ajax({url:url,type:type,dataType:"html",data:params,complete:function(res,status){if(status=="success"||status=="notmodified")self.html(selector?jQuery("
").append(res.responseText.replace(//g,"")).find(selector):res.responseText);self.each(callback,[res.responseText,status,res]);}});return this;},serialize:function(){return jQuery.param(this.serializeArray());},serializeArray:function(){return this.map(function(){return jQuery.nodeName(this,"form")?jQuery.makeArray(this.elements):this;}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password/i.test(this.type));}).map(function(i,elem){var val=jQuery(this).val();return val==null?null:val.constructor==Array?jQuery.map(val,function(val,i){return{name:elem.name,value:val};}):{name:elem.name,value:val};}).get();}});jQuery.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(i,o){jQuery.fn[o]=function(f){return this.bind(o,f);};});var jsc=(new Date).getTime();jQuery.extend({get:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data=null;}return jQuery.ajax({type:"GET",url:url,data:data,success:callback,dataType:type});},getScript:function(url,callback){return jQuery.get(url,null,callback,"script");},getJSON:function(url,data,callback){return jQuery.get(url,data,callback,"json");},post:function(url,data,callback,type){if(jQuery.isFunction(data)){callback=data;data={};}return jQuery.ajax({type:"POST",url:url,data:data,success:callback,dataType:type});},ajaxSetup:function(settings){jQuery.extend(jQuery.ajaxSettings,settings);},ajaxSettings:{global:true,type:"GET",timeout:0,contentType:"application/x-www-form-urlencoded",processData:true,async:true,data:null,username:null,password:null,accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(s){var jsonp,jsre=/=\?(&|$)/g,status,data;s=jQuery.extend(true,s,jQuery.extend(true,{},jQuery.ajaxSettings,s));if(s.data&&s.processData&&typeof s.data!="string")s.data=jQuery.param(s.data);if(s.dataType=="jsonp"){if(s.type.toLowerCase()=="get"){if(!s.url.match(jsre))s.url+=(s.url.match(/\?/)?"&":"?")+(s.jsonp||"callback")+"=?";}else if(!s.data||!s.data.match(jsre))s.data=(s.data?s.data+"&":"")+(s.jsonp||"callback")+"=?";s.dataType="json";}if(s.dataType=="json"&&(s.data&&s.data.match(jsre)||s.url.match(jsre))){jsonp="jsonp"+jsc++;if(s.data)s.data=(s.data+"").replace(jsre,"="+jsonp+"$1");s.url=s.url.replace(jsre,"="+jsonp+"$1");s.dataType="script";window[jsonp]=function(tmp){data=tmp;success();complete();window[jsonp]=undefined;try{delete window[jsonp];}catch(e){}if(head)head.removeChild(script);};}if(s.dataType=="script"&&s.cache==null)s.cache=false;if(s.cache===false&&s.type.toLowerCase()=="get"){var ts=(new Date()).getTime();var ret=s.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+ts+"$2");s.url=ret+((ret==s.url)?(s.url.match(/\?/)?"&":"?")+"_="+ts:"");}if(s.data&&s.type.toLowerCase()=="get"){s.url+=(s.url.match(/\?/)?"&":"?")+s.data;s.data=null;}if(s.global&&!jQuery.active++)jQuery.event.trigger("ajaxStart");if((!s.url.indexOf("http")||!s.url.indexOf("//"))&&s.dataType=="script"&&s.type.toLowerCase()=="get"){var head=document.getElementsByTagName("head")[0];var script=document.createElement("script");script.src=s.url;if(s.scriptCharset)script.charset=s.scriptCharset;if(!jsonp){var done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){done=true;success();complete();head.removeChild(script);}};}head.appendChild(script);return undefined;}var requestDone=false;var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();xml.open(s.type,s.url,s.async,s.username,s.password);try{if(s.data)xml.setRequestHeader("Content-Type",s.contentType);if(s.ifModified)xml.setRequestHeader("If-Modified-Since",jQuery.lastModified[s.url]||"Thu, 01 Jan 1970 00:00:00 GMT");xml.setRequestHeader("X-Requested-With","XMLHttpRequest");xml.setRequestHeader("Accept",s.dataType&&s.accepts[s.dataType]?s.accepts[s.dataType]+", */*":s.accepts._default);}catch(e){}if(s.beforeSend)s.beforeSend(xml);if(s.global)jQuery.event.trigger("ajaxSend",[xml,s]);var onreadystatechange=function(isTimeout){if(!requestDone&&xml&&(xml.readyState==4||isTimeout=="timeout")){requestDone=true;if(ival){clearInterval(ival);ival=null;}status=isTimeout=="timeout"&&"timeout"||!jQuery.httpSuccess(xml)&&"error"||s.ifModified&&jQuery.httpNotModified(xml,s.url)&&"notmodified"||"success";if(status=="success"){try{data=jQuery.httpData(xml,s.dataType);}catch(e){status="parsererror";}}if(status=="success"){var modRes;try{modRes=xml.getResponseHeader("Last-Modified");}catch(e){}if(s.ifModified&&modRes)jQuery.lastModified[s.url]=modRes;if(!jsonp)success();}else jQuery.handleError(s,xml,status);complete();if(s.async)xml=null;}};if(s.async){var ival=setInterval(onreadystatechange,13);if(s.timeout>0)setTimeout(function(){if(xml){xml.abort();if(!requestDone)onreadystatechange("timeout");}},s.timeout);}try{xml.send(s.data);}catch(e){jQuery.handleError(s,xml,null,e);}if(!s.async)onreadystatechange();function success(){if(s.success)s.success(data,status);if(s.global)jQuery.event.trigger("ajaxSuccess",[xml,s]);}function complete(){if(s.complete)s.complete(xml,status);if(s.global)jQuery.event.trigger("ajaxComplete",[xml,s]);if(s.global&&!--jQuery.active)jQuery.event.trigger("ajaxStop");}return xml;},handleError:function(s,xml,status,e){if(s.error)s.error(xml,status,e);if(s.global)jQuery.event.trigger("ajaxError",[xml,s,e]);},active:0,httpSuccess:function(r){try{return!r.status&&location.protocol=="file:"||(r.status>=200&&r.status<300)||r.status==304||r.status==1223||jQuery.browser.safari&&r.status==undefined;}catch(e){}return false;},httpNotModified:function(xml,url){try{var xmlRes=xml.getResponseHeader("Last-Modified");return xml.status==304||xmlRes==jQuery.lastModified[url]||jQuery.browser.safari&&xml.status==undefined;}catch(e){}return false;},httpData:function(r,type){var ct=r.getResponseHeader("content-type");var xml=type=="xml"||!type&&ct&&ct.indexOf("xml")>=0;var data=xml?r.responseXML:r.responseText;if(xml&&data.documentElement.tagName=="parsererror")throw"parsererror";if(type=="script")jQuery.globalEval(data);if(type=="json")data=eval("("+data+")");return data;},param:function(a){var s=[];if(a.constructor==Array||a.jquery)jQuery.each(a,function(){s.push(encodeURIComponent(this.name)+"="+encodeURIComponent(this.value));});else for(var j in a)if(a[j]&&a[j].constructor==Array)jQuery.each(a[j],function(){s.push(encodeURIComponent(j)+"="+encodeURIComponent(this));});else s.push(encodeURIComponent(j)+"="+encodeURIComponent(a[j]));return s.join("&").replace(/%20/g,"+");}});jQuery.fn.extend({show:function(speed,callback){return speed?this.animate({height:"show",width:"show",opacity:"show"},speed,callback):this.filter(":hidden").each(function(){this.style.display=this.oldblock||"";if(jQuery.css(this,"display")=="none"){var elem=jQuery("<"+this.tagName+" />").appendTo("body");this.style.display=elem.css("display");if(this.style.display=="none")this.style.display="block";elem.remove();}}).end();},hide:function(speed,callback){return speed?this.animate({height:"hide",width:"hide",opacity:"hide"},speed,callback):this.filter(":visible").each(function(){this.oldblock=this.oldblock||jQuery.css(this,"display");this.style.display="none";}).end();},_toggle:jQuery.fn.toggle,toggle:function(fn,fn2){return jQuery.isFunction(fn)&&jQuery.isFunction(fn2)?this._toggle(fn,fn2):fn?this.animate({height:"toggle",width:"toggle",opacity:"toggle"},fn,fn2):this.each(function(){jQuery(this)[jQuery(this).is(":hidden")?"show":"hide"]();});},slideDown:function(speed,callback){return this.animate({height:"show"},speed,callback);},slideUp:function(speed,callback){return this.animate({height:"hide"},speed,callback);},slideToggle:function(speed,callback){return this.animate({height:"toggle"},speed,callback);},fadeIn:function(speed,callback){return this.animate({opacity:"show"},speed,callback);},fadeOut:function(speed,callback){return this.animate({opacity:"hide"},speed,callback);},fadeTo:function(speed,to,callback){return this.animate({opacity:to},speed,callback);},animate:function(prop,speed,easing,callback){var optall=jQuery.speed(speed,easing,callback);return this[optall.queue===false?"each":"queue"](function(){if(this.nodeType!=1)return false;var opt=jQuery.extend({},optall);var hidden=jQuery(this).is(":hidden"),self=this;for(var p in prop){if(prop[p]=="hide"&&hidden||prop[p]=="show"&&!hidden)return jQuery.isFunction(opt.complete)&&opt.complete.apply(this);if(p=="height"||p=="width"){opt.display=jQuery.css(this,"display");opt.overflow=this.style.overflow;}}if(opt.overflow!=null)this.style.overflow="hidden";opt.curAnim=jQuery.extend({},prop);jQuery.each(prop,function(name,val){var e=new jQuery.fx(self,opt,name);if(/toggle|show|hide/.test(val))e[val=="toggle"?hidden?"show":"hide":val](prop);else{var parts=val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),start=e.cur(true)||0;if(parts){var end=parseFloat(parts[2]),unit=parts[3]||"px";if(unit!="px"){self.style[name]=(end||1)+unit;start=((end||1)/e.cur(true))*start;self.style[name]=start+unit;}if(parts[1])end=((parts[1]=="-="?-1:1)*end)+start;e.custom(start,end,unit);}else e.custom(start,val,"");}});return true;});},queue:function(type,fn){if(jQuery.isFunction(type)||(type&&type.constructor==Array)){fn=type;type="fx";}if(!type||(typeof type=="string"&&!fn))return queue(this[0],type);return this.each(function(){if(fn.constructor==Array)queue(this,type,fn);else{queue(this,type).push(fn);if(queue(this,type).length==1)fn.apply(this);}});},stop:function(clearQueue,gotoEnd){var timers=jQuery.timers;if(clearQueue)this.queue([]);this.each(function(){for(var i=timers.length-1;i>=0;i--)if(timers[i].elem==this){if(gotoEnd)timers[i](true);timers.splice(i,1);}});if(!gotoEnd)this.dequeue();return this;}});var queue=function(elem,type,array){if(!elem)return undefined;type=type||"fx";var q=jQuery.data(elem,type+"queue");if(!q||array)q=jQuery.data(elem,type+"queue",array?jQuery.makeArray(array):[]);return q;};jQuery.fn.dequeue=function(type){type=type||"fx";return this.each(function(){var q=queue(this,type);q.shift();if(q.length)q[0].apply(this);});};jQuery.extend({speed:function(speed,easing,fn){var opt=speed&&speed.constructor==Object?speed:{complete:fn||!fn&&easing||jQuery.isFunction(speed)&&speed,duration:speed,easing:fn&&easing||easing&&easing.constructor!=Function&&easing};opt.duration=(opt.duration&&opt.duration.constructor==Number?opt.duration:{slow:600,fast:200}[opt.duration])||400;opt.old=opt.complete;opt.complete=function(){if(opt.queue!==false)jQuery(this).dequeue();if(jQuery.isFunction(opt.old))opt.old.apply(this);};return opt;},easing:{linear:function(p,n,firstNum,diff){return firstNum+diff*p;},swing:function(p,n,firstNum,diff){return((-Math.cos(p*Math.PI)/2)+0.5)*diff+firstNum;}},timers:[],timerId:null,fx:function(elem,options,prop){this.options=options;this.elem=elem;this.prop=prop;if(!options.orig)options.orig={};}});jQuery.fx.prototype={update:function(){if(this.options.step)this.options.step.apply(this.elem,[this.now,this]);(jQuery.fx.step[this.prop]||jQuery.fx.step._default)(this);if(this.prop=="height"||this.prop=="width")this.elem.style.display="block";},cur:function(force){if(this.elem[this.prop]!=null&&this.elem.style[this.prop]==null)return this.elem[this.prop];var r=parseFloat(jQuery.css(this.elem,this.prop,force));return r&&r>-10000?r:parseFloat(jQuery.curCSS(this.elem,this.prop))||0;},custom:function(from,to,unit){this.startTime=(new Date()).getTime();this.start=from;this.end=to;this.unit=unit||this.unit||"px";this.now=this.start;this.pos=this.state=0;this.update();var self=this;function t(gotoEnd){return self.step(gotoEnd);}t.elem=this.elem;jQuery.timers.push(t);if(jQuery.timerId==null){jQuery.timerId=setInterval(function(){var timers=jQuery.timers;for(var i=0;ithis.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var done=true;for(var i in this.options.curAnim)if(this.options.curAnim[i]!==true)done=false;if(done){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(jQuery.css(this.elem,"display")=="none")this.elem.style.display="block";}if(this.options.hide)this.elem.style.display="none";if(this.options.hide||this.options.show)for(var p in this.options.curAnim)jQuery.attr(this.elem.style,p,this.options.orig[p]);}if(done&&jQuery.isFunction(this.options.complete))this.options.complete.apply(this.elem);return false;}else{var n=t-this.startTime;this.state=n/this.options.duration;this.pos=jQuery.easing[this.options.easing||(jQuery.easing.swing?"swing":"linear")](this.state,n,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update();}return true;}};jQuery.fx.step={scrollLeft:function(fx){fx.elem.scrollLeft=fx.now;},scrollTop:function(fx){fx.elem.scrollTop=fx.now;},opacity:function(fx){jQuery.attr(fx.elem.style,"opacity",fx.now);},_default:function(fx){fx.elem.style[fx.prop]=fx.now+fx.unit;}};jQuery.fn.offset=function(){var left=0,top=0,elem=this[0],results;if(elem)with(jQuery.browser){var parent=elem.parentNode,offsetChild=elem,offsetParent=elem.offsetParent,doc=elem.ownerDocument,safari2=safari&&parseInt(version)<522&&!/adobeair/i.test(userAgent),fixed=jQuery.css(elem,"position")=="fixed";if(elem.getBoundingClientRect){var box=elem.getBoundingClientRect();add(box.left+Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),box.top+Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));add(-doc.documentElement.clientLeft,-doc.documentElement.clientTop);}else{add(elem.offsetLeft,elem.offsetTop);while(offsetParent){add(offsetParent.offsetLeft,offsetParent.offsetTop);if(mozilla&&!/^t(able|d|h)$/i.test(offsetParent.tagName)||safari&&!safari2)border(offsetParent);if(!fixed&&jQuery.css(offsetParent,"position")=="fixed")fixed=true;offsetChild=/^body$/i.test(offsetParent.tagName)?offsetChild:offsetParent;offsetParent=offsetParent.offsetParent;}while(parent&&parent.tagName&&!/^body|html$/i.test(parent.tagName)){if(!/^inline|table.*$/i.test(jQuery.css(parent,"display")))add(-parent.scrollLeft,-parent.scrollTop);if(mozilla&&jQuery.css(parent,"overflow")!="visible")border(parent);parent=parent.parentNode;}if((safari2&&(fixed||jQuery.css(offsetChild,"position")=="absolute"))||(mozilla&&jQuery.css(offsetChild,"position")!="absolute"))add(-doc.body.offsetLeft,-doc.body.offsetTop);if(fixed)add(Math.max(doc.documentElement.scrollLeft,doc.body.scrollLeft),Math.max(doc.documentElement.scrollTop,doc.body.scrollTop));}results={top:top,left:left};}function border(elem){add(jQuery.curCSS(elem,"borderLeftWidth",true),jQuery.curCSS(elem,"borderTopWidth",true));}function add(l,t){left+=parseInt(l)||0;top+=parseInt(t)||0;}return results;};})();lua-cgi-5.2~alpha2/examples/login.lp000077500000000000000000000011011220116477200174500ustar00rootroot00000000000000 Login <% if logged then %>

User <%= username %> logged in

Logout <% else %>

<%= errorMsg %>

User name:
Password:
<% end %> lua-cgi-5.2~alpha2/examples/test.lp000077500000000000000000000145071220116477200173350ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi CGILua Test <% require"cgilua.cookies" if cgilua.POST.user then cgilua.cookies.sethtml("cookie_kepler", cgilua.POST.user) end %>
CGILua simple tests

Form Handling

Entering values on this form should display them as values in the first submission, and as a cookie in the next submission

The values should show the previous POST

Values: Username = <%= cgilua.POST.user or "(not set)"%>, Password = <%= cgilua.POST.pass or "(not set)"%>

Cookies test

Here you should see the values posted before the ones shown above

cookie_kepler = <%= cgilua.cookies.get("cookie_kepler") or "(not set)" %>

File Upload

Choose a file to upload, press "Upload" and a link to the file should appear below with the corresponding "Remove" button.

<% local f = cgilua.POST.file if f and next(f) then local _, name = cgilua.splitonlast(f.filename) local file = f.file local dest = io.open(name, "wb") if dest then local bytes = file:read("*a") dest:write(bytes) dest:close() cgilua.print(""..name.."\n") cgilua.print([[
]]) cgilua.print([[]]) cgilua.print([[]]) cgilua.print([[
]]) end end %> <% if cgilua.POST.remove then os.remove(cgilua.POST.filename) end %> <% local function showtable(t) cgilua.put "{" for i,v in pairs (t) do cgilua.put("\n") if type(v) == "table" then local vv = "{\n" for a,b in pairs(v) do vv = string.format ("%s %s = [[%s]],\n", vv, a, tostring(b)) end v = vv.." }," cgilua.put (string.format (" %s = %s", i, tostring(v))) else cgilua.put (string.format (" %s = [[%s]],", i, tostring(v))) end end if next(t) then cgilua.put "\n" end cgilua.put "}\n" end %>

cgilua.QUERY

<% showtable (cgilua.QUERY) %>

cgilua.POST

<% showtable (cgilua.POST) %>

CGILua Variables

<% local vars = { "script_file", "script_path", "script_pdir", "script_vdir", "script_vpath", "urlpath", } for _, v in ipairs(vars) do %> <% end %>
cgilua.<%= v %><%= tostring(cgilua[v]) %>

Server Variables

<% local vars = { "SERVER_SOFTWARE", "SERVER_NAME", "SERVER_PROTOCOL", "SERVER_PORT", "GATEWAY_INTERFACE", "REQUEST_METHOD", "SCRIPT_NAME", "PATH_INFO", "PATH_TRANSLATED", "QUERY_STRING", "CONTENT_TYPE", "CONTENT_LENGTH", "REMOTE_ADDR", "REMOTE_HOST", "REMOTE_USER", "REMOTE_IDENT", "AUTH_TYPE", } for _, v in ipairs(vars) do %> <% end %>
<%= v %><%= tostring(cgilua.servervariable(v)) %>

Multiple Output

The next test should show numbers, from 1 to 3, and the string "OK" together. The first line should show the results without spaces and the second should separate them with tabs.

cgilua.put(1, 2, 3, "OK")   --> <% cgilua.put(1, 2, 3, "OK") %>

The next test should show numbers, from 1 to 3, and the string "OK" separated by tabs.

cgilua.print(1, 2, 3, "OK") --> <% cgilua.print(1, 2, 3, "OK") %>

Date

Today is: <%= os.date() %>

Image test

Here should be a small image: a small photograph

FileSystem test

<% local d = lfs.currentdir () or "" cgilua.put("Iterating over "..d.."
") for file in lfs.dir(d) do cgilua.put("   "..file.."
") end %>

Containment test

<% if (x == nil) then x = 1 else x = x + 1 end %> Expected value: 1, actual value: <%= x %>.

Valid XHTML 1.0

$Id: test.lp,v 1.3 2008/07/03 20:34:36 carregal Exp $

lua-cgi-5.2~alpha2/rockspec/000077500000000000000000000000001220116477200160025ustar00rootroot00000000000000lua-cgi-5.2~alpha2/rockspec/cgilua-5.1.2-1.rockspec000077500000000000000000000015451220116477200216100ustar00rootroot00000000000000package = "CGILua" version = "5.1.2-1" source = { url = "http://luaforge.net/frs/download.php/3398/cgilua-5.1.2.tar.gz" } description = { summary = "Tool for creating dynamic Web pages and manipulating data from Web forms", detailed = [[ CGILua allows the separation of logic and data handling from the generation of pages, making it easy to develop web applications with Lua. CGILua can be used with a variety of Web servers and, for each server, with different launchers. A launcher is responsible for the interaction of CGILua and the Web server, for example using ISAPI on IIS or mod_lua on Apache. ]] } dependencies = { "lua >= 5.1", "luafilesystem >= 1.4.1", } build = { type = "make", build_pass = false, install_target = "install", install_variables = { LUA_DIR = "$(LUADIR)" } } lua-cgi-5.2~alpha2/rockspec/cgilua-5.1.2-2.rockspec000077500000000000000000000015451220116477200216110ustar00rootroot00000000000000package = "CGILua" version = "5.1.2-2" source = { url = "http://luaforge.net/frs/download.php/3398/cgilua-5.1.2.tar.gz" } description = { summary = "Tool for creating dynamic Web pages and manipulating data from Web forms", detailed = [[ CGILua allows the separation of logic and data handling from the generation of pages, making it easy to develop web applications with Lua. CGILua can be used with a variety of Web servers and, for each server, with different launchers. A launcher is responsible for the interaction of CGILua and the Web server, for example using ISAPI on IIS or mod_lua on Apache. ]] } dependencies = { "lua >= 5.1", "luafilesystem >= 1.4.1", } build = { type = "make", build_pass = false, install_target = "install", install_variables = { LUA_DIR = "$(LUADIR)" } } lua-cgi-5.2~alpha2/rockspec/cgilua-5.1.2rc1-1.rockspec000077500000000000000000000015341220116477200222140ustar00rootroot00000000000000package = "CGILua" version = "5.1.2rc1-1" description = { summary = "Tool for creating dynamic Web pages and manipulating data from Web forms", detailed = [[ CGILua allows the separation of logic and data handling from the generation of pages, making it easy to develop web applications with Lua. CGILua can be used with a variety of Web servers and, for each server, with different launchers. A launcher is responsible for the interaction of CGILua and the Web server, for example using ISAPI on IIS or mod_lua on Apache. ]] } dependencies = { "lua >= 5.1", "luafilesystem 1.4.1rc1", } source = { url = "http://cgilua.luaforge.net/cgilua-5.1.2rc1.tar.gz" } build = { type = "make", build_pass = false, install_target = "install", install_variables = { LUA_DIR = "$(LUADIR)" } } lua-cgi-5.2~alpha2/rockspec/cgilua-5.1.3-1.rockspec000077500000000000000000000025231220116477200216060ustar00rootroot00000000000000package = "CGILua" version = "5.1.3-1" source = { url = "http://luaforge.net/frs/download.php/3970/cgilua-5.1.3.tar.gz" } description = { summary = "Tool for creating dynamic Web pages and manipulating data from Web forms", detailed = [[ CGILua allows the separation of logic and data handling from the generation of pages, making it easy to develop web applications with Lua. CGILua can be used with a variety of Web servers and, for each server, with different launchers. A launcher is responsible for the interaction of CGILua and the Web server, for example using ISAPI on IIS or mod_lua on Apache. ]] } dependencies = { "lua >= 5.1", "luafilesystem >= 1.4.1", } local CGILUA_LUAS = { "src/cgilua/authentication.lua", "src/cgilua/cookies.lua", "src/cgilua/dispatcher.lua", "src/cgilua/loader.lua", "src/cgilua/lp.lua", "src/cgilua/mime.lua", "src/cgilua/post.lua", "src/cgilua/readuntil.lua", "src/cgilua/serialize.lua", "src/cgilua/session.lua", "src/cgilua/urlcode.lua" } build = { type = "module", modules = { cgilua = "src/cgilua/cgilua.lua" } } for i = 1, #CGILUA_LUAS do local file = CGILUA_LUAS[i] local mod = "cgilua." .. file:match("^src/cgilua/([^%.]+)%.lua$") build.modules[mod] = file end lua-cgi-5.2~alpha2/rockspec/cgilua-5.1.4-1.rockspec000077500000000000000000000027451220116477200216150ustar00rootroot00000000000000package = "CGILua" version = "5.1.4-1" source = { url = "http://github.com/downloads/keplerproject/cgilua/cgilua-5.1.4.tar.gz" } description = { summary = "Tool for creating dynamic Web pages and manipulating data from Web forms", detailed = [[ CGILua allows the separation of logic and data handling from the generation of pages, making it easy to develop web applications with Lua. CGILua can be used with a variety of Web servers and, for each server, with different launchers. A launcher is responsible for the interaction of CGILua and the Web server, for example using ISAPI on IIS or mod_lua on Apache. ]] } dependencies = { "lua >= 5.1", "luafilesystem >= 1.5.0", } local CGILUA_LUAS = { "src/cgilua/authentication.lua", "src/cgilua/cookies.lua", "src/cgilua/dispatcher.lua", "src/cgilua/loader.lua", "src/cgilua/lp.lua", "src/cgilua/mime.lua", "src/cgilua/post.lua", "src/cgilua/readuntil.lua", "src/cgilua/serialize.lua", "src/cgilua/session.lua", "src/cgilua/urlcode.lua" } build = { type = "builtin", modules = { cgilua = "src/cgilua/cgilua.lua" }, copy_directories = { "examples", "doc", "tests" }, install = { bin = { "src/launchers/cgilua.cgi", "src/launchers/cgilua.fcgi" } } } for i = 1, #CGILUA_LUAS do local file = CGILUA_LUAS[i] local mod = "cgilua." .. file:match("^src/cgilua/([^%.]+)%.lua$") build.modules[mod] = file end lua-cgi-5.2~alpha2/rockspec/cgilua-5.2-1.rockspec000077500000000000000000000027411220116477200214500ustar00rootroot00000000000000package = "CGILua" version = "5.2-1" source = { url = "http://github.com/downloads/keplerproject/cgilua/cgilua-5.2.tar.gz" } description = { summary = "Tool for creating dynamic Web pages and manipulating data from Web forms", detailed = [[ CGILua allows the separation of logic and data handling from the generation of pages, making it easy to develop web applications with Lua. CGILua can be used with a variety of Web servers and, for each server, with different launchers. A launcher is responsible for the interaction of CGILua and the Web server, for example using ISAPI on IIS or mod_lua on Apache. ]] } dependencies = { "lua >= 5.2", "luafilesystem >= 1.6.0", } local CGILUA_LUAS = { "src/cgilua/authentication.lua", "src/cgilua/cookies.lua", "src/cgilua/dispatcher.lua", "src/cgilua/loader.lua", "src/cgilua/lp.lua", "src/cgilua/mime.lua", "src/cgilua/post.lua", "src/cgilua/readuntil.lua", "src/cgilua/serialize.lua", "src/cgilua/session.lua", "src/cgilua/urlcode.lua" } build = { type = "builtin", modules = { cgilua = "src/cgilua/cgilua.lua" }, copy_directories = { "examples", "doc", "tests" }, install = { bin = { "src/launchers/cgilua.cgi", "src/launchers/cgilua.fcgi" } } } for i = 1, #CGILUA_LUAS do local file = CGILUA_LUAS[i] local mod = "cgilua." .. file:match("^src/cgilua/([^%.]+)%.lua$") build.modules[mod] = file end lua-cgi-5.2~alpha2/rockspec/cgilua-cvs-2.rockspec000077500000000000000000000015451220116477200217410ustar00rootroot00000000000000package = "CGILua" version = "cvs-2" source = { url = "cvs://:pserver:anonymous:@cvs.luaforge.net:/cvsroot/cgilua", cvs_tag = "HEAD", } description = { summary = "Tool for creating dynamic Web pages and manipulating data from Web forms", detailed = [[ CGILua allows the separation of logic and data handling from the generation of pages, making it easy to develop web applications with Lua. CGILua can be used with a variety of Web servers and, for each server, with different launchers. A launcher is responsible for the interaction of CGILua and the Web server, for example using ISAPI on IIS or mod_lua on Apache. ]] } dependencies = { "lua >= 5.1", "luafilesystem > 1.0", "luasocket >= 2.0" } build = { type = "make", build_pass = false, install_variables = { LUA_DIR = "$(LUADIR)" } } lua-cgi-5.2~alpha2/rockspec/cgilua-cvs-3.rockspec000077500000000000000000000016021220116477200217340ustar00rootroot00000000000000package = "CGILua" version = "cvs-3" description = { summary = "Tool for creating dynamic Web pages and manipulating data from Web forms", detailed = [[ CGILua allows the separation of logic and data handling from the generation of pages, making it easy to develop web applications with Lua. CGILua can be used with a variety of Web servers and, for each server, with different launchers. A launcher is responsible for the interaction of CGILua and the Web server, for example using ISAPI on IIS or mod_lua on Apache. ]] } dependencies = { "lua >= 5.1", "luafilesystem cvs", } source = { url = "cvs://:pserver:anonymous@cvs.luaforge.net:/cvsroot/cgilua", cvs_tag = "HEAD", dir = "cgilua" } build = { type = "make", build_pass = false, install_target = "install", install_variables = { LUA_DIR = "$(LUADIR)" } } lua-cgi-5.2~alpha2/rockspec/cgilua-cvs-4.rockspec000077500000000000000000000026771220116477200217520ustar00rootroot00000000000000package = "CGILua" version = "cvs-4" description = { summary = "Tool for creating dynamic Web pages and manipulating data from Web forms", detailed = [[ CGILua allows the separation of logic and data handling from the generation of pages, making it easy to develop web applications with Lua. CGILua can be used with a variety of Web servers and, for each server, with different launchers. A launcher is responsible for the interaction of CGILua and the Web server, for example using ISAPI on IIS or mod_lua on Apache. ]] } dependencies = { "lua >= 5.1", "luafilesystem >= 1.5.0", } source = { url = "git://github.com/keplerproject/cgilua.git", } local CGILUA_LUAS = { "src/cgilua/authentication.lua", "src/cgilua/cookies.lua", "src/cgilua/dispatcher.lua", "src/cgilua/loader.lua", "src/cgilua/lp.lua", "src/cgilua/mime.lua", "src/cgilua/post.lua", "src/cgilua/readuntil.lua", "src/cgilua/serialize.lua", "src/cgilua/session.lua", "src/cgilua/urlcode.lua" } build = { type = "module", modules = { cgilua = "src/cgilua/cgilua.lua" }, install = { bin = { "src/launchers/cgilua.cgi", "src/launchers/cgilua.fcgi" } }, copy_directories = { "examples", "doc" } } for i = 1, #CGILUA_LUAS do local file = CGILUA_LUAS[i] local mod = "cgilua." .. file:match("^src/cgilua/([^%.]+)%.lua$") build.modules[mod] = file end lua-cgi-5.2~alpha2/src/000077500000000000000000000000001220116477200147605ustar00rootroot00000000000000lua-cgi-5.2~alpha2/src/cgilua/000077500000000000000000000000001220116477200162245ustar00rootroot00000000000000lua-cgi-5.2~alpha2/src/cgilua/authentication.lua000077500000000000000000000164651220116477200217650ustar00rootroot00000000000000-- CGILua authentication Module -- Author: Leonardo Godinho -- -- Offers a basic API for authentication assuming the presence of -- cgilua.POST.user, cgilua.POST.pass, cgilua.QUERY.logout, cgilua.QUERY[tokenName] -- -- The API consists in the functions -- check(username, passwd) - Checks if the pair username/passwd is authenticated by the configured method -- checkURL() - returns the URL for the checking script -- configure(options, methods) - configures the authentication framework (see /examples/authentication_conf.lua) -- logoutURL() - returns the URL for the logout page -- refURL() - returns the original URL being checked for authentication -- username() - returns the authenticated user if existent -- -- The authenticated user can be persisted by using a cookie or an ID in the URL -- -- $Id: authentication.lua,v 1.2 2007/12/05 19:41:13 carregal Exp $ local mime=require"mime" -- from LuaSocket local md5=require"md5" local cookies = require"cgilua.cookies" local cgilua = require"cgilua" local string = require"string" local math = require"math" local error = error local M = {} local authenticatedUser local configuration local _check -- check function provided by the configuration -- Callback functions to manipulate Tokens in the URL -- if not defined, CGILua standard URLs are assumed -- Returns the current token function M.getToken() return cgilua.QUERY[configuration.tokenName] end -- Sets the current token function M.setToken(token) cgilua.QUERY[configuration.tokenName] = token end -- Returns the current URL function M.currentURL() local script_name = cgilua.servervariable"SCRIPT_NAME" local path_info = cgilua.servervariable"PATH_INFO" or "" local query_string = cgilua.servervariable"QUERY_STRING" or "" if query_string ~= "" then query_string = "?"..query_string end return cgilua.mkabsoluteurl(script_name..path_info..query_string) end -- URL Base64 encoder and decoder functions -- (http://en.wikipedia.org/wiki/Base64) -- -- '=' is replaced by '' -- '+' and '/' are respectively replaced by '*' and '-' function M.encodeURLbase64(str) local b64str = mime.b64(str) local urlb64str = string.gsub(b64str,"=","") urlb64str = string.gsub(urlb64str,"+","*") urlb64str = string.gsub(urlb64str,"/","-") urlb64str = string.gsub(urlb64str," ","_") return urlb64str end function M.decodeURLbase64(urlb64str) local b64str = string.gsub(urlb64str,"*","+") b64str = string.gsub(b64str,"-","/") b64str = string.gsub(b64str,"_"," ") local b64strPadLen = math.fmod(4 - math.fmod(string.len(b64str), 4), 4) b64str = b64str..string.rep("=", b64strPadLen) local str = mime.unb64(b64str) return str end -- Returns the authenticated username or nil if no user is authenticated function M.username() if authenticatedUser == nil then local authenticatedUserData local token if configuration.tokenPersistence == "url" then token = M.getToken() elseif configuration.tokenPersistence == "cookie" then token = cgilua.cookies.get(configuration.tokenName) end if token then authenticatedUserData = md5.decrypt(M.decodeURLbase64(token), configuration.criptKey) -- check if IP in crypted data match with client IP local authenticatedUserIP = authenticatedUserData and string.gsub(authenticatedUserData, ",.*$","") or nil if authenticatedUserIP ~= cgilua.servervariable("REMOTE_ADDR") then return nil end authenticatedUser=authenticatedUserData and string.gsub(authenticatedUserData, "^.*,", "") or nil end end return authenticatedUser end -- encrypt the user IP and username for the user hash token local function cryptUserData() if authenticatedUser then local userData = cgilua.servervariable("REMOTE_ADDR") ..",".. authenticatedUser local cryptedUserData = M.encodeURLbase64(md5.crypt(userData, configuration.criptKey)) return cryptedUserData end end -- defines the logged user name and sets the user hash token local function setUser(username) authenticatedUser = username if username then local cryptedUserData = cryptUserData() if configuration.tokenPersistence == "url" then M.setToken(cryptedUserData) cgilua.cookies.delete(configuration.tokenName) -- removes an eventual previous cookie token elseif configuration.tokenPersistence == "cookie" then cgilua.cookies.set(configuration.tokenName, cryptedUserData) M.setToken() -- remove an eventual previous token from the URLs end end end -- User logout, clear everything function M.logout() setUser() cgilua.cookies.delete(configuration.tokenName) M.setToken() cgilua.QUERY.logout = nil end -- Checks if a user name/password is authenticated by the configured method -- if the user is authenticaded then login the user else logout the user -- returns true if the user has been succesfully authenticated or false plus -- an error message when the authentication fails function M.check(name, pass) name = name or cgilua.POST.user pass = pass or cgilua.POST.pass if name then -- Tries to authenticate the user using the configured method local retauth,errauth = _check(name, pass) if retauth then setUser(name) return true else M.logout() return false, errauth end else local authuser = M.username() if authuser then if cgilua.QUERY.logout ~= nil then M.logout() return false end end return authuser end end -- Returns a authentication URL with ref URL as a parameter, -- accepts an optional value for the logout action function M.checkURL(ref, tologout) local token if configuration.tokenPersistence == "url" then token = M.getToken() elseif configuration.tokenPersistence == "cookie" then token = cgilua.cookies.get(configuration.tokenName) end -- As HTTP header referer information can violate privacy, -- some browsers allow the user to disable the sending of referer information. -- Some proxy and firewall software will also filter out referer information, -- to avoid leaking the location of non-public websites. -- So we send the current URL as an URL parameter to the login URL. M.setToken() local args = {ref = ref or M.currentURL(), logout = tologout} if string.find(configuration.checkURL, "^https?:") then local params = "?"..urlcode.encodetable(args) return configuration.checkURL..params end return cgilua.mkabsoluteurl(cgilua.mkurlpath(configuration.checkURL, args)) end -- Returns the logout URL, based on the login URL function M.logoutURL() return M.checkURL(nil, 1) end -- Returns the referenced URL, the one supposed to be offered only for authenticated users function M.refURL() local url local baseURL = cgilua.QUERY.ref or configuration.checkURL if string.find(baseURL, "\?") then url = string.gsub(baseURL, "\?", "?"..configuration.tokenName.."="..cryptUserData().."&") else url = baseURL.."?"..configuration.tokenName.."="..cryptUserData() end return url end -- Sets the current configuration function M.configure(options, methods) configuration = options local method = methods[options.method] or {} if method.check then _check = method.check end if method.username then username = method.username end end return M lua-cgi-5.2~alpha2/src/cgilua/cgilua.lua000077500000000000000000000522441220116477200202050ustar00rootroot00000000000000---------------------------------------------------------------------------- -- CGILua library. -- -- @release $Id: cgilua.lua,v 1.85 2009/06/28 22:42:34 tomas Exp $ ---------------------------------------------------------------------------- local _G = assert(_G) local urlcode = require"cgilua.urlcode" local lp = require"cgilua.lp" local lfs = require"lfs" local debug = require"debug" local assert, error, ipairs, select, tostring, type, unpack, xpcall = assert, error, ipairs, select, tostring, type, unpack, xpcall local pairs = pairs local gsub, format, strfind, strlower, strsub, match = string.gsub, string.format, string.find, string.lower, string.sub, string.match local setmetatable = setmetatable local _open = io.open local tinsert, tremove, concat = table.insert, table.remove, table.concat local date = os.date local os_tmpname = os.tmpname local getenv = os.getenv local remove = os.remove local seeall = package.seeall lp.setoutfunc ("cgilua.put") lp.setcompatmode (true) local M = { _COPYRIGHT = "Copyright (C) 2003-2013 Kepler Project", _DESCRIPTION = "CGILua is a tool for creating dynamic Web pages and manipulating input data from forms", _VERSION = "CGILua 5.2", } -- -- Internal state variables. local SAPI local _default_errorhandler = debug.traceback local _errorhandler = _default_errorhandler local _default_erroroutput = function (msg) if type(msg) ~= "string" and type(msg) ~= "number" then msg = format ("bad argument #1 to 'error' (string expected, got %s)", type(msg)) end -- Logging error SAPI.Response.errorlog (msg) SAPI.Response.errorlog (" ") SAPI.Response.errorlog (SAPI.Request.servervariable"REMOTE_ADDR") SAPI.Response.errorlog (" ") SAPI.Response.errorlog (date()) SAPI.Response.errorlog ("\n") -- Building user message msg = gsub (gsub (msg, "\n", "
\n"), "\t", "  ") SAPI.Response.contenttype ("text/html") SAPI.Response.write ("CGILua Error" .. msg .. "") end local _erroroutput = _default_erroroutput local _default_maxfilesize = 512 * 1024 local _maxfilesize = _default_maxfilesize local _default_maxinput = 1024 * 1024 local _maxinput = _default_maxinput M.script_path = false -- -- Header functions ---------------------------------------------------------------------------- -- Sends a header. -- @name header -- @class function -- @param header String with the header. -- @param value String with the corresponding value. ---------------------------------------------------------------------------- function M.header (...) return SAPI.Response.header (...) end ---------------------------------------------------------------------------- -- Sends a Content-type header. -- @param type String with the type of the header. -- @param subtype String with the subtype of the header. ---------------------------------------------------------------------------- function M.contentheader (type, subtype) SAPI.Response.contenttype (type..'/'..subtype) end ---------------------------------------------------------------------------- -- Sends the HTTP header "text/html". ---------------------------------------------------------------------------- function M.htmlheader() SAPI.Response.contenttype ("text/html") end ---------------------------------------------------------------------------- -- Sends an HTTP header redirecting the browser to another URL -- @param url String with the URL. -- @param args Table with the arguments (optional). ---------------------------------------------------------------------------- function M.redirect (url, args) if strfind(url,"^https?:") then local params="" if args then params = "?"..urlcode.encodetable(args) end return SAPI.Response.redirect(url..params) else return SAPI.Response.redirect(M.mkabsoluteurl(M.mkurlpath(url,args))) end end ---------------------------------------------------------------------------- -- Returns a server variable -- @name servervariable -- @class function -- @param name String with the name of the server variable. -- @return String with the value of the server variable. ---------------------------------------------------------------------------- function M.servervariable (...) return SAPI.Request.servervariable (...) end ---------------------------------------------------------------------------- -- Primitive error output function -- @param msg String (or number) with the message. -- @param level String with the error level (optional). ---------------------------------------------------------------------------- function M.errorlog (msg, level) local t = type(msg) if t == "string" or t == "number" then SAPI.Response.errorlog (msg, level) else error ("bad argument #1 to `cgilua.errorlog' (string expected, got "..t..")", 2) end end ---------------------------------------------------------------------------- -- Converts all its arguments to strings before sending them to the server. ---------------------------------------------------------------------------- function M.print (...) local args = { ... } for i = 1, select("#",...) do args[i] = tostring(args[i]) end SAPI.Response.write (concat(args,"\t")) SAPI.Response.write ("\n") end ---------------------------------------------------------------------------- -- Function 'put' sends its arguments (basically strings of HTML text) -- to the server -- Its basic implementation is to use Lua function 'write', which writes -- each of its arguments (strings or numbers) to file _OUTPUT (a file -- handle initialized with the file descriptor for stdout) -- @name put -- @class function -- @param s String (or number) with output. ---------------------------------------------------------------------------- function M.put (...) return SAPI.Response.write (...) end -- Returns the current errorhandler function M._geterrorhandler(msg) return _errorhandler(msg) end ---------------------------------------------------------------------------- -- Executes a function using the CGILua error handler. -- @param f Function to be called. ---------------------------------------------------------------------------- function M.pcall (f) local results = {xpcall (f, _errorhandler)} local ok = results[1] tremove(results, 1) if ok then if #results == 0 then results = { true } end return unpack(results) else _erroroutput (unpack(results)) end end local function buildscriptenv() local env = { cgilua = M, print = M.print, write = M.put } setmetatable(env, { __index = _G, __newindex = _G }) return env end ---------------------------------------------------------------------------- -- Execute a script -- If an error is found, Lua's error handler is called and this function -- does not return -- @param filename String with the name of the file to be processed. -- @return The result of the execution of the file. ---------------------------------------------------------------------------- function M.doscript (filename) local env = buildscriptenv() local f, err = loadfile(filename, "bt", env) if not f then error (format ("Cannot execute `%s'. Exiting.\n%s", filename, err)) else return M.pcall(f) end end ---------------------------------------------------------------------------- -- Execute the file if there is no "file error". -- If an error is found, and it is not a "file error", Lua 'error' -- is called and this function does not return -- @param filename String with the name of the file to be processed. -- @return The result of the execution of the file or nil (in case the -- file does not exists or if it cannot be opened). -- @return It could return an error message if the file cannot be opened. ---------------------------------------------------------------------------- function M.doif (filename) if not filename then return end -- no file local f, err = _open(filename) if not f then return nil, err end -- no file (or unreadable file) f:close() return M.doscript (filename) end --------------------------------------------------------------------------- -- Set the maximum "total" input size allowed (in bytes) -- @param nbytes Number of the maximum size (in bytes) of the whole POST data. --------------------------------------------------------------------------- function M.setmaxinput(nbytes) _maxinput = nbytes end --------------------------------------------------------------------------- -- Set the maximum size for an "uploaded" file (in bytes) -- Might be less or equal than _maxinput. -- @param nbytes Number of the maximum size (in bytes) of a file. --------------------------------------------------------------------------- function M.setmaxfilesize(nbytes) _maxfilesize = nbytes end -- Default path for temporary files M.tmp_path = CGILUA_TMP or getenv("TEMP") or getenv ("TMP") or "/tmp" -- Default function for temporary names -- @returns a temporay name using os.tmpname function M.tmpname () local tempname = os_tmpname() -- Lua os.tmpname returns a full path in Unix, but not in Windows -- so we strip the eventual prefix tempname = gsub(tempname, "(/tmp/)", "") return tempname end local _tmpfiles = {} --------------------------------------------------------------------------- -- Returns a temporary file in a directory using a name generator -- @param dir Base directory for the temporary file -- @param namefunction Name generator function --------------------------------------------------------------------------- function M.tmpfile(dir, namefunction) dir = dir or M.tmp_path namefunction = namefunction or M.tmpname local tempname = namefunction() local filename = dir.."/"..tempname local file, err = _open(filename, "w+b") if file then tinsert(_tmpfiles, {name = filename, file = file}) end return file, err end ---------------------------------------------------------------------------- -- Preprocess the content of a mixed HTML file and output a complete -- HTML document ( a 'Content-type' header is inserted before the -- preprocessed HTML ) -- @param filename String with the name of the file to be processed. -- @param env Optional environment ---------------------------------------------------------------------------- function M.handlelp (filename, env) env = env or buildscriptenv() M.htmlheader () lp.include (filename, env) end ---------------------------------------------------------------------------- -- Builds a handler that sends a header and the contents of the given file. -- Sends the contents of the file to the output without processing it. -- @param type String with the type of the header. -- @param subtype String with the subtype of the header. -- @return Function (which receives a filename as argument) that produces -- the header and copies the content of the given file. ---------------------------------------------------------------------------- function M.buildplainhandler (type, subtype) return function (filename) local fh, err = _open (filename, "rb") local contents = "" if fh then contents = fh:read("*a") fh:close() else error(err) end M.header("Content-Lenght", #contents) M.contentheader (type, subtype) M.put (contents) end end ---------------------------------------------------------------------------- -- Builds a handler that sends a header and the processed file. -- Processes the file as a Lua Page. -- @param type String with the type of the header. -- @param subtype String with the subtype of the header. -- @return Function (which receives a filename as argument) that produces -- the header and processes the given file. ---------------------------------------------------------------------------- function M.buildprocesshandler (type, subtype) return function (filename) local env = buildscriptenv() M.contentheader (type, subtype) lp.include (filename, env) end end ---------------------------------------------------------------------------- -- Builds the default handler table from cgilua.mime ---------------------------------------------------------------------------- local function buildhandlers() local mime = require "cgilua.mime" for ext, mediatype in pairs(mime) do local t, st = match(mediatype, "([^/]*)/([^/]*)") M.addscripthandler(ext, M.buildplainhandler(t, st)) end end ---------------------------------------------------------------------------- -- Create an URL path to be used as a link to a CGILua script -- @param script String with the name of the script. -- @param args Table with arguments to script (optional). -- @return String in URL format. ---------------------------------------------------------------------------- function M.mkurlpath (script, args) -- URL-encode the parameters to be passed do the script local params = "" if args then params = "?"..urlcode.encodetable(args) end if strsub(script,1,1) == '/' or M.script_vdir == '/' then return script .. params else return M.script_vdir .. script .. params end end ---------------------------------------------------------------------------- -- Create an absolute URL containing the given URL path -- @param path String with the path. -- @param protocol String with the name of the protocol (default = "http"). -- @return String in URL format. ---------------------------------------------------------------------------- function M.mkabsoluteurl (path, protocol) protocol = protocol or "http" if path:sub(1,1) ~= '/' then path = '/'..path end return format("%s://%s:%s%s", protocol, M.servervariable"SERVER_NAME", M.servervariable"SERVER_PORT", path) end ---------------------------------------------------------------------------- -- Extract the "directory" and "file" parts of a path -- @param path String with a path. -- @return String with the directory part. -- @return String with the file part. ---------------------------------------------------------------------------- function M.splitonlast (path, sep) local dir,file = match(path,"^(.-)([^:/\\]*)$") return dir,file end M.splitpath = M.splitonlast -- compatibility with previous versions ---------------------------------------------------------------------------- -- Extracts the first and remaining parts of a path -- @param path separator (defaults to "/") -- @return String with the extracted part. -- @return String with the remaining path. ---------------------------------------------------------------------------- function M.splitonfirst(path, sep) local first, rest = match(path, "^/([^:/\\]*)(.*)") return first, rest end -- -- Define variables and build the cgilua.POST, cgilua.GET tables. -- local function getparams () local requestmethod = M.servervariable"REQUEST_METHOD" -- Fill in the POST table. M.POST = {} if requestmethod == "POST" then M.post.parsedata { read = SAPI.Request.getpostdata, discardinput = ap and ap.discard_request_body, content_type = M.servervariable"CONTENT_TYPE", content_length = M.servervariable"CONTENT_LENGTH", maxinput = _maxinput, maxfilesize = _maxfilesize, args = M.POST, } end -- Fill in the QUERY table. M.QUERY = {} urlcode.parsequery (M.servervariable"QUERY_STRING", M.QUERY) end -- -- Stores all script handlers and the file extensions used to identify -- them. Loads the default local _script_handlers = {} -- -- Default handler. -- Sends the contents of the file to the output without processing it. -- This relies in the browser being able to discover the content type -- which is not reliable. -- @param filename String with the name of the file. -- local function default_handler (filename) local fh, err = _open (filename, "rb") local contents if fh then contents = fh:read("*a") fh:close() else error(err) end M.header("Content-Lenght", #contents) M.put ("\n") M.put (contents) end ---------------------------------------------------------------------------- -- Add a script handler. -- @param file_extension String with the lower-case extension of the script. -- @param func Function to handle this kind of scripts. ---------------------------------------------------------------------------- function M.addscripthandler (file_extension, func) assert (type(file_extension) == "string", "File extension must be a string") if strfind (file_extension, '%.', 1) then file_extension = strsub (file_extension, 2) end file_extension = strlower(file_extension) assert (type(func) == "function", "Handler must be a function") _script_handlers[file_extension] = func end --------------------------------------------------------------------------- -- Obtains the handler corresponding to the given script path. -- @param path String with a script path. -- @return Function that handles it or nil. ---------------------------------------------------------------------------- function M.getscripthandler (path) local i,f, ext = strfind (path, "%.([^.]+)$") return _script_handlers[strlower(ext or '')] end --------------------------------------------------------------------------- -- Execute the given path with the corresponding handler. -- @param path String with a script path. -- @return The returned values from the script. --------------------------------------------------------------------------- function M.handle (path) local h = M.getscripthandler (path) or default_handler return h (path) end --------------------------------------------------------------------------- -- Sets "errorhandler" function -- This function is called by Lua when an error occurs. -- It receives the error message generated by Lua and it is resposible -- for the final message which should be returned. -- @param Function. --------------------------------------------------------------------------- function M.seterrorhandler (f) local tf = type(f) if tf == "function" then _errorhandler = f else error (format ("Invalid type: expected `function', got `%s'", tf)) end end --------------------------------------------------------------------------- -- Defines the "erroroutput" function -- This function is called to generate the error output. -- @param Function. --------------------------------------------------------------------------- function M.seterroroutput (f) local tf = type(f) if tf == "function" then _erroroutput = f else error (format ("Invalid type: expected `function', got `%s'", tf)) end end -- -- Stores all close functions in order they are set. local _close_functions = { } --------------------------------------------------------------------------- -- Adds a function to be executed after the script. -- @param f Function to be registered. --------------------------------------------------------------------------- function M.addclosefunction (f) local tf = type(f) if tf == "function" then tinsert (_close_functions, f) else error (format ("Invalid type: expected `function', got `%s'", tf)) end end -- -- Close function. -- local function close() for i = #_close_functions, 1, -1 do _close_functions[i]() end end -- -- Stores all open functions in order they are set. local _open_functions = { } --------------------------------------------------------------------------- -- Adds a function to be executed before the script. -- @param f Function to be registered. --------------------------------------------------------------------------- function M.addopenfunction (f) local tf = type(f) if tf == "function" then tinsert (_open_functions, f) else error (format ("Invalid type: expected `function', got `%s'", tf)) end end -- -- Open function. -- Call all defined open-functions in the order they were created. -- local function open() for i = #_open_functions, 1, -1 do _open_functions[i]() end end -- -- Resets CGILua's state. -- local function reset () M.script_path = false M.script_vpath, M.pdir, M.use_executable_name, M.urlpath, M.script_vdir, M.script_pdir, M.script_file, M.authentication, M.app_name = nil, nil, nil, nil, nil, nil, nil, nil, nil _maxfilesize = _default_maxfilesize _maxinput = _default_maxinput -- Error Handling _errorhandler = _default_errorhandler _erroroutput = _default_erroroutput -- Handlers _script_handlers = {} _open_functions = {} _close_functions = {} -- clean temporary files for i, v in ipairs(_tmpfiles) do _tmpfiles[i] = nil v.file:close() local _, err = remove(v.name) if err then error(err) end end end --------------------------------------------------------------------------- -- Request processing. --------------------------------------------------------------------------- function M.main () SAPI = _G.SAPI buildhandlers() -- Default handler values M.addscripthandler ("lua", M.doscript) M.addscripthandler ("lp", M.handlelp) -- Looks for an optional loader module M.pcall (function () M.loader = require"cgilua.loader" end) -- post.lua needs to be loaded after cgilua.lua is compiled M.pcall (function () M.post = require"cgilua.post" end) if M.loader then M.loader.init() end -- Build QUERY/POST tables if not M.pcall (getparams) then return nil end local result -- Executes the optional loader module if M.loader then M.loader.run() end -- Changing curent directory to the script's "physical" dir local curr_dir = lfs.currentdir () M.pcall (function () lfs.chdir (M.script_pdir) end) -- Opening functions M.pcall (open) -- Executes the script result, err = M.pcall (function () return M.handle (M.script_file) end) -- Closing functions M.pcall (close) -- Changing to original directory M.pcall (function () lfs.chdir (curr_dir) end) -- Cleanup reset () if result then -- script executed ok! return result end end return M lua-cgi-5.2~alpha2/src/cgilua/cookies.lua000077500000000000000000000061411220116477200203700ustar00rootroot00000000000000---------------------------------------------------------------------------- -- Cookies Library -- -- @release $Id: cookies.lua,v 1.8 2008/04/24 13:42:04 mascarenhas Exp $ ---------------------------------------------------------------------------- local cgilua = require"cgilua" local os = require"os" local string = require"string" local urlcode = require"cgilua.urlcode" local error = error local format, gsub, strfind = string.format, string.gsub, string.find local date = os.date local escape, unescape = urlcode.escape, urlcode.unescape local header = SAPI.Response.header local write = SAPI.Response.write local servervariable = SAPI.Request.servervariable local M = {} local function optional (what, name) if name ~= nil and name ~= "" then return format("; %s=%s", what, name) else return "" end end local function build (name, value, options) if not name or not value then error("cookie needs a name and a value") end local cookie = name .. "=" .. escape(value) options = options or {} if options.expires then local t = date("!%A, %d-%b-%Y %H:%M:%S GMT", options.expires) cookie = cookie .. optional("expires", t) end cookie = cookie .. optional("path", options.path) cookie = cookie .. optional("domain", options.domain) cookie = cookie .. optional("secure", options.secure) return cookie end ---------------------------------------------------------------------------- -- Sets a value to a cookie, with the given options. -- Generates a header "Set-Cookie", thus it can only be used in Lua Scripts. -- @param name String with the name of the cookie. -- @param value String with the value of the cookie. -- @param options Table with the options (optional). function M.set (name, value, options) header("Set-Cookie", build(name, value, options)) end ---------------------------------------------------------------------------- -- Sets a value to a cookie, with the given options. -- Generates an HTML META tag, thus it can be used in Lua Pages. -- @param name String with the name of the cookie. -- @param value String with the value of the cookie. -- @param options Table with the options (optional). function M.sethtml (name, value, options) write(format('', build(name, value, options))) end ---------------------------------------------------------------------------- -- Gets the value of a cookie. -- @param name String with the name of the cookie. -- @return String with the value associated with the cookie. function M.get (name) local cookies = servervariable"HTTP_COOKIE" or "" cookies = ";" .. cookies .. ";" cookies = gsub(cookies, "%s*;%s*", ";") -- remove extra spaces local pattern = ";" .. name .. "=(.-);" local _, __, value = strfind(cookies, pattern) return value and unescape(value) end ---------------------------------------------------------------------------- -- Deletes a cookie, by setting its value to "xxx". -- @param name String with the name of the cookie. -- @param options Table with the options (optional). function M.delete (name, options) options = options or {} options.expires = 1 M.set(name, "xxx", options) end return M lua-cgi-5.2~alpha2/src/cgilua/dispatcher.lua000077500000000000000000000042151220116477200210620ustar00rootroot00000000000000-- CGILua dispatcher module -- @release $Id: dispatcher.lua,v 1.8 2007/12/07 18:49:49 carregal Exp $ -- Checks if an URL matches a route pattern local function route_match(url, pattern) local params = {} local captures = string.gsub(pattern, "(/$[%w_-]+)", "/([^/]*)") local url_parts = {string.match(url, captures)} local i = 1 for name in string.gmatch(pattern, "/$([%w_-]+)") do params[name] = url_parts[i] i = i + 1 end return next(params) and params end local route_URLs = {} -- Maps the correct function for an URL local function route_map(url) for i, v in ipairs(route_URLs) do local pattern, f, name = unpack(v) local params = route_match(url, pattern) if params then return f, params end end end -- Returns an URL for a named route -- @param map_name Name associated with the map in the routed URL table. -- @param params Table of named parameters used in the URL map -- @param queryargs Optional table of named parameters used for the QUERY part of the URL local function route_url(map_name, params, queryargs) local queryparams = "" if queryargs then queryparams = "?"..cgilua.urlcode.encodetable(queryargs) end for i, v in ipairs(route_URLs) do local pattern, f, name = unpack(v) if name == map_name then local url = string.gsub(pattern, "$([%w_-]+)", params) url = cgilua.urlpath.."/"..cgilua.app_name..url..queryparams return url end end end -- Defines the routing using a table of URLs maps or a single map -- a map defines a URL mask using $name to extract parameters, -- a function to be called with the extracted parameters and -- a name for the map when used with route_url -- @param table of maps or a single map local function route(URLs) URLs = URLs or {} if type(URLs[1]) == "string" then -- accepts a single map as the only entry in a map table URLs = {URLs} end route_URLs = URLs f, args = route_map(cgilua.script_vpath) if f then return f(args) else error("Missing page parameters") end end return { route_url = route_url, route = route, } lua-cgi-5.2~alpha2/src/cgilua/loader.lua000077500000000000000000000064641220116477200202120ustar00rootroot00000000000000-- CGILua loader -- -- Assumes two global variables pointing to directories: -- CGILUA_CONF - CGILua configuration directory -- CGILUA_TMP - CGILua temporary files directory -- -- # $Id: loader.lua,v 1.7 2008/03/28 22:01:18 ignacio Exp $ local cgilua = require"cgilua" local lfs = require "lfs" local M = {} function M.init() -- Loads the user configuration cgilua.doif (CGILUA_CONF.."/config.lua") end function M.run() local servervariable = cgilua.servervariable cgilua.script_vpath = cgilua.script_vpath or servervariable"PATH_INFO" if cgilua.script_vpath == nil or cgilua.script_vpath == "" then cgilua.script_vpath = "/" end local document_root = cgilua.pdir or servervariable"DOCUMENT_ROOT" if not cgilua.script_path then if CGILUA_ISDIRECT then -- the launcher is associated with scripts (Xavante, mod_lua or isapi usually) if servervariable"PATH_TRANSLATED" ~= "" then cgilua.script_path = servervariable"PATH_TRANSLATED" else cgilua.script_path = servervariable"SCRIPT_FILENAME" end else -- the launcher executable is present in the URL (CGI or FastCGI only) if document_root == nil or document_root == "" then -- tries to obtain documents_root from the server local path_info = cgilua.script_vpath if path_info == nil or path_info == "" or path_info == "/" then document_root = cgilua.pdir or servervariable"PATH_TRANSLATED" else if string.find(servervariable("SERVER_SOFTWARE"), "IIS") then path_info = string.gsub(path_info, "/", "\\") end document_root = cgilua.pdir or string.gsub(servervariable"PATH_TRANSLATED", path_info, "") end end if cgilua.use_executable_name then -- looks for a Lua script with the same name as the executable local _, name = cgilua.splitpath(servervariable"SCRIPT_NAME") name = string.gsub(name, "%.[^%.]-$","") if name and lfs.attributes(document_root.."/"..name..".lua") then cgilua.script_path = document_root.."/"..name..".lua" end else -- uses /index.lua then /index.lp as the default script if cgilua.script_vpath == "/" then if lfs.attributes(document_root.."/index.lua") then cgilua.script_vpath = "/index.lua" elseif lfs.attributes(document_root.."/index.lp") then cgilua.script_vpath = "/index.lp" else error("Kepler is correctly configured, but you didn't provide a script!") end end -- checks if PATH_INFO refers to a valid file and ajusts the settings accordingly local filepath, path_info = string.match (cgilua.script_vpath, "^([^%.]-%.[^/]+)(.*)") if filepath and lfs.attributes(document_root..filepath) then -- if one is found use it cgilua.script_path = document_root..filepath cgilua.script_vpath = path_info cgilua.urlpath = cgilua.urlpath or servervariable"SCRIPT_NAME"..filepath else -- otherwise go with the current PATH_INFO cgilua.script_path = document_root..cgilua.script_vpath end end end end -- define other cgilua vars so mkurlpath can work correctly if cgilua.script_vpath then cgilua.script_vdir = cgilua.splitpath (cgilua.script_vpath) cgilua.urlpath = cgilua.urlpath or servervariable"SCRIPT_NAME" else cgilua.script_vdir = cgilua.splitpath (servervariable"SCRIPT_NAME") cgilua.urlpath = cgilua.urlpath or "" end cgilua.script_pdir, cgilua.script_file = cgilua.splitpath (cgilua.script_path) end return M lua-cgi-5.2~alpha2/src/cgilua/lp.lua000077500000000000000000000107151220116477200173510ustar00rootroot00000000000000---------------------------------------------------------------------------- -- Lua Pages Template Preprocessor. -- -- @release $Id: lp.lua,v 1.15 2008/12/11 17:40:24 mascarenhas Exp $ ---------------------------------------------------------------------------- local assert, error, loadstring = assert, error, loadstring local find, format, gsub, strsub, char = string.find, string.format, string.gsub, string.sub, string.char local concat, tinsert = table.concat, table.insert local open = io.open local M = {} ---------------------------------------------------------------------------- -- function to do output local outfunc = "io.write" -- accepts the old expression field: `$| |$' local compatmode = true -- -- Builds a piece of Lua code which outputs the (part of the) given string. -- @param s String. -- @param i Number with the initial position in the string. -- @param f Number with the final position in the string (default == -1). -- @return String with the correspondent Lua code which outputs the part of the string. -- local function out (s, i, f) s = strsub(s, i, f or -1) if s == "" then return s end -- we could use `%q' here, but this way we have better control s = gsub(s, "([\\\n\'])", "\\%1") -- substitute '\r' by '\'+'r' and let `loadstring' reconstruct it s = gsub(s, "\r", "\\r") return format(" %s('%s'); ", outfunc, s) end ---------------------------------------------------------------------------- -- Translate the template to Lua code. -- @param s String to translate. -- @return String with translated code. ---------------------------------------------------------------------------- function M.translate (s) s = gsub(s, "^#![^\n]+\n", "") if compatmode then s = gsub(s, "$|(.-)|%$", "") s = gsub(s, "", "") end s = gsub(s, "<%%(.-)%%>", "") local res = {} local start = 1 -- start of untranslated part in `s' while true do local ip, fp, target, exp, code = find(s, "<%?(%w*)[ \t]*(=?)(.-)%?>", start) if not ip then break end tinsert(res, out(s, start, ip-1)) if target ~= "" and target ~= "lua" then -- not for Lua; pass whole instruction to the output tinsert(res, out(s, ip, fp)) else if exp == "=" then -- expression? tinsert(res, format(" %s(%s);", outfunc, code)) else -- command tinsert(res, format(" %s ", code)) end end start = fp + 1 end tinsert(res, out(s, start)) return concat(res) end ---------------------------------------------------------------------------- -- Defines the name of the output function. -- @param f String with the name of the function which produces output. function M.setoutfunc (f) outfunc = f end ---------------------------------------------------------------------------- -- Turns on or off the compatibility with old CGILua 3.X behavior. -- @param c Boolean indicating if the compatibility mode should be used. function M.setcompatmode (c) compatmode = c end ---------------------------------------------------------------------------- -- Internal compilation cache. local cache = {} ---------------------------------------------------------------------------- -- Translates a template into a Lua function. -- Does NOT execute the resulting function. -- Uses a cache of templates. -- @param string String with the template to be translated. -- @param chunkname String with the name of the chunk, for debugging purposes. -- @param env Table with the environment of the resulting function (optional). -- @return Function with the resulting translation. function M.compile (string, chunkname, env) local s, err = cache[string] if not s then s = M.translate (string) cache[string] = s end f, err = load (s, chunkname, "bt", env) if not f then error (err, 3) end return f end ---------------------------------------------------------------------------- -- Translates and executes a template in a given file. -- The translation creates a Lua function which will be executed in an -- optionally given environment. -- @param filename String with the name of the file containing the template. -- @param env Table with the environment to run the resulting function. local BOM = char(239) .. char(187) .. char(191) function M.include (filename, env) -- read the whole contents of the file local fh = assert (open (filename)) local src = fh:read("*a") fh:close() if src:sub(1,3) == BOM then src = src:sub(4) end -- translates the file into a function local prog = M.compile (src, '@'..filename, env) prog () end return M lua-cgi-5.2~alpha2/src/cgilua/mime.lua000077500000000000000000000124551220116477200176700ustar00rootroot00000000000000----------------------------------------------------------------------------- -- Xavante MIME types -- -- Authors: Javier Guerra and Andre Carregal -- Copyright (c) 2004-2007 Kepler Project -- -- $Id: mime.lua,v 1.1 2007/09/25 23:17:56 carregal Exp $ ----------------------------------------------------------------------------- -- Extracted from Apache's mime.types -- This file controls what Internet media types are sent to the client for -- given file extension(s). Sending the correct media type to the client -- is important so they know how to handle the content of the file. -- Extra types can either be added here or by using an AddType directive -- in your config files. For more information about Internet media types, -- please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type -- registry is at . return { ez = "application/andrew-inset", atom = "application/atom+xml", hqx = "application/mac-binhex40", cpt = "application/mac-compactpro", mathml = "application/mathml+xml", doc = "application/msword", bin = "application/octet-stream", dms = "application/octet-stream", lha = "application/octet-stream", lzh = "application/octet-stream", exe = "application/octet-stream", class = "application/octet-stream", so = "application/octet-stream", dll = "application/octet-stream", dmg = "application/octet-stream", oda = "application/oda", ogg = "application/ogg", pdf = "application/pdf", ai = "application/postscript", eps = "application/postscript", ps = "application/postscript", rdf = "application/rdf+xml", smi = "application/smil", smil = "application/smil", gram = "application/srgs", grxml = "application/srgs+xml", mif = "application/vnd.mif", xul = "application/vnd.mozilla.xul+xml", xls = "application/vnd.ms-excel", ppt = "application/vnd.ms-powerpoint", rm = "application/vnd.rn-realmedia", wbxml = "application/vnd.wap.wbxml", wmlc = "application/vnd.wap.wmlc", wmlsc = "application/vnd.wap.wmlscriptc", vxml = "application/voicexml+xml", bcpio = "application/x-bcpio", vcd = "application/x-cdlink", pgn = "application/x-chess-pgn", cpio = "application/x-cpio", csh = "application/x-csh", dcr = "application/x-director", dir = "application/x-director", dxr = "application/x-director", dvi = "application/x-dvi", spl = "application/x-futuresplash", gtar = "application/x-gtar", hdf = "application/x-hdf", xhtml = "application/xhtml+xml", xht = "application/xhtml+xml", js = "application/x-javascript", skp = "application/x-koan", skd = "application/x-koan", skt = "application/x-koan", skm = "application/x-koan", latex = "application/x-latex", xml = "application/xml", xsl = "application/xml", dtd = "application/xml-dtd", nc = "application/x-netcdf", cdf = "application/x-netcdf", sh = "application/x-sh", shar = "application/x-shar", swf = "application/x-shockwave-flash", xslt = "application/xslt+xml", sit = "application/x-stuffit", sv4cpio = "application/x-sv4cpio", sv4crc = "application/x-sv4crc", tar = "application/x-tar", tcl = "application/x-tcl", tex = "application/x-tex", texinfo = "application/x-texinfo", texi = "application/x-texinfo", t = "application/x-troff", tr = "application/x-troff", roff = "application/x-troff", man = "application/x-troff-man", me = "application/x-troff-me", ms = "application/x-troff-ms", ustar = "application/x-ustar", src = "application/x-wais-source", zip = "application/zip", au = "audio/basic", snd = "audio/basic", mid = "audio/midi", midi = "audio/midi", kar = "audio/midi", mpga = "audio/mpeg", mp2 = "audio/mpeg", mp3 = "audio/mpeg", aif = "audio/x-aiff", aiff = "audio/x-aiff", aifc = "audio/x-aiff", m3u = "audio/x-mpegurl", ram = "audio/x-pn-realaudio", ra = "audio/x-pn-realaudio", wav = "audio/x-wav", pdb = "chemical/x-pdb", xyz = "chemical/x-xyz", bmp = "image/bmp", cgm = "image/cgm", gif = "image/gif", ief = "image/ief", jpeg = "image/jpeg", jpg = "image/jpeg", jpe = "image/jpeg", png = "image/png", svg = "image/svg+xml", svgz = "image/svg+xml", tiff = "image/tiff", tif = "image/tiff", djvu = "image/vnd.djvu", djv = "image/vnd.djvu", wbmp = "image/vnd.wap.wbmp", ras = "image/x-cmu-raster", ico = "image/x-icon", pnm = "image/x-portable-anymap", pbm = "image/x-portable-bitmap", pgm = "image/x-portable-graymap", ppm = "image/x-portable-pixmap", rgb = "image/x-rgb", xbm = "image/x-xbitmap", xpm = "image/x-xpixmap", xwd = "image/x-xwindowdump", igs = "model/iges", iges = "model/iges", msh = "model/mesh", mesh = "model/mesh", silo = "model/mesh", wrl = "model/vrml", vrml = "model/vrml", ics = "text/calendar", ifb = "text/calendar", css = "text/css", html = "text/html", htm = "text/html", asc = "text/plain", txt = "text/plain", rtx = "text/richtext", rtf = "text/rtf", sgml = "text/sgml", sgm = "text/sgml", tsv = "text/tab-separated-values", wml = "text/vnd.wap.wml", wmls = "text/vnd.wap.wmlscript", etx = "text/x-setext", mpeg = "video/mpeg", mpg = "video/mpeg", mpe = "video/mpeg", qt = "video/quicktime", mov = "video/quicktime", mxu = "video/vnd.mpegurl", avi = "video/x-msvideo", movie = "video/x-sgi-movie", ice = "x-conference/x-cooltalk", } lua-cgi-5.2~alpha2/src/cgilua/post.lua000077500000000000000000000227351220116477200177300ustar00rootroot00000000000000---------------------------------------------------------------------------- -- Process POST data. -- This library depends on some functions that read POST data and other -- HTTP information. A beginning is: -- require"post" -- local params = {} -- post.parsedata { -- read = ap.get_client_block or io.input, -- discardinput = ap.discard_request_body, -- content_type = ap.get_header"content-type" or os.getenv"CONTENT_TYPE", -- content_length = ap.get_header"content-length" or os.getenv"CONTENT_LENGTH", -- maxinput = 1024 * 1024, -- maxfilesize = 512 * 1024, -- args = params, -- } -- -- @release $Id: post.lua,v 1.17 2008/04/03 21:55:28 mascarenhas Exp $ ---------------------------------------------------------------------------- local iterate = require"cgilua.readuntil".iterate local urlcode = require"cgilua.urlcode" local tmpfile = require"cgilua".tmpfile local assert, error, pairs, tonumber, tostring, type = assert, error, pairs, tonumber, tostring, type local getn, tinsert = table.getn, table.insert local format, gsub, strfind, strlower, strlen = string.format, string.gsub, string.find, string.lower, string.len local min = math.min --local iterate = cgilua.readuntil.iterate --local urlcode = cgilua.urlcode --local tmpfile = cgilua.tmpfile -- environment for processing multipart/form-data input local boundary = nil -- boundary string that separates each 'part' of input local maxfilesize = nil -- maximum size for file upload local maxinput = nil -- maximum size of total POST data local inputfile = nil -- temporary file for inputting form-data local bytesleft = nil -- number of bytes yet to be read local content_type = nil -- request's content-type -- local functions local discardinput = nil -- discard all remaining input local readuntil = nil -- read until delimiter local read = nil -- basic read function -- -- Extract the boundary string from CONTENT_TYPE metavariable -- local function getboundary () local _,_,boundary = strfind (content_type, "boundary%=(.-)$") return "--"..boundary end -- -- Create a table containing the headers of a multipart/form-data field -- local function breakheaders (hdrdata) local headers = {} gsub (hdrdata, '([^%c%s:]+):%s+([^\n]+)', function(type,val) type = strlower(type) headers[type] = val end) return headers end -- -- Read the headers of the next multipart/form-data field -- -- This function returns a table containing the headers values. Each header -- value is indexed by the corresponding header "type". -- If end of input is reached (no more fields to process) it returns nil. -- local function readfieldheaders () local EOH = "\r\n\r\n" -- local hdrdata = "" local out = function (str) hdrdata = hdrdata..str end if readuntil (EOH, out) then -- parse headers return breakheaders (hdrdata) else -- no header found return nil end end -- -- Extract a field name (and possible filename) from its disposition header -- local function getfieldnames (headers) local disposition_hdr = headers["content-disposition"] local attrs = {} if disposition_hdr then gsub(disposition_hdr, ';%s*([^%s=]+)="(.-)"', function(attr, val) attrs[attr] = val end) else error("Error processing multipart/form-data.".. "\nMissing content-disposition header") end return attrs.name, attrs.filename end -- -- Read the contents of a 'regular' field to a string -- local function readfieldcontents () local value = "" local boundaryline = "\r\n"..boundary local out = function (str) value = value..str end if readuntil (boundaryline, out) then return value else error("Error processing multipart/form-data.\nUnexpected end of input\n") end end -- -- Read the contents of a 'file' field to a temporary file (file upload) -- local function fileupload (filename) -- create a temporary file for uploading the file field local file, err = tmpfile() if file == nil then discardinput(bytesleft) error("Cannot create a temporary file.\n"..err) end local bytesread = 0 local boundaryline = "\r\n"..boundary local out = function (str) local sl = strlen (str) if bytesread + sl > maxfilesize then discardinput (bytesleft) error (format ("Maximum file size (%d kbytes) exceeded while uploading `%s'", maxfilesize / 1024, filename)) end file:write (str) bytesread = bytesread + sl end if readuntil (boundaryline, out) then file:seek ("set", 0) return file, bytesread else error (format ("Error processing multipart/form-data.\nUnexpected end of input while uploading %s", filename)) end end -- -- Compose a file field 'value' -- local function filevalue (filehandle, filename, filesize, headers) -- the temporary file handle local value = { file = filehandle, filename = filename, filesize = filesize } -- copy additional header values for hdr, hdrval in pairs(headers) do if hdr ~= "content-disposition" then value[hdr] = hdrval end end return value end -- -- Process multipart/form-data -- -- This function receives the total size of the incoming multipart/form-data, -- the maximum size for a file upload, and a reference to a table where the -- form fields should be stored. -- -- For every field in the incoming form-data a (name=value) pair is -- inserted into the given table. [[name]] is the field name extracted -- from the content-disposition header. -- -- If a field is of type 'file' (i.e., a 'filename' attribute was found -- in its content-disposition header) a temporary file is created -- and the field contents are written to it. In this case, -- [[value]] has a table that contains the temporary file handle -- (key 'file') and the file name (key 'filename'). Optional headers -- included in the field description are also inserted into this table, -- as (header_type=value) pairs. -- -- If the field is not of type 'file', [[value]] contains the field -- contents. -- local function Main (inputsize, args) -- create a temporary file for processing input data local inputf,err = tmpfile() if inputf == nil then discardinput(inputsize) error("Cannot create a temporary file.\n"..err) end -- set the environment for processing the multipart/form-data inputfile = inputf bytesleft = inputsize maxfilesize = maxfilesize or inputsize boundary = getboundary() while true do -- read the next field header(s) local headers = readfieldheaders() if not headers then break end -- end of input -- get the name attributes for the form field (name and filename) local name, filename = getfieldnames(headers) -- get the field contents local value if filename then local filehandle, filesize = fileupload(filename) value = filevalue(filehandle, filename, filesize, headers) else value = readfieldcontents() end -- insert the form field into table [[args]] urlcode.insertfield(args, name, value) end end -- -- Initialize the library by setting the dependent functions: -- content_type = value of "Content-type" header -- content_length = value of "Content-length" header -- read = function that can read POST data -- discardinput (optional) = function that discard POST data -- maxinput (optional) = limit of POST data (in bytes) -- maxfilesize (optional) = limit of uploaded file(s) (in bytes) -- local function init (defs) assert (defs.read) read = defs.read readuntil = iterate (function () if bytesleft then if bytesleft <= 0 then return nil end local n = min (bytesleft, 2^13) -- 2^13 == 8192 local bytes = read (n) bytesleft = bytesleft - #bytes return bytes end end) if defs.discard_function then discardinput = defs.discardinput else discardinput = function (inputsize) readuntil ('\0', function()end) end end content_type = defs.content_type if defs.maxinput then maxinput = defs.maxinput end if defs.maxfilesize then maxfilesize = defs.maxfilesize end end ---------------------------------------------------------------------------- -- Parse the POST REQUEST incoming data according to its "content type" -- as defined by the metavariable CONTENT_TYPE (RFC CGI) -- -- An error is issued if the "total" size of the incoming data -- (defined by the metavariable CONTENT_LENGTH) exceeds the -- maximum input size allowed ---------------------------------------------------------------------------- return { parsedata = function (defs) assert (type(defs.args) == "table", "field `args' must be a table") init (defs) -- get the "total" size of the incoming data local inputsize = tonumber(defs.content_length) or 0 if inputsize > maxinput then -- some Web Servers (like IIS) require that all the incoming data is read bytesleft = inputsize discardinput(inputsize) error(format("Total size of incoming data (%d KB) exceeds configured maximum (%d KB)", inputsize /1024, maxinput / 1024)) end -- process the incoming data according to its content type local contenttype = content_type if not contenttype then error("Undefined Media Type") end if strfind(contenttype, "x-www-form-urlencoded", 1, true) then urlcode.parsequery (read (inputsize), defs.args) elseif strfind(contenttype, "multipart/form-data", 1, true) then Main (inputsize, defs.args) elseif strfind (contenttype, "application/xml", 1, true) or strfind (contenttype, "text/xml", 1, true) or strfind (contenttype, "text/plain", 1, true) then tinsert (defs.args, read (inputsize)) else error("Unsupported Media Type: "..contenttype) end end, } lua-cgi-5.2~alpha2/src/cgilua/readuntil.lua000077500000000000000000000027411220116477200207250ustar00rootroot00000000000000---------------------------------------------------------------------------- -- Reads an input until a given character. -- -- @release $Id: readuntil.lua,v 1.5 2007/04/16 14:01:32 tomas Exp $ ---------------------------------------------------------------------------- local strsub, strfind, strlen = string.sub, string.find, string.len ---------------------------------------------------------------------------- -- Creates a function which reads an input until a given character. -- @param inp Function which reads the input. -- @return Function which receives a delimiter character and an output -- function. ---------------------------------------------------------------------------- return { iterate = function (inp) local current = "" return function (del, out) local dellen = strlen(del) local i, e while true do i, e = strfind(current, del, 1, 1) if i then break end local new = inp() if not new then break end do -- handle borders local endcurrent = strsub(current, -dellen+1) local border = endcurrent .. strsub(new, 1, dellen-1) if strlen(current) < dellen or strlen(new) < dellen or strfind(border, del, 1, 1) then -- move last part of `current' to new block current = strsub(current, 1, -dellen) new = endcurrent .. new end end out(current) current = new end out(strsub(current, 1, (i or 0) - 1)) current = strsub(current, (e or strlen(current)) + 1) return (i ~= nil) end end, } lua-cgi-5.2~alpha2/src/cgilua/serialize.lua000077500000000000000000000057031220116477200207260ustar00rootroot00000000000000---------------------------------------------------------------------------- -- Serialize tables. -- It works only for tables without cycles and without functions or -- userdata inside it. -- @release $Id: serialize.lua,v 1.7 2007/04/16 14:01:32 tomas Exp $ ---------------------------------------------------------------------------- local ipairs, pairs, type = ipairs, pairs, type local format = string.format local sort, tinsert = table.sort, table.insert -- local value = nil ---------------------------------------------------------------------------- -- Serializes a table. -- @param tab Table representing the session. -- @param outf Function used to generate the output. -- @param ind String with indentation pattern (default = ""). -- @param pre String with indentation prefix (default = ""). ---------------------------------------------------------------------------- local function tabledump (tab, outf, ind, pre) local sep_n, sep, _n = ",\n", ", ", "\n" if (not ind) or (ind == "") then ind = ""; sep_n = ", "; _n = "" end if not pre then pre = "" end outf ("{") local p = pre..ind -- prepare list of keys local keys = { boolean = {}, number = {}, string = {} } local total = 0 for key in pairs (tab) do total = total + 1 local t = type(key) if t == "string" then tinsert (keys.string, key) else keys[t][key] = true end end local many = total > 5 if not many then sep_n = sep; _n = " " end outf (_n) -- serialize entries with numeric keys if many then local _f,_s,_v = ipairs(tab) if _f(_s,_v) then outf (p) end end local num = keys.number local ok = false -- entries with automatic index for key, val in ipairs (tab) do value (val, outf, ind, p) outf (sep) num[key] = nil ok = true end if ok and many then outf (_n) end -- entries with explicit index for key in pairs (num) do if many then outf (p) end outf ("[") outf (key) outf ("] = ") value (tab[key], outf, ind, p) outf (sep_n) end -- serialize entries with boolean keys local tr = keys.boolean[true] if tr then outf (format ("%s[true] = ", many and p or '')) value (tab[true], outf, ind, p) outf (sep_n) end local fa = keys.boolean[false] if fa then outf (format ("%s[false] = ", many and p or '')) value (tab[false], outf, ind, p) outf (sep_n) end -- serialize entries with string keys sort (keys.string) for _, key in ipairs (keys.string) do outf (format ("%s[%q] = ", many and p or '', key)) value (tab[key], outf, ind, p) outf (sep_n) end if many then outf (pre) end outf ("}") end -- -- Serializes a value. -- value = function (v, outf, ind, pre) local t = type (v) if t == "string" then outf (format ("%q", v)) elseif t == "number" then outf (tostring(v)) elseif t == "boolean" then outf (tostring(v)) elseif t == "table" then tabledump (v, outf, ind, pre) else outf (format ("%q", tostring(v))) end end ---------------------------------------------------------------------------- return { serialize = tabledump, } lua-cgi-5.2~alpha2/src/cgilua/session.lua000077500000000000000000000163721220116477200204260ustar00rootroot00000000000000---------------------------------------------------------------------------- -- Session library. -- -- @release $Id: session.lua,v 1.29 2007/11/21 16:33:20 carregal Exp $ ---------------------------------------------------------------------------- local cgilua = require"cgilua" local lfs = require"lfs" local serialize = require"cgilua.serialize".serialize local assert, error, ipairs, loadfile, next, tostring, type = assert, error, ipairs, loadfile, next, tostring, type local format, gsub, strfind, strsub = string.format, string.gsub, string.find, string.sub local tinsert = table.insert local _open = io.open local remove, time = os.remove, os.time local mod, rand, randseed = (math.mod or math.fmod), math.random, math.randomseed local attributes, dir, mkdir = lfs.attributes, lfs.dir, lfs.mkdir local M = {} local RANGE = 999999999 local INVALID_SESSION_ID = "Invalid session identification" randseed (mod (time(), RANGE)) ---------------------------------------------------------------------------- -- Internal state variables. local root_dir = nil local timeout = 10 * 60 -- 10 minutes -- -- Checks identifier's format. -- local function check_id (id) return id and (strfind (id, "^%d+$") ~= nil) end -- -- Produces a file name based on a session. -- @param id Session identification. -- @return String with the session file name. -- local function filename (id) return format ("%s/%s.lua", root_dir, id) end ---------------------------------------------------------------------------- -- Deletes a session. -- @param id Session identification. ---------------------------------------------------------------------------- function M.delete (id) if not check_id (id) then return nil, INVALID_SESSION_ID end remove (filename (id)) end -- -- Searches for a file in the root_dir -- local function find (file) local fh = _open (root_dir.."/"..file) if fh then fh:close () return true else return false end end -- -- Creates a new identifier. -- @return New identifier. -- local function new_id () return rand (RANGE) end ---------------------------------------------------------------------------- -- Creates a new session identifier. -- @return Session identification. ---------------------------------------------------------------------------- function M.new () local id = new_id () if find (id..".lua") then randseed (mod (time(), RANGE)) repeat id = new_id (id) until not find (id..".lua") end return id end ---------------------------------------------------------------------------- -- Changes the session identificator generator. -- @param func Function. ---------------------------------------------------------------------------- function M.setidgenerator (func) if type (func) == "function" then new_id = func end end ---------------------------------------------------------------------------- -- Loads data from a session. -- @param id Session identification. -- @return Table with session data or nil in case of error. -- @return In case of error, also returns the error message. ---------------------------------------------------------------------------- function M.load (id) if not check_id (id) then return nil, INVALID_SESSION_ID end local f, err = loadfile (filename (id)) if not f then return nil, err else return f() end end ---------------------------------------------------------------------------- -- Saves data to a session. -- @param id Session identification. -- @param data Table with session data to be saved. ---------------------------------------------------------------------------- function M.save (id, data) if not check_id (id) then return nil, INVALID_SESSION_ID end local fh = assert (_open (filename (id), "w+")) fh:write "return " serialize (data, function (s) fh:write(s) end) fh:close() end ---------------------------------------------------------------------------- -- Removes expired sessions. ---------------------------------------------------------------------------- function M.cleanup () local rem = {} local now = time () for file in dir (root_dir) do local attr = attributes(root_dir.."/"..file) if attr and attr.mode == 'file' then if attr.modification + timeout < now then tinsert (rem, file) end end end for _, file in ipairs (rem) do remove (root_dir.."/"..file) end end ---------------------------------------------------------------------------- -- Changes the session timeout. -- @param t Number of seconds to maintain a session. ---------------------------------------------------------------------------- function M.setsessiontimeout (t) if type (t) == "number" then timeout = t end end ---------------------------------------------------------------------------- -- Changes the session directory. -- @param path String with the new session directory. ---------------------------------------------------------------------------- function M.setsessiondir (path) path = gsub (path, "[/\\]$", "") -- Make sure the given path is a directory if not attributes (path, "mode") then assert (mkdir (path)) end -- Make sure it can create a new file in the given directory local test_file = path.."/"..cgilua.tmpname() local fh, err = _open (test_file, "w") if not fh then error ("Could not open a file in session directory: ".. tostring(err), 2) end fh:close () remove (test_file) root_dir = path end ---------------------------------------------------------------------------- local ID_NAME = "cgilua session identification" local id = nil ---------------------------------------------------------------------------- -- Destroys the session. ---------------------------------------------------------------------------- function M.destroy () M.data = {} -- removes data from session table to avoid recreation by `close' M.delete (id) end ---------------------------------------------------------------------------- -- Open user session. -- This function should be called before the script is executed. ---------------------------------------------------------------------------- function M.open () -- Redefine cgilua.mkurlpath to manage the session identification local mkurlpath = cgilua.mkurlpath function cgilua.mkurlpath (script, data) if not data then data = {} end data[ID_NAME] = id return mkurlpath (script, data) end M.cleanup() id = cgilua.QUERY[ID_NAME] or M.new() if id then cgilua.QUERY[ID_NAME] = nil M.data = M.load (id) or {} end end ---------------------------------------------------------------------------- -- Close user session. -- This function should be called after the script is executed. ---------------------------------------------------------------------------- function M.close () if next (cgilua.session.data) then M.save (id, cgilua.session.data) id = nil end end local already_enabled = false ---------------------------------------------------------------------------- -- Enables the use of sessions. -- This function must be called by every script that needs sessions. -- It just calls the `open' function and register the `close' function -- to be called at the end of the execution. ---------------------------------------------------------------------------- function M.enablesession () if already_enabled then -- avoid misuse when a script calls another one return else already_enabled = true end M.open () cgilua.addclosefunction (M.close) end return M lua-cgi-5.2~alpha2/src/cgilua/urlcode.lua000077500000000000000000000072621220116477200203760ustar00rootroot00000000000000---------------------------------------------------------------------------- -- Utility functions for encoding/decoding of URLs. -- -- @release $Id: urlcode.lua,v 1.10 2008/01/21 16:11:32 carregal Exp $ ---------------------------------------------------------------------------- local ipairs, next, pairs, tonumber, type = ipairs, next, pairs, tonumber, type local string = require"string" local gsub = string.gsub local strbyte, strchar, strformat, strsub = string.byte, string.char, string.format, string.sub local tinsert = require"table".insert local M = {} -- Converts an hexadecimal code in the form %XX to a character local function hexcode2char (h) return strchar(tonumber(h,16)) end ---------------------------------------------------------------------------- -- Decode an URL-encoded string (see RFC 2396) ---------------------------------------------------------------------------- function M.unescape (str) str = gsub (str, "+", " ") str = gsub (str, "%%(%x%x)", hexcode2char) str = gsub (str, "\r\n", "\n") return str end -- Converts a character to an hexadecimal code in the form %XX local function char2hexcode (c) return strformat ("%%%02X", strbyte(c)) end ---------------------------------------------------------------------------- -- URL-encode a string (see RFC 2396) ---------------------------------------------------------------------------- function M.escape (str) str = gsub (str, "\n", "\r\n") str = gsub (str, "([^0-9a-zA-Z ])", char2hexcode) -- locale independent str = gsub (str, " ", "+") return str end ---------------------------------------------------------------------------- -- Insert a (name=value) pair into table [[args]] -- @param args Table to receive the result. -- @param name Key for the table. -- @param value Value for the key. -- Multi-valued names will be represented as tables with numerical indexes -- (in the order they came). ---------------------------------------------------------------------------- function M.insertfield (args, name, value) if not args[name] then args[name] = value else local t = type (args[name]) if t == "string" then args[name] = { args[name], value, } elseif t == "table" then tinsert (args[name], value) else error ("CGILua fatal error (invalid args table)!") end end end ---------------------------------------------------------------------------- -- Parse url-encoded request data -- (the query part of the script URL or url-encoded post data) -- -- Each decoded (name=value) pair is inserted into table [[args]] -- @param query String to be parsed. -- @param args Table where to store the pairs. ---------------------------------------------------------------------------- function M.parsequery (query, args) if type(query) == "string" then local insertfield, unescape = M.insertfield, M.unescape gsub (query, "([^&=]+)=([^&=]*)&?", function (key, val) M.insertfield (args, unescape(key), unescape(val)) end) end end ---------------------------------------------------------------------------- -- URL-encode the elements of a table creating a string to be used in a -- URL for passing data/parameters to another script -- @param args Table where to extract the pairs (name=value). -- @return String with the resulting encoding. ---------------------------------------------------------------------------- function M.encodetable (args) if args == nil or next(args) == nil then -- no args or empty args? return "" end local escape = M.escape local strp = "" for key, vals in pairs(args) do if type(vals) ~= "table" then vals = {vals} end for i,val in ipairs(vals) do strp = strp.."&"..escape(key).."="..escape(val) end end -- remove first & return strsub(strp,2) end return M lua-cgi-5.2~alpha2/src/launchers/000077500000000000000000000000001220116477200167445ustar00rootroot00000000000000lua-cgi-5.2~alpha2/src/launchers/cgilua.cgi000077500000000000000000000010261220116477200206760ustar00rootroot00000000000000#!/usr/bin/env lua -- CGILua (SAPI) launcher, extracts script to launch -- either from the command line (use #!cgilua in the script) -- or from SCRIPT_FILENAME/PATH_TRANSLATED pcall(require, "luarocks.require") local common = require "wsapi.common" local cgi = require "wsapi.cgi" local sapi = require "wsapi.sapi" local arg_filename = (...) local function sapi_loader(wsapi_env) common.normalize_paths(wsapi_env, arg_filename, "cgilua.cgi") return sapi.run(wsapi_env) end cgi.run(sapi_loader) lua-cgi-5.2~alpha2/src/launchers/cgilua.fcgi000066400000000000000000000021631220116477200210440ustar00rootroot00000000000000#!/usr/bin/env lua -- CGILua (SAPI) launcher, extracts script to launch -- either from the command line (use #!cgilua in the script) -- or from SCRIPT_FILENAME/PATH_TRANSLATED pcall(require, "luarocks.require") local common = require "wsapi.common" local ok, err = pcall(require, "wsapi.fastcgi") if not ok then io.stderr:write("WSAPI FastCGI not loaded:\n" .. err .. "\n\nPlease install wsapi-fcgi with LuaRocks\n") os.exit(1) end local ONE_HOUR = 60 * 60 local ONE_DAY = 24 * ONE_HOUR local sapi_loader = common.make_isolated_launcher{ filename = nil, -- if you want to force the launch of a single script launcher = "cgilua.fcgi", -- the name of this launcher modname = "wsapi.sapi", -- WSAPI application that processes the script reload = false, -- if you want to reload the application on every request period = ONE_HOUR, -- frequency of Lua state staleness checks ttl = ONE_DAY, -- time-to-live for Lua states vars = -- order of checking for the path of the script { "SCRIPT_FILENAME", "PATH_TRANSLATED" } } wsapi.fastcgi.run(sapi_loader) lua-cgi-5.2~alpha2/tests/000077500000000000000000000000001220116477200153335ustar00rootroot00000000000000lua-cgi-5.2~alpha2/tests/Makefile000077500000000000000000000005041220116477200167750ustar00rootroot00000000000000# $Id: Makefile,v 1.5 2004/11/08 16:39:51 tomas Exp $ T= test include ../config V= 1.0a #DIST_DIR=../$(PKG)/$T SRCS= test_main.html test_main.lua test_main.lp test_cookies.lua test_cookies.lp clean cgi fcgi mod: cgiinstall fcgiinstall modinstall: dist dist_dir: mkdir -p $(DIST_DIR) cp $(SRCS) Makefile $(DIST_DIR) lua-cgi-5.2~alpha2/tests/download.lua000077500000000000000000000030161220116477200176500ustar00rootroot00000000000000#!/usr/local/bin/lua require"luasocket" function receive (connection) connection:settimeout(0) local s, status = connection:receive (2^10) if status == "timeout" then coroutine.yield (connection) end return s, status end function download (host, file, outfile) --local f = assert (io.open (outfile, "w")) local c = assert (socket.connect (host, 80)) c:send ("GET "..file.." HTTP/1.0\r\n\r\n") while true do local s, status = receive (c) --f:write (s) if status == "closed" then break end end c:close() --f:close() end local threads = {} function get (host, file, outfile) print (string.format ("Downloading %s from %s to %s", file, host, outfile)) local co = coroutine.create (function () return download (host, file, outfile) end) table.insert (threads, co) end function dispatcher () while true do local n = table.getn (threads) if n == 0 then break end local connections = {} for i = 1, n do local status, res = coroutine.resume (threads[i]) if not res then table.remove (threads, i) break else table.insert (connections, res) end end if table.getn (connections) == n then socket.select (connections) end end end local url = arg[1] if not url then print (string.format ("usage: %s url [times]", arg[0])) os.exit() end local times = arg[2] or 5 url = string.gsub (url, "^http.?://", "") local _, _, host, file = string.find (url, "^([^/]+)(/.*)") local _, _, fn = string.find (file, "([^/]+)$") for i = 1, times do get (host, file, fn..i) end dispatcher () lua-cgi-5.2~alpha2/tests/env.lua000077500000000000000000000013331220116477200166310ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi -- This file should be executed before any script in this directory -- according to the configuration (cgilua/conf.lua). pcall (cgilua.enablesession) local put, mkurlpath = cgilua.put, cgilua.mkurlpath cgilua.addclosefunction (function () put [[

Main]] for _, test in ipairs{ { "Get", "test_main.lua", {ab = "cd", ef = "gh"} }, { "Cookies", "test_cookies.lua", }, { "FileSystem", "test_fs.lua", }, { "Libraries", "test_lib.lua", }, { "Session", "test_session.lua", }, { "Variables", "test_variables.lp", }, } do put (string.format (' · %s', mkurlpath (test[2], test[3]), test[1])) end put [[ ]] end) lua-cgi-5.2~alpha2/tests/overview.lp000077500000000000000000000034031220116477200175410ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi CGILua installation overview

CGILua installation overview

Version Copyright Description
<%= tostring(_G[l[2]]) %>
<%= idx(p,"VERSION") %> <%= idx(p,"COPYRIGHT") %> <%= idx(p,"DESCRIPTION") %>
lua-cgi-5.2~alpha2/tests/prepara_sql2.lua000077500000000000000000000013161220116477200204350ustar00rootroot00000000000000#!/usr/local/bin/lua -- Prepara o 2o. teste de acesso ao banco de dados. -- Sao criadas duas tabelas com uma chave estrangeira ligando-as. MAX_ROWS = arg[1] or 10 require"postgres" local env = assert (luasql.postgres ()) local conn = assert (env:connect ("luasql-test", "tomas")) -- Apaga restos de outros testes. conn:execute "drop table t2" conn:execute "drop table t1" -- Criando as tabelas. assert (conn:execute [[create table t1 ( a int, b int )]]) assert (conn:execute [[create table t2 ( c int, d int )]]) -- Preenchedo as tabelas. for i = 1, MAX_ROWS do local ii = 2*i assert (conn:execute (string.format ([[ insert into t1 values (%d, %d); insert into t2 values (%d, %d);]], ii, i, ii, i))) end lua-cgi-5.2~alpha2/tests/tcgi1.lua000077500000000000000000000005631220116477200170540ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi -- $Id: tcgi1.lua,v 1.1 2004/03/25 19:31:05 tomas Exp $ io.stdout:write"Content-type: text/html\n\n" for i,v in pairs{"QUERY_STRING", } do io.stdout:write (string.format ("%s = %s", v, os.getenv(v) or ' ')) end io.stdout:write "
\n" local post_data = io.stdin:read"*a" io.stdout:write (string.format ("post_data = {%s}", post_data)) lua-cgi-5.2~alpha2/tests/test.html000077500000000000000000000042561220116477200172120ustar00rootroot00000000000000
GET:
cgi fcgi modulo
POST:
field 1:
field 2:
cgi fcgi modulo
POST (with upload):
field 1:
file:
cgi fcgi modulo
$Id: test.html,v 1.2 2004/06/07 12:04:10 tomas Exp $ lua-cgi-5.2~alpha2/tests/test_conc.lua000077500000000000000000000014111220116477200200170ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi cgilua.htmlheader() if ap then local pid, ppid = ap.pid () if not ppid then ppid = "no parent pid" end cgilua.put ("pid = "..pid.." ("..ppid..")".."\n") end assert(type(stable.get) == "function") assert(type(stable.set) == "function") cgilua.put"stable.pairs = {
\n" for i, v in stable.pairs () do cgilua.put (i.." = "..tostring(v).."
\n") end cgilua.put"}
\n" local counter = stable.get"counter" or 0 stable.set ("counter", counter + 1) local f = stable.get"f" if not f then local d = os.date() stable.set ("f", function () return d end) else cgilua.put ("f() = "..tostring (f ())) end cgilua.put"
\n" for i = 1,800 do cgilua.put (i) for ii = 1,1000 do cgilua.put ("") end cgilua.put ("\n") end cgilua.put ("End") lua-cgi-5.2~alpha2/tests/test_cookies.lp000077500000000000000000000005241220116477200203670ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi

Testing Cookies library

<%= CL_COOKIE%> = <%= tostring(test)%>
Assigning current date to cookie!
Reload this script to check cookie's value! lua-cgi-5.2~alpha2/tests/test_cookies.lua000077500000000000000000000005621220116477200205370ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi local cookies = require"cgilua.cookies" CL_COOKIE = "cgilua_cookie" local test = cookies.get (CL_COOKIE) cookies.set (CL_COOKIE, os.date()) cgilua.htmlheader () cgilua.put ([[

Testing Cookies library

]]..CL_COOKIE..' = '..tostring(test)..[[
Assigning current date to cookie!
Reload this script to check cookie's value! ]]) lua-cgi-5.2~alpha2/tests/test_err.lua000077500000000000000000000001671220116477200176740ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi cgilua.htmlheader() cgilua.put"Oi!" --io.write"something\n" cgilua.errorlog ("eca", "emerg") lua-cgi-5.2~alpha2/tests/test_fs.lua000077500000000000000000000012111220116477200175030ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi function link_dir (dir, base) local path = base.."/"..dir local mode = lfs.attributes (path).mode if mode == "directory" then return string.format ('%s', cgilua.mkurlpath ("test_fs.lua", { dir = path }), dir) else return dir end end cgilua.htmlheader () cgilua.put ("

Testing Filesystem library

\n") cgilua.put ("\n") cgilua.put ("\n") local i = 0 local dir = cgilua.QUERY.dir or "." for file in lfs.dir (dir) do i = i+1 cgilua.put ("\n") end cgilua.put ("
Testing dir
"..i..""..link_dir(file, dir).."
\n") lua-cgi-5.2~alpha2/tests/test_htk.lua000077500000000000000000000006551220116477200176740ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi require"htk" local a_table = {} for i = 1, 20 do local l = {} for j = 1, 20 do table.insert (l, HTK.TD { "cell "..i..","..j }) end table.insert (a_table, HTK.TR (l)) end cgilua.htmlheader() cgilua.put (HTK.HTML { HTK.HEAD { HTK.TITLE { "Titulo da Pagina" } }, HTK.BODY { bgcolor = "#FFFFFF", HTK.H1 { "Titulo da Pagina" }, HTK.P {}, "Uma pgina qualquer", HTK.TABLE (a_table), } }) lua-cgi-5.2~alpha2/tests/test_lib.lua000077500000000000000000000014661220116477200176550ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi local function getfield (t, f) for w in string.gfind(f, "[%w_]+") do if not t then return nil end t = t[w] end return t end function test_lib (libname) local ok, err = pcall (require, libname) if not ok then cgilua.put ("Library "..libname.." not found
\n".. err) else cgilua.put ("Library "..libname.."
\n") local t = getfield (_G, libname) if type(t) ~= "table" then cgilua.put (tostring(t)) else for i, v in pairs (t) do cgilua.put ("  "..tostring(i).." = "..tostring(v).."
\n") end end end cgilua.put ("\n

\n") end cgilua.htmlheader () for _, lib in ipairs { "lfs", "socket", "luasql.postgres", "luasql", "lxp", "lxp.lom", "lualdap", "htk", "xmlrpc", "xmlrpc.http" } do test_lib (lib) end lua-cgi-5.2~alpha2/tests/test_main.html000077500000000000000000000133261220116477200202140ustar00rootroot00000000000000 Test Page
GET:
Lua script cgi fcgi module
HTML template cgi fcgi module
POST:
field 1:
field 2:
field 3: op 1 op 2 op 3
Lua script cgi fcgi module
HTML template cgi fcgi module
POST (with upload):
field 1:
file (binary!):
Lua script cgi fcgi module
HTML template cgi fcgi module
Cookies:
Lua script cgi fcgi module
HTML template cgi fcgi module
Filesystem:
Lua script cgi fcgi module
Session:
Lua script cgi fcgi module
CGI Variables:
HTML template cgi fcgi module
Library Overview:
HTML template cgi fcgi module
Concurrency
Lua script cgi fcgi module
$Id: test_main.html,v 1.12 2004/11/25 10:52:58 tomas Exp $ lua-cgi-5.2~alpha2/tests/test_main.lp000077500000000000000000000011401220116477200176520ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi Embeded Lua Test cgilua.QUERY =
cgilua.POST =
Remote address: <%= cgilua.servervariable"REMOTE_ADDR" %>
Is persistent = <%= tostring (SAPI.Info.ispersistent) %>
ap =
lfcgi = <% = tostring(lfcgi) %>
<%= (ap and ap.handler()) or "" %>
$Id: test_main.lp,v 1.5 2005/02/11 14:39:21 tomas Exp $ lua-cgi-5.2~alpha2/tests/test_main.lua000077500000000000000000000023211220116477200200220ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi -- $Id: test_main.lua,v 1.11 2006/01/06 16:33:57 tomas Exp $ cgilua.serialize = require"cgilua.serialize".serialize cgilua.htmlheader() cgilua.put[[ Script Lua Test cgilua.QUERY = ]] cgilua.serialize (cgilua.QUERY, cgilua.put) cgilua.put[[
cgilua.POST = ]] cgilua.serialize (cgilua.POST, cgilua.put) cgilua.put "
\n" cgilua.put ("Remote address: "..cgilua.servervariable"REMOTE_ADDR") cgilua.put "
\n" cgilua.put ("Is persistent = "..tostring (SAPI.Info.ispersistent).."
\n") cgilua.put ("ap="..tostring(ap).."
\n") cgilua.put ("lfcgi="..tostring(lfcgi).."
\n") -- Checking Virtual Environment local my_output = cgilua.put cgilua.put = nil local status, err = pcall (function () assert (cgilua.put == nil, "cannot change cgilua.put value") end) cgilua.put = my_output assert (status == true, err) -- Checking require local status, err = pcall (function () require"unknown_module" end) assert (status == false, "unknown_module loaded!") --assert (package == nil, "Access to package table allowed!") cgilua.put[[

$Id: test_main.lua,v 1.11 2006/01/06 16:33:57 tomas Exp $ ]] cgilua = nil lua-cgi-5.2~alpha2/tests/test_session.lua000077500000000000000000000021661220116477200205700ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi cgilua.session = require"cgilua.session" cgilua.session.setdir"/tmp/" cgilua.session.enable () function pt (tab) for i, v in pairs (tab) do local vv = v if type(v) == "table" then vv = "" for _i, _v in pairs (v) do vv = vv..string.format ("%s = %q, ", _i, _v) end vv = '{'..vv..'}' end cgilua.put (string.format ("%s = %s
\n", tostring (i), tostring (vv))) end end if cgilua.POST.field then if not cgilua.session.data.field then cgilua.session.data.field = {} end table.insert (cgilua.session.data.field, cgilua.POST.field) end cgilua.htmlheader() if cgilua.session then cgilua.put "cgilua.POST = {
\n" pt (cgilua.POST) cgilua.put "}
\n" cgilua.put "cgilua.session.data = {
\n" pt (cgilua.session.data) cgilua.put "}
\n" cgilua.put [[

field:

]] else cgilua.put "Sessions library is not available or not well configured" end lua-cgi-5.2~alpha2/tests/test_sql.lua000077500000000000000000000006651220116477200177060ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi local s = require"luasql.postgres" local env = assert (luasql.postgres ()) local conn = assert (env:connect ("luasql-test", "tomas")) local cur = assert (conn:execute ("select count(*) from fetch_test")) cgilua.htmlheader() cgilua.put ("Total lines at table fetch_test is "..cur:fetch()) cgilua.put (string.format ("
\n%s == %s
\n", tostring(s), tostring(luasql))) cur:close() conn:close() env:close() lua-cgi-5.2~alpha2/tests/test_sql2.lua000077500000000000000000000012441220116477200177620ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi require"postgres" local env = assert (luasql.postgres ()) local conn = assert (env:connect ("luasql-test", "tomas")) local cur = assert (conn:execute ("select count(*) from t1")) local total = tonumber (cur:fetch()) cur:close() local aleatorio = math.random(total) local cur = assert (conn:execute ("select * from t1, t2 where b = d and a != "..2*aleatorio)) cgilua.htmlheader() cgilua.put ("Aleatorio = "..aleatorio.."
\n") local a,b,c,d = cur:fetch() cgilua.put ("\n") while a do -- cgilua.put ("") a,b,c,d = cur:fetch() end cgilua.put ("
",a,"",b,"",c,"",d,"
\n") cur:close() conn:close() env:close() lua-cgi-5.2~alpha2/tests/test_variables.lp000077500000000000000000000015511220116477200207040ustar00rootroot00000000000000#!/usr/bin/env cgilua.cgi <% for _, var in pairs { "SERVER_SOFTWARE", "SERVER_NAME", "GATEWAY_INTERFACE", "SERVER_PROTOCOL", "SERVER_PORT", "REQUEST_METHOD", "PATH_INFO", "PATH_TRANSLATED", "SCRIPT_NAME", "QUERY_STRING", "REMOTE_HOST", "REMOTE_ADDR", "AUTH_TYPE", "REMOTE_USER", "REMOTE_IDENT", "CONTENT_TYPE", "CONTENT_LENGTH", "HTTP_REFERER", "HTTP_COOKIE", "SCRIPT_FILENAME", "DOCUMENT_ROOT", } do %> <% end %>
<%= var %>="<%= cgilua.servervariable(var) or "not defined"%>"

<% for _, var in ipairs { "script_file", "script_path", "script_pdir", "script_vdir", "script_vpath", "urlpath", } do %> <% end %>
<%= var %>="<%= cgilua[var] %>"

<% url = cgilua.mkurlpath'test_variables.lp' %> <%= url %>
test_main.html

lua-cgi-5.2~alpha2/tests/tfcgi1.lua000077500000000000000000000005501220116477200172160ustar00rootroot00000000000000-- $Id: tfcgi1.lua,v 1.1 2004/03/25 19:31:05 tomas Exp $ lfcgi.stdout:write"Content-type: text/html\n\n" for i,v in pairs{"QUERY_STRING", } do lfcgi.stdout:write (string.format ("%s = %s", v, os.getenv(v) or ' ')) end lfcgi.stdout:write "
\n" local post_data = lfcgi.stdin:read"*a" lfcgi.stdout:write (string.format ("post_data = {%s}", post_data)) lua-cgi-5.2~alpha2/tests/tmod1.lua000077500000000000000000000010621220116477200170640ustar00rootroot00000000000000-- $Id: tmod1.lua,v 1.1 2004/03/25 19:31:05 tomas Exp $ ap.set_content_type"text/html" ap.rputs "ap.args = {" ap.rputs (ap.args() or '') ap.rputs "}
\n" assert (ap.setup_client_block ("REQUEST_CHUNKED_ERROR") == ap.OK) if ap.should_client_block () ~= 0 then post_data = {} local block, err = ap.get_client_block () while block do table.insert (post_data, block) block, err = ap.get_client_block () end if err then error (err) end post_data = table.concat (post_data) end ap.rputs "post_data = {" ap.rputs (tostring (post_data)) ap.rputs "}\n"