tinyhttp/milliparsec

Always get 415 error

clearfram3 opened this issue · 14 comments

I copied the code from this example:
tinyHTTP - database integration

I tried using urlencoded and json together, each by itself, in different orders....nada, always
Status 415 Unsupported Media Type

I know it's not anything else because using body-parser's json middleware works.

Any ideas?

Hey. Did you happen to (not) explicitly supply the Content-Type header on the request? If so, have you try explicitly supplying them?

The simple server:

const app = new App()
app.use(json())
app.post('/', json(), (req, res) => {
  res.json({ body: req.body })
})
app.listen(3000)

The request:

// this works
const response = await fetch('http://localhost:3000/', {
    method: 'post',
    body: JSON.stringify({ hello: 'there' }),
    headers: {
      'content-type': 'application/json'
    }
  })

// this doesn't
const response = await fetch('http://localhost:3000/', {
    method: 'post',
    body: JSON.stringify({ hello: 'there' }),
    headers: {}
  })

that's my bad, I added Content-Type validation but seems like original body parser doesn't care. So I'll make a check if header is present or not.

But imo when u send smth u should specify the Content-Type

interesting

by default content-type is still present and it defaults to plain text... so this isn't a bug?

Ok, so this works

const axios = require('axios').default;
axios.defaults.headers.post['content-type'] = 'application/json';
axios.post('https://massive-mayfly-38.loca.lt/', {foo: "the dog is gonna get u"})

with

app
  .use(cors())
  .use(json())
  .post("/", (req, res) => {
    console.log(req.body.foo);
  })
  .listen(3000, console.log("go rabbit go"));

I was using https://hoppscotch.io/ to send requests and I realized they attach "charset=utf-8"

fetch("https://massive-mayfly-38.loca.lt/", {
  method: "POST",
  body: JSON.stringify({ "foo": "sup bro"}),
  headers: {
    "Content-Type": "application/json; charset=utf-8"
  }
})

so is charset=utf-8 something that needs to be supported? I don't know if the Ky client adds it or if any others do...

Also,

app.use(json())
app.post('/', json(), (req, res) => {
  res.json({ body: req.body })
})

Shouldn't the app.use(json()) work for all routes?
Also lol urlencoded() and json() can be used together right? If I'm sending all my data over POST requests is there any need for urlEncoded? What about images?

Thanks!

@ClearedFram3 oh I didn't include a case with charset
my bad

regarding using them together I'm not that sure, I haven't tried yet. probably a better behavior would be just not parsing a body in case it doesn't match content type instead of finishing a request

about images, if you meant file upload, it's not handled by milliparsec. use multer instead

Do you think that is something worth doing? I haven't seen a whole lot of charsets, but just like hopscotch, it could be added in automatically and then drop errors for seemingly no apparent reason.

Do you mean doing something like

app.post('/thisOneNeedsJSON', json(), routeHandler)
//or
app.post("/someRoute", (req,res, next) => {
  if(req.headers['content-type'] === 'application/json') next()
  else throw Error //idk how to handle errors actually hahah
}, json(), handleRouteWithJson)

suggestions are very welcome :)

I have been seeing (didn't actually read it) a lot of stuff about eliminating "if" checks. So maybe cutting out the content-type check and parsing things might be better and more performant. If someone is using the json middleware there are probably using where they are getting json anyway

@ClearedFram3 i've released 2.1

pls check if it works now

This

const axios = require('axios').default;
axios.defaults.headers.post['content-type'] = 'application/json';
axios.post('https://massive-mayfly-38.loca.lt/', {foo: "the dog is gonna get u"})

works whether you put a semicolon or comma between "application/json" and "charset=utf-8" with and without a space after the delimiter. You can even only put a space between them or NO space at all and it still works.

Hopscotch only works if it's running through their proxy. I'm not sure if their credentials: "same-origin" on request effect anything.

I'm having the same error using the axios delete method. And the same happens using Insomnia.

released 2.2 a few minutes ago, thanks to @aldy505

@FranciscoMendes10866, @ClearedFram3 could u check pls?

@talentlessguy The latest version on npm is still 2.1.1.

@FranciscoMendes10866 sorry for delays, it's published now

@talentlessguy It's perfect!