Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The new routing table #52

Open
tailhook opened this issue Aug 29, 2017 · 2 comments
Open

The new routing table #52

tailhook opened this issue Aug 29, 2017 · 2 comments
Milestone

Comments

@tailhook
Copy link
Collaborator

tailhook commented Aug 29, 2017

Motivation

Currently, we have two tables matching urls routing and authorization, let's take an example [1]:

routing:
  example.org: main
  example.org/admin: admin
  example.org/admin/metrics: metrics

authorization:
  example.org/admin: internal_zone

The motivation was: if you need to specify authorization info in the handler, it's easy to omit it for child route and get a security issue. On the other hand, we can't introduce inheritance between handlers, like nginx does, because they are of very different types and we would need very complex rules of which settings are inherited between handlers when matching down the tree and which do not inherit.

In reality, we need more things that can be either inherited or not, and don't depend on a handler. Here is a list of all things we think could potentially have their own routing table:

  1. Handlers
  2. Authorization
  3. Request rate limits (i.e, DoS protection, not implemented yet, but is planned)
  4. Access logs (and maybe error logs too)
  5. Error pages, and also maintenance page (which is basically a 50x error page)

Another point is: we need a compact and comprehensible routing table, i.e. the bad example [2]:

routing:
  example.org:
    handler: main
    authorization: no-auth
    access-logs: example-org-logs
    error-pages: example-error-pages
  example.org/admin:
    handler: admin
    authorization: admin-auth
    access-logs: example-org-logs
    error-pages: example-error-pages
  example.org/admin/metrics:
    handler: admin-metrics
    authorization: admin-auth
    access-logs: example-org-logs
    error-pages: example-error-pages

Few routes take a screenful of text, while in the real sites there are much more of them. Even if text editors can collapse mapping keys for you, they also hide important information.

Transposition isn't super-useful too, let's look at another bad example [3]:

routing:
  example.org: main
  example.org/admin: admin
  example.org/admin/metrics: metrics
authorization:
  example.org: main
  example.org/admin: admin
logging:
  example.org: main
  example.org/admin: admin
error-pages:
  example.org: main
  example.org/admin: admin

While it's quite good for small table, but it scales too bad for multi-site installations.

Another alternative would be to introduce two-level table, here is another bad example [4]:

routing:
  example.org:
    error-pages: example-log
    log: example-log
    child-routes:
      /: root-handler
      /admin: admin-handler

While at a glance this introduces short and comprehensible routing table, in which each site has their own settings, which also allows putting that section into another file, still it has shortcomings both
ways:

  1. Not all sites depend on domain so much, an application can span multiple and potentially infinite
    number of domains
  2. Many sites have "subsites" hosted in a folder rather than different domain. I.e the /admin section in the first example is actually another site (i.e. it has another handler, error pages, logs, access control and rate limits)

Specification

So the idea is to create small DSL for making routing table compact:

routing:
  example.org: main->example-org-log errors=admin-err
  example.org/admin: admin@admin->example-admin-log
  example.org/admin/metrics: metrics

DSL looks like:

  1. Adding @something to the name of the handler uses the authorizer something for the route and all the enclosed routes
  2. Adding ->something uses logger named something for the route and all enclosed routes
  3. Error pages are marked as errors=something as probably will be overridden more sparingly

Notes:

  1. errors= syntax is extensible to xx=yy but we don't plan to add anything more here yet
  2. Handlers are still not inherited, as they are most crucial part of routing table
  3. Authorization routes and DoS protection domains are combined under a single @something umbrella, we think they are integrated quite close
  4. All names of loggers, authorizers, handlers and error-page domains are defined in their own sections. The function of the routing table is to show where routing does change, rather than provide full details.

Unsolved Problems

Sometimes unauthorized users should be presented different route than authorized. Currently we presume that it's application's problem, rather than the one of a frontend server.

/cc @popravich, @anti-social

@tailhook tailhook added this to the v0.7.0 milestone Aug 29, 2017
@popravich
Copy link
Collaborator

So the idea is to create small DSL

Ouch, it looks creepy at the first sight...

@tailhook
Copy link
Collaborator Author

tailhook commented Sep 5, 2017

So the idea is to create small DSL

Ouch, it looks creepy at the first sight...

So what are the alternatives? All ones mentioned in "motivation" section are clearly worse than this one. The nginx and caddy are basically example [2]. While linkerd has basically a mapping between a routing table and handler written as a weird DSL for rewrite rules (but note that linkerd has only proxying so it doesn't have our auth-rate-limit-error-page dilemma, and has access log only at granularity of protocol level as far as I can see).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants