Skip to content

Commit

Permalink
feat: support xml (#131)
Browse files Browse the repository at this point in the history
  • Loading branch information
atian25 committed Mar 24, 2020
1 parent 6fd7e9c commit 705673d
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 4 deletions.
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -48,11 +48,12 @@ app.use(async ctx => {

## Options

* **enableTypes**: parser will only parse when request type hits enableTypes, default is `['json', 'form']`.
* **enableTypes**: parser will only parse when request type hits enableTypes, support `json/form/text/xml`, default is `['json', 'form']`.
* **encoding**: requested encoding. Default is `utf-8` by `co-body`.
* **formLimit**: limit of the `urlencoded` body. If the body ends up being larger than this limit, a 413 error code is returned. Default is `56kb`.
* **jsonLimit**: limit of the `json` body. Default is `1mb`.
* **textLimit**: limit of the `text` body. Default is `1mb`.
* **xmlLimit**: limit of the `xml` body. Default is `1mb`.
* **strict**: when set to true, JSON parser will only accept arrays and objects. Default is `true`. See [strict mode](https://github.com/cojs/co-body#options) in `co-body`. In strict mode, `ctx.request.body` will always be an object(or array), this avoid lots of type judging. But text body will always return string type.
* **detectJSON**: custom json request detect function. Default is `null`.

Expand Down
12 changes: 12 additions & 0 deletions index.js
Expand Up @@ -34,6 +34,7 @@ module.exports = function (opts) {
var enableForm = checkEnable(enableTypes, 'form');
var enableJson = checkEnable(enableTypes, 'json');
var enableText = checkEnable(enableTypes, 'text');
var enableXml = checkEnable(enableTypes, 'xml');

opts.detectJSON = undefined;
opts.onerror = undefined;
Expand All @@ -59,15 +60,23 @@ module.exports = function (opts) {
'text/plain',
];

// default xml types
var xmlTypes = [
'text/xml',
'application/xml',
];

var jsonOpts = formatOptions(opts, 'json');
var formOpts = formatOptions(opts, 'form');
var textOpts = formatOptions(opts, 'text');
var xmlOpts = formatOptions(opts, 'xml');

var extendTypes = opts.extendTypes || {};

extendType(jsonTypes, extendTypes.json);
extendType(formTypes, extendTypes.form);
extendType(textTypes, extendTypes.text);
extendType(xmlTypes, extendTypes.xml);

return async function bodyParser(ctx, next) {
if (ctx.request.body !== undefined) return await next();
Expand Down Expand Up @@ -96,6 +105,9 @@ module.exports = function (opts) {
if (enableText && ctx.request.is(textTypes)) {
return await parse.text(ctx, textOpts) || '';
}
if (enableXml && ctx.request.is(xmlTypes)) {
return await parse.text(ctx, xmlOpts) || '';
}
return {};
}
};
Expand Down
72 changes: 69 additions & 3 deletions test/middleware.test.js
Expand Up @@ -210,8 +210,56 @@ describe('test/middleware.test.js', function () {
});
});

describe('extent type', function () {
it('should extent json ok', function (done) {
describe('xml body', function () {
it('should parse xml body ok', function (done) {
var app = App({
enableTypes: ['xml'],
});
app.use(async (ctx) => {
ctx.headers['content-type'].should.equal('application/xml');
ctx.request.body.should.equal('<xml>abc</xml>');
ctx.request.rawBody.should.equal('<xml>abc</xml>');
ctx.body = ctx.request.body;
});
request(app.listen())
.post('/')
.type('xml')
.send('<xml>abc</xml>')
.expect('<xml>abc</xml>', done);
});

it('should not parse text body when disable', function (done) {
var app = App();
app.use(async (ctx) => {
ctx.headers['content-type'].should.equal('application/xml');
ctx.body = ctx.request.body;
});
request(app.listen())
.post('/')
.type('xml')
.send('<xml>abc</xml>')
.expect({}, done);
});

it('should xml body reach the limit size', function (done) {
var app = App({
enableTypes: ['xml'],
xmlLimit: 10,
});
app.use(async (ctx) => {
ctx.headers['content-type'].should.equal('application/xml');
ctx.body = ctx.request.body;
});
request(app.listen())
.post('/')
.type('xml')
.send('<xml>abcdefghijklmn</xml>')
.expect(413, done);
});
});

describe('extend type', function () {
it('should extend json ok', function (done) {
var app = App({
extendTypes: {
json: 'application/x-javascript'
Expand All @@ -228,7 +276,7 @@ describe('test/middleware.test.js', function () {
.expect({ foo: 'bar' }, done);
});

it('should extent json with array ok', function (done) {
it('should extend json with array ok', function (done) {
var app = App({
extendTypes: {
json: ['application/x-javascript', 'application/y-javascript']
Expand All @@ -244,6 +292,24 @@ describe('test/middleware.test.js', function () {
.send(JSON.stringify({ foo: 'bar' }))
.expect({ foo: 'bar' }, done);
});

it('should extend xml ok', function (done) {
var app = App({
enableTypes: ['xml'],
extendTypes: {
xml: 'application/xml-custom'
}
});
app.use(async (ctx) => {
ctx.body = ctx.request.body;
});

request(app.listen())
.post('/')
.type('application/xml-custom')
.send('<xml>abc</xml>')
.expect('<xml>abc</xml>', done);
});
});

describe('enableTypes', function () {
Expand Down

0 comments on commit 705673d

Please sign in to comment.