You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
55 lines
2.1 KiB
Plaintext
55 lines
2.1 KiB
Plaintext
3 years ago
|
#!/usr/bin/env python3
|
||
|
from http.server import BaseHTTPRequestHandler, HTTPServer
|
||
|
from subprocess import Popen, PIPE
|
||
|
from shlex import quote
|
||
|
|
||
|
import argparse
|
||
|
import sys
|
||
|
|
||
|
def server_class_factory(command):
|
||
|
class MyServer(BaseHTTPRequestHandler):
|
||
|
def do_GET(self):
|
||
|
self.handle_all()
|
||
|
def do_POST(self):
|
||
|
self.handle_all()
|
||
|
def do_PUT(self):
|
||
|
self.handle_all()
|
||
|
def handle_all(self):
|
||
|
self.send_response(200)
|
||
|
self.send_header("Content-type", "text/html")
|
||
|
self.end_headers()
|
||
|
content = self.rfile.read(int(self.headers.get('Content-Length', 0)))
|
||
|
p = Popen(command + [quote(self.command), quote(self.path)], stdin=PIPE, shell=False)
|
||
|
p.communicate(input=content)
|
||
|
|
||
|
def log_message(self, format, *args):
|
||
|
return
|
||
|
return MyServer
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
parser = argparse.ArgumentParser(description='shellsrv - Translate HTTP requests to command invocations on the host system.\n\n\nEach GET request results in the execution of COMMAND ARGS GET <path>. Other HTTP verbs might be added later.', prog='shellsrv')
|
||
|
|
||
|
parser.add_argument('--host', '-H', type=str, help='HTTP server host, default 0.0.0.0', default="0.0.0.0")
|
||
|
parser.add_argument('--port', '-p', type=int, help='HTTP server port, default 8080', default=8080)
|
||
|
parser.add_argument('--limit', '-n', type=int, help='Close the server after limit requests', default=-1)
|
||
|
parser.add_argument('command', metavar='COMMAND', type=str, nargs=1, help='command to call')
|
||
|
parser.add_argument('args', metavar='ARG', type=str, nargs='*', help='args of the command to call')
|
||
|
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
command = args.command + args.args
|
||
|
request_limit = args.limit
|
||
|
|
||
|
server = HTTPServer((args.host, args.port), server_class_factory(command))
|
||
|
print("Server started http://%s:%s" % (args.host, args.port), file=sys.stderr)
|
||
|
|
||
|
if request_limit < 0:
|
||
|
try:
|
||
|
server.serve_forever()
|
||
|
except KeyboardInterrupt:
|
||
|
pass
|
||
|
else:
|
||
|
for _ in range(request_limit):
|
||
|
server.handle_request()
|
||
|
|
||
|
server.server_close()
|