2P by GN⁺ 4시간전 | ★ favorite | 댓글 1개
  • ymawky는 ARM64 어셈블리만으로 작성된 정적 파일 웹 서버로, libc 없이 syscall만 사용하고 연결마다 fork하는 구조로 동작함
  • 개발 대상은 MacOS이며 실행은 Apple silicon arm64에서만 가능하고, 빌드에는 Xcode Command Line Tools와 make가 필요함
  • 기본 실행은 127.0.0.1:8080에서 시작하며 포트 지정은 가능하지만, 현재 사용자 지정 주소는 지원하지 않고 127.0.0.1에서만 동작함
  • 문서 루트는 기본적으로 www/이며 GET /www/index.html을 찾고, 오류 페이지는 err/(code).html에서 제공하도록 구성됨
  • 지원 HTTP 메서드는 GET, PUT, DELETE, OPTIONS, HEAD이며, 서버 측 코드 실행이나 /search?query=term 같은 고급 URL 파싱은 지원하지 않음
  • PUT은 최대 1GiB 업로드를 기본 지원하고, 임시 파일 www/.ymawky_tmp_<pid>에 쓴 뒤 rename하는 방식으로 부분 업로드가 기존 파일을 덮어쓰지 않게 함
  • GETRange: bytes= 요청을 지원해 bytes=X-N, bytes=-N, bytes=X- 형식을 처리하며, 비디오 탐색도 잘 지원한다고 되어 있음
  • 파일 확장자를 기반으로 MIME 타입을 감지해 Content-Type 응답 헤더를 보내며, 웹 파일·이미지·폰트·문서·비디오·오디오·압축 파일 확장자를 다수 인식함
  • 경로 안전장치로 PATH_MAX 이상 경로 거부, .. 기반 경로 탈출 차단, 모든 요청 경로에 www/ 접두, O_NOFOLLOW_ANY로 symlink 포함 경로 거부를 적용함
  • slowloris류 DoS 완화를 위해 읽기 사이가 10초를 넘거나 전체 헤더 수신이 10초를 넘으면 연결을 닫고 408 Request Timeout을 반환함
  • HTTP/1.1 요청은 Host: 헤더가 필요하며, Host 값을 실제로 사용하지는 않지만 RFC 9112 Section 3.2에 따라 헤더 존재를 요구함
  • config.S에서 문서 루트, 오류 페이지 디렉터리, 기본 파일, 수신 타임아웃, PUT 속도·크기 제한, 최대 동시 프로세스 수 등을 조정할 수 있음
  • Linux나 다른 Unix로 이식하려면 syscall 호출 레지스터와 svc, 오류 반환 방식, fork(), SO_NOSIGPIPE, O_NOFOLLOW_ANY, renameatx_np(), 구조체 레이아웃, Mach-O 재배치 문법, signal handling 등을 수정해야 함
