在 Python 3 中提供目录

Way*_*eio 4 python python-3.x server

我有这个基本的 python3 服务器,但不知道如何提供目录。

class SimpleHTTPRequestHandler(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')
            if self.path == '/down':
                self.send_response(200)
                self.end_headers()
                self.wfile.write(B'Going Down')

httpd = socketserver.TCPServer(("", PORT), SimpleHTTPRequestHandler)
print("Server started on ", PORT)
httpd.serve_forever()
Run Code Online (Sandbox Code Playgroud)

如果不是上面的自定义类,我只是简单地传入Handler = http.server.SimpleHTTPRequestHandlerTCPServer():,默认功能是提供一个目录,但我想提供该目录并在上面的两个 GET 上提供功能。

例如,如果有人要访问 localhost:8080/index.html,我希望将该文件提供给他们

edd*_*izm 6

如果你使用 3.7,你可以简单地提供一个目录,你的 html 文件,例如。index.html 仍然是

python -m http.server 8080 --bind 127.0.0.1 --directory \your_directory\
Run Code Online (Sandbox Code Playgroud)

对于文档


use*_*343 4

简单的方法

您想要扩展的功能SimpleHTTPRequestHandler,因此您可以对它进行子类化!检查您的特殊条件,如果都不适用,请致电super().do_GET()并让其完成其余的工作。

例子:

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()
Run Code Online (Sandbox Code Playgroud)

漫漫长路

要提供文件,您基本上只需打开它们,读取内容并发送即可。要提供目录(索引),请使用os.listdir(). (如果需要,您可以在接收目录时首先检查 index.html,然后,如果失败,则提供索引列表)。

将其放入您的代码中将为您提供:

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')
Run Code Online (Sandbox Code Playgroud)

这个例子有很多错误处理。您可能想将其移到其他地方。问题是这是从您的根目录提供的。要阻止这种情况,您必须(简单的方法)只需将服务目录添加到self.path. 还要检查是否..导致您着陆得比您想要的更高。一种方法是os.path.abspath(serve_from+self.path).startswith(serve_from)

将其放入其中(在检查 /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')
Run Code Online (Sandbox Code Playgroud)

请注意您随后定义path并使用它,否则您仍将从 / 提供服务