Added gethostname.

Cleaned up TODO.
Moved luasocket specific stuff from auxiliar.c to luasocket.c
This commit is contained in:
Diego Nehab 2004-01-19 18:22:51 +00:00
parent fbb42b80cb
commit 3f1712ed48
8 changed files with 145 additions and 106 deletions

95
TODO
View File

@ -1,48 +1,37 @@
manual
add shutdown
add gethostname
the need of a content-length header in the post method...
notice the change in callback conventions
the callback.lua module and the new mime module.
escape and unescape in url, not in code!
add timeout and proxy to request table
change stay to redirect
socket.time and socket.sleep
connect with timeout
local connect
add thanks to 'carlos cassino' and 'david burgess'
add new ip- options and reuseaddr option
comment the need of a content-length header in the post method... tests
checar todos os metodos
comment the callback.lua module and the new mime module. checar todas as globais
escape and unescape are missing! checar garbage collection
check for interrupts
new option.c module to put all options (TCP and UDP share...)?
testar os options!
add _tostring methods! add _tostring methods!
add callback module to manual change all modules to use the new namespace scheme
change stay to redirect in http.lua and in manual
add timeout to request table
change code to mime
change *all* modules to be namespace independent
write some utilities that use the code.lua module and put them write some utilities that use the code.lua module and put them
in etc, modify the README.etc file and makefile.dist (eol.lua is done) in etc, modify the README.etc file and makefile.dist (eol.lua is done)
check for interrupt compliance use gethostname it in SMTP
add connect with timeout
add gethostname and use it in HTTP, SMTP etc, and add manual entry.
add thanks for cassino and david burgess
add local connect, and manual entry
add shutdown manual entry
only allocate in case of success
only call select if io fails...
Proxy support pro http
make REUSEADDR an option...
make sure modules know if their dependencies are there. make sure modules know if their dependencies are there.
_
one thing i noticed in usocket.c is that it doesn't check for EINTR
after write(), sendto(), read(), recvfrom() etc. ? the usual trick is
to loop while you get EINTR:
do
ret = write(...);
while(ret < 0 && errno == EINTR)
Read about Read about
250-ENHANCEDSTATUSCODES 250-ENHANCEDSTATUSCODES
250-PIPELINING 250-PIPELINING
250-8BITMIME 250-8BITMIME
@ -62,29 +51,30 @@ Make sure nobody can fuck up with the metatables...
Create a passive mode option for the FTP (good for firewall). Create a passive mode option for the FTP (good for firewall).
Use environments in module definitions or declare all local and create the
function with exported symbols later?
local P = {}
complex = P
setfenv(1, P)
Modules should return their namespace table in the end of the chunk. Modules should return their namespace table in the end of the chunk.
Adjust dates in all files Adjust dates in all files
Test the library on every system possible Test the library on every system possible
Document socket.time and socket.sleep
Implement time critical stuff from code module in C.
Add service name translation. Add service name translation.
Ajeitar o protocolo da luaopen_socket()... sei lá qual é. Ajeitar o protocolo da luaopen_socket()... sei lá qual é.
- testar os options!
- adicionar exemplos de expansão: pipe, local, named pipe - adicionar exemplos de expansão: pipe, local, named pipe
* should be interrupt-safe
* notice the change in callback conventions
* new mime module replacing old code module (faster, more functionality)
* new socket options (many)
* only allocate in case of success
* optimize for success (only call select if fails)
* add proxy support to http
* add gethostname
* local connect
* connect with timeout
* change code to mime
* change stay to redirect
* add shutdown * add shutdown
* change send/recv to avoid using select * change send/recv to avoid using select
* O location do "redirect" pode ser relativo ao servidor atual (não pode, * O location do "redirect" pode ser relativo ao servidor atual (não pode,
@ -93,24 +83,13 @@ Ajeitar o protocolo da luaopen_socket()... sei l
* Padronizar os retornos de funccao * Padronizar os retornos de funccao
* Separar as classes em arquivos * Separar as classes em arquivos
* Retorno de sendto em datagram sockets pode ser refused * Retorno de sendto em datagram sockets pode ser refused
* Fazer compilar com g++
- Fazer compilar com g++
- Thread-safe - Thread-safe
- proteger gethostby*.* com um mutex GLOBAL! - proteger gethostby*.* com um mutex GLOBAL!
- proteger ou atomizar o conjunto (timedout, receive), (timedout, send) - proteger ou atomizar o conjunto (timedout, receive), (timedout, send)
- inet_ntoa também é uma merda. - inet_ntoa também é uma merda.
- SSL - SSL
- checar operações em closed sockets
- checar teste de writable socket com select
- checar todos os metodos
- checar options em UDP
- checar todas as globais
- checar os metodos virtuais
- checar garbage collection
- unix 92 bytes maximo no endereço, incluindo o zero - unix 92 bytes maximo no endereço, incluindo o zero
- unix 9216 maximo de datagram size - unix 9216 maximo de datagram size

View File

@ -17,24 +17,7 @@
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
void aux_open(lua_State *L) void aux_open(lua_State *L)
{ {
/* create namespace table */ ;
lua_pushstring(L, LUASOCKET_LIBNAME);
lua_newtable(L);
#ifdef LUASOCKET_DEBUG
lua_pushstring(L, "debug");
lua_pushnumber(L, 1);
lua_rawset(L, -3);
#endif
/* make version string available so scripts */
lua_pushstring(L, "version");
lua_pushstring(L, LUASOCKET_VERSION);
lua_rawset(L, -3);
/* store namespace as global */
lua_settable(L, LUA_GLOBALSINDEX);
/* make sure modules know what is our namespace */
lua_pushstring(L, "LUASOCKET_LIBNAME");
lua_pushstring(L, LUASOCKET_LIBNAME);
lua_settable(L, LUA_GLOBALSINDEX);
} }
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\

View File

@ -25,7 +25,7 @@ TIMEOUT = 60
-- default port for document retrieval -- default port for document retrieval
PORT = 80 PORT = 80
-- user agent field sent in request -- user agent field sent in request
USERAGENT = "LuaSocket 2.0" USERAGENT = socket.version
-- block size used in transfers -- block size used in transfers
BLOCKSIZE = 8192 BLOCKSIZE = 8192
@ -429,8 +429,7 @@ local function authorize(reqt, parsed, respt)
body_cb = reqt.body_cb, body_cb = reqt.body_cb,
headers = reqt.headers, headers = reqt.headers,
timeout = reqt.timeout, timeout = reqt.timeout,
proxyhost = reqt.proxyhost, proxy = reqt.proxy,
proxyport = reqt.proxyport
} }
return request_cb(autht, respt) return request_cb(autht, respt)
end end
@ -471,8 +470,7 @@ local function redirect(reqt, respt)
body_cb = reqt.body_cb, body_cb = reqt.body_cb,
headers = reqt.headers, headers = reqt.headers,
timeout = reqt.timeout, timeout = reqt.timeout,
proxyhost = reqt.proxyhost, proxy = reqt.proxy
proxyport = reqt.proxyport
} }
respt = request_cb(redirt, respt) respt = request_cb(redirt, respt)
-- we pass the location header as a clue we tried to redirect -- we pass the location header as a clue we tried to redirect
@ -491,7 +489,7 @@ end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
local function request_uri(reqt, parsed) local function request_uri(reqt, parsed)
local url local url
if not reqt.proxyhost and not reqt.proxyport then if not reqt.proxy then
url = { url = {
path = parsed.path, path = parsed.path,
params = parsed.params, params = parsed.params,
@ -522,6 +520,39 @@ local function build_request(data)
return reqt return reqt
end end
-----------------------------------------------------------------------------
-- Connects to a server, be it a proxy or not
-- Input
-- reqt: the request table
-- parsed: the parsed request url
-- Returns
-- sock: connection socket, or nil in case of error
-- err: error message
-----------------------------------------------------------------------------
local function try_connect(reqt, parsed)
reqt.proxy = reqt.proxy or PROXY
local host, port
if reqt.proxy then
local pproxy = socket.url.parse(reqt.proxy)
if not pproxy.port or not pproxy.host then
return nil, "invalid proxy"
end
host, port = pproxy.host, pproxy.port
else
host, port = parsed.host, parsed.port
end
local sock, ret, err
sock, err = socket.tcp()
if not sock then return nil, err end
sock:settimeout(reqt.timeout or TIMEOUT)
ret, err = sock:connect(host, port)
if not ret then
sock:close()
return nil, err
end
return sock
end
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
-- Sends a HTTP request and retrieves the server reply using callbacks to -- Sends a HTTP request and retrieves the server reply using callbacks to
-- send the request body and receive the response body -- send the request body and receive the response body
@ -562,18 +593,8 @@ function request_cb(reqt, respt)
-- fill default headers -- fill default headers
reqt.headers = fill_headers(reqt.headers, parsed) reqt.headers = fill_headers(reqt.headers, parsed)
-- try to connect to server -- try to connect to server
sock, respt.error = socket.tcp() sock, respt.error = try_connect(reqt, parsed)
if not sock then return respt end if not sock then return respt end
-- set connection timeout so that we do not hang forever
sock:settimeout(reqt.timeout or TIMEOUT)
ret, respt.error = sock:connect(
reqt.proxyhost or PROXYHOST or parsed.host,
reqt.proxyport or PROXYPORT or parsed.port
)
if not ret then
sock:close()
return respt
end
-- send request message -- send request message
respt.error = send_request(sock, reqt.method, respt.error = send_request(sock, reqt.method,
request_uri(reqt, parsed), reqt.headers, reqt.body_cb) request_uri(reqt, parsed), reqt.headers, reqt.body_cb)

View File

@ -36,8 +36,63 @@
#include "mime.h" #include "mime.h"
/*=========================================================================*\ /*=========================================================================*\
* Exported functions * Declarations
\*=========================================================================*/ \*=========================================================================*/
static int global_gethostname(lua_State *L);
static int base_open(lua_State *L);
/* functions in library namespace */
static luaL_reg func[] = {
{"gethostname", global_gethostname},
{NULL, NULL}
};
/*-------------------------------------------------------------------------*\
* Setup basic stuff.
\*-------------------------------------------------------------------------*/
static int base_open(lua_State *L)
{
/* create namespace table */
lua_pushstring(L, LUASOCKET_LIBNAME);
lua_newtable(L);
#ifdef LUASOCKET_DEBUG
lua_pushstring(L, "debug");
lua_pushnumber(L, 1);
lua_rawset(L, -3);
#endif
/* make version string available so scripts */
lua_pushstring(L, "version");
lua_pushstring(L, LUASOCKET_VERSION);
lua_rawset(L, -3);
/* store namespace as global */
lua_settable(L, LUA_GLOBALSINDEX);
/* make sure modules know what is our namespace */
lua_pushstring(L, "LUASOCKET_LIBNAME");
lua_pushstring(L, LUASOCKET_LIBNAME);
lua_settable(L, LUA_GLOBALSINDEX);
/* define library functions */
luaL_openlib(L, LUASOCKET_LIBNAME, func, 0);
lua_pop(L, 1);
return 0;
}
/*-------------------------------------------------------------------------*\
* Gets the host name
\*-------------------------------------------------------------------------*/
static int global_gethostname(lua_State *L)
{
char name[257];
name[256] = '\0';
if (gethostname(name, 256) < 0) {
lua_pushnil(L);
lua_pushstring(L, "gethostname failed");
return 2;
} else {
lua_pushstring(L, name);
return 1;
}
}
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Initializes all library modules. * Initializes all library modules.
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
@ -45,6 +100,7 @@ LUASOCKET_API int luaopen_socket(lua_State *L)
{ {
if (!sock_open()) return 0; if (!sock_open()) return 0;
/* initialize all modules */ /* initialize all modules */
base_open(L);
aux_open(L); aux_open(L);
tm_open(L); tm_open(L);
buf_open(L); buf_open(L);

View File

@ -13,7 +13,7 @@
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Current luasocket version * Current luasocket version
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
#define LUASOCKET_VERSION "LuaSocket 2.0 (alpha)" #define LUASOCKET_VERSION "LuaSocket 2.0 (beta)"
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Library's namespace * Library's namespace

View File

@ -153,7 +153,7 @@ static int opt_keepalive(lua_State *L)
return opt_boolean(L, SOL_SOCKET, SO_KEEPALIVE); return opt_boolean(L, SOL_SOCKET, SO_KEEPALIVE);
} }
int opt_linger(lua_State *L) static int opt_linger(lua_State *L)
{ {
p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1); p_tcp tcp = (p_tcp) aux_checkclass(L, "tcp{client}", 1);
struct linger li; struct linger li;
@ -334,7 +334,7 @@ static int meth_settimeout(lua_State *L)
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Creates a master tcp object * Creates a master tcp object
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
int global_create(lua_State *L) static int global_create(lua_State *L)
{ {
t_sock sock; t_sock sock;
const char *err = inet_trycreate(&sock, SOCK_STREAM); const char *err = inet_trycreate(&sock, SOCK_STREAM);

View File

@ -417,7 +417,7 @@ static int meth_setsockname(lua_State *L)
/*-------------------------------------------------------------------------*\ /*-------------------------------------------------------------------------*\
* Creates a master udp object * Creates a master udp object
\*-------------------------------------------------------------------------*/ \*-------------------------------------------------------------------------*/
int global_create(lua_State *L) static int global_create(lua_State *L)
{ {
t_sock sock; t_sock sock;
const char *err = inet_trycreate(&sock, SOCK_DGRAM); const char *err = inet_trycreate(&sock, SOCK_DGRAM);

View File

@ -5,14 +5,15 @@
-- needs "AllowOverride AuthConfig" on /home/c/diego/tec/luasocket/test/auth -- needs "AllowOverride AuthConfig" on /home/c/diego/tec/luasocket/test/auth
dofile("noglobals.lua") dofile("noglobals.lua")
local host, proxyhost, proxyport, request, response local host, proxy, request, response
local ignore, expect, index, prefix, cgiprefix local ignore, expect, index, prefix, cgiprefix
socket.http.TIMEOUT = 5
local t = socket.time() local t = socket.time()
host = host or "diego.princeton.edu" host = host or "diego.student.dyn.cs.princeton.edu"
proxyhost = proxyhost or "localhost" proxy = proxy or "http://localhost:3128"
proxyport = proxyport or 3128
prefix = prefix or "/luasocket-test" prefix = prefix or "/luasocket-test"
cgiprefix = cgiprefix or "/luasocket-test-cgi" cgiprefix = cgiprefix or "/luasocket-test-cgi"
@ -66,6 +67,7 @@ end
io.write("testing request uri correctness: ") io.write("testing request uri correctness: ")
local forth = cgiprefix .. "/request-uri?" .. "this+is+the+query+string" local forth = cgiprefix .. "/request-uri?" .. "this+is+the+query+string"
local back, h, c, e = socket.http.get("http://" .. host .. forth) local back, h, c, e = socket.http.get("http://" .. host .. forth)
if not back then fail(e) end
back = socket.url.parse(back) back = socket.url.parse(back)
if similar(back.query, "this+is+the+query+string") then print("ok") if similar(back.query, "this+is+the+query+string") then print("ok")
else fail() end else fail() end
@ -129,8 +131,7 @@ request = {
method = "POST", method = "POST",
body = index, body = index,
headers = { ["content-length"] = string.len(index) }, headers = { ["content-length"] = string.len(index) },
proxyport = proxyport, proxy= proxy
proxyhost = proxyhost
} }
expect = { expect = {
body = index, body = index,
@ -170,8 +171,7 @@ check_request(request, expect, ignore)
io.write("testing proxy with redirection: ") io.write("testing proxy with redirection: ")
request = { request = {
url = "http://" .. host .. prefix, url = "http://" .. host .. prefix,
proxyhost = proxyhost, proxy = proxy
proxyport = proxyport
} }
expect = { expect = {
body = index, body = index,