-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdefinitions.lua
8033 lines (7332 loc) Β· 311 KB
/
definitions.lua
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
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
---@meta
error("Tried to evaluate definition file.")
--Documents redbean 2.2, lsqlite3 0.9.5
--[[
SYNOPSIS
redbean [-?BVabdfghjkmsuvz] [-p PORT] [-D DIR] [-- SCRIPTARGS...]
DESCRIPTION
redbean - single-file distributable web server
OVERVIEW
redbean makes it possible to share web applications that run offline
as a single-file Actually Portable Executable PKZIP archive which
contains your assets.
redbean can serve 1 million+ gzip encoded responses per second on a
cheap personal computer. That performance is thanks to zip and gzip
using the same compression format, which enables kernelspace copies.
Another reason redbean goes fast is that it's a tiny static binary,
which makes fork memory paging nearly free.
redbean is also easy to modify to suit your own needs. The program
itself is written as a single .c file. It embeds the Lua programming
language and SQLite which let you write dynamic pages.
FEATURES
- Lua v5.4
- SQLite 3.35.5
- TLS v1.2 / v1.1 / v1.0
- HTTP v1.1 / v1.0 / v0.9
- Chromium-Zlib Compression
- Statusz Monitoring Statistics
- Self-Modifying PKZIP Object Store
- Linux + Windows + Mac + FreeBSD + OpenBSD + NetBSD
FLAGS
-h or -? help
-d daemonize
-u uniprocess
-z print port
-m log messages
-i interpreter mode
-b log message bodies
-a log resource usage
-g log handler latency
-E show crash reports to public ips
-j enable ssl client verify
-k disable ssl fetch verify
-Z log worker system calls
-f log worker function calls
-B only use stronger cryptography
-X disable ssl server and client support
-* permit self-modification of executable
-J disable non-ssl server and client support
-% hasten startup by not generating an rsa key
-s increase silence [repeatable]
-v increase verbosity [repeatable]
-V increase ssl verbosity [repeatable]
-S increase pledge sandboxing [repeatable]
-e CODE eval Lua code in arg [repeatable]
-F PATH eval Lua code in file [repeatable]
-H K:V sets http header globally [repeatable]
-D DIR overlay assets in local directory [repeatable]
-r /X=/Y redirect X to Y [repeatable]
-R /X=/Y rewrites X to Y [repeatable]
-K PATH tls private key path [repeatable]
-C PATH tls certificate(s) path [repeatable]
-A PATH add assets with path (recursive) [repeatable]
-M INT tunes max message payload size [def. 65536]
-t INT timeout ms or keepalive sec if <0 [def. 60000]
-p PORT listen port [def. 8080; repeatable]
-l ADDR listen addr [def. 0.0.0.0; repeatable]
-c SEC configures static cache-control
-W TTY use tty path to monitor memory pages
-L PATH log file location
-P PATH pid file location
-U INT daemon set user id
-G INT daemon set group id
-w PATH launch browser on startup
--strace enables system call tracing (see also -Z)
--ftrace enables function call tracing (see also -f)
KEYBOARD
CTRL-D EXIT
CTRL-C CTRL-C EXIT
CTRL-E END
CTRL-A START
CTRL-B BACK
CTRL-F FORWARD
CTRL-L CLEAR
CTRL-H BACKSPACE
CTRL-D DELETE
CTRL-N NEXT HISTORY
CTRL-P PREVIOUS HISTORY
CTRL-R SEARCH HISTORY
CTRL-G CANCEL SEARCH
ALT-< BEGINNING OF HISTORY
ALT-> END OF HISTORY
ALT-F FORWARD WORD
ALT-B BACKWARD WORD
CTRL-RIGHT FORWARD WORD
CTRL-LEFT BACKWARD WORD
CTRL-K KILL LINE FORWARDS
CTRL-U KILL LINE BACKWARDS
ALT-H KILL WORD BACKWARDS
CTRL-W KILL WORD BACKWARDS
CTRL-ALT-H KILL WORD BACKWARDS
ALT-D KILL WORD FORWARDS
CTRL-Y YANK
ALT-Y ROTATE KILL RING AND YANK AGAIN
CTRL-T TRANSPOSE
ALT-T TRANSPOSE WORD
ALT-U UPPERCASE WORD
ALT-L LOWERCASE WORD
ALT-C CAPITALIZE WORD
CTRL-\ QUIT PROCESS
CTRL-S PAUSE OUTPUT
CTRL-Q UNPAUSE OUTPUT (IF PAUSED)
CTRL-Q ESCAPED INSERT
CTRL-ALT-F FORWARD EXPR
CTRL-ALT-B BACKWARD EXPR
ALT-RIGHT FORWARD EXPR
ALT-LEFT BACKWARD EXPR
ALT-SHIFT-B BARF EXPR
ALT-SHIFT-S SLURP EXPR
CTRL-SPACE SET MARK
CTRL-X CTRL-X GOTO MARK
CTRL-Z SUSPEND PROCESS
ALT-\ SQUEEZE ADJACENT WHITESPACE
PROTIP REMAP CAPS LOCK TO CTRL
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
USAGE
This executable is also a ZIP file that contains static assets.
You can run redbean interactively in your terminal as follows:
./redbean -vvvmbag # starts server verbosely
open http://127.0.0.1:8080/ # shows zip listing page
CTRL-C # 1x: graceful shutdown
CTRL-C # 2x: forceful shutdown
You can override the default listing page by adding:
zip redbean index.lua # lua server pages take priority
zip redbean index.html # default page for directory
The listing page only applies to the root directory. However the
default index page applies to subdirectories too. In order for it
to work, there needs to be an empty directory entry in the zip.
That should already be the default practice of your zip editor.
wget \
--mirror \
--convert-links \
--adjust-extension \
--page-requisites \
--no-parent \
--no-if-modified-since \
http://a.example/index.html
zip -r redbean a.example/ # default page for directory
redbean normalizes the trailing slash for you automatically:
$ printf 'GET /a.example HTTP/1.0\n\n' | nc 127.0.0.1 8080
HTTP/1.0 307 Temporary Redirect
Location: /a.example/
Virtual hosting is accomplished this way too. The Host is simply
prepended to the path, and if it doesn't exist, it gets removed.
$ printf 'GET / HTTP/1.1\nHost:a.example\n\n' | nc 127.0.0.1 8080
HTTP/1.1 200 OK
Link: <http://127.0.0.1/a.example/index.html>; rel="canonical"
If you mirror a lot of websites within your redbean then you can
actually tell your browser that redbean is your proxy server, in
which redbean will act as your private version of the Internet.
$ printf 'GET http://a.example HTTP/1.0\n\n' | nc 127.0.0.1 8080
HTTP/1.0 200 OK
Link: <http://127.0.0.1/a.example/index.html>; rel="canonical"
If you use a reverse proxy, then redbean recognizes the following
provided that the proxy forwards requests over the local network:
X-Forwarded-For: 203.0.113.42:31337
X-Forwarded-Host: foo.example:80
There's a text/plain statistics page called /statusz that makes
it easy to track and monitor the health of your redbean:
printf 'GET /statusz\n\n' | nc 127.0.0.1 8080
redbean will display an error page using the /redbean.png logo
by default, embedded as a bas64 data uri. You can override the
custom page for various errors by adding files to the zip root.
zip redbean 404.html # custom not found page
Audio video content should not be compressed in your ZIP files.
Uncompressed assets enable browsers to send Range HTTP request.
On the other hand compressed assets are best for gzip encoding.
zip redbean index.html # adds file
zip -0 redbean video.mp4 # adds without compression
You can have redbean run as a daemon by doing the following:
sudo ./redbean -vvdp80 -p443 -L redbean.log -P redbean.pid
kill -TERM $(cat redbean.pid) # 1x: graceful shutdown
kill -TERM $(cat redbean.pid) # 2x: forceful shutdown
redbean currently has a 32kb limit on request messages and 64kb
including the payload. redbean will grow to whatever the system
limits allow. Should fork() or accept() fail redbean will react
by going into "meltdown mode" which closes lingering workers.
You can trigger this at any time using:
kill -USR2 $(cat redbean.pid)
Another failure condition is running out of disk space in which
case redbean reacts by truncating the log file. Lastly, redbean
does the best job possible reporting on resource usage when the
logger is in debug mode noting that NetBSD is the best at this.
Your redbean is an actually portable executable, that's able to
run on six different operating systems. To do that, it needs to
extract a 4kb loader program to ${TMPDIR:-${HOME:-.}}/.ape that'll
map your redbean into memory. It does however check to see if `ape`
is on the system path beforehand. You can also "assimilate" any
redbean into the platform-local executable format by running:
$ file redbean
redbean: DOS/MBR boot sector
$ ./redbean --assimilate
$ file redbean
redbean: ELF 64-bit LSB executable
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
SECURITY
redbean uses a protocol polyglot for serving HTTP and HTTPS on
the same port numbers. For example, both of these are valid:
http://127.0.0.1:8080/
https://127.0.0.1:8080/
SSL verbosity is controlled as follows for troubleshooting:
-V log ssl errors
-VV log ssl state changes too
-VVV log ssl informational messages too
-VVVV log ssl verbose details too
Redbean supports sandboxing flags on Linux and OpenBSD.
-S (online policy)
This causes unix.pledge("stdio rpath inet dns") to be called on
workers after fork() is called. This permits read-only operations
and APIs like Fetch() that let workers send and receive data with
private and public Internet hosts. Access to the unix module is
somewhat restricted, disallowing its more powerful APIs like exec.
-SS (offline policy)
This causes unix.pledge("stdio rpath") to be called on workers
after after fork() is called. This prevents workers from talking
to the network (other than the client) and allows read-only file
system access (e.g. `-D DIR` flag).
-SSS (contained policy)
This causes unix.pledge("stdio") to be called on workers after
after fork() is called. This prevents workers from communicating
with the network (other than the client connection) and prevents
file system access (with some exceptions like logging). Redbean
should only be able to serve from its own zip file in this mode.
Lua script access to the unix module is highly restricted.
See http://redbean.dev for further details.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
LUA SERVER PAGES
Any files with the extension .lua will be dynamically served by redbean.
Here's the simplest possible example:
Write('<b>Hello World</b>')
The Lua Server Page above should be able to perform at 700,000 responses
per second on a Core i9, without any sort of caching. If you want a Lua
handler that can do 1,000,000 responses per second, then try adding the
following global handler to your /.init.lua file:
function OnHttpRequest()
Write('<b>Hello World</b>')
end
Here's an example of a more typical workflow for Lua Server Pages using
the redbean API:
SetStatus(200)
SetHeader('Content-Type', 'text/plain; charset=utf-8')
Write('<p>Hello ')
Write(EscapeHtml(GetParam('name')))
We didn't need the first two lines in the previous example, because
they're implied by redbean automatically if you don't set them. Responses
are also buffered until the script finishes executing. That enables
redbean to make HTTP as easy as possible. In the future, API capabilities
will be expanded to make possible things like websockets.
redbean embeds the Lua standard library. You can use packages such as io
to persist and share state across requests and connections, as well as the
StoreAsset function, and the lsqlite3 module.
Your Lua interpreter begins its life in the main process at startup in the
.init.lua, which is likely where you'll want to perform all your expensive
one-time operations like importing modules. Then, as requests roll in,
isolated processes are cloned from the blueprint you created.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
REPL
Your redbean displays a Read-Eval-Print-Loop that lets you modify the
state of the main server process while your server is running. Any
changes will propagate into forked clients.
Your REPL is displayed only when redbean is run as a non-daemon in a
Unix terminal or the Windows 10 command prompt or PowerShell. Since
the REPL is a Lua REPL it's not included in a redbean-static builds.
redbean uses the same keyboard shortcuts as GNU Readline and Emacs.
Some of its keyboard commands (listed in a previous section) were
inspired by Paredit.
A history of your commands is saved to `~/.redbean_history`.
If you love the redbean repl and want to use it as your language
interpreter then you can pass the `-i` flag to put redbean into
interpreter mode.
redbean -i binarytrees.lua 15
When the `-i` flag is passed (for interpreter mode), redbean won't
start a web server and instead functions like the `lua` command. The
first command line argument becomes the script you want to run. If you
don't supply a script, then the repl without a web server is
displayed. This is useful for testing since redbean extensions and
modules for the Lua language, are still made available. You can also
write redbean scripts with shebang lines:
#!/usr/bin/redbean -i
print('hello world')
However UNIX operating systems usually require that interpreters be
encoded in its preferred executable format. You can assimilate your
redbean into the local format using the following commands:
$ file redbean
redbean: DOS/MBR boot sector
$ ./redbean --assimilate
$ file redbean
redbean: ELF 64-bit LSB executable
$ sudo cp redbean /usr/bin/redbean
By following the above steps, redbean can be installed systemwide for
multiple user accounts. It's also possible to chmod the binary to have
setuid privileges. Please note that, if you do this, the UNIX section
provides further details on APIs like `unix.setuid` that will help you
remove root privileges from the process in the appropriate manner.
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
LUA ENHANCEMENTS
We've made some enhancements to the Lua language that should make it
more comfortable for C/C++ and Python developers. Some of these
- redbean supports a printf modulus operator, like Python. For
example, you can say `"hello %s" % {"world"}` instead of
`string.format("hello %s", "world")`.
--
- redbean supports a string multiply operator, like Python. For
example, you can say `"hi" * 2` instead of `string.rep("hi", 2)`.
- redbean supports octal (base 8) integer literals. For example
`0644 == 420` is the case in redbean, whereas in upstream Lua
`0644 == 644` would be the case.
- redbean supports binary (base 2) integer literals. For example
`0b1010 == 10` is the case in redbean, whereas in upstream Lua
`0b1010` would result in an error.
- redbean supports the GNU syntax for the ASCII ESC character in
string literals. For example, `"\e"` is the same as `"\x1b"`.
]]
---@class string
---@operator mod(any[]): string
---@operator mul(integer): string
-- GLOBALS
--- Array of command line arguments, excluding those parsed by
--- getopt() in the C code, which stops parsing at the first
--- non-hyphenated arg. In some cases you can use the magic --
--- argument to delimit C from Lua arguments.
---
--- For example, if you launch your redbean as follows:
---
--- redbean -v arg1 arg2
---
--- Then your `/.init.lua` file will have the `arg` array like:
---
--- arg[-1] = '/usr/bin/redbean'
--- arg[ 0] = '/zip/.init.lua'
--- arg[ 1] = 'arg1'
--- arg[ 2] = 'arg2'
---
--- If you launch redbean in interpreter mode (rather than web
--- server) mode, then an invocation like this:
---
--- ./redbean -i script.lua arg1 arg2
---
--- Would have an `arg` array like this:
---
--- arg[-1] = './redbean'
--- arg[ 0] = 'script.lua'
--- arg[ 1] = 'arg1'
--- arg[ 2] = 'arg2'
---@type string[]
arg = nil
---@deprecated Use `arg` instead.
argv = nil
--[[
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
SPECIAL PATHS
/
redbean will generate a zip central directory listing for this
page, and this page only, but only if there isn't an /index.lua or
/index.html file defined.
/.init.lua
This script is run once in the main process at startup. This lets
you modify the state of the Lua interpreter before connection
processes are forked off. For example, it's a good idea to do
expensive one-time computations here. You can also use this file
to call the ProgramFOO() functions below. The init module load
happens after redbean's arguments and zip assets have been parsed,
but before calling functions like socket() and fork(). Note that
this path is a hidden file so that it can't be unintentionally run
by the network client.
/.reload.lua (deprecated; use OnServerReload instead)
This script is run from the main process when SIGHUP is received.
This only applies to redbean when running in daemon mode. Any
changes that are made to the Lua interpreter state will be
inherited by future forked connection processes. Note that this
path is a hidden file so that it can't be unintentionally run by
the network client.
/.lua/...
Your Lua modules go in this directory. The way it works is redbean
sets Lua's package.path to /zip/.lua/?.lua;/zip/.lua/?/init.lua by
default. Cosmopolitan Libc lets system calls like open read from
the ZIP structure, if the filename is prefixed with /zip/. So this
works like magic.
/redbean.png
If it exists, it'll be used as the / listing page icon, embedded
as a base64 URI.
/usr/share/zoneinfo
This directory contains a subset of the timezone database.
Your `TZ` environment variable controls which one of these
files is used by functions such as unix.localtime().
/usr/share/ssl/root
This directory contains your root certificate authorities. It is
needed so the Fetch() HTTPS client API can verify that a remote
certificate was signed by a third party. You can add your own
certificate files to this directory within the ZIP executable.
If you enable HTTPS client verification then redbean will check
that HTTPS clients (a) have a certificate and (b) it was signed.
/.args
Specifies default command-line arguments.
There's one argument per line. Trailing newline is ignored. If
the special argument `...` is *not* encountered, then the
replacement will only happen if *no* CLI args are specified.
If the special argument `...` *is* encountered, then it'll be
replaced with whatever CLI args were specified by the user.
For example, you might want to use redbean in interpreter
mode, where your script file is inside the zip. Then, if your
redbean is run, what you want is to have the default behavior
be running your script. In that case, you might:
$ cat <<'EOF' >.args
-i
/zip/hello.lua
EOF
$ cat <<'EOF' >hello.lua
print("hello world")
EOF
$ zip redbean .args hello.lua
$ ./redbean
hello world
Please note that if you ran:
$ ./redbean -vv
Then the default mode of redbean will kick back in. To prevent
that from happening, simply add the magic arg `...` to the end
of your `.args` file.
]]
-- HOOKS
--- Hooks HTTP message handling.
---
--- If this function is defined in the global scope by your `/.init.lua`
--- then redbean will call it at the earliest possible moment to
--- hand over control for all messages (with the exception of `OPTIONS--*`
--- See functions like `Route` which asks redbean to do its default
--- thing from the handler.
---
function OnHttpRequest() end
--- Hooks catch errors
---
--- If this functiopn is defined in the global scope by your `/.init.lua`
--- then any errors occuring in the OnHttpRequest() hook will be catched.
--- You'll be able then to do whatever you need with the error status and
--- error message.
---
---@param status uint16
---@param message string
function OnError(status, message) end
--- Hooks client connection creation.
---
--- If this function is defined it'll be called from the main process
--- each time redbean accepts a new client connection.
---
---@param ip uint32
---@param port uint16
---@param serverip uint32
---@param serverport uint16
---@return boolean # If it returns `true`, redbean will close the connection without calling `fork`.
function OnClientConnection(ip, port, serverip, serverport) end
--- Hook latency logging.
---
--- If this function is defined it'll be called from the main process
--- each time redbean completes handling of a request, but before the
--- response is sent. The handler received the time (in Β΅s) since the
--- request handling and connection handling started.
---
---@param reqtimeus integer
---@param contimeus integer
function OnLogLatency(reqtimeus, contimeus) end
--- Hooks process creation.
---
--- If this function is defined it'll be called from the main process
--- each time redbean forks a connection handler worker process. The
--- ip/port of the remote client is provided, along with the ip/port
--- of the listening interface that accepted the connection. This may
--- be used to create a server activity dashboard, in which case the
--- data provider handler should set `SetHeader('Connection','Close')`.
--- This won't be called in uniprocess mode.
---
---@param pid integer
---@param ip uint32
---@param port uint16
---@param serverip uint32
---@param serverport uint16
function OnProcessCreate(pid, ip, port, serverip, serverport) end
--- If this function is defined it'll be called from the main process
--- each time redbean reaps a child connection process using `wait4()`.
--- This won't be called in uniprocess mode.
---@param pid integer
function OnProcessDestroy(pid) end
--- If this function is defined it'll be called from the main process
--- on each server heartbeat. The heartbeat interval is configurable
--- with `ProgramHeartbeatInterval`.
function OnServerHeartbeat() end
--- If this function is defined it'll be called from the main process
--- before redbean starts listening on a port. This hook can be used
--- to modify socket configuration to set `SO_REUSEPORT`, for example.
---@param socketdescriptor integer
---@param serverip uint32
---@param serverport uint16
---@return boolean ignore If `true`, redbean will not listen to that ip/port.
function OnServerListen(socketdescriptor, serverip, serverport) end
--- If this function is defined it'll be called from the main process
--- on each server reload triggered by SIGHUP (for daemonized) and
--- SIGUSR1 (for all) redbean instances. `reindex` indicates if redbean
--- assets have been re-indexed following the signal.
---@param reindex boolean
function OnServerReload(reindex) end
--- If this function is defined it'll be called from the main process
--- right before the main event loop starts.
function OnServerStart() end
--- If this function is defined it'll be called from the main process
--- after all the connection processes have been reaped and `exit()` is
--- ready to be called.
function OnServerStop() end
--- If this function is defined it'll be called from the child worker
--- process after it's been forked and before messages are handled.
--- This won't be called in uniprocess mode.
function OnWorkerStart() end
--- If this function is defined it'll be called from the child worker
--- process once `_exit()` is ready to be called. This won't be called
--- in uniprocess mode.
function OnWorkerStop() end
-- DATATYPES
---@class Url
---@field scheme string e.g. `"http"`
---@field user string? the username string, or nil if absent
---@field pass string? the password string, or nil if absent
---@field host string? the hostname string, or nil if `url` was a path
---@field port string? the port string, or nil if absent
---@field path string? the path string, or nil if absent
---@field params string[][]? the URL paramaters e.g. `/?a=b&c` would be
--- represented as the data structure `{{"a", "b"}, {"c"}, ...}`
---@field fragment string? the stuff after the `#` character
---@alias uint32 integer Unsigned 32-bit integer
---@alias uint16 integer Unsigned 16-bit integer
---@alias uint8 integer Unsigned 8-bit integer
---@alias int8 integer Signed 8-bit integer
---@class EncoderOptions
---@field useoutput boolean? defaults to `false`. Encodes the result directly to the output buffer and returns `nil` value. This option is ignored if used outside of request handling code.
---@field sorted boolean? defaults to `true`. Lua uses hash tables so the order of object keys is lost in a Lua table. So, by default, we use strcmp to impose a deterministic output order. If you don't care about ordering then setting sorted=false should yield a performance boost in serialization.
---@field pretty boolean? defaults to `false`. Setting this option to true will cause tables with more than one entry to be formatted across multiple lines for readability.
---@field indent string? defaults to " ". This option controls the indentation of pretty formatting. This field is ignored if pretty isn't true.
---@field maxdepth integer? defaults to 64. This option controls the maximum amount of recursion the serializer is allowed to perform. The max is 32767. You might not be able to set it that high if there isn't enough C stack memory. Your serializer checks for this and will return an error rather than crashing.
-- FUNCTIONS
--- Appends data to HTTP response payload buffer.
---
--- This is buffered independently of headers.
---
---@param data string
function Write(data) end
--- Starts an HTTP response, specifying the parameters on its first line.
---
--- This method will reset the response and is therefore mutually
--- exclusive with `ServeAsset` and other `Serve*` functions. If a
--- status setting function isn't called, then the default behavior is
--- to send `200 OK`.
---
---@param code integer
---@param reason? string is optional since redbean can fill in the appropriate text for well-known magic numbers, e.g. `200`, `404`, etc.
function SetStatus(code, reason) end
--- Appends HTTP header to response header buffer.
---
--- Leading and trailing whitespace is trimmed automatically. Overlong
--- characters are canonicalized. C0 and C1 control codes are forbidden,
--- with the exception of tab. This function automatically calls
--- `SetStatus(200, "OK")` if a status has not yet been set. As
--- `SetStatus` and `Serve*` functions reset the response, `SetHeader`
--- needs to be called after `SetStatus` and `Serve*` functions are
--- called. The header buffer is independent of the payload buffer.
--- Neither is written to the wire until the Lua Server Page has
--- finished executing. This function disallows the setting of certain
--- headers such as and Content-Range which are abstracted by the
--- transport layer. In such cases, consider calling `ServeAsset`.
---
---@param name string is case-insensitive and restricted to non-space ASCII
---@param value string is a UTF-8 string that must be encodable as ISO-8859-1.
function SetHeader(name, value) end
--- Appends Set-Cookie HTTP header to the response header buffer.
---
--- Several Set-Cookie headers can be added to the same response.
--- `__Host-` and `__Secure-` prefixes are supported and may set or
--- overwrite some of the options (for example, specifying `__Host-`
--- prefix sets the Secure option to `true`, sets the path to `"/"`, and
--- removes the Domain option). The following options can be used (their
--- lowercase equivalents are supported as well):
---
--- - `Expires` sets the maximum lifetime of the cookie as an HTTP-date timestamp. Can be specified as a Date in the RFC1123 (string) format or as a UNIX timestamp (number of seconds).
--- - `MaxAge` sets number of seconds until the cookie expires. A zero or negative number will expire the cookie immediately. If both Expires and MaxAge are set, MaxAge has precedence.
--- - `Domain` sets the host to which the cookie will be sent.
--- - `Path` sets the path that must be present in the request URL, or the client will not send the Cookie header.
--- - `Secure` (boolean) requests the cookie to be only send to the server when a request is made with the https: scheme.
--- - `HttpOnly` (boolean) forbids JavaScript from accessing the cookie.
--- - `SameSite` (Strict, Lax, or None) controls whether a cookie is sent with cross-origin requests, providing some protection against cross-site request forgery attacks.
---
---@param name string
---@param value string
---@param options { Expires: string|integer?, MaxAge: integer?, Domain: string?, Path: string?, Secure: boolean?, HttpOnly: boolean?, SameSite: "Strict"|"Lax"|"None"? }?
function SetCookie(name, value, options) end
--- Returns first value associated with name. name is handled in a case-sensitive manner. This function checks Request-URL parameters first. Then it checks `application/x-www-form-urlencoded` from the message body, if it exists, which is common for HTML forms sending `POST` requests. If a parameter is supplied matching name that has no value, e.g. `foo` in `?foo&bar=value`, then the returned value will be `nil`, whereas for `?foo=&bar=value` it would be `""`. To differentiate between no-equal and absent, use the `HasParam` function. The returned value is decoded from ISO-8859-1 (only in the case of Request-URL) and we assume that percent-encoded characters were supplied by the client as UTF-8 sequences, which are returned exactly as the client supplied them, and may therefore may contain overlong sequences, control codes, `NUL` characters, and even numbers which have been banned by the IETF. It is the responsibility of the caller to impose further restrictions on validity, if they're desired.
---@param name string
---@return string value
---@nodiscard
function GetParam(name) end
--- Escapes HTML entities: The set of entities is `&><"'` which become `&><"'`. This function is charset agnostic and will not canonicalize overlong encodings. It is assumed that a UTF-8 string will be supplied. See `escapehtml.c`.
---@param str string
---@return string
---@nodiscard
function EscapeHtml(str) end
--- Launches web browser on local machine with URL to this redbean server. This function may be called from your `/.init.lua`.
---@param path string?
function LaunchBrowser(path) end
---@param ip uint32
---@return string # a string describing the IP address. This is currently Class A granular. It can tell you if traffic originated from private networks, ARIN, APNIC, DOD, etc.
---@nodiscard
function CategorizeIp(ip) end
--- Turns ISO-8859-1 string into UTF-8.
---@param iso_8859_1 string
---@return string UTF8
---@nodiscard
function DecodeLatin1(iso_8859_1) end
--- Turns binary into ASCII base-16 hexadecimal lowercase string.
---@param binary string
---@return string ascii
function EncodeHex(binary) end
--- Turns ASCII base-16 hexadecimal byte string into binary string,
--- case-insensitively. Non-hex characters may not appear in string.
---@param ascii string
---@return string binary
function DecodeHex(ascii) end
--- Decodes binary data encoded as base64.
---
--- This turns ASCII into binary, in a permissive way that ignores
--- characters outside the base64 alphabet, such as whitespace. See
--- `decodebase64.c`.
---
---@param ascii string
---@return string binary
---@nodiscard
function DecodeBase64(ascii) end
--- Turns binary into ASCII. This can be used to create HTML data:
--- URIs that do things like embed a PNG file in a web page. See
--- encodebase64.c.
---@param binary string
---@return string ascii
---@nodiscard
function EncodeBase64(binary) end
---@alias JsonEl<T> string|number|boolean|nil|{ [integer]: T }|{ [string]: T }
---@alias JsonValue JsonEl<JsonEl<JsonEl<JsonEl<JsonEl<JsonEl<JsonEl<any>>>>>>>
--- Turns JSON string into a Lua data structure.
---
--- This is a generally permissive parser, in the sense that like
--- v8, it permits scalars as top-level values. Therefore we must
--- note that this API can be thought of as special, in the sense
---
--- val = assert(DecodeJson(str))
---
--- will usually do the right thing, except in cases where `false`
--- or `null` are the top-level value. In those cases, it's needed
--- to check the second value too in order to discern from error
---
--- val, err = DecodeJson(str)
--- if not val then
--- if err then
--- print('bad json', err)
--- elseif val == nil then
--- print('val is null')
--- elseif val == false then
--- print('val is false')
--- end
--- end
---
--- This parser supports 64-bit signed integers. If an overflow
--- happens, then the integer is silently coerced to double, as
--- consistent with v8. If a double overflows into `Infinity`, we
--- coerce it to `null` since that's what v8 does, and the same
--- goes for underflows which, like v8, are coerced to `0.0`.
---
--- When objects are parsed, your Lua object can't preserve the
--- original ordering of fields. As such, they'll be sorted by
--- `EncodeJson()` and may not round-trip with original intent.
---
--- This parser has perfect conformance with JSONTestSuite.
---
--- This parser validates utf-8 and utf-16.
---@param input string
---@return JsonValue
---@nodiscard
---@overload fun(input: string): nil, error: string
function DecodeJson(input) end
--- Turns Lua data structure into JSON string.
---
--- Since Lua uses tables are both hashmaps and arrays, we use a
--- simple fast algorithm for telling the two apart. Tables with
--- non-zero length (as reported by `#`) are encoded as arrays,
--- and any non-array elements are ignored. For example:
---
--- >: EncodeJson({2})
--- "[2]"
--- >: EncodeJson({[1]=2, ["hi"]=1})
--- "[2]"
---
--- If there are holes in your array, then the serialized array
--- will exclude everything after the first hole. If the beginning
--- of your array is a hole, then an error is returned.
---
--- >: EncodeJson({[1]=1, [3]=3})
--- "[1]"
--- >: EncodeJson({[2]=1, [3]=3})
--- "[]"
--- >: EncodeJson({[2]=1, [3]=3})
--- nil "json objects must only use string keys"
---
--- If the raw length of a table is reported as zero, then we
--- check for the magic element `[0]=false`. If it's present, then
--- your table will be serialized as empty array `[]`. An entry is
--- inserted by `DecodeJson()` automatically, only when encountering
--- empty arrays, and it's necessary in order to make empty arrays
--- round-trip. If raw length is zero and `[0]=false` is absent,
--- then your table will be serialized as an iterated object.
---
--- >: EncodeJson({})
--- "{}"
--- >: EncodeJson({[0]=false})
--- "[]"
--- >: EncodeJson({["hi"]=1})
--- "{\"hi\":1}"
--- >: EncodeJson({["hi"]=1, [0]=false})
--- "[]"
--- >: EncodeJson({["hi"]=1, [7]=false})
--- nil "json objects must only use string keys"
---
--- The following options may be used:
---
--- - `useoutput`: `(bool=false)` encodes the result directly to the output buffer
--- and returns nil value. This option is ignored if used outside of request
--- handling code.
--- - `sorted`: `(bool=true)` Lua uses hash tables so the order of object keys is
--- lost in a Lua table. So, by default, we use strcmp to impose a deterministic
--- output order. If you don't care about ordering then setting `sorted=false`
--- should yield a performance boost in serialization.
--- - `pretty`: `(bool=false)` Setting this option to true will cause tables with
--- more than one entry to be formatted across multiple lines for readability.
--- - `indent`: `(str=" ")` This option controls the indentation of pretty
--- formatting. This field is ignored if pretty isn't `true`.
--- - `maxdepth`: `(int=64)` This option controls the maximum amount of recursion
--- the serializer is allowed to perform. The max is 32767. You might not be able
--- to set it that high if there isn't enough C stack memory. Your serializer
--- checks for this and will return an error rather than crashing.
---
--- If the raw length of a table is reported as zero, then we
--- check for the magic element `[0]=false`. If it's present, then
--- your table will be serialized as empty array `[]`. An entry is
--- inserted by `DecodeJson()` automatically, only when encountering
--- empty arrays, and it's necessary in order to make empty arrays
--- round-trip. If raw length is zero and `[0]=false` is absent,
--- then your table will be serialized as an iterated object.
---
--- This function will return an error if:
---
--- - value is cyclic
--- - value has depth greater than 64
--- - value contains functions, user data, or threads
--- - value is table that blends string / non-string keys
--- - Your serializer runs out of C heap memory (setrlimit)
---
--- We assume strings in value contain UTF-8. This serializer currently does not
--- produce UTF-8 output. The output format is right now ASCII. Your UTF-8 data
--- will be safely transcoded to `\uXXXX` sequences which are UTF-16. Overlong
--- encodings in your input strings will be canonicalized rather than validated.
---
--- NaNs are serialized as `null` and Infinities are `null` which is consistent
--- with the v8 behavior.
---@param value JsonValue
---@param options { useoutput: false?, sorted: boolean?, pretty: boolean?, indent: string?, maxdepth: integer? }?
---@return string
---@nodiscard
---@overload fun(value: JsonValue, options: { useoutput: true, sorted: boolean?, pretty: boolean?, indent: string?, maxdepth: integer? }): true
---@overload fun(value: JsonValue, options: { useoutput: boolean?, sorted: boolean?, pretty: boolean?, indent: string?, maxdepth: integer? }? ): nil, error: string
function EncodeJson(value, options) end
--- Turns Lua data structure into Lua code string.
---
--- Since Lua uses tables as both hashmaps and arrays, tables will only be
--- serialized as an array with determinate order, if it's an array in the
--- strictest possible sense.
---
--- 1. for all π=π£ in table, π is an integer β₯1
--- 2. no holes exist between MIN(π) and MAX(π)
--- 3. if non-empty, MIN(π) is 1
---
--- In all other cases, your table will be serialized as an object which is
--- iterated and displayed as a list of (possibly) sorted entries that have
--- equal signs.
---
--- >: EncodeLua({3, 2})
--- "{3, 2}"
--- >: EncodeLua({[1]=3, [2]=3})
--- "{3, 2}"
--- >: EncodeLua({[1]=3, [3]=3})
--- "{[1]=3, [3]=3}"
--- >: EncodeLua({["hi"]=1, [1]=2})
--- "{[1]=2, hi=1}"
---
--- The following options may be used:
---
--- - `useoutput`: `(bool=false)` encodes the result directly to the output buffer
--- and returns nil value. This option is ignored if used outside of request
--- handling code.
--- - `sorted`: `(bool=true)` Lua uses hash tables so the order of object keys is
--- lost in a Lua table. So, by default, we use strcmp to impose a deterministic
--- output order. If you don't care about ordering then setting `sorted=false`
--- should yield a performance boost in serialization.
--- - `pretty`: `(bool=false)` Setting this option to true will cause tables with
--- more than one entry to be formatted across multiple lines for readability.
--- - `indent`: `(str=" ")` This option controls the indentation of pretty
--- formatting. This field is ignored if pretty isn't `true`.
--- - `maxdepth`: `(int=64)` This option controls the maximum amount of recursion
--- the serializer is allowed to perform. The max is 32767. You might not be able
--- to set it that high if there isn't enough C stack memory. Your serializer
--- checks for this and will return an error rather than crashing.
---
--- If a user data object has a `__repr` or `__tostring` meta method, then that'll
--- be used to encode the Lua code.
---
--- This serializer is designed primarily to describe data. For example, it's used
--- by the REPL where we need to be able to ignore errors when displaying data
--- structures, since showing most things imperfectly is better than crashing.
--- Therefore this isn't the kind of serializer you'd want to use to persist data
--- in prod. Try using the JSON serializer for that purpose.
---
--- Non-encodable value types (e.g. threads, functions) will be represented as a
--- string literal with the type name and pointer address. The string description
--- is of an unspecified format that could most likely change. This encoder detects
--- cyclic tables; however instead of failing, it embeds a string of unspecified
--- layout describing the cycle.
---
--- Integer literals are encoded as decimal. However if the int64 number is β₯256
--- and has a population count of 1 then we switch to representating the number in
--- hexadecimal, for readability. Hex numbers have leading zeroes added in order
--- to visualize whether the number fits in a uint16, uint32, or int64. Also some
--- numbers can only be encoded expressionally. For example, `NaN`s are serialized
--- as `0/0`, and `Infinity` is `math.huge`.
---
--- >: 7000
--- 7000
--- >: 0x100
--- 0x0100
--- >: 0x10000
--- 0x00010000
--- >: 0x100000000
--- 0x0000000100000000
--- >: 0/0
--- 0/0
--- >: 1.5e+9999
--- math.huge