diff options
-rw-r--r-- | NEW | 3 | ||||
-rw-r--r-- | TODO | 3 | ||||
-rw-r--r-- | doc/index.html | 7 | ||||
-rw-r--r-- | doc/tcp.html | 3 | ||||
-rw-r--r-- | gem/TODO | 2 | ||||
-rw-r--r-- | gem/ltn012.tex | 46 | ||||
-rw-r--r-- | makefile.dist | 2 | ||||
-rw-r--r-- | src/http.lua | 28 | ||||
-rw-r--r-- | src/usocket.c | 2 |
9 files changed, 59 insertions, 37 deletions
@@ -2,6 +2,9 @@ What's New | |||
2 | 2 | ||
3 | This is just a bug-fix/update release. | 3 | This is just a bug-fix/update release. |
4 | 4 | ||
5 | * Improved: http.request() now supports deprecated HTTP/0.9 | ||
6 | servers (Florian Berger) | ||
7 | * Fixed: could return "timedout" instead of "timeout" (Leo Leo) | ||
5 | * Fixed: crash when reading '*a' on closed socket (Paul Ducklin); | 8 | * Fixed: crash when reading '*a' on closed socket (Paul Ducklin); |
6 | * Fixed: return values are consistent when reading from closed sockets; | 9 | * Fixed: return values are consistent when reading from closed sockets; |
7 | * Fixed: case sensitivity in headers of multipart messages in | 10 | * Fixed: case sensitivity in headers of multipart messages in |
@@ -1,7 +1,6 @@ | |||
1 | replace \r\n with \0xD\0xA in everything | ||
1 | New mime support | 2 | New mime support |
2 | 3 | ||
3 | |||
4 | |||
5 | ftp send should return server replies? | 4 | ftp send should return server replies? |
6 | make sure there are no object files in the distribution tarball | 5 | make sure there are no object files in the distribution tarball |
7 | http handling of 100-continue, see DB patch | 6 | http handling of 100-continue, see DB patch |
diff --git a/doc/index.html b/doc/index.html index 1605af1..57a7907 100644 --- a/doc/index.html +++ b/doc/index.html | |||
@@ -124,7 +124,7 @@ Special thanks go to | |||
124 | David Burgess, who has helped push the library to a new level of quality and | 124 | David Burgess, who has helped push the library to a new level of quality and |
125 | from whom I have learned a lot of stuff that doesn't show up in RFCs. | 125 | from whom I have learned a lot of stuff that doesn't show up in RFCs. |
126 | Special thanks also to Carlos Cassino, who played a big part in the | 126 | Special thanks also to Carlos Cassino, who played a big part in the |
127 | extensible design seen in the C core of LuaSocket 2.0. Recently, Mike Pall | 127 | extensible design seen in the C core of LuaSocket 2.0. Mike Pall |
128 | has been helping a lot too! Thanks to you all! | 128 | has been helping a lot too! Thanks to you all! |
129 | </p> | 129 | </p> |
130 | 130 | ||
@@ -137,6 +137,9 @@ has been helping a lot too! Thanks to you all! | |||
137 | </p> | 137 | </p> |
138 | 138 | ||
139 | <ul> | 139 | <ul> |
140 | <li> Improved: http.request() now supports deprecated | ||
141 | HTTP/0.9 servers (Florian Berger); | ||
142 | <li> Fixed: could return "timedout" instead of "timeout" (Leo Leo); | ||
140 | <li> Fixed: crash when reading '*a' on closed socket (Paul Ducklin); | 143 | <li> Fixed: crash when reading '*a' on closed socket (Paul Ducklin); |
141 | <li> Fixed: return values are consistent when reading from closed sockets; | 144 | <li> Fixed: return values are consistent when reading from closed sockets; |
142 | <li> Fixed: case sensitivity in headers of multipart | 145 | <li> Fixed: case sensitivity in headers of multipart |
@@ -195,7 +198,7 @@ still available for those that have compatibility issues. | |||
195 | <p> | 198 | <p> |
196 | <small> | 199 | <small> |
197 | Last modified by Diego Nehab on <br> | 200 | Last modified by Diego Nehab on <br> |
198 | Thu Apr 20 00:25:23 EDT 2006 | 201 | Wed Oct 3 02:07:59 BRT 2007 |
199 | </small> | 202 | </small> |
200 | </p> | 203 | </p> |
201 | </center> | 204 | </center> |
diff --git a/doc/tcp.html b/doc/tcp.html index 602c73c..a16a09e 100644 --- a/doc/tcp.html +++ b/doc/tcp.html | |||
@@ -284,7 +284,8 @@ closed. No end-of-line translation is performed; | |||
284 | <li> '<tt>*l</tt>': reads a line of text from the socket. The line is | 284 | <li> '<tt>*l</tt>': reads a line of text from the socket. The line is |
285 | terminated by a LF character (ASCII 10), optionally preceded by a | 285 | terminated by a LF character (ASCII 10), optionally preceded by a |
286 | CR character (ASCII 13). The CR and LF characters are not included in | 286 | CR character (ASCII 13). The CR and LF characters are not included in |
287 | the returned line. This is the default pattern; | 287 | the returned line. In fact, <em>all</em> CR characters are |
288 | ignored by the pattern. This is the default pattern; | ||
288 | <li> <tt>number</tt>: causes the method to read a specified <tt>number</tt> | 289 | <li> <tt>number</tt>: causes the method to read a specified <tt>number</tt> |
289 | of bytes from the socket. | 290 | of bytes from the socket. |
290 | </ul> | 291 | </ul> |
diff --git a/gem/TODO b/gem/TODO deleted file mode 100644 index bdbe84e..0000000 --- a/gem/TODO +++ /dev/null | |||
@@ -1,2 +0,0 @@ | |||
1 | Talk a bout Wim | ||
2 | Move thanks into the acknowledgement section. | ||
diff --git a/gem/ltn012.tex b/gem/ltn012.tex index 8eccd46..8027ecc 100644 --- a/gem/ltn012.tex +++ b/gem/ltn012.tex | |||
@@ -61,7 +61,7 @@ sinks, and pumps, which we introduce below. | |||
61 | 61 | ||
62 | \emph{Filters} are functions that can be repeatedly invoked | 62 | \emph{Filters} are functions that can be repeatedly invoked |
63 | with chunks of input, successively returning processed | 63 | with chunks of input, successively returning processed |
64 | chunks of output. More importantly, the result of | 64 | chunks of output. Naturally, the result of |
65 | concatenating all the output chunks must be the same as the | 65 | concatenating all the output chunks must be the same as the |
66 | result of applying the filter to the concatenation of all | 66 | result of applying the filter to the concatenation of all |
67 | input chunks. In fancier language, filters \emph{commute} | 67 | input chunks. In fancier language, filters \emph{commute} |
@@ -81,11 +81,12 @@ which data will flow, potentially being transformed many | |||
81 | times along the way. Chains connect these nodes together. | 81 | times along the way. Chains connect these nodes together. |
82 | The initial and final nodes of the network are | 82 | The initial and final nodes of the network are |
83 | \emph{sources} and \emph{sinks}, respectively. Less | 83 | \emph{sources} and \emph{sinks}, respectively. Less |
84 | abstractly, a source is a function that produces new data | 84 | abstractly, a source is a function that produces new chunks |
85 | every time it is invoked. Conversely, sinks are functions | 85 | of data every time it is invoked. Conversely, sinks are |
86 | that give a final destination to the data they receive. | 86 | functions that give a final destination to the chunks of |
87 | Naturally, sources and sinks can also be chained with | 87 | data they receive in sucessive calls. Naturally, sources |
88 | filters to produce filtered sources and sinks. | 88 | and sinks can also be chained with filters to produce |
89 | filtered sources and sinks. | ||
89 | 90 | ||
90 | Finally, filters, chains, sources, and sinks are all passive | 91 | Finally, filters, chains, sources, and sinks are all passive |
91 | entities: they must be repeatedly invoked in order for | 92 | entities: they must be repeatedly invoked in order for |
@@ -95,8 +96,8 @@ sink, and indirectly through all intervening filters. | |||
95 | 96 | ||
96 | In the following sections, we start with a simplified | 97 | In the following sections, we start with a simplified |
97 | interface, which we later refine. The evolution we present | 98 | interface, which we later refine. The evolution we present |
98 | is not contrived: it recreates the steps we followed | 99 | is not contrived: it recreates the steps we ourselves |
99 | ourselves as we consolidated our understanding of these | 100 | followed as we consolidated our understanding of these |
100 | concepts within our application domain. | 101 | concepts within our application domain. |
101 | 102 | ||
102 | \subsection{A simple example} | 103 | \subsection{A simple example} |
@@ -290,8 +291,8 @@ static int eol(lua_State *L) { | |||
290 | \end{C} | 291 | \end{C} |
291 | \end{quote} | 292 | \end{quote} |
292 | 293 | ||
293 | When designing your own filters, the challenging part is to | 294 | When designing filters, the challenging part is usually |
294 | decide what will be in the context. For line breaking, for | 295 | deciding what to store in the context. For line breaking, for |
295 | instance, it could be the number of bytes that still fit in the | 296 | instance, it could be the number of bytes that still fit in the |
296 | current line. For Base64 encoding, it could be a string | 297 | current line. For Base64 encoding, it could be a string |
297 | with the bytes that remain after the division of the input | 298 | with the bytes that remain after the division of the input |
@@ -408,8 +409,8 @@ associated filter before returning it to the caller. | |||
408 | Filtered sources are useful when working with | 409 | Filtered sources are useful when working with |
409 | functions that get their input data from a source (such as | 410 | functions that get their input data from a source (such as |
410 | the pumps in our examples). By chaining a source with one or | 411 | the pumps in our examples). By chaining a source with one or |
411 | more filters, the function can be transparently provided | 412 | more filters, such functions can be transparently provided |
412 | with filtered data, with no need to change its interface. | 413 | with filtered data, with no need to change their interfaces. |
413 | Here is a factory that does the job: | 414 | Here is a factory that does the job: |
414 | \begin{quote} | 415 | \begin{quote} |
415 | \begin{lua} | 416 | \begin{lua} |
@@ -434,11 +435,11 @@ end | |||
434 | 435 | ||
435 | \subsection{Sinks} | 436 | \subsection{Sinks} |
436 | 437 | ||
437 | Just as we defined an interface for source of data, | 438 | Just as we defined an interface for a source of data, we can |
438 | we can also define an interface for a data destination. | 439 | also define an interface for a data destination. We call |
439 | We call any function respecting this | 440 | any function respecting this interface a sink. In our first |
440 | interface a \emph{sink}. In our first example, we used a | 441 | example, we used a file sink connected to the standard |
441 | file sink connected to the standard output. | 442 | output. |
442 | 443 | ||
443 | Sinks receive consecutive chunks of data, until the end of | 444 | Sinks receive consecutive chunks of data, until the end of |
444 | data is signaled by a \nil\ input chunk. A sink can be | 445 | data is signaled by a \nil\ input chunk. A sink can be |
@@ -665,7 +666,7 @@ SMTP dot-stuffing filter, connects a socket sink | |||
665 | with the server, and simply pumps the data. The message is never | 666 | with the server, and simply pumps the data. The message is never |
666 | assembled in memory. Everything is produced on demand, | 667 | assembled in memory. Everything is produced on demand, |
667 | transformed in small pieces, and sent to the server in chunks, | 668 | transformed in small pieces, and sent to the server in chunks, |
668 | including the file attachment that is loaded from disk and | 669 | including the file attachment which is loaded from disk and |
669 | encoded on the fly. It just works. | 670 | encoded on the fly. It just works. |
670 | 671 | ||
671 | \section{Conclusions} | 672 | \section{Conclusions} |
@@ -685,11 +686,10 @@ components. Pumps simply push the data through. | |||
685 | The concepts described in this text are the result of long | 686 | The concepts described in this text are the result of long |
686 | discussions with David Burgess. A version of this text has | 687 | discussions with David Burgess. A version of this text has |
687 | been released on-line as the Lua Technical Note 012, hence | 688 | been released on-line as the Lua Technical Note 012, hence |
688 | the name of the corresponding LuaSocket module, | 689 | the name of the corresponding LuaSocket module, LTN12. Wim |
689 | \texttt{ltn12}. Wim Couwenberg contributed to the | 690 | Couwenberg contributed to the implementation of the module, |
690 | implementation of the module, and Adrian Sietsma was the | 691 | and Adrian Sietsma was the first to notice the |
691 | first to notice the correspondence between sources and Lua | 692 | correspondence between sources and Lua iterators. |
692 | iterators. | ||
693 | 693 | ||
694 | 694 | ||
695 | \end{document} | 695 | \end{document} |
diff --git a/makefile.dist b/makefile.dist index 58ae5b3..876cf18 100644 --- a/makefile.dist +++ b/makefile.dist | |||
@@ -86,7 +86,7 @@ MAKE = \ | |||
86 | DOC = \ | 86 | DOC = \ |
87 | doc/dns.html \ | 87 | doc/dns.html \ |
88 | doc/ftp.html \ | 88 | doc/ftp.html \ |
89 | doc/home.html \ | 89 | doc/index.html \ |
90 | doc/http.html \ | 90 | doc/http.html \ |
91 | doc/installation.html \ | 91 | doc/installation.html \ |
92 | doc/introduction.html \ | 92 | doc/introduction.html \ |
diff --git a/src/http.lua b/src/http.lua index 9d739a4..3a386a6 100644 --- a/src/http.lua +++ b/src/http.lua | |||
@@ -142,7 +142,12 @@ function metat.__index:sendbody(headers, source, step) | |||
142 | end | 142 | end |
143 | 143 | ||
144 | function metat.__index:receivestatusline() | 144 | function metat.__index:receivestatusline() |
145 | local status = self.try(self.c:receive()) | 145 | local status = self.try(self.c:receive(5)) |
146 | -- identify HTTP/0.9 responses, which do not contain a status line | ||
147 | -- this is just a heuristic, but is what the RFC recommends | ||
148 | if status ~= "HTTP/" then return nil, status end | ||
149 | -- otherwise proceed reading a status line | ||
150 | status = self.try(self.c:receive("*l", status)) | ||
146 | local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)")) | 151 | local code = socket.skip(2, string.find(status, "HTTP/%d*%.%d* (%d%d%d)")) |
147 | return self.try(base.tonumber(code), status) | 152 | return self.try(base.tonumber(code), status) |
148 | end | 153 | end |
@@ -163,6 +168,12 @@ function metat.__index:receivebody(headers, sink, step) | |||
163 | sink, step)) | 168 | sink, step)) |
164 | end | 169 | end |
165 | 170 | ||
171 | function metat.__index:receive09body(status, sink, step) | ||
172 | local source = ltn12.source.rewind(socket.source("until-closed", self.c)) | ||
173 | source(status) | ||
174 | return self.try(ltn12.pump.all(source, sink, step)) | ||
175 | end | ||
176 | |||
166 | function metat.__index:close() | 177 | function metat.__index:close() |
167 | return self.c:close() | 178 | return self.c:close() |
168 | end | 179 | end |
@@ -271,6 +282,7 @@ function tredirect(reqt, location) | |||
271 | create = reqt.create | 282 | create = reqt.create |
272 | } | 283 | } |
273 | -- pass location header back as a hint we redirected | 284 | -- pass location header back as a hint we redirected |
285 | headers = headers or {} | ||
274 | headers.location = headers.location or location | 286 | headers.location = headers.location or location |
275 | return result, code, headers, status | 287 | return result, code, headers, status |
276 | end | 288 | end |
@@ -283,17 +295,23 @@ function trequest(reqt) | |||
283 | -- send request line and headers | 295 | -- send request line and headers |
284 | h:sendrequestline(nreqt.method, nreqt.uri) | 296 | h:sendrequestline(nreqt.method, nreqt.uri) |
285 | h:sendheaders(nreqt.headers) | 297 | h:sendheaders(nreqt.headers) |
286 | local code = 100 | 298 | -- if there is a body, send it |
287 | local headers, status | ||
288 | -- if there is a body, check for server status | ||
289 | if nreqt.source then | 299 | if nreqt.source then |
290 | h:sendbody(nreqt.headers, nreqt.source, nreqt.step) | 300 | h:sendbody(nreqt.headers, nreqt.source, nreqt.step) |
291 | end | 301 | end |
302 | local code, status = h:receivestatusline() | ||
303 | -- if it is an HTTP/0.9 server, simply get the body and we are done | ||
304 | if not code then | ||
305 | h:receive09body(status, nreqt.sink, nreqt.step) | ||
306 | return 1, 200 | ||
307 | end | ||
308 | local headers | ||
292 | -- ignore any 100-continue messages | 309 | -- ignore any 100-continue messages |
293 | while code == 100 do | 310 | while code == 100 do |
294 | code, status = h:receivestatusline() | ||
295 | headers = h:receiveheaders() | 311 | headers = h:receiveheaders() |
312 | code, status = h:receivestatusline() | ||
296 | end | 313 | end |
314 | headers = h:receiveheaders() | ||
297 | -- at this point we should have a honest reply from the server | 315 | -- at this point we should have a honest reply from the server |
298 | -- we can't redirect if we already used the source, so we report the error | 316 | -- we can't redirect if we already used the source, so we report the error |
299 | if shouldredirect(nreqt, code, headers) and not nreqt.source then | 317 | if shouldredirect(nreqt, code, headers) and not nreqt.source then |
diff --git a/src/usocket.c b/src/usocket.c index ef275b4..2c30b9a 100644 --- a/src/usocket.c +++ b/src/usocket.c | |||
@@ -359,7 +359,7 @@ const char *socket_strerror(int err) { | |||
359 | case ECONNREFUSED: return "connection refused"; | 359 | case ECONNREFUSED: return "connection refused"; |
360 | case ECONNABORTED: return "closed"; | 360 | case ECONNABORTED: return "closed"; |
361 | case ECONNRESET: return "closed"; | 361 | case ECONNRESET: return "closed"; |
362 | case ETIMEDOUT: return "timedout"; | 362 | case ETIMEDOUT: return "timeout"; |
363 | default: return strerror(errno); | 363 | default: return strerror(errno); |
364 | } | 364 | } |
365 | } | 365 | } |