Python HttpServer 文件上传下载

1. 介绍

在Web开发中,文件上传和下载是非常常见的功能。Python提供了简单的HTTP服务器功能,可以使用Python的http.server模块快速搭建一个HTTP服务器。

本文将介绍如何使用Python的http.server模块搭建一个简单的HTTP服务器,并实现文件的上传和下载功能。

2. 搭建HTTP服务器

首先,我们需要搭建一个HTTP服务器。Python提供了http.server模块,其中包含了一个SimpleHTTPRequestHandler类,可以用于处理HTTP请求。

下面是一个简单的示例代码:

from http.server import HTTPServer, SimpleHTTPRequestHandler

def run(server_class=HTTPServer, handler_class=SimpleHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    print('Starting server...')
    httpd.serve_forever()

if __name__ == '__main__':
    run()

在这个示例中,我们使用HTTPServer类和SimpleHTTPRequestHandler类创建了一个HTTP服务器,并监听本地的8000端口。然后调用serve_forever()方法启动服务器。

运行这段代码后,你会看到输出Starting server...表示服务器已经启动。

3. 文件上传

接下来,我们将实现文件的上传功能。在HTTP请求中,文件的上传通常是使用POST方法,并将文件数据放在请求体中。在SimpleHTTPRequestHandler类中,我们可以重写do_POST()方法来处理文件的上传。

下面是一个简单的示例代码:

from http.server import HTTPServer, SimpleHTTPRequestHandler

class MyHTTPRequestHandler(SimpleHTTPRequestHandler):
    def do_POST(self):
        content_length = int(self.headers['Content-Length'])
        file_data = self.rfile.read(content_length)
        with open('uploaded_file', 'wb') as f:
            f.write(file_data)
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()
        self.wfile.write(b'File uploaded successfully')

def run(server_class=HTTPServer, handler_class=MyHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    print('Starting server...')
    httpd.serve_forever()

if __name__ == '__main__':
    run()

在这个示例中,我们创建了一个自定义的MyHTTPRequestHandler类,继承自SimpleHTTPRequestHandler类,并重写了do_POST()方法。在do_POST()方法中,我们首先获取请求体的长度,然后读取请求体中的文件数据,并将文件数据写入到名为uploaded_file的文件中。最后,我们返回一个HTTP 200响应,并在响应体中返回一个消息表示文件上传成功。

现在,我们重新运行服务器,并使用浏览器或其他工具发送一个POST请求,将一个文件上传到服务器。上传完成后,你会在服务器的根目录下看到一个名为uploaded_file的文件,表示文件上传成功。

4. 文件下载

除了文件上传,我们还可以实现文件的下载功能。在SimpleHTTPRequestHandler类中,我们可以重写do_GET()方法来处理文件的下载。

下面是一个简单的示例代码:

from http.server import HTTPServer, SimpleHTTPRequestHandler

class MyHTTPRequestHandler(SimpleHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/download':
            file_path = 'file_to_download'
            with open(file_path, 'rb') as f:
                file_data = f.read()
            self.send_response(200)
            self.send_header('Content-type', 'application/octet-stream')
            self.send_header('Content-Disposition', 'attachment; filename="downloaded_file"')
            self.end_headers()
            self.wfile.write(file_data)
        else:
            super().do_GET()

def run(server_class=HTTPServer, handler_class=MyHTTPRequestHandler):
    server_address = ('', 8000)
    httpd = server_class(server_address, handler_class)
    print('Starting server...')
    httpd.serve_forever()

if __name__ == '__main__':
    run()

在这个示例中,我们仍然使用自定义的MyHTTPRequestHandler类,继承自SimpleHTTPRequestHandler类,并重写了do_GET()方法。在do_GET()方法中,我们判断URL路径是否为/download,如果是,则读取名为file_to_download的文件,并将文件数据作为响应体返回给客户端。我们还设置了Content-Disposition头部,告诉客户端将响应体保存为一个附件,并指定附件的文件名为`download