L’écart entre un schéma de protocole et un client utile.

L’ancienne interface pouvait illustrer un menu Gopher, mais pas prouver l’essentiel : comment un selector devient des octets sur un socket, où se termine le framing du texte ou ce qui se passe lorsqu’un serveur distant se bloque, annonce un mauvais type ou renvoie du binaire.

La version 3.2.0 conserve le chemin Node.js borné de la CLI et de la passerelle, puis ajoute un transport Android natif pour l’usage mobile direct. L’édition web est installable et sûre hors ligne ; Pages reste sur fixtures car le navigateur ne peut pas ouvrir de socket TCP brut.

Les règles que l’implémentation ne peut pas brouiller.

Le protocole est simple ; sa frontière de confiance ne l’est pas :

  1. Le traitement RFC 4266 doit préserver selector et recherche, tandis que framing RFC 1436, fin de texte, dot-stuffing et types binaires gardent des règles distinctes sur le réseau et en sortie.
  2. Toute opération réseau doit avoir une échéance totale, un délai d’inactivité, une limite de requête, une limite de réponse et un plafond d’entrées de menu.
  3. Les accès hébergés doivent refuser les réponses DNS privées, loopback ou mixtes, puis se connecter à l’adresse validée sans résoudre le nom une seconde fois.
  4. Un texte non fiable ne doit pas piloter le terminal, et une réponse binaire ne doit être ni décodée ni imprimée comme du texte.

Une passerelle locale, pas un proxy ouvert.

Placer un proxy HTTP ouvert à Internet derrière l’explorateur rendrait la page pratique tout en créant un service SSRF. DIG garde donc la passerelle près de l’utilisateur, n’accepte les appels API que depuis sa propre origine web et n’accorde aucun accès CORS aux autres sites.

Le mode hébergé se choisit explicitement. Il exige un jeton, bloque les destinations privées et lie le résultat DNS validé à la connexion TCP. L’accès local aux adresses privées n’existe que derrière une option explicite et un avertissement visible.

Deux transports bornés, quatre surfaces honnêtes.

CLI et explorateur local partagent politique, TCP épinglé et parser Node.js. Android applique nativement les mêmes limites de destination publique et de réponse, puis remet des octets typés à l’explorateur embarqué. PWA et Pages restent sur la fixture sans passerelle authentifiée.

Deux transports bornés, quatre surfaces honnêtes. Chaque surface dit si ses octets viennent du TCP direct, de la passerelle same-origin ou de la fixture hors ligne.VUE DU SYSTÈME / DIGURL + RECHERCHEPOLITIQUE CIBLETCP NODE/ ANDROIDPARSER RFCCLI +EXPLORATEURPARCOURS DE LIVRAISON VERSIONNÉ
Chaque surface dit si ses octets viennent du TCP direct, de la passerelle same-origin ou de la fixture hors ligne.

Pourquoi ces technologies.

La stack rend Gopher accessible dans le navigateur sans transformer le projet en proxy public.

T01 Le choix

Une passerelle TCP locale en Node.js.

Pourquoi
Le navigateur ne peut pas ouvrir de socket Gopher brut ; la passerelle applique résolution, politique de destination, délais et limites de taille avant la connexion.
Ce que j’ai écarté
Un proxy générique ou distant offrirait une surface SSRF et de relais bien plus large que ne l’exige le protocole.
Ce que cela a coûté
Nous acceptons un processus Node local et renonçons explicitement à prendre en charge des protocoles arbitraires.
T02 Le choix

Des endpoints connectés, bornés et same-origin.

Pourquoi
L’explorateur utilise la passerelle sous la même origine, avec des requêtes et réponses maintenues dans des contrats étroits.
Ce que j’ai écarté
Un proxy public cross-origin pourrait servir au scan, à l’accès aux réseaux privés ou à du trafic imprévu.
Ce que cela a coûté
Nous acceptons que le site public n’affiche que des fixtures et que l’accès connecté exige l’installation locale.
T03 Le choix

Préserver les octets jusqu’à la frontière de présentation.

Pourquoi
Gopher transporte texte, menus et données binaires ; garder les octets intacts évite d’altérer téléchargements ou terminateurs du protocole.
Ce que j’ai écarté
Tout décoder en amont imposerait un jeu de caractères, pourrait corrompre les payloads binaires et confondre contenu et transport.
Ce que cela a coûté
Nous acceptons des buffers, métadonnées de type et limites explicites plus exigeants à gérer.
T04 Le choix

Un transport Capacitor natif sous Android.

