func (parser *BigRequestsParser) Parse() (res []*HttpBigRequest) { if (parser.body_writer != nil) && (len(parser.unworked_data) != 0) { panic(errors.New("(parser.body_writer != nil) && (len(parser.unworked_data) != 0)")) } req_identifier := []byte(http_version + endline_str) // Признак запроса (версия HTTP + символы конца строки) endl := []byte(endline_str) for len(parser.unworked_data) > 0 { if parser.unfinished_req == nil { // Обрабатываем накопленные данные как начало нового запроса p_req_id := bytes.Index(parser.unworked_data, req_identifier) p_endl := -1 if p_req_id >= 0 { p_endl = bytes.LastIndex(parser.unworked_data[:p_req_id], endl) } else { p_endl = bytes.LastIndex(parser.unworked_data, endl) } if p_req_id < 0 { // Признак запроса не был обнаружен if p_endl > 0 { // ...но был обнаружен переход на новую строку - ошибка parser.unworked_data = parser.unworked_data[p_endl+len(endline_str):] if len(parser.unworked_data) == 0 { parser.unworked_data = nil } res = append(res, nil) } return } else { p_req_id += len(req_identifier) } if p_endl < 0 { p_endl = 0 } else { // Обнаружен переход на новую строку перед признаком запроса res = append(res, nil) p_endl += len(endline_str) } // Найден признак запроса req_head_line := string(parser.unworked_data[p_endl:p_req_id]) parser.unworked_data = parser.unworked_data[p_req_id:] if len(parser.unworked_data) == 0 { parser.unworked_data = nil } params := strings.Split(req_head_line, " ") if len(params) == 3 { // Нашли заголовок запроса parser.unfinished_req = &HttpBigRequest{Type: params[0], Host: params[1]} } else { // Неверный заголовок res = append(res, nil) continue } } // if parser.unfinished_req == nil // Формируем параметры заголовка param_error := false pos := bytes.Index(parser.unworked_data, endl) for ; pos >= 0; pos = bytes.Index(parser.unworked_data, endl) { // Формируем строку с параметром (без символа перехода на следующую строку) // и отрезаем обработанный кусок данных от необработанных данных (вместе с символом перехода) one_param_str := string(parser.unworked_data[:pos]) parser.unworked_data = parser.unworked_data[pos+len(endl):] if len(parser.unworked_data) == 0 { parser.unworked_data = nil } if pos == 0 { // Дошли до конца заголовка break } // Обрабатываем параметр заголовка param, success := param_parser(one_param_str) if success { // Обработали один параметр - добавляем его е запросу parser.unfinished_req.HeaderParams = append(parser.unfinished_req.HeaderParams, param) } else { // Ошибка разбора параметра заголовка parser.unfinished_req = nil res = append(res, nil) param_error = true break } } // for ; pos >= 0; pos = bytes.Index(parser.unworked_data, endl) if param_error { // При разборке параметров заголовка произошла ошибка continue } else if pos < 0 { // Символ перехода на следующую строку не найден - больше обрабатывать нечего return } // Если попали сюда - параметры заголовка считаны полностью, // дальше идёт тело и/или следующий запрос var body_len int = len(parser.unworked_data) for _, param := range parser.unfinished_req.HeaderParams { if param.Name == BodySizeParamName { // Обнаружили параметр длины тела var e error body_len, e = strconv.Atoi(param.Value) if e != nil { // Некорректное значение параметра длины parser.unfinished_req = nil res = append(res, nil) param_error = true } break } // if param.Name == BodySizeParamName } // for _, param := range parser.unfinished_req.HeaderParams if param_error { continue } if body_len <= len(parser.unworked_data) { // В необработанных данных уже содержится всё тело запроса parser.unfinished_req.Body = bytes.NewReader(parser.unworked_data[:body_len]) parser.unworked_data = parser.unworked_data[body_len:] if len(parser.unworked_data) == 0 { parser.unworked_data = nil } } else if body_len != 0 { // Всё тело ещё не считали var one_piece_max_sz int = body_len 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) parser.body_writer = IoUtils.LimitWriteCloser(writer, int64(body_len)) parser.unfinished_req.Body = io.LimitReader(reader, int64(body_len)) if parser.unworked_data != nil { sz, e := parser.body_writer.Write(parser.unworked_data) if (sz < len(parser.unworked_data)) || (e != nil) { // Были записаны не все данные panic(errors.New("Ошибка записи тела запроса")) // Возможно, стоит убрать } parser.unworked_data = nil } } res = append(res, parser.unfinished_req) parser.unfinished_req = nil } // for len(parser.unworked_data) > 0 return res } // func (p *BigRequestsParser) Parse() []*HttpBigRequest
// Разбор полученных данных 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)