1

I'm adding photo uploading feature to my chat. I have POST parser from this answer, and little code that saves image to uploads directory.

var ext = exports.getFileExt(Object.keys(partsByName)[0]);
var time = (new Date()).getTime();
fs.writeFile("./img/user/upload_" + time + "." + ext,
    partsByName[Object.keys(partsByName)[0]], "binary", function (err) {
        if (!err) {
            res.writeHead(200, "OK", { "Content-Type": "text/html" });
            res.write(exports.wrapHTML(<title>, <html>, <font params>));
            res.end();
        } else {
            console.error(err);
            res.writeHead(500, "Internal Server Error");
            res.end();
        }
    });

Image saves with expected name, but it doesn't opens and I think there is incorrect encoding.

Source file start looks like this:

яШяа JFIF H H яб"Exif MM *

but newly saved file is different:

ээээ JFIF H H ээ"Exif MM *

I tried writing my own parser before I found that answer, and it has other structure - it extracted boundary with /boundary=(.+)/ regex, then getting file extension from parsed file name, and cutting 2 first lines with array, then joining with "\r\n", and applying substr(boundary.length, data.length - (boundary.length * 2)) (and some other corrections), saving with fs.writeFile, and file again looked incorrectly.

UPD: Now I think that Cyrillic just lost when sending data. In console and browser they look as unknown character (stroked rectangle).

1 Answers1

0

The body parser is probably not correct. Handling multipart/form POST data in a safe way can be rather tricky.

When you want to get a better grasp of how it works it's great to write your own version. As soon as you have a good enough understanding you should switch to battletested code from a library.

About the first bytes, they are sometimes called 'magic bytes', read more about those here: https://en.wikipedia.org/wiki/List_of_file_signatures

These bytes are used by most operating systems to determine the type of file.

EECOLOR
  • 11,184
  • 3
  • 41
  • 75
  • I tried writing my own parser before I found that answer, and it has other structure - extracted boundary with `/boundary=(.+)/` regex, then getting file extension from parsed file name, and cutting 2 first lines with array, then joining with "\r\n", and applying `substr(boundary.length, data.length - (boundary.length * 2))` (and some other corrections), saving with `fs.writeFile`, and file again looked incorrectly. –  Jul 03 '18 at 17:31
  • You should not read the body of the request as a string but as bytes. A file contains bytes that will interpreted differently when you 'convert' it to a string. Just read the bytes and handle them according to the [RFC](https://tools.ietf.org/html/rfc2046). Again - if you want to use this in production, use a library. – EECOLOR Jul 03 '18 at 20:36