# Extended python -m http.serve with --username and --password parameters for # basic auth, based on https://gist.github.com/fxsjy/5465353 # Usage: python -m http_server_auth -u USERNAME -p PASSWORD -d . from functools import partial from http.server import SimpleHTTPRequestHandler, test import base64 import os class AuthHTTPRequestHandler(SimpleHTTPRequestHandler): """ Main class to present webpages and authentication. """ def __init__(self, *args, **kwargs): username = kwargs.pop("username") password = kwargs.pop("password") self._auth = base64.b64encode(f"{username}:{password}".encode()).decode() super().__init__(*args) def do_HEAD(self): self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() def do_AUTHHEAD(self): self.send_response(401) self.send_header("WWW-Authenticate", 'Basic realm="Test"') self.send_header("Content-type", "text/html") self.end_headers() def do_GET(self): """ Present frontpage with user authentication. """ if self.headers.get("Authorization") == None: self.do_AUTHHEAD() self.wfile.write(b"no auth header received") elif self.headers.get("Authorization") == "Basic " + self._auth: SimpleHTTPRequestHandler.do_GET(self) else: self.do_AUTHHEAD() self.wfile.write(self.headers.get("Authorization").encode()) self.wfile.write(b"not authenticated") if __name__ == "__main__": import argparse parser = argparse.ArgumentParser() parser.add_argument("--cgi", action="store_true", help="Run as CGI Server") parser.add_argument( "--bind", "-b", metavar="ADDRESS", default="127.0.0.1", help="Specify alternate bind address " "[default: all interfaces]", ) parser.add_argument( "--directory", "-d", default=os.getcwd(), help="Specify alternative directory " "[default:current directory]", ) parser.add_argument( "port", action="store", default=8000, type=int, nargs="?", help="Specify alternate port [default: 8000]", ) parser.add_argument("--username", "-u", metavar="USERNAME") parser.add_argument("--password", "-p", metavar="PASSWORD") args = parser.parse_args() handler_class = partial( AuthHTTPRequestHandler, username=args.username, password=args.password, directory=args.directory, ) test(HandlerClass=handler_class, port=args.port, bind=args.bind)