moonbridge

annotate reference.txt @ 91:6b26783f9323

write_nb returns total number of bytes buffered in case of block; Updated reference
author jbe
date Tue Apr 07 03:50:28 2015 +0200 (2015-04-07)
parents 0ec070d6f5d9
children de0e69673953
rev   line source
jbe@0 1
jbe@0 2 Moonbridge reference
jbe@0 3 ====================
jbe@0 4
jbe@0 5
jbe@0 6
jbe@52 7 Global function listen{...}
jbe@0 8 ---------------------------
jbe@0 9
jbe@0 10 This function initializes the Moonbridge Network Server. It may be called
jbe@0 11 multiple times. However, it is not allowed to register additional listeners by
jbe@0 12 calling listen(...) from a "prepare", "connect", or "finish" handler.
jbe@0 13
jbe@0 14 See file "example.lua" for parametrization of the listen(...) function.
jbe@0 15
jbe@0 16 Warning: Moonbridge will fork the Lua environment to handle parallel requests.
jbe@0 17 Functions provided as "prepare", "connect", and "finish" handlers may access
jbe@0 18 global variables, but for every child process these global variables will not
jbe@0 19 be shared! If you require a global state, a DBMS, cache server, or similar is
jbe@0 20 necessary.
jbe@0 21
jbe@0 22
jbe@0 23
jbe@50 24 Global function timeout(...)
jbe@50 25 ----------------------------
jbe@50 26
jbe@50 27 Calling this function with a positive number (time in seconds) sets a timer
jbe@50 28 that kills the current process after the selected time runs out. The remaining
jbe@50 29 time can be queried by calling this function without arguments.
jbe@50 30
jbe@50 31 Calling this function with a single argument that is the number zero will
jbe@50 32 disable the timeout.
jbe@50 33
jbe@50 34 Another mode of operation is selected by passing two arguments: a time (in
jbe@50 35 seconds) as first argument and a function as second argument. In this case, a
jbe@50 36 sub-timer will be used to limit the execution time of the function. In case of
jbe@50 37 timeout, the process will be killed (and the timeout function does not return).
jbe@50 38 If the time for the sub-timer is longer than a previously set timeout (using
jbe@50 39 the timeout(...) function with one argument), the shorter timeout (of the
jbe@50 40 previous call of timeout(...)) will have precedence.
jbe@50 41
jbe@52 42 Timers are also automatically reset (disabled) when a handler (prepare handler
jbe@52 43 or connect handler) returns. To shutdown processes after a certain time waiting
jbe@52 44 for a new request, use the idle_time parameter of the listen function.
jbe@52 45
jbe@50 46
jbe@50 47
jbe@0 48 Socket object passed to "connect" handler
jbe@0 49 -----------------------------------------
jbe@0 50
jbe@0 51 For every incoming connection, the registered "connect" handler is called with
jbe@0 52 a single socket object as argument, which is described below:
jbe@0 53
jbe@0 54
jbe@0 55 ### socket:close(timeout)
jbe@0 56
jbe@0 57 Closes the socket connection (input and output stream) by flushing all data and
jbe@91 58 sending a TCP FIN packet. If the timeout value is non-nil but zero, a TCP RST
jbe@91 59 is sent instead. If a positive timeout value is given and if the remote peer
jbe@91 60 doesn't respond with a TCP FIN within the given time, a TCP RST is sent in
jbe@91 61 addition to the previously sent TCP FIN packet. If the timeout value is nil or
jbe@91 62 negative, the call returns immediately and the operating system will wait for
jbe@91 63 the peer's TCP FIN packet.
jbe@91 64
jbe@91 65 Returns true on success, or nil plus error message in case of an I/O error.
jbe@91 66 Using this method on sockets that have already been closed (or reset) will
jbe@91 67 throw an error.
jbe@0 68
jbe@0 69 Warning: Pending data on the input stream may cause connection aborts (TCP RST)
jbe@0 70 depending on the particular operating system used. All pending input data
jbe@91 71 should have been read (or drained) before calling socket:close().
jbe@91 72
jbe@91 73
jbe@91 74 ### socket:drain(maxlen, terminator)
jbe@0 75
jbe@91 76 Same as socket:read(maxlen, terminator), but discards the input and returns the
jbe@91 77 number of discarded bytes. If no bytes could be read but EOF was encountered,
jbe@91 78 then true is returned.
jbe@91 79
jbe@91 80 In case of an I/O error, nil (as first return value) plus an error message (as
jbe@91 81 second result value) are returned.
jbe@0 82
jbe@0 83
jbe@91 84 ### socket:drain_nb(maxlen, terminator)
jbe@0 85
jbe@91 86 Same as socket:read_nb(maxlen, terminator), but discards the input and returns
jbe@91 87 the number of discarded bytes. If no bytes could be read but EOF was
jbe@91 88 encountered, then true is returned.
jbe@91 89
jbe@91 90 In case of an I/O error, nil (as first return value) plus an error message (as
jbe@91 91 second result value) are returned.
jbe@91 92
jbe@0 93
jbe@0 94
jbe@91 95 ### socket:flush(...)
jbe@91 96
jbe@91 97 Same as socket:write(...) but additionally flushes the socket (i.e. all pending
jbe@91 98 data is passed to the operating system).
jbe@91 99
jbe@91 100 In case of an I/O error, nil (as first return value) plus an error message (as
jbe@91 101 second result value) are returned. On success, the socket userdata object is
jbe@91 102 returned.
jbe@91 103
jbe@0 104
jbe@91 105 ### socket:flush_nb(...)
jbe@91 106
jbe@91 107 Same as socket:write_nb(...) but additionally flushes the socket (i.e. all
jbe@91 108 pending data is passed to the operating system). The total number of bytes that
jbe@91 109 could not be passed yet to the operating system is returned. Zero is returned
jbe@91 110 if all data could be flushed out.
jbe@91 111
jbe@91 112 In case of an I/O error, nil (as first return value) plus an error message (as
jbe@91 113 second result value) are returned.
jbe@0 114
jbe@0 115
jbe@0 116 ### socket.interval
jbe@0 117
jbe@0 118 Set to the name of an interval timer if the "connect" handler was called due to
jbe@0 119 an elapsed interval timer. Otherwise nil.
jbe@0 120
jbe@0 121
jbe@0 122 ### socket.local_ip4
jbe@0 123
jbe@0 124 Local IPv4 address used for the connection. Encoded as 4 raw bytes in form of a
jbe@0 125 string.
jbe@0 126
jbe@0 127
jbe@0 128 ### socket.local_ip6
jbe@0 129
jbe@0 130 Local IPv6 address used for the connection. Encoded as 16 raw bytes in form of
jbe@0 131 a string.
jbe@0 132
jbe@0 133
jbe@0 134 ### socket.local_tcpport
jbe@0 135
jbe@0 136 Local TCP port used for the connection.
jbe@0 137
jbe@0 138
jbe@91 139 ### socket:read(maxlen, terminator)
jbe@0 140
jbe@91 141 Read up to maxlen bytes or until an optional termination character is
jbe@91 142 encountered (which is included in the result). The maxlen value may be nil, in
jbe@91 143 which case there is no limit on the number of bytes read.
jbe@0 144
jbe@91 145 If EOF is encountered before any data could be read, then false (as first
jbe@91 146 return value) plus a notice string (as second return value) are returned.
jbe@0 147
jbe@91 148 In case of an I/O error, nil (as first return value) plus an error message (as
jbe@91 149 second result value) are returned.
jbe@0 150
jbe@0 151
jbe@91 152 ### socket:read_nb(maxlen, terminator)
jbe@91 153
jbe@91 154 Read up to maxlen bytes, until an optional termination character is encountered
jbe@91 155 (which is included in the result), or until no more data is available for
jbe@91 156 reading. The maxlen value may be nil, in which case there is no limit on the
jbe@91 157 number of bytes read.
jbe@78 158
jbe@91 159 If EOF is encountered before any data could be read, then false (as first
jbe@91 160 return value) plus a notice string (as second return value) are returned.
jbe@78 161
jbe@91 162 If no data was available for reading, but no EOF was encountered, then an empty
jbe@91 163 string is returned.
jbe@91 164
jbe@91 165 In case of an I/O error, nil (as first return value) plus an error message (as
jbe@91 166 second result value) are returned.
jbe@78 167
jbe@78 168
jbe@0 169 ### socket.remote_ip4
jbe@0 170
jbe@0 171 Remote IPv4 address used for the connection. Encoded as 4 raw bytes in form of
jbe@0 172 a string.
jbe@0 173
jbe@0 174
jbe@0 175 ### socket.remote_ip6
jbe@0 176
jbe@0 177 Remote IPv6 address used for the connection. Encoded as 16 raw bytes in form of
jbe@0 178 a string.
jbe@0 179
jbe@0 180
jbe@0 181 ### socket.remote_tcpport
jbe@0 182
jbe@0 183 Remote TCP port used for the connection.
jbe@0 184
jbe@0 185
jbe@91 186 ### socket:reset()
jbe@91 187
jbe@91 188 Alias for socket:close(0). Closes the socket connection by sending a TCP RST
jbe@91 189 packet if possible to indicate error condition.
jbe@91 190
jbe@91 191 Returns true on success, or nil (as first result value) plus error message (as
jbe@91 192 second result value) in case of an I/O error. Using this method on sockets that
jbe@91 193 have already been closed (or reset) will throw an error.
jbe@91 194
jbe@91 195 Warning: Previously sent (and flushed) data may be lost during transmission.
jbe@91 196
jbe@91 197
jbe@0 198 ### socket:write(...)
jbe@0 199
jbe@91 200 Takes a variable number of strings and sends them to the peer. The operation is
jbe@91 201 buffered, so to actually send out the data, it is necessary to eventually call
jbe@91 202 socket:flush(), socket:finish(), or socket:close().
jbe@91 203
jbe@91 204 In case of an I/O error, nil (as first return value) plus an error message (as
jbe@91 205 second result value) are returned. On success, the socket userdata object is
jbe@91 206 returned.
jbe@91 207
jbe@91 208
jbe@91 209 ### socket:write_nb(...)
jbe@91 210
jbe@91 211 Takes a variable number of strings and sends them to the peer. The operation is
jbe@91 212 buffered, so to actually send out the data, it is necessary to eventually call
jbe@91 213 socket:flush_nb(), socket:flush(), socket:finish(), or socket:close().
jbe@91 214
jbe@91 215 This function always returns immediately (i.e. it does not block). If all data
jbe@91 216 (but a small buffered portion) could be sent out, then zero is returned.
jbe@91 217 Otherwise, all arguments that could not be sent are stored in a buffer of
jbe@91 218 unlimited size (up to memory capabilities) and an integer is returned that
jbe@91 219 indicates the number of bytes currently in the buffer.
jbe@91 220
jbe@91 221 In case of an I/O error, nil (as first return value) plus an error message (as
jbe@91 222 second result value) are returned.
jbe@0 223
jbe@0 224
jbe@0 225
jbe@0 226 HTTP module
jbe@0 227 -----------
jbe@0 228
jbe@0 229 The http module exports the function http.generate_handler(callback) that
jbe@0 230 converts an HTTP handler to a "connect" handler. See file "example.lua" for an
jbe@0 231 example of invocation. A table with options may be passed either as a second
jbe@0 232 argument, or as a first argument preceeding the callback function (whichever is
jbe@0 233 more convenient).
jbe@0 234
jbe@0 235 The following options are supported:
jbe@0 236
jbe@0 237 - request_body_size_limit: maximum size of payload of HTTP request body
jbe@0 238 (transfer encoding is allowed to add a limited amount of extra data)
jbe@0 239 - chunk_size: optional default value for maximum_input_chunk_size and
jbe@0 240 minimum_output_chunk_size
jbe@0 241 - request_header_size_limit: maximum size of HTTP request headers
jbe@0 242 - maximum_input_chunk_size: maximum chunk size when streaming a request body or
jbe@0 243 certain POST fields (bigger chunks will be fragmented automatically)
jbe@0 244 - minimum_output_chunk_size: minimum size for a chunk when sending a response
jbe@0 245 body (smaller chunks will be buffered and concatenated with future data;
jbe@0 246 ignored when request:flush() is called)
jbe@0 247 - static_headers: a set of headers to be included in every HTTP response
jbe@0 248 (may be a string, a table or strings, or a table of key-value pairs)
jbe@0 249
jbe@0 250 The callback function receives a single request object as argument, which is
jbe@0 251 described below.
jbe@0 252
jbe@0 253
jbe@0 254 ### request.body
jbe@0 255
jbe@0 256 The request body (without headers) as a string. Accessing this value makes
jbe@0 257 further access to request.post_params and request.post_params_list, or
jbe@0 258 invocation of request:stream_request_body(...) impossible.
jbe@0 259
jbe@0 260
jbe@60 261 ### request:close_after_finish()
jbe@60 262
jbe@60 263 Closes the connection after answering the request.
jbe@60 264
jbe@60 265 This method can only be called before the HTTP response header section has been
jbe@60 266 finished (i.e. before request:finish_headers(), request:send_data(...), or
jbe@60 267 request:finish() were called), but it may be called before a status code has
jbe@60 268 been sent using request:send_status(...).
jbe@60 269
jbe@60 270 A corresponding "Connection: close" header is automatically sent.
jbe@60 271
jbe@60 272
jbe@0 273 ### request.cookies
jbe@0 274
jbe@0 275 A table with all cookies sent by the client.
jbe@0 276
jbe@0 277
jbe@0 278 ### request.defer_reading()
jbe@0 279
jbe@0 280 Disables automatic request body processing on write. Can be called before
jbe@0 281 sending a HTTP status code to send a response before the request has been fully
jbe@0 282 received.
jbe@0 283
jbe@0 284 CAUTION: Responding to a request before the request body has been processed may
jbe@0 285 lead to a deadlock if the browser does not process the response while trying to
jbe@0 286 send the request. Therefore, this function should only be used if:
jbe@0 287
jbe@0 288 - the TCP stack has enough buffer space for the response (i.e. if the response
jbe@0 289 is small enough), and if
jbe@0 290 - a timer is used to cancel the response in case of a deadlock.
jbe@0 291
jbe@0 292 It is recommended to not use this function unless certain performance tweaks
jbe@0 293 are desired.
jbe@0 294
jbe@0 295
jbe@50 296 ### request.faulty
jbe@50 297
jbe@50 298 Normally set to false. In case of a read or write error on the client
jbe@50 299 connection, this value is set to true before a Lua error is raised.
jbe@50 300
jbe@50 301 A faulty request handle must not be used, or another Lua error will be raised.
jbe@50 302
jbe@50 303
jbe@0 304 ### request:finish()
jbe@0 305
jbe@0 306 Finishes and flushes a HTTP response. May be called multiple times. An
jbe@0 307 HTTP status, all headers, and the response body (if applicable) must have been
jbe@0 308 previously sent. After calling this method, no further data may be written.
jbe@0 309
jbe@0 310
jbe@0 311 ### request:finish_headers()
jbe@0 312
jbe@0 313 Finishes and flushes the HTTP response header section. May be called multiple
jbe@0 314 times, as long as the request is not finished completely. This method is
jbe@0 315 automatically invoked if the application is beginning to send a response body.
jbe@0 316 After calling this method, no further headers may be sent.
jbe@0 317
jbe@0 318
jbe@0 319 ### request:flush()
jbe@0 320
jbe@0 321 Flushes any pending output data. Note: In order to mark the end of a response
jbe@0 322 body, it is required to call request:finish().
jbe@0 323
jbe@0 324
jbe@0 325 ### request.get_params
jbe@0 326
jbe@0 327 A table that maps field names to their corresponding GET value. If there are
jbe@0 328 several GET values with the given field name, then the first value is used.
jbe@0 329
jbe@35 330 Note: May be implemented through metamethods, but does support iteration
jbe@35 331 through pairs(...).
jbe@35 332
jbe@0 333
jbe@0 334 ### request.get_params_list
jbe@0 335
jbe@0 336 A table that maps field names to a sequence of their corresponding GET values.
jbe@0 337
jbe@35 338 Note: May be implemented through metamethods, but does support iteration
jbe@35 339 through pairs(...).
jbe@35 340
jbe@0 341
jbe@0 342 ### request.headers
jbe@0 343
jbe@0 344 A table that maps (case-insensitively) a HTTP header field name to a sequence
jbe@0 345 of values. One entry is created for every occurrence of a header line with the
jbe@0 346 given field name).
jbe@0 347
jbe@0 348
jbe@0 349 ### request.headers_csv_string
jbe@0 350
jbe@0 351 A table that maps (case-insensitively) a HTTP header field name to a comma
jbe@0 352 separated string. Multiple occurrences of the header with the given field name
jbe@0 353 are automatically merged into the comma separated string.
jbe@0 354
jbe@0 355
jbe@0 356 ### request.headers_csv_table
jbe@0 357
jbe@0 358 A table that maps (case-insensitively) a HTTP header field name to a sequence
jbe@0 359 of values. One entry is created for every comma separated value of each header
jbe@0 360 with the given field name.
jbe@0 361
jbe@0 362
jbe@0 363 ### request.headers_flags
jbe@0 364
jbe@0 365 A table that maps (case-insensitively) a HTTP header field name to another
jbe@0 366 table which (again case-insensitively) maps a string to a boolean, depending on
jbe@0 367 whether this string occurred in the list of comma separated values of one
jbe@0 368 header line with the given field name that was the key in the first table.
jbe@0 369
jbe@0 370
jbe@0 371 ### request.headers_value
jbe@0 372
jbe@0 373 A table that maps (case-insensitively) a HTTP header field name to a value. If
jbe@0 374 multiple header lines with the given field name have been received, false is
jbe@0 375 used as value.
jbe@0 376
jbe@0 377
jbe@0 378 ### request.method
jbe@0 379
jbe@0 380 The HTTP request method, e.g. "HEAD", "GET", or "POST".
jbe@0 381
jbe@0 382
jbe@0 383 ### request.path
jbe@0 384
jbe@10 385 The requested path without a leading slash and without the query part (e.g.
jbe@10 386 "index.html" if "/index.html?a=b&c=d" has been requested). For the query part,
jbe@10 387 see request.query.
jbe@10 388
jbe@10 389 This value will be nil if (and only if) the request method is "OPTIONS" with a
jbe@10 390 request target equal to "*" (see also asterisk-form of request-target in
jbe@10 391 section 5.3.4 in RFC 7230).
jbe@0 392
jbe@0 393
jbe@0 394 ### request.post_metadata
jbe@0 395
jbe@0 396 Only set for multipart/form-data POST requests. A table that maps field names
jbe@0 397 to their corresponding POST metadata table which contains two entries:
jbe@0 398 "file_name" and "content_type". If there are several POST values with the given
jbe@0 399 field name, then the first value/file is used.
jbe@0 400
jbe@0 401
jbe@0 402 ### request.post_metadata_list
jbe@0 403
jbe@0 404 Only set for multipart/form-data POST requests. A table that maps field names
jbe@0 405 to a sequence with their corresponding POST metadata tables. Needed if multiple
jbe@0 406 files are uploaded with the same field name.
jbe@0 407
jbe@0 408
jbe@0 409 ### request.post_params
jbe@0 410
jbe@0 411 A table that maps field names to their corresponding POST value. If there are
jbe@0 412 several POST values with the given field name, then the first value is used.
jbe@0 413
jbe@35 414 Note: May be implemented through metamethods, but does support iteration
jbe@35 415 through pairs(...).
jbe@35 416
jbe@0 417
jbe@0 418 ### request.post_params_list
jbe@0 419
jbe@0 420 A table that maps field names to a sequence of their corresponding POST values.
jbe@0 421
jbe@35 422 Note: May be implemented through metamethods, but does support iteration
jbe@35 423 through pairs(...).
jbe@35 424
jbe@0 425
jbe@0 426 ### request.query
jbe@0 427
jbe@12 428 Query part of the request target including the leading question mark, e.g.
jbe@12 429 "?a=b&c=d" if the requested target is "/index.html?a=b&c=d". The data is
jbe@10 430 automatically parsed and made available through request.get_params and
jbe@10 431 request.get_params_list.
jbe@10 432
jbe@10 433 If there is no query part given in the request target, then this string is
jbe@10 434 the empty string. This value will be nil if (and only if) the request method
jbe@10 435 is "OPTIONS" with a request target equal to "*" (see also asterisk-form of
jbe@10 436 request-target in section 5.3.4 in RFC 7230).
jbe@0 437
jbe@0 438
jbe@0 439 ### request:process_request_body()
jbe@0 440
jbe@0 441 Starts processing the request body (if existent) to set the values
jbe@0 442 request.post_params, request.post_params_list, request.post_metadata, and
jbe@0 443 and request.post_metadata_list and/or to call POST field stream handlers that
jbe@0 444 have been previously registered with request:stream_post_param(...) or
jbe@0 445 request:stream_post_params(...).
jbe@0 446
jbe@0 447 This method gets invoked automatically when the POST param tables
jbe@0 448 (request.post_params, etc.) are accessed, or if a response is sent (to avoid
jbe@0 449 deadlocks with the webbrowser). (Note: Automatic request body processing on
jbe@0 450 write may be disabled by calling request:defer_reading().)
jbe@0 451
jbe@0 452 After this method returned, all registered POST field stream handlers have
jbe@0 453 received all data. Registration of other POST field stream handlers is not
jbe@0 454 possible after this method has been called (or after request.post_params_list
jbe@0 455 or request.post_params have been accessed).
jbe@0 456
jbe@0 457
jbe@0 458 ### request:send_data(...)
jbe@0 459
jbe@0 460 Sends data as response body. All arguments are converted via tostring(...) and
jbe@0 461 concatenated. May be called multiple times until the request has been finished
jbe@0 462 by calling request:finish().
jbe@0 463
jbe@0 464 If the request method (see request.method) is "HEAD", then calls to
jbe@0 465 request:send_data(...) are automatically ignored.
jbe@0 466
jbe@0 467
jbe@0 468 ### request:send_header(key, value)
jbe@0 469
jbe@0 470 Sends a HTTP response header that consists of the given key and the given
jbe@0 471 value. Note: Key and value must be provided as separate arguments. Before any
jbe@0 472 headers can be sent, a HTTP status must have been set with
jbe@0 473 request:send_status(status_string).
jbe@0 474
jbe@0 475
jbe@0 476 ### request:send_status(status_string)
jbe@0 477
jbe@0 478 Sends a HTTP response status that is given as a string consisting of a 3-digit
jbe@0 479 number and an explanatory string, e.g. "200 OK" or "404 Not Found". This
jbe@0 480 function must be called once before any headers or response body data may be
jbe@0 481 sent.
jbe@0 482
jbe@0 483
jbe@0 484 ### request.socket
jbe@0 485
jbe@0 486 The underlaying socket. Can be used to force a TCP RST, etc.
jbe@0 487
jbe@0 488
jbe@0 489 ### request:stream_post_param(field_name, callback)
jbe@0 490
jbe@0 491 Registers a stream handler for the given POST parameter. The callback function
jbe@0 492 will be called in the following manner:
jbe@0 493
jbe@0 494 - For the initial chunk, the first chunk gets passed as first argument while a
jbe@0 495 table with metadata ("field_name" and "content_type") gets passed as second
jbe@0 496 argument. In case of an immediate EOF (i.e. an empty file), the passed
jbe@0 497 chunk is the empty string. In all other cases the chunk has a length greater
jbe@0 498 than zero.
jbe@0 499 - For any remaining chunks, the respective chunk gets passed as first and only
jbe@0 500 argument (no metadata). Here, the chunk has always a length greater than
jbe@0 501 zero.
jbe@0 502 - To indicate the end of the stream, the callback function is called without
jbe@0 503 arguments. This also happens in case of an immediate EOF (see above).
jbe@0 504
jbe@0 505 In case of an immediate EOF (i.e. an empty file), the callback function is thus
jbe@0 506 called as follows:
jbe@0 507
jbe@0 508 - The first time with an empty string as first argument, and with the metadata
jbe@0 509 as second argument.
jbe@0 510 - The second time without any arguments.
jbe@0 511
jbe@0 512
jbe@0 513 ### request:stream_post_params(pattern, callback)
jbe@0 514
jbe@0 515 Same as request:stream_post_param(...) but providing a string pattern to match
jbe@0 516 multiple field names (e.g. "^file_[0-9]+$").
jbe@0 517
jbe@0 518
jbe@0 519 ### request:stream_request_body(callback)
jbe@0 520
jbe@0 521 Start streaming of request body. For each chunk of the request body, the
jbe@0 522 callback function is called with the corresponding chunk. End of data is
jbe@0 523 indicated through return of request:stream_request_body(...) (not by calling
jbe@0 524 the callback without arguments).
jbe@0 525
jbe@44 526 The function may be called with nil instead of a callback function. In this
jbe@44 527 case, the request body is read and discarded. Only if nil is passed instead of
jbe@44 528 a callback, then the function may also be invoked when the request body has
jbe@44 529 already been read and/or processed. In the latter case, the function performs
jbe@44 530 no operation.
jbe@0 531
jbe@44 532

Impressum / About Us