- ymawky là một máy chủ web phục vụ tệp tĩnh được viết hoàn toàn bằng hợp ngữ ARM64, hoạt động chỉ với syscall mà không dùng libc, và có kiến trúc
fork cho mỗi kết nối
- Mục tiêu phát triển là MacOS và chỉ có thể chạy trên Apple silicon arm64; để build cần Xcode Command Line Tools và
make
- Cách chạy mặc định là khởi động tại
127.0.0.1:8080; có thể chỉ định cổng nhưng hiện chưa hỗ trợ địa chỉ tùy chỉnh và chỉ hoạt động trên 127.0.0.1
- Document root mặc định là
www/; GET / sẽ tìm www/index.html, và các trang lỗi được cấu hình để phục vụ từ err/(code).html
- Các phương thức HTTP được hỗ trợ là GET, PUT, DELETE, OPTIONS, HEAD; không hỗ trợ thực thi mã phía máy chủ hoặc phân tích URL nâng cao như
/search?query=term
PUT mặc định hỗ trợ tải lên tối đa 1GiB, ghi vào tệp tạm www/.ymawky_tmp_<pid> rồi mới rename để việc tải lên dở dang không ghi đè tệp hiện có
GET hỗ trợ yêu cầu Range: bytes= để xử lý các dạng bytes=X-N, bytes=-N, bytes=X-, và được mô tả là cũng hỗ trợ tốt việc tua video
- Dựa trên phần mở rộng tệp để nhận diện MIME type và gửi header phản hồi
Content-Type; nhận diện được nhiều phần mở rộng của tệp web, hình ảnh, font, tài liệu, video, âm thanh và tệp nén
- Các biện pháp an toàn đường dẫn gồm từ chối đường dẫn dài từ
PATH_MAX trở lên, chặn thoát đường dẫn dựa trên .., thêm tiền tố www/ cho mọi đường dẫn yêu cầu, và từ chối các đường dẫn có chứa symlink bằng O_NOFOLLOW_ANY
- Để giảm thiểu DoS kiểu slowloris, nếu khoảng cách giữa các lần đọc vượt quá 10 giây hoặc tổng thời gian nhận toàn bộ header vượt quá 10 giây thì kết nối sẽ bị đóng và trả về
408 Request Timeout
- Với yêu cầu HTTP/1.1, header
Host: là bắt buộc; dù giá trị Host không thực sự được dùng, máy chủ vẫn yêu cầu header này theo RFC 9112 Mục 3.2
- Có thể điều chỉnh document root, thư mục trang lỗi, tệp mặc định, timeout nhận, giới hạn tốc độ và kích thước
PUT, số tiến trình đồng thời tối đa, v.v. trong config.S
- Để port sang Linux hoặc Unix khác, cần sửa các thanh ghi gọi syscall và
svc, cách trả về lỗi, fork(), SO_NOSIGPIPE, O_NOFOLLOW_ANY, renameatx_np(), layout struct, cú pháp relocation Mach-O, xử lý signal, v.v.
1 bình luận
Ý kiến trên Hacker News
Khi thực sự viết những chương trình lớn bằng assembly, đặc biệt là bằng macro assembler, bạn sẽ nhanh chóng nhận ra rằng ngoài việc dài dòng hơn thì về cơ bản nó không khác mấy so với lập trình bậc cao
Cuối cùng chỉ cần quen với việc tạo trừu tượng hóa bằng procedure và macro là đủ, và nhiều khi đọc assembly hiệu quả còn khó hơn viết nó
strlendù là trong C, Rust, Assembly hay ngôn ngữ nào khác thì rốt cuộc vẫn là duyệt chuỗi để tìm byte NULL. Vì bạn phải trải ra đúng chính xác CPU cần làm gì và theo thứ tự nào, đôi khi nó còn cho cảm giác trực quan hơn các ngôn ngữ khácĐây thực sự là một dự án đẹp và được làm rất tốt. Nối tiếp ý của các bình luận khác, với tôi những dự án kiểu này giống một bản đồ Minecraft hơn
Có những bản đồ khổng lồ đầy kinh ngạc, có những bản đồ sinh tồn nhỏ, có những bản đồ chỉ mở local cho bạn bè và bản thân, và cũng có những server nhắm tới quy mô thương mại lớn. Nhờ AI, việc xây nhà trên server hay thiết kế con đường mới đã trở nên cực kỳ dễ dàng, nhưng giá trị được tạo ra trong thế giới đó phụ thuộc vào mục đích ban đầu của server và việc xây thêm nhà hay đường có thực sự mang ý nghĩa hay không
Việc các server thương mại có thể lớn nhanh hơn và có nhiều nhà cùng đường hơn là điều tuyệt vời, nhưng tình cảm mà một dự án nghệ thuật tạo ra thì không gì sánh được
Thật ấm lòng khi biết rằng vẫn có người muốn làm những thứ như thế này bằng tay trực tiếp. Hóa ra không chỉ có mình tôi
Nếu có dự án tương tự nào tôi rất muốn xem, và thật vui vì không chỉ có mình tôi. Tôi nghĩ rằng nếu phần lớn lập trình viên dành vài tuần hay vài tháng để học assembly thì cảm giác bí ẩn về cách CPU và các ngôn ngữ biên dịch hoạt động sẽ giảm đi rất nhiều
Dự án thú vị đấy. Tôi có làm một phiên bản tối giản hơn nhiều cho x86 Linux, nếu muốn xem nó trông thế nào thì ở đây: https://github.com/jcalvinowens/asmhttpd
Tôi muốn hỏi liệu có thể thêm liên kết tới repo của bạn vào README của mình không
Cái bìa sách O'Reilly giả đó đúng là đỉnh thật
Dù là một so sánh có phần vô nghĩa, tôi vẫn tò mò không biết hiệu năng của nó ra sao khi so với các web server đầy đủ tính năng. Tôi muốn xem các chỉ số như số request tối đa mỗi giây
ymawky dùng mô hình
forkcho mỗi kết nối, nên về bản chất nó chậm hơn cách mà các server phục vụ production như nginx hay Apache sử dụng. nginx dùng I/O hướng sự kiện vớikqueue/epoll, nhờ đó có thể xử lý hàng nghìn kết nối đồng thời mà không có chi phí fork process cho từng request. Apache dùng thread pool để xử lý nhiều kết nối mà không cần tạo mới cho từng requestNếu so trực diện với các web server khác thì phần lớn bạn chỉ đang đo sự khác biệt giữa fork cho mỗi kết nối và event loop/thread pool, chứ chẳng liên quan mấy đến assembly
Nếu so với một server cũng fork cho mỗi kết nối nhưng viết bằng C, tôi đoán thông lượng sẽ gần như tương đương. Nút thắt của mô hình này không nằm ở đoạn mã thực tế mà ở chính
fork()vì nó. Có lẽ nó ảnh hưởng đến kích thước binary và thời gian khởi động nhiều hơn là số request mỗi giây. Dù vậy, benchmark thực tế chắc vẫn sẽ rất thú vịLàm tốt lắm. Tôi cũng đang làm một dự án tương tự nhưng nhỏ hơn bằng RISC-V, và cái này thật sự rất tuyệt
Trong lúc thế giới vibe coding này cứ đi theo hướng của nó, tôi lại muốn cố tình đi ngược chiều và tìm lại cảm giác được thử thách bằng cách viết một software renderer WebAssembly
Tôi không biết có thể hoàn thành nó không, nó khá điên rồ và cũng khó gọi là hữu ích. Nhưng cảm giác thì thực sự rất tuyệt
Xin chúc mừng thành tựu của tác giả gốc
Sau khi hoàn thành, tôi đang dùng nó để làm game, nhưng giờ phần thú vị của thử thách đã hết nên tiến độ bên đó không được bao nhiêu. Dù sao cũng không sao, vì nó rất vui. Nếu làm bằng vibe coding thì tôi đã không có được niềm vui hay sự thỏa mãn đó
Tôi từng thử bắt LLM viết renderer cho CGA bằng 8088 assembly thuần chỉ để xem nó làm tốt đến đâu, và nó đã tạo ra một bản demo khá ổn ngay từ lần đầu. Trong prompt tôi đã đưa vào các vector của tàu Elite
https://imgur.com/a/Dy5rUku
Một trong những dự án assembly đầu tiên của tôi là một script CGI viết 100% bằng x86 assembly
Một web server hoàn chỉnh tất nhiên ấn tượng hơn hẳn. Nhưng nếu là người mới bắt đầu, tôi vẫn muốn khuyên hãy thử tìm hiểu CGI của Apache và
mod_cgitrướcTôi đã nghĩ về hỗ trợ CGI từ vài tuần trước nhưng vẫn chưa thực sự đào sâu. Nếu có chỗ nào host nó thì tôi rất muốn xem, có lẽ sau này khi bắt tay vào làm sẽ là tài liệu tham khảo tốt
Chúng ta đang chuyển sang AI, ngừng tự viết code và vắt óc suy nghĩ, còn ở đây lại có người viết web server bằng assembly
Khiến người ta phải khiêm tốn lại