// Формирование набора байт для отправки
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)
示例#2
0
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)
}
示例#3
0
// Формирование большого запроса 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)