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对这种请求需要额外定义正则解析规则
代码
- 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来实现,留给下次实现。

浙公网安备 33010602011771号