In pre release mode!

master
Diego Nehab 2005-11-20 08:56:19 +00:00
parent f20f4889bf
commit 5e09779c7f
13 changed files with 279 additions and 407 deletions

69
NEW
View File

@ -1,21 +1,54 @@
What's New
The big change for the 2.0 (beta3) release was the adoption of the Lua
5.1 package proposal. There were several bug fixes too (a beta is a
beta, is a beta).
There is no big change for the 2.0 (final) release. It is
basically a bug fix release. The main improvement is in the
non-blocking support.
* New compat-5.1 distribution:
- Instalation uses new directory structure;
- Namespace hierarchy is in now back in use (ex. socket.url instead of url);
- All modules call require even for standard libraries;
* LTN12 avoids coroutines (so you can go wild on the C side);
* socket.select wasn't calling tm_markstart;
* Kludge on wsocket.c:sock_send for Windows timeout issue moved to
buffer.c:sendraw so it's not a kludge anymore;
* socket.protect only catches errors thrown by socket.try;
* Fixed udp:sendto to call sock_sendto instead of sock_send;
* close wasn't returning 1!
* socket.gettime returns time since Unix Epoch 1/1/1970 (UTC)
* socket.sleep is robust to interrupts;
* http.PROXY wasn't working.
* fixed some of the examples
* New: sample module dispatch.lua implements a coroutine
based dispatcher;
* New: sample check-links.lua works both in blocking and
non-blocking mode using coroutines (using the new
dispatcher);
* New: sample forward.lua implements a coroutine based
forward server (using the new dispatcher);
* Improved: tcp:send(data, i, j) to return (i+sent-1). This
is great for non-blocking I/O, but might break some code;
* Improved: HTTP, SMTP, and FTP functions to accept a new
field create that overrides the function used to create
socket objects;
* Improved: smtp.message now supports multipart/alternative
(for the HTML messages we all love so much);
* Fixed: smtp.send was hanging on errors returned by LTN12
sources;
* Fixed: url.absolute() to work when base_url is in parsed
form;
* Fixed: http.request() not to redirect when the location
header is empty (naughty servers...);
* Fixed: tcp{client}:shutdown() to check for class instead
of group;
* Fixed: The manual to stop using socket.try() in place of
assert(), since it can't;
* Improved: Got rid of package.loaded.base = _G kludge;
* Fixed: Parts of the manual referred to require("http")
instead of require("socket.http");
* Improved: Socket and MIME binaries are called 'core' each
inside their directory (ex. "socket/core.dll"). The 'l'
prefix was just a bad idea;
* Improved: Using bundles in Mac OS X, instead of dylibs;
* Fixed: luasocket.h to export luaopen_socket_core;
* Fixed: udp:setpeername() so you can "disconnect" an UDP
socket;
* Fixed: A weird bug in HTTP support that caused some
requests to fail (Florian Berger);
* Fixed: Bug in socket.select() that caused sockets with
descriptor 0 to be ignored (Renato Maia);
* Fixed: "Bug" that caused dns.toip() to crash under uLinux
(William Trenker);
* Fixed: "Bug" that caused gethostbyname to crash under VMS
(Renato Maia);
* Fixed: tcp:send("") to return 0 bytes sent (Alexander
Marinov);
* Improved: socket.DEBUG and socket.VERSION became
socket._DEBUGs and socket._VERSION for uniformity with other
libraries;
* Improved: socket.select now works on empty sets on Windows.

20
config
View File

@ -37,20 +37,20 @@ INSTALL_EXEC=cp
# Compiler and linker settings
# for Mac OS X
#
#CC=gcc
#DEF=-DLUASOCKET_DEBUG -DUNIX_HAS_SUN_LEN
#CFLAGS= $(LUAINC) -I$(COMPAT) $(DEF) -pedantic -Wall -O2 -fno-common
#LDFLAGS=-bundle -undefined dynamic_lookup
#LD=export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc
CC=gcc
DEF=-DLUASOCKET_DEBUG -DUNIX_HAS_SUN_LEN
CFLAGS= $(LUAINC) -I$(COMPAT) $(DEF) -pedantic -Wall -O2 -fno-common
LDFLAGS=-bundle -undefined dynamic_lookup
LD=export MACOSX_DEPLOYMENT_TARGET="10.3"; gcc
#------
# Compiler and linker settings
# for Linux
CC=gcc
DEF=-DLUASOCKET_DEBUG
CFLAGS= $(LUAINC) -I$(COMPAT) $(DEF) -pedantic -Wall -O2 -fpic
LDFLAGS=-O -shared
LD=gcc
#CC=gcc
#DEF=-DLUASOCKET_DEBUG
#CFLAGS= $(LUAINC) -I$(COMPAT) $(DEF) -pedantic -Wall -O2 -fpic
#LDFLAGS=-O -shared
#LD=gcc
#------
# End of makefile configuration

