1 |
|
2 | 'use strict';
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | const util = require('util');
|
9 | const createError = require('http-errors');
|
10 | const httpAssert = require('http-assert');
|
11 | const delegate = require('delegates');
|
12 | const statuses = require('statuses');
|
13 | const Cookies = require('cookies');
|
14 |
|
15 | const COOKIES = Symbol('context#cookies');
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 | const proto = module.exports = {
|
22 |
|
23 | |
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 | inspect() {
|
32 | if (this === proto) return this;
|
33 | return this.toJSON();
|
34 | },
|
35 |
|
36 | |
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 | toJSON() {
|
49 | return {
|
50 | request: this.request.toJSON(),
|
51 | response: this.response.toJSON(),
|
52 | app: this.app.toJSON(),
|
53 | originalUrl: this.originalUrl,
|
54 | req: '<original node req>',
|
55 | res: '<original node res>',
|
56 | socket: '<original node socket>'
|
57 | };
|
58 | },
|
59 |
|
60 | |
61 |
|
62 |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 | assert: httpAssert,
|
74 |
|
75 | |
76 |
|
77 |
|
78 |
|
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 | throw(...args) {
|
97 | throw createError(...args);
|
98 | },
|
99 |
|
100 | |
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 | onerror(err) {
|
108 |
|
109 |
|
110 |
|
111 | if (null == err) return;
|
112 |
|
113 | if (!(err instanceof Error)) err = new Error(util.format('non-error thrown: %j', err));
|
114 |
|
115 | let headerSent = false;
|
116 | if (this.headerSent || !this.writable) {
|
117 | headerSent = err.headerSent = true;
|
118 | }
|
119 |
|
120 |
|
121 | this.app.emit('error', err, this);
|
122 |
|
123 |
|
124 |
|
125 |
|
126 | if (headerSent) {
|
127 | return;
|
128 | }
|
129 |
|
130 | const { res } = this;
|
131 |
|
132 |
|
133 |
|
134 | if (typeof res.getHeaderNames === 'function') {
|
135 | res.getHeaderNames().forEach(name => res.removeHeader(name));
|
136 | } else {
|
137 | res._headers = {};
|
138 | }
|
139 |
|
140 |
|
141 | this.set(err.headers);
|
142 |
|
143 |
|
144 | this.type = 'text';
|
145 |
|
146 |
|
147 | if ('ENOENT' == err.code) err.status = 404;
|
148 |
|
149 |
|
150 | if ('number' != typeof err.status || !statuses[err.status]) err.status = 500;
|
151 |
|
152 |
|
153 | const code = statuses[err.status];
|
154 | const msg = err.expose ? err.message : code;
|
155 | this.status = err.status;
|
156 | this.length = Buffer.byteLength(msg);
|
157 | res.end(msg);
|
158 | },
|
159 |
|
160 | get cookies() {
|
161 | if (!this[COOKIES]) {
|
162 | this[COOKIES] = new Cookies(this.req, this.res, {
|
163 | keys: this.app.keys,
|
164 | secure: this.request.secure
|
165 | });
|
166 | }
|
167 | return this[COOKIES];
|
168 | },
|
169 |
|
170 | set cookies(_cookies) {
|
171 | this[COOKIES] = _cookies;
|
172 | }
|
173 | };
|
174 |
|
175 |
|
176 |
|
177 |
|
178 |
|
179 |
|
180 |
|
181 |
|
182 |
|
183 | if (util.inspect.custom) {
|
184 | module.exports[util.inspect.custom] = module.exports.inspect;
|
185 | }
|
186 |
|
187 |
|
188 |
|
189 |
|
190 |
|
191 | delegate(proto, 'response')
|
192 | .method('attachment')
|
193 | .method('redirect')
|
194 | .method('remove')
|
195 | .method('vary')
|
196 | .method('has')
|
197 | .method('set')
|
198 | .method('append')
|
199 | .method('flushHeaders')
|
200 | .access('status')
|
201 | .access('message')
|
202 | .access('body')
|
203 | .access('length')
|
204 | .access('type')
|
205 | .access('lastModified')
|
206 | .access('etag')
|
207 | .getter('headerSent')
|
208 | .getter('writable');
|
209 |
|
210 |
|
211 |
|
212 |
|
213 |
|
214 | delegate(proto, 'request')
|
215 | .method('acceptsLanguages')
|
216 | .method('acceptsEncodings')
|
217 | .method('acceptsCharsets')
|
218 | .method('accepts')
|
219 | .method('get')
|
220 | .method('is')
|
221 | .access('querystring')
|
222 | .access('idempotent')
|
223 | .access('socket')
|
224 | .access('search')
|
225 | .access('method')
|
226 | .access('query')
|
227 | .access('path')
|
228 | .access('url')
|
229 | .access('accept')
|
230 | .getter('origin')
|
231 | .getter('href')
|
232 | .getter('subdomains')
|
233 | .getter('protocol')
|
234 | .getter('host')
|
235 | .getter('hostname')
|
236 | .getter('URL')
|
237 | .getter('header')
|
238 | .getter('headers')
|
239 | .getter('secure')
|
240 | .getter('stale')
|
241 | .getter('fresh')
|
242 | .getter('ips')
|
243 | .getter('ip');
|