Go မှာအခြေခံ Web Server တခုရေးဖို့ ဘာတွေလိုအပ်မလဲ
ဟိုနေ့က Rust နဲ့ HTTP web server လေးရေးကြည့်တယ်ဆိုတဲ့ post တွေ့လို့ စဥ်းစားကြည့်မိတယ်။ သူက Rust သုံးထားပြီးသားဆိုတော့ ကိုယ်က Go ဖက်က စဉ်းစားကြည့်တာပေါ့။
Go အတွက်ဆိုရင် ဒါက net.Listen တို့၊ net.Conn.Read တို့တွေကို ကိုယ်တိုင် implement လုပ်ရမယ်ဆိုတဲ့သဘောပါပဲ။ အဲဒီတော့ syscall တွေသုံးရမယ်။ socket binding လုပ်ရမှာမလို့ အဓိက syscall.Socket, syscall.Bind, syscall.Listen, syscall.Accept သုံးရမယ်။ Byte stream ကိုဖတ်ဖို့အတွက် syscall.Recvfrom နဲ့ Read လိုမယ်။ client ဆီ Byte ပြန်ရေးဖို့အတွက် syscall.Sendto နဲ့ Write တွေ လိုမယ်။ နောက်ပြီး File descriptors တွေသိရမယ်။ concurrent connection တွေကိုကိုင်တွယ်ဖို့ epoll တို့ kqueue တို့သုံးရမယ်။ Byte stream တွေကို ကိုယ့်ဟာကိုယ် parse ရမယ်။ HTTP compliant byte sequence တွေဆောက်ရမယ်။ ဒါမျိုးပေါ့ အကြမ်းဖျင်းကတော့။
fd, _ := syscall.Socket(syscall.AF_INET, syscall.SOCK_STREAM, syscall.IPPROTO_TCP)
addr := syscall.SockaddrInet4{Port: 8080}
copy(addr.Addr[:], net.ParseIP("0.0.0.0").To4())
syscall.Bind(fd, &addr)
syscall.Listen(fd, syscall.SOMAXCONN)
for {
nfd, _, _ := syscall.Accept(fd)
go func(fd int) {
buf := make([]byte, 4096)
n, _ := syscall.Read(fd, buf)
resp := "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\nHello"
syscall.Write(fd, []byte(resp))
syscall.Close(fd)
}(nfd)
}
ဆိုတော့ Go သုံးပြီး Web server ဆောက်မယ်ဆိုရင်
- parsing ကိုယ့်ဟာကိုယ် လုပ်ရမယ်။
- raw byte တွေနဲ့ အလုပ်လုပ်ရမယ်။
- TCP ဆိုတာ message-based protocol မဟုတ်တဲ့အတွက် TCP stream boundaries ကိုကိုင်တွယ်နိုင်ဖို့ လိုမယ်။ ဆိုလိုချင်တာက UDP လိုမျိုး message unit နဲ့မဟုတ်တဲ့အတွက် message တခုဘယ်မှာစပြီး ဘယ်မှာဆုံးတယ်ဆိုတာ ကိုယ်က သိရမယ်။ client တွေကို enforce လုပ်နိုင်ရမယ်။ HTTP protocol မှာဆိုရင် delimiter နဲ့ Content-Length သုံးတာကို မြင်ဖူးကြလိမ့်မယ်။ ဒါပေမယ့် အခုလို ကိုယ်ပိုင် server ရေးမယ်ဆိုရင်တော့ client ကြေညာလာတဲ့ length နဲ့ content မကိုက်တာမျိုးတွေကို aware ဖြစ်ရမယ်ပေါ့။
- parsing မှာ attacker တွေရဲ့ ထောင်ချောက်မိပြီး infinite loop တွေထဲ ညှပ်မနေဖို့ သတိထားရမယ်။ ဥပမာ endless marshaling loop ဖြစ်စေပြီး DDos လုပ်ဖို့ ကြံတာမျိုးတွေ ရှောင်နိုင်ရမယ်။
- concurrency ကိုကိုယ့်ဘာသာ goroutine တွေ၊ channel တွေ၊ context တွေနဲ့ manage လုပ်ရမယ်။
client byte stream တွေရဲ့ nature ကိုကြိုနားလည်ထားပြီး performance ရှယ် tweak ဖို့လိုအပ်တာတို့၊ security tools တွေ (ဥပမာ intrusion detection ဘာညာ) ရေးချင်တာတို့၊ ဒါမှမဟုတ် ကိုယ်ပိုင် proxy စမ်းရေးကြည့်ချင်တာတို့ဆိုရင် အခုလို system level programming လုပ်ဖို့လိုမှာပေါ့လေ။ မဟုတ်ရင်တော့ နဂိုပါပြီးသား http.ListenAndServe() တကြောင်းနဲ့တင် လုံလောက်တာထက် ပိုပါတယ်ခင်ဗျာ။