Make improvements

- Expand redbean UNIX module
- Expand redbean documentation
- Ensure Lua copyright is embedded in binary
- Increase the PATH_MAX limit especially on NT
- Use column major sorting for linenoise completions
- Fix some suboptimalities in redbean's new UNIX API
- Figured out right flags for Multics newline in raw mode
This commit is contained in:
Justine Tunney 2022-04-24 09:59:22 -07:00
parent cf3174dc74
commit 2046c0d2ae
305 changed files with 6602 additions and 4221 deletions

View file

@ -34,3 +34,7 @@ function OnHttpRequest()
end
SetHeader('Server', 'redbean!')
end
function Adder(x, y)
return x + y
end

View file

@ -12,7 +12,7 @@ function dosomething(param1, x)
SetHeader('Content-Type', 'text/plain; charset=utf-8')
Write('preprae to crash... now\r\n')
res = x / y
Write(string.format('42 / 0 is %d\r\n', res))
Write('42 / 0 is %d\r\n' % {res})
end
function start(param1)

View file

@ -2,7 +2,7 @@
local function WriteForm(url)
Write('<!doctype html>\r\n')
Write(string.format([[
Write([[
<title>redbean fetch demo</title>
<style>
body {
@ -41,7 +41,7 @@ local function WriteForm(url)
value="%s" placeholder="uri" autofocus>
<input type="submit" value="fetch">
</form>
]], EscapeHtml(url)))
]] % {EscapeHtml(url)})
end
local function main()
@ -54,7 +54,7 @@ local function main()
WriteForm(GetParam('url'))
Write('<dl>\r\n')
Write('<dt>Status\r\n')
Write(string.format('<dd><p>%d %s\r\n', status, GetHttpReason(status)))
Write('<dd><p>%d %s\r\n' % {status, GetHttpReason(status)})
Write('<dt>Headers\r\n')
Write('<dd>\r\n')
for k,v in pairs(headers) do

View file

@ -167,7 +167,7 @@ local function main()
Write('<dt>GetRemoteAddr() <small>(from Berkeley Sockets or X-Forwarded-For header)</small>\r\n')
Write('<dd>')
ip, port = GetRemoteAddr()
Write(string.format('%s, %d', FormatIp(ip), port))
Write('%s, %d' % {FormatIp(ip), port})
if CategorizeIp(ip) then
Write('<br>\r\n')
Write(CategorizeIp(ip))
@ -176,7 +176,7 @@ local function main()
Write('<dt>GetClientAddr()\r\n')
Write('<dd>')
ip, port = GetClientAddr()
Write(string.format('%s, %d', FormatIp(ip), port))
Write('%s, %d' % {FormatIp(ip), port})
if CategorizeIp(ip) then
Write('<br>\r\n')
Write(CategorizeIp(ip))
@ -185,7 +185,7 @@ local function main()
Write('<dt>GetServerIp()\r\n')
Write('<dd>')
ip, port = GetServerAddr()
Write(string.format('%s, %d', FormatIp(ip), port))
Write('%s, %d' % {FormatIp(ip), port})
if CategorizeIp(ip) then
Write('<br>\r\n')
Write(CategorizeIp(ip))
@ -269,28 +269,28 @@ local function main()
m,a,b,c,d = pat:search(s) -- m and rest are nil if match not found
Write('<pre>\r\n')
Write([[pat = re.compile('([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})')]])
Write(string.format('\r\nm,a,b,c,d = pat:search(%q)\r\n', s))
Write('\r\nm,a,b,c,d = pat:search(%q)\r\n' % {s})
Write('</pre>\r\n')
Write('<dl>\r\n')
Write('<dt>m\r\n')
Write('<dd>')
Write(string.format("%q", m))
Write("%q" % {m})
Write('\r\n')
Write('<dt>a\r\n')
Write('<dd>')
Write(string.format("%q", a))
Write("%q" % {a})
Write('\r\n')
Write('<dt>b\r\n')
Write('<dd>')
Write(string.format("%q", b))
Write("%q" % {b})
Write('\r\n')
Write('<dt>c\r\n')
Write('<dd>')
Write(string.format("%q", c))
Write("%q" % {c})
Write('\r\n')
Write('<dt>d\r\n')
Write('<dd>')
Write(string.format("%q", d))
Write("%q" % {d})
Write('\r\n')
Write('</dl>\r\n')
@ -328,7 +328,7 @@ local function main()
Write(FormatHttpDateTime(GetLastModifiedTime(paths[i])))
Write('<br>\r\n')
Write('Mode: ')
Write(string.format("0%o", GetAssetMode(paths[i])))
Write("0%o" % {GetAssetMode(paths[i])})
Write('<br>\r\n')
Write('Size: ')
Write(tostring(GetAssetSize(paths[i])))

View file

@ -3,53 +3,58 @@ local unix = require 'unix'
Write('<!doctype html>\r\n')
Write('<title>redbean</title>\r\n')
Write('<h3>UNIX Information Demo</h3>\r\n')
Write('<style>dt { margin: .5em 0; font-style:italic; }</style>\r\n')
Write('<dl>\r\n')
Write('<dt>getuid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getuid()))
Write('<dt>getgid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getgid()))
Write('<dt>getpid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getpid()))
Write('<dt>getppid()\r\n')
Write(string.format('<dd>%d\r\n', unix.getppid()))
Write('<dt>getpgrp()\r\n')
Write(string.format('<dd>%d\r\n', unix.getpgrp()))
Write('<dt>unix.getuid()\r\n')
Write('<dd>%d\r\n' % {unix.getuid()})
Write('<dt>unix.getgid()\r\n')
Write('<dd>%d\r\n' % {unix.getgid()})
Write('<dt>unix.getpid()\r\n')
Write('<dd>%d\r\n' % {unix.getpid()})
Write('<dt>unix.getppid()\r\n')
Write('<dd>%d\r\n' % {unix.getppid()})
Write('<dt>unix.getpgrp()\r\n')
Write('<dd>%d\r\n' % {unix.getpgrp()})
Write('<dt>unix.umask()\r\n')
mask = unix.umask(027)
unix.umask(mask)
Write('<dd>%.4o\r\n' % {mask})
Write('<dt>getsid(0)\r\n')
Write('<dt>unix.getsid(0)\r\n')
sid, errno = unix.getsid(0)
if sid then
Write(string.format('<dd>%d\r\n', sid))
Write('<dd>%d\r\n' % {sid})
else
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.strerrno(errno))))
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
end
Write('<dt>gethostname()\r\n')
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.gethostname())))
Write('<dt>getcwd()\r\n')
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.getcwd())))
Write('<dt>unix.gethostname()\r\n')
Write('<dd>%s\r\n' % {EscapeHtml(unix.gethostname())})
Write('<dt>unix.getcwd()\r\n')
Write('<dd>%s\r\n' % {EscapeHtml(unix.getcwd())})
function PrintResourceLimit(name, id)
soft, hard, errno = unix.getrlimit(id)
Write(string.format('<dt>getrlimit(%s)\r\n', name))
Write('<dt>getrlimit(%s)\r\n' % {name})
if soft then
Write('<dd>')
Write('soft ')
if soft == -1 then
Write('')
else
Write(string.format('%d', soft))
Write('%d' % {soft})
end
Write('<br>\r\n')
Write('hard ')
if hard == -1 then
Write('')
else
Write(string.format('%d', hard))
Write('%d' % {hard})
end
Write('\r\n')
else
Write(string.format('<dd>%s\r\n', EscapeHtml(unix.strerrno(errno))))
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
end
end
PrintResourceLimit('RLIMIT_AS', unix.RLIMIT_AS)
@ -59,7 +64,7 @@ PrintResourceLimit('RLIMIT_FSIZE', unix.RLIMIT_FSIZE)
PrintResourceLimit('RLIMIT_NPROC', unix.RLIMIT_NPROC)
PrintResourceLimit('RLIMIT_NOFILE', unix.RLIMIT_NOFILE)
Write('<dt>siocgifconf()\r\n')
Write('<dt>unix.siocgifconf()\r\n')
Write('<dd>\r\n')
ifs, errno = unix.siocgifconf()
if ifs then
@ -69,12 +74,217 @@ if ifs then
else
cidr = 0
end
Write(string.format('%s %s/%d<br>\r\n',
EscapeHtml(ifs[i].name),
FormatIp(ifs[i].ip),
cidr))
Write('%s %s/%d<br>\r\n' % {EscapeHtml(ifs[i].name), FormatIp(ifs[i].ip), cidr})
end
else
Write(string.format('%s\r\n', EscapeHtml(unix.strerrno(errno))))
Write('%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
end
Write('</dl>\r\n')
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DEBUG)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DEBUG)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEADDR)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEADDR)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEPORT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_REUSEPORT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_KEEPALIVE)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_KEEPALIVE)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NODELAY)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NODELAY)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, secs, micros = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVTIMEO)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVTIMEO)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d sec %d µs\r\n' % {secs, micros})
end
errno, secs, micros = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDTIMEO)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDTIMEO)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d sec %d µs\r\n' % {secs, micros})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DONTROUTE)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_DONTROUTE)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDBUF)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDBUF)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVBUF)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVBUF)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_BROADCAST)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_BROADCAST)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_CORK)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_CORK)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_QUICKACK)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_QUICKACK)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_DEFER_ACCEPT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_DEFER_ACCEPT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, enabled = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN_CONNECT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_FASTOPEN_CONNECT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%s\r\n' % {enabled})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDLOWAT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_SNDLOWAT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVLOWAT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_SOCKET, unix.SO_RCVLOWAT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPCNT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPCNT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_MAXSEG)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_MAXSEG)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_SYNCNT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_SYNCNT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NOTSENT_LOWAT)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_NOTSENT_LOWAT)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_WINDOW_CLAMP)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_WINDOW_CLAMP)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPIDLE)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPIDLE)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
errno, bytes = unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPINTVL)
Write('<dt>unix.getsockopt(GetClientFd(), unix.SOL_TCP, unix.TCP_KEEPINTVL)\r\n')
if errno then
Write('<dd>%s\r\n' % {EscapeHtml(unix.strerrno(errno))})
else
Write('<dd>%d\r\n' % {bytes})
end
Write('<dt>unix.environ()\r\n')
Write('<dd>\r\n')
Write('<ul>\r\n')
env = unix.environ()
for i = 1,#env do
Write('<li>%s\r\n' % {EscapeHtml(env[i])})
end
Write('</ul>\r\n')