View File

@ -209,11 +209,16 @@ Here are a few examples with the simple interface:
<pre class=example>
-- load the http module
http = require("socket.http")
local io = require("io")
local http = require("socket.http")
local ltn12 = require("ltn12")
-- connect to server "www.tecgraf.puc-rio.br" and retrieves this manual
-- file from "/luasocket/http.html"
b = http.request("http://www.tecgraf.puc-rio.br/luasocket/http.html")
-- connect to server "www.cs.princeton.edu" and retrieves this manual
-- file from "~diego/professional/luasocket/http.html" and print it to stdout
http.request{
url = "http://www.cs.princeton.edu/~diego/professional/luasocket/http.html",
sink = ltn12.sink.file(io.stdout)
}
-- connect to server "www.example.com" and tries to retrieve
-- "/private/index.html". Fails because authentication is needed.

View File

@ -165,6 +165,13 @@ support.
</p>
<ul>
<li> New: sample module <tt>dispatch.lua</tt> implements a
coroutine based dispatcher;
<li> New: sample <tt>check-links.lua</tt> works
both in blocking and non-blocking mode using coroutines
(using the new dispatcher);
<li> New: sample <tt>forward.lua</tt> implements a coroutine
based forward server (using the new dispatcher);
<li> Improved: <tt>tcp:send(data, i, j)</tt> to return <tt>(i+sent-1)</tt>. This is great for non-blocking I/O, but might break some code;
<li> Improved: HTTP, SMTP, and FTP functions to accept a new field
<tt>create</tt> that overrides the function used to create socket objects;

View File

@ -76,9 +76,9 @@ distribution directory structure:</p>
<pre class=example>
&lt;SHARE&gt;/compat-5.1.lua
&lt;SHARE&gt;/ltn12.lua
&lt;SHARE&gt;/mime/init.lua (originally mime.lua)
&lt;SHARE&gt;/mime/mime.lua
&lt;LIB&gt;/mime/core.dll
&lt;SHARE&gt;/socket/init.lua (originally socket.lua)
&lt;SHARE&gt;/socket/socket.lua
&lt;LIB&gt;/socket/core.dll
&lt;SHARE&gt;/socket/http.lua
&lt;SHARE&gt;/socket/tp.lua
@ -88,9 +88,7 @@ distribution directory structure:</p>
</pre>
<p> Naturally, on Unix systems, <tt>core.dll</tt>
would be replaced by <tt>core.so</tt>. Notice that in the instalation,
<tt>socket.lua</tt> becomes <tt>socket/init.lua</tt>, and the same happens
with <tt>mime.lua</tt>, which becomes <tt>mime/init.lua</tt>.
would be replaced by <tt>core.so</tt>.
</p>
<p> In order for the interpreter to find all LuaSocket components, three

View File

@ -446,6 +446,7 @@ The method returns 1 in case of success and <tt><b>nil</b></tt> otherwise.
<!-- settimeout +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=settimeout>
master:<b>settimeout(</b>value [, mode]<b>)</b><br>
client:<b>settimeout(</b>value [, mode]<b>)</b><br>
server:<b>settimeout(</b>value [, mode]<b>)</b>
</p>

View File

