2 points par GN⁺ 4 시간 전 | 1 commentaires | Partager sur WhatsApp
  • ymawky est un serveur web de fichiers statiques écrit uniquement en assembleur ARM64, qui fonctionne sans libc en utilisant uniquement des appels système, avec une architecture qui effectue un fork pour chaque connexion
  • La cible de développement est MacOS et l’exécution n’est possible que sur Apple silicon arm64 ; la compilation nécessite Xcode Command Line Tools et make
  • Par défaut, l’exécution démarre sur 127.0.0.1:8080 ; il est possible de spécifier le port, mais les adresses personnalisées ne sont pas encore prises en charge et le serveur fonctionne uniquement sur 127.0.0.1
  • La racine documentaire est par défaut www/ ; GET / recherche www/index.html, et les pages d’erreur sont configurées pour être fournies depuis err/(code).html
  • Les méthodes HTTP prises en charge sont GET, PUT, DELETE, OPTIONS, HEAD ; l’exécution de code côté serveur ou le parsing avancé d’URL comme /search?query=term ne sont pas pris en charge
  • PUT prend en charge par défaut des uploads jusqu’à 1GiB, en écrivant d’abord dans le fichier temporaire www/.ymawky_tmp_<pid> puis en le renommant, afin qu’un upload partiel n’écrase pas un fichier existant
  • GET prend en charge les requêtes Range: bytes= et traite les formats bytes=X-N, bytes=-N, bytes=X-, ce qui permet notamment une bonne prise en charge de la navigation dans les vidéos
  • Le serveur détecte les types MIME à partir de l’extension du fichier et envoie l’en-tête de réponse Content-Type, avec la reconnaissance de nombreuses extensions de fichiers web, images, polices, documents, vidéos, audio et archives compressées
  • Parmi les protections sur les chemins : rejet des chemins supérieurs à PATH_MAX, blocage des sorties de chemin basées sur .., ajout du préfixe www/ à tous les chemins de requête, et rejet des chemins contenant des symlinks via O_NOFOLLOW_ANY
  • Pour atténuer les DoS de type slowloris, la connexion est fermée et 408 Request Timeout est renvoyé si plus de 10 secondes s’écoulent entre deux lectures ou si la réception complète des en-têtes dépasse 10 secondes
  • Les requêtes HTTP/1.1 nécessitent un en-tête Host: ; la valeur de Host n’est pas réellement utilisée, mais la présence de l’en-tête est exigée conformément à la section 3.2 de la RFC 9112
  • Dans config.S, il est possible d’ajuster la racine documentaire, le répertoire des pages d’erreur, le fichier par défaut, le délai de réception, les limites de débit et de taille de PUT, le nombre maximal de processus simultanés, etc.
  • Pour porter le projet vers Linux ou un autre Unix, il faut modifier les registres d’appel système et svc, le mode de retour des erreurs, fork(), SO_NOSIGPIPE, O_NOFOLLOW_ANY, renameatx_np(), la disposition des structures, la syntaxe de relocalisation Mach-O, la gestion des signaux, etc.

