Fichiers acceptés

Liste noire d'extensions, taille maximale, envoi par tranches, versions et aperçus.

Une liste noire, pas une liste blanche

Un drive généraliste reçoit ce que les gens s'échangent, ce qui interdit d'énumérer à l'avance ce qui est permis. Le module refuse donc une liste d'extensions et accepte le reste.

Sont refusés : les exécutables et bibliothèques (.exe, .msi, .dll, .com, .scr…), les paquets et applications (.jar, .apk, .deb, .rpm, .dmg…), les scripts (.bat, .cmd, .sh, .ps1, .vbs, .js, .php, .py…), les raccourcis et fichiers de configuration système (.reg, .lnk, .inf, .url…), et les documents bureautiques à macros (.docm, .xlsm, .pptm…).

LRVO_MODULE_DRIVE_BLOCKED_EXTENSIONS allonge cette liste.

LRVO_MODULE_DRIVE_ALLOWED_EXTENSIONS la raccourcit : les extensions qu'elle nomme sont retirées de la liste intégrée et redeviennent acceptées.

LRVO_MODULE_DRIVE_ALLOWED_EXTENSIONS=.bat,.ps1

Les deux variables s'écrivent de la même façon : des extensions séparées par des virgules, avec ou sans le point, sans égard à la casse. Une extension nommée dans les deux reste refusée.

Le refus protège le destinataire, pas le serveur : un fichier stocké ici n'est jamais exécuté par le site, mais un .bat s'exécute d'un double clic sur la machine de la personne qui le télécharge. Lever une extension vaut pour tout le drive, liens publics et dépôts externes compris.

Le cas du SVG

Refusé par défaut, parce qu'un SVG porte du script. LRVO_MODULE_DRIVE_ALLOW_SVG=true l'autorise, et c'est le seul réglage qui le fait : .svg dans LRVO_MODULE_DRIVE_ALLOWED_EXTENSIONS est sans effet. Même autorisé, il n'est jamais servi en ligne ni miniaturisé : il redescend en pièce jointe, donc il ne s'exécute pas dans l'origine du site.

Pourquoi le module a sa propre validation

Le core expose validateUpload(), qui fonctionne sur liste blanche et refuse tout fichier dont les premiers octets ressemblent à du HTML, du SVG ou du XML. C'est la bonne politique pour une médiathèque d'images. Pour un drive, elle bloquerait le dépôt d'un .html, d'un .xml ou d'un .txt commençant par un chevron, qui sont des fichiers parfaitement ordinaires.

Le module applique donc sa propre politique, et ne conserve le scan de contenu que pour les extensions d'image, seul cas où le polyglotte est une vraie attaque : du HTML déguisé en .png et rendu par une balise <img>. Un fichier annoncé comme image doit prouver qu'il en est une, par sa signature puis par l'absence de balises dans ses 512 premiers octets.

Ce qui rend cette politique suffisante, c'est la règle de service : hors des quatre types d'image que le core accepte de rendre en ligne, tout redescend en pièce jointe. Un .html stocké ici n'est jamais une page du site.

Taille et découpage

LRVO_MODULE_DRIVE_MAX_FILE_SIZE_MB plafonne la taille, 2 Go par défaut.

Tous les fichiers transitent par l'application. Le navigateur ne parle jamais au seau, dans aucun sens.

Un fichier qui tient dans une tranche part en une seule requête. Un fichier plus gros est découpé par le navigateur, et chaque tranche part dans sa propre requête. Le serveur pousse chaque tranche comme une part d'un téléversement en plusieurs parties, et le seau assemble à la fin : la mémoire du serveur vaut une tranche, quelle que soit la taille du fichier.

Le découpage n'est pas une optimisation. Un proxy plafonne le corps d'une requête, 100 Mo chez Cloudflare sur le forfait gratuit, et il la refuse avant que l'application ne voie le premier octet : découper à la réception serait sans effet. Voir Installation pour aligner la taille de tranche sur votre proxy.

Une tranche qui échoue est réessayée seule, sans reprendre le fichier depuis le début. Un rechargement de page, lui, perd la référence au fichier : l'envoi doit être relancé.

Le scan anti-polyglotte tourne sur la première tranche, donc avant que l'objet n'existe : les 512 octets qu'il inspecte sont précisément ceux qui arrivent en premier. Un HTML déguisé en .png est refusé au premier envoi, et rien n'est jamais assemblé.

