-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TempFile persist_to fails with I/O Error 18 (Invalid cross-device link) #1600
Comments
Ouch. Yes, it looks like the underlying code ( https://docs.rs/tempfile/3.2.0/src/tempfile/file/imp/unix.rs.html#112 ) uses either |
I'd conjecture that the underlying reason for this issue is the desire/need for renaming/relinking to be atomic. I'm not sure if we're liable to find a solution for this issue with the same security properties. One "workaround" is to set your temporary directory to be in the other mount point: [default]
temp_dir = "/home/tmp" |
Perhaps we should provide a |
Allows moving across mount points rwf2/Rocket#1600
did you solved this issue? @thacoon |
@jiangxiaoqiang I just checked for you. I was using it in a small side project 2 years ago. My API looks like this where I am using #[post("/upload", data = "<form>")]
pub async fn upload(
mut form: Form<FileUploadForm<'_>>,
config: &State<config::Config>,
_key: security::ApiKey,
) -> JsonValue {
let mime_type;
match extract_file_type(form.file.path()) {
Some(m) => mime_type = m,
None => return error_as_json(INVALID_FILE_TYPE),
}
if form
.allowed_file_types
.contains(&mime_type.to_string())
.not()
{
return error_as_json(FILE_TYPE_NOT_ALLOWED);
}
let filename = format!("{}.{}", form.id.to_string(), mime_type.extension().unwrap());
let path = Path::new(&config.media_root).join(filename.clone());
if form.file.persist_to(&path).await.is_err() {
return error_as_json(FILE_COULD_NOT_BE_PERSISTED);
}
json!({"status": "ok", "resource": filename})
} And in my [default]
api_key = "secret-api-key"
temp_dir = "./media/tmp"
media_root = "./media"
[debug]
api_key = "secret-api-key"
temp_dir = "./media/tmp"
media_root = "./media"
[release]
address = "0.0.0.0"
port = 8000
api_key = "secret-api-key"
temp_dir = "./media/tmp"
media_root = "./media"
[global.limits]
data-form = "5MiB"
file = "5MiB" So, I think I am using the workaround mentioned by Sergio, that my source and destination are under the same mount. |
I have the following code where I have a form with a
TempFile
which I want to save.However, the code fails with the following error message:
I/O Error: Os { code: 18, kind: Other, message: "Invalid cross-device link" }
. I think, this is because my source (/tmp/
) and my destination (/home/username/Example
) have different mounts. If I change my source to the same mount, viaexport TMPDIR=/home/username/Example/tmp/
it works.Does the code behaves as intended? Because I would argue that it should not fail because of the tmp dir being on a different mount than my persistent destination.
I am using the
0.5.0-dev
version.The text was updated successfully, but these errors were encountered: