Tizen 2.0 Release
[platform/framework/web/web-ui-fw.git] / libs / js / jquery-mobile-1.2.0 / node_modules / grunt / node_modules / connect / lib / middleware / compress.js
1 /*!
2  * Connect - compress
3  * Copyright(c) 2010 Sencha Inc.
4  * Copyright(c) 2011 TJ Holowaychuk
5  * MIT Licensed
6  */
7
8 /**
9  * Module dependencies.
10  */
11
12 var zlib = require('zlib');
13
14 /**
15  * Supported content-encoding methods.
16  */
17
18 exports.methods = {
19     gzip: zlib.createGzip
20   , deflate: zlib.createDeflate
21 };
22
23 /**
24  * Default filter function.
25  */
26
27 exports.filter = function(req, res){
28   return /json|text|javascript/.test(res.getHeader('Content-Type'));
29 };
30
31 /**
32  * Compress:
33  *
34  * Compress response data with gzip/deflate.
35  *
36  * Filter:
37  *
38  *  A `filter` callback function may be passed to
39  *  replace the default logic of:
40  *
41  *     exports.filter = function(req, res){
42  *       return /json|text|javascript/.test(res.getHeader('Content-Type'));
43  *     };
44  *
45  * Options:
46  *
47  *  All remaining options are passed to the gzip/deflate
48  *  creation functions. Consult node's docs for additional details.
49  *
50  *   - `chunkSize` (default: 16*1024)
51  *   - `windowBits`
52  *   - `level`: 0-9 where 0 is no compression, and 9 is slow but best compression
53  *   - `memLevel`: 1-9 low is slower but uses less memory, high is fast but uses more
54  *   - `strategy`: compression strategy
55  *
56  * @param {Object} options
57  * @return {Function}
58  * @api public
59  */
60
61 module.exports = function compress(options) {
62   var options = options || {}
63     , names = Object.keys(exports.methods)
64     , filter = options.filter || exports.filter;
65
66   return function(req, res, next){
67     var accept = req.headers['accept-encoding']
68       , write = res.write
69       , end = res.end
70       , stream
71       , method;
72
73     // vary
74     res.setHeader('Vary', 'Accept-Encoding');
75
76     // proxy
77
78     res.write = function(chunk, encoding){
79       if (!this.headerSent) this._implicitHeader();
80       return stream
81         ? stream.write(new Buffer(chunk, encoding))
82         : write.call(res, chunk, encoding);
83     };
84
85     res.end = function(chunk, encoding){
86       if (chunk) this.write(chunk, encoding);
87       return stream
88         ? stream.end()
89         : end.call(res);
90     };
91
92     res.on('header', function(){
93       // default request filter
94       if (!filter(req, res)) return;
95
96       // SHOULD use identity
97       if (!accept) return;
98
99       // head
100       if ('HEAD' == req.method) return;
101
102       // default to gzip
103       if ('*' == accept.trim()) method = 'gzip';
104
105       // compression method
106       if (!method) {
107         for (var i = 0, len = names.length; i < len; ++i) {
108           if (~accept.indexOf(names[i])) {
109             method = names[i];
110             break;
111           }
112         }
113       }
114
115       // compression method
116       if (!method) return;
117
118       // compression stream
119       stream = exports.methods[method](options);
120
121       // header fields
122       res.setHeader('Content-Encoding', method);
123       res.removeHeader('Content-Length');
124
125       // compression
126
127       stream.on('data', function(chunk){
128         write.call(res, chunk);
129       });
130
131       stream.on('end', function(){
132         end.call(res);
133       });
134
135       stream.on('drain', function() {
136         res.emit('drain');
137       });
138     });
139
140     next();
141   };
142 }