# RushLink A URL shortener and (maybe) a pastebin server for our #ru community. ## Libraries Use standard-Go-libraries if the job can be done with those. As of now, these are the exceptions: - `github.com/gorilla/mux` provides useful stuff for routing requests. - `github.com/gorilla/sessions` for session management. - `go.etcd.io/bbolt` is our database driver. - `github.com/joomcode/errorx` provides a [`Decorate`] function. This dependency will be dropped when [`errors.Wrap`] is properly supported. [`Decorate`]: https://godoc.org/github.com/joomcode/errorx#Decorate [`errors.Wrap`]: https://godoc.org/github.com/pkg/errors#Wrap ## Database We will be using [`go.etcd.io/bbolt`]. This file should be the *only* file apart from our monolithic binary. All settings and keys should go in here. Any read-only data resides in the binary file (possibly compressed). [`go.etcd.io/bbolt`]: `go.etcd.io/bbolt` ## Namespacing All shortened URLs exist as a key on the root of the webserver, i.e. `/xd42`. That means that we have to separate every other page with some kind of namespace. Ideas: - `/z/` reserved for flat pages. - `/p/` reserved for "pastes". - `/u/` reserved for "users". - `/f/` reserved for "files". - `/z/static/` reserved for "static files". ## Shorten keys and collisions For the first version of the keys, we will use 3 bytes encoded as base64url, as described in [RFC4648, par. 5]. To allow for truncate-resistant upgrading of the URL key format, the first bit is set to `0`. That means the first base64 character will always be in `[A-Za-f]`. This domain contains `8388608` values. If the service is somewhat used, we will get collisions early when we generate those keys at random. Instead, we will use format-preserving-encryption to construct a counter that visits every value in an unpredictable order. Daan will fix this. [RFC4648, par. 5]: https://tools.ietf.org/html/rfc4648#section-5 ## UI design As is tradition in a lot of URL-shortener/pastebin-like services, we will put everything in a single `
` tag, and if possible, just serve `text/plain`.
A good example is .

The reason we would use `text/html` instead of `text/plain` is basically
form submissions and JavaScript. Our main API should be cURL, but it would be
useful if users could also use the website and/or drag-and-drop files and URLs.

On the other hand, using `text/plain` saves us *so much effort*, because we
don't have to do any HTML/CSS/JavaScript. We have native terminal support, etc.

The best thing would probably to do both, and correctly listen to the `Accept`
header that the client sends. We can still wrap the plain-text page in a single
`
` to keep it easy for ourselves.

## Retention

- If we can, we don't want to have user accounts. We store the sessions
  forever, and store a user's data in there, without having to collect personal
  data in any way.
- URL-shortening links will be retained for always, unless the submitter
  revokes it, in which case it will be replaced by a `410 Gone` page*.
- The probles of pastes are not solved. This is an unsolved problem*.

* In any case, we going to comply with all European laws and reasonable
  requests for deletion.

## Privacy

We will try as hard as possible to not store any data about our users, and will
only provide any data when we have the legal obligation to do so.