Skip to content

Instantly share code, notes, and snippets.

@notatallshaw
Created February 13, 2022 02:07
Show Gist options
  • Save notatallshaw/f314c40d915c91d66def102fc05b67a0 to your computer and use it in GitHub Desktop.
Save notatallshaw/f314c40d915c91d66def102fc05b67a0 to your computer and use it in GitHub Desktop.
import io
import os
import sys
import html
import http.server
import urllib.parse
from http import HTTPStatus
from functools import partial
class SimpleHTTP5RequestHandler(http.server.SimpleHTTPRequestHandler):
def list_directory(self, path):
try:
list = os.listdir(path)
except OSError:
self.send_error(
HTTPStatus.NOT_FOUND,
"No permission to list directory")
return None
list.sort(key=lambda a: a.lower())
r = []
try:
displaypath = urllib.parse.unquote(self.path,
errors='surrogatepass')
except UnicodeDecodeError:
displaypath = urllib.parse.unquote(path)
displaypath = html.escape(displaypath, quote=False)
enc = sys.getfilesystemencoding()
title = 'Directory listing for %s' % displaypath
r.append('<!DOCTYPE HTML>')
r.append('<html>\n<head>')
r.append('<meta http-equiv="Content-Type" '
'content="text/html; charset=%s">' % enc)
r.append('<title>%s</title>\n</head>' % title)
r.append('<body>\n<h1>%s</h1>' % title)
r.append('<hr>\n<ul>')
for name in list:
fullname = os.path.join(path, name)
displayname = linkname = name
# Append / for directories or @ for symbolic links
if os.path.isdir(fullname):
displayname = name + "/"
linkname = name + "/"
if os.path.islink(fullname):
displayname = name + "@"
# Note: a link to a directory displays with @ and links with /
r.append('<li><a href="%s">%s</a></li>'
% (urllib.parse.quote(linkname,
errors='surrogatepass'),
html.escape(displayname, quote=False)))
r.append('</ul>\n<hr>\n</body>\n</html>\n')
encoded = '\n'.join(r).encode(enc, 'surrogateescape')
f = io.BytesIO()
f.write(encoded)
f.seek(0)
self.send_response(HTTPStatus.OK)
self.send_header("Content-type", "text/html; charset=%s" % enc)
self.send_header("Content-Length", str(len(encoded)))
self.end_headers()
return f
def simple_html5_server(bind, port, directory):
http.server.test(
HandlerClass=partial(
SimpleHTTP5RequestHandler,
directory=directory,
),
bind=bind,
port=port,
)
if __name__ == '__main__':
simple_html5_server('127.0.0.1', 8000, os.getcwd())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment