在 Python 3 中提供目录 [英] Serve directory in Python 3

查看:47
本文介绍了在 Python 3 中提供目录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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()

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

If Instead of the custom class above, I simply pass Handler = http.server.SimpleHTTPRequestHandler into TCPServer():, the default functionality is to serve a directory, but I want to serve that directory and have functionality on my two GETs above.

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

As an example, if someone were to go to localhost:8080/index.html, I'd want that file to be served to them

推荐答案

简单的方法

您想扩展SimpleHTTPRequestHandler 的功能,所以您子类化它!检查您的特殊条件,如果它们都不适用,请调用 super().do_GET() 并让它完成其余的工作.

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.

示例:

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()

路漫漫其修远兮

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

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')

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

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)

把它放在里面(在检查/up 之后):

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')

注意你定义了 path 并随后使用它,否则你仍然会从/

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

这篇关于在 Python 3 中提供目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