Modifier une URL avec un middleware Traefik

J’héberge sur mon réseau le projet Redlib. Celui-ci est un remplacement du frontend de Reddit afin de rendre le site davantage utilisable quand on ne souhaite pas créer un compte sur cette plateforme.

L’idée principale du projet est qu’on peut s’abonner à des contenus sans avoir besoin d’être connecté. On peut ainsi tout explorer depuis RedLib. On peut aussi rechercher directement une page à partir de l’URL officielle dans l’UI de Redlib.

Si on veut atteindre directement une page à partir de l’URL originale, il faut modifier le domaine. Par exemple, au lieu de

https://www.reddit.com/r/RedditAlternatives/comments/1bccb7p/guys_i_found_the_solution/

on utilise

https://son-domaine-redlib.com/r/RedditAlternatives/comments/1bccb7p/guys_i_found_the_solution/

Cette dernière approche est cependant peu pratique avec le clavier d’un smartphone, et j’ai voulu pouvoir faire comme avec le très pratique https://archive.ph/ : pouvoir coller l’URL complète derrière mon domaine redlib, telle que

https://son-domaine-redlib.com/https://www.reddit.com/r/RedditAlternatives/comments/1bccb7p/guys_i_found_the_solution/

Malheureusement ce n’est pas supporté pour le moment (c’est tellement évident que je pense que ça finira par se faire dans le futur).

Comme j’héberge Redlib sur mon cluster Kubernetes, avec une IngressRoute Traefik, il est très simple d’ajouter un middleware replacePathRegex pour simplement retirer /https://www.reddit.com du préfixe d’URL.

Voici les deux manifestes pour l’IngressRoute et le Middleware:


apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: redlib-ingress-https
  namespace: redlib
spec:
  entryPoints:
    - websecure
  routes:
  - match: Host(`redlib.my-domain.com`)
    kind: Rule
    middlewares:
    - name: replacepathregex-reddit
    services:
    - name: redlib-service
      namespace: redlib
      port: 8080
      scheme: http
  tls:
    certResolver: acme
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: replacepathregex-reddit
  namespace: redlib
spec:
  replacePathRegex:
    regex: "^/https://www.reddit\\.com(.*)"
    replacement: "$1"

Il aurait probablement été possible d’utiliser un autre type de middleware tel que StripPrefix (voir la liste des middlewares Traefik HTTP), cependant ce dernier répond à un but bien précis qui n’est pas le mien: il ajoute une entête HTTP X-Forwarded-Prefix qui, bien que pas strictement standard, est devenu un standard de facto que les serveurs web applicatifs peuvent utiliser pour générer leurs URL en tenant compte du reverse proxy (en incluant le préfixe retiré par le reverse proxy lors de la génération d’URL pour que l’URL publique inclut le préfixe). Tandis que le middleware ReplacePathRegex va ajouter l’entête HTTP X-Replaced-Path, qui a bien moins de chances de perturber la génération d’URL de l’application web. Dans le cas de RedLib, je pense que l’un ou l’autre fonctionne car je ne pense pas qu’ils exploitent l’entête X-Forwarded-Prefix.