1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | var cookie = require('cookie');
|
13 | var deprecate = require('depd')('connect');
|
14 | var http = require('http');
|
15 | var merge = require('utils-merge');
|
16 | var onHeaders = require('on-headers');
|
17 | var utils = require('./utils')
|
18 | , res = http.ServerResponse.prototype
|
19 | , addListener = res.addListener
|
20 | , setHeader = res.setHeader;
|
21 |
|
22 |
|
23 |
|
24 | if (!res._hasConnectPatch) {
|
25 |
|
26 | |
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 | Object.defineProperty(res, 'headerSent', {
|
35 | configurable: true,
|
36 | enumerable: true,
|
37 | get: headersSent
|
38 | });
|
39 |
|
40 | deprecate.property(res, 'headerSent', 'res.headerSent: use standard res.headersSent');
|
41 |
|
42 | if (!('headersSent' in res)) {
|
43 |
|
44 | |
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | Object.defineProperty(res, 'headersSent', {
|
53 | configurable: true,
|
54 | enumerable: true,
|
55 | get: headersSent
|
56 | });
|
57 |
|
58 | }
|
59 |
|
60 | /**
|
61 | * Set cookie `name` to `val`, with the given `options`.
|
62 | *
|
63 | * Options:
|
64 | *
|
65 | * - `maxAge` max-age in milliseconds, converted to `expires`
|
66 | * - `path` defaults to "/"
|
67 | *
|
68 | * @param {String} name
|
69 | * @param {String} val
|
70 | * @param {Object} options
|
71 | * @api public
|
72 | */
|
73 |
|
74 | res.cookie = function(name, val, options){
|
75 | options = merge({}, options);
|
76 | if ('maxAge' in options) {
|
77 | options.expires = new Date(Date.now() + options.maxAge);
|
78 | options.maxAge /= 1000;
|
79 | }
|
80 | if (null == options.path) options.path = '/';
|
81 | this.setHeader('Set-Cookie', cookie.serialize(name, String(val), options));
|
82 | };
|
83 |
|
84 | |
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 | res.appendHeader = function appendHeader(field, val){
|
93 | var prev = this.getHeader(field);
|
94 |
|
95 | if (!prev) return setHeader.call(this, field, val);
|
96 |
|
97 |
|
98 | val = Array.isArray(prev) ? prev.concat(val)
|
99 | : Array.isArray(val) ? [prev].concat(val)
|
100 | : [prev, val];
|
101 |
|
102 | return setHeader.call(this, field, val);
|
103 | };
|
104 |
|
105 | |
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 | res.setHeader = function(field, val){
|
115 | var key = field.toLowerCase()
|
116 | , prev;
|
117 |
|
118 |
|
119 | if (key === 'set-cookie') {
|
120 |
|
121 | if (Array.isArray(val) && val.length > 1) {
|
122 | prev = [].concat(this.getHeader(field) || []);
|
123 | val = unique(prev, val);
|
124 | }
|
125 |
|
126 | return this.appendHeader(field, val);
|
127 | }
|
128 |
|
129 |
|
130 | if ('content-type' == key && this.charset) {
|
131 | val = utils.setCharset(val, this.charset, true);
|
132 | }
|
133 |
|
134 | return setHeader.call(this, field, val);
|
135 | };
|
136 |
|
137 | |
138 |
|
139 |
|
140 |
|
141 | res.on = function(type, listener){
|
142 | if (type === 'header') {
|
143 | deprecate('res.on("header"): use on-headers npm module instead');
|
144 | onHeaders(this, listener);
|
145 | return this;
|
146 | }
|
147 |
|
148 | return addListener.apply(this, arguments);
|
149 | };
|
150 |
|
151 | res._hasConnectPatch = true;
|
152 | }
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 | function headersSent(){
|
162 | return Boolean(this._header);
|
163 | }
|
164 |
|
165 |
|
166 |
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 | function unique(reference, arr){
|
175 | var array = [];
|
176 |
|
177 | for (var i = 0; i < arr.length; i++) {
|
178 | if (reference.indexOf(arr[i]) === -1) {
|
179 | array.push(arr[i]);
|
180 | }
|
181 | }
|
182 |
|
183 | return array;
|
184 | }
|