UNPKG

7.61 kBMarkdownView Raw
1Mitm.js
2=======
3[![NPM version][npm-badge]](http://badge.fury.io/js/mitm)
4[npm-badge]: https://badge.fury.io/js/mitm.png
5
6Mitm.js is a library for Node.js to **intercept and mock** network **TCP** and
7**HTTP** connections. Mitm.js intercepts and gives you a `Net.Socket` to
8communicate as if you were the remote server. For **HTTP requests** it even
9gives you `Http.IncomingMessage` and `Http.ServerResponse` — just like you're
10used to when writing Node.js servers. Except there's no actual server running,
11it's all just _In-Process Interception™_.
12
13Intercepting connections and requests is **extremely useful to test and ensure
14your code does what you expect**. Assert on request parameters and send back
15various responses to your code without ever having to hit the real network.
16**Fast as hell** and **a lot easier to develop with than external test
17servers**.
18
19Mitm.js should work both on the stable Node **v0.10.24** and up and **v0.11.11**
20and up and has **automated tests** to ensure it will stay that way.
21
22**Note**: This is a fairly early release of Mitm.js, so it might not cover all
23use cases you may come across. I've developed this on a need-to basis for
24testing [Monday Calendar][monday]'s syncing, so if you find a use-case I haven't
25come across, please fling me an [email][email], a [tweet][twitter] or [create an
26issue][issues] on GitHub.
27
28### Tour
29- Intercept both **TCP socket connections** (`Net.connect`) and **HTTP
30 requests** (`Http.request` and `Https.request`).
31
32- Hooks to Node.js's network functions at a **very low level** with the goal of
33 not having to patch existing classes and have everything behave as if bytes
34 were arriving from the network.
35
36- Does *not* have any kitchen sink features or yet another API to assert on
37 intercepted connections.
38 That's a different responsibility handled better by assertion libraries
39 (you'll do no better than to pick [Must.js][must] for that ;-).
40
41- Use an **API you already to know** to assert or respond to requests — Mitm.js
42 gives you access to a vanilla `Net.Socket` to respond with:
43
44 ```javascript
45 mitm.on("connection", function(socket) { socket.write("Hello back!") })
46
47 var socket = Net.connect(22, "example.org")
48 socket.write("Hello!")
49 socket.setEncoding("utf8")
50 socket.read() // => "Hello back!"
51 ```
52
53- When you do **HTTP or HTTPS** requests, Mitm.js gives you both
54 a `Http.IncomingMessage` and `Http.ServerResponse` to play the server with.
55 That means you'll be using an **API you're already familiar with**
56 rather than yet another idiosyncratic domain specific language.
57
58 Mitm.js comes very handy to ensure your code makes requests with the
59 appropriate parameters:
60 ```javascript
61 mitm.on("request", function(req, res) {
62 req.headers.authorization.must.equal("OAuth DEADBEEF")
63 })
64
65 Http.get("http://example.org")
66 ```
67
68 It's also useful to see if your code behaves as you'd expect if everything is
69 not `200 OK`:
70 ```javascript
71 mitm.on("request", function(req, res) {
72 res.statusCode = 402
73 res.end("Pay up, sugar!")
74 })
75
76 Http.get("http://example.org", function(res) {
77 res.setEncoding("utf8")
78 res.statusCode // => 402
79 res.on("data", console.log) // => "Pay up, sugar!"
80 })
81 ```
82
83 `Http.IncomingMessage` and `Http.ServerResponse` are the same objects
84 you get when you write Node.js HTTP servers with `Net.Server` or use a library
85 like [Express.js][express].
86
87- **Developed with automated tests**. Yeah, I know, why should one list this
88 a feature when writing tests is just a sign of professionalism and respect
89 towards other developers? But in a world where so many libraries and
90 "production" software are released without *any* tests, I like to point out
91 that I even write tests for testing libraries. ;-)
92
93[must]: https://github.com/moll/js-must
94[express]: http://expressjs.com
95
96
97Installing
98----------
99```
100npm install mitm
101```
102
103From v1.0.0 Mitm.js will follow [semantic versioning][semver], but until then,
104breaking changes may appear between minor versions (the middle number).
105
106[semver]: http://semver.org/
107
108
109Using
110-----
111Require Mitm.js and invoke it as a function to both create an instance of `Mitm`
112and enable intercepting:
113```javascript
114var Mitm = require("mitm")
115var mitm = Mitm()
116```
117
118Mitm.js will then intercept all requests until you disable it:
119```javascript
120mitm.disable()
121```
122
123### Intercepting in tests
124In tests, it's best to use the _before_ and _after_ hooks to enable and disable
125intercepting for each test case:
126```javascript
127beforeEach(function() { this.mitm = Mitm() })
128afterEach(function() { this.mitm.disable() })
129```
130
131### Intercepting TCP connections
132After you've called `Mitm()`, Mitm.js will intercept and emit `connection` on
133itself for each new connection.
134The `connection` event will be given a server side `Net.Socket` for you to reply
135with:
136
137```javascript
138mitm.on("connection", function(socket) { socket.write("Hello back!") })
139
140var socket = Net.connect(22, "example.org")
141socket.write("Hello!")
142socket.setEncoding("utf8")
143socket.read() // => "Hello back!"
144```
145
146### Intercepting HTTP/HTTPS requests
147After you've called `Mitm()`, Mitm.js will intercept and emit `request` on itself for each new HTTP or HTTPS request.
148The `request` event will be given a server side `Http.IncomingMessage` and
149`Http.ServerResponse`.
150
151For example, asserting on HTTP requests would look something like this:
152```javascript
153mitm.on("request", function(req, res) {
154 req.headers.authorization.must.equal("OAuth DEADBEEF")
155})
156
157Http.get("http://example.org")
158```
159
160Responding to requests is just as easy and exactly like you're used to from
161using Node.js HTTP servers (or from libraries like [Express.js][express]):
162```javascript
163mitm.on("request", function(req, res) {
164 res.statusCode = 402
165 res.end("Pay up, sugar!")
166})
167
168Http.get("http://example.org", function(res) {
169 res.statusCode // => 402
170 res.setEncoding("utf8")
171 res.on("data", console.log) // => "Pay up, sugar!"
172})
173```
174
175Please note that HTTPS requests are currently "morphed" into HTTP requests.
176That's to save us from having to set up certificates and disable their
177verification. But if you do need to test this, please ping me and we'll see if
178we can get Mitm.js to support that.
179
180
181Events
182------
183All events that Mitm will emit on an instance of itself (see [Using
184Mitm.js](#using) for examples):
185
186Event | Description
187-----------|------------
188connect | Emitted when a TCP connection is made.<br> Given the client side `Net.Socket`.
189connection | Emitted when a TCP connection is made.<br> Given the server side `Net.Socket`.
190request | Emitted when a HTTP/HTTPS request is made.<br> Given the server side `Http.IncomingMessage` and `Http.ServerResponse`.
191
192
193License
194-------
195Mitm.js is released under a *Lesser GNU Affero General Public License*, which
196in summary means:
197
198- You **can** use this program for **no cost**.
199- You **can** use this program for **both personal and commercial reasons**.
200- You **do not have to share your own program's code** which uses this program.
201- You **have to share modifications** (e.g. bug-fixes) you've made to this
202 program.
203
204For more convoluted language, see the `LICENSE` file.
205
206
207About
208-----
209**[Andri Möll][moll]** typed this and the code.
210[Monday Calendar][monday] supported the engineering work.
211
212If you find Mitm.js needs improving, please don't hesitate to type to me now
213at [andri@dot.ee][email] or [create an issue online][issues].
214
215[email]: mailto:andri@dot.ee
216[issues]: https://github.com/moll/js-mitm/issues
217[moll]: http://themoll.com
218[monday]: https://mondayapp.com
219[twitter]: https://twitter.com/theml