@ -1,48 +1,89 @@
This directory contains code that is more useful than the examples. This code
*is* supported.
This directory contains code that is more useful than the
samples. This code *is* supported.
tftp.lua -- Trivial FTP client
This module implements file retrieval by the TFTP protocol. Its main use
was to test the UDP code, but since someone found it usefull, I turned it
into a module that is almost official (no uploads, yet).
This module implements file retrieval by the TFTP protocol.
Its main use was to test the UDP code, but since someone
found it usefull, I turned it into a module that is almost
official (no uploads, yet).
dict.lua -- Dict client
The dict.lua module started with a cool simple client for the DICT
protocol, written by Luiz Henrique Figueiredo. This new version has been
converted into a library, similar to the HTTP and FTP libraries, that can
be used from within any luasocket application. Take a look on the source
code and you will be able to figure out how to use it.
The dict.lua module started with a cool simple client
for the DICT protocol, written by Luiz Henrique Figueiredo.
This new version has been converted into a library, similar
to the HTTP and FTP libraries, that can be used from within
any luasocket application. Take a look on the source code
and you will be able to figure out how to use it.
lp.lua -- LPD client
lp.lua -- LPD client library
The lp.lua module implements the client part of the Line Printer Daemon
protocol, used to print files on Unix machines. It is courtesy of David
Burgess and I heard he would be the one supporting it, even after I messed
with it. See the source code and the lpr.lua in the examples directory.
The lp.lua module implements the client part of the Line
Printer Daemon protocol, used to print files on Unix
machines. It is courtesy of David Burgess! See the source
code and the lpr.lua in the examples directory.
b64.lua
qp.lua
eol.lua
These are tiny programs that perform Base64,
Quoted-Printable and end-of-line marker conversions.
get.lua -- file retriever
This little program is a client that uses the FTP and HTTP code to
implement a command line file graber. Just run
This little program is a client that uses the FTP and
HTTP code to implement a command line file graber. Just
run
lua get.lua <remote-file> [<local-file>]
to download a remote file (either ftp:// or http://) to the specified
local file. The program also prints the download throughput, elapsed
time, bytes already downloaded etc during download.
to download a remote file (either ftp:// or http://) to
the specified local file. The program also prints the
download throughput, elapsed time, bytes already downloaded
etc during download.
check-memory.lua -- checks memory consumption
This is just to see how much memory each module uses.
dispatch.lua -- coroutine based dispatcher
This is a first try at a coroutine based non-blocking
dispatcher for LuaSocket. Take a look at 'check-links.lua'
and at 'forward.lua' to see how to use it.
check-links.lua -- HTML link checker program
This little program scans a HTML file and checks for broken links. It is
similar to check-links.pl by Jamie Zawinski, but uses all facilities of
the LuaSocket library and the Lua language. It has not been thoroughly
tested, but it should work. Just run
This little program scans a HTML file and checks for broken
links. It is similar to check-links.pl by Jamie Zawinski,
but uses all facilities of the LuaSocket library and the Lua
language. It has not been thoroughly tested, but it should
work. Just run
lua check-links.lua {<url>} > output
lua check-links.lua [-n] {<url>} > output
and open the result to see a list of broken links.
and open the result to see a list of broken links. You can
also use the '-n' switch to run the same program in
non-blocking mode to see how much faster things can get.
forward.lua -- coroutine based forward server
This is a forward server that can accept several connections
and transfers simultaneously using non-blocking I/O and the
coroutine-based dispatcher. You can run, for example
lua forward.lua 8080:proxy.com:3128
to redirect all local conections to port 8080 to the host
'proxy.com' at port 3128.
unix.c and unix.h
This is an implementation of Unix local domain sockets and
demonstrates how to extend LuaSocket with a new type of
transport. It has been tested on Linux and on Mac OS X.
Good luck,
Diego.

View File

@ -7,7 +7,7 @@ function load(s)
print(s .. ":\t " .. (b-a) .. "k")
end
load("url")
load("socket.url")
load("ltn12")
load("socket")
load("mime")

View File

@ -4,125 +4,128 @@
DIST = luasocket-2.0
COMPAT = compat-5.1r4
COMPAT = src/compat-5.1r4
LUA = \
ftp.lua \
http.lua \
ltn12.lua \
mime.lua \
smtp.lua \
socket.lua \
tp.lua \
url.lua
TESTS = \
testclnt.lua \
testsrvr.lua \
testsupport.lua
TEST = \
test/testclnt.lua \
test/testsrvr.lua \
test/testsupport.lua
EXAMPLES = \
check-memory.lua \
b64.lua \
cddb.lua \
daytimeclnt.lua \
echoclnt.lua \
echosrvr.lua \
eol.lua \
listener.lua \
qp.lua \
lpr.lua \
talker.lua \
tinyirc.lua
SAMPLES = \
samples/README \
samples/cddb.lua \
samples/daytimeclnt.lua \
samples/echoclnt.lua \
samples/echosrvr.lua \
samples/listener.lua \
samples/lpr.lua \
samples/talker.lua \
samples/tinyirc.lua
ETC = \
check-links.lua \
check-links-nb.lua \
dict.lua \
get.lua \
unix.c \
unix.h \
lp.lua \
tftp.lua
etc/README \
etc/b64.lua \
etc/check-links.lua \
etc/check-memory.lua \
etc/dict.lua \
etc/dispatch.lua \
etc/eol.lua \
etc/forward.lua \
etc/get.lua \
etc/links \
etc/lp.lua \
etc/qp.lua \
etc/tftp.lua
CORE = \
auxiliar.c \
auxiliar.h \
buffer.c \
buffer.h \
except.c \
except.h \
inet.c \
inet.h \
io.c \
io.h \
luasocket.c \
luasocket.h \
mime.c \
mime.h \
options.c \
options.h \
select.c \
select.h \
socket.h \
tcp.c \
tcp.h \
timeout.c \
timeout.h \
udp.c \
udp.h \
usocket.c \
usocket.h \
wsocket.c \
wsocket.h
SRC = \
src/auxiliar.c \
src/auxiliar.h \
src/buffer.c \
src/buffer.h \
src/except.c \
src/except.h \
src/inet.c \
src/inet.h \
src/io.c \
src/io.h \
src/luasocket.c \
src/luasocket.h \
src/mime.c \
src/mime.h \
src/options.c \
src/options.h \
src/select.c \
src/select.h \
src/socket.h \
src/tcp.c \
src/tcp.h \
src/timeout.c \
src/timeout.h \
src/udp.c \
src/udp.h \
src/unix.c \
src/unix.h \
src/usocket.c \
src/usocket.h \
src/wsocket.c \
src/wsocket.h \
src/ftp.lua \
src/http.lua \
src/ltn12.lua \
src/mime.lua \
src/smtp.lua \
src/socket.lua \
src/tp.lua \
src/url.lua
MAKE = \
makefile \
config \
luasocket.sln \
luasocket.vcproj \
socket.vcproj \
mime.vcproj
MANUAL = \
manual/dns.html \
manual/ftp.html \
manual/home.html \
manual/http.html \
manual/introduction.html \
manual/ltn12.html \
manual/luasocket.png \
manual/mime.html \
manual/installation.html \
manual/reference.css \
manual/reference.html \
manual/smtp.html \
manual/socket.html \
manual/tcp.html \
manual/udp.html \
manual/url.html
DOC = \
doc/dns.html \
doc/ftp.html \
doc/home.html \
doc/http.html \
doc/installation.html \
doc/introduction.html \
doc/ltn12.html \
doc/luasocket.png \
doc/mime.html \
doc/reference.css \
doc/reference.html \
doc/smtp.html \
doc/socket.html \
doc/tcp.html \
doc/udp.html \
doc/url.html
dist:
mkdir -p $(DIST)/examples
mkdir -p $(DIST)/tests
mkdir -p $(DIST)/etc
mkdir -p $(DIST)/lua
mkdir -p $(DIST)/manual
cp -vfr $(COMPAT) $(DIST)
cp -vf $(CORE) $(DIST)
cp -vf README $(DIST)
mkdir -p $(DIST)
cp -vf NEW $(DIST)
cp -vf LICENSE $(DIST)
cp -vf $(MAKE) $(DIST)
cp -vf make.README $(DIST)/INSTALL
cp -vf $(LUA) $(DIST)/lua
cp -vf lua.README $(DIST)/lua/README
cp -vf $(EXAMPLES) $(DIST)/examples
cp -vf examples.README $(DIST)/examples/README
cp -vf $(TESTS) $(DIST)/tests
cp -vf tests.README $(DIST)/tests/README
mkdir -p $(DIST)/etc
cp -vf $(ETC) $(DIST)/etc
cp -vf etc.README $(DIST)/etc/README
cp -vf $(MANUAL) $(DIST)/manual
mkdir -p $(DIST)/src
cp -vf $(SRC) $(DIST)/src
cp -vfr $(COMPAT) $(DIST)/src
mkdir -p $(DIST)/doc
cp -vf $(DOC) $(DIST)/doc
mkdir -p $(DIST)/samples
cp -vf $(SAMPLES) $(DIST)/samples
mkdir -p $(DIST)/test
cp -vf $(TEST) $(DIST)/test
tar -zcvf $(DIST).tar.gz $(DIST)
zip -r $(DIST).zip $(DIST)

View File

@ -1,59 +1,50 @@
This directory contains some sample programs using LuaSocket. This code
is not supported.
This directory contains some sample programs using
LuaSocket. This code is not supported.
listener.lua -- socket to stdout
talker.lua -- stdin to socket
listener.lua and talker.lua are about the simplest applications you can
write using LuaSocket. Run
listener.lua and talker.lua are about the simplest
applications you can write using LuaSocket. Run
'lua listener.lua' and 'lua talker.lua'
on different terminals. Whatever you type on talk.lua will be
printed by listen.lua.
b64.lua
qp.lua
eol.lua
These are tiny programs that perform Base64, Quoted-Printable and
end-of-line marker conversions.
on different terminals. Whatever you type on talk.lua will
be printed by listen.lua.
lpr.lua -- lpr client
This is a cool program written by David Burgess to print files using the
Line Printer Daemon protocol, widely used in Unix machines. It uses the
lp.lua implementation, in the etc directory. Just run
'lua lpr.lua <filename> queue=<printername>' and the file will print!
This is a cool program written by David Burgess to print
files using the Line Printer Daemon protocol, widely used in
Unix machines. It uses the lp.lua implementation, in the
etc directory. Just run 'lua lpr.lua <filename>
queue=<printername>' and the file will print!
cddb.lua -- CDDB client
This is the first try on a simple CDDB client. Not really useful, but one
day it might become a module.
This is the first try on a simple CDDB client. Not really
useful, but one day it might become a module.
daytimeclnt.lua -- day time client
Just run the program to retrieve the hour and date in readable form from
any server running an UDP daytime daemon.
Just run the program to retrieve the hour and date in
readable form from any server running an UDP daytime daemon.
echoclnt.lua -- UDP echo client
echosrvr.lua -- UDP echo server
These are a UDP echo client/server pair. They work with other client and
servers as well.
These are a UDP echo client/server pair. They work with
other client and servers as well.
tinyirc.lua -- irc like broadcast server
This is a simple server that waits simultaneously on two server sockets
for telnet connections. Everything it receives from the telnet clients
is broadcasted to every other connected client. It tests the select
function and shows how to create a simple server whith LuaSocket. Just
run tinyirc.lua and then open as many telnet connections as you want
to ports 8080 and 8081.
check-memory.lua -- checks memory consumption
This is just to see how much memory each module uses.
This is a simple server that waits simultaneously on two
server sockets for telnet connections. Everything it
receives from the telnet clients is broadcasted to every
other connected client. It tests the select function and
shows how to create a simple server whith LuaSocket. Just
run tinyirc.lua and then open as many telnet connections
as you want to ports 8080 and 8081.
Good luck,
Diego.

View File

@ -1,207 +0,0 @@
-- load our favourite library
local socket = require"socket"
-- creates a new set data structure
function newset()
local reverse = {}
local set = {}
return setmetatable(set, {__index = {
insert = function(set, value)
if not reverse[value] then
table.insert(set, value)
reverse[value] = table.getn(set)
end
end,
remove = function(set, value)
local index = reverse[value]
if index then
reverse[value] = nil
local top = table.remove(set)
if top ~= value then
reverse[top] = index
set[index] = top
end
end
end
}})
end
-- timeout before an inactive thread is kicked
local TIMEOUT = 10
-- set of connections waiting to receive data
local receiving = newset(1)
-- set of sockets waiting to send data
local sending = newset()
-- context for connections and servers
local context = {}
function wait(who, what)
if what == "input" then receiving:insert(who)
else sending:insert(who) end
context[who].last = socket.gettime()
coroutine.yield()
end
-- initializes the forward server
function init()
if table.getn(arg) < 1 then
print("Usage")
print(" lua forward.lua <iport:ohost:oport> ...")
os.exit(1)
end
-- for each tunnel, start a new server socket
for i, v in ipairs(arg) do
-- capture forwarding parameters
local iport, ohost, oport =
socket.skip(2, string.find(v, "([^:]+):([^:]+):([^:]+)"))
assert(iport, "invalid arguments")
-- create our server socket
local server = assert(socket.bind("*", iport))
server:settimeout(0) -- we don't want to be killed by bad luck
-- make sure server is tested for readability
receiving:insert(server)
-- add server context
context[server] = {
thread = coroutine.create(accept),
ohost = ohost,
oport = oport
}
end
end
-- starts a connection in a non-blocking way
function connect(who, host, port)
who:settimeout(0)
local ret, err = who:connect(host, port)
if not ret and err == "timeout" then
wait(who, "output")
ret, err = who:connect(host, port)
if not ret and err ~= "already connected" then
kick(context[who].peer)
kick(who)
return
end
end
return forward(who)
end
-- gets rid of a client
function kick(who)
if who then
sending:remove(who)
receiving:remove(who)
who:close()
context[who] = nil
end
end
-- loops accepting connections and creating new threads to deal with them
function accept(server)
while true do
-- accept a new connection and start a new coroutine to deal with it
local client = server:accept()
if client then
-- create contexts for client and peer.
local peer, err = socket.tcp()
if peer then
context[client] = {
last = socket.gettime(),
-- client goes straight to forwarding loop
thread = coroutine.create(forward),
peer = peer,
}
context[peer] = {
last = socket.gettime(),
peer = client,
-- peer first tries to connect to forwarding address
thread = coroutine.create(connect),
last = socket.gettime()
}
-- resume peer and client so they can do their thing
local ohost = context[server].ohost
local oport = context[server].oport
coroutine.resume(context[peer].thread, peer, ohost, oport)
coroutine.resume(context[client].thread, client)
else
print(err)
client:close()
end
end
-- tell scheduler we are done for now
wait(server, "input")
end
end
-- forwards all data arriving to the appropriate peer
function forward(who)
who:settimeout(0)
while true do
-- wait until we have something to read
wait(who, "input")
-- try to read as much as possible
local data, rec_err, partial = who:receive("*a")
-- if we had an error other than timeout, abort
if rec_err and rec_err ~= "timeout" then return kick(who) end
-- if we got a timeout, we probably have partial results to send
data = data or partial
-- forward what we got right away
local peer = context[who].peer
while true do
-- tell scheduler we need to wait until we can send something
wait(who, "output")
local ret, snd_err
local start = 0
ret, snd_err, start = peer:send(data, start+1)
if ret then break
elseif snd_err ~= "timeout" then return kick(who) end
end
-- if we are done receiving, we are done
if not rec_err then
kick(who)
kick(peer)
break
end
end
end
-- loop waiting until something happens, restarting the thread to deal with
-- what happened, and routing it to wait until something else happens
function go()
while true do
-- check which sockets are interesting and act on them
readable, writable = socket.select(receiving, sending)
-- for all readable connections, resume its thread
for _, who in ipairs(readable) do
if context[who] then
receiving:remove(who)
coroutine.resume(context[who].thread, who)
end
end
-- for all writable connections, do the same
for _, who in ipairs(writable) do
if context[who] then
sending:remove(who)
coroutine.resume(context[who].thread, who)
end
end
-- put all inactive threads in death row
local now = socket.gettime()
local deathrow
for who, data in pairs(context) do
if data.peer then
if now - data.last > TIMEOUT then
-- only create table if at least one is doomed
deathrow = deathrow or {}
deathrow[who] = true
end
end
end
-- finally kick everyone in deathrow
if deathrow then
for who in pairs(deathrow) do kick(who) end
end
end
end
init()
go()

View File

@ -1,7 +1,7 @@
local lp = require("socket.lp")
local function usage()
print('\nUsage: lua lptest.lua [filename] [keyword=val...]\n')
print('\nUsage: lua lpr.lua [filename] [keyword=val...]\n')
print('Valid keywords are :')
print(
' host=remote host or IP address (default "localhost")\n' ..

View File

@ -22,8 +22,8 @@ http.TIMEOUT = 10
local t = socket.gettime()
host = host or "dell-diego" -- "diego.student.princeton.edu"
proxy = proxy or "http://dell-diego:3128"
host = host or "diego.student.princeton.edu"
proxy = proxy or "http://localhost:3128"
prefix = prefix or "/luasocket-test"
cgiprefix = cgiprefix or "/luasocket-test-cgi"
index_file = "index.html"