Invalid characters in fileName, API response after sending Zip buffer

I'm trying to send the buffer of a zipped dir to an API that expects that, but I'm receiving a kind of weird response:

{
    "message": "invalid characters in fileName: store\\\\blocks/\\nError: invalid characters in fileName: store\\\\blocks/\\n    at /usr/local/data/service/node_modules/yauzl/index.js:352:83\\n    at /usr/local/data/service/node_modules/yauzl/index.js:473:5\\n    at /usr/local/data/service/node_modules/fd-slicer/index.js:32:7\\n    at FSReqCallback.wrapper [as oncomplete] (fs.js:520:5)"
}

I'm imagining now it's something related to the final file name, but being a buffer I have no idea if it affects or even exists. But if it has, I would love to know how to change it, or if someone has already passed for something like this, how to solve it!

Some code here:

Zip + send

// ? Zip the file, using the zip utils.
    let file: Vec<u8> = gzip::file::zip(path);

    // ? Send the file to the builder.
    match builder::link(file, token) {
        Ok(res) => {
            println!("{:?}", res.text());
        }
        Err(e) => {
            println!("{:?}", e);
        }
    }

API

    let client = reqwest::blocking::Client::new(); // Create a new HTTP blocking client.
    return client // Setup the request.
        .post(Routes::assemble(Link)) // Define the endpoint.
        .header(ACCEPT, "application/json, text/plain, */*") // Define the headers.
        .header(ACCEPT_ENCODING, "gzip") // More headers.
        .header(CONTENT_LENGTH, file.len()) // And more headers.
        .header(CONTENT_TYPE, "application/octet-stream") // Guess what.
        .header(AUTHORIZATION, format!("Bearer {}", token)) // One more.
        .body(file) // And finally the body.
        .send(); // Just wrap it up and send it.

Resumed zipping function

    let mut buf = Vec::new(); // Responsible for handling the buffer and the bytes in it.
    let mut cursor = Cursor::new(&mut buf); // Responsible for the cursor.
    let mut zip = ZipWriter::new(&mut cursor); // Responsible for the zip writer.
    let options = FileOptions::default()
        .compression_method(zip::CompressionMethod::Stored)
        .unix_permissions(0o755);
    let mut buffer = Vec::new();
    for entry in it {
        let path = entry.path(); // Get the file path
        if path.is_file() {
            zip.start_file(name.to_str().unwrap(), options).unwrap();
            let mut f = File::open(path).unwrap();
            f.read_to_end(&mut buffer).unwrap();
            zip.write_all(&*buffer).unwrap();
            buffer.clear();
        } else if name.as_os_str().len() != 0 {
            zip.add_directory(name.to_str().unwrap(), options).unwrap();
        }
    }

    zip.finish().unwrap(); // Close the file in the zip archive
    drop(zip);

    return buf;

According to the error message, your filename seems to be store\\blocks. Are you sure that is the filename you want?

1 Like

Definitely not in this case. The file name really doesn't matter, but it has at least to be valid.

How I'm creating this file from a buffer. I'm really not sure how to change or set a specific name for this zip file.

I took a look at this lib that is giving this error, it's a JS library used in this project, and apparently it only blocked if it has \ which mine has. :confused:

Então não use o nome do arquivo desse formulário. (Não sei português, estou usando o Google tradutor).
[So don't use the filename of that form. (I don't know Portuguese, I used Google translate)]

What library are you using to perform the zip?

1 Like

Where are you getting the name variable from in your last snippet?

2 Likes

Sorry for the confusion, I already edited the previous answer, sometimes using two languages ​​in everyday life ends up getting confusing haha.

Yep, I thought about that, but the way I'm creating this file from a buffer I'm not setting a name anywhere in the function.

And the library is the most common I think, zip

I meant the one you use to gzip.

But you are passing the path to the gzip function.

Oh, really. Sorry, I probably messed up creating this reduced snippet, but it comes from this one:

let name = path.strip_prefix(prefix).unwrap();

Where path is a Path of the actual file we're iterating, and prefix is the root path of the folder we're iterating over.

Oh, ok. That's a custom function to create the zip and return the final bytes, then I send it via an HTTP Post request. Actually its the last snippet.

First, I'd like to thank the community for the help overall, I found one issue related to that error message in the lib, as we theorized its really the \\, and apparently because of this being a buffer the final name is not a thing, he's related to the file content. Heres the issue.

The final snippet to prevent this error, thats definetly not the best way, but seems like the unique for now:

// ? Thats definitely not the beauty way to do this, but it works.
// ! The zip writer in windows devices, uses \\ to separate directories, but when handling it on linux, it uses /, this creates a problem, here we replace it.
let mut p = str::replace(&name.to_str().unwrap(), "\\", "/"); // Replace the backslashes with slashes.
if p.starts_with('/') {
    p.remove(0);
} // ? Remove the first '/'
```