
Good evening, Habrayuzer. I want to share a little experience in limiting the size of a downloadable file. The whole experience was obtained empirically.
What did TK look like:- In the template we create a mold with a field for files.
- On the server, check the file extension and its size.
- If all conditions are met - we load the file and save the link in the database
Everything looks simple, but sadness overtook me when checking the file size. How did I solve this problem? Welcome under habrakat.
Start
At first, everything went just fine - and the template was made, and the server part was loaded, and everything was loading - it was nice to watch. But here I understand that I absolutely do not need that some kindly man began to merge me 4 GB. traffic to the server. We google and find the
official dock in which we see the magic lines:
By default, you can choose the maximum key for the MAX_CONTENT_LENGTH config key:
from flask import Flask, Request app = Flask(__name__) app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
Fine! Add a line to the config, run, and ... And we get an error 413 ... Trouble ... Google, we find
werkzeug.exceptions and
RequestEnityTooLarge . We are trying to start the construction of the form.
try: file = request.files["file"] except RequestEnityTooLarge as e: return "ERROR", 200
but without result - the browser does not want to return something other than an error. Even vaunted
@app.errorhandler(413)
did not help me, output to the console does not count - the client is in the drum.
')
Continuation
I was puzzled for 5 days, until I got to the
FileStorage filling. This class is inherited from
object and has a
read method that reads content into RAM. And this method has an optional
size argument, which sets the maximum size of the read information. From here and dance.
Throw a draft: from flask import Flask, render_template, request MAX_FILE_SIZE = 1024 * 1024 + 1 app = Flask(__name__) @app.route("/", methods=["POST", "GET"]) def index(): args = {"method": "GET"} if request.method == "POST": file = request.files["file"] if bool(file.filename): file_bytes = file.read(MAX_FILE_SIZE) args["file_size_error"] = len(file_bytes) == MAX_FILE_SIZE args["method"] = "POST" return render_template("index.html", args=args) if __name__ == "__main__": app.run(debug=True)
where in the variable
MAX_FILE_SIZE specify the maximum file size + 1 byte for catching the excess. The rest, I think, is not necessary to explain, if that - questions in the comments.
Throw a template: <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Uploads</title> </head> <body> {% if args["method"] == "POST" %} {% if args["file_size_error"] %} <h1> 1.!</h1> {% else %} <h1> .</h1> {% endif %} {% endif %} <form action="/" method="POST" enctype="multipart/form-data"> <input type="file" name="file"> <button type="submit"></button> </form> </body> </html>
We start, we check. When issuing a file larger than 1mb. they will shout at us, shout and curse, and we can rather rub our hands. Everything is working.
Results
What can you say about the results? Perhaps these are crutches. Maybe I'm a kettle, lamer and bottom. But even in the maillist, the developers did not give me a normal solution to this problem.
However, this solution also has a minus, namely the variation of the limit and the amount of RAM.
On this note I want to say goodbye. Thank you for reading, I will be glad to hear all the criticism in the comments. Good luck to all!