Pourquoi
L’explorateur embarqué ouvre des connexions TCP bornées et conserve ses assets dans l’APK ; sa politique ne propose aucun contournement vers les réseaux privés.
Ce que j’ai écarté
Embarquer le site hébergé laisserait la dépendance à la passerelle, et installer une PWA ne donne pas accès aux sockets bruts.
Ce que cela a coûté
Nous acceptons une frontière Kotlin, le SDK, la signature Android et des tests de parité avec la politique Node.js.

Les choix qui rendent la frontière visible.

Chaque surface indique clairement ce qu’elle peut atteindre et ce qu’elle conserve.

D01

Résoudre une fois, puis joindre la cible contrôlée

La politique hébergée rejette tout le nom d’hôte dès qu’une réponse DNS n’est pas publique. Une résolution valide fournit exactement l’adresse utilisée par le client TCP, ce qui ferme l’écart habituel entre contrôle et connexion.

Le compromisLe rejet strict des réponses mixtes peut bloquer une configuration DNS inhabituelle mais légitime ; il est plus sûr que de deviner la réponse voulue par un attaquant.

D02

Distinguer visiblement démonstration et mode connecté

Le mode public indique qu’il navigue uniquement dans les fixtures incluses. L’accès Gopher réel apparaît comme un mode distinct et exige la passerelle locale ou une passerelle hébergée volontairement.

Le compromisPages n’ouvre pas de ressources réelles, mais l’utilisateur ne confond pas une démonstration statique avec un client connecté.

D03

Achever les téléchargements atomiquement

La CLI écrit dans un fichier temporaire du dossier cible, puis ne rend le chemin final visible qu’après une fin réussie ; erreur ou interruption ne laisse aucun téléchargement partiel apparemment valide.

Le compromisIl faut de l’espace temporaire et une étape finale de commit, mais les outils en aval ne voient pas un fichier partiel comme un résultat complet.

Comment la version 3.2.0 est vérifiée.

Les 102 tests Node.js couvrent parsing RFC, fixtures TCP, politique réseau, contrat HTTP, sortie atomique, état PWA, bundle Android et contrats de publication. Quinze parcours Playwright vérifient Chromium et WebKit mobile, dont navigation réelle et reprise hors ligne.

La CI Android compile et analyse le projet natif, exécute ses tests et vérifie les assets embarqués. Le contrôle couvre aussi archives déterministes, audit des dépendances, smoke test du conteneur et contrat de l’APK signé.

Ce qui fonctionne aujourd’hui.

Dans le terminal ou l’application Android, on peut récupérer menus, textes, recherches et types binaires réels. L’explorateur local ajoute historique, favoris, recherche, inspection brute, export JSON et téléchargement via la passerelle ; la PWA installée garde la fixture hors ligne.

DIG ne transforme pas Gopher en HTTP. Le trafic vers le serveur Gopher reste en clair, Pages ne récupère aucune ressource réelle, et Gopher+, TLS, les sessions Telnet ainsi que le crawling récursif restent hors du contrat pris en charge.

Registre des preuves.

Les affirmations sur la version 3.2.0 reposent sur des contrôles exécutables et des limites visibles :

Vérification
Le code source vérifié passe 102 tests Node.js et 15 parcours web sous Chromium et WebKit mobile ; un test est volontairement ignoré sur la plateforme où il ne s’applique pas.
Android
L’application Capacitor 8 prend en charge Android 7/API 24 et plus, cible l’API 36 et utilise un transport TCP natif direct au lieu de charger le site hébergé.
Politique réseau
Le mode hébergé exige un jeton d’accès, refuse un nom d’hôte dès qu’une réponse DNS n’est pas publique et se connecte uniquement à l’adresse déjà validée.
Intégrité des sorties
La CLI écrit dans un fichier temporaire du même répertoire puis rend le chemin final visible de façon atomique ; aucun octet binaire n’est imprimé dans un terminal interactif.
Frontière hors ligne
La PWA met en cache l’interface statique et le contenu de démonstration vérifié, jamais les réponses API. Au retour de la connexion, elle ne reprend qu’une session de passerelle auparavant active.

Version publiée vérifiée v3.2.0 Vérification du

Ce que ce cas peut démontrer

Cette étude décrit la version 3.2.0 vérifiée : framing RFC 1436, URL et recherche RFC 4266, types binaires, transports TCP bornés en Node.js et Android, passerelle same-origin et PWA hors ligne sur fixture. Gopher reste non authentifié et non chiffré.

Voir le projet fonctionnel