2 var assert = require('assert')
3 var Buffer = require('safe-buffer').Buffer
4 var express = require('..')
5 var request = require('supertest')
7 describe('express.text()', function () {
12 it('should parse text/plain', function (done) {
15 .set('Content-Type', 'text/plain')
17 .expect(200, '"user is tobi"', done)
20 it('should 400 when invalid content-length', function (done) {
23 app.use(function (req, res, next) {
24 req.headers['content-length'] = '20' // bad length
28 app.use(express.text())
30 app.post('/', function (req, res) {
36 .set('Content-Type', 'text/plain')
38 .expect(400, /content length/, done)
41 it('should handle Content-Length: 0', function (done) {
42 request(createApp({ limit: '1kb' }))
44 .set('Content-Type', 'text/plain')
45 .set('Content-Length', '0')
46 .expect(200, '""', done)
49 it('should handle empty message-body', function (done) {
50 request(createApp({ limit: '1kb' }))
52 .set('Content-Type', 'text/plain')
53 .set('Transfer-Encoding', 'chunked')
55 .expect(200, '""', done)
58 it('should handle duplicated middleware', function (done) {
61 app.use(express.text())
62 app.use(express.text())
64 app.post('/', function (req, res) {
70 .set('Content-Type', 'text/plain')
72 .expect(200, '"user is tobi"', done)
75 describe('with defaultCharset option', function () {
76 it('should change default charset', function (done) {
77 var app = createApp({ defaultCharset: 'koi8-r' })
78 var test = request(app).post('/')
79 test.set('Content-Type', 'text/plain')
80 test.write(Buffer.from('6e616d6520697320cec5d4', 'hex'))
81 test.expect(200, '"name is нет"', done)
84 it('should honor content-type charset', function (done) {
85 var app = createApp({ defaultCharset: 'koi8-r' })
86 var test = request(app).post('/')
87 test.set('Content-Type', 'text/plain; charset=utf-8')
88 test.write(Buffer.from('6e616d6520697320e8aeba', 'hex'))
89 test.expect(200, '"name is 论"', done)
93 describe('with limit option', function () {
94 it('should 413 when over limit with Content-Length', function (done) {
95 var buf = Buffer.alloc(1028, '.')
96 request(createApp({ limit: '1kb' }))
98 .set('Content-Type', 'text/plain')
99 .set('Content-Length', '1028')
100 .send(buf.toString())
104 it('should 413 when over limit with chunked encoding', function (done) {
105 var buf = Buffer.alloc(1028, '.')
106 var app = createApp({ limit: '1kb' })
107 var test = request(app).post('/')
108 test.set('Content-Type', 'text/plain')
109 test.set('Transfer-Encoding', 'chunked')
110 test.write(buf.toString())
111 test.expect(413, done)
114 it('should accept number of bytes', function (done) {
115 var buf = Buffer.alloc(1028, '.')
116 request(createApp({ limit: 1024 }))
118 .set('Content-Type', 'text/plain')
119 .send(buf.toString())
123 it('should not change when options altered', function (done) {
124 var buf = Buffer.alloc(1028, '.')
125 var options = { limit: '1kb' }
126 var app = createApp(options)
128 options.limit = '100kb'
132 .set('Content-Type', 'text/plain')
133 .send(buf.toString())
137 it('should not hang response', function (done) {
138 var buf = Buffer.alloc(10240, '.')
139 var app = createApp({ limit: '8kb' })
140 var test = request(app).post('/')
141 test.set('Content-Type', 'text/plain')
145 test.expect(413, done)
149 describe('with inflate option', function () {
150 describe('when false', function () {
152 this.app = createApp({ inflate: false })
155 it('should not accept content-encoding', function (done) {
156 var test = request(this.app).post('/')
157 test.set('Content-Encoding', 'gzip')
158 test.set('Content-Type', 'text/plain')
159 test.write(Buffer.from('1f8b080000000000000bcb4bcc4d55c82c5678b16e170072b3e0200b000000', 'hex'))
160 test.expect(415, 'content encoding unsupported', done)
164 describe('when true', function () {
166 this.app = createApp({ inflate: true })
169 it('should accept content-encoding', function (done) {
170 var test = request(this.app).post('/')
171 test.set('Content-Encoding', 'gzip')
172 test.set('Content-Type', 'text/plain')
173 test.write(Buffer.from('1f8b080000000000000bcb4bcc4d55c82c5678b16e170072b3e0200b000000', 'hex'))
174 test.expect(200, '"name is 论"', done)
179 describe('with type option', function () {
180 describe('when "text/html"', function () {
182 this.app = createApp({ type: 'text/html' })
185 it('should parse for custom type', function (done) {
188 .set('Content-Type', 'text/html')
190 .expect(200, '"<b>tobi</b>"', done)
193 it('should ignore standard type', function (done) {
196 .set('Content-Type', 'text/plain')
197 .send('user is tobi')
198 .expect(200, '{}', done)
202 describe('when ["text/html", "text/plain"]', function () {
204 this.app = createApp({ type: ['text/html', 'text/plain'] })
207 it('should parse "text/html"', function (done) {
210 .set('Content-Type', 'text/html')
212 .expect(200, '"<b>tobi</b>"', done)
215 it('should parse "text/plain"', function (done) {
218 .set('Content-Type', 'text/plain')
220 .expect(200, '"tobi"', done)
223 it('should ignore "text/xml"', function (done) {
226 .set('Content-Type', 'text/xml')
227 .send('<user>tobi</user>')
228 .expect(200, '{}', done)
232 describe('when a function', function () {
233 it('should parse when truthy value returned', function (done) {
234 var app = createApp({ type: accept })
236 function accept (req) {
237 return req.headers['content-type'] === 'text/vnd.something'
242 .set('Content-Type', 'text/vnd.something')
243 .send('user is tobi')
244 .expect(200, '"user is tobi"', done)
247 it('should work without content-type', function (done) {
248 var app = createApp({ type: accept })
250 function accept (req) {
254 var test = request(app).post('/')
255 test.write('user is tobi')
256 test.expect(200, '"user is tobi"', done)
259 it('should not invoke without a body', function (done) {
260 var app = createApp({ type: accept })
262 function accept (req) {
263 throw new Error('oops!')
273 describe('with verify option', function () {
274 it('should assert value is function', function () {
275 assert.throws(createApp.bind(null, { verify: 'lol' }),
276 /TypeError: option verify must be function/)
279 it('should error from verify', function (done) {
280 var app = createApp({ verify: function (req, res, buf) {
281 if (buf[0] === 0x20) throw new Error('no leading space')
286 .set('Content-Type', 'text/plain')
287 .send(' user is tobi')
288 .expect(403, 'no leading space', done)
291 it('should allow custom codes', function (done) {
292 var app = createApp({ verify: function (req, res, buf) {
293 if (buf[0] !== 0x20) return
294 var err = new Error('no leading space')
301 .set('Content-Type', 'text/plain')
302 .send(' user is tobi')
303 .expect(400, 'no leading space', done)
306 it('should allow pass-through', function (done) {
307 var app = createApp({ verify: function (req, res, buf) {
308 if (buf[0] === 0x20) throw new Error('no leading space')
313 .set('Content-Type', 'text/plain')
314 .send('user is tobi')
315 .expect(200, '"user is tobi"', done)
318 it('should 415 on unknown charset prior to verify', function (done) {
319 var app = createApp({ verify: function (req, res, buf) {
320 throw new Error('unexpected verify call')
323 var test = request(app).post('/')
324 test.set('Content-Type', 'text/plain; charset=x-bogus')
325 test.write(Buffer.from('00000000', 'hex'))
326 test.expect(415, 'unsupported charset "X-BOGUS"', done)
330 describe('charset', function () {
332 this.app = createApp()
335 it('should parse utf-8', function (done) {
336 var test = request(this.app).post('/')
337 test.set('Content-Type', 'text/plain; charset=utf-8')
338 test.write(Buffer.from('6e616d6520697320e8aeba', 'hex'))
339 test.expect(200, '"name is 论"', done)
342 it('should parse codepage charsets', function (done) {
343 var test = request(this.app).post('/')
344 test.set('Content-Type', 'text/plain; charset=koi8-r')
345 test.write(Buffer.from('6e616d6520697320cec5d4', 'hex'))
346 test.expect(200, '"name is нет"', done)
349 it('should parse when content-length != char length', function (done) {
350 var test = request(this.app).post('/')
351 test.set('Content-Type', 'text/plain; charset=utf-8')
352 test.set('Content-Length', '11')
353 test.write(Buffer.from('6e616d6520697320e8aeba', 'hex'))
354 test.expect(200, '"name is 论"', done)
357 it('should default to utf-8', function (done) {
358 var test = request(this.app).post('/')
359 test.set('Content-Type', 'text/plain')
360 test.write(Buffer.from('6e616d6520697320e8aeba', 'hex'))
361 test.expect(200, '"name is 论"', done)
364 it('should 415 on unknown charset', function (done) {
365 var test = request(this.app).post('/')
366 test.set('Content-Type', 'text/plain; charset=x-bogus')
367 test.write(Buffer.from('00000000', 'hex'))
368 test.expect(415, 'unsupported charset "X-BOGUS"', done)
372 describe('encoding', function () {
374 this.app = createApp({ limit: '10kb' })
377 it('should parse without encoding', function (done) {
378 var test = request(this.app).post('/')
379 test.set('Content-Type', 'text/plain')
380 test.write(Buffer.from('6e616d6520697320e8aeba', 'hex'))
381 test.expect(200, '"name is 论"', done)
384 it('should support identity encoding', function (done) {
385 var test = request(this.app).post('/')
386 test.set('Content-Encoding', 'identity')
387 test.set('Content-Type', 'text/plain')
388 test.write(Buffer.from('6e616d6520697320e8aeba', 'hex'))
389 test.expect(200, '"name is 论"', done)
392 it('should support gzip encoding', function (done) {
393 var test = request(this.app).post('/')
394 test.set('Content-Encoding', 'gzip')
395 test.set('Content-Type', 'text/plain')
396 test.write(Buffer.from('1f8b080000000000000bcb4bcc4d55c82c5678b16e170072b3e0200b000000', 'hex'))
397 test.expect(200, '"name is 论"', done)
400 it('should support deflate encoding', function (done) {
401 var test = request(this.app).post('/')
402 test.set('Content-Encoding', 'deflate')
403 test.set('Content-Type', 'text/plain')
404 test.write(Buffer.from('789ccb4bcc4d55c82c5678b16e17001a6f050e', 'hex'))
405 test.expect(200, '"name is 论"', done)
408 it('should be case-insensitive', function (done) {
409 var test = request(this.app).post('/')
410 test.set('Content-Encoding', 'GZIP')
411 test.set('Content-Type', 'text/plain')
412 test.write(Buffer.from('1f8b080000000000000bcb4bcc4d55c82c5678b16e170072b3e0200b000000', 'hex'))
413 test.expect(200, '"name is 论"', done)
416 it('should fail on unknown encoding', function (done) {
417 var test = request(this.app).post('/')
418 test.set('Content-Encoding', 'nulls')
419 test.set('Content-Type', 'text/plain')
420 test.write(Buffer.from('000000000000', 'hex'))
421 test.expect(415, 'unsupported content encoding "nulls"', done)
426 function createApp (options) {
429 app.use(express.text(options))
431 app.use(function (err, req, res, next) {
432 res.status(err.status || 500)
433 res.send(err.message)
436 app.post('/', function (req, res) {