upload with PUT allows streaming

This commit is contained in:
2023-08-20 10:44:16 +03:00
parent 07aafd746d
commit 654891a61e
6 changed files with 110 additions and 60 deletions

View File

@@ -27,7 +27,7 @@ from utils.files import (
db_maintenance,
)
__VERSION__ = "20230819.0"
__VERSION__ = "20230820.0"
app = Flask(__name__)
app.config.from_object(__name__)
app.config.from_prefixed_env()
@@ -42,7 +42,7 @@ def index():
return "", 200
@app.route("/upload", methods=["POST"])
@app.route("/upload", methods=["PUT","POST"])
def upload():
"""
Upload a file, example CURL:
@@ -58,45 +58,64 @@ def upload():
- Additionally, "Expires-Hours" can be used.
- Max-Dowloads: -1 means no upper limit
IF using GET, you can upload larger files with pipes
cat largefile | \
curl -fL -w "\n" --upload-file - \
-H "Name: my.file.ext" \
-H "Max-Downloads: 4000" \
-H "Expires-Days: 14" \
-H "Secret: dff789f0bbe8183d32542" \
"$FLASK_PUBLIC_URL"/upload
Returns the file download URL
"""
name = request.headers.get("Name", None)
if name is None:
return "Name required", 500
safe_filename = secure_filename(name)
secret = request.headers.get("Secret", "")
if secret != app.config["ACCESS_TOKEN"]:
return "Error", 401
max_dl = request.headers.get("Max-Downloads", app.config["DEFAULT_MAX_DL"])
expires = int(time.time()) + int(app.config["DEFAULT_EXPIRE"])
if "Expires-days" in request.headers:
expires = int(time.time()) + 24 * 3600 * int(
request.headers.get("Expires-days")
)
if "Expires-hours" in request.headers:
expires = int(time.time()) + 3600 * int(
request.headers.get("Expires-hours")
)
while True:
token = random_token()
folder = os.path.join(app.config["DATAFOLDER"], token)
if not os.path.exists(folder):
break
filename = file_full_path(token, safe_filename)
os.mkdir(folder)
if request.method == "POST":
file = request.files.get("file")
name = request.headers.get("Name", None)
if name is None:
return "Name required", 500
secret = request.headers.get("Secret", "")
if secret != app.config["ACCESS_TOKEN"]:
return "Error", 401
max_dl = request.headers.get("Max-Downloads", app.config["DEFAULT_MAX_DL"])
expires = int(time.time()) + int(app.config["DEFAULT_EXPIRE"])
if "Expires-days" in request.headers:
expires = int(time.time()) + 24 * 3600 * int(
request.headers.get("Expires-days")
)
if "Expires-hours" in request.headers:
expires = int(time.time()) + 3600 * int(
request.headers.get("Expires-hours")
)
if file:
safe_filename = secure_filename(name)
while True:
token = random_token()
folder = os.path.join(app.config["DATAFOLDER"], token)
if not os.path.exists(folder):
break
os.mkdir(folder)
filename = file_full_path(token, safe_filename)
file.save(filename)
db_store_file(token, safe_filename, expires, max_dl)
download_url = file_full_url(token, safe_filename)
return "File uploaded\n%s\n" % (download_url,), 200
else:
return "Use the 'file' variable to upload\n", 400
if request.method == "PUT":
chunk_size = 1024 * 1024 * 64 # 64Mb
with open(filename, 'wb') as f:
while True:
chunk = request.stream.read(chunk_size)
if not chunk:
break
f.write(chunk)
db_store_file(token, safe_filename, expires, max_dl)
download_url = file_full_url(token, safe_filename)
return "File uploaded\n%s\n" % (download_url,), 200
@app.route("/details/<token>/<name>", methods=["GET"])
def details(token, name):