How to handle multipart/form-data upload in rocket (rust)?

Viewed 23

I'm trying to handle POST requests on my webserver for file uploads, but i haven't found good documentation or examples on how to do it.

Here is the POST function i came up with after a long time:

#[post("/upload",data="<file>")]
fn upload_handler(file: Data) -> Redirect {
    let mut buffer = Vec::new();
    file.stream_to(&mut buffer).unwrap();
    let split_pos = buffer.windows(4).position(|pos|pos == b"\r\n\r\n").unwrap();
    let split_end = buffer.windows(8).position(|pos|pos == b"\r\n------").unwrap();
    let headers = String::from_utf8_lossy(&buffer[0..split_pos]);
    let content = &buffer[split_pos+4..split_end];
    println!("{}",&headers);
    let re = Regex::new("filename=\"(?P<filename>.*)\"").unwrap();
    let captures = re.captures(&headers).unwrap();
    let filename = &captures["filename"].to_owned();
    let mut local_file = File::create(filename).unwrap();
    local_file.write(content).unwrap();
    Redirect::to("/")
}

It kinda works but has a lot of flaws like:

  • I can't limit the file upload size.
  • I don't know the size of the file being uploaded.
  • I had to manually regex the filename (which i don't think is a thing you have to do when using a framework).
  • I can't see the entire request header.

When spliting the headers from the content this is all i got:

Content-Disposition: form-data; name="file"; filename="image.jpg"
Content-Type: image/jpeg

Here's a simple working code i had on a python flask server that did the job:

@app.route("/upload",methods=["POST"])
def upload():
    if int(request.headers["Content-Length"]) > app.config["MAX_CONTENT_LENGTH"]:
        abort(413)
    f = request.files["file"]
    filename = secure_filename(f.filename)
    if filename.endswith(ALLOWED_EXTENSIONS):
        f.save("src/"+filename)
        return render_template("upload.html",file=filename),{"Refresh": "2; url=/"}
    else:
        return render_template("denied.html")

If anyone knows a better/right way of doing it please tell me.

0 Answers
Related