1 |
|
2 | var http = require('http');
|
3 | var parse = require('url').parse;
|
4 | var zlib = require('zlib');
|
5 | var stream = require('stream');
|
6 | var convert = require('encoding').convert;
|
7 | var Multipart = require('parted').multipart;
|
8 |
|
9 | module.exports = TestServer;
|
10 |
|
11 | function TestServer() {
|
12 | this.server = http.createServer(this.router);
|
13 | this.port = 30001;
|
14 | this.hostname = 'localhost';
|
15 | this.server.on('error', function(err) {
|
16 | console.log(err.stack);
|
17 | });
|
18 | this.server.on('connection', function(socket) {
|
19 | socket.setTimeout(1500);
|
20 | });
|
21 | }
|
22 |
|
23 | TestServer.prototype.start = function(cb) {
|
24 | this.server.listen(this.port, this.hostname, cb);
|
25 | }
|
26 |
|
27 | TestServer.prototype.stop = function(cb) {
|
28 | this.server.close(cb);
|
29 | }
|
30 |
|
31 | TestServer.prototype.router = function(req, res) {
|
32 |
|
33 | var p = parse(req.url).pathname;
|
34 |
|
35 | if (p === '/hello') {
|
36 | res.statusCode = 200;
|
37 | res.setHeader('Content-Type', 'text/plain');
|
38 | res.end('world');
|
39 | }
|
40 |
|
41 | if (p === '/plain') {
|
42 | res.statusCode = 200;
|
43 | res.setHeader('Content-Type', 'text/plain');
|
44 | res.end('text');
|
45 | }
|
46 |
|
47 | if (p === '/options') {
|
48 | res.statusCode = 200;
|
49 | res.setHeader('Allow', 'GET, HEAD, OPTIONS');
|
50 | res.end('hello world');
|
51 | }
|
52 |
|
53 | if (p === '/html') {
|
54 | res.statusCode = 200;
|
55 | res.setHeader('Content-Type', 'text/html');
|
56 | res.end('<html></html>');
|
57 | }
|
58 |
|
59 | if (p === '/json') {
|
60 | res.statusCode = 200;
|
61 | res.setHeader('Content-Type', 'application/json');
|
62 | res.end(JSON.stringify({
|
63 | name: 'value'
|
64 | }));
|
65 | }
|
66 |
|
67 | if (p === '/gzip') {
|
68 | res.statusCode = 200;
|
69 | res.setHeader('Content-Type', 'text/plain');
|
70 | res.setHeader('Content-Encoding', 'gzip');
|
71 | zlib.gzip('hello world', function(err, buffer) {
|
72 | res.end(buffer);
|
73 | });
|
74 | }
|
75 |
|
76 | if (p === '/deflate') {
|
77 | res.statusCode = 200;
|
78 | res.setHeader('Content-Type', 'text/plain');
|
79 | res.setHeader('Content-Encoding', 'deflate');
|
80 | zlib.deflate('hello world', function(err, buffer) {
|
81 | res.end(buffer);
|
82 | });
|
83 | }
|
84 |
|
85 | if (p === '/deflate-raw') {
|
86 | res.statusCode = 200;
|
87 | res.setHeader('Content-Type', 'text/plain');
|
88 | res.setHeader('Content-Encoding', 'deflate');
|
89 | zlib.deflateRaw('hello world', function(err, buffer) {
|
90 | res.end(buffer);
|
91 | });
|
92 | }
|
93 |
|
94 | if (p === '/sdch') {
|
95 | res.statusCode = 200;
|
96 | res.setHeader('Content-Type', 'text/plain');
|
97 | res.setHeader('Content-Encoding', 'sdch');
|
98 | res.end('fake sdch string');
|
99 | }
|
100 |
|
101 | if (p === '/invalid-content-encoding') {
|
102 | res.statusCode = 200;
|
103 | res.setHeader('Content-Type', 'text/plain');
|
104 | res.setHeader('Content-Encoding', 'gzip');
|
105 | res.end('fake gzip string');
|
106 | }
|
107 |
|
108 | if (p === '/timeout') {
|
109 | setTimeout(function() {
|
110 | res.statusCode = 200;
|
111 | res.setHeader('Content-Type', 'text/plain');
|
112 | res.end('text');
|
113 | }, 1000);
|
114 | }
|
115 |
|
116 | if (p === '/slow') {
|
117 | res.statusCode = 200;
|
118 | res.setHeader('Content-Type', 'text/plain');
|
119 | res.write('test');
|
120 | setTimeout(function() {
|
121 | res.end('test');
|
122 | }, 1000);
|
123 | }
|
124 |
|
125 | if (p === '/cookie') {
|
126 | res.statusCode = 200;
|
127 | res.setHeader('Set-Cookie', ['a=1', 'b=1']);
|
128 | res.end('cookie');
|
129 | }
|
130 |
|
131 | if (p === '/size/chunk') {
|
132 | res.statusCode = 200;
|
133 | res.setHeader('Content-Type', 'text/plain');
|
134 | setTimeout(function() {
|
135 | res.write('test');
|
136 | }, 50);
|
137 | setTimeout(function() {
|
138 | res.end('test');
|
139 | }, 100);
|
140 | }
|
141 |
|
142 | if (p === '/size/long') {
|
143 | res.statusCode = 200;
|
144 | res.setHeader('Content-Type', 'text/plain');
|
145 | res.end('testtest');
|
146 | }
|
147 |
|
148 | if (p === '/encoding/gbk') {
|
149 | res.statusCode = 200;
|
150 | res.setHeader('Content-Type', 'text/html');
|
151 | res.end(convert('<meta charset="gbk"><div>中文</div>', 'gbk'));
|
152 | }
|
153 |
|
154 | if (p === '/encoding/gb2312') {
|
155 | res.statusCode = 200;
|
156 | res.setHeader('Content-Type', 'text/html');
|
157 | res.end(convert('<meta http-equiv="Content-Type" content="text/html; charset=gb2312"><div>中文</div>', 'gb2312'));
|
158 | }
|
159 |
|
160 | if (p === '/encoding/shift-jis') {
|
161 | res.statusCode = 200;
|
162 | res.setHeader('Content-Type', 'text/html; charset=Shift-JIS');
|
163 | res.end(convert('<div>日本語</div>', 'Shift_JIS'));
|
164 | }
|
165 |
|
166 | if (p === '/encoding/euc-jp') {
|
167 | res.statusCode = 200;
|
168 | res.setHeader('Content-Type', 'text/xml');
|
169 | res.end(convert('<?xml version="1.0" encoding="EUC-JP"?><title>日本語</title>', 'EUC-JP'));
|
170 | }
|
171 |
|
172 | if (p === '/encoding/utf8') {
|
173 | res.statusCode = 200;
|
174 | res.end('中文');
|
175 | }
|
176 |
|
177 | if (p === '/encoding/order1') {
|
178 | res.statusCode = 200;
|
179 | res.setHeader('Content-Type', 'charset=gbk; text/plain');
|
180 | res.end(convert('中文', 'gbk'));
|
181 | }
|
182 |
|
183 | if (p === '/encoding/order2') {
|
184 | res.statusCode = 200;
|
185 | res.setHeader('Content-Type', 'text/plain; charset=gbk; qs=1');
|
186 | res.end(convert('中文', 'gbk'));
|
187 | }
|
188 |
|
189 | if (p === '/encoding/chunked') {
|
190 | res.statusCode = 200;
|
191 | res.setHeader('Content-Type', 'text/html');
|
192 | res.setHeader('Transfer-Encoding', 'chunked');
|
193 | var padding = 'a';
|
194 | for (var i = 0; i < 10; i++) {
|
195 | res.write(padding);
|
196 | }
|
197 | res.end(convert('<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS" /><div>日本語</div>', 'Shift_JIS'));
|
198 | }
|
199 |
|
200 | if (p === '/encoding/invalid') {
|
201 | res.statusCode = 200;
|
202 | res.setHeader('Content-Type', 'text/html');
|
203 | res.setHeader('Transfer-Encoding', 'chunked');
|
204 |
|
205 | var padding = new Array(120 + 1).join('a');
|
206 | for (var i = 0; i < 10; i++) {
|
207 | res.write(padding);
|
208 | }
|
209 | res.end(convert('中文', 'gbk'));
|
210 | }
|
211 |
|
212 | if (p === '/redirect/301') {
|
213 | res.statusCode = 301;
|
214 | res.setHeader('Location', '/inspect');
|
215 | res.end();
|
216 | }
|
217 |
|
218 | if (p === '/redirect/302') {
|
219 | res.statusCode = 302;
|
220 | res.setHeader('Location', '/inspect');
|
221 | res.end();
|
222 | }
|
223 |
|
224 | if (p === '/redirect/303') {
|
225 | res.statusCode = 303;
|
226 | res.setHeader('Location', '/inspect');
|
227 | res.end();
|
228 | }
|
229 |
|
230 | if (p === '/redirect/307') {
|
231 | res.statusCode = 307;
|
232 | res.setHeader('Location', '/inspect');
|
233 | res.end();
|
234 | }
|
235 |
|
236 | if (p === '/redirect/308') {
|
237 | res.statusCode = 308;
|
238 | res.setHeader('Location', '/inspect');
|
239 | res.end();
|
240 | }
|
241 |
|
242 | if (p === '/redirect/chain') {
|
243 | res.statusCode = 301;
|
244 | res.setHeader('Location', '/redirect/301');
|
245 | res.end();
|
246 | }
|
247 |
|
248 | if (p === '/error/redirect') {
|
249 | res.statusCode = 301;
|
250 |
|
251 | res.end();
|
252 | }
|
253 |
|
254 | if (p === '/error/400') {
|
255 | res.statusCode = 400;
|
256 | res.setHeader('Content-Type', 'text/plain');
|
257 | res.end('client error');
|
258 | }
|
259 |
|
260 | if (p === '/error/404') {
|
261 | res.statusCode = 404;
|
262 | res.setHeader('Content-Encoding', 'gzip');
|
263 | res.end();
|
264 | }
|
265 |
|
266 | if (p === '/error/500') {
|
267 | res.statusCode = 500;
|
268 | res.setHeader('Content-Type', 'text/plain');
|
269 | res.end('server error');
|
270 | }
|
271 |
|
272 | if (p === '/error/reset') {
|
273 | res.destroy();
|
274 | }
|
275 |
|
276 | if (p === '/error/json') {
|
277 | res.statusCode = 200;
|
278 | res.setHeader('Content-Type', 'application/json');
|
279 | res.end('invalid json');
|
280 | }
|
281 |
|
282 | if (p === '/no-content') {
|
283 | res.statusCode = 204;
|
284 | res.end();
|
285 | }
|
286 |
|
287 | if (p === '/no-content/gzip') {
|
288 | res.statusCode = 204;
|
289 | res.setHeader('Content-Encoding', 'gzip');
|
290 | res.end();
|
291 | }
|
292 |
|
293 | if (p === '/not-modified') {
|
294 | res.statusCode = 304;
|
295 | res.end();
|
296 | }
|
297 |
|
298 | if (p === '/not-modified/gzip') {
|
299 | res.statusCode = 304;
|
300 | res.setHeader('Content-Encoding', 'gzip');
|
301 | res.end();
|
302 | }
|
303 |
|
304 | if (p === '/inspect') {
|
305 | res.statusCode = 200;
|
306 | res.setHeader('Content-Type', 'application/json');
|
307 | var body = '';
|
308 | req.on('data', function(c) { body += c });
|
309 | req.on('end', function() {
|
310 | res.end(JSON.stringify({
|
311 | method: req.method,
|
312 | url: req.url,
|
313 | headers: req.headers,
|
314 | body: body
|
315 | }));
|
316 | });
|
317 | }
|
318 |
|
319 | if (p === '/multipart') {
|
320 | res.statusCode = 200;
|
321 | res.setHeader('Content-Type', 'application/json');
|
322 | var parser = new Multipart(req.headers['content-type']);
|
323 | var body = '';
|
324 | parser.on('part', function(field, part) {
|
325 | body += field + '=' + part;
|
326 | });
|
327 | parser.on('end', function() {
|
328 | res.end(JSON.stringify({
|
329 | method: req.method,
|
330 | url: req.url,
|
331 | headers: req.headers,
|
332 | body: body
|
333 | }));
|
334 | });
|
335 | req.pipe(parser);
|
336 | }
|
337 | }
|