1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>LuaSocket: Network support for the Lua language</title>
<link rel="stylesheet" href="reference.css" type="text/css">
</head>
<body>
<!-- header +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<div class=header>
<hr>
<center>
<table summary="LuaSocket logo">
<tr><td align=center><a href="http://www.lua.org">
<img border=0 alt="LuaSocket" src="luasocket.png">
</a></td></tr>
<tr><td align=center valign=top>Network support for the Lua language
</td></tr>
</table>
<p class=bar>
<a href="home.html">home</a> ·
<a href="home.html#download">download</a> ·
<a href="introduction.html">introduction</a> ·
<a href="reference.html">reference</a>
</p>
</center>
<hr>
</div>
<!-- stream ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<h2 id=stream>Streaming with Callbacks</h2>
<p>
HTTP, FTP, and SMTP transfers sometimes involve large amounts of
information. Sometimes an application needs to generate outgoing data
in real time, or needs to process incoming information as it is being
received. To address these problems, LuaSocket allows HTTP and SMTP message
bodies and FTP file contents to be received or sent through the
callback mechanism outlined below.
</p>
<p>
Instead of returning the received contents
as a big to the Lua application, the library allows the user to
provide a <em>receive callback</em> that will be called with successive
chunks of data, as the data becomes available. Conversely, the <em>send
callback</em> mechanism can be used when the application wants to incrementally provide LuaSocket with the data to be sent.
</p>
<!-- tohostname +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=receive>
<b>receive_cb(</b>chunk, err<b>)</b>
</p>
<p class=description>
A receive callback will be repeatedly called by
LuaSocket wheneve new data is available. Each time it is called, the
callback receives successive chunks of downloaded data.
</p>
<p class=parameters>
<tt>Chunk</tt> contains the latest downloaded chunk of data.
When the transmission is over, the function is called with an
empty string (i.e. <tt>""</tt>) in <tt>chunk</tt>.
If an error occurs, the function receives a <b><tt>nil</tt></b>
<tt>chunk</tt> and an error message in <tt>err</tt>.
</p>
<p class=return>
The callback can abort transmission by returning <b><tt>nil</tt></b> as its first
return value, and an optional error message as the
second return value. To continue receiving
data, the function should return non-<b><tt>nil</tt></b> as its first return
value. Optionally, in this case, it may return a
second return value, with a new callback function to take its place.
</p>
<!-- send_cb ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=send>
<b>send_cb()</b>
</p>
<p class=description>
A send callback will be called whenever LuaSocket
needs more data to be sent.
</p>
<p class=return>
Each time the callback is called, it should return the next chunk of data. It
can optionally return, as it's second return value, a new callback to replace
itself. The callback can abort the process at any time by returning
<b><tt>nil</tt></b> followed by an optional error message.
</p>
<!-- predefined +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<h2 id=predefined>Predefined Callbacks</h2>
<p>
The Callback module provides several predefined callbacks to
perform the most common input/output operations. Callbacks are provided
that send and receive contents of files and strings. Furthermore,
composition functions are provided to chain callbacks with filters, such as
the filters defined in the <a href=mime.html>MIME</a> module.
Together, these two modules provide a powerful interface to send and
receive information.
</p>
<!-- send.file ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=send.file>
<b>send.file</b>(file, io_err<b>)</b>
</p>
<p class=description>
This function creates a send callback that returns the contents
of a file, chunk by chunk, until the file has been entirely sent.
When done, the callback closes the file.
</p>
<p class=parameters>
<tt>File</tt> is a file opened for reading. If <tt>file</tt> is
<b><tt>nil</tt></b>, <tt>io_err</tt> can contain an error message. In this
case, the function returns a callback that just aborts
transmission with the error message.
</p>
<p class=return>
Returns a send callback for the file.
</p>
<p class=note>
Note: This function is designed so that it directly accepts the return
values of the <tt>io.open</tt> function.
</p>
<!-- send.string ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=send.string>
<b>send.string(</b>str, err<b>)</b>
</p>
<p class=description>
This function creates a send callback that will send
the contents of a string.
</p>
<p class=parameters>
<tt>Str</tt> is the string to be sent.
<!--
If <tt>str</tt> is
<b><tt>nil</tt></b>, <tt>err</tt> can optionally contain an error message.
-->
</p>
<p class=return>
Returns a send callback for the string, or <b><tt>nil</tt></b> if the string is
<b><tt>nil</tt></b>.
</p>
<p class=note>
Note: A <tt>nil</tt></b>
send callback is equivalent to a callback that returns the empty string.
</p>
<!-- send.chain ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<p class=name id=send.chain>
<b>send.chain(</b>send_cb, filter<b>)</b>
</p>
<p class=description>
This function creates a send callback that will filter
all the data it receives from another send callback, before
sending it through.
</p>
<p class=parameters>
<tt>Send_cb</tt> is the send callback to be chained to <tt>filter</tt>.
</p>
<p class=return>
Returns a callback chained with the filter.
</p>
<p class=note>
Note: Several filters are defined in the <a href=mime.html>MIME</a>
module. Below is an example that creates a send callback that sends
a file's contents encoded in the Base64 transfer content encoding.
</p>
<pre class=example>
send_cb = socket.callback.send.chain(
socket.callback.send.file(io.open("input.bin"))
socket.mime.chain(
socket.mime.encode("base64"),
socket.mime.wrap("base64")
)
)
</pre>
<p class=note>
The call to <a href=mime.html#chain><tt>socket.mime.chain</tt></a>
creates a chained filter that encodes it's input and then breaks it
into lines. The call to <tt>socket.callback.chain</tt> creates a chained
send callback that reads the file from disk and passes it through the
filter before sending it.
</p>
<!-- footer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
<div class=footer>
<hr>
<center>
<p class=bar>
<a href="home.html">home</a> ·
<a href="home.html#down">download</a> ·
<a href="introduction.html">introduction</a> ·
<a href="reference.html">reference</a>
</p>
<p>
<small>
Last modified by Diego Nehab on <br>
Sat Aug 9 01:00:41 PDT 2003
</small>
</p>
</center>
</div>
</body>
</html>
|