package main import ( "encoding/json" "log" "net" ) const ( MESSAGE = "message" AUTHENTICATE = "authenticate" RENAME = "rename" ) const ( SUCCESS = "success" FAILURE = "failure" ) type Message struct { Type string Data string User string } type Response struct { Status string Data string } func parseMessage(data []byte) Message { var m Message // TODO(andrew): Добавить обработку ошибок json.Unmarshal(data, &m) return m } func toBytes(num uint32) []byte { buf := make([]byte, 4) var mask uint32 = 0x00FF for i := 0; i < 4; i += 1 { buf[4-i-1] = byte(num & mask) num >>= 8 } return buf } func fromBytes(data []byte) uint32 { var num uint32 for i := 0; i < 4; i += 1 { num += uint32(data[i] << ((4 - i - 1) * 8)) } return num } func sendMessage(conn net.Conn, message []byte) error { size := uint32(len(message)) _, err := conn.Write(toBytes(size)) if err != nil { return err } _, err = conn.Write(message) if err != nil { return err } return nil } func handleConnection(conn net.Conn) { defer conn.Close() // 1 мегабайт var maxBodySize uint32 = 1048576 maxAuthAttempts := 5 authAttempts := 0 authenticated := false buf := make([]byte, 256) for { if authAttempts >= maxAuthAttempts { resp, _ := json.Marshal(Response{ Status: FAILURE, Data: "Превышено количество неавторизованных запросов", }) _ = sendMessage(conn, resp) break } _, err := conn.Read(buf) if err != nil { break } size := fromBytes(buf[:4]) if size > maxBodySize { resp, _ := json.Marshal(Response{ Status: FAILURE, Data: "Превышен максимальный размер запроса", }) _ = sendMessage(conn, resp) break } rawMessage := buf[4 : size+4] message := parseMessage(rawMessage) //fmt.Println(message.Data) if message.Type == AUTHENTICATE { // TODO(andrew): Добавить процесс аутентификации if true { authenticated = true } } if !authenticated { resp, _ := json.Marshal(Response{ Status: FAILURE, Data: "Для работы с сервером необходима аутентификация", }) err = sendMessage(conn, resp) if err != nil { break } authAttempts += 1 continue } if message.Data == "exit" { break } resp, _ := json.Marshal(Response{ Status: SUCCESS, Data: "some data", }) err = sendMessage(conn, resp) if err != nil { break } } } func main() { sock, err := net.Listen("tcp", "localhost:8080") defer sock.Close() handleError(err) for { conn, err := sock.Accept() if err == nil { go handleConnection(conn) } else { handleError(err) } } } func handleError(err error) { if err != nil { log.Fatal(err) } }