I've got a problem where when the user sends image data, it's saved on the server corrupt.
So, I essentially have this setup:
- api
. index.js
- methods
. users.js
(I've cut out files that are unrelated to the problem)
Outside of the API file, there is a server.js
which initaites it whenever api.example.com is visisted. (Basically like a VirtualHost)
That being said. Here is the problem:
./api/index.js
(Points of problem)
// All this essentiall does is get the get the whole payload as a buffer.
req.on("data", function(chunk){
// Potential problem area.
req.api.payload = ((req.api.payload) ? (Buffer.concat([req.api.payload, chunk])) : (chunk));
});
req.on("end", function(){
// Check if we're on api.example.com/users/
if (path[0].match(/^users$/i)) {
methods.users(req, res);
}
});
I think the issue is somewhere when the payload.
But... Just incase, I'll include the ./api/methods/users.js
... (Only including parts where the problem could arise, since it's a big file)
./api/methods/users.js
else if (req.method.match(/^POST$/i)) {
if (!path[2] || path[2].match(/^(?:info|data)$/i)) {
// ... (Everything that was here didn't apply to the image upload)
} else if (path[2].match(/^(?:pic|picture|avatar)$/i)) {
// Url matches api.example.com/users/<user_id>/pic
var __base = "/home/user/web/hosts/resources/static/images/api/users/"; // Upload path
// Another potential spot where the problem could be.
fs.writeFile(__base + path[1] + ".png", req.api.payload, "binary", function(err){
if (err) res.api.end(err);
res.api.end(req.api.payload.slice(0, 40)); // Testing
});
}
}
Note that this is just for testing the uploading, I realize someone could upload other data, but this is local. It's simply for testing the uploaded data, for now.
Another note, any variable that you don't see explicitly defined is not related to the problem, just no that:
path
: Url as array e.g. "/user/xero/info"
-> ["user", "xero", "info"]
req.api
: A object created before hand (in the main server.js
file).One more note, I'm uploading the file via a cURL command:
curl -X POST -d @random.png http://api.poweredrails.org/users/test4/pic
The problem is with your curl
usage, you need to specify --data-binary
instead of just -d
. You should also set a Content-Type
header so that curl will do the right thing:
curl -X POST -H "Content-Type: image/png" --data-binary @random.png http://api.poweredrails.org/users/test4/pic
Another option is to support the use of multipart/form-data in your backend app, especially if want to submit other information with the image. Then your curl usage would look like:
curl -X POST --form "mypicture=@random.png" --form "foo=bar" http://api.poweredrails.org/users/test4/pic