mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-26 04:28:20 +01:00
New release.
This commit is contained in:
parent
52ac60af81
commit
d1a72435d5
3
NEW
3
NEW
@ -2,6 +2,9 @@ What's New
|
|||||||
|
|
||||||
This is just a bug-fix/update release.
|
This is just a bug-fix/update release.
|
||||||
|
|
||||||
|
* Improved: http.request() now supports deprecated HTTP/0.9
|
||||||
|
servers (Florian Berger)
|
||||||
|
* Fixed: could return "timedout" instead of "timeout" (Leo Leo)
|
||||||
* Fixed: crash when reading '*a' on closed socket (Paul Ducklin);
|
* Fixed: crash when reading '*a' on closed socket (Paul Ducklin);
|
||||||
* Fixed: return values are consistent when reading from closed sockets;
|
* Fixed: return values are consistent when reading from closed sockets;
|
||||||
* Fixed: case sensitivity in headers of multipart messages in
|
* Fixed: case sensitivity in headers of multipart messages in
|
||||||
|
3
TODO
3
TODO
@ -1,7 +1,6 @@
|
|||||||
|
replace \r\n with \0xD\0xA in everything
|
||||||
New mime support
|
New mime support
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ftp send should return server replies?
|
ftp send should return server replies?
|
||||||
make sure there are no object files in the distribution tarball
|
make sure there are no object files in the distribution tarball
|
||||||
http handling of 100-continue, see DB patch
|
http handling of 100-continue, see DB patch
|
||||||
|
@ -124,7 +124,7 @@ Special thanks go to
|
|||||||
David Burgess, who has helped push the library to a new level of quality and
|
David Burgess, who has helped push the library to a new level of quality and
|
||||||
from whom I have learned a lot of stuff that doesn't show up in RFCs.
|
from whom I have learned a lot of stuff that doesn't show up in RFCs.
|
||||||
Special thanks also to Carlos Cassino, who played a big part in the
|
Special thanks also to Carlos Cassino, who played a big part in the
|
||||||
extensible design seen in the C core of LuaSocket 2.0. Recently, Mike Pall
|
extensible design seen in the C core of LuaSocket 2.0. Mike Pall
|
||||||
has been helping a lot too! Thanks to you all!
|
has been helping a lot too! Thanks to you all!
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@ -137,6 +137,9 @@ has been helping a lot too! Thanks to you all!
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
<li> Improved: http.request() now supports deprecated
|
||||||
|
HTTP/0.9 servers (Florian Berger);
|
||||||
|
<li> Fixed: could return "timedout" instead of "timeout" (Leo Leo);
|
||||||
<li> Fixed: crash when reading '*a' on closed socket (Paul Ducklin);
|
<li> Fixed: crash when reading '*a' on closed socket (Paul Ducklin);
|
||||||
<li> Fixed: return values are consistent when reading from closed sockets;
|
<li> Fixed: return values are consistent when reading from closed sockets;
|
||||||
<li> Fixed: case sensitivity in headers of multipart
|
<li> Fixed: case sensitivity in headers of multipart
|
||||||
@ -195,7 +198,7 @@ still available for those that have compatibility issues.
|
|||||||
<p>
|
<p>
|
||||||
<small>
|
<small>
|
||||||
Last modified by Diego Nehab on <br>
|
Last modified by Diego Nehab on <br>
|
||||||
Thu Apr 20 00:25:23 EDT 2006
|
Wed Oct 3 02:07:59 BRT 2007
|
||||||
</small>
|
</small>
|
||||||
</p>
|
</p>
|
||||||
</center>
|
</center>
|
||||||
|
@ -284,7 +284,8 @@ closed. No end-of-line translation is performed;
|
|||||||
<li> '<tt>*l</tt>': reads a line of text from the socket. The line is
|
<li> '<tt>*l</tt>': reads a line of text from the socket. The line is
|
||||||
terminated by a LF character (ASCII 10), optionally preceded by a
|
terminated by a LF character (ASCII 10), optionally preceded by a
|
||||||
CR character (ASCII 13). The CR and LF characters are not included in
|
CR character (ASCII 13). The CR and LF characters are not included in
|
||||||
the returned line. This is the default pattern;
|
the returned line. In fact, <em>all</em> CR characters are
|
||||||
|
ignored by the pattern. This is the default pattern;
|
||||||
<li> <tt>number</tt>: causes the method to read a specified <tt>number</tt>
|
<li> <tt>number</tt>: causes the method to read a specified <tt>number</tt>
|
||||||
of bytes from the socket.
|
of bytes from the socket.
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -61,7 +61,7 @@ sinks, and pumps, which we introduce below.
|
|||||||
|
|
||||||
\emph{Filters} are functions that can be repeatedly invoked
|
\emph{Filters} are functions that can be repeatedly invoked
|
||||||
with chunks of input, successively returning processed
|
with chunks of input, successively returning processed
|
||||||
chunks of output. More importantly, the result of
|
chunks of output. Naturally, the result of
|
||||||
concatenating all the output chunks must be the same as the
|
concatenating all the output chunks must be the same as the
|
||||||
result of applying the filter to the concatenation of all
|
result of applying the filter to the concatenation of all
|
||||||
input chunks. In fancier language, filters \emph{commute}
|
input chunks. In fancier language, filters \emph{commute}
|
||||||
@ -81,11 +81,12 @@ which data will flow, potentially being transformed many
|
|||||||
times along the way. Chains connect these nodes together.
|
times along the way. Chains connect these nodes together.
|
||||||
The initial and final nodes of the network are
|
The initial and final nodes of the network are
|
||||||
\emph{sources} and \emph{sinks}, respectively. Less
|
\emph{sources} and \emph{sinks}, respectively. Less
|
||||||
abstractly, a source is a function that produces new data
|
abstractly, a source is a function that produces new chunks
|
||||||
every time it is invoked. Conversely, sinks are functions
|
of data every time it is invoked. Conversely, sinks are
|
||||||
that give a final destination to the data they receive.
|
functions that give a final destination to the chunks of
|
||||||
Naturally, sources and sinks can also be chained with
|
data they receive in sucessive calls. Naturally, sources
|
||||||
filters to produce filtered sources and sinks.
|
and sinks can also be chained with filters to produce
|
||||||
|
filtered sources and sinks.
|
||||||
|
|
||||||
Finally, filters, chains, sources, and sinks are all passive
|
Finally, filters, chains, sources, and sinks are all passive
|
||||||
entities: they must be repeatedly invoked in order for
|
entities: they must be repeatedly invoked in order for
|
||||||
@ -95,8 +96,8 @@ sink, and indirectly through all intervening filters.
|
|||||||
|
|
||||||
In the following sections, we start with a simplified
|
In the following sections, we start with a simplified
|
||||||
interface, which we later refine. The evolution we present
|
interface, which we later refine. The evolution we present
|
||||||
is not contrived: it recreates the steps we followed
|
is not contrived: it recreates the steps we ourselves
|
||||||
ourselves as we consolidated our understanding of these
|
followed as we consolidated our understanding of these
|
||||||
concepts within our application domain.
|
concepts within our application domain.
|
||||||
|
|
||||||
\subsection{A simple example}
|
\subsection{A simple example}
|
||||||
@ -290,8 +291,8 @@ static int eol(lua_State *L) {
|
|||||||
\end{C}
|
\end{C}
|
||||||
\end{quote}
|
\end{quote}
|
||||||
|
|
||||||
When designing your own filters, the challenging part is to
|
When designing filters, the challenging part is usually
|
||||||
decide what will be in the context. For line breaking, for
|
deciding what to store in the context. For line breaking, for
|
||||||
instance, it could be the number of bytes that still fit in the
|
instance, it could be the number of bytes that still fit in the
|
||||||
current line. For Base64 encoding, it could be a string
|
current line. For Base64 encoding, it could be a string
|
||||||
with the bytes that remain after the division of the input
|
with the bytes that remain after the division of the input
|
||||||
@ -408,8 +409,8 @@ associated filter before returning it to the caller.
|
|||||||
Filtered sources are useful when working with
|
Filtered sources are useful when working with
|
||||||
functions that get their input data from a source (such as
|
functions that get their input data from a source (such as
|
||||||
the pumps in our examples). By chaining a source with one or
|
the pumps in our examples). By chaining a source with one or
|
||||||
more filters, the function can be transparently provided
|
more filters, such functions can be transparently provided
|
||||||
with filtered data, with no need to change its interface.
|
with filtered data, with no need to change their interfaces.
|
||||||
Here is a factory that does the job:
|
Here is a factory that does the job:
|
||||||
\begin{quote}
|
\begin{quote}
|
||||||
\begin{lua}
|
\begin{lua}
|
||||||
@ -434,11 +435,11 @@ end
|
|||||||
|
|
||||||
\subsection{Sinks}
|
\subsection{Sinks}
|
||||||
|
|
||||||
Just as we defined an interface for source of data,
|
Just as we defined an interface for a source of data, we can
|
||||||
we can also define an interface for a data destination.
|
also define an interface for a data destination. We call
|
||||||
We call any function respecting this
|
any function respecting this interface a sink. In our first
|
||||||
interface a \emph{sink}. In our first example, we used a
|
example, we used a file sink connected to the standard
|
||||||
file sink connected to the standard output.
|
output.
|
||||||
|
|
||||||
Sinks receive consecutive chunks of data, until the end of
|
Sinks receive consecutive chunks of data, until the end of
|
||||||
data is signaled by a \nil\ input chunk. A sink can be
|
data is signaled by a \nil\ input chunk. A sink can be
|
||||||
@ -665,7 +666,7 @@ SMTP dot-stuffing filter, connects a socket sink
|
|||||||
with the server, and simply pumps the data. The message is never
|
with the server, and simply pumps the data. The message is never
|
||||||
assembled in memory. Everything is produced on demand,
|
assembled in memory. Everything is produced on demand,
|
||||||
transformed in small pieces, and sent to the server in chunks,
|
transformed in small pieces, and sent to the server in chunks,
|
||||||
including the file attachment that is loaded from disk and
|
including the file attachment which is loaded from disk and
|
||||||
encoded on the fly. It just works.
|
encoded on the fly. It just works.
|
||||||
|
|
||||||
\section{Conclusions}
|
\section{Conclusions}
|
||||||
@ -685,11 +686,10 @@ components. Pumps simply push the data through.
|
|||||||
The concepts described in this text are the result of long
|
The concepts described in this text are the result of long
|
||||||
discussions with David Burgess. A version of this text has
|
discussions with David Burgess. A version of this text has
|
||||||
been released on-line as the Lua Technical Note 012, hence
|
been released on-line as the Lua Technical Note 012, hence
|
||||||
the name of the corresponding LuaSocket module,
|
the name of the corresponding LuaSocket module, LTN12. Wim
|
||||||
\texttt{ltn12}. Wim Couwenberg contributed to the
|
Couwenberg contributed to the implementation of the module,
|
||||||
implementation of the module, and Adrian Sietsma was the
|
and Adrian Sietsma was the first to notice the
|
||||||
first to notice the correspondence between sources and Lua
|
correspondence between sources and Lua iterators.
|
||||||
iterators.
|
|
||||||
|
|
||||||
|
|
||||||
\end{document}
|
\end{document}
|
||||||
|
@ -86,7 +86,7 @@ MAKE = \
|
|||||||
DOC = \
|
DOC = \
|
||||||
doc/dns.html \
|
doc/dns.html \
|
||||||
doc/ftp.html \
|
doc/ftp.html \
|
||||||
doc/home.html \
|
doc/index.html \
|
||||||
doc/http.html \
|
doc/http.html \
|
||||||
doc/installation.html \
|
doc/installation.html \
|
||||||
doc/introduction.html \
|
doc/introduction.html \
|
||||||
|
28
src/http.lua
28
src/http.lua
@ -142,7 +142,12 @@ function metat.__index:sendbody(headers, source, step)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function metat.__index:receivestatusline()
|
function metat.__index:receivestatusline()
|
||||||
local status = self.try(self.c:receive())
|
local status = self.try(self.c:receive(5))
|
||||||
|
-- identify HTTP/0.9 responses, which do not contain a status line
|
||||||
|
-- this is just a heuristic, but is what the RFC recommends
|
||||||
|
if status ~= "HTTP/" then return nil, status end
|
||||||
|
-- otherwise proceed reading a status line
|
||||||
|
status = self.try(self.c:receive("*l", status))
|
||||||
local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)"))
|
local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)"))
|
||||||
return self.try(base.tonumber(code), status)
|
return self.try(base.tonumber(code), status)
|
||||||
end
|
end
|
||||||
@ -163,6 +168,12 @@ function metat.__index:receivebody(headers, sink, step)
|
|||||||
sink, step))
|
sink, step))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function metat.__index:receive09body(status, sink, step)
|
||||||
|
local source = ltn12.source.rewind(socket.source("until-closed", self.c))
|
||||||
|
source(status)
|
||||||
|
return self.try(ltn12.pump.all(source, sink, step))
|
||||||
|
end
|
||||||
|
|
||||||
function metat.__index:close()
|
function metat.__index:close()
|
||||||
return self.c:close()
|
return self.c:close()
|
||||||
end
|
end
|
||||||
@ -271,6 +282,7 @@ function tredirect(reqt, location)
|
|||||||
create = reqt.create
|
create = reqt.create
|
||||||
}
|
}
|
||||||
-- pass location header back as a hint we redirected
|
-- pass location header back as a hint we redirected
|
||||||
|
headers = headers or {}
|
||||||
headers.location = headers.location or location
|
headers.location = headers.location or location
|
||||||
return result, code, headers, status
|
return result, code, headers, status
|
||||||
end
|
end
|
||||||
@ -283,17 +295,23 @@ function trequest(reqt)
|
|||||||
-- send request line and headers
|
-- send request line and headers
|
||||||
h:sendrequestline(nreqt.method, nreqt.uri)
|
h:sendrequestline(nreqt.method, nreqt.uri)
|
||||||
h:sendheaders(nreqt.headers)
|
h:sendheaders(nreqt.headers)
|
||||||
local code = 100
|
-- if there is a body, send it
|
||||||
local headers, status
|
|
||||||
-- if there is a body, check for server status
|
|
||||||
if nreqt.source then
|
if nreqt.source then
|
||||||
h:sendbody(nreqt.headers, nreqt.source, nreqt.step)
|
h:sendbody(nreqt.headers, nreqt.source, nreqt.step)
|
||||||
end
|
end
|
||||||
|
local code, status = h:receivestatusline()
|
||||||
|
-- if it is an HTTP/0.9 server, simply get the body and we are done
|
||||||
|
if not code then
|
||||||
|
h:receive09body(status, nreqt.sink, nreqt.step)
|
||||||
|
return 1, 200
|
||||||
|
end
|
||||||
|
local headers
|
||||||
-- ignore any 100-continue messages
|
-- ignore any 100-continue messages
|
||||||
while code == 100 do
|
while code == 100 do
|
||||||
code, status = h:receivestatusline()
|
|
||||||
headers = h:receiveheaders()
|
headers = h:receiveheaders()
|
||||||
|
code, status = h:receivestatusline()
|
||||||
end
|
end
|
||||||
|
headers = h:receiveheaders()
|
||||||
-- at this point we should have a honest reply from the server
|
-- at this point we should have a honest reply from the server
|
||||||
-- we can't redirect if we already used the source, so we report the error
|
-- we can't redirect if we already used the source, so we report the error
|
||||||
if shouldredirect(nreqt, code, headers) and not nreqt.source then
|
if shouldredirect(nreqt, code, headers) and not nreqt.source then
|
||||||
|
@ -359,7 +359,7 @@ const char *socket_strerror(int err) {
|
|||||||
case ECONNREFUSED: return "connection refused";
|
case ECONNREFUSED: return "connection refused";
|
||||||
case ECONNABORTED: return "closed";
|
case ECONNABORTED: return "closed";
|
||||||
case ECONNRESET: return "closed";
|
case ECONNRESET: return "closed";
|
||||||
case ETIMEDOUT: return "timedout";
|
case ETIMEDOUT: return "timeout";
|
||||||
default: return strerror(errno);
|
default: return strerror(errno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user