1 | var _ = require("underscore")
|
2 | var Sinon = require("sinon")
|
3 | var Net = require("net")
|
4 | var Tls = require("tls")
|
5 | var Http = require("http")
|
6 | var Https = require("https")
|
7 | var Semver = require("semver")
|
8 | var IncomingMessage = Http.IncomingMessage
|
9 | var ServerResponse = Http.ServerResponse
|
10 | var ClientRequest = Http.ClientRequest
|
11 | var EventEmitter = require("events").EventEmitter
|
12 | var Mitm = require("..")
|
13 | var NODE_0_10 = Semver.satisfies(process.version, ">= 0.10 < 0.11")
|
14 |
|
15 | describe("Mitm", function() {
|
16 | beforeEach(function() { Mitm.passthrough = false })
|
17 |
|
18 | it("must return an instance of Mitm when called as a function", function() {
|
19 | var mitm = Mitm()
|
20 | mitm.must.be.an.instanceof(Mitm)
|
21 | mitm.disable()
|
22 | })
|
23 |
|
24 | function mustConnect(module) {
|
25 | describe("as connect", function() {
|
26 | it("must return an instance of Net.Socket", function() {
|
27 | var socket = module.connect({host: "foo", port: 80})
|
28 | socket.must.be.an.instanceof(Net.Socket)
|
29 | })
|
30 |
|
31 | it("must return an instance of Net.Socket given port", function() {
|
32 | module.connect(80).must.be.an.instanceof(Net.Socket)
|
33 | })
|
34 |
|
35 | it("must return an instance of Net.Socket given port and host",
|
36 | function() {
|
37 | module.connect(80, "10.0.0.1").must.be.an.instanceof(Net.Socket)
|
38 | })
|
39 |
|
40 | it("must emit connect on Mitm", function() {
|
41 | var onConnect = Sinon.spy()
|
42 | this.mitm.on("connect", onConnect)
|
43 | var opts = {host: "foo"}
|
44 | var socket = module.connect(opts)
|
45 |
|
46 | onConnect.callCount.must.equal(1)
|
47 | onConnect.firstCall.args[0].must.equal(socket)
|
48 | onConnect.firstCall.args[1].must.equal(opts)
|
49 | })
|
50 |
|
51 | it("must emit connect on Mitm with options object given host and port",
|
52 | function() {
|
53 | var onConnect = Sinon.spy()
|
54 | this.mitm.on("connect", onConnect)
|
55 | var socket = module.connect(9, "127.0.0.1")
|
56 |
|
57 | onConnect.callCount.must.equal(1)
|
58 | onConnect.firstCall.args[0].must.equal(socket)
|
59 | onConnect.firstCall.args[1].must.eql({host: "127.0.0.1", port: 9})
|
60 | })
|
61 |
|
62 | it("must emit connection on Mitm", function() {
|
63 | var onConnection = Sinon.spy()
|
64 | this.mitm.on("connection", onConnection)
|
65 | var opts = {host: "foo"}
|
66 | var socket = module.connect(opts)
|
67 |
|
68 | onConnection.callCount.must.equal(1)
|
69 | onConnection.firstCall.args[0].must.be.an.instanceof(Net.Socket)
|
70 | onConnection.firstCall.args[0].must.not.equal(socket)
|
71 | onConnection.firstCall.args[1].must.equal(opts)
|
72 | })
|
73 |
|
74 | it("must emit connect on socket in next ticks", function(done) {
|
75 | var socket = module.connect({host: "foo"})
|
76 | socket.on("connect", done.bind(null, null))
|
77 | })
|
78 |
|
79 | it("must call back on connect given callback", function(done) {
|
80 | module.connect({host: "foo"}, done.bind(null, null))
|
81 | })
|
82 |
|
83 | it("must call back on connect given port and callback", function(done) {
|
84 | module.connect(80, done.bind(null, null))
|
85 | })
|
86 |
|
87 |
|
88 |
|
89 |
|
90 | it("must call back on connect given port, host and callback",
|
91 | function(done) {
|
92 | module.connect(80, "localhost", done.bind(null, null))
|
93 | })
|
94 |
|
95 | it("must intercept 127.0.0.1", function(done) {
|
96 | var server; this.mitm.on("connection", function(s) { server = s })
|
97 | var client = module.connect({host: "127.0.0.1"})
|
98 | server.write("Hello")
|
99 |
|
100 | client.setEncoding("utf8")
|
101 | client.on("data", function(data) { data.must.equal("Hello") })
|
102 | client.on("data", done.bind(null, null))
|
103 | })
|
104 |
|
105 | describe("when bypassed", function() {
|
106 | beforeEach(function() { this.sinon = Sinon.sandbox.create() })
|
107 | afterEach(function() { this.sinon.restore() })
|
108 |
|
109 | it("must not intercept", function(done) {
|
110 | this.mitm.on("connect", function(client) { client.bypass() })
|
111 |
|
112 | module.connect({host: "127.0.0.1", port: 9}).on("error", function(err) {
|
113 | err.must.be.an.instanceof(Error)
|
114 | err.message.must.include("ECONNREFUSED")
|
115 | done()
|
116 | })
|
117 | })
|
118 |
|
119 | it("must call original module.connect", function() {
|
120 | this.mitm.disable()
|
121 |
|
122 | var connect = this.sinon.spy(module, "connect")
|
123 | var mitm = Mitm()
|
124 | mitm.on("connect", function(client) { client.bypass() })
|
125 |
|
126 | try {
|
127 | module.connect({host: "127.0.0.1", port: 9}).on("error", noop)
|
128 | connect.callCount.must.equal(1)
|
129 | connect.firstCall.args[0].must.eql({host: "127.0.0.1", port: 9})
|
130 | }
|
131 |
|
132 |
|
133 | finally { mitm.disable() }
|
134 | })
|
135 |
|
136 | it("must not call back twice on connect given callback",
|
137 | function(done) {
|
138 | this.mitm.on("connect", function(client) { client.bypass() })
|
139 |
|
140 | var onConnect = Sinon.spy()
|
141 | var client = module.connect({host: "127.0.0.1", port: 9}, onConnect)
|
142 |
|
143 | client.on("error", process.nextTick.bind(null, function() {
|
144 | onConnect.callCount.must.equal(0)
|
145 | done()
|
146 | }))
|
147 | })
|
148 |
|
149 | it("must not emit connection", function() {
|
150 | this.mitm.on("connect", function(client) { client.bypass() })
|
151 | var onConnection = Sinon.spy()
|
152 | this.mitm.on("connection", onConnection)
|
153 | module.connect({host: "127.0.0.1", port: 9}).on("error", noop)
|
154 | onConnection.callCount.must.equal(0)
|
155 | })
|
156 | })
|
157 | })
|
158 | }
|
159 |
|
160 | describe("Net.connect", function() {
|
161 | beforeEach(function() { this.mitm = Mitm() })
|
162 | afterEach(function() { this.mitm.disable() })
|
163 |
|
164 | mustConnect(Net)
|
165 |
|
166 | if (!NODE_0_10)
|
167 | it("must not return an instance of Tls.TLSSocket", function() {
|
168 | var client = Net.connect({host: "foo", port: 80})
|
169 | client.must.not.be.an.instanceof(Tls.TLSSocket)
|
170 | })
|
171 |
|
172 | it("must not set the encrypted property", function() {
|
173 | Net.connect({host: "foo"}).must.not.have.property("encrypted")
|
174 | })
|
175 |
|
176 | it("must not set the authorized property", function() {
|
177 | Net.connect({host: "foo"}).must.not.have.property("authorized")
|
178 | })
|
179 |
|
180 | it("must not emit secureConnect on client", function(done) {
|
181 | var client = Net.connect({host: "foo"})
|
182 |
|
183 | client.on("secureConnect", done.bind(null, null))
|
184 | done()
|
185 | })
|
186 |
|
187 | it("must not emit secureConnect on server", function(done) {
|
188 | var server; this.mitm.on("connection", function(s) { server = s })
|
189 | Net.connect({host: "foo"})
|
190 |
|
191 | server.on("secureConnect", done.bind(null, null))
|
192 | done()
|
193 | })
|
194 |
|
195 | describe("Socket", function() {
|
196 | describe(".prototype.write", function() {
|
197 | it("must write to client from server", function(done) {
|
198 | var server; this.mitm.on("connection", function(s) { server = s })
|
199 | var client = Net.connect({host: "foo"})
|
200 | server.write("Hello")
|
201 |
|
202 | client.setEncoding("utf8")
|
203 | client.on("data", function(data) { data.must.equal("Hello") })
|
204 | client.on("data", done.bind(null, null))
|
205 | })
|
206 |
|
207 | it("must write to client from server in the next tick", function(done) {
|
208 | var server; this.mitm.on("connection", function(s) { server = s })
|
209 | var client = Net.connect({host: "foo"})
|
210 |
|
211 | var ticked = false
|
212 | client.once("data", function() { ticked.must.be.true(); done() })
|
213 | server.write("Hello")
|
214 | ticked = true
|
215 | })
|
216 |
|
217 | it("must write to server from client", function(done) {
|
218 | var server; this.mitm.on("connection", function(s) { server = s })
|
219 | var client = Net.connect({host: "foo"})
|
220 | client.write("Hello")
|
221 |
|
222 | server.setEncoding("utf8")
|
223 | process.nextTick(function() { server.read().must.equal("Hello") })
|
224 | process.nextTick(done)
|
225 | })
|
226 |
|
227 | it("must write to server from client in the next tick", function(done) {
|
228 | var server; this.mitm.on("connection", function(s) { server = s })
|
229 | var client = Net.connect({host: "foo"})
|
230 |
|
231 | var ticked = false
|
232 | server.once("data", function() { ticked.must.be.true(); done() })
|
233 | client.write("Hello")
|
234 | ticked = true
|
235 | })
|
236 |
|
237 |
|
238 |
|
239 | it("must write to server from client given binary", function(done) {
|
240 | var server; this.mitm.on("connection", function(s) { server = s })
|
241 | var client = Net.connect({host: "foo"})
|
242 | client.write("Hello", "binary")
|
243 |
|
244 | server.setEncoding("binary")
|
245 | process.nextTick(function() { server.read().must.equal("Hello") })
|
246 | process.nextTick(done)
|
247 | })
|
248 |
|
249 |
|
250 |
|
251 | if (Semver.satisfies(process.version, ">= 6.4"))
|
252 | it("must write to server from client given latin1", function(done) {
|
253 | var server; this.mitm.on("connection", function(s) { server = s })
|
254 | var client = Net.connect({host: "foo"})
|
255 | client.write("Hello", "latin1")
|
256 |
|
257 | server.setEncoding("latin1")
|
258 | process.nextTick(function() { server.read().must.equal("Hello") })
|
259 | process.nextTick(done)
|
260 | })
|
261 |
|
262 | it("must write to server from client given a buffer", function(done) {
|
263 | var server; this.mitm.on("connection", function(s) { server = s })
|
264 | var client = Net.connect({host: "foo"})
|
265 | client.write(new Buffer("Hello"))
|
266 |
|
267 | server.setEncoding("utf8")
|
268 | process.nextTick(function() { server.read().must.equal("Hello") })
|
269 | process.nextTick(done)
|
270 | })
|
271 |
|
272 | it("must write to server from client given a UTF-8 string",
|
273 | function(done) {
|
274 | var server; this.mitm.on("connection", function(s) { server = s })
|
275 | var client = Net.connect({host: "foo"})
|
276 | client.write("Hello", "utf8")
|
277 |
|
278 | server.setEncoding("utf8")
|
279 | process.nextTick(function() { server.read().must.equal("Hello") })
|
280 | process.nextTick(done)
|
281 | })
|
282 |
|
283 | it("must write to server from client given a ASCII string",
|
284 | function(done) {
|
285 | var server; this.mitm.on("connection", function(s) { server = s })
|
286 | var client = Net.connect({host: "foo"})
|
287 | client.write("Hello", "ascii")
|
288 |
|
289 | server.setEncoding("utf8")
|
290 | process.nextTick(function() { server.read().must.equal("Hello") })
|
291 | process.nextTick(done)
|
292 | })
|
293 |
|
294 | it("must write to server from client given a UCS-2 string",
|
295 | function(done) {
|
296 | var server; this.mitm.on("connection", function(s) { server = s })
|
297 | var client = Net.connect({host: "foo"})
|
298 | client.write("Hello", "ucs2")
|
299 |
|
300 | process.nextTick(function() {
|
301 | server.setEncoding("ucs2")
|
302 | server.read().must.equal("H\u0000e\u0000l\u0000l\u0000o\u0000")
|
303 | done()
|
304 | })
|
305 | })
|
306 | })
|
307 |
|
308 | describe(".prototype.end", function() {
|
309 | it("must emit end when closed on server", function(done) {
|
310 | var server; this.mitm.on("connection", function(s) { server = s })
|
311 | var client = Net.connect({host: "foo"})
|
312 | server.end()
|
313 | client.on("end", done)
|
314 | })
|
315 | })
|
316 |
|
317 | describe(".prototype.ref", function() {
|
318 | it("must allow calling on client", function() {
|
319 | Net.connect({host: "foo"}).ref()
|
320 | })
|
321 |
|
322 | it("must allow calling on server", function() {
|
323 | var server; this.mitm.on("connection", function(s) { server = s })
|
324 | Net.connect({host: "foo"})
|
325 | server.ref()
|
326 | })
|
327 | })
|
328 |
|
329 | describe(".prototype.unref", function() {
|
330 | it("must allow calling on client", function() {
|
331 | Net.connect({host: "foo"}).unref()
|
332 | })
|
333 |
|
334 | it("must allow calling on server", function() {
|
335 | var server; this.mitm.on("connection", function(s) { server = s })
|
336 | Net.connect({host: "foo"})
|
337 | server.unref()
|
338 | })
|
339 | })
|
340 | })
|
341 | })
|
342 |
|
343 | describe("Net.createConnection", function() {
|
344 | beforeEach(function() { this.mitm = Mitm() })
|
345 | afterEach(function() { this.mitm.disable() })
|
346 |
|
347 | it("must be equal to Net.connect", function() {
|
348 | Net.createConnection.must.equal(Net.connect)
|
349 | })
|
350 | })
|
351 |
|
352 | describe("Tls.connect", function() {
|
353 | beforeEach(function() { this.mitm = Mitm() })
|
354 | afterEach(function() { this.mitm.disable() })
|
355 |
|
356 | mustConnect(Tls)
|
357 |
|
358 | if (!NODE_0_10)
|
359 | it("must return an instance of Tls.TLSSocket", function() {
|
360 | Tls.connect({host: "foo", port: 80}).must.be.an.instanceof(Tls.TLSSocket)
|
361 | })
|
362 |
|
363 | if (!NODE_0_10)
|
364 | it("must return an instance of Tls.TLSSocket given port", function() {
|
365 | Tls.connect(80).must.be.an.instanceof(Tls.TLSSocket)
|
366 | })
|
367 |
|
368 | if (!NODE_0_10)
|
369 | it("must return an instance of Tls.TLSSocket given port and host",
|
370 | function() {
|
371 | Tls.connect(80, "10.0.0.1").must.be.an.instanceof(Tls.TLSSocket)
|
372 | })
|
373 |
|
374 | it("must emit secureConnect in next ticks", function(done) {
|
375 | var socket = Tls.connect({host: "foo"})
|
376 | socket.on("secureConnect", done.bind(null, null))
|
377 | })
|
378 |
|
379 | it("must emit secureConnect after connect in next ticks", function(done) {
|
380 | var socket = Tls.connect({host: "foo"})
|
381 |
|
382 | socket.on("connect", function() {
|
383 | socket.on("secureConnect", done.bind(null, null))
|
384 | })
|
385 | })
|
386 |
|
387 | it("must not emit secureConnect on server", function(done) {
|
388 | var server; this.mitm.on("connection", function(s) { server = s })
|
389 | Tls.connect({host: "foo"})
|
390 |
|
391 | server.on("secureConnect", done.bind(null, null))
|
392 | done()
|
393 | })
|
394 |
|
395 | it("must call back on secureConnect", function(done) {
|
396 | var connected = false
|
397 |
|
398 | var client = Tls.connect({host: "foo"}, function() {
|
399 | connected.must.be.true()
|
400 | done()
|
401 | })
|
402 |
|
403 | client.on("connect", function() { connected = true })
|
404 | })
|
405 |
|
406 | it("must set encrypted true", function() {
|
407 | Tls.connect({host: "foo"}).encrypted.must.be.true()
|
408 | })
|
409 |
|
410 | it("must set authorized true", function() {
|
411 | Tls.connect({host: "foo"}).authorized.must.be.true()
|
412 | })
|
413 | })
|
414 |
|
415 | function mustRequest(request) {
|
416 | describe("as request", function() {
|
417 | beforeEach(function() { this.mitm.disable() })
|
418 | beforeEach(function() { this.mitm = Mitm() })
|
419 | afterEach(function() { this.mitm.disable() })
|
420 |
|
421 | it("must return ClientRequest", function() {
|
422 | request({host: "foo"}).must.be.an.instanceof(ClientRequest)
|
423 | })
|
424 |
|
425 | it("must emit connect on Mitm", function() {
|
426 | var onConnect = Sinon.spy()
|
427 | this.mitm.on("connect", onConnect)
|
428 | request({host: "foo"})
|
429 | onConnect.callCount.must.equal(1)
|
430 | })
|
431 |
|
432 | it("must emit connect on Mitm after multiple connections", function() {
|
433 | var onConnect = Sinon.spy()
|
434 | this.mitm.on("connect", onConnect)
|
435 | request({host: "foo"})
|
436 | request({host: "foo"})
|
437 | request({host: "foo"})
|
438 | onConnect.callCount.must.equal(3)
|
439 | })
|
440 |
|
441 | it("must emit connection on Mitm", function() {
|
442 | var onConnection = Sinon.spy()
|
443 | this.mitm.on("connection", onConnection)
|
444 | request({host: "foo"})
|
445 | onConnection.callCount.must.equal(1)
|
446 | })
|
447 |
|
448 | it("must emit connection on Mitm after multiple connections", function() {
|
449 | var onConnection = Sinon.spy()
|
450 | this.mitm.on("connection", onConnection)
|
451 | request({host: "foo"})
|
452 | request({host: "foo"})
|
453 | request({host: "foo"})
|
454 | onConnection.callCount.must.equal(3)
|
455 | })
|
456 |
|
457 | it("must emit request on Mitm", function(done) {
|
458 | var client = request({host: "foo"})
|
459 | client.end()
|
460 |
|
461 | this.mitm.on("request", function(req, res) {
|
462 | req.must.be.an.instanceof(IncomingMessage)
|
463 | req.must.not.equal(client)
|
464 | res.must.be.an.instanceof(ServerResponse)
|
465 | done()
|
466 | })
|
467 | })
|
468 |
|
469 | it("must emit request on Mitm after multiple requests", function(done) {
|
470 | request({host: "foo"}).end()
|
471 | request({host: "foo"}).end()
|
472 | request({host: "foo"}).end()
|
473 | this.mitm.on("request", _.after(3, done.bind(null, null)))
|
474 | })
|
475 |
|
476 | it("must emit socket on request in next ticks", function(done) {
|
477 | var client = request({host: "foo"})
|
478 | client.on("socket", done.bind(null, null))
|
479 | })
|
480 |
|
481 |
|
482 | it("must emit connect after socket event", function(done) {
|
483 | var client = request({host: "foo"})
|
484 |
|
485 | client.on("socket", function(socket) {
|
486 | socket.on("connect", done.bind(null, null))
|
487 | })
|
488 | })
|
489 |
|
490 | describe("when bypassed", function() {
|
491 | it("must not intercept", function(done) {
|
492 | this.mitm.on("connect", function(client) { client.bypass() })
|
493 | request({host: "127.0.0.1"}).on("error", function(err) {
|
494 | err.must.be.an.instanceof(Error)
|
495 | err.message.must.include("ECONNREFUSED")
|
496 | done()
|
497 | })
|
498 | })
|
499 |
|
500 | it("must not emit request", function(done) {
|
501 | this.mitm.on("connect", function(client) { client.bypass() })
|
502 | var onRequest = Sinon.spy()
|
503 | this.mitm.on("request", onRequest)
|
504 | request({host: "127.0.0.1"}).on("error", function(err) {
|
505 | onRequest.callCount.must.equal(0)
|
506 | done()
|
507 | })
|
508 | })
|
509 | })
|
510 | })
|
511 | }
|
512 |
|
513 | describe("via Http.request", function() {
|
514 | mustRequest(Http.request)
|
515 | })
|
516 |
|
517 | describe("via Https.request", function() {
|
518 | beforeEach(function() { this.mitm = Mitm() })
|
519 | afterEach(function() { this.mitm.disable() })
|
520 |
|
521 | mustRequest(Https.request)
|
522 |
|
523 |
|
524 | it("must emit secureConnect after socket event", function(done) {
|
525 | var client = Https.request({host: "foo"})
|
526 |
|
527 | client.on("socket", function(socket) {
|
528 | socket.on("secureConnect", done.bind(null, null))
|
529 | })
|
530 | })
|
531 | })
|
532 |
|
533 | describe("via Http.Agent", function() {
|
534 | mustRequest(function(opts) {
|
535 | return Http.request(_.extend({agent: new Http.Agent}, opts))
|
536 | })
|
537 | })
|
538 |
|
539 | describe("via Https.Agent", function() {
|
540 | mustRequest(function(opts) {
|
541 | return Https.request(_.extend({agent: new Https.Agent}, opts))
|
542 | })
|
543 | })
|
544 |
|
545 | describe("IncomingMessage", function() {
|
546 | beforeEach(function() { this.mitm = Mitm() })
|
547 | afterEach(function() { this.mitm.disable() })
|
548 |
|
549 | it("must have URL", function(done) {
|
550 | Http.request({host: "foo", path: "/foo"}).end()
|
551 |
|
552 | this.mitm.on("request", function(req) {
|
553 | req.url.must.equal("/foo")
|
554 | done()
|
555 | })
|
556 | })
|
557 |
|
558 | it("must have headers", function(done) {
|
559 | var req = Http.request({host: "foo"})
|
560 | req.setHeader("Content-Type", "application/json")
|
561 | req.end()
|
562 |
|
563 | this.mitm.on("request", function(req) {
|
564 | req.headers["content-type"].must.equal("application/json")
|
565 | done()
|
566 | })
|
567 | })
|
568 |
|
569 | it("must have body", function(done) {
|
570 | var client = Http.request({host: "foo", method: "POST"})
|
571 | client.write("Hello")
|
572 |
|
573 | this.mitm.on("request", function(req, res) {
|
574 | req.setEncoding("utf8")
|
575 | req.on("data", function(data) { data.must.equal("Hello"); done() })
|
576 | })
|
577 | })
|
578 |
|
579 | it("must have a reference to the ServerResponse", function(done) {
|
580 | Http.request({host: "foo", method: "POST"}).end()
|
581 | this.mitm.on("request", function(req, res) { req.res.must.equal(res) })
|
582 | this.mitm.on("request", done.bind(null, null))
|
583 | })
|
584 | })
|
585 |
|
586 | describe("ServerResponse", function() {
|
587 | beforeEach(function() { this.mitm = Mitm() })
|
588 | afterEach(function() { this.mitm.disable() })
|
589 |
|
590 | it("must respond with status, headers and body", function(done) {
|
591 | this.mitm.on("request", function(req, res) {
|
592 | res.statusCode = 442
|
593 | res.setHeader("Content-Type", "application/json")
|
594 | res.end("Hi!")
|
595 | })
|
596 |
|
597 | Http.request({host: "foo"}).on("response", function(res) {
|
598 | res.statusCode.must.equal(442)
|
599 | res.headers["content-type"].must.equal("application/json")
|
600 | res.setEncoding("utf8")
|
601 | res.once("data", function(data) { data.must.equal("Hi!"); done() })
|
602 | }).end()
|
603 | })
|
604 |
|
605 | it("must have a reference to the IncomingMessage", function(done) {
|
606 | Http.request({host: "foo", method: "POST"}).end()
|
607 | this.mitm.on("request", function(req, res) { res.req.must.equal(req) })
|
608 | this.mitm.on("request", done.bind(null, null))
|
609 | })
|
610 |
|
611 | describe(".prototype.write", function() {
|
612 | it("must make clientRequest emit response", function(done) {
|
613 | var req = Http.request({host: "foo"})
|
614 | req.end()
|
615 | this.mitm.on("request", function(req, res) { res.write("Test") })
|
616 | req.on("response", done.bind(null, null))
|
617 | })
|
618 |
|
619 |
|
620 |
|
621 | it("must call given callback", function(done) {
|
622 | Http.request({host: "foo"}).end()
|
623 | this.mitm.on("request", function(req, res) { res.write("Test", done) })
|
624 | })
|
625 | })
|
626 |
|
627 | describe(".prototype.end", function() {
|
628 | it("must make ClientRequest emit response", function(done) {
|
629 | var client = Http.request({host: "foo"})
|
630 | client.end()
|
631 | this.mitm.on("request", function(req, res) { res.end() })
|
632 | client.on("response", done.bind(null, null))
|
633 | })
|
634 |
|
635 |
|
636 |
|
637 |
|
638 | it("must make IncomingMessage emit end", function(done) {
|
639 | var client = Http.request({host: "foo"})
|
640 | client.end()
|
641 | this.mitm.on("request", function(req, res) { res.end() })
|
642 |
|
643 | client.on("response", function(res) {
|
644 | res.on("data", noop)
|
645 | res.on("end", done)
|
646 | })
|
647 | })
|
648 | })
|
649 | })
|
650 |
|
651 | describe(".prototype.addListener", function() {
|
652 | it("must be an alias to EventEmitter.prototype.addListener", function() {
|
653 | Mitm.prototype.addListener.must.equal(EventEmitter.prototype.addListener)
|
654 | })
|
655 | })
|
656 |
|
657 | describe(".prototype.off", function() {
|
658 | it("must be an alias to EventEmitter.prototype.removeListener", function() {
|
659 | Mitm.prototype.off.must.equal(EventEmitter.prototype.removeListener)
|
660 | })
|
661 | })
|
662 | })
|
663 |
|
664 | function noop() {}
|