// Формирование набора байт для отправки func Serialize(fin bool, rsvs [3]bool, frame_type byte, mask bool, mask_key [4]byte, data_len uint64, data io.Reader) io.Reader { if frame_type > 0xF { // Тип (опкод) не может быть больше 15 panic(FrameOpcodeError) } // Размер данных header := make([]byte, 0, 16) var v byte = frame_type if fin { v |= 0x80 } for t := byte(0); t < 3; t++ { if rsvs[t] { v |= byte(0x40) >> t } } header = append(header, v) if mask { v = 0x80 } else { v = 0 } if data_len < 126 { v |= byte(data_len) header = append(header, v) } else if data_len <= 0xFFFF { v |= 126 header = append(header, v) header = append(header, byte(0xFF&(data_len>>8))) header = append(header, byte(0xFF&data_len)) } else { v |= 127 header = append(header, v) for i := int8(7); i > -1; i-- { header = append(header, byte(0xFF&(data_len>>(8*byte(i))))) } } var conv IoUtils.Converter if mask { header = append(header, mask_key[:]...) conv = &frame_data_converter{mask_key: mask_key} } return IoUtils.Serialize(header, data, conv, nil) } // func (f *Frame) Serialize() (res []byte)
func SerializeBigResponse(resp_code uint16, resp_what string, head_params []HeaderParam, body io.Reader) io.Reader { header_strs := make([]string, len(head_params)+2) header_strs[0] = strings.Join([]string{http_version, strconv.Itoa(int(resp_code)), resp_what}, " ") header_strs[len(header_strs)-1] = endline_str for i, p := range head_params { header_strs[i+1] = p.Serialize() } header := strings.Join(header_strs, endline_str) return IoUtils.Serialize([]byte(header), body, nil, nil) }
// Формирование большого запроса http в виде набора байт для отправки по сети func SerializeBigRequest(req_type, req_host string, head_params []HeaderParam, body io.Reader) io.Reader { header_strs := make([]string, len(head_params)+2) header_strs[0] = strings.Join([]string{req_type, req_host, http_version}, " ") header_strs[len(header_strs)-1] = endline_str for i, p := range head_params { header_strs[i+1] = p.Serialize() } header := strings.Join(header_strs, endline_str) return IoUtils.Serialize([]byte(header), body, nil, nil) }
// Разбор полученных данных func (p *BigFrameParser) Parse() (res []BigFrame) { for len(p.unworked_data) > 0 { if p.data_writer != nil { panic(errors.New("Не закончили запись данных предыдущего пакета, а уже есть данные для нового")) } // Начинаем формировать новый пакет head_len := 2 // Длина заголовка (минимум 2 байта) data_len := len(p.unworked_data) if data_len < head_len { // Недостаточно данных даже для формирования заголовка return } if (0x80 & p.unworked_data[1]) != 0 { // В заголовке присутствует маска - +4 байта к заголовку head_len += 4 } if ln_param := 0x7F & p.unworked_data[1]; ln_param == 126 { // Поле длины пакета занимает лишние 2 байта head_len += 2 } else if ln_param == 127 { // Поле длины пакета занимает лишние 8 байт head_len += 8 } if data_len < head_len { // Недостаточно данных даже для формироваиня заголовка return } // Формируем заголовок пакета new_frame := BigFrame{} new_frame.Fin = (0x80 & p.unworked_data[0]) != 0 for t := byte(0); t < 3; t++ { new_frame.Rsvs[t] = (p.unworked_data[0] & (byte(0x40) >> t)) != 0 } new_frame.Type = 0xF & p.unworked_data[0] new_frame.Mask = (0x80 & p.unworked_data[1]) != 0 if new_frame.Mask { for i := 0; i < 4; i++ { new_frame.MaskKey[i] = p.unworked_data[head_len-4+i] } } data_sz := uint64(0x7F & p.unworked_data[1]) if data_sz == 126 { data_sz = 0 for _, v := range p.unworked_data[2:4] { data_sz <<= 8 data_sz |= uint64(v) } } else if data_sz > 126 { data_sz = 0 for _, v := range p.unworked_data[2:10] { data_sz <<= 8 data_sz |= uint64(v) } } p.unworked_data = p.unworked_data[head_len:] if len(p.unworked_data) == 0 { p.unworked_data = nil } // Формируем данные пакета if data_sz <= uint64(len(p.unworked_data)) { // Считано достаточно данных для форрмирования тела frame_data := p.unworked_data[:data_sz] p.unworked_data = p.unworked_data[data_sz:] if len(p.unworked_data) == 0 { p.unworked_data = nil } if new_frame.Mask { // Задана маска - расшифровываем данные for i := range frame_data { frame_data[i] = frame_data[i] ^ new_frame.MaskKey[i%4] } } new_frame.Data = bytes.NewReader(frame_data) } else { // Всё тело ещё не считали var one_piece_max_sz int = int(data_sz) var chan_sz uint16 = 2 if one_piece_max_sz > 10240 { one_piece_max_sz = 10240 chan_sz = 10 } reader, writer := IoUtils.NonBlockingPipe(one_piece_max_sz, chan_sz) p.data_writer = IoUtils.LimitWriteCloser(writer, int64(data_sz)) var conv IoUtils.Converter if new_frame.Mask { conv = &frame_data_converter{mask_key: new_frame.MaskKey} } new_frame.Data = IoUtils.Serialize(nil, io.LimitReader(reader, int64(data_sz)), conv, nil) if p.unworked_data != nil { sz, e := p.data_writer.Write(p.unworked_data) if (sz < len(p.unworked_data)) || (e != nil) { // Были записаны не все данные panic(errors.New("Ошибка записи тела запроса")) // Возможно, стоит убрать } p.unworked_data = nil } } // Пакет сформирован res = append(res, new_frame) } // for len(r.unworked_data) > 0 return } // func (p *BigFrameParser) Parse() (res []BigFrame)