Skip to content
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

ContentType: text/plain not showing in fields #875

Open
neronim1141 opened this issue Aug 1, 2022 · 16 comments
Open

ContentType: text/plain not showing in fields #875

neronim1141 opened this issue Aug 1, 2022 · 16 comments
Labels

Comments

@neronim1141
Copy link

Support plan

  • Which support plan is this issue covered by? Community
  • Currently blocking your project/work? yes
  • Affecting a production system? yes

Context

  • Node.js version: 16.13.1
  • Release Line of Formidable (Legacy, Current, Next): Next
  • Formidable exact version: 3.2.4
  • Environment (node, browser, native, OS): node
  • Used with (popular names of modules): nextjs, next-connect

What are you trying to achieve or the steps to reproduce?

Im trying to make custom server functionality on nextjs api route,
where i get some request data from game as "multipart/form-data;"
but some of the data has "text/plain" content type.

router.post(async (req, res) => {

  const form = new IncomingForm();
  form.parse(req, (err, fields, files) => {
    console.log(fields);
    console.log(files);
  });

  res.end();
});

export const config = {
  api: {
    bodyParser: false,
  },
};

What was the result you got?

Only the files variable gets populated.
As i needed to disable parser for nextjs
i cant really use req.body.
looping for 'text/plain' mimetype in files and parsing them manualy is not desired either

What result did you expect?

'text/plain' content type parsed into fields variable

@neronim1141 neronim1141 added the bug label Aug 1, 2022
@GrosSacASac
Copy link
Contributor

If I understand correctly you want to access files sent as text/plain as if it was another field ?

@GrosSacASac
Copy link
Contributor

This line in the code separates fields from files:
if (!part.mimetype) {

So if you don't have a mimetype it will appear as a field

@neronim1141
Copy link
Author

Yes, i managed to do it in an ugly way around

for (let [fileField, filesArray] of Object.entries(files)) {
          const file = (filesArray as File[])[0];
          switch (fileField) {
            case "id":
              id = await fileToString(file.filepath);
              fs.rm(file.filepath);
              break;
            case "extraData":
              extraData = JSON.parse(await fileToString(file.filepath));
              fs.rm(file.filepath);
              break;
            default:
              tile = file;
              break;
          }
        }

but i think as text/plain usually contain string,
if they arent too big maybe they should convert to fileds also?

for disclaimer i cant really change how i receive data, and 'id','extradata' are bassically oneliners
i remember that i used that API with multer some time ago and it was quite simple

@GrosSacASac
Copy link
Contributor

Do you suggest to change formidable ?

@ajmeese7
Copy link

ajmeese7 commented Aug 3, 2022

@GrosSacASac I would like to see this change as well, I missed this issue but I commented about running into the same problem in #495

@GrosSacASac
Copy link
Contributor

What exactly should change ?

@neronim1141
Copy link
Author

if mimetype is text/plain it should be decoded into fields instead of file with provided charset, unless explicity specified,
or allow us to exclude fields from converting to files

@tunnckoCore
Copy link
Member

not automatically, and not default behavior

or allow us to exclude fields from converting to files

yep, through option.

@prigaux
Copy link

prigaux commented Nov 28, 2022

Formidable v1 used to put "a" in fields for:

Invoke-RestMethod -Uri '...' -Method Post -Form  @{ a = 'A'; file = Get-Item -Path '.\foo.txt' }

which sends:

Content-Type: text/plain; charset=utf-8
Content-Disposition: form-data; name="a"

Upgrading to Formidable v2 broke my app.

NB: curl does not send "Content-Type" for non-files.

@prigaux
Copy link

prigaux commented Nov 28, 2022

Workaround tested on v2:

form.onPart = function (part) {
    if (part.mimetype && !part.headers['content-disposition']?.match(/filename="/)) {
        // we want it to be a "field" (cf https://github.com/node-formidable/formidable/issues/875 )
        delete part.mimetype
    }
    form._handlePart(part);
}

@okcompute
Copy link

okcompute commented Feb 25, 2023

I have the same issue. My user is calling my API with a C# client. Their multipart/form implemtation always adds the text/plain mimetype. To solve the issue, I have to apply the solution from @prigaux above.

I think this should be fixed upstream in this library, no?

@tunnckoCore
Copy link
Member

That's why we even expose internals and allow overriding, so it can be extended. ;)

Converting text/plain to fields by passing some option, could be a good feature too.

Formidable v1 used to put "a" in fields for:

Really strange.. :D Never noticed that, or I forgot it.
That's weird. And what happens when multiple? Multiple as or what? haha.

@CollapsedMetal
Copy link

CollapsedMetal commented Apr 19, 2023

I can confirm that there's no way to succesfully get fields data from submited forms using HttpClient on C#
Had no previous issues using v1
@prigaux workaround works great!

@kkirby
Copy link

kkirby commented Apr 21, 2023

So, the code used to look at the existence of a filename and would consider it a field if a file name did not exist.

I've been tracing back the code and it used to be what I would consider correct:

if (part.filename === undefined) {

But then was changed to look at mime type here: 621e72a

I'm not really sure what the change fixed, but it's not correct. A field is a file if it contains a filename. Otherwise, it's a field. Right??

@pankaj89
Copy link

pankaj89 commented Dec 28, 2023

As of now only workaround by @prigaux is working, Is there any fix in library? I am using Retrofit as client in Android app.

@msojocs
Copy link

msojocs commented Apr 3, 2024

I am using this code:

const form = formidable({
        uploadDir: storagePath,
        createDirsFromUploads: true,
        keepExtensions: true,
    });
    form.onPart =  function (part) {
        log.info('part:', part)
        if (part.mimetype && !(part as any).headers['content-disposition']?.match(/filename="/)) {
            // we want it to be a "field" (cf https://github.com/node-formidable/formidable/issues/875 )
            part.mimetype = null
        }
        form._handlePart(part);
    }

After add 'onPart' function, the uploaded file can not open any more;
if I comment them, the uploaded file can open again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants