-
Notifications
You must be signed in to change notification settings - Fork 0
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
Support multipart/form-data #36
Comments
My initial foray into creating a helper function with |
Makes sense. To get access to a If this is not sufficient, and you need access to something that's more stream-like, let me know. There's probably something we can do about this, although it might require some changes in core. I'm going to need this very feature next week, so if you're hitting a wall this will come soon. |
Oh that's fantastic. Perfect timing I guess! I can definitely work on other things in the meantime. |
@NetOperatorWibby Looking into this a bit. I first thought I would just add something to this package and just put everything in However, the implication kind of is that this is all going to be stored in memory. That might be ok for our cases (I don't think we'll exceed a few megabytes) but it might not be something you'd want to do, and maybe not a pattern we'd want to encourage. So I'm thinking now to just suggest people use this package: https://www.npmjs.com/package/busboy Which really just means right now you need some way to get access to the underlying stream. So, I'll make that my focus and not add something by default to For our usecase we'll also use this stream and busbuy to extract the attachments. |
Actually, we have this already:
So I think this should work:
|
I'll give it a try! |
Alright, here's the relevant code I have in my copy of curveball's bodyparser:
function parse(ctx: Context): Promise<void> {
if (ctx.request.is("multipart/form-data"))
return parseForm(ctx);
if (ctx.request.is("json"))
return parseJson(ctx);
if (ctx.request.is("x-www-form-urlencoded"))
return parseUrlEncoded(ctx);
if (ctx.request.type.startsWith("text/"))
return parseText(ctx);
return Promise.resolve();
}
const parseFormData = (event: any) => {
return new Promise((resolve, reject) => {
const busboy = new Busboy({
// headers: {
// ...event.headers,
// "content-type":
// event.headers["Content-Type"] || event.headers["content-type"]
// }
headers: event.headers.getAll()
});
const result = {
files: []
};
busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
console.log(fieldname, file, filename, encoding, mimetype);
file.on("data", data => {
result.files.push({
// @ts-ignore
contentType: mimetype,
// @ts-ignore
file: data,
// @ts-ignore
fileName: filename
});
});
});
busboy.on("field", (fieldname, value) => {
try {
// @ts-ignore
result[fieldname] = JSON.parse(value);
} catch(err) {
// @ts-ignore
result[fieldname] = value;
}
});
// @ts-ignore
busboy.on("error", error => reject(`Parse error: ${error}`));
busboy.on("finish", () => {
event.body = result;
resolve(event);
});
// console.log("+++");
// console.log(event);
busboy.write(event.body, event.isBase64Encoded ? "base64" : "binary");
busboy.end();
});
};
async function parseForm(ctx: Context) {
if (!String(ctx.request.headers.getAll()["content-type"]).includes("boundary"))
return; // This is not a valid multipart request
ctx.request.body = await parseFormData(ctx.request);
} The data I'm sending to my API looks like this: There's a good chance I'm doing something wrong because I'm not seeing busboy write anything. My original code basically copied what's in their README but I deleted that. |
So I probably wouldn't do this as a middleware, but rather use busbuy directly in the controller where you need it. In the middleware kind of implies that you parse the whole thing, and then place the result in However, if you are going down this route. I'm not seeing where you call |
You're not missing anything, I just don't know what I'm doing. I've never had to deal with file uploads in any of my projects until now so I'm just slapping things together until something works. |
I think this is what's preventing my API from seeing my uploads.
The text was updated successfully, but these errors were encountered: