flask写文件服务器

目标

用python web框架flask写一个文件服务器,可以用curl上传和下载文件

原理

#上传文件命令
curl -T /tmp/test  http://ip:port/upload
#发送给服务器的请求是PUT  /upload/test

curl -T /tmp/test  http://ip:port/upload/dir1/
#发送给服务器的请求是PUT  /upload/dir1/test,flask对这种请求需要额外定义正则解析规则

代码

  1. RegexConverter.py 因为flask默认的正则不支持匹配/,为了用正则匹配路径,从而支持将文件上传到指定路径下需要自定义一个正则匹配规则
from werkzeug.routing import BaseConverter

class RegexConverter(BaseConverter):
    def __init__(self, url_map, *args):
        super(RegexConverter, self).__init__(url_map)
        self.url = url_map
        self.regex = args[0]

    def to_python(self,value):
        return value

2.app.py 程序的主体:

from flask import Flask,request,send_file
from RegexConverter import RegexConverter
import os

#最大文件路径长度
MaxPathLen=1024

#上传文件存放路径
datadir='/data/upload/'

app = Flask(__name__)
app.url_map.converters['re'] = RegexConverter

#检查路径是否存在..,存在则可能发送路径向上层跳转,要禁止这种不安全行为
#检查服务器上是否存在同名文件,存在就报错
#检查文件夹是否存在,不存在就创建文件夹
def checkdestfile(destfile):
    if ".." in destfile or len(destfile)>=MaxPathLen or os.path.exists(destfile):
        return False
    tmploc = destfile.rfind('/')
    destdir =  destfile[0:tmploc]
    if not os.path.exists(destdir):
        os.makedirs(destdir)
    return True

@app.route('/upload/<re(r".*"):filename>',methods=["PUT","GET","HEAD"])
def fileupload(filename):
    destfile=datadir+filename
    print(destfile)
    #文件上传
    if request.method == "PUT":
        if checkdestfile(destfile):
            print(destfile)
            f = open(destfile,'wb+')
            f.write(request.data)
            f.close()
            return "ok\n",200
        else:
            return "fail\n",403
    #文件下载
    elif request.method == "GET" or request.method == "HEAD":
        if os.path.isfile(destfile):
            return send_file(destfile, as_attachment=True)
        else:
            return "fail\n",403
    else:
        return "fail\n",403

文件夹浏览功能

对于文件的浏览,需要使用template来实现,留给下次实现。

posted @ 2024-01-02 20:35  董少奇  阅读(35)  评论(0)    收藏  举报