Serve directory in Python 3

前端 未结 2 1364
自闭症患者
自闭症患者 2021-01-19 07:20

I\'ve got this basic python3 server but can\'t figure out how to serve a directory.

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
        def do_GE         


        
2条回答
  •  暖寄归人
    2021-01-19 08:07

    The simple way

    You want to extend the functionality of SimpleHTTPRequestHandler, so you subclass it! Check for your special condition(s), if none of them apply, call super().do_GET() and let it do the rest.

    Example:

    class MyHandler(http.server.SimpleHTTPRequestHandler):
        def do_GET(self):
            if self.path == '/up':
                self.send_response(200)
                self.end_headers()
                self.wfile.write(b'up')
            else:
                super().do_GET()
    

    The long way

    To serve files, you basically just have to open them, read the contents and send it. To serve directories (indexes), use os.listdir(). (If you want, you can when receiving directories first check for an index.html and then, if that fails, serve an index listing).

    Putting this into your code will give you:

    class MyHandler(http.server.BaseHTTPRequestHandler):
        def do_GET(self):
            print(self.path)
            if self.path == '/up':
                self.send_response(200)
                self.end_headers()
                self.wfile.write(b'Going up')
            elif os.path.isdir(self.path):
                try:
                    self.send_response(200)
                    self.end_headers()
                    self.wfile.write(str(os.listdir(self.path)).encode())
                except Exception:
                    self.send_response(500)
                    self.end_headers()
                    self.wfile.write(b'error')
            else:
                try:
                    with open(self.path, 'rb') as f:
                        data = f.read()
                    self.send_response(200)
                    self.end_headers()
                    self.wfile.write(data)
                except FileNotFoundError:
                    self.send_response(404)
                    self.end_headers()
                    self.wfile.write(b'not found')
                except PermissionError:
                    self.send_response(403)
                    self.end_headers()
                    self.wfile.write(b'no permission')
                except Exception:
                    self.send_response(500)
                    self.end_headers()
                    self.wfile.write(b'error')
    

    This example has a lot of error handling. You might want to move it somewhere else. The problem is this serves from your root directory. To stop this, you'll have to (easy way) just add the serving directory to the beginning of self.path. Also check if .. cause you to land higher than you want. A way to do this is os.path.abspath(serve_from+self.path).startswith(serve_from)

    Putting this inside (after the check for /up):

    class MyHandler(http.server.BaseHTTPRequestHandler):
        def do_GET(self):
            print(self.path)
            path = serve_from + self.path
            if self.path == '/up':
                self.send_response(200)
                self.end_headers()
                self.wfile.write(b'Going up')
            elif not os.path.abspath(path).startswith(serve_from):
                self.send_response(403)
                self.end_headers()
                self.wfile.write(b'Private!')
            elif os.path.isdir(path):
                try:
                    self.send_response(200)
                    self.end_headers()
                    self.wfile.write(str(os.listdir(path)).encode())
                except Exception:
                    self.send_response(500)
                    self.end_headers()
                    self.wfile.write(b'error')
            else:
                try:
                    with open(path, 'rb') as f:
                        data = f.read()
                    self.send_response(200)
                    self.end_headers()
                    self.wfile.write(data)
                # error handling skipped
                except Exception:
                    self.send_response(500)
                    self.end_headers()
                    self.wfile.write(b'error')
    

    Note you define path and use it subsequently, otherwise you will still serve from /

提交回复
热议问题