Skip to content

Serving Assets

Brian Graham edited this page Jul 19, 2020 · 1 revision

In general there are three options for hosting assets:

  1. Use a CDN
  2. Serve from another web server
  3. Introduce an asset controller (not recommended).

Use a CDN

The simplest way to host assets is by uploading them to a CDN which will typically be less expensive than hosting the files on a webserver itself (because you don't have to pay for all the idle time).

There are a number of CDNs that can be found with a simple websearch with various costs and features. Assets can be directly referenced from the templates in One-Time-Secret. It would be a best-practice to prefix your assets with an envvar that lets you easily switch between development and production mode for asset loading.

Serve from another web server

You can set up a server like Nginx or Apache to stand in front of all request. Infact, you should do this any time you're self-hosting as servers like nginx are much better and dealing with encryption (also known as HTTPS, SSL, or TLS).

                                  +------------+
                                  |            |
                                  |   NodeJS   |
+--------+       +----------+     |            |
|        |       |          +---->-------------+
| Client +------>+  Nginx   |
|        |       |          +---->-------------+
+--------+       +----------+     |            |
                                  | Filesystem |
                                  |            |
                                  +------------+

Depending on the URL of a resource, nginx can either serve an asset from the filesystem, or forward the request to NodeJS which will deal with all of the one-time-secret logic.

Introduce an asset controller (not recommended).

You may also introduce a new controller which can serve files from the filesystem on the NodeJS host.

I don't encourage this because:

  1. Each file type will need different HTTP headers. You can solve this by doing a lot of work yourself, or installing a package. But if you install packages, you increase the amount of third-party-code running on your server.
  2. It's really easy to make a small mistake with programming this. If you get into sending files directly, the opportunities for an attacker will increase. For example, you may wish to only expose files under ./assets, so you write the code: fs.readFile('./assets' . filePath, 'binary'); , but an attacker will make filePath equal to ../../../../path_to_private__key.pem. There's a lot of tiny problems you can miss with knowing it. I don't encourage this option.

Nevertheless, you would need to do two things:

  1. Add a general route to src/WebControllers/router.ts, something like /assets.
  2. Add a controller under src/WebControllers, something like AssetController which will open files from the filesystem and forward them to the response object.
Clone this wiki locally