6210ed56e7
Query params were not included when using the "/_/" prefix for farside links. This extracts the logic for parsing query params into a function that is then used for both /_/ and non-/_/ links. |
||
---|---|---|
.github/workflows | ||
config | ||
img | ||
lib | ||
test | ||
.formatter.exs | ||
.gitignore | ||
index.eex | ||
LICENSE | ||
mix.exs | ||
mix.lock | ||
README.md | ||
route.eex | ||
services.json |
A redirecting service for FOSS alternative frontends.
Farside provides links that automatically redirect to working instances of privacy-oriented alternative frontends, such as Nitter, Libreddit, etc. This allows for users to have more reliable access to the available public instances for a particular service, while also helping to distribute traffic more evenly across all instances and avoid performance bottlenecks and rate-limiting.
Demo
Farside's links work with the following structure: farside.link/<service>/<path>
For example:
Service | Page | Farside Link |
---|---|---|
Libreddit | /r/popular | https://farside.link/libreddit/r/popular |
Teddit | /r/popular | https://farside.link/teddit/r/popular |
Nitter | User Profile | https://farside.link/nitter/josevalim |
Invidious | Home Page | https://farside.link/invidious |
Piped | Video Page | https://farside.link/piped/watch?v=eBGIQ7ZuuiU |
Bibliogram | User Profile | https://farside.link/bibliogram/u/kbdfans |
Whoogle | Search "Elixir" | https://farside.link/whoogle/search?q=elixir&lang_interface=en |
SearX | Search "Redis" | https://farside.link/searx/search?q=redis |
SearXNG | Search "EFF" | https://farside.link/searxng/search?q=EFF |
SimplyTranslate | Translate "hola" | https://farside.link/simplytranslate/?engine=google&text=hola |
Lingva | Translate "bonjour" | https://farside.link/lingva/auto/en/bonjour |
Rimgo | View photo album | https://farside.link/rimgo/a/H8M4rcp |
Scribe | View Medium post | https://farside.link/scribe/@ftrain/big-data-small-effort-b62607a43a8c |
Farside also accepts URLs to "parent" services, and will redirect to an appropriate front end service, for example:
- https://farside.link/https://www.youtube.com/watch?v=dQw4w9WgXcQ will redirect to a Piped or Invidious instance
- https://farside.link/reddit.com/r/popular will redirect to a Libreddit or Teddit instance
- etc.
How It Works
The app runs with an internally scheduled cron task that queries all instances for services defined in services.json every 5 minutes. For each instance, as long as the instance takes <5 seconds to respond and returns a successful response code, the instance is added to a list of available instances for that particular service. If not, it is discarded until the next update period.
Farside's routing is very minimal, with only the following routes:
/
- The app home page, displaying all live instances for every service
/ping
- A passthrough "ping" to redis to ensure both app and redis are working
/:service/*glob
- The main endpoint for redirecting a user to a working instance of a particular service with the specified path
- Ex:
/libreddit/r/popular
would navigate to<libreddit instance URL>/r/popular
- If the service provided is actually a URL to a "parent" service (i.e. "youtube.com" instead of "piped" or "invidious"), Farside will determine the correct frontend to use for the specified URL.
- Note that a path is not required.
/libreddit
for example will still redirect the user to a working libreddit instance
/_/:service/*glob
- Achieves the same redirect as the main
/:service/*glob
endpoint, but preserves a short landing page in the browser's history to allow quickly jumping between instances by navigating back. - Ex:
/_/nitter
-> nitter instance A -> (navigate back one page) -> nitter instance B -> ... - Note: Uses Javascript to preserve the page in history
- Achieves the same redirect as the main
When a service is requested with the /:service/...
endpoint, Farside requests
the list of working instances from Redis and returns a random one from the list
and adds that instance as a new entry in Redis to remove from subsequent
requests for that service. For example:
A user navigates to /nitter
and is redirected to nitter.net
. The next user
to request /nitter
will be guaranteed to not be directed to nitter.net
, and
will instead be redirected to a separate (random) working instance. That
instance will now take the place of nitter.net
as the "reserved" instance, and
nitter.net
will be returned to the list of available Nitter instances.
This "reserving" of previously chosen instances is performed in an attempt to ensure better distribution of traffic to available instances for each service.
Farside also has built-in IP ratelimiting for all requests, enforcing only one request per second per IP.
Development
- Install redis
- Install elixir
- (on Debian systems) Install erlang-dev
- Start redis:
redis-server
- Install dependencies:
mix deps.get
- Initialize redis contents:
mix run -e Farside.Instances.sync
- Run Farside:
mix run --no-halt
- Uses localhost:4001
Environment Variables
Name | Purpose |
---|---|
FARSIDE_TEST | If enabled, bypasses the instance availability check and adds all instances to the pool. |