'Helper to produce a directory listing (absent index.html).
Return value is either a file object, or None (indicating an
error).  In either case, the headers are sent, making the
interface the same as for send_head().'

def list_directory(self, path):

    try:
        list = os.listdir(path)
    except OSError:
        self.send_error(404, '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)
    enc = sys.getfilesystemencoding()
    title = ('Directory    listing    for    %s' % displaypath)
    r.append('<!DOCTYPE    HTML    PUBLIC    "-//W3C//DTD    HTML    4.01//EN"    "http://www.w3.org/TR/html4/strict.dtd">')
    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
        if os.path.isdir(fullname):
            displayname = (name + '/')
            linkname = (name + '/')
        if os.path.islink(fullname):
            displayname = (name + '@')
        r.append(('<li><a    href="%s">%s</a></li>' % (urllib.parse.quote(linkname, errors='surrogatepass'), html.escape(displayname))))
    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(200)
    self.send_header('Content-type', ('text/html;    charset=%s' % enc))
    self.send_header('Content-Length', str(len(encoded)))
    self.end_headers()
    return f
