Your implementation has a race condition in it. If two threads run at the same 
time and get the same port from “find_free_port” one of your nc calls will fail.

Also why are you not using the subprocess module?

> On 26 Jul 2018, at 4:11 pm, Andrew Stuart <andrew.stu...@supercoders.com.au> 
> wrote:
> 
> 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()
> 
> 
> 
> 
> 
> 
> _______________________________________________
> melbourne-pug mailing list
> melbourne-pug@python.org
> https://mail.python.org/mailman/listinfo/melbourne-pug
_______________________________________________
melbourne-pug mailing list
melbourne-pug@python.org
https://mail.python.org/mailman/listinfo/melbourne-pug

Reply via email to