From 5e09779c7f6b1710150d5a0f12d86ded7ede75c6 Mon Sep 17 00:00:00 2001
From: Diego Nehab
Date: Sun, 20 Nov 2005 08:56:19 +0000
Subject: [PATCH] In pre release mode!
---
NEW | 69 ++++++++++----
config | 20 ++--
doc/http.html | 13 ++-
doc/index.html | 7 ++
doc/installation.html | 8 +-
doc/tcp.html | 1 +
etc/README | 93 +++++++++++++------
etc/check-memory.lua | 2 +-
makefile.dist | 203 +++++++++++++++++++++--------------------
samples/README | 57 +++++-------
samples/forward.lua | 207 ------------------------------------------
samples/lpr.lua | 2 +-
test/httptest.lua | 4 +-
13 files changed, 279 insertions(+), 407 deletions(-)
delete mode 100644 samples/forward.lua
diff --git a/NEW b/NEW
index b84b5fb..7c94368 100644
--- a/NEW
+++ b/NEW
@@ -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.
diff --git a/config b/config
index 175a885..255477b 100644
--- a/config
+++ b/config
@@ -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
diff --git a/doc/http.html b/doc/http.html
index 096ab2b..9d80c23 100644
--- a/doc/http.html
+++ b/doc/http.html
@@ -209,11 +209,16 @@ Here are a few examples with the simple interface:
-- 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.
diff --git a/doc/index.html b/doc/index.html
index 3d5acb3..7ac0d4c 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -165,6 +165,13 @@ support.
+- 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;
diff --git a/doc/installation.html b/doc/installation.html
index 1b82ed3..4086f41 100644
--- a/doc/installation.html
+++ b/doc/installation.html
@@ -76,9 +76,9 @@ distribution directory structure:
<SHARE>/compat-5.1.lua
<SHARE>/ltn12.lua
-<SHARE>/mime/init.lua (originally mime.lua)
+<SHARE>/mime/mime.lua
<LIB>/mime/core.dll
-<SHARE>/socket/init.lua (originally socket.lua)
+<SHARE>/socket/socket.lua
<LIB>/socket/core.dll
<SHARE>/socket/http.lua
<SHARE>/socket/tp.lua
@@ -88,9 +88,7 @@ distribution directory structure:
Naturally, on Unix systems, core.dll
-would be replaced by core.so. Notice that in the instalation,
-socket.lua becomes socket/init.lua, and the same happens
-with mime.lua, which becomes mime/init.lua.
+would be replaced by core.so.
In order for the interpreter to find all LuaSocket components, three
diff --git a/doc/tcp.html b/doc/tcp.html
index 5c810de..2c687c0 100644
--- a/doc/tcp.html
+++ b/doc/tcp.html
@@ -446,6 +446,7 @@ The method returns 1 in case of success and nil otherwise.
+master:settimeout(value [, mode])
client:settimeout(value [, mode])
server:settimeout(value [, mode])
diff --git a/etc/README b/etc/README
index 6be740b..5a919cd 100644
--- a/etc/README
+++ b/etc/README
@@ -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 []
-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 {} > output
+ lua check-links.lua [-n] {} > 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.
diff --git a/etc/check-memory.lua b/etc/check-memory.lua
index 7bcdf67..7bd984d 100644
--- a/etc/check-memory.lua
+++ b/etc/check-memory.lua
@@ -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")
diff --git a/makefile.dist b/makefile.dist
index 8b79653..54a9751 100644
--- a/makefile.dist
+++ b/makefile.dist
@@ -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)
diff --git a/samples/README b/samples/README
index 0100a4a..e63a6f5 100644
--- a/samples/README
+++ b/samples/README
@@ -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 queue=' 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
+queue=' 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.
diff --git a/samples/forward.lua b/samples/forward.lua
deleted file mode 100644
index 548a753..0000000
--- a/samples/forward.lua
+++ /dev/null
@@ -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 ...")
- 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()
diff --git a/samples/lpr.lua b/samples/lpr.lua
index caab387..5ab4d69 100644
--- a/samples/lpr.lua
+++ b/samples/lpr.lua
@@ -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' ..
diff --git a/test/httptest.lua b/test/httptest.lua
index 0951389..c05b4cc 100644
--- a/test/httptest.lua
+++ b/test/httptest.lua
@@ -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"