Hacker News 의견들
  • 실제로 어셈블리, 특히 매크로 어셈블러로 큰 프로그램을 작성해 보면 더 장황할 뿐, 고수준 프로그래밍과 근본적으로 다르지는 않다는 걸 금방 알게 됨
    결국 프로시저와 매크로로 추상화를 만드는 법에 익숙해지면 충분하고, 어셈블리를 효과적으로 읽는 일이 쓰는 것보다 훨씬 어려울 때가 많음

    • 이번 작업을 하면서 나도 같은 걸 깨달았음. 훨씬 더 명시적으로 써야 하지만, 개별 함수가 동작하는 방식 자체는 근본적으로 다르지 않음
      strlen은 C든 Rust든 Assembly든 다른 언어든 결국 문자열을 순회하며 NULL 바이트를 찾음. CPU가 정확히 무엇을 어떤 순서로 해야 하는지 그대로 펼쳐 쓰기 때문에, 오히려 다른 언어보다 더 직관적으로 느껴질 때도 있음
  • 정말 아름답고 잘 만든 프로젝트임. 다른 댓글들과 이어서 보자면, 이런 프로젝트는 나에게 Minecraft 맵에 가까움
    거대하고 놀라운 맵도 있고, 작은 생존 맵도 있고, 친구들과 나만을 위해 로컬에서 여는 맵도 있고, 상업적으로 큰 규모를 노리는 서버도 있음. AI 덕분에 서버에 집을 짓거나 새 길을 설계하는 일은 아주 쉬워졌지만, 그 세계에서 만들어지는 가치는 서버의 원래 목적과 집과 길을 더 만드는 일이 실제로 의미 있는지에 달려 있음
    상업 서버가 더 빠르게 커지고 더 많은 집과 도로를 갖출 수 있는 건 훌륭하지만, 예술 프로젝트가 만들어내는 애정은 비교할 수 없음

  • 아직도 누군가가 이런 걸 손으로 직접 하려 든다는 걸 알게 되니 따뜻한 느낌이 들었음. 나만 그런 게 아니었음

    • 이 아이디어에 한동안 꽂혀 있다가 결국 시작했고, 몇 주 동안 완전히 몰두했음
      비슷한 프로젝트가 있다면 보고 싶고, 나만 그런 게 아니라서 반가움. 대부분의 프로그래머가 몇 주나 몇 달 정도 어셈블리를 배워 보면 CPU와 컴파일 언어가 어떻게 동작하는지에 대한 신비감이 많이 걷힐 거라고 봄
  • 재미있는 프로젝트임. x86 Linux용으로 훨씬 더 미니멀한 버전을 만들어 둔 게 있는데, 어떤 모습인지 보고 싶다면 여기 있음: https://github.com/jcalvinowens/asmhttpd

    • 와, 그 프로젝트가 실제로 나에게 큰 영감을 줬음. 예전에 읽어 보면서 정말 인상 깊었음
      내 README에 당신 저장소 링크를 추가해도 괜찮을지 궁금함
  • 그 가짜 O'Reilly 책 표지는 정말 최고임

    • 그 책이 애초에 이걸 만들게 된 정확한 계기였음. 책의 부제가 프로젝트 이름의 약어를 만들어 줬음
  • 의미 없는 비교이긴 해도, 완전한 기능을 갖춘 웹 서버들과 비교했을 때 성능이 어느 정도인지 궁금함. 초당 최대 요청 수 같은 지표를 보고 싶음

    • 솔직히 벤치마크는 아직 안 해 봤지만, ymawky는 대부분의 완전한 웹 서버보다 꽤 느릴 것 같음
      ymawky는 연결마다 fork하는 구조라서, nginx나 Apache 같은 운영 환경용 서버가 쓰는 방식보다 근본적으로 느림. nginx는 이벤트 기반 입출력인 kqueue/epoll을 써서 요청마다 프로세스를 포크하는 오버헤드 없이 수천 개의 동시 연결을 처리할 수 있음. Apache는 스레드 풀을 써서 요청마다 새로 생성하지 않고 여러 연결을 처리함
      다른 웹 서버와 정면 비교하면 대부분 연결마다 fork와 이벤트 루프/스레드 풀의 차이를 측정하게 될 뿐이고, 어셈블리와는 별 상관이 없음
      비슷하게 연결마다 포크하는 서버를 C로 작성한 것과 비교한다면 처리량은 거의 같을 것 같음. 이 모델의 병목은 실제 코드가 아니라 fork() 자체이기 때문임. 초당 요청 수보다는 바이너리 크기와 시작 시간에 더 영향을 줄 가능성이 큼. 그래도 실제로 벤치마크해 보면 재미있을 듯함
  • 잘 만들었음. 나도 RISC-V로 비슷하지만 더 작은 프로젝트를 작업 중인데, 이건 훌륭함

    • 정말 멋짐. 어디든 공개해 둔 곳이 있다면 꼭 보고 싶음
  • 이 바이브 코딩 세상이 가는 방향에 굳이 거슬러 가고 싶고, 다시 도전받는 느낌을 얻고 싶어서 WebAssembly 소프트웨어 렌더러를 작성해 보려는 중임
    끝낼 수 있을지는 모르겠고, 미친 짓이며, 유용하다고 할 수도 없음. 그래도 정말 기분이 좋음
    원 작성자의 성취를 축하함

    • 나도 정확히 같은 걸 해 봤고 정말 재미있었음. 새로운 무언가를 세상에 내놓기 위한 게 아니라, 그냥 나 자신을 위한 즐거운 도전이었음
      완성한 뒤에는 그걸로 게임을 만들고 있는데, 이제 도전의 재미가 사라져서 그쪽은 진도가 별로 안 나감. 그래도 상관없음, 재미있었으니까. 바이브 코딩으로 했다면 그런 재미나 만족감은 얻지 못했을 것임
    • 3D 소프트웨어 렌더러를 말하는 건가? 10대 시절과 커리어 초반에 x86과 C로 그런 걸 많이 만들면서 배웠음
      LLM이 순수 8088 어셈블러로 CGA용 렌더러를 얼마나 잘 작성하는지 보고 싶어서 시켜 봤는데, 한 번에 꽤 괜찮은 데모를 만들어 냈음. 프롬프트에는 Elite 함선의 벡터를 넣어 줬음
      https://imgur.com/a/Dy5rUku
  • 내 첫 어셈블리 프로젝트 중 하나는 100% x86 어셈블리로 작성한 CGI 스크립트였음
    완전한 웹 서버가 확실히 더 인상적이긴 함. 그래도 초보자라면 먼저 Apache의 CGI와 mod_cgi를 찾아보라고 권하고 싶음

    • 와, 솔직히 서버를 어셈블리로 쓰는 것보다 CGI 스크립트를 어셈블리로 쓰는 쪽이 더 겁날 것 같음
      CGI 지원은 몇 주 전부터 생각하고 있었지만 아직 제대로 파보지는 않았음. 어디 호스팅된 곳이 있다면 보고 싶고, 나중에 작업할 때 좋은 참고 자료가 될 수 있을 듯함
  • 우리는 AI로 넘어가며 코드를 쓰고 머리를 싸매는 일을 멈추고 있는데, 여기서는 어셈블리로 웹 서버를 쓰고 있음
    겸손해지게 만듦

    • 겸손해지긴 함. 내가 어느 길을 더 선호하는지는 분명함
    • 여기서 “우리”가 누구임? 스스로 제대로 일하는 대신 조잡한 기계 생성 코드를 제출할 만큼 자존심이 없지는 않음