Bouncy - Open Source Code Exploration
Tags: github, opensource, node, exploration
Published: 2018-02-22 21:39:40

---
title: "Bouncy - Open Source Code Exploration"
published: true
tags: GitHub,OSS,nodejs,Exploration
canonical_url: https://theopensourceu.org/bouncy-open-source-code-exploration/
---

 ![Bouncy - Open Source Code Exploration](https://theopensourceu.org/content/images/2017/08/code-2620118_1280.jpg)

[Bouncy](https://github.com/substack/bouncy) is a tool to "pipe raw http traffic from [an] incoming http request to a another remote end point."

It's an interesting tool and, for me, a useful find. Not to reveal too much but this site is running on [Node](https://nodejs.org/) among other technologies.

I think this tool has a lot of possible applications<sup><a href="#fn1" id="fnref1">[1]</a></sup> but for me, it acts as a [virtual host](https://en.wikipedia.org/wiki/Virtual_hosting) router. I don't want to go into too much detail here (you can see [here](https://en.wikipedia.org/wiki/Virtual_hosting) for more info) but in my scenario, I wanted to setup my server so that I could host another site on the same server if needed or desired.

[Bouncy](https://github.com/substack/bouncy) allows me to do that; using bouncy I created a small custom program that listens on port 80 (the website port). When it accepts an incoming request it routes it to the correct site which is running on another port (on the same server) -- say 8000 for discussion.

It determines the site via the request host headers (`req.headers.host`).

**Summary of example configuration:**

- Bouncy = Port 80
- The Open Source U = Port 8000
- _Possible_ future sites = Port 8001, 8002, etc

It's a small library (it's available as a CLI tool as well) and I think it's an excellent candidate for a first article. I'm, frankly, curious how it works and it's small enough to sort out the structure of these posts.

For the purpose of this article, I've forked the git repository to [https://github.com/TheOpenSourceU/bouncy](https://github.com/TheOpenSourceU/bouncy)

I'll use and reference this version in this article. Because the parent/source project could continue to be developed, I've created a branch called **[tOSU/explore](https://github.com/TheOpenSourceU/bouncy/tree/tOSU/explore)**. This will remain consistent with this article whereas master can deviate. I want to keep master consistent with the sources' master.

## Technology Prerequisites

I'll do my best to link or explain related technologies and concepts. A principle goal of this site is to engage folks with a diverse backgrounds and experience levels.

That said, I do make some assumptions about a basic familiarity with some technology. At this time, I don't have public comments on this site but should you need to provide critical (respectful) feedback or ask questions, please feel use the [GitHub](https://github.com/TheOpenSourceU/TheOpenSourceU.github.io/issues) issues [located here](https://github.com/TheOpenSourceU/TheOpenSourceU.github.io/issues).

## Index of Dependencies

Knowing and understanding the high-level purpose of a package/programs dependencies is helpful in understanding the parent application.

Bouncy has two main dependencies (for those unfamiliar, this is in the [`package.json`](https://github.com/TheOpenSourceU/bouncy/blob/tOSU/explore/package.json) file.

```
// ...
"dependencies" : {
 "through": "~2.3.4",
 "optimist": "~0.3.5"
},
// ...
```

- [through](https://github.com/dominictarr/through): Creates a stream that is readable and writable.
- [optimist](https://github.com/substack/node-optimist): ([deprecated](https://github.com/substack/node-optimist#deprecation-notice)) is a command line option parser written by the same author as Bouncy.

## index.js

The entry point and frankly the main implementation. Bouncy is built on top of the bog standard NodeJS [http](https://nodejs.org/api/http.html)/[https](https://nodejs.org/api/https.html) library and in a way, simply wraps it. Given it's relationship to `http`/`https`, Bouncy is event driven.

The correct server type is created (secure or not); then three events are assigned handlers. The first is the `connection` _or_ `secureConnection` event which is handled by an anonymous function which we'll call the "connection event handler". The other two events are `upgrade` and `request` which are both assigned `onrequest`.

### Connection Event Handler

This accepts the parameter `stream`. This represents the network stream of data coming in for the request. The handler adds a property called `_bouncyStream` which is the results of stealthBuffer().

The next snippet is the nuts and bolts of the handler.

```
var src = stream._bouncyStream = stealthBuffer();
// ... old version work around ...
else stream.pipe(src);
```

At this point, `stream` is an instance of [Socket](https://nodejs.org/api/net.html#net_class_net_socket) and `src` is an instance of [Stream](https://nodejs.org/api/stream.html). (Notice that despite the name, _stream_ is not _Stream_ -- that capital "S" is important.)

The `src` (Stream) is piped (sent) to the Socket. This completes the set up of the connection. Now, bouncy will wait for incoming requests and through `onrequest`, route them.

### `onrequest`

**This is the main _purpose_ of Bouncy**. This ultimately bounces the request to another port via the `cb` parameter as this is the user implemented code provided as a callback.

Here's the [example](https://github.com/TheOpenSourceU/bouncy/tree/tOSU/explore#routejs) given on the GitHub page.

```
var bouncy = require('bouncy');

var server = bouncy(function (req, res, bounce) {
    if (req.headers.host === 'beep.example.com') {
        bounce(8001);
    }
    else if (req.headers.host === 'boop.example.com') {
        bounce(8002);
    }
    else {
        res.statusCode = 404;
        res.end('no such host');
    }
});
server.listen(8000);
```

The anonymous function passed into the `bouncy` and is called after some setup which is mainly creating the `bounce` method. The end user then calls `bounce` with the appropriate port and said method `pipes` the connection to the new path.

This "bounces" the request to the new port.

### `stealthBuffer()`

`stealthBuffer()` returns an instance of the dependency `through`; recall this provides the means to make a stream readable and writable.

This is ultimately used in the connection event handler. The bottom line is it augments the request for passing it through to the `bounce` method in the `onrequest` handler.

* * *
<section>
<ol>
<li id="fn1">
<p>I'm wondering if Bouncy can be used to load balance the same site on two different instances of NodeJS. I strongly suspect it could and hope to test that soon... <a href="#fnref1">↩︎</a></p>
</li>
</ol>
</section>