Issue handling multiple types in one header
tunnckoCore opened this issue · comments
stated at helapkg/hela#22
Problem is that some API service - Alipay, sending request content-type header like that
application/x-www-form-urlencoded; text/html; charset=utf-8
I dont know why they send it like that, but there's no logic for me. We've tried in different ways, but didn't work.
is(req, ['x-www-form-urlencoded', 'html'])
is(req, ['application/x-www-form-urlencoded', 'text/html'])
It's not koa-better-body
implementation issue, cuz it support extendTypes
option that pass things to koa this.is
/this.request.is
I think it would not be correct to support (if cant currently) thing like that and maybe we should pass the problem to Alipay tracker to fix their header?
Right, this module explicitly rejects that header value on purpose. The reason is that we detect if the type of a request is something; if the value in the content-type
header is not a valid type, we're no longer comparing types, but rather random strings. In order to do intelligent type comparisons, like ignoring the parameters, we have to at least know it's actually a content-type
header value.
There are really only two good courses of action here:
- Get them to fix their header.
- Re-write the header value before calling this module, either by altering the
content-type
header or callingis.is
with the altered type (probably after callingis.hasBody
).
You can also find some previous discussion on this exact Alipay issue in #12
It's also amusing to search Google for the string "application/x-www-form-urlencoded; text/html; charset=utf-8"
, as you see people using all kind of different language like Ruby, Java, C#, and more also having issues with Alipay's dumb header.
And for reference, you can find the exact format the Content-Type
's value needs to be in at http://tools.ietf.org/html/rfc7231#section-3.1.1.5 . The issue with that header is that the second semicolon is an illegal character and no longer matches the RFC's ABNF expression for the Content-Type
header.
Hm, okey. Just didn't have time to look at google.
So Alipay issue and we won't do anything, and with reason.
So @daiwhea, that's the way currently.
app.use(function * (next) {
if (this.request.header['content-type'] === 'application/x-www-form-urlencoded; text/html; charset=utf-8') {
this.request.header['content-type'] = 'application/x-www-form-urlencoded'
// or
// this.request.header['content-type'] = 'application/x-www-form-urlencoded; charset=utf-8'
}
yield next
})
I'll think to do something on koa-better-body
.
One option with koa-better-body
is you could perhaps even take a function
as the type to match, which is what I allow with the body-parser
module (https://github.com/expressjs/body-parser#type).
If a function, the type option is called as fn(req) and the request is parsed if it returns a truthy value.