La distanza tra uno schema del protocollo e un client utile.
L’interfaccia precedente poteva illustrare un menu Gopher, ma non provava le parti importanti: come un selector diventa byte su un socket, dove termina il framing del testo o cosa accade se un server remoto si blocca, dichiara un tipo errato o restituisce dati binari.
La versione 3.2.0 mantiene il percorso Node.js limitato per CLI e gateway e aggiunge un trasporto Android nativo per l’uso mobile diretto. L’edizione browser è installabile e sicura offline, ma Pages resta su fixture perché JavaScript non può creare il socket TCP grezzo richiesto da Gopher.
Regole che l’implementazione non può confondere.
Il protocollo è semplice; il confine di fiducia non lo è:
- Il parsing RFC 4266 deve conservare selector e query, mentre framing RFC 1436, terminatori del testo, dot-stuffing e tipi binari mantengono regole distinte sulla rete e nell’output.
- Ogni operazione di rete deve avere scadenza totale, timeout di inattività, limite della richiesta, limite della risposta e tetto alle voci di menu.
- Le richieste hosted devono bloccarsi su risposte DNS private, loopback o miste e devono connettersi all’indirizzo validato senza risolvere di nuovo il nome.
- Il testo non attendibile non deve controllare il terminale e le risposte binarie non possono essere decodificate o stampate come testo.
Un gateway locale, non un proxy aperto.
Mettere un proxy HTTP aperto a Internet dietro l’explorer renderebbe la pagina comoda e creerebbe contemporaneamente un servizio SSRF. DIG mantiene invece il gateway vicino all’utente, accetta chiamate API soltanto dalla propria origine browser e non concede accesso CORS ad altri siti.
La modalità hosted è esplicita, non dedotta. Richiede un token, blocca le destinazioni private e vincola il risultato DNS validato alla connessione TCP. L’accesso locale a indirizzi privati esiste soltanto dietro un flag esplicito e un avviso visibile.
Due trasporti limitati, quattro superfici oneste.
CLI ed explorer locale condividono policy, TCP vincolato e parser Node.js. Android applica gli stessi limiti di destinazione pubblica e risposta nel trasporto nativo, poi passa byte tipizzati all’explorer incluso nell’APK. PWA e Pages restano sulla fixture offline se manca un gateway autenticato.
Perché queste tecnologie.
Lo stack rende possibile Gopher nel browser senza trasformare il progetto in un proxy pubblico.
Un gateway TCP locale in Node.js.
- Perché
- Il browser non può aprire socket Gopher grezzi; il gateway applica risoluzione, policy di destinazione, timeout e limiti di dimensione prima della connessione.
- Cosa ho escluso
- Un proxy generico o remoto offrirebbe una superficie SSRF e di relay molto più ampia del protocollo necessario.
- Quanto è costata
- Accettiamo un processo Node locale e nessuna pretesa di supportare protocolli arbitrari.
Endpoint live same-origin e limitati.
- Perché
- L’explorer può usare il gateway sotto la stessa origine mantenendo richieste e risposte entro contratti stretti.
- Cosa ho escluso
- Un proxy pubblico cross-origin potrebbe essere abusato per scansioni, accesso a reti private o traffico non previsto.
- Quanto è costata
- Accettiamo che il sito pubblico mostri solo fixture e che l’accesso live richieda l’installazione locale.
Preservare i byte fino al confine di presentazione.
- Perché
- Gopher trasporta testo, menu e dati binari; conservare i byte evita di alterare download o terminatori del protocollo.
- Cosa ho escluso
- Decodificare tutto in anticipo imporrebbe un charset, potrebbe corrompere payload binari e confondere contenuto con trasporto.
- Quanto è costata
- Accettiamo buffer, metadati di tipo e limiti espliciti più laboriosi da gestire.
Un trasporto Capacitor nativo su Android.
- Perché
- L’explorer pacchettizzato apre connessioni TCP limitate e mantiene gli asset dell’interfaccia nell’APK, con una policy che non consente override verso reti private.
- Cosa ho escluso
- Incorporare il sito hosted manterrebbe la dipendenza dal gateway; installare una PWA non concede al browser l’accesso ai socket grezzi.
- Quanto è costata
- Accettiamo un confine Kotlin, SDK e firma Android, oltre ai test di parità con la policy Node.js.
Scelte che rendono visibile il confine.
Ogni superficie dichiara con chiarezza cosa può raggiungere e cosa conserva.
Risolvere una volta e connettersi a ciò che è stato verificato
La policy hosted rifiuta l’intero hostname se una risposta DNS non è pubblica. Una risoluzione valida restituisce l’indirizzo esatto usato dal client TCP, chiudendo il consueto divario tra controllo e connessione.
Il compromessoIl rifiuto delle risposte miste può bloccare configurazioni DNS insolite ma legittime; è più sicuro che indovinare quale risposta intendesse usare un attaccante.
Dichiarare quando l’explorer è una dimostrazione
La modalità pubblica segnala che naviga soltanto fixture incluse. L’accesso Gopher live appare come modalità distinta e richiede il gateway locale o un gateway hosted attivato esplicitamente.
Il compromessoPages non offre la comodità di aprire risorse reali, ma l’utente non confonde una demo statica con un client connesso.
Rendere atomico il completamento dei download
La CLI scrive nella cartella di destinazione su un file temporaneo, quindi espone il percorso finale soltanto dopo il completamento riuscito; errori o interruzioni non lasciano un download apparentemente valido.
Il compromessoServono spazio temporaneo e un passaggio finale di commit, ma gli strumenti a valle non osservano file parziali come risultati completi.
Come viene verificata la v3.2.0.
I 102 test Node.js coprono parsing RFC, fixture TCP, policy di rete, contratto HTTP, output atomico, stato PWA, bundle Android e regole di rilascio. Quindici flussi Playwright verificano Chromium e WebKit mobile, compresi navigazione live e ripristino offline.
La CI Android compila e analizza il progetto nativo, esegue i test unitari e verifica gli asset inclusi. Il gate controlla inoltre archivi deterministici, audit delle dipendenze, smoke test del container e contratto dell’APK firmato.
Cosa funziona oggi.
Dal terminale o dall’app Android si possono recuperare menu, testi, ricerche e tipi binari reali. L’explorer locale aggiunge cronologia, preferiti, ricerca, ispezione raw, export JSON e download tramite il gateway; la PWA installata mantiene la fixture disponibile offline.
DIG non trasforma Gopher in HTTP. Il traffico verso un server Gopher resta in chiaro, Pages non recupera risorse live e Gopher+, TLS, sessioni Telnet e crawling ricorsivo rimangono fuori dal contratto supportato.
Registro delle evidenze.
Le affermazioni sulla v3.2.0 sono legate a controlli eseguibili e limiti visibili:
- Verifica
- Il sorgente controllato supera 102 test Node.js e 15 flussi browser tra Chromium e WebKit mobile, con uno skip intenzionalmente specifico per piattaforma.
- Android
- L’app Capacitor 8 supporta Android 7/API 24 e successivi, usa il target API 36 e apre connessioni TCP native senza caricare il sito hosted.
- Policy di rete
- La modalità hosted richiede un token, rifiuta un hostname se anche una sola risposta DNS non è pubblica e si connette soltanto all’indirizzo già validato.
- Integrità dell’output
- La CLI scrive in un file temporaneo nella stessa cartella e rende visibile il percorso finale con un’operazione atomica; i byte binari non vengono mai stampati in un terminale interattivo.
- Confine offline
- La PWA memorizza shell statica e fixture verificata, mai le risposte API. Il ritorno online riprende soltanto una sessione gateway che era già live.
Release verificata v3.2.0 Verifica del
Questo case study descrive la v3.2.0 verificata: framing RFC 1436, URL e ricerca RFC 4266, tipi binari comuni, trasporti TCP limitati in Node.js e Android, gateway same-origin e PWA offline su fixture. Il traffico Gopher resta non autenticato e non cifrato.