Skip to content

Commit 11192bd

Browse files
committedMay 8, 2019
tests: add express.raw test suite
1 parent 0bcdd88 commit 11192bd

File tree

1 file changed

+387
-0
lines changed

1 file changed

+387
-0
lines changed
 

‎test/express.raw.js

+387
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,387 @@
1+
2+
var assert = require('assert')
3+
var Buffer = require('safe-buffer').Buffer
4+
var express = require('..')
5+
var request = require('supertest')
6+
7+
describe('express.raw()', function () {
8+
before(function () {
9+
this.app = createApp()
10+
})
11+
12+
it('should parse application/octet-stream', function (done) {
13+
request(this.app)
14+
.post('/')
15+
.set('Content-Type', 'application/octet-stream')
16+
.send('the user is tobi')
17+
.expect(200, { buf: '746865207573657220697320746f6269' }, done)
18+
})
19+
20+
it('should 400 when invalid content-length', function (done) {
21+
var app = express()
22+
23+
app.use(function (req, res, next) {
24+
req.headers['content-length'] = '20' // bad length
25+
next()
26+
})
27+
28+
app.use(express.raw())
29+
30+
app.post('/', function (req, res) {
31+
if (Buffer.isBuffer(req.body)) {
32+
res.json({ buf: req.body.toString('hex') })
33+
} else {
34+
res.json(req.body)
35+
}
36+
})
37+
38+
request(app)
39+
.post('/')
40+
.set('Content-Type', 'application/octet-stream')
41+
.send('stuff')
42+
.expect(400, /content length/, done)
43+
})
44+
45+
it('should handle Content-Length: 0', function (done) {
46+
request(this.app)
47+
.post('/')
48+
.set('Content-Type', 'application/octet-stream')
49+
.set('Content-Length', '0')
50+
.expect(200, { buf: '' }, done)
51+
})
52+
53+
it('should handle empty message-body', function (done) {
54+
request(this.app)
55+
.post('/')
56+
.set('Content-Type', 'application/octet-stream')
57+
.set('Transfer-Encoding', 'chunked')
58+
.send('')
59+
.expect(200, { buf: '' }, done)
60+
})
61+
62+
it('should handle duplicated middleware', function (done) {
63+
var app = express()
64+
65+
app.use(express.raw())
66+
app.use(express.raw())
67+
68+
app.post('/', function (req, res) {
69+
if (Buffer.isBuffer(req.body)) {
70+
res.json({ buf: req.body.toString('hex') })
71+
} else {
72+
res.json(req.body)
73+
}
74+
})
75+
76+
request(app)
77+
.post('/')
78+
.set('Content-Type', 'application/octet-stream')
79+
.send('the user is tobi')
80+
.expect(200, { buf: '746865207573657220697320746f6269' }, done)
81+
})
82+
83+
describe('with limit option', function () {
84+
it('should 413 when over limit with Content-Length', function (done) {
85+
var buf = Buffer.alloc(1028, '.')
86+
var app = createApp({ limit: '1kb' })
87+
var test = request(app).post('/')
88+
test.set('Content-Type', 'application/octet-stream')
89+
test.set('Content-Length', '1028')
90+
test.write(buf)
91+
test.expect(413, done)
92+
})
93+
94+
it('should 413 when over limit with chunked encoding', function (done) {
95+
var buf = Buffer.alloc(1028, '.')
96+
var app = createApp({ limit: '1kb' })
97+
var test = request(app).post('/')
98+
test.set('Content-Type', 'application/octet-stream')
99+
test.set('Transfer-Encoding', 'chunked')
100+
test.write(buf)
101+
test.expect(413, done)
102+
})
103+
104+
it('should accept number of bytes', function (done) {
105+
var buf = Buffer.alloc(1028, '.')
106+
var app = createApp({ limit: 1024 })
107+
var test = request(app).post('/')
108+
test.set('Content-Type', 'application/octet-stream')
109+
test.write(buf)
110+
test.expect(413, done)
111+
})
112+
113+
it('should not change when options altered', function (done) {
114+
var buf = Buffer.alloc(1028, '.')
115+
var options = { limit: '1kb' }
116+
var app = createApp(options)
117+
118+
options.limit = '100kb'
119+
120+
var test = request(app).post('/')
121+
test.set('Content-Type', 'application/octet-stream')
122+
test.write(buf)
123+
test.expect(413, done)
124+
})
125+
126+
it('should not hang response', function (done) {
127+
var buf = Buffer.alloc(10240, '.')
128+
var app = createApp({ limit: '8kb' })
129+
var test = request(app).post('/')
130+
test.set('Content-Type', 'application/octet-stream')
131+
test.write(buf)
132+
test.write(buf)
133+
test.write(buf)
134+
test.expect(413, done)
135+
})
136+
})
137+
138+
describe('with inflate option', function () {
139+
describe('when false', function () {
140+
before(function () {
141+
this.app = createApp({ inflate: false })
142+
})
143+
144+
it('should not accept content-encoding', function (done) {
145+
var test = request(this.app).post('/')
146+
test.set('Content-Encoding', 'gzip')
147+
test.set('Content-Type', 'application/octet-stream')
148+
test.write(Buffer.from('1f8b080000000000000bcb4bcc4db57db16e170099a4bad608000000', 'hex'))
149+
test.expect(415, 'content encoding unsupported', done)
150+
})
151+
})
152+
153+
describe('when true', function () {
154+
before(function () {
155+
this.app = createApp({ inflate: true })
156+
})
157+
158+
it('should accept content-encoding', function (done) {
159+
var test = request(this.app).post('/')
160+
test.set('Content-Encoding', 'gzip')
161+
test.set('Content-Type', 'application/octet-stream')
162+
test.write(Buffer.from('1f8b080000000000000bcb4bcc4db57db16e170099a4bad608000000', 'hex'))
163+
test.expect(200, { buf: '6e616d653de8aeba' }, done)
164+
})
165+
})
166+
})
167+
168+
describe('with type option', function () {
169+
describe('when "application/vnd+octets"', function () {
170+
before(function () {
171+
this.app = createApp({ type: 'application/vnd+octets' })
172+
})
173+
174+
it('should parse for custom type', function (done) {
175+
var test = request(this.app).post('/')
176+
test.set('Content-Type', 'application/vnd+octets')
177+
test.write(Buffer.from('000102', 'hex'))
178+
test.expect(200, { buf: '000102' }, done)
179+
})
180+
181+
it('should ignore standard type', function (done) {
182+
var test = request(this.app).post('/')
183+
test.set('Content-Type', 'application/octet-stream')
184+
test.write(Buffer.from('000102', 'hex'))
185+
test.expect(200, '{}', done)
186+
})
187+
})
188+
189+
describe('when ["application/octet-stream", "application/vnd+octets"]', function () {
190+
before(function () {
191+
this.app = createApp({
192+
type: ['application/octet-stream', 'application/vnd+octets']
193+
})
194+
})
195+
196+
it('should parse "application/octet-stream"', function (done) {
197+
var test = request(this.app).post('/')
198+
test.set('Content-Type', 'application/octet-stream')
199+
test.write(Buffer.from('000102', 'hex'))
200+
test.expect(200, { buf: '000102' }, done)
201+
})
202+
203+
it('should parse "application/vnd+octets"', function (done) {
204+
var test = request(this.app).post('/')
205+
test.set('Content-Type', 'application/vnd+octets')
206+
test.write(Buffer.from('000102', 'hex'))
207+
test.expect(200, { buf: '000102' }, done)
208+
})
209+
210+
it('should ignore "application/x-foo"', function (done) {
211+
var test = request(this.app).post('/')
212+
test.set('Content-Type', 'application/x-foo')
213+
test.write(Buffer.from('000102', 'hex'))
214+
test.expect(200, '{}', done)
215+
})
216+
})
217+
218+
describe('when a function', function () {
219+
it('should parse when truthy value returned', function (done) {
220+
var app = createApp({ type: accept })
221+
222+
function accept (req) {
223+
return req.headers['content-type'] === 'application/vnd.octet'
224+
}
225+
226+
var test = request(app).post('/')
227+
test.set('Content-Type', 'application/vnd.octet')
228+
test.write(Buffer.from('000102', 'hex'))
229+
test.expect(200, { buf: '000102' }, done)
230+
})
231+
232+
it('should work without content-type', function (done) {
233+
var app = createApp({ type: accept })
234+
235+
function accept (req) {
236+
return true
237+
}
238+
239+
var test = request(app).post('/')
240+
test.write(Buffer.from('000102', 'hex'))
241+
test.expect(200, { buf: '000102' }, done)
242+
})
243+
244+
it('should not invoke without a body', function (done) {
245+
var app = createApp({ type: accept })
246+
247+
function accept (req) {
248+
throw new Error('oops!')
249+
}
250+
251+
request(app)
252+
.get('/')
253+
.expect(404, done)
254+
})
255+
})
256+
})
257+
258+
describe('with verify option', function () {
259+
it('should assert value is function', function () {
260+
assert.throws(createApp.bind(null, { verify: 'lol' }),
261+
/TypeError: option verify must be function/)
262+
})
263+
264+
it('should error from verify', function (done) {
265+
var app = createApp({ verify: function (req, res, buf) {
266+
if (buf[0] === 0x00) throw new Error('no leading null')
267+
} })
268+
269+
var test = request(app).post('/')
270+
test.set('Content-Type', 'application/octet-stream')
271+
test.write(Buffer.from('000102', 'hex'))
272+
test.expect(403, 'no leading null', done)
273+
})
274+
275+
it('should allow custom codes', function (done) {
276+
var app = createApp({ verify: function (req, res, buf) {
277+
if (buf[0] !== 0x00) return
278+
var err = new Error('no leading null')
279+
err.status = 400
280+
throw err
281+
} })
282+
283+
var test = request(app).post('/')
284+
test.set('Content-Type', 'application/octet-stream')
285+
test.write(Buffer.from('000102', 'hex'))
286+
test.expect(400, 'no leading null', done)
287+
})
288+
289+
it('should allow pass-through', function (done) {
290+
var app = createApp({ verify: function (req, res, buf) {
291+
if (buf[0] === 0x00) throw new Error('no leading null')
292+
} })
293+
294+
var test = request(app).post('/')
295+
test.set('Content-Type', 'application/octet-stream')
296+
test.write(Buffer.from('0102', 'hex'))
297+
test.expect(200, { buf: '0102' }, done)
298+
})
299+
})
300+
301+
describe('charset', function () {
302+
before(function () {
303+
this.app = createApp()
304+
})
305+
306+
it('should ignore charset', function (done) {
307+
var test = request(this.app).post('/')
308+
test.set('Content-Type', 'application/octet-stream; charset=utf-8')
309+
test.write(Buffer.from('6e616d6520697320e8aeba', 'hex'))
310+
test.expect(200, { buf: '6e616d6520697320e8aeba' }, done)
311+
})
312+
})
313+
314+
describe('encoding', function () {
315+
before(function () {
316+
this.app = createApp({ limit: '10kb' })
317+
})
318+
319+
it('should parse without encoding', function (done) {
320+
var test = request(this.app).post('/')
321+
test.set('Content-Type', 'application/octet-stream')
322+
test.write(Buffer.from('6e616d653de8aeba', 'hex'))
323+
test.expect(200, { buf: '6e616d653de8aeba' }, done)
324+
})
325+
326+
it('should support identity encoding', function (done) {
327+
var test = request(this.app).post('/')
328+
test.set('Content-Encoding', 'identity')
329+
test.set('Content-Type', 'application/octet-stream')
330+
test.write(Buffer.from('6e616d653de8aeba', 'hex'))
331+
test.expect(200, { buf: '6e616d653de8aeba' }, done)
332+
})
333+
334+
it('should support gzip encoding', function (done) {
335+
var test = request(this.app).post('/')
336+
test.set('Content-Encoding', 'gzip')
337+
test.set('Content-Type', 'application/octet-stream')
338+
test.write(Buffer.from('1f8b080000000000000bcb4bcc4db57db16e170099a4bad608000000', 'hex'))
339+
test.expect(200, { buf: '6e616d653de8aeba' }, done)
340+
})
341+
342+
it('should support deflate encoding', function (done) {
343+
var test = request(this.app).post('/')
344+
test.set('Content-Encoding', 'deflate')
345+
test.set('Content-Type', 'application/octet-stream')
346+
test.write(Buffer.from('789ccb4bcc4db57db16e17001068042f', 'hex'))
347+
test.expect(200, { buf: '6e616d653de8aeba' }, done)
348+
})
349+
350+
it('should be case-insensitive', function (done) {
351+
var test = request(this.app).post('/')
352+
test.set('Content-Encoding', 'GZIP')
353+
test.set('Content-Type', 'application/octet-stream')
354+
test.write(Buffer.from('1f8b080000000000000bcb4bcc4db57db16e170099a4bad608000000', 'hex'))
355+
test.expect(200, { buf: '6e616d653de8aeba' }, done)
356+
})
357+
358+
it('should fail on unknown encoding', function (done) {
359+
var test = request(this.app).post('/')
360+
test.set('Content-Encoding', 'nulls')
361+
test.set('Content-Type', 'application/octet-stream')
362+
test.write(Buffer.from('000000000000', 'hex'))
363+
test.expect(415, 'unsupported content encoding "nulls"', done)
364+
})
365+
})
366+
})
367+
368+
function createApp (options) {
369+
var app = express()
370+
371+
app.use(express.raw(options))
372+
373+
app.use(function (err, req, res, next) {
374+
res.status(err.status || 500)
375+
res.send(String(err[req.headers['x-error-property'] || 'message']))
376+
})
377+
378+
app.post('/', function (req, res) {
379+
if (Buffer.isBuffer(req.body)) {
380+
res.json({ buf: req.body.toString('hex') })
381+
} else {
382+
res.json(req.body)
383+
}
384+
})
385+
386+
return app
387+
}

0 commit comments

Comments
 (0)
Please sign in to comment.