@@ -0,0 +1,180 @@
# Microsoft Developer Studio Generated NMAKE File, Based on libapreq.dsp
# Compile with NMAKE /f libapreq2.mak "CFG=libapreq2 - Win32 Debug"

APR_LIB=c:\lua-apr\apr\Release\libapr-1.lib
APU_LIB=c:\lua-apr\apr-util\Release\libaprutil-1.lib
APREQ_HOME=c:\lua-apr\libapreq2

!IF "$(CFG)" == ""
CFG=libapreq2 - Win32 Release
!MESSAGE No configuration specified. Defaulting to libapreq2 - Win32 Release.
!ENDIF

!IF "$(CFG)" != "libapreq2 - Win32 Release" && "$(CFG)" != "libapreq2 - Win32 Debug"
!MESSAGE Invalid configuration "$(CFG)" specified.
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "libapreq2.mak" CFG="libapreq2 - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "libapreq2 - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "libapreq2 - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
!ERROR An invalid configuration is specified.
!ENDIF

!IF "$(OS)" == "Windows_NT"
NULL=
!ELSE
NULL=nul
!ENDIF

CPP=cl.exe /IC:\lua-apr\apr\include /IC:\lua-apr\apr-util\include
RSC=rc.exe /IC:\lua-apr\apr\include /IC:\lua-apr\apr-util\include

CFG_HOME=$(APREQ_HOME)\win32
OUTDIR=$(CFG_HOME)\libs
INTDIR=$(CFG_HOME)\libs
LIBDIR=$(APREQ_HOME)\library

LINK32_OBJS= \
"$(INTDIR)\cookie.obj" \
"$(INTDIR)\param.obj" \
"$(INTDIR)\parser.obj" \
"$(INTDIR)\parser_header.obj" \
"$(INTDIR)\parser_multipart.obj" \
"$(INTDIR)\parser_urlencoded.obj" \
"$(INTDIR)\util.obj" \
"$(INTDIR)\version.obj" \
"$(INTDIR)\error.obj" \
"$(INTDIR)\libapreq.res"

!IF "$(CFG)" == "libapreq2 - Win32 Release"

ALL : "$(OUTDIR)\libapreq2.dll"

"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"

CPP_PROJ=/nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "APREQ_DECLARE_EXPORT" /I"$(APREQ_HOME)\include" /FD /c
MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
RSC_PROJ=/l 0x409 /d "NDEBUG" /i "$(APREQ_HOME)\include"
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\libapreq2.bsc"
LINK32=link.exe
MANIFEST=$(OUTDIR)\libapreq2.dll.manifest
LINK32_FLAGS="$(APR_LIB)" "$(APU_LIB)" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:no /machine:I386 /out:"$(OUTDIR)\libapreq2.dll" /implib:"$(OUTDIR)\libapreq2.lib"

"$(OUTDIR)\libapreq2.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) $(LINK32_FLAGS) $(DEF_FLAGS) $(LINK32_OBJS)
if exist $(MANIFEST) mt /nologo /manifest $(MANIFEST) /outputresource:$(OUTDIR)\libapreq2.dll;2

!ELSEIF "$(CFG)" == "libapreq2 - Win32 Debug"

ALL : "$(OUTDIR)\libapreq2.dll"

"$(OUTDIR)" :
if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"

CPP_PROJ=/nologo /MDd /W3 /Gm /EHsc /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "APREQ_DECLARE_EXPORT" /I"$(APREQ_HOME)\include" /FD /RTC1 /c
MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
RSC_PROJ=/l 0x409 /d "_DEBUG" /i "$(APREQ_HOME)\include"
BSC32=bscmake.exe
BSC32_FLAGS=/nologo /o"$(OUTDIR)\libapreq2.bsc"
LINK32=link.exe
MANIFEST=$(OUTDIR)\libapreq2.dll.manifest
LINK32_FLAGS="$(APR_LIB)" "$(APU_LIB)" kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\libapreq2.pdb" /debug /machine:I386 /out:"$(OUTDIR)\libapreq2.dll" /implib:"$(OUTDIR)\libapreq2.lib" /pdbtype:sept

