Hack the planet! Send feedback to jtunney@gmail.com

command line api

Latency should be 30 milliseconds, plus network overhead.

curl --tcp-fastopen -H 'Content-Type: text/plain' -d '
import time
time.sleep(1)
print("hello")
time.sleep(1)
print("hello")
' http://redbean.systems/python

source code

# Copyright 2023 Justine Alexandra Roberts Tunney
#
# Permission to use, copy, modify, and/or distribute this software for
# any purpose with or without fee is hereby granted, provided that the
# above copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
# AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.

import cosmo
import errno
import http.server
import math
import os
import resource
import signal
import socketserver
import sys
import time
import tokenbucket
import traceback
import urllib.parse

# public python sandbox
# secured by pledge() and unveil()
#
# git clone https://github.com/jart/cosmopolitan
# cd cosmopolitan
# make -j8 o//third_party/python/python.com
# o//third_party/python/python.com pledgethon.py 8080
# google-chrome http://127.0.0.1:8080

REPLENISH = 30.                                            # seconds to grant a token
BUCKETBIT = 24                                             # netmask bits for each bucket
BURSTNESS = 5                                              # number of fast executions allowed
TIM_LIMIT = 3.                                             # max seconds of wall time for client
THR_LIMIT = (0, 0)                                         # max numbers of threads on whole system
CPU_LIMIT = (1, 2)                                         # max seconds of cpu time for each client
FDS_LIMIT = (128, 128)                                     # highest numbered file descriptor allowed
FSZ_LIMIT = (500*1000, 512*1000)                           # maximum number of bytes allowed in file
RAM_LIMIT = (64*1024*1024, 65*1024*1024)                   # bytes of ram client is allowed to have
SERVER_PLEDGE = 'stdio rpath wpath cpath anet proc unveil' # system calls allowed for whole server
CLIENT_PLEDGE = 'stdio rpath wpath cpath'                  # subset of above syscalls for clients

std_print = print  # make print() non-buffered to stdout
print = lambda *args, **kwargs: std_print(*args, **kwargs, flush=True)


def run(cmd):
  print(cmd)
  os.system(cmd)


def on_sigalrm(signum, frame):
  os.write(2, b'*** RAN OUT OF WALL TIME ***n')
  os.kill(pid, signal.SIGKILL)


def on_sigxcpu(signum, frame):
  os.write(2, b'*** RAN OUT OF CPU QUOTA ***n')
  os._exit(128 + signal.SIGXCPU)


def on_sigxfsz(signum, frame):
  os.write(2, b'*** RAN OUT OF FILE QUOTA ***n')
  os._exit(128 + signal.SIGXFSZ)


class Server(socketserver.ForkingMixIn, http.server.HTTPServer):
  max_children = 256
  protocol_version = 'HTTP/1.0'

  def forked_request(self, request, client_address):
    resource.setrlimit(resource.RLIMIT_AS, RAM_LIMIT)
    resource.setrlimit(resource.RLIMIT_CPU, CPU_LIMIT)
    resource.setrlimit(resource.RLIMIT_FSIZE, FSZ_LIMIT)
    os.close(0)                        # close standard input
    os.close(3)                        # close server socket
    cosmo.verynice()                   # low client priority
    cosmo.unveil('/public', 'rwc')     # unveil the fun folder
    cosmo.unveil('/proc/cpuinfo', 'r') # unveil this file to our visitors
    cosmo.unveil(None, None)           # commit filesystem policy
    os.chdir('/public')                # go to fun folder


class Handler(http.server.SimpleHTTPRequestHandler):
  protocol_version = 'HTTP/1.0'
  server_version = 'pledgethon/1.o'

  def do_GET(self):
    self.close_connection = True
    self.send_response(200)
    content = b'''



Redbean Systems

Redbean Systems


source code

%s

''' % (SAUCE)
self.send_header('Content-Type', 'text/html; charset=utf-8')
self.send_header('Cache-Control', 'max-age=0, no-store');
self.send_header('Content-Length', str(len(content)))
self.send_header('Connection', 'close')
self.end_headers()
self.wfile.write(content)
self.wfile.flush()

def do_POST(self):
self.close_connection = True
ip = self.client_address[0]
if ip == '127.0.0.1' and 'X-Forwarded-For' in self.headers:
ip = self.headers['X-Forwarded-For']
tokens = tokenbucket.acquire(ip)
debt = 128 - BURSTNESS - tokens
if debt > 0:
if tokens < 60: tokenbucket.blackhole(ip) self.bounce(debt) return content_length = int(self.headers['Content-Length']) post_data = self.rfile.read(content_length) post_data = post_data.decode('utf-8') parameters = urllib.parse.parse_qs(post_data) code = parameters['code'][0] if 'code' in parameters else '' self.send_response(200) self.send_header('Content-Type', 'text/plain; charset=utf-8') self.send_header('Cache-Control', 'max-age=0, no-store'); self.send_header('Connection', 'close') self.end_headers() self.wfile.flush() os.dup2(4, 1) # map client socket to stdout os.dup2(4, 2) # map client socket to stderr supervise() resource.setrlimit(resource.RLIMIT_NPROC, THR_LIMIT) cosmo.pledge(CLIENT_PLEDGE, None) # restrict permissible system calls exec(code) def bounce(self, debt): self.send_response(429) self.send_header('Content-Type', 'text/plain; charset=utf-8') self.send_header('Cache-Control', 'max-age=0, no-store'); self.send_header('Connection', 'close') self.end_headers() self.wfile.write(b'*** TOO MANY REQUESTS ***n') self.wfile.write(b'*** WAIT %d SECONDS ***n' % (int(math.ceil(debt * REPLENISH)))) self.wfile.flush() def supervise(): global pid signal.setitimer(signal.ITIMER_REAL, TIM_LIMIT) started = time.time() pid = os.fork() if not pid: return pid, ws, ru = os.wait4(pid, 0) if os.WIFEXITED(ws): print('*** EXITED WITH STATUS %d ***' % (os.WEXITSTATUS(ws))) else: print('*** TERMINATED BY %s ***' % (signal.Signals(os.WTERMSIG(ws)).name)) cputime = ru.ru_utime + ru.ru_stime print('*** USED %.6f SECONDS OF WALL TIME ***' % (time.time() - started)) print('*** USED %.6f SECONDS OF CPU TIME (%.3f%% SYSTEM) ***' % (cputime, ru.ru_stime / cputime * 100)) print('*** BALLOONED TO %d KB OF RESIDENT MEMORY ***' % (ru.ru_maxrss)) if ru.ru_msgrcv or ru.ru_msgsnd: print('*** RECEIVED %d MESSAGES AND SENT %d ***' % (ru.ru_msgrcv, ru.ru_msgsnd)) if ru.ru_nvcsw or ru.ru_nivcsw: print('*** TRIGGERED %d CONTEXT SWITCHES ***' % (ru.ru_nvcsw + ru.ru_nivcsw)) print('*** TRIGGERED %d PAGE FAULTS ***' % (ru.ru_minflt + ru.ru_majflt)) if ru.ru_nsignals: print('*** RECEIVED %d SIGNALS ***' % (ru.ru_nsignals)) os._exit(0) if __name__ == '__main__': with open(sys.argv[0], 'rb') as fin: SAUCE = fin.read().replace(b'&', b'&').replace(b'<', b'<').replace(b'>', b'>')
if not os.path.isdir('/public'):
run('sudo mkdir /public')
run('sudo chmod 1777 /public')
if tokenbucket.blackhole('0.0.0.0') != 0:
sys.stderr.write("warning: blackholed.com isn't runningn")
tokenbucket.config(REPLENISH, BUCKETBIT)
resource.setrlimit(resource.RLIMIT_NOFILE, FDS_LIMIT)
signal.signal(signal.SIGALRM, on_sigalrm)
signal.signal(signal.SIGXCPU, on_sigxcpu)
signal.signal(signal.SIGXFSZ, on_sigxfsz)
cosmo.pledge(None, None) # throws exception if seccomp isn't available
cosmo.unveil('', None) # throws exception if landlock isn't available
cosmo.pledge(SERVER_PLEDGE, None) # server system call restrictions
port = int(sys.argv[1]) if len(sys.argv) > 1 else 8080
addr = ('0.0.0.0', port)
print('pledgethon http://%s:%d' % (addr[0], addr[1]))
httpd = Server(addr, Handler)
httpd.serve_forever()

Read More