1 commentaires

 
GN⁺ 4 시간 전
Avis Hacker News
  • En pratique, quand on écrit de gros programmes en assembleur, surtout avec un assembleur à macros, on se rend vite compte que c’est surtout plus verbeux, mais pas fondamentalement différent de la programmation de plus haut niveau
    Au final, il suffit de s’habituer à créer des abstractions avec des procédures et des macros, et il est souvent bien plus difficile de lire efficacement de l’assembleur que d’en écrire

    • C’est exactement ce que j’ai réalisé en faisant ce projet. Il faut tout écrire de manière beaucoup plus explicite, mais la façon dont chaque fonction marche n’est pas fondamentalement différente
      strlen, que ce soit en C, en Rust, en Assembly ou dans un autre langage, parcourt toujours la chaîne jusqu’à trouver un octet NULL. Comme on déroule exactement ce que le CPU doit faire et dans quel ordre, ça peut même sembler plus intuitif que dans d’autres langages
  • C’est un projet vraiment beau et très bien réalisé. Pour reprendre l’idée d’autres commentaires, ce genre de projet me fait penser à une map Minecraft
    Il y a des maps immenses et impressionnantes, de petites maps de survie, des maps ouvertes en local juste pour soi et ses amis, et des serveurs commerciaux visant une grande échelle. Grâce à l’IA, il est devenu très facile de construire des maisons sur le serveur ou de tracer de nouvelles routes, mais la valeur créée dans ce monde dépend du but initial du serveur et du fait que construire davantage de maisons et de routes ait ou non un vrai sens
    C’est formidable si les serveurs commerciaux peuvent grossir plus vite et avoir plus de maisons et de routes, mais l’attachement qu’un projet artistique suscite est incomparable

  • Ça m’a fait chaud au cœur de voir que quelqu’un essaie encore de faire ce genre de chose à la main. Je ne suis donc pas le seul

    • Cette idée m’obsédait depuis un moment, puis je me suis enfin lancé et j’y ai été complètement absorbé pendant des semaines
      J’aimerais bien voir d’autres projets similaires, et ça fait plaisir de savoir que je ne suis pas seul. À mon avis, si la plupart des programmeurs passaient quelques semaines ou quelques mois à apprendre l’assembleur, une grande partie du mystère autour du fonctionnement du CPU et des langages compilés disparaîtrait
  • Projet amusant. J’ai une version bien plus minimaliste pour x86 Linux, si vous voulez voir à quoi ça ressemble : https://github.com/jcalvinowens/asmhttpd

    • Waouh, ce projet m’a en fait énormément inspiré. Je l’avais lu il y a quelque temps et il m’avait vraiment marqué
      Je me demandais si ça vous allait que j’ajoute un lien vers votre dépôt dans mon README
  • Cette fausse couverture de livre O'Reilly est absolument géniale

    • C’est précisément ce livre qui m’a donné l’impulsion de faire ça au départ. Son sous-titre m’a donné l’acronyme qui est devenu le nom du projet
  • Même si la comparaison est un peu vaine, je me demande quel est le niveau de performance par rapport à des serveurs web complets. J’aimerais voir des métriques comme le nombre maximal de requêtes par seconde

    • Honnêtement, je n’ai pas encore fait de benchmark, mais je pense que ymawky est probablement nettement plus lent que la plupart des serveurs web complets
      ymawky fonctionne en faisant un fork par connexion, donc c’est fondamentalement plus lent que l’approche utilisée par des serveurs de production comme nginx ou Apache. nginx utilise des E/S événementielles avec kqueue/epoll, ce qui lui permet de gérer des milliers de connexions simultanées sans le surcoût de forker un processus à chaque requête. Apache utilise un pool de threads pour traiter plusieurs connexions sans en créer un nouveau à chaque requête
      Une comparaison frontale avec d’autres serveurs web mesurerait surtout la différence entre un fork par connexion et une boucle d’événements ou un pool de threads, bien plus que quoi que ce soit lié à l’assembleur
      Si on le comparait à un serveur similaire écrit en C et forkant lui aussi à chaque connexion, le débit serait probablement presque identique. Dans ce modèle, le goulet d’étranglement est fork() lui-même, pas vraiment le code. L’impact se verrait probablement davantage sur la taille du binaire et le temps de démarrage que sur le nombre de requêtes par seconde. Cela dit, ce serait amusant de faire un vrai benchmark
  • Beau travail. Je suis moi aussi en train de faire quelque chose de similaire mais plus petit en RISC-V, et c’est excellent

    • Très sympa. Si c’est publié quelque part, j’aimerais vraiment y jeter un œil
  • J’essaie d’aller délibérément à contre-courant de la direction que prend ce monde du vibe coding, et de retrouver le sentiment d’être à nouveau mis au défi, en écrivant un rendu logiciel WebAssembly
    Je ne sais pas si j’irai au bout, c’est insensé et on ne peut pas vraiment dire que ce soit utile. Mais ça fait vraiment du bien
    Félicitations à l’auteur original pour cet accomplissement

    • J’ai fait exactement la même chose, et c’était vraiment amusant. Ce n’était pas pour mettre quelque chose de nouveau au monde, juste un défi plaisant pour moi-même
      Après l’avoir terminé, je me suis mis à faire un jeu avec, mais maintenant que le plaisir du défi a disparu, ça n’avance plus beaucoup de ce côté-là. Et ce n’est pas grave, parce que c’était amusant. Si je l’avais fait en vibe coding, je n’aurais pas eu ce plaisir ni cette satisfaction
    • Tu parles d’un moteur de rendu logiciel 3D ? J’ai beaucoup appris en en construisant plein en x86 et en C pendant mon adolescence et au début de ma carrière
      J’ai voulu voir à quel point un LLM pouvait écrire correctement un moteur de rendu pour CGA en pur assembleur 8088, alors je lui ai demandé, et il a produit une démo plutôt correcte du premier coup. Dans le prompt, je lui avais donné les vecteurs d’un vaisseau d’Elite
      https://imgur.com/a/Dy5rUku
  • L’un de mes premiers projets en assembleur a été un script CGI écrit à 100 % en assembleur x86
    Un serveur web complet est clairement encore plus impressionnant. Mais pour un débutant, je recommanderais quand même d’aller d’abord voir le CGI d’Apache et mod_cgi

    • Waouh, honnêtement, écrire un script CGI en assembleur me ferait encore plus peur qu’écrire le serveur lui-même en assembleur
      Le support CGI me trotte dans la tête depuis quelques semaines, mais je n’ai pas encore vraiment creusé la question. Si c’est hébergé quelque part, j’aimerais bien voir ça, ce serait sans doute une bonne référence quand je m’y mettrai plus tard
  • On est en train de basculer vers l’IA, d’arrêter d’écrire du code et de se prendre la tête, et ici quelqu’un écrit un serveur web en assembleur
    Ça remet à sa place

    • Oui, ça remet à sa place. Et mes préférences quant au chemin à suivre sont très claires
    • Qui ça, « on » ? Je n’ai pas si peu de fierté que je vais soumettre du code bricolé généré par une machine au lieu de faire correctement mon travail moi-même