func OneConnectionCheck(addr string, num uint64, t *testing.T) { conn, err := net.Dial("tcp", addr) if err != nil { t.Errorf("Ошибка подключения: %s\n", err.Error()) return } defer conn.Close() req_body := make([]byte, 100) for t := range req_body { req_body[t] = byte((uint64(t) + num) % 0xFF) } head_params := []HttpUtils.HeaderParam{{Name: HttpUtils.BodySizeParamName, Value: strconv.Itoa(len(req_body))}} var unworked_data []byte buf := make([]byte, 1000) for n := uint64(0); n < 5; n++ { for t := range req_body { req_body[t] = byte((uint64(t)*n + num) % 0xFF) } // Шлём запрос req := HttpUtils.MakeRequest("GET", "/", head_params, req_body) data := req.Serialize() for sz, e := conn.Write(data); (sz > 0) && (len(data) > 0); sz, e = conn.Write(data) { if e != nil { t.Errorf("Ошибка записи %s\n", e.Error()) return } data = data[sz:] } // Получаем и обрабатываем ответ for sz, e := conn.Read(buf); sz > 0; sz, e = conn.Read(buf) { if e != nil { t.Errorf("Ошибка чтения %s\n", e.Error()) return } unworked_data = append(unworked_data, buf[:sz]...) resp, uw_data, succ := HttpUtils.ParseOneResp(unworked_data) unworked_data = uw_data if !succ { t.Fatal("Получили мусор в ответ на запрос") } else if resp != nil { if resp.Code != 200 { t.Errorf("Получили ответ с кодом %i, отличным от 200\n", resp.Code) return } else if resp.What != "OK" { t.Errorf("Получили ответ с описанием %s, отличным от OK\n", resp.What) return } else if bytes.Compare(req.Body, resp.Body) != 0 { t.Error("Тело ответа отличается от тела запроса") return } else if len(req.HeaderParams) != len(resp.HeaderParams) { t.Error("Параметры запроса отличаются от параметров ответа") return } for i, v := range resp.HeaderParams { if (req.HeaderParams[i].Name != v.Name) || (req.HeaderParams[i].Value != v.Value) { t.Error("Параметры запроса отличаются от параметров ответа") return } } break } } // for sz, e := conn.Read(buf); sz > 0; sz, e = conn.Read(buf) } // for n := 0; n < 100; n++ if len(unworked_data) > 0 { t.Error("Остались необработанные данные") } } // func OneConnectionCheck(addr string, num byte, t *testing.T)
func OneWebsockConnectionCheck(addr string, N uint64, t *testing.T) { conn, err := net.Dial("tcp", addr) if err != nil { t.Errorf("Ошибка подключения: %s\n", err.Error()) return } defer conn.Close() // Переходим на протокол веб-сокетов ws_key := "Iv8io/9s+lYFgZWcXczP8Q==" head_params := []HttpUtils.HeaderParam{{"Upgrade", "websocket"}, {"Connection", "Upgrade"}, {"Sec-WebSocket-Key", ws_key}} req := HttpUtils.MakeRequest("GET", "/", head_params, nil) data := req.Serialize() var sz int var e error for sz, e = conn.Write(data); (sz > 0) && (len(data) > 0); sz, e = conn.Write(data) { data = data[sz:] } if len(data) > 0 { if e == nil { t.Fatal("Запрос отправлен не полностью, ошибка - nil") } else { t.Fatalf("Запрос отправлен не полностью, ошибка - %s\n", e.Error()) } } // Ждём ответ buf := make([]byte, 100) var unworked_data []byte var resp *HttpUtils.HttpResponse for sz, _ := conn.Read(buf); sz > 0; sz, _ = conn.Read(buf) { unworked_data = append(unworked_data, buf[:sz]...) r, uw, succ := HttpUtils.ParseOneResp(unworked_data) resp = r unworked_data = uw if !succ || (resp != nil) { break } } if resp == nil { t.Fatal("Подтверждение не было получено") } if len(unworked_data) > 0 { t.Error("Остались необработанные данные") } // Проверяем ответ if resp.Code != 101 { t.Fatalf("Ошибка HTTP, код %d\n, ожидали 101", resp.Code) } var chks [3]bool for _, param := range resp.HeaderParams { if param.Name == "Upgrade" { if param.Value != "websocket" { t.Fatalf("Ошибка подтверждения: поле %s равно %s\n", param.Name, param.Value) } chks[0] = true } else if param.Name == "Connection" { if param.Value != "Upgrade" { t.Fatalf("Ошибка подтверждения: поле %s равно %s\n", param.Name, param.Value) } chks[1] = true } else if param.Name == "Sec-WebSocket-Accept" { expected_key := WebsocketUtils.GetAcceptKey(ws_key) if param.Value != expected_key { t.Fatalf("Ошибка подтверждения: поле %s равно %s вместо %s\n", param.Name, param.Value, expected_key) } chks[2] = true } } // for _, param := range resp.HeaderParams if !chks[0] { t.Fatal("Подтверждение не содержит поля Upgrade") } else if !chks[1] { t.Fatal("Подтверждение не содержит поля Connection") } else if !chks[2] { t.Fatal("Подтверждение не содержит поля Sec-WebSocket-Accept") } // Проверка отправки/получения пакетов var reader WebsocketUtils.FrameParser for num := 0; num < 100; num++ { v := (num % 2) == 0 var mask_key [4]byte for j := 0; j < 4; j++ { mask_key[j] = byte((j*num + int(N)) % 0xFF) } f := WebsocketUtils.Frame{Fin: v, Rsvs: [3]bool{v, !v, v}, Type: byte(num) % 0xF, Mask: v, MaskKey: mask_key} f.Data = make([]byte, 0, 1000) for j := 0; j < 1000; j++ { f.Data = append(f.Data, byte((j*num+int(N))%0xFF)) } f_ser := f.Serialize() for s, e := conn.Write(f_ser); (len(f_ser) > 0) && (s > 0); s, e = conn.Write(f_ser) { if e != nil { t.Fatalf("Ошибка отправки %s\n", e.Error()) } f_ser = f_ser[s:] } if len(f_ser) > 0 { t.Fatal("Не весь пакет был отправлен") } var f_rcv *WebsocketUtils.Frame for s, _ := conn.Read(buf); s > 0; s, _ = conn.Read(buf) { reader.Write(buf[:s]) if rcv_f := reader.Parse(); len(rcv_f) > 0 { // Получили пакет f_rcv = &(rcv_f[0]) break } else if s < len(buf) { break } } // Сравниваем отправленный пакет и полученный if f_rcv == nil { t.Fatal("Ответный пакет не был получен") } else if f.Type != f_rcv.Type { t.Fatalf("Неверный тип полученного пакета: ожидали %d, получили %d\n", f.Type, f_rcv.Type) } else if bytes.Compare(f.Data, f_rcv.Data) != 0 { t.Fatal("Неверные данные в полученном пакете") } } // for num := 0; num < 100; num++ } // func OneWebsockConnectionCheck(addr string, num byte, t *testing.T)