Add GetDescendants to DocumentStore API

You can read and write pages in Goose, but there's no way to discover
pages (ie to find what pages exist). Search is the main way to do this
on the modern internet, but it's also useful to have page lists.

Search is a future problem for Goose to tackle, but listing pages is a
simpler one. The first thing we need to implement this feature is a
DocumentStore method to get those pages. That's where GetDescendants
comes into the picture.
Add GetDescendants tests

Of course, these tests will fail at the moment. We'll fix them shortly.
Implement GetDescendants for FileDocumentStore

Having to walk the whole file tree is a bit inconvenient, but it's
unavoidable, since we don't know what subdirectories exist until we walk
into them.
Implement GetDescendants for SqlDocumentStore

This query is about as simple as it gets. The string pattern is anchored
at the start, so it does hit the index.
Refactor controller preprocessing

This preprocessing will be useful for other handlers, such as the one
I'm about to write, so I want it moved into a place where it can be
reused.
Implement /l route

This provides a basic route for GetDescendants. It just dumps all the
descendants of /w/foo/bar onto /l/foo/bar.