[melbourne-pug] Spawn new process to handle inbound websocket connection
Andrew Stuart
andrew.stuart at supercoders.com.au
Thu Jul 26 02:11:05 EDT 2018
Thanks to Tim and Rory and Ben Finney who all chipped in with ideas.
Just to follow through, here’s the solution I put together in the end. It spawns a netcat process in response to a POST request (Python 3.6). I managed to avoid implementing a queueing system and lots of file juggling. It’s just plain TCP sockets, not websockets.
Send this to get a new netcat process spawned on a port:
curl -X POST -H "Content-Type: text/plain" --data ‘example data' localhost:8000
from http.server import HTTPServer, BaseHTTPRequestHandler
import socket
import os
import io
host = '0.0.0.0'
port = 8000
def find_free_port():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('', 0))
return s.getsockname()[1]
def spawn_netcat(port):
command = "/bin/nc"
params = f"nc -l {port}"
spawnDaemon(command, params.split())
def spawnDaemon(path_to_executable, params):
# Do first fork
pid = os.fork()
if (pid != 0):
os.waitid(os.P_PID, pid, os.WEXITED)
return
# Decouple from parent environment
os.chdir("/opt")
os.setsid()
os.umask(0)
# Do second fork
pid = os.fork()
if (pid != 0):
os._exit(0)
# exec this process into netcat.....
os.execv(path_to_executable, params)
class Server(BaseHTTPRequestHandler):
def do_POST(self):
netcat_listen_port = find_free_port()
spawn_netcat(netcat_listen_port)
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
response = io.BytesIO()
response.write(str(netcat_listen_port).encode())
self.wfile.write(response.getvalue())
if __name__ == "__main__":
httpd = HTTPServer((host, port), Server)
httpd.serve_forever()
More information about the melbourne-pug
mailing list