mirror of
https://github.com/lunarmodules/luasocket.git
synced 2024-12-25 12:08:21 +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.
|
||||
|
||||
* 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: return values are consistent when reading from closed sockets;
|
||||
* 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
|
||||
|
||||
|
||||
|
||||
ftp send should return server replies?
|
||||
make sure there are no object files in the distribution tarball
|
||||
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
|
||||
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
|
||||
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!
|
||||
</p>
|
||||
|
||||
@ -137,6 +137,9 @@ has been helping a lot too! Thanks to you all!
|
||||
</p>
|
||||
|
||||
<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: return values are consistent when reading from closed sockets;
|
||||
<li> Fixed: case sensitivity in headers of multipart
|
||||
@ -195,7 +198,7 @@ still available for those that have compatibility issues.
|
||||
<p>
|
||||
<small>
|
||||
Last modified by Diego Nehab on <br>
|
||||
Thu Apr 20 00:25:23 EDT 2006
|
||||
Wed Oct 3 02:07:59 BRT 2007
|
||||
</small>
|
||||
</p>
|
||||
</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
|
||||
terminated by a LF character (ASCII 10), optionally preceded by a
|
||||
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>
|
||||
of bytes from the socket.
|
||||
</ul>
|
||||
|
@ -61,7 +61,7 @@ sinks, and pumps, which we introduce below.
|
||||
|
||||
\emph{Filters} are functions that can be repeatedly invoked
|
||||
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
|
||||
result of applying the filter to the concatenation of all
|
||||
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.
|
||||
The initial and final nodes of the network are
|
||||
\emph{sources} and \emph{sinks}, respectively. Less
|
||||
abstractly, a source is a function that produces new data
|
||||
every time it is invoked. Conversely, sinks are functions
|
||||
that give a final destination to the data they receive.
|
||||
Naturally, sources and sinks can also be chained with
|
||||
filters to produce filtered sources and sinks.
|
||||
abstractly, a source is a function that produces new chunks
|
||||
of data every time it is invoked. Conversely, sinks are
|
||||
functions that give a final destination to the chunks of
|
||||
data they receive in sucessive calls. Naturally, sources
|
||||
and sinks can also be chained with filters to produce
|
||||
filtered sources and sinks.
|
||||
|
||||
Finally, filters, chains, sources, and sinks are all passive
|
||||
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
|
||||
interface, which we later refine. The evolution we present
|
||||
is not contrived: it recreates the steps we followed
|
||||
ourselves as we consolidated our understanding of these
|
||||
is not contrived: it recreates the steps we ourselves
|
||||
followed as we consolidated our understanding of these
|
||||
concepts within our application domain.
|
||||
|
||||
\subsection{A simple example}
|
||||
@ -290,8 +291,8 @@ static int eol(lua_State *L) {
|
||||
\end{C}
|
||||
\end{quote}
|
||||
|
||||
When designing your own filters, the challenging part is to
|
||||
decide what will be in the context. For line breaking, for
|
||||
When designing filters, the challenging part is usually
|
||||
deciding what to store in the context. For line breaking, for
|
||||
instance, it could be the number of bytes that still fit in the
|
||||
current line. For Base64 encoding, it could be a string
|
||||
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
|
||||
functions that get their input data from a source (such as
|
||||
the pumps in our examples). By chaining a source with one or
|
||||
more filters, the function can be transparently provided
|
||||
with filtered data, with no need to change its interface.
|
||||
more filters, such functions can be transparently provided
|
||||
with filtered data, with no need to change their interfaces.
|
||||
Here is a factory that does the job:
|
||||
\begin{quote}
|
||||
\begin{lua}
|
||||
@ -434,11 +435,11 @@ end
|
||||
|
||||
\subsection{Sinks}
|
||||
|
||||
Just as we defined an interface for source of data,
|
||||
we can also define an interface for a data destination.
|
||||
We call any function respecting this
|
||||
interface a \emph{sink}. In our first example, we used a
|
||||
file sink connected to the standard output.
|
||||
Just as we defined an interface for a source of data, we can
|
||||
also define an interface for a data destination. We call
|
||||
any function respecting this interface a sink. In our first
|
||||
example, we used a file sink connected to the standard
|
||||
output.
|
||||
|
||||
Sinks receive consecutive chunks of data, until the end of
|
||||
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
|
||||
assembled in memory. Everything is produced on demand,
|
||||
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.
|
||||
|
||||
\section{Conclusions}
|
||||
@ -685,11 +686,10 @@ components. Pumps simply push the data through.
|
||||
The concepts described in this text are the result of long
|
||||
discussions with David Burgess. A version of this text has
|
||||
been released on-line as the Lua Technical Note 012, hence
|
||||
the name of the corresponding LuaSocket module,
|
||||
\texttt{ltn12}. Wim Couwenberg contributed to the
|
||||
implementation of the module, and Adrian Sietsma was the
|
||||
first to notice the correspondence between sources and Lua
|
||||
iterators.
|
||||
the name of the corresponding LuaSocket module, LTN12. Wim
|
||||
Couwenberg contributed to the implementation of the module,
|
||||
and Adrian Sietsma was the first to notice the
|
||||
correspondence between sources and Lua iterators.
|
||||
|
||||
|
||||
\end{document}
|
||||
|
@ -86,7 +86,7 @@ MAKE = \
|
||||
DOC = \
|
||||
doc/dns.html \
|
||||
doc/ftp.html \
|
||||
doc/home.html \
|
||||
doc/index.html \
|
||||
doc/http.html \
|
||||
doc/installation.html \
|
||||
doc/introduction.html \
|
||||
|
28
src/http.lua
28
src/http.lua
@ -142,7 +142,12 @@ function metat.__index:sendbody(headers, source, step)
|
||||
end
|
||||
|
||||
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)"))
|
||||
return self.try(base.tonumber(code), status)
|
||||
end
|
||||
@ -163,6 +168,12 @@ function metat.__index:receivebody(headers, sink, step)
|
||||
sink, step))
|
||||
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()
|
||||
return self.c:close()
|
||||
end
|
||||
@ -271,6 +282,7 @@ function tredirect(reqt, location)
|
||||
create = reqt.create
|
||||
}
|
||||
-- pass location header back as a hint we redirected
|
||||
headers = headers or {}
|
||||
headers.location = headers.location or location
|
||||
return result, code, headers, status
|
||||
end
|
||||
@ -283,17 +295,23 @@ function trequest(reqt)
|
||||
-- send request line and headers
|
||||
h:sendrequestline(nreqt.method, nreqt.uri)
|
||||
h:sendheaders(nreqt.headers)
|
||||
local code = 100
|
||||
local headers, status
|
||||
-- if there is a body, check for server status
|
||||
-- if there is a body, send it
|
||||
if nreqt.source then
|
||||
h:sendbody(nreqt.headers, nreqt.source, nreqt.step)
|
||||
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
|
||||
while code == 100 do
|
||||
code, status = h:receivestatusline()
|
||||
headers = h:receiveheaders()
|
||||
code, status = h:receivestatusline()
|
||||
end
|
||||
headers = h:receiveheaders()
|
||||
-- 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
|
||||
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 ECONNABORTED: return "closed";
|
||||
case ECONNRESET: return "closed";
|
||||
case ETIMEDOUT: return "timedout";
|
||||
case ETIMEDOUT: return "timeout";
|
||||
default: return strerror(errno);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user