Writing raw bytes to an actix response

Hello! I'm writing a new project using actix and I have an upload/download of binary files (encrypted sqlite databases). They are stored at the moment in a postgres database using the array binary column type in postgres.

For the upload I don't have issue in storing it and it is correctly saved but when I implemented the download seems that the output is different from what I expect. What I did was

    let data_bytes;
    match sqlx::query!(
        r#"SELECT data FROM core_saveddata where user_id=$1
        ORDER BY last_modify_ts DESC LIMIT 1;
        "#,
        user_id,
    )
    .fetch_one(pool.get_ref())
    .await
    {
        Ok(row) => data_bytes = row.data.clone(),
        Err(e) => {
            log::error!("Failed to execute query: {:?}", e);
            return HttpResponse::NotFound().body("Couldn't find record in database");
        }
    }

    HttpResponse::Ok()
    .body(BoxBody::new(data_bytes))

but the response body seems to be bigger than what it should and I'm not sure what is the proper way of doing it nor I have found docs explaining it. Could anyone help?

To me this makes it sound like you don't know whether your program behaves correctly or not. It sounds like you only assume it is not working right. I think an easy way to find out if your download works or not would be by downloading an sqlite file and making sure is is not corrupted. Did you do that and it failed?

1 Like

As @jofas said, you should check other parts of your system first.

Firstly, you should confirm that the data in your data column is the length you expect. You can run something like this in your Postgres command-line:

SELECT user_id,last_modify_ts,LENGTH(data) AS filesize FROM core_saveddata;

Pick a file and make sure that the byte count stored in the database is exactly the same as that of the original file.

If there's no problem, try downloading a file in your web browser and check the downloaded file's length is equal to the filesize from the database.

I don't see anything in your code that looks wrong to me, but you can skip a clone() by returning an HttpResponse directly in your Ok(row) match arm:

Ok(row) => {
    return HttpResponse::Ok().body(BoxBody::new(row.data));
}

Thanks you both @hax10 @jofas It was indeed a failure the function doing the check. I'm porting a python code and some details were different. Due to the setup it was hard to check with the actual production code.

Also thanks @hax10 for the tip to about the clone!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.