-
Notifications
You must be signed in to change notification settings - Fork 19
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
handle blobs as fields #53
Conversation
It is the problem is
I would say it is better to make those decision customizable by the consumer. I am happy if both option exist. |
According to the spec: https://datatracker.ietf.org/doc/html/rfc7578#section-4.4
So it seams, that we must handle all content types which are not text/plain as files?! |
Thanks for your research. It's given me more understanding of the matter. If I understand it correctly the spec doesn't allow separating between files and fields - it's all just parts and everything else is up to the developer to decide. So I think:
Therefore I propose the following:
That's implemented like this:
A rough idea:
That's a bit like my workaround from the original issue fastify/fastify-multipart#292 (comment) Or it might be done even more high-level (kind of a webpack loader chain (but run from left to right)).
I think that this would be a huge paradigm shift for this package. |
@cyantree See how busboy is currently used: https://github.com/fastify/fastify-multipart/blob/master/index.js From my understanding, it is created once per request and then discarded. Multer does same thing: https://github.com/expressjs/multer/blob/master/lib/make-middleware.js So I think that having a config option on Busboy instance, which would be responsible for deciding what is field and what is file is a valid approach. It should fall upon higher-level library (such as multer or fastify-multipart) to pass correct configuration per-route. |
Actually if no mimetype is set it should be text/plain. https://datatracker.ietf.org/doc/html/rfc7578#section-4.6 How about a simple regex or function for content type? That is imho closes to the rfc |
@kibertoad You're absolutely right, sorry for mixing up these two packages. :) |
@Uzlopak What if I send a |
@Uzlopak
What I take from this:
|
Then it is actually non conform to the spec imho. Ok, different approach: We supply per config a function which gets the values of content type, fieldname and filename. Depending on this everybody can determine if it is a file or a field. In higher levels like fastify you have already schemas. So you could reuse them to configure busboy accordingly |
Yes, that would be fine for me. And when not supplying the function everything gets handled as a file. Btw: Maybe let's check how other languages do it. I know that PHP also handles files seperately. So they must also use some aspect to mark something as a file, presumable Content-Type and/or filename. |
Why should everything be by default a file? I kind of prefer the other way round |
I've made some tests with PHP:
all these three result in file uploads. So I couldn't manage adding a blob as a field. |
I think this is how busboy used to work, and what users are going to expect. Experiment done by @cyantree seems to confirm that this is actually a norm. |
Because without any configuration every field would be loaded into memory which could easily lead to memory and performance issues. The whole thing is quite confusing and I'm asking myself if this gets out of hand. So maybe let's take a step back and start over: Finding a sensible default for separating fields from files should be managable and maybe the status quo (before our PRs), already is it. If other languages have a solid way in handling parts, why should this library need some customization options for this? So maybe the current version of |
Does busboy currently expose enough configuration for that to be feasible, though? |
I pushed my proposal. You could supply a isPartAFile as option to busboy. I chose the old behaviour of busboy as fallback if no isPartAFile is supplied as option. Now everybody can write his own function based on fieldName, contentType and fileName if it is a file or a field. |
Yes, I think so.
They contain pretty much everything.
|
Thanks. Yes, that should do the trick, if exposed by |
@cyantree @kibertoad If you agree with me, I would add the necessary changes to typings and documentation. Maybe isPartAFile is not the best name? but it is quite descriptive :) |
@Uzlopak Yes, I think this is the exactly right solution. |
added documentation. anything missing? |
LGTM. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My comments don't affect the overall functionality but only code quality and code coverage.
Done |
Thanks @Uzlopak and @kibertoad for your work and time. 👍 |
Thank you for for bearing with us through all of this :D. |
It was quite a ride and it was good that we worked together to get the best solution possible :) I really love this hands-on mentality |
@Uzlopak I'll work on benchmarks now. Then we can hopefully land all outstanding PRs and publish 1.0.0 :) |
I think this handles the issue with blob uploads correctly:
It doesnt matter we have set a filename or not. We just check if the content is an octet stream. If so we treat it as a file. If not, we treat it as a field.
Also according to the Spec, a filename is not mandatory.
https://datatracker.ietf.org/doc/html/rfc7578#section-4.2
So the check if filename was not undefined was already non spec conform.
You could also create a Blob with mimetype
application/octet-stream
and upload it, and because we would maybe check for filename,e.g. 'blob' we would not handle the blob correctly. Blob only means, that we have the data in-memory of the browser. For the server it should be actually not be important if an upload was made with a blob or not. It should only look if it is octet-stream or not.Checklist
npm run test
andnpm run benchmark
and the Code of conduct