Skip to content

lukaszraczylo/router

 
 

Repository files navigation

router

This is a HTTP reverse proxy router built on top of triemux. It loads a routing table into memory from a MongoDB database and acts as a:

  • Reverse proxy, forwarding requests to and serving responses from multiple backend servers on a single domain.
  • Redirector, serving HTTP 301 and 302 redirects to new URLs.
  • Gone responder, serving HTTP 410 responses for resources that used to but no longer exist.

The sister project router-api provides a read/write interface to the underlying database and route reloading.

Environment assumptions

Our usage of router places it behind and in front of Nginx and/or Varnish.

As such, there are some things that we are guarded against:

  • Response buffering for slow clients
  • Basic request sanitisation

And some features that we have no need to implement:

  • Access logging (but error logging is implemented)
  • SSL
  • Health check probes
  • Custom header mangling
  • Response rewriting
  • Authentication

Dependencies

This project uses gom to manage it's dependencies. If you have a working Go development setup, you should be able to install gom by running:

go install github.com/mattn/gom

Build

Once you have gom installed, you should be able to run:

make
./router -h

Tests

You can run all tests by running:

make test

The trie and triemux sub-packages have unit tests and benchmarks written in Go's own testing framework. To run them individually:

gom test -bench=. ./trie ./triemux

The router itself doesn't really benefit from having unit tests around individual functions. Instead it has a comprehensive set of integration tests to exercise it's HTTP handling, error reporting, and performance.

These require a local MongoDB instance and can be run with:

gom test ./integration_tests

Some of the integration tests are optional because they have certain environment requirements that make them unfeasible to run within CI.

Data structure

The Router requires two MongoDB collections: routes and backends.

Routes

The routes collection uses the following data structure:

{
  "_id"           : ObjectId(),
  "route_type"    : ["prefix","exact"],
  "incoming_path" : "/url-path/here",
  "handler"       : ["backend", "redirect", "gone"],
}

Incoming paths with special characters must be in their % encoded form in the database (eg spaces must be stored as %20).

The behaviour is determined by handler. See below for extra fields corresponding to handler types.

backend handler

The backend handler causes the Router to reverse proxy to a named backend. The following extra fields are supported:

{
  "backend_id" : "backend-id-corresponding-to-backends-collection"
}

redirect handler

The redirect handler causes the Router to redirect the given incoming_path to the path stored in redirect_to. The following extra fields are supported:

{
  "redirect_to"   : "/target-of-redirect",
  "redirect_type" : ["permanent", "temporary"]
}

gone handler

The gone handler causes the Router to return a 410 response.

Backends

The backends collection uses the following data structure:

{
  "_id"         : ObjectId(),
  "backend_id"  : "arbitrary-slug-or-name",
  "backend_url" : "https://example.com:port/"
}

License

router is released under the MIT license, a copy of which can be found in LICENSE.

Packages

No packages published

Languages

  • Go 98.3%
  • Other 1.7%