From fd729b32a8966291f007567f72f3dc0158bdab35 Mon Sep 17 00:00:00 2001
From: Diego Nehab
+
socket._DEBUG
+socket._DATAGRAMSIZE +
+ ++Default datagram size used by calls to +receive and +receivefrom. +(Unless changed in compile time, the value is 8192.) +
+@@ -393,6 +406,16 @@ The maximum number of sockets that the select function can handle.
+ + ++socket._SOCKETINVALID +
+ ++The OS value for an invalid socket. +
+diff --git a/doc/udp.html b/doc/udp.html index 22d7c72..9437c51 100644 --- a/doc/udp.html +++ b/doc/udp.html @@ -42,7 +42,7 @@
-socket.udp([buffersize]) +socket.udp()
@@ -62,13 +62,6 @@ The setpeername is used to connect the object.
--The optional buffersize parameter -specifies the size of the largest datagram that will -ever be received by the UDP object. The default value is -8192. -
-In case of success, a new unconnected UDP object returned. In case of error, nil is returned, followed by @@ -92,7 +85,7 @@ href=#setoption>setoption will fail.
-socket.udp4([buffersize]) +socket.udp4()
@@ -112,13 +105,6 @@ The setpeername is used to connect the object.
--The optional buffersize parameter -specifies the size of the largest datagram that will -ever be received by the UDP object. The default value is -8192. -
-In case of success, a new unconnected UDP object returned. In case of error, nil is returned, followed by @@ -128,7 +114,7 @@ an error message.
-socket.udp6([buffersize]) +socket.udp6()
@@ -148,13 +134,6 @@ The setpeername is used to connect the object.
--The optional buffersize parameter -specifies the size of the largest datagram that will -ever be received by the UDP object. The default value is -8192. -
-In case of success, a new unconnected UDP object returned. In case of error, nil is returned, followed by @@ -261,8 +240,10 @@ the excess bytes are discarded. If there are less then size bytes available in the current datagram, the available bytes are returned. If size is omitted, the -buffersize argument at creation time is used -(which defaults to 8192 bytes). +compile-time constant socket._DATAGRAMSIZE is used +(it defaults to 8192 bytes). Larger sizes will cause a +temporary buffer to be allocated for the operation.
diff --git a/src/select.c b/src/select.c
index d14c40a..9d133b7 100644
--- a/src/select.c
+++ b/src/select.c
@@ -39,7 +39,10 @@ static luaL_Reg func[] = {
\*-------------------------------------------------------------------------*/
int select_open(lua_State *L) {
lua_pushstring(L, "_SETSIZE");
- lua_pushnumber(L, FD_SETSIZE);
+ lua_pushinteger(L, FD_SETSIZE);
+ lua_rawset(L, -3);
+ lua_pushstring(L, "_SOCKETINVALID");
+ lua_pushinteger(L, SOCKET_INVALID);
lua_rawset(L, -3);
luaL_setfuncs(L, func, 0);
return 0;
diff --git a/src/udp.c b/src/udp.c
index 9c27b60..968dca8 100644
--- a/src/udp.c
+++ b/src/udp.c
@@ -41,7 +41,6 @@ static int meth_setpeername(lua_State *L);
static int meth_close(lua_State *L);
static int meth_setoption(lua_State *L);
static int meth_getoption(lua_State *L);
-static int meth_getbufferlength(lua_State *L);
static int meth_settimeout(lua_State *L);
static int meth_getfd(lua_State *L);
static int meth_setfd(lua_State *L);
@@ -64,7 +63,6 @@ static luaL_Reg udp_methods[] = {
{"setfd", meth_setfd},
{"setoption", meth_setoption},
{"getoption", meth_getoption},
- {"getoption", meth_getbufferlength},
{"setpeername", meth_setpeername},
{"setsockname", meth_setsockname},
{"settimeout", meth_settimeout},
@@ -118,8 +116,7 @@ static luaL_Reg func[] = {
/*-------------------------------------------------------------------------*\
* Initializes module
\*-------------------------------------------------------------------------*/
-int udp_open(lua_State *L)
-{
+int udp_open(lua_State *L) {
/* create classes */
auxiliar_newclass(L, "udp{connected}", udp_methods);
auxiliar_newclass(L, "udp{unconnected}", udp_methods);
@@ -130,6 +127,10 @@ int udp_open(lua_State *L)
auxiliar_add2group(L, "udp{unconnected}", "select{able}");
/* define library functions */
luaL_setfuncs(L, func, 0);
+ /* export default UDP size */
+ lua_pushliteral(L, "_DATAGRAMSIZE");
+ lua_pushinteger(L, UDP_DATAGRAMSIZE);
+ lua_rawset(L, -3);
return 0;
}
@@ -205,30 +206,26 @@ static int meth_sendto(lua_State *L) {
static int meth_receive(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
char buf[UDP_DATAGRAMSIZE];
- size_t len = MAX(udp->len, UDP_DATAGRAMSIZE);
- char *dgram = len > sizeof(buf)? udp->buf: buf;
- size_t got, wanted = (size_t) luaL_optnumber(L, 2, len);
+ size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buf));
+ char *dgram = wanted > sizeof(buf)? (char *) malloc(wanted): buf;
int err;
p_timeout tm = &udp->tm;
timeout_markstart(tm);
- wanted = MIN(wanted, len);
+ if (!dgram) {
+ lua_pushnil(L);
+ lua_pushliteral(L, "out of memory");
+ return 2;
+ }
err = socket_recv(&udp->sock, dgram, wanted, &got, tm);
/* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */
- if (err != IO_DONE && err != IO_CLOSED ) {
+ if (err != IO_DONE && err != IO_CLOSED) {
lua_pushnil(L);
lua_pushstring(L, udp_strerror(err));
+ if (wanted > sizeof(buf)) free(dgram);
return 2;
}
lua_pushlstring(L, dgram, got);
- return 1;
-}
-
-/*-------------------------------------------------------------------------*\
-* Receives data from a UDP socket
-\*-------------------------------------------------------------------------*/
-static int meth_getbufferlength(lua_State *L) {
- p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
- lua_pushinteger(L, MAX(UDP_DATAGRAMSIZE, udp->len));
+ if (wanted > sizeof(buf)) free(dgram);
return 1;
}
@@ -238,9 +235,8 @@ static int meth_getbufferlength(lua_State *L) {
static int meth_receivefrom(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkclass(L, "udp{unconnected}", 1);
char buf[UDP_DATAGRAMSIZE];
- size_t len = MAX(udp->len, UDP_DATAGRAMSIZE);
- char *dgram = len > sizeof(buf)? udp->buf: buf;
- size_t got, wanted = (size_t) luaL_optnumber(L, 2, len);
+ size_t got, wanted = (size_t) luaL_optnumber(L, 2, sizeof(buf));
+ char *dgram = wanted > sizeof(buf)? (char *) malloc(wanted): buf;
struct sockaddr_storage addr;
socklen_t addr_len = sizeof(addr);
char addrstr[INET6_ADDRSTRLEN];
@@ -248,13 +244,18 @@ static int meth_receivefrom(lua_State *L) {
int err;
p_timeout tm = &udp->tm;
timeout_markstart(tm);
- wanted = MIN(wanted, len);
+ if (!dgram) {
+ lua_pushnil(L);
+ lua_pushliteral(L, "out of memory");
+ return 2;
+ }
err = socket_recvfrom(&udp->sock, dgram, wanted, &got, (SA *) &addr,
&addr_len, tm);
/* Unlike TCP, recv() of zero is not closed, but a zero-length packet. */
if (err != IO_DONE && err != IO_CLOSED) {
lua_pushnil(L);
lua_pushstring(L, udp_strerror(err));
+ if (wanted > sizeof(buf)) free(dgram);
return 2;
}
err = getnameinfo((struct sockaddr *)&addr, addr_len, addrstr,
@@ -262,19 +263,20 @@ static int meth_receivefrom(lua_State *L) {
if (err) {
lua_pushnil(L);
lua_pushstring(L, gai_strerror(err));
+ if (wanted > sizeof(buf)) free(dgram);
return 2;
}
lua_pushlstring(L, dgram, got);
lua_pushstring(L, addrstr);
lua_pushinteger(L, (int) strtol(portstr, (char **) NULL, 10));
+ if (wanted > sizeof(buf)) free(dgram);
return 3;
}
/*-------------------------------------------------------------------------*\
* Returns family as string
\*-------------------------------------------------------------------------*/
-static int meth_getfamily(lua_State *L)
-{
+static int meth_getfamily(lua_State *L) {
p_udp udp = (p_udp) auxiliar_checkgroup(L, "udp{any}", 1);
if (udp->family == AF_INET6) {
lua_pushliteral(L, "inet6");
@@ -419,19 +421,13 @@ static int meth_setsockname(lua_State *L) {
* Creates a master udp object
\*-------------------------------------------------------------------------*/
static int udp_create(lua_State *L, int family) {
- p_udp udp = NULL;
- /* optional length for private datagram buffer. this is useful when
- * you need larger datagrams than UDP_DATAGRAMSIZE */
- size_t len = (size_t) luaL_optinteger(L, 1, 0);
- if (len <= UDP_DATAGRAMSIZE) len = 0;
/* allocate udp object */
- udp = (p_udp) lua_newuserdata(L, sizeof(t_udp) + len - 1);
+ p_udp udp = (p_udp) lua_newuserdata(L, sizeof(t_udp));
auxiliar_setclass(L, "udp{unconnected}", -1);
/* if family is AF_UNSPEC, we leave the socket invalid and
* store AF_UNSPEC into family. This will allow it to later be
* replaced with an AF_INET6 or AF_INET socket upon first use. */
udp->sock = SOCKET_INVALID;
- udp->len = len;
timeout_init(&udp->tm, -1, -1);
udp->family = family;
if (family != AF_UNSPEC) {
diff --git a/src/udp.h b/src/udp.h
index da27a7a..be9b6a5 100644
--- a/src/udp.h
+++ b/src/udp.h
@@ -23,8 +23,6 @@ typedef struct t_udp_ {
t_socket sock;
t_timeout tm;
int family;
- size_t len; /* length of datagram buffer below */
- char buf[1]; /* allocate larger structure to hold actual buffer */
} t_udp;
typedef t_udp *p_udp;
diff --git a/test/testclnt.lua b/test/testclnt.lua
index ee1201f..170e187 100644
--- a/test/testclnt.lua
+++ b/test/testclnt.lua
@@ -669,7 +669,6 @@ local udp_methods = {
"settimeout"
}
-
------------------------------------------------------------------------
test_methods(socket.udp(), udp_methods)
do local sock = socket.tcp6()
--
cgit v1.2.3-55-g6feb
From 944305dc21350fd2ec32a9552d893da86894fd62 Mon Sep 17 00:00:00 2001
From: Diego Nehab
-mime.normalize([marker])
-
-Converts most common end-of-line markers to a specific given marker.
-
-Marker is the new marker. It defaults to CRLF, the canonic
-end-of-line marker defined by the MIME standard.
-
-The function returns a filter that performs the conversion.
-
-Note: There is no perfect solution to this problem. Different end-of-line
-markers are an evil that will probably plague developers forever.
-This function, however, will work perfectly for text created with any of
-the most common end-of-line markers, i.e. the Mac OS (CR), the Unix (LF),
-or the DOS (CRLF) conventions. Even if the data has mixed end-of-line
-markers, the function will still work well, although it doesn't
-guarantee that the number of empty lines will be correct.
-
+mime.normalize([marker])
+
+Converts most common end-of-line markers to a specific given marker.
+
+Marker is the new marker. It defaults to CRLF, the canonic
+end-of-line marker defined by the MIME standard.
+
+The function returns a filter that performs the conversion.
+
+Note: There is no perfect solution to this problem. Different end-of-line
+markers are an evil that will probably plague developers forever.
+This function, however, will work perfectly for text created with any of
+the most common end-of-line markers, i.e. the Mac OS (CR), the Unix (LF),
+or the DOS (CRLF) conventions. Even if the data has mixed end-of-line
+markers, the function will still work well, although it doesn't
+guarantee that the number of empty lines will be correct.
+
@@ -466,7 +467,7 @@ marker.
Last modified by Diego Nehab on
+smtp.message(mesgt)
+
+Returns a simple
+LTN12 source that sends an SMTP message body, possibly multipart (arbitrarily deep).
+
+The only parameter of the function is a table describing the message.
+Mesgt has the following form (notice the recursive structure):
+
+For a simple message, all that is needed is a set of headers
+and the body. The message body can be given as a string
+or as a simple
+LTN12
+source. For multipart messages, the body is a table that
+recursively defines each part as an independent message, plus an optional
+preamble and epilogue.
+
+The function returns a simple
+LTN12
+source that produces the
+message contents as defined by mesgt, chunk by chunk.
+Hopefully, the following
+example will make things clear. When in doubt, refer to the appropriate RFC
+as listed in the introduction.
@@ -275,123 +393,6 @@ r, e = smtp.send{
}
-
-
-
-smtp.message(mesgt)
-
-Returns a simple
-LTN12 source that sends an SMTP message body, possibly multipart (arbitrarily deep).
-
-The only parameter of the function is a table describing the message.
-Mesgt has the following form (notice the recursive structure):
-
-For a simple message, all that is needed is a set of headers
-and the body. The message body can be given as a string
-or as a simple
-LTN12
-source. For multipart messages, the body is a table that
-recursively defines each part as an independent message, plus an optional
-preamble and epilogue.
-
-The function returns a simple
-LTN12
-source that produces the
-message contents as defined by mesgt, chunk by chunk.
-Hopefully, the following
-example will make things clear. When in doubt, refer to the appropriate RFC
-as listed in the introduction. High-level filters
-
-
-
-Thu Apr 20 00:25:44 EDT 2006
+Fri Mar 4 15:19:17 BRT 2016
+
+
+
+
+
+
+mesgt = {
+ headers = header-table,
+ body = LTN12 source or string or
+multipart-mesgt
+}
+
+multipart-mesgt = {
+ [preamble = string,]
+ [1] = mesgt,
+ [2] = mesgt,
+ ...
+ [n] = mesgt,
+ [epilogue = string,]
+}
+
+-- load the smtp support and its friends
+local smtp = require("socket.smtp")
+local mime = require("mime")
+local ltn12 = require("ltn12")
+
+-- creates a source to send a message with two parts. The first part is
+-- plain text, the second part is a PNG image, encoded as base64.
+source = smtp.message{
+ headers = {
+ -- Remember that headers are *ignored* by smtp.send.
+ from = "Sicrano de Oliveira <sicrano@example.com>",
+ to = "Fulano da Silva <fulano@example.com>",
+ subject = "Here is a message with attachments"
+ },
+ body = {
+ preamble = "If your client doesn't understand attachments, \r\n" ..
+ "it will still display the preamble and the epilogue.\r\n" ..
+ "Preamble will probably appear even in a MIME enabled client.",
+ -- first part: no headers means plain text, us-ascii.
+ -- The mime.eol low-level filter normalizes end-of-line markers.
+ [1] = {
+ body = mime.eol(0, [[
+ Lines in a message body should always end with CRLF.
+ The smtp module will *NOT* perform translation. However, the
+ send function *DOES* perform SMTP stuffing, whereas the message
+ function does *NOT*.
+ ]])
+ },
+ -- second part: headers describe content to be a png image,
+ -- sent under the base64 transfer content encoding.
+ -- notice that nothing happens until the message is actually sent.
+ -- small chunks are loaded into memory right before transmission and
+ -- translation happens on the fly.
+ [2] = {
+ headers = {
+ ["content-type"] = 'image/png; name="image.png"',
+ ["content-disposition"] = 'attachment; filename="image.png"',
+ ["content-description"] = 'a beautiful image',
+ ["content-transfer-encoding"] = "BASE64"
+ },
+ body = ltn12.source.chain(
+ ltn12.source.file(io.open("image.png", "rb")),
+ ltn12.filter.chain(
+ mime.encode("base64"),
+ mime.wrap()
+ )
+ )
+ },
+ epilogue = "This might also show up, but after the attachments"
+ }
+}
+
+-- finally send it
+r, e = smtp.send{
+ from = "<sicrano@example.com>",
+ rcpt = "<fulano@example.com>",
+ source = source,
+}
+
+
+
-
-
-
-
-
-
-mesgt = {
- headers = header-table,
- body = LTN12 source or string or
-multipart-mesgt
-}
-
-multipart-mesgt = {
- [preamble = string,]
- [1] = mesgt,
- [2] = mesgt,
- ...
- [n] = mesgt,
- [epilogue = string,]
-}
-
--- load the smtp support and its friends
-local smtp = require("socket.smtp")
-local mime = require("mime")
-local ltn12 = require("ltn12")
-
--- creates a source to send a message with two parts. The first part is
--- plain text, the second part is a PNG image, encoded as base64.
-source = smtp.message{
- headers = {
- -- Remember that headers are *ignored* by smtp.send.
- from = "Sicrano de Oliveira <sicrano@example.com>",
- to = "Fulano da Silva <fulano@example.com>",
- subject = "Here is a message with attachments"
- },
- body = {
- preamble = "If your client doesn't understand attachments, \r\n" ..
- "it will still display the preamble and the epilogue.\r\n" ..
- "Preamble will probably appear even in a MIME enabled client.",
- -- first part: no headers means plain text, us-ascii.
- -- The mime.eol low-level filter normalizes end-of-line markers.
- [1] = {
- body = mime.eol(0, [[
- Lines in a message body should always end with CRLF.
- The smtp module will *NOT* perform translation. However, the
- send function *DOES* perform SMTP stuffing, whereas the message
- function does *NOT*.
- ]])
- },
- -- second part: headers describe content to be a png image,
- -- sent under the base64 transfer content encoding.
- -- notice that nothing happens until the message is actually sent.
- -- small chunks are loaded into memory right before transmission and
- -- translation happens on the fly.
- [2] = {
- headers = {
- ["content-type"] = 'image/png; name="image.png"',
- ["content-disposition"] = 'attachment; filename="image.png"',
- ["content-description"] = 'a beautiful image',
- ["content-transfer-encoding"] = "BASE64"
- },
- body = ltn12.source.chain(
- ltn12.source.file(io.open("image.png", "rb")),
- ltn12.filter.chain(
- mime.encode("base64"),
- mime.wrap()
- )
- )
- },
- epilogue = "This might also show up, but after the attachments"
- }
-}
-
--- finally send it
-r, e = smtp.send{
- from = "<sicrano@example.com>",
- rcpt = "<fulano@example.com>",
- source = source,
-}
-
-