"$(OUTDIR)\libapreq2.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) $(LINK32_FLAGS) $(DEF_FLAGS) $(LINK32_OBJS)
if exist $(MANIFEST) mt /nologo /manifest $(MANIFEST) /outputresource:$(OUTDIR)\libapreq2.dll;2

!ENDIF

.c{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<

.cpp{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<

.cxx{$(INTDIR)}.obj::
$(CPP) @<<
$(CPP_PROJ) $<
<<

.c{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<

.cpp{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<

.cxx{$(INTDIR)}.sbr::
$(CPP) @<<
$(CPP_PROJ) $<
<<


!IF "$(CFG)" == "libapreq2 - Win32 Release" || "$(CFG)" == "libapreq2 - Win32 Debug"

SOURCE=$(LIBDIR)\cookie.c

"$(INTDIR)\cookie.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) /Fo"$(INTDIR)\cookie.obj" $(CPP_PROJ) $(SOURCE)

SOURCE=$(LIBDIR)\param.c

"$(INTDIR)\param.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) /Fo"$(INTDIR)\param.obj" $(CPP_PROJ) $(SOURCE)

SOURCE=$(LIBDIR)\parser.c

"$(INTDIR)\parser.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) /Fo"$(INTDIR)\parser.obj" $(CPP_PROJ) $(SOURCE)

SOURCE=$(LIBDIR)\parser_header.c

"$(INTDIR)\parser_header.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) /Fo"$(INTDIR)\parser_header.obj" $(CPP_PROJ) $(SOURCE)

SOURCE=$(LIBDIR)\parser_multipart.c

"$(INTDIR)\parser_multipart.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) /Fo"$(INTDIR)\parser_multipart.obj" $(CPP_PROJ) $(SOURCE)

SOURCE=$(LIBDIR)\parser_urlencoded.c

"$(INTDIR)\parser_urlencoded.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) /Fo"$(INTDIR)\parser_urlencoded.obj" $(CPP_PROJ) $(SOURCE)

SOURCE=$(LIBDIR)\version.c

"$(INTDIR)\version.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) /Fo"$(INTDIR)\version.obj" $(CPP_PROJ) $(SOURCE)

SOURCE=$(LIBDIR)\util.c

"$(INTDIR)\util.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) /Fo"$(INTDIR)\util.obj" $(CPP_PROJ) $(SOURCE)

SOURCE=$(LIBDIR)\error.c

"$(INTDIR)\error.obj" : $(SOURCE) "$(INTDIR)"
$(CPP) /Fo"$(INTDIR)\error.obj" $(CPP_PROJ) $(SOURCE)

SOURCE=.\libapreq.rc

"$(INTDIR)\libapreq.res" : $(SOURCE) "$(INTDIR)"
$(RSC) /fo"$(INTDIR)\libapreq.res" $(RSC_PROJ) $(SOURCE)

!ENDIF

@@ -3,10 +3,10 @@
Lua source code for the Lua/APR binding.
Author: Peter Odding <peter@peterodding.com>
Last Change: February 22, 2011
Last Change: February 26, 2011
Homepage: http://peterodding.com/code/lua/apr/
License: MIT
Version: 0.15.1
Version: 0.16
This Lua script is executed on require("apr"), loads the binary module using
require("apr.core"), defines several library functions implemented on top of
@@ -15,7 +15,7 @@
--]]

local apr = require 'apr.core'
apr._VERSION = '0.15.1'
apr._VERSION = '0.16'

-- apr.md5(input [, binary]) -> digest {{{1
--
@@ -1,7 +1,7 @@
/* Command argument parsing module for the Lua/APR binding.
*
* Author: Peter Odding <peter@peterodding.com>
* Last Change: February 20, 2011
* Last Change: February 25, 2011
* Homepage: http://peterodding.com/code/lua/apr/
* License: MIT
*/
@@ -66,12 +66,6 @@ int lua_apr_getopt(lua_State *L)
if (silent)
os->errfn = NULL;

# define PUSH_OPTARG(L, S) \
if (s != NULL) \
lua_pushstring(L, s); \
else \
lua_pushboolean(L, 1)

/* Parse options, save matched options in table #1. */
lua_createtable(L, 0, optc);
for (;;) {
@@ -97,21 +91,21 @@ int lua_apr_getopt(lua_State *L)
lua_pop(L, 1); /* existing value */
} else if (lua_istable(L, -1)) {
/* Add argument to table of existing values. */
PUSH_OPTARG(L, s);
push_string_or_true(L, s);
lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
lua_pop(L, 1); /* existing value */
} else if (!lua_isnil(L, -1)) {
/* Combine 1st and 2nd argument in table. */
lua_newtable(L);
lua_insert(L, -2);
lua_rawseti(L, -2, 1);
PUSH_OPTARG(L, s);
push_string_or_true(L, s);
lua_rawseti(L, -2, 2);
lua_setfield(L, -2, buffer);
} else {
/* Set 1st argument value. */
lua_pop(L, 1); /* pop nil result */
PUSH_OPTARG(L, s);
push_string_or_true(L, s);
lua_setfield(L, -2, buffer);
}
}

Large diffs are not rendered by default.

@@ -1,7 +1,7 @@
/* Miscellaneous functions module for the Lua/APR binding.
*
* Author: Peter Odding <peter@peterodding.com>
* Last Change: February 22, 2011
* Last Change: February 26, 2011
* Homepage: http://peterodding.com/code/lua/apr/
* License: MIT
*/
@@ -34,15 +34,6 @@ lua_apr_objtype *lua_apr_types[] = {

/* luaopen_apr_core() initializes the binding and library. {{{1 */

/* Enable redefining exporting of loader function, with sane defaults. */
#ifndef LUA_APR_EXPORT
# ifdef WIN32
# define LUA_APR_EXPORT __declspec(dllexport)
# else
# define LUA_APR_EXPORT extern
# endif
#endif

LUA_APR_EXPORT int luaopen_apr_core(lua_State *L)
{
apr_status_t status;
@@ -98,9 +89,17 @@ LUA_APR_EXPORT int luaopen_apr_core(lua_State *L)
{ "fnmatch", lua_apr_fnmatch },
{ "fnmatch_test", lua_apr_fnmatch_test },

/* getopt.c */
/* getopt.c -- command argument parsing. */
{ "getopt", lua_apr_getopt },

# if LUA_APR_ENABLE_APREQ
/* http.c -- HTTP request parsing. */
{ "parse_headers", lua_apr_parse_headers },
{ "parse_multipart", lua_apr_parse_multipart },
{ "parse_cookie_header", lua_apr_parse_cookie_header },
{ "parse_query_string", lua_apr_parse_query_string },
# endif

/* io_dir.c -- directory manipulation. */
{ "temp_dir_get", lua_apr_temp_dir_get },
{ "dir_make", lua_apr_dir_make },
@@ -1,11 +1,14 @@
/* Header file for the Lua/APR binding.
*
* Author: Peter Odding <peter@peterodding.com>
* Last Change: February 19, 2011
* Last Change: February 26, 2011
* Homepage: http://peterodding.com/code/lua/apr/
* License: MIT
*/

#ifndef LUA_APR_H
#define LUA_APR_H

/* Global headers. {{{1 */
#include <assert.h>
#include <stdlib.h>
@@ -23,6 +26,18 @@

/* Macro definitions. {{{1 */

/* Enable redefining exporting of loader function, with sane defaults. */
#ifndef LUA_APR_EXPORT
# ifdef WIN32
# define LUA_APR_EXPORT __declspec(dllexport)
# else
# define LUA_APR_EXPORT extern
# endif
#endif

#define LUA_APR_POOL_KEY "Lua/APR memory pool"
#define LUA_APR_POOL_MT "Lua/APR memory pool metamethods"

/* FIXME Pushing onto the stack might not work in this scenario? */
#define error_message_memory "memory allocation error"

@@ -65,6 +80,9 @@
#define time_put(L, time) \
lua_pushnumber(L, (lua_Number)time / APR_USEC_PER_SEC)

#define push_string_or_true(L, s) \
(s != NULL && s[0] != '\0' ? lua_pushstring(L, s) : lua_pushboolean(L, 1))

/* Debugging aids. {{{1 */

#include <stdio.h>
@@ -267,6 +285,12 @@ int lua_apr_fnmatch_test(lua_State*);
/* getopt.c */
int lua_apr_getopt(lua_State*);

/* http.c */
int lua_apr_parse_headers(lua_State*);
int lua_apr_parse_multipart(lua_State*);
int lua_apr_parse_cookie_header(lua_State*);
int lua_apr_parse_query_string(lua_State*);

/* io_dir.c */
int lua_apr_temp_dir_get(lua_State*);
int lua_apr_dir_make(lua_State*);
@@ -396,6 +420,6 @@ int lua_apr_xlate(lua_State*);
/* xml.c */
int lua_apr_xml(lua_State*);

/* vim: set ts=2 sw=2 et tw=79 fen fdm=marker : */

#endif

/* vim: set ts=2 sw=2 et tw=79 fen fdm=marker : */
@@ -1,78 +1,56 @@
/* Global memory pool handling for the Lua/APR binding.
*
* Author: Peter Odding <peter@peterodding.com>
* Last Change: February 19, 2011
* Last Change: February 26, 2011
* Homepage: http://peterodding.com/code/lua/apr/
* License: MIT
*/

#include "lua_apr.h"

typedef struct {
/* FIXME Reference counting isn't actually used for the global memory pool;
* it's just that it's required by new_object() and related functions. */
lua_apr_refobj header;
/* Destroy the global memory pool, wait for any child threads to terminate. */

static int pool_gc(lua_State *L)
{
apr_pool_t *pool;
} lua_apr_gpool;

lua_apr_objtype lua_apr_pool_type;
# if APR_HAS_THREADS && !defined(APREQ_STANDALONE)
threads_terminate();
# endif

pool = *(apr_pool_t**)luaL_checkudata(L, 1, LUA_APR_POOL_MT);
apr_pool_destroy(pool);

return 0;
}

/* Initialize and/or retrieve the global memory pool from Lua's registry (every
* Lua state has it's own global memory pool). */
/* Initialize and/or retrieve the global memory pool from Lua's registry
* (every Lua state has it's own global memory pool). */

apr_pool_t *to_pool(lua_State *L)
{
lua_apr_gpool *reference;
apr_pool_t *memory_pool;
apr_status_t status;

luaL_checkstack(L, 1, "not enough stack space to get memory pool");
lua_pushlightuserdata(L, &lua_apr_pool_type); /* push anchor */
lua_rawget(L, LUA_REGISTRYINDEX); /* pop anchor, push result */
lua_getfield(L, LUA_REGISTRYINDEX, LUA_APR_POOL_KEY);
if (!lua_isuserdata(L, -1)) {
lua_pop(L, 1); /* pop nil result */
lua_pop(L, 1);
status = apr_pool_create(&memory_pool, NULL);
if (status != APR_SUCCESS)
raise_error_status(L, status);
lua_pushlightuserdata(L, &lua_apr_pool_type); /* push anchor */
reference = new_object(L, &lua_apr_pool_type);
reference->pool = memory_pool;
lua_rawset(L, LUA_REGISTRYINDEX); /* pop pool, anchor */
*(apr_pool_t**)lua_newuserdata(L, sizeof(apr_pool_t*)) = memory_pool;
if (luaL_newmetatable(L, LUA_APR_POOL_MT)) {
lua_pushcfunction(L, pool_gc);
lua_setfield(L, -2, "__gc");
}
lua_setmetatable(L, -2);
lua_setfield(L, LUA_REGISTRYINDEX, LUA_APR_POOL_KEY);
} else {
reference = lua_touserdata(L, -1);
memory_pool = reference->pool;
memory_pool = *(apr_pool_t**)lua_touserdata(L, -1);
apr_pool_clear(memory_pool);
lua_pop(L, 1); /* pop result */
lua_pop(L, 1);
}

return memory_pool;
}

/* Destroy the global memory pool, wait for any child threads to terminate. */

static int pool_gc(lua_State *L)
{
lua_apr_gpool *gpool;

# if APR_HAS_THREADS
threads_terminate();
# endif

gpool = check_object(L, 1, &lua_apr_pool_type);
apr_pool_destroy(gpool->pool);

return 0;
}

static luaL_Reg pool_metamethods[] = {
{ "__gc", pool_gc },
{ NULL, NULL }
};

lua_apr_objtype lua_apr_pool_type = {
"lua_apr_pool*", /* metatable name in registry */
"memory pool", /* friendly object name */
sizeof(lua_apr_gpool), /* structure size */
NULL, /* methods table */
pool_metamethods /* metamethods table */
};
@@ -0,0 +1,158 @@
--[[
Unit tests for the HTTP request parsing module of the Lua/APR binding.
Author: Peter Odding <peter@peterodding.com>
Last Change: February 27, 2011
Homepage: http://peterodding.com/code/lua/apr/
License: MIT
--]]

local apr = require 'apr'
local helpers = require 'apr.test.helpers'
if not apr.parse_headers then
helpers.warning "HTTP request parsing module not available!\n"
return false
end

local function nl2crlf(s)
return (s:gsub('\r?\n', '\r\n'))
end

-- Test apr.parse_query_string() {{{1
local expected = { alpha = 'one', beta = 'two', omega = 'last' }
local actual = assert(apr.parse_query_string 'alpha=one&beta=two;omega=last')
assert(helpers.deepequal(expected, actual))
local expected = { key = { '1', '2', '3' }, novalue = true }
local actual = assert(apr.parse_query_string 'key=1;key=2;key=3;novalue')
assert(helpers.deepequal(expected, actual))

-- Test apr.parse_cookie_header() {{{1

-- Netscape cookies
local nscookies = 'a=1; foo=bar; fl=left; fr=right;bad; ns=foo=1&bar=2,frl=right-left; flr=left-right; fll=left-left; good_one=1;=;bad'
local cookies, msg, code = assert(apr.parse_cookie_header(nscookies))
assert(code == 'NOTOKEN')
assert(cookies.bad == nil) -- ignore wacky cookies that don't have an '=' sign
assert(helpers.deepequal({
a = '1',
ns = 'foo=1&bar=2', -- accept wacky cookies that contain multiple '='
foo = 'bar',
fl = 'left',
fr = 'right',
frl = 'right-left',
flr = 'left-right',
fll = 'left-left',
good_one = '1',
}, cookies))

-- RFC cookies
local rfccookies = '$Version=1; first=a;$domain=quux;second=be,$Version=1;third=cie'
local cookies, msg, code = assert(apr.parse_cookie_header(rfccookies))
assert(not (msg or code))
assert(helpers.deepequal({
first = 'a',
second = 'be',
third = 'cie',
}, cookies))

-- Invalid cookies.
local wpcookies = 'wordpressuser_c580712eb86cad2660b3601ac04202b2=admin; wordpresspass_c580712eb86cad2660b3601ac04202b2=7ebeeed42ef50720940f5b8db2f9db49; rs_session=59ae9b8b503e3af7d17b97e7f77f7ea5; dbx-postmeta=grabit=0-,1-,2-,3-,4-,5-,6-&advancedstuff=0-,1+,2-'
local cookies, msg, code = apr.parse_cookie_header(wpcookies)
assert(code == 'NOTOKEN')

local cgcookies1 = 'UID=MTj9S8CoAzMAAFEq21YAAAAG|c85a9e59db92b261408eb7539ff7f949b92c7d58; $Version=0;SID=MTj9S8CoAzMAAFEq21YAAAAG|c85a9e59db92b261408eb7539ff7f949b92c7d58;$Domain=www.xxxx.com;$Path=/'
local cookies, msg, code = apr.parse_cookie_header(cgcookies1)
assert(code == 'MISMATCH')

local cgcookies2 = 'UID=Gh9VxX8AAAIAAHP7h6AAAAAC|2e809a9cc99c2dca778c385ebdefc5cb86c95dc3; SID=Gh9VxX8AAAIAAHP7h6AAAAAC|2e809a9cc99c2dca778c385ebdefc5cb86c95dc3; $Version=1'
local cookies, msg, code = apr.parse_cookie_header(cgcookies2)
assert(code == 'MISMATCH')

local cgcookies3 = 'UID=hCijN8CoAzMAAGVDO2QAAAAF|50299f079343fd6146257c105b1370f2da78246a; SID=hCijN8CoAzMAAGVDO2QAAAAF|50299f079343fd6146257c105b1370f2da78246a; $Path="/"; $Domain="www.xxxx.com"'
local cookies, msg, code = apr.parse_cookie_header(cgcookies3)
assert(code == 'MISMATCH')

-- Valid cookie.
local cgcookies4 = 'SID=66XUEH8AAAIAAFmLLRkAAAAV|2a48c4ae2e9fb8355e75192db211f0779bdce244; UID=66XUEH8AAAIAAFmLLRkAAAAV|2a48c4ae2e9fb8355e75192db211f0779bdce244; __utma=144149162.4479471199095321000.1234471650.1234471650.1234471650.1; __utmb=144149162.24.10.1234471650; __utmc=144149162; __utmz="144149162.1234471650.1.1.utmcsr=szukaj.xxxx.pl|utmccn=(referral)|utmcmd=referral|utmcct=/internet/0,0.html"'
local cookies, msg, code = apr.parse_cookie_header(cgcookies4)
assert(type(cookies) == 'table')
assert(not (msg or code))

-- Test apr.parse_headers() {{{1

local expected = {
['Host'] = 'lua-users.org',
['User-Agent'] = 'Mozilla/5.0 (X11; U; Linux i686; nl; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13',
['Accept'] = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
['Accept-Language'] = 'nl,en-us;q=0.7,en;q=0.3',
['Accept-Encoding'] = 'gzip,deflate',
['Accept-Charset'] = 'ISO-8859-1,utf-8;q=0.7,*;q=0.7',
['Keep-Alive'] = '115',
['Connection'] = 'keep-alive',
['Cookie'] = 'wiki=randkey&944319634&rev&1&id&4216',
}

local actual = assert(apr.parse_headers(nl2crlf [[
Host: lua-users.org
User-Agent: Mozilla/5.0 (X11; U; Linux i686; nl; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: nl,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Cookie: wiki=randkey&944319634&rev&1&id&4216
]]))

assert(helpers.deepequal(expected, actual))

-- Test apr.parse_multipart() {{{1

local expected = {
field1 = {
'Joe owes =80100.',
['content-disposition'] = 'form-data; name="field1"',
['content-transfer-encoding'] = 'quoted-printable',
['content-type'] = 'text/plain;charset=windows-1250'
},
pics = {
'file1.txt',
'... contents of file1.txt ...\r\n',
['Content-Type'] = 'text/plain',
['content-disposition'] = 'form-data; name="pics"; filename="file1.txt"'
},
[''] = {
'Joe owes =80100.',
['content-disposition'] = 'form-data; name=""',
['content-transfer-encoding'] = 'quoted-printable',
['content-type'] = 'text/plain;\r\n charset=windows-1250'
}
}

local actual = assert(apr.parse_multipart(nl2crlf [[
--AaB03x
content-disposition: form-data; name="field1"
content-type: text/plain;charset=windows-1250
content-transfer-encoding: quoted-printable
Joe owes =80100.
--AaB03x
content-disposition: form-data; name="pics"; filename="file1.txt"
Content-Type: text/plain
... contents of file1.txt ...
--AaB03x
content-disposition: form-data; name=""
content-type: text/plain;
charset=windows-1250
content-transfer-encoding: quoted-printable
Joe owes =80100.
--AaB03x--
]], 'multipart/form-data; charset="iso-8859-1"; boundary="AaB03x"'))

assert(helpers.deepequal(expected, actual))
@@ -3,7 +3,7 @@
Driver script for the unit tests of the Lua/APR binding.
Author: Peter Odding <peter@peterodding.com>
Last Change: February 20, 2011
Last Change: February 27, 2011
Homepage: http://peterodding.com/code/lua/apr/
License: MIT
@@ -28,6 +28,7 @@ local modules = {
'filepath',
'fnmatch',
'getopt',
'http',
'io_dir',
'io_file',
'io_net',
@@ -56,7 +57,8 @@ for _, testname in ipairs(modules) do
end
package.loaded[modname] = nil
-- Garbage collect unreferenced objects before testing the next module.
collectgarbage 'collect'; collectgarbage 'collect'
collectgarbage 'collect'
collectgarbage 'collect'
end
helpers.message("Done!\n")