1 | var zlib = require('zlib')
|
2 | var Stream = require('stream')
|
3 | var bytes = require('bytes')
|
4 | var Negotiator = require('negotiator')
|
5 |
|
6 | var encodingMethods = {
|
7 | gzip: zlib.createGzip,
|
8 | deflate: zlib.createDeflate
|
9 | }
|
10 |
|
11 | module.exports = function compress(options) {
|
12 | options = options || {}
|
13 |
|
14 | var filter = options.filter
|
15 | || /json|text|javascript|dart/i
|
16 |
|
17 | var threshold = !options.threshold ? 1024
|
18 | : typeof options.threshold === 'number' ? options.threshold
|
19 | : typeof options.threshold === 'string' ? bytes(options.threshold)
|
20 | : 1024
|
21 |
|
22 | return function (next) {
|
23 | return function *() {
|
24 | yield next
|
25 |
|
26 | this.vary('Accept-Encoding')
|
27 |
|
28 | var body = this.body
|
29 |
|
30 | if (this.compress === false
|
31 | || this.method === 'HEAD'
|
32 | || this.status === 204
|
33 | || this.status === 304
|
34 |
|
35 | || body == null
|
36 | ) return
|
37 |
|
38 | var length
|
39 | if (Buffer.isBuffer(body)) {
|
40 | if (!this.responseHeader['content-type'])
|
41 | this.set('Content-Type', 'application/octet-stream')
|
42 |
|
43 | length = body.length
|
44 | } else if (typeof body === 'string') {
|
45 | if (!this.responseHeader['content-type'])
|
46 | this.set('Content-Type', 'text/plain; charset=utf-8')
|
47 |
|
48 | length = Buffer.byteLength(body)
|
49 | } else if (body instanceof Stream) {
|
50 | if (!this.responseHeader['content-type'])
|
51 | this.set('Content-Type', 'application/octet-stream')
|
52 | } else {
|
53 |
|
54 | body = JSON.stringify(body, null, this.app.jsonSpaces)
|
55 | length = Buffer.byteLength(body)
|
56 | this.set('Content-Type', 'application/json')
|
57 | }
|
58 |
|
59 | var contentType = this.responseHeader['content-type']
|
60 | if (!(this.compress === true || filter.test(contentType)))
|
61 | return
|
62 |
|
63 | var encodings = new Negotiator(this.req)
|
64 | .preferredEncodings(['gzip', 'deflate', 'identity'])
|
65 | var encoding = encodings[0] || 'identity'
|
66 | if (encoding === 'identity')
|
67 | return
|
68 |
|
69 | if (threshold
|
70 | && (typeof body === 'string' || Buffer.isBuffer(body))
|
71 | && length < threshold
|
72 | ) return
|
73 |
|
74 | this.set('Content-Encoding', encoding)
|
75 | this.res.removeHeader('Content-Length')
|
76 |
|
77 | var stream = encodingMethods[encoding](options)
|
78 | .on('error', this.error.bind(this))
|
79 |
|
80 | if (body instanceof Stream)
|
81 | body.pipe(stream)
|
82 | else
|
83 | stream.end(body)
|
84 |
|
85 | this.body = stream
|
86 | }
|
87 | }
|
88 | } |
\ | No newline at end of file |