Le quota est vérifié trois fois : sur la taille annoncée à l'ouverture de la session, sur le total reçu à chaque tranche, puis sur la taille réelle relue depuis le stockage après assemblage. C'est cette dernière qui est comptabilisée, jamais celle que le client annonce.

Un onglet fermé au milieu d'un envoi laisse des parts stockées et facturées que plus rien ne référence. La tâche drive-sweep-uploads interrompt ces envois chaque heure. Annuler explicitement un envoi le fait immédiatement.

Versions

Chaque dépôt d'un fichier portant un nom déjà pris dans le dossier crée une version, plutôt qu'un doublon, quand le remplacement est demandé. Sinon le nom est suffixé : rapport (2).pdf.

LRVO_MODULE_DRIVE_VERSION_KEEP fixe combien de versions sont conservées, la courante comprise. Au delà, les plus anciennes sont supprimées du stockage.

L'historique des versions d'un fichier s'ouvre par « Versions », dans le menu en fin de sa ligne. L'entrée n'apparaît que si le fichier compte plus d'une version.

Restaurer une version antérieure ne recopie pas l'objet : la nouvelle version pointe la même clé. Deux entrées d'historique peuvent donc partager un objet, ce dont la purge tient compte.

Aperçus

Un clic simple sur un fichier ouvre son aperçu. « Aperçu » figure aussi dans le menu de sa ligne. Ni l'un ni l'autre ne touche à la sélection en cours, qui ne dépend que des cases à cocher.

La visionneuse s'ouvre en plein écran. Une bande en haut porte au centre le nom du fichier, sa taille et sa version le cas échéant, et à droite les actions : versions, téléchargement, fermeture. Tout le reste de la fenêtre appartient au document, parce qu'un PDF ou un plan lus dans un cadre de quelques centaines de pixels ne se lisent pas. Échap ferme, et le clic dans le vide aussi, autour du document comme dans la bande du haut. Seul un clic sur le document lui même, sur un bouton ou sur une commande de lecture ne ferme rien.

Le fond n'est pas opaque : c'est celui des fenêtres modales du reste de l'interface, un noir translucide et flouté qui laisse deviner l'arborescence derrière. L'aperçu se lit ainsi comme une couche posée sur la page en cours, pas comme un écran séparé. Ce fond étant sombre dans les deux thèmes, la bande du haut et ses boutons s'affichent en thème sombre même sur un site clair.

TypeAperçu
ImagesImage complète dans la visionneuse. Miniature webp dans la liste de la page publique de partage.
PDFVisionneuse native du navigateur, dans un cadre isolé.
Vidéo, audioLecture directe, sans limite de taille.
Texte, CSV, JSON, XMLAffichage du contenu, plafonné à 512 ko.
Bureautique et autresPas d'aperçu, téléchargement seul.

Le PDF mérite une explication, parce que sa mise en œuvre n'est pas évidente. Le core interdit d'afficher en ligne un fichier téléversé par un utilisateur : il s'exécuterait dans l'origine du site, avec accès aux témoins et à la page. Le module récupère donc les octets, les enveloppe dans un objet local, et les rend dans un cadre en bac à sable sans accès à l'origine. La visionneuse intégrée du navigateur fonctionne, mais un PDF piégé n'atteint ni les témoins ni la page. Aucune bibliothèque n'est ajoutée pour cela.

La vidéo et l'audio sont servis par plages d'octets : la lecture démarre sans attendre le fichier entier, et la barre de défilement fonctionne. Safari refuse de lire une vidéo dont le serveur ne répond pas aux plages, donc ce n'est pas un raffinement.

Les autres aperçus chargent le fichier entier dans l'onglet, ce qui les plafonne à 50 Mo. Au delà, la visionneuse propose le téléchargement plutôt qu'un aperçu qui figerait le navigateur.

La visionneuse sert aussi la page publique de partage, aux mêmes conditions et avec le même code : seules changent les adresses qu'elle interroge. Un lien qui ne permet pas de télécharger n'ouvre aucun aperçu, parce que la route qui sert les octets exige ce droit.

Les miniatures demandent sharp. Sans lui, le module fonctionne à l'identique, avec une icône par type de fichier à la place de la vignette. Un fichier assemblé par tranches n'obtient une miniature que sous 32 Mo : au delà, la relire pour la miniaturiser rouvrirait le problème de mémoire que le découpage vient de fermer.

Sur cette page