View file

@ -32,8 +32,9 @@ local function main()
-- steal client from redbean
fd = GetClientFd()
rc, errno = unix.fork()
-- this function returns twice
pid, errno = unix.fork()
if errno then
SetStatus(400)
SetHeader('Content-Type', 'text/html; charset=utf-8')
@ -44,7 +45,7 @@ local function main()
Write(EncodeBase64(LoadAsset('/redbean.png')))
Write('">\r\n')
Write('redbean unix demo\r\n')
Write(string.format('<span style="color:red">&nbsp;%s</span>\r\n', unix.strerrno(errno)))
Write('<span style="color:red">&nbsp;%s</span>\r\n' % {unix.strerrno(errno)})
Write('</h1>\r\n')
Write([[
<p>
@ -57,11 +58,13 @@ local function main()
return
end
if rc ~= 0 then
-- the parent process gets the pid
if pid ~= 0 then
unix.close(fd)
return
end
-- if pid is zero then we're the child
-- turn into a daemon
unix.umask(0)
unix.setsid()
@ -119,7 +122,7 @@ local function main()
else
st, err = unix.stat(name)
if st then
unix.write(fd, string.format(' (%d bytes)', st:size()))
unix.write(fd, ' (%d bytes)' % {st:size()})
end
end
unix.write(fd, '\r\n')
@ -127,7 +130,7 @@ local function main()
unix.write(fd, '</ul>\r\n')
else
unix.write(fd, '<p>\r\n')
unix.write(fd, string.format('failed: %s\r\n', EscapeHtml(VisualizeControlCodes(unix:strerror(err)))))
unix.write(fd, 'failed: %s\r\n' % {EscapeHtml(VisualizeControlCodes(unix:strerror(err)))})
unix.write(fd, '</p>\r\n')
end

View file

@ -2,15 +2,20 @@
-- and pipe its output to the http user
local unix = require "unix"
function main()
if GetHostOs() == 'WINDOWS' then
cmd = 'dir'
else
cmd = 'ls'
end
syscall = 'commandv'
ls, errno = unix.commandv("ls")
ls, errno = unix.commandv(cmd)
if ls then
syscall = 'pipe'
reader, writer, errno = unix.pipe()
if reader then
oldint = unix.sigaction(unix.SIGINT, unix.SIG_IGN)
oldquit = unix.sigaction(unix.SIGQUIT, unix.SIG_IGN)
oldmask = unix.sigprocmask(unix.SIG_BLOCK, unix.SIGCHLD)
-- oldint = unix.sigaction(unix.SIGINT, unix.SIG_IGN)
-- oldquit = unix.sigaction(unix.SIGQUIT, unix.SIG_IGN)
-- oldmask = unix.sigprocmask(unix.SIG_BLOCK, unix.SIGCHLD)
syscall = 'fork'
child, errno = unix.fork()
if child then
@ -19,10 +24,10 @@ function main()
unix.dup(writer)
unix.close(writer)
unix.close(reader)
unix.sigaction(unix.SIGINT, oldint)
unix.sigaction(unix.SIGQUIT, oldquit)
unix.sigprocmask(unix.SIG_SETMASK, oldmask)
unix.execve(ls, {ls, "-Shal"})
-- unix.sigaction(unix.SIGINT, oldint)
-- unix.sigaction(unix.SIGQUIT, oldquit)
-- unix.sigprocmask(unix.SIG_SETMASK, oldmask)
unix.execve(ls, {ls, '-Shal'})
unix.exit(127)
else
unix.close(writer)
@ -31,21 +36,21 @@ function main()
while true do
data, errno = unix.read(reader)
if data then
if data ~= "" then
if data ~= '' then
Write(data)
else
break
end
elseif errno ~= unix.EINTR then
Log(kLogWarn, string.format('read() failed: %s', unix.strerror(errno)))
Log(kLogWarn, 'read() failed: %s' % {unix.strerror(errno)})
break
end
end
unix.close(reader)
unix.wait(-1)
unix.sigaction(unix.SIGINT, oldint)
unix.sigaction(unix.SIGQUIT, oldquit)
unix.sigprocmask(unix.SIG_SETMASK, oldmask)
-- unix.sigaction(unix.SIGINT, oldint)
-- unix.sigaction(unix.SIGQUIT, oldquit)
-- unix.sigprocmask(unix.SIG_SETMASK, oldmask)
return
end
end
@ -53,6 +58,6 @@ function main()
end
SetStatus(200)
SetHeader('Content-Type', 'text/plain')
Write(string.format('error %s calling %s()', unix.strerrno(errno), syscall))
Write('error %s calling %s()' % {unix.strerrno(errno), syscall})
end
main()

View file

@ -46,12 +46,10 @@ function main()
unix.bind(server, ifs[i].ip)
unix.listen(server)
ip, port = unix.getsockname(server)
addr = string.format('%s:%d', FormatIp(ip), port)
url = string.format('http://%s', addr)
Log(kLogInfo, string.format('listening on %s', addr))
unix.write(mainfd, string.format(
'listening on <a target="_blank" href="%s">%s</a><br>\r\n',
url, url))
addr = '%s:%d' % {FormatIp(ip), port}
url = 'http://%s' % {addr}
Log(kLogInfo, 'listening on %s' % {addr})
unix.write(mainfd, 'listening on <a target="_blank" href="%s">%s</a><br>\r\n' % {url, url})
pollfds[server] = unix.POLLIN | unix.POLLHUP
servers[server] = true
addrs[server] = addr
@ -67,7 +65,7 @@ function main()
if fd == mainfd then
data, errno = unix.read(mainfd)
if not data then
Log(kLogInfo, string.format('got %s from parent client', unix.strerrno(errno)))
Log(kLogInfo, 'got %s from parent client' % {unix.strerrno(errno)})
-- prevent redbean core from writing a response
unix.exit(1)
end
@ -80,20 +78,20 @@ function main()
-- echo it back for fun
unix.write(mainfd, data)
elseif servers[fd] then
unix.write(mainfd, string.format('preparing to accept from %d<br>\r\n', fd))
unix.write(mainfd, 'preparing to accept from %d<br>\r\n' % {fd})
client, clientip, clientport = unix.accept(fd)
unix.write(mainfd, string.format('preparing to accept from %d<br>\r\n', fd))
addr = string.format('%s:%d', FormatIp(clientip), clientport)
unix.write(mainfd, 'preparing to accept from %d<br>\r\n' % {fd})
addr = '%s:%d' % {FormatIp(clientip), clientport}
addrs[client] = addr
unix.write(mainfd, string.format('got client %s<br>\r\n', addr))
unix.write(mainfd, 'got client %s<br>\r\n' % {addr})
pollfds[client] = unix.POLLIN
evs[server] = nil
else
unix.write(mainfd, string.format('preparing to read from %d<br>\r\n', fd))
unix.write(mainfd, 'preparing to read from %d<br>\r\n' % {fd})
data = unix.read(fd)
unix.write(mainfd, string.format('done reading from %d<br>\r\n', fd))
unix.write(mainfd, 'done reading from %d<br>\r\n' % {fd})
if data and #data ~= 0 then
unix.write(mainfd, string.format('got %d bytes from %s<br>\r\n', #data, addrs[fd]))
unix.write(mainfd, 'got %d bytes from %s<br>\r\n' % {#data, addrs[fd]})
unix.write(fd, 'HTTP/1.0 200 OK\r\n' ..
'Date: '.. FormatHttpDateTime(GetDate()) ..'\r\n' ..
'Content-Type: text/html; charset=utf-8\r\n' ..