Skip to content

Поддержка протокола WebSocket на 2.0 от нативного веб сервера#112

Open
Nivanchenko wants to merge 9 commits intomasterfrom
feat/native_ws
Open

Поддержка протокола WebSocket на 2.0 от нативного веб сервера#112
Nivanchenko wants to merge 9 commits intomasterfrom
feat/native_ws

Conversation

@Nivanchenko
Copy link
Member

No description provided.

@coderabbitai
Copy link

coderabbitai bot commented Sep 16, 2025

Warning

Rate limit exceeded

@Nivanchenko has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 3 minutes and 38 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between b634d82 and 0033997.

📒 Files selected for processing (1)
  • tests/alltest.os (9 hunks)

Walkthrough

Добавлена нативная поддержка WebSocket: сервер обрабатывает Upgrade и регистрирует соединения; добавлены классы соединения, подписки, фабрики и мок‑шифрование; формирование параметров переключено с Структура на Соответствие; обновлены декларации экспортируемых переменных шифрования.

Changes

Cohort / File(s) Summary
Нативный WebSocket сервер
src/Классы/НативныйВебСервер.os
Включение WebSocket (ИспользоватьВебСокеты), обработка апгрейда, подключение контекстного сокета, создание/инициализация СоединениеВебСокета, регистрация в реестре и ввод в ожидание жизненного цикла; добавлены глобальные СоединенияВебСокетов, Поделка.
Обёртка соединения
src/Классы/СоединениеВебСокета.os
Новый модуль: публичные globals Сокет, Активно, Контекст; тип &Желудь с конструктором; методы Закрыть, СокетАктивен, ОтправитьСтроку, ОтправитьДвоичныеДанные.
Подписка и цикл обработки
src/Классы/ПодпискаНаВебСокетНативная.os
Новый модуль: API Подписатся, Отписаться, ЗапуститьОбработкуСообщений; фоновый цикл чтения строк из сокета, делегирование брокеру, обработка исключений, удаление соединения и уведомление брокера при отключении.
Фабрика WebSocket
src/Классы/ФабрикаВебСокетов.os
Выбор реализации (нативная/прикладная) по настройкам/версии; экспорт ПодпискаНаВебСокет() и ШифрованиеВебСокетаОбщий(); хранит дескриптор Поделка.
Мок шифрования/фреймов
src/Классы/ШифрованиеВебСокетаМок.os
Новый модуль: МагическаяСтрока, ХешОтветаРукопожатия, ЗапаковатьСообщениеТекстовоеСообщение, РаспаковатьСообщение (возвращает структуру с ТипСообщения = 1).
Брокер сообщений
src/Классы/БрокерСообщенийВебСокетов.os
Переход с Структура(...) на Соответствие при формировании параметров входящих сообщений и при обработке подписки; изменена публичная декларация переменной шифрования — введён макросный wrapper ШифрованиеВебСокетаОбщий и отдельная Перем ШифрованиеВебСокета.
Фабрика ответов
src/Классы/ФабрикаОтветов.os
Обновлено объявление экспортируемой переменной: &Пластилин("ШифрованиеВебСокетаОбщий") Перем ШифрованиеВебСокета;.
Состояния WebSocket
src/Модули/СостоянияВебСокетов.os
Добавлена экспортная функция Открыт() — возвращает значение состояния открытого сокета через Выполнить.
Тесты
tests/alltest.os
Добавлен флаг версии ЭтоВерсия2, увеличен таймаут в HTTP тестах, активированы/переписаны тесты handshake и WebSocket с ветвлением по версии.
Документация
README.md, docs/product/index.md
README переработан: удалён/упрощён Hello World, добавлен раздел Документация с внешней ссылкой, обновлён Disclaimer и секция Контейнеризация; в docs удалён дублирующий линк.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant Клиент
  participant Сервер as НативныйВебСервер
  participant Контекст as Контекст.ВебСокеты
  participant Поделка
  participant Соединение as СоединениеВебСокета
  participant Реестр as СоединенияВебСокетов
  participant Подписка as ПодпискаНаВебСокетНативная
  participant Брокер as БрокерСообщенийВебСокетов

  Клиент->>Сервер: HTTP с Upgrade (WebSocket)
  Сервер->>Контекст: ПодключитьВебСокет()
  Контекст-->>Сервер: сокет
  Сервер->>Поделка: НайтиЖелудь("СоединениеВебСокета")
  Поделка-->>Сервер: экземпляр Соединение
  Сервер->>Соединение: Установить Сокет/Контекст/Активно
  Сервер->>Реестр: Добавить(Соединение, Идентификатор, Топик)
  Сервер->>Подписка: Подписатся(Соединение, Идентификатор, Топик)
  Подписка->>Брокер: ПриПодключении(Топик, Идентификатор)
  loop Пока сокет открыт
    Соединение->>Подписка: ПолучитьСтроку()
    Подписка->>Брокер: ВходящееСообщение(Идентификатор, Топик, Текст)
  end
  alt Закрытие/ошибка
    Подписка->>Реестр: УдалитьСоединение(Соединение)
    Подписка->>Брокер: ПриОтключении(Топик, Идентификатор)
    Соединение->>Соединение: Закрыть()
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60–90 minutes

Possibly related PRs

  • Feat/native ws #94 — Похожая интеграция нативного WebSocket и связанные изменения в сервере, фабриках и классах.

Poem

Я кролик в коде, в миг апгрейда прыг —
Сокеты, фабрики, брокер в стройный миг.
Соответствие вместо Структуры я принёс,
Подписка читает строки — брокер их внос.
Морковкой помечаю коммит — вперёд, команда, рис! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning Описание пулл‑реквеста отсутствует (поле описания не заполнено), поэтому нет явного текста, связывающего цели и изменения PR с кодовой базой; это мешает быстрой оценке и аудиту изменений. Отсутствие описания не проходит проверку, так как ожидается хотя бы минимальная связанная сводка. Попросите автора добавить краткое описание: цель и мотивация изменений, ключевые файлы и модули (например: src/Классы/НативныйВебСервер.os, src/Классы/СоединениеВебСокета.os, src/Классы/ПодпискаНаВебСокетНативная.os, src/Классы/ФабрикаВебСокетов.os, src/Классы/ШифрованиеВебСокетаМок.os, обновлённые тесты и README), указать возможные ломания API (новые глобальные переменные и изменение декларации ШифрованиеВебСокета) и дать краткие инструкции по тестированию/миграции.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed Заголовок краток и однозначно отражает основную цель PR — добавление поддержки протокола WebSocket в нативном веб‑сервере для версии 2.0, что согласуется с изменениями в raw_summary (добавлены модули для WebSocket и изменения в НативныйВебСервер и фабрике). Формулировка понятна команде при просмотре истории коммитов и фокусируется на главном изменении.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Nivanchenko Nivanchenko changed the title Поддержка веб сокета на 2.0 от нативного веб сервера Поддержка протокола WebSocket на 2.0 от нативного веб сервера Sep 16, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/Классы/БрокерСообщенийВебСокетов.os (1)

27-71: Большинство типов сообщений WebSocket не реализовано

В обработке входящих сообщений есть заготовки для всех типов фреймов WebSocket (0-16), но реализована только обработка текстовых сообщений (тип 1). Отсутствует обработка важных типов: Ping (9), Pong (10), Close (8).

Хотите, чтобы я создал задачу на реализацию обработки остальных типов сообщений WebSocket?

🧹 Nitpick comments (9)
src/Классы/ФабрикаОтветов.os (1)

33-45: Проверьте обработку ошибок при формировании WebSocket handshake

Метод ОтветРукопожатияВебСокета не проверяет валидность Запрос.КлючРукопожатия перед передачей в ШифрованиеВебСокета.ХешОтветаРукопожатия(). Рекомендую добавить проверку на заполненность ключа.

 Функция ОтветРукопожатияВебСокета(Запрос) Экспорт
 	Ответ = ПустойОтвет();
 
 	Ответ.СостояниеКод = 101;
 	Ответ.СостояниеТекст = "Switching Protocol";
 
+	Если НЕ ЗначениеЗаполнено(Запрос.КлючРукопожатия) Тогда
+		ВызватьИсключение "Отсутствует ключ рукопожатия WebSocket";
+	КонецЕсли;
+	
 	Ответ.Заголовки["Sec-WebSocket-Accept"] = ШифрованиеВебСокета.ХешОтветаРукопожатия(Запрос.КлючРукопожатия);
src/Классы/ФабрикаВебСокетов.os (1)

23-29: Несоответствие в именовании: Mock vs Общий

Функция ШифрованиеВебСокетаОбщий возвращает ШифрованиеВебСокетаМок для нативного сервера. Название "Мок" подразумевает тестовую заглушку, но судя по коду в ШифрованиеВебСокетаМок.os, это рабочая реализация.

Рекомендую переименовать ШифрованиеВебСокетаМок в ШифрованиеВебСокетаНативное для ясности:

 Функция ШифрованиеВебСокетаОбщий() Экспорт
 	Если ИспользоватьНативныйСервер Тогда
-		Возврат Поделка.НайтиЖелудь("ШифрованиеВебСокетаМок");
+		Возврат Поделка.НайтиЖелудь("ШифрованиеВебСокетаНативное");
 	Иначе
 		Возврат Поделка.НайтиЖелудь("ШифрованиеВебСокета");	
 	КонецЕсли;
 КонецФункции
src/Классы/НативныйВебСервер.os (1)

68-69: Проверьте инициализацию сессии

Код предполагает, что Запрос.Сессия всегда инициализирована. Добавьте проверку на Неопределено.

+		Если Запрос.Сессия = Неопределено Тогда
+			ВызватьИсключение "Сессия не инициализирована для WebSocket соединения";
+		КонецЕсли;
 		Идентификатор = Запрос.Сессия.Идентификатор();
 		Топик = Запрос.Путь;
src/Классы/ШифрованиеВебСокетаМок.os (2)

3-5: Пустая процедура инициализации

Процедура ПриСозданииОбъекта пуста. Если инициализация не требуется, можно удалить эту процедуру.

-&Желудь
-Процедура ПриСозданииОбъекта()
-
-КонецПроцедуры

25-30: Жёстко закодированный тип сообщения

Функция РаспаковатьСообщение всегда возвращает ТипСообщения = 1 (текстовый фрейм), что может не соответствовать реальному типу входящего сообщения.

Рекомендую либо переименовать функцию для ясности, либо добавить определение типа:

-Функция РаспаковатьСообщение(ТекстСообщения) Экспорт
+Функция РаспаковатьТекстовоеСообщение(ТекстСообщения) Экспорт
 
 	ДанныеСообщения = Новый Структура("ТипСообщения, Сообщение", 1, ТекстСообщения);
 	Возврат ДанныеСообщения;
 
 КонецФункции
src/Классы/СоединениеВебСокета.os (2)

12-17: Сделать Закрыть() идемпотентной и очищать ссылку на сокет.

Сейчас сокет закрывается без очистки ссылки и без обработки исключений.

Примените дифф:

-Процедура Закрыть() Экспорт
-	Если НЕ Сокет = Неопределено Тогда
-		Сокет.Закрыть();
-		Активно = Ложь;
-	КонецЕсли;
-КонецПроцедуры
+Процедура Закрыть() Экспорт
+	Попытка
+		Если Сокет <> Неопределено Тогда
+			Сокет.Закрыть();
+		КонецЕсли;
+	Исключение
+		Сообщить("Ошибка закрытия веб-сокета: " + ОписаниеОшибки());
+	КонецПопытки;
+	Сокет = Неопределено;
+	Активно = Ложь;
+КонецПроцедуры

19-25: Упростить проверку активности и избежать двусмысленного «НЕ X = Неопределено».

Текущая форма читается хуже и не покрывает случай, когда Сокет неопределён.

Примените дифф:

-Функция СокетАктивен() Экспорт
-	Если НЕ Сокет = Неопределено Тогда
-		Возврат Сокет.Состояние = СостояниеВебСокета.Открыт;
-	Иначе
-		Возврат Ложь;
-	КонецЕсли;
-КонецФункции
+Функция СокетАктивен() Экспорт
+	Если Сокет = Неопределено Тогда
+		Возврат Ложь;
+	КонецЕсли;
+	Возврат Сокет.Состояние = СостояниеВебСокета.Открыт;
+КонецФункции
src/Классы/ПодпискаНаВебСокетНативная.os (2)

32-39: Старт обработки: добавить более явную диагностику.

Сообщение исключения без контекста усложнит разбор инцидентов.

Примените дифф:

 Процедура ЗапуститьОбработкуСообщений() Экспорт
 	Если НЕ _Соединение = Неопределено Тогда
 		_БрокерСообщенийВебСокетов.ПриПодключении(_Топик, _Идентификатор);
 		ОбработкаСообщений();
 	Иначе
-		ВызватьИсключение "Не инициализировано соединение, невозможно запустить обработку сообщений"
+		ВызватьИсключение "Не инициализировано соединение для топика '" + Строка(_Топик) + "' (" + Строка(_Идентификатор) + ")"
 	КонецЕсли;	
 КонецПроцедуры

54-57: Сделать Отключить() идемпотентной и устойчивой к повторным вызовам.

Добавьте проверки на Неопределено, обработку ошибок и сброс состояния.

Примените дифф:

 Процедура Отключить()
-	_СоединенияВебСокетов.УдалитьСоединение(_Соединение);
-	_БрокерСообщенийВебСокетов.ПриОтключении(_Топик, _Идентификатор);
+	Если _СоединенияВебСокетов <> Неопределено И _Соединение <> Неопределено Тогда
+		Попытка
+			_СоединенияВебСокетов.УдалитьСоединение(_Соединение);
+		Исключение
+			Сообщить("Ошибка удаления соединения: " + ОписаниеОшибки());
+		КонецПопытки;
+	КонецЕсли;
+	Если _БрокерСообщенийВебСокетов <> Неопределено Тогда
+		Попытка
+			_БрокерСообщенийВебСокетов.ПриОтключении(_Топик, _Идентификатор);
+		Исключение
+			Сообщить("Ошибка уведомления брокера об отключении: " + ОписаниеОшибки());
+		КонецПопытки;
+	КонецЕсли;
+	_Включена = Ложь;
+	_Соединение = Неопределено;
 КонецПроцедуры
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 30707d5 and da635e3.

📒 Files selected for processing (7)
  • src/Классы/БрокерСообщенийВебСокетов.os (3 hunks)
  • src/Классы/НативныйВебСервер.os (3 hunks)
  • src/Классы/ПодпискаНаВебСокетНативная.os (1 hunks)
  • src/Классы/СоединениеВебСокета.os (1 hunks)
  • src/Классы/ФабрикаВебСокетов.os (1 hunks)
  • src/Классы/ФабрикаОтветов.os (1 hunks)
  • src/Классы/ШифрованиеВебСокетаМок.os (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: build (ubuntu-latest, stable)
  • GitHub Check: test (dev) / build (windows-latest, dev)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)
  • GitHub Check: test (dev) / build (windows-latest, dev)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: build (ubuntu-latest, stable)
🔇 Additional comments (10)
src/Классы/ФабрикаОтветов.os (1)

4-4: Изменение декоратора выглядит корректно

Переход на использование &Пластилин("ШифрованиеВебСокетаОбщий") обеспечивает правильное внедрение зависимости через фабрику.

src/Классы/ФабрикаВебСокетов.os (1)

14-20: Логика выбора реализации выглядит корректно

Функция ПодпискаНаВебСокет правильно выбирает между нативной и прикладной реализацией на основе флага.

src/Классы/НативныйВебСервер.os (1)

55-55: Включение WebSocket поддержки выглядит корректно

Вызов ВебСервер.ИспользоватьВебСокеты() правильно добавлен после создания сервера.

src/Классы/ШифрованиеВебСокетаМок.os (2)

7-9: Магическая строка реализована корректно

Константа соответствует RFC 6455 для WebSocket.


11-17: Реализация handshake выглядит корректно

Функция правильно реализует алгоритм генерации Sec-WebSocket-Accept согласно спецификации WebSocket.

src/Классы/БрокерСообщенийВебСокетов.os (3)

1-2: Изменение декоратора согласовано с фабрикой

Использование &Пластилин("ШифрованиеВебСокетаОбщий") корректно соответствует изменениям в ФабрикаВебСокетов.


32-37: Переход на Соответствие улучшает гибкость

Замена Структура на Соответствие для передачи параметров делает код более гибким и позволяет добавлять параметры динамически.


117-117: Стилистическое изменение оператора НЕ

Использование НЕ в верхнем регистре соответствует стилю кода в других местах файла.

src/Классы/ПодпискаНаВебСокетНативная.os (2)

12-17: DI‑конструктор выглядит корректно.

Инициализация зависимостей и флага включения — ок.


19-26: Переименовать публичный метод: «Подписатся» → «Подписаться» и сделать вызов идемпотентным

Опечатка в публичном API; неправильное имя приведёт к расхождениям при вызове. Метод должен игнорировать повторные вызовы (идемпотентность).

Примените дифф:

-Процедура Подписатся(Соединение, Идентификатор, Топик) Экспорт
+Процедура Подписаться(Соединение, Идентификатор, Топик) Экспорт
+	Если _Включена Тогда
+		Возврат;
+	КонецЕсли;
 	_Идентификатор = Идентификатор;
 	_Соединение = Соединение;
 	_Топик = Топик;
 	_Включена = Истина;
 
 	ФоновыеЗадания.Выполнить(ЭтотОбъект, "ЗапуститьОбработкуСообщений");
 КонецПроцедуры

Обновите все вызовы метода во всём репозитории и во внешних клиентах/интеграциях — текущий поиск (rg -nP -C2 'Подписац[ья]') не вернул совпадений, поэтому проверьте внешние потребители перед переименованием.

Comment on lines 31 to 39
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Отсутствует обработка ошибок при вызове обработчика

При вызове Рефлектор.ВызватьМетод отсутствует обработка исключений, что может привести к падению всего соединения при ошибке в обработчике.

 		Обработчик = НайтиОбработчик(Топик);
 		СоответствиеПараметров = Новый Соответствие();
 		СоответствиеПараметров.Вставить("Идентификатор", Идентификатор);
 		СоответствиеПараметров.Вставить("Топик", Топик);
 		СоответствиеПараметров.Вставить("Сообщение", ДанныеСообщения.Сообщение);
 		Параметры = КонструкторыПараметров.СформироватьМассивНеобходимыхПараметров(Обработчик.Действие.Параметры, 
 			СоответствиеПараметров);
 
-		Рефлектор.ВызватьМетод(Обработчик.Действие.Желудь, Обработчик.Действие.ИмяМетода, Параметры);	
+		Попытка
+			Рефлектор.ВызватьМетод(Обработчик.Действие.Желудь, Обработчик.Действие.ИмяМетода, Параметры);
+		Исключение
+			// Логируем ошибку, но не разрываем соединение
+			// TODO: Добавить логирование
+		КонецПопытки;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Обработчик = НайтиОбработчик(Топик);
СоответствиеПараметров = Новый Соответствие();
СоответствиеПараметров.Вставить("Идентификатор", Идентификатор);
СоответствиеПараметров.Вставить("Топик", Топик);
СоответствиеПараметров.Вставить("Сообщение", ДанныеСообщения.Сообщение);
Параметры = КонструкторыПараметров.СформироватьМассивНеобходимыхПараметров(Обработчик.Действие.Параметры,
Новый Структура("Идентификатор, Топик, Сообщение",
Идентификатор,
Топик,
ДанныеСообщения.Сообщение));
СоответствиеПараметров);
Рефлектор.ВызватьМетод(Обработчик.Действие.Желудь, Обработчик.Действие.ИмяМетода, Параметры);
Обработчик = НайтиОбработчик(Топик);
СоответствиеПараметров = Новый Соответствие();
СоответствиеПараметров.Вставить("Идентификатор", Идентификатор);
СоответствиеПараметров.Вставить("Топик", Топик);
СоответствиеПараметров.Вставить("Сообщение", ДанныеСообщения.Сообщение);
Параметры = КонструкторыПараметров.СформироватьМассивНеобходимыхПараметров(Обработчик.Действие.Параметры,
СоответствиеПараметров);
Попытка
Рефлектор.ВызватьМетод(Обработчик.Действие.Желудь, Обработчик.Действие.ИмяМетода, Параметры);
Исключение
// Логируем ошибку, но не разрываем соединение
// TODO: Добавить логирование
КонецПопытки;
🤖 Prompt for AI Agents
In src/Классы/БрокерСообщенийВебСокетов.os around lines 31 to 39, the call to
Рефлектор.ВызватьМетод is unprotected and may throw, so wrap the call in a
try/except (Попытка/Исключение) block, catch and log the exception with
contextual details (Идентификатор, Топик, имя метода), send an error/ответ
клиенту or отказ по протоколу if applicable, and ensure any necessary cleanup
(не допустить падения соединения) in the finally/последний блок; this prevents
an exception in a handler from crashing the whole websocket connection.

Comment on lines 64 to 84
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Критическая проблема: утечка ресурсов при обработке WebSocket

Цикл ожидания с Приостановить(10000) блокирует поток обработки запроса на 10 секунд, что может привести к исчерпанию пула потоков сервера. Также отсутствует обработка исключений и очистка ресурсов.

 	Если Контекст.ВебСокеты.ЭтоВебСокетЗапрос Тогда
 
 		Сокет = Контекст.ВебСокеты.ПодключитьВебСокет();
 
 		Идентификатор = Запрос.Сессия.Идентификатор();
 		Топик = Запрос.Путь;
 
 		СоединениеВебСокета = Поделка.НайтиЖелудь("СоединениеВебСокета");
 		СоединениеВебСокета.Сокет = Сокет;
 		СоединениеВебСокета.Активно = СоединениеВебСокета.СокетАктивен();
 		СоединениеВебСокета.Контекст = Контекст;
 
-		СоединенияВебСокетов.Добавить(СоединениеВебСокета, Идентификатор, Топик);
-
-		// Если этот метод завершится, то соединение будет разорвано. поэтому ждем
-		Пока СоединениеВебСокета.СокетАктивен() Цикл
-			Приостановить(10000);
-		КонецЦикла;
+		Попытка
+			СоединенияВебСокетов.Добавить(СоединениеВебСокета, Идентификатор, Топик);
+			
+			// Если этот метод завершится, то соединение будет разорвано. поэтому ждем
+			// Используем меньший интервал для более отзывчивой проверки
+			Пока СоединениеВебСокета.СокетАктивен() Цикл
+				Приостановить(100); // 100мс вместо 10000мс
+			КонецЦикла;
+		Исключение
+			// Гарантируем удаление соединения при ошибке
+			СоединенияВебСокетов.Удалить(Идентификатор, Топик);
+			ВызватьИсключение;
+		КонецПопытки;
 
 		Возврат;
 	КонецЕсли;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Если Контекст.ВебСокеты.ЭтоВебСокетЗапрос Тогда
Сокет = Контекст.ВебСокеты.ПодключитьВебСокет();
Идентификатор = Запрос.Сессия.Идентификатор();
Топик = Запрос.Путь;
СоединениеВебСокета = Поделка.НайтиЖелудь("СоединениеВебСокета");
СоединениеВебСокета.Сокет = Сокет;
СоединениеВебСокета.Активно = СоединениеВебСокета.СокетАктивен();
СоединениеВебСокета.Контекст = Контекст;
СоединенияВебСокетов.Добавить(СоединениеВебСокета, Идентификатор, Топик);
// Если этот метод завершится, то соединение будет разорвано. поэтому ждем
Пока СоединениеВебСокета.СокетАктивен() Цикл
Приостановить(10000);
КонецЦикла;
Возврат;
КонецЕсли;
Если Контекст.ВебСокеты.ЭтоВебСокетЗапрос Тогда
Сокет = Контекст.ВебСокеты.ПодключитьВебСокет();
Идентификатор = Запрос.Сессия.Идентификатор();
Топик = Запрос.Путь;
СоединениеВебСокета = Поделка.НайтиЖелудь("СоединениеВебСокета");
СоединениеВебСокета.Сокет = Сокет;
СоединениеВебСокета.Активно = СоединениеВебСокета.СокетАктивен();
СоединениеВебСокета.Контекст = Контекст;
Попытка
СоединенияВебСокетов.Добавить(СоединениеВебСокета, Идентификатор, Топик);
// Если этот метод завершится, то соединение будет разорвано. поэтому ждем
// Используем меньший интервал для более отзывчивой проверки
Пока СоединениеВебСокета.СокетАктивен() Цикл
Приостановить(100); // 100мс вместо 10000мс
КонецЦикла;
Исключение
// Гарантируем удаление соединения при ошибке
СоединенияВебСокетов.Удалить(Идентификатор, Топик);
ВызватьИсключение;
КонецПопытки;
Возврат;
КонецЕсли;
🤖 Prompt for AI Agents
В src/Классы/НативныйВебСервер.os около строк 64-84 цикл с Приостановить(10000)
блокирует поток и не обрабатывает исключения/очистку, что вызывает утечку
ресурсов; замените блокирующий цикл на событийно-ориентированную или асинхронную
ожидалку закрытия сокета (например, подписка на событие "закрыт" или await
Promise, завершающийся при закрытии), оберните работу с сокетом в конструкцию
try/finally чтобы в finally всегда удалять соединение из СоединенияВебСокетов и
корректно закрывать/освобождать Сокет, добавьте перехват исключений для
логирования ошибок и гарантированной очистки, и убедитесь, что любые
долгоживущие операции не удерживают поток запроса.

Comment on lines 28 to 30
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Отписка не прерывает блокирующее чтение — возможна «зависшая» фоновая задача.

Если поток чтения блокируется на ПолучитьСтроку(), простая смена флага не завершит цикл.

Примените дифф:

 Процедура Отписаться() Экспорт
-	_Включена = Ложь;
+	_Включена = Ложь;
+	Если _Соединение <> Неопределено Тогда
+		// Закрываем сокет, чтобы прервать блокирующее чтение
+		Попытка
+			_Соединение.Закрыть();
+		Исключение
+			Сообщить("Ошибка при закрытии соединения при отписке: " + ОписаниеОшибки());
+		КонецПопытки;
+	КонецЕсли;
+	Отключить();
 КонецПроцедуры
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Процедура Отписаться() Экспорт
_Включена = Ложь;
КонецПроцедуры
Процедура Отписаться() Экспорт
_Включена = Ложь;
Если _Соединение <> Неопределено Тогда
// Закрываем сокет, чтобы прервать блокирующее чтение
Попытка
_Соединение.Закрыть();
Исключение
Сообщить("Ошибка при закрытии соединения при отписке: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Отключить();
КонецПроцедуры
🤖 Prompt for AI Agents
В файле src/Классы/ПодпискаНаВебСокетНативная.os около строк 28–30: текущая
реализация Отписаться() только переключает флаг _Включена = Ложь, но если в фоне
блокируется чтение методом ПолучитьСтроку(), фоновая задача не завершится;
исправьте Отписаться() так, чтобы помимо установки флага она разрывала/закрывала
ресурс, на котором блокируется чтение (закрыть сокет/поток/соединение или
вызвать API прерывания чтения), и дождаться завершения фоновой задачи
(join/ожидание задачи) или установить таймаут на чтение; обеспечьте безопасную
очистку ресурсов и обработку исключений при принудительном завершении чтения.

Comment on lines 41 to 52
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Цикл чтения: устранить потенциальную блокировку и улучшить завершение.

Добавьте выход при Неопределено/закрытии, закрывайте соединение перед отключением, улучшите лог.

Примените дифф:

 Процедура ОбработкаСообщений()
 	Попытка
-		Пока _Включена = Истина И _Соединение.Сокет.Состояние = СостояниеВебСокета.Открыт Цикл		
-			ТекстСообщения = _Соединение.Сокет.ПолучитьСтроку();
-			_БрокерСообщенийВебСокетов.ВходящееСообщение(_Идентификатор, _Топик, ТекстСообщения);
-		КонецЦикла;
-		_Соединение.Активно = Ложь;
+		Пока _Включена = Истина 
+			И _Соединение <> Неопределено 
+			И _Соединение.Сокет <> Неопределено
+			И _Соединение.Сокет.Состояние = СостояниеВебСокета.Открыт Цикл
+			ТекстСообщения = _Соединение.Сокет.ПолучитьСтроку();
+			Если ТекстСообщения = Неопределено Тогда
+				Прервать;
+			КонецЕсли;
+			_БрокерСообщенийВебСокетов.ВходящееСообщение(_Идентификатор, _Топик, ТекстСообщения);
+		КонецЦикла;
 	Исключение
-		Сообщить("Ошибка обработки сообщения " + ОписаниеОшибки());
+		Сообщить("Ошибка обработки сообщения (" + Строка(_Идентификатор) + ", " + Строка(_Топик) + "): " + ОписаниеОшибки());
 	КонецПопытки;
+	Если _Соединение <> Неопределено Тогда
+		_Соединение.Активно = Ложь;
+		Попытка
+			_Соединение.Закрыть();
+		Исключение
+			Сообщить("Ошибка при закрытии соединения: " + ОписаниеОшибки());
+		КонецПопытки;
+	КонецЕсли;
 	Отключить();
 КонецПроцедуры
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Процедура ОбработкаСообщений()
Попытка
Пока _Включена = Истина И _Соединение.Сокет.Состояние = СостояниеВебСокета.Открыт Цикл
ТекстСообщения = _Соединение.Сокет.ПолучитьСтроку();
_БрокерСообщенийВебСокетов.ВходящееСообщение(_Идентификатор, _Топик, ТекстСообщения);
КонецЦикла;
_Соединение.Активно = Ложь;
Исключение
Сообщить("Ошибка обработки сообщения " + ОписаниеОшибки());
КонецПопытки;
Отключить();
КонецПроцедуры
Процедура ОбработкаСообщений()
Попытка
Пока _Включена = Истина
И _Соединение <> Неопределено
И _Соединение.Сокет <> Неопределено
И _Соединение.Сокет.Состояние = СостояниеВебСокета.Открыт Цикл
ТекстСообщения = _Соединение.Сокет.ПолучитьСтроку();
Если ТекстСообщения = Неопределено Тогда
Прервать;
КонецЕсли;
_БрокерСообщенийВебСокетов.ВходящееСообщение(_Идентификатор, _Топик, ТекстСообщения);
КонецЦикла;
Исключение
Сообщить("Ошибка обработки сообщения (" + Строка(_Идентификатор) + ", " + Строка(_Топик) + "): " + ОписаниеОшибки());
КонецПопытки;
Если _Соединение <> Неопределено Тогда
_Соединение.Активно = Ложь;
Попытка
_Соединение.Закрыть();
Исключение
Сообщить("Ошибка при закрытии соединения: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Отключить();
КонецПроцедуры
🤖 Prompt for AI Agents
В файле src/Классы/ПодпискаНаВебСокетНативная.os около строк 41-52 цикл чтения
может блокировать при получении Неопределено/закрытии сокета, лог недостаточно
информативен и соединение отключается в неверном порядке; измените логику так:
внутри цикла после ПолучитьСтроку проверяйте результат на Неопределено или
текущее состояние сокета не Открыт — в этом случае выходите из цикла; при выходе
установите _Соединение.Активно = Ложь, явно закройте/закройте сокет перед
вызовом Отключить(), и в блоке Исключение логируйте ОписаниеОшибки() вместе с
контекстной информацией (_Идентификатор, _Топик) для понятного отлова ошибок.

Comment on lines 2 to 4
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

🧩 Analysis chain

Инкапсуляция состояния вместо экспортируемых переменных.

Экспорт Перем Сокет/Активно/Контекст делает состояние уязвимым к внешним записям и затрудняет соблюдение инвариантов. Предпочтительнее хранить поля приватно и предоставлять методы/геттеры.

Найдите внешние обращения к этим полям:


🏁 Script executed:

#!/bin/bash
rg -nP -C2 'СоединениеВебСокета\.(Сокет|Активно|Контекст)'

Length of output: 877


Инкапсуляция: сделать Сокет/Активно/Контекст приватными и предоставить API (геттеры/методы)

Экспорт этих переменных даёт внешним модулям возможность напрямую менять состояние — обнаружены прямые записи/чтения:

  • src/Классы/НативныйВебСервер.os:72 — СоединениеВебСокета.Сокет = Сокет;
  • src/Классы/НативныйВебСервер.os:73 — СоединениеВебСокета.Активно = СоединениеВебСокета.СокетАктивен();
  • src/Классы/НативныйВебСервер.os:74 — СоединениеВебСокета.Контекст = Контекст;
  • src/Классы/НативныйВебСервер.os:79 — Пока СоединениеВебСокета.СокетАктивен() Цикл

Сделать поля приватными, добавить методы/фабрику для инициализации и управляемых обновлений (УстановитьСокет/УстановитьКонтекст/ОбновитьАктивность + геттеры) и заменить в указанных местах прямые присвоения/доступ на вызовы этих методов.

🤖 Prompt for AI Agents
In src/Классы/СоединениеВебСокета.os around lines 2-4, the exported variables
"Сокет", "Активно" и "Контекст" must be made private: change them from exported
module-level vars to private fields and add a controlled API
(constructor/factory + методы УстановитьСокет(сокет),
УстановитьКонтекст(контекст), ОбновитьАктивность(значение) и геттеры
ПолучитьСокет(), ПолучитьКонтекст(), ПолучитьАктивно()). Then update all call
sites that currently read/write these vars to use the new methods:
src/Классы/НативныйВебСервер.os lines 72–74 (replace direct assignments with
УстановитьСокет/УстановитьКонтекст/ОбновитьАктивность) and line 79 (replace
direct СоединениеВебСокета.СокетАктивен() access with the new getter/метод).
Ensure methods validate inputs where appropriate and preserve previous behavior.

Comment on lines 27 to 40
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

На ошибке отправки стоит закрывать соединение.

Сейчас при неактивном сокете/исключении только сбрасывается флаг, но ресурс не освобождается.

Примените дифф:

 Процедура ОтправитьСтроку(Сообщение) Экспорт
 	Попытка
 		
 		Если СокетАктивен() Тогда
 			Сокет.ОтправитьСтроку(Сообщение);
 		Иначе
-			Активно = Ложь;
+			Закрыть();
 		КонецЕсли;
 
 	Исключение
 		Сообщить("Ошибка отправки сообщения в веб сокет " + ОписаниеОшибки());
-		Активно = Ложь;
+		Закрыть();
 	КонецПопытки;
 КонецПроцедуры
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Процедура ОтправитьСтроку(Сообщение) Экспорт
Попытка
Если СокетАктивен() Тогда
Сокет.ОтправитьСтроку(Сообщение);
Иначе
Активно = Ложь;
КонецЕсли;
Исключение
Сообщить("Ошибка отправки сообщения в веб сокет " + ОписаниеОшибки());
Активно = Ложь;
КонецПопытки;
КонецПроцедуры
Процедура ОтправитьСтроку(Сообщение) Экспорт
Попытка
Если СокетАктивен() Тогда
Сокет.ОтправитьСтроку(Сообщение);
Иначе
Закрыть();
КонецЕсли;
Исключение
Сообщить("Ошибка отправки сообщения в веб сокет " + ОписаниеОшибки());
Закрыть();
КонецПопытки;
КонецПроцедуры
🤖 Prompt for AI Agents
В файле src/Классы/СоединениеВебСокета.os строках 27-40: при неактивном сокете
или в блоке Исключение надо не только сбрасывать флаг Активно, но и корректно
закрывать и освобождать ресурс сокета; добавьте проверку наличия объекта Сокет и
вызов метода закрытия (например Сокет.Закрыть()), затем обнулите ссылку на Сокет
(или Уничтожить/Освободить в зависимости от API) и установите Активно = Ложь;
при этом вызовы закрытия должны быть защищены от исключений (в собственном
try/catch), чтобы не ломать поток обработки ошибок.

Comment on lines 42 to 44
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

Отправка двоичных данных не должна проксироваться в строковую — риск порчи данных.

Нужна отдельная отправка бинарного фрейма (если поддерживается API), с понижающим переходом на текст только когда вход — строка.

Примените дифф:

-Процедура ОтправитьДвоичныеДанные(Сообщение) Экспорт // Для обратной совместимости с брокером
-	ОтправитьСтроку(Сообщение);
-КонецПроцедуры
+Процедура ОтправитьДвоичныеДанные(Сообщение) Экспорт // Для обратной совместимости с брокером
+	Если ТипЗнч(Сообщение) = Тип("ДвоичныеДанные") Тогда
+		Попытка
+			Если СокетАктивен() Тогда
+				// Предпочтительно отправлять бинарный фрейм
+				Сокет.ОтправитьДвоичныеДанные(Сообщение);
+			Иначе
+				Закрыть();
+			КонецЕсли;
+		Исключение
+			Сообщить("Ошибка отправки двоичных данных в веб сокет " + ОписаниеОшибки());
+			Закрыть();
+		КонецПопытки;
+	Иначе
+		// Фоллбэк: текст
+		ОтправитьСтроку(Сообщение);
+	КонецЕсли;
+КонецПроцедуры

Проверьте, что у нативного веб‑сокета есть метод отправки бинарных данных и как он называется:

Также найдите места, где вызывается ОтправитьДвоичныеДанные со значением типа ДвоичныеДанные, чтобы подтвердить необходимость бинарной отправки:


🏁 Script executed:

#!/bin/bash
rg -nP -C2 'Отправ(ить)?ДвоичныеДанные\s*\('

Length of output: 3823


🌐 Web query:

1C: поддерживает ли нативный веб‑сервер метод отправки бинарных данных в WebSocket? Укажите точное имя метода и сигнатуру.

💡 Result:

Коротко: нет — нативный веб‑сервер 1С не предоставляет серверный API WebSocket для отправки бинарных сообщений, поэтому точного имени/сигнатуры метода нет.

Основание:

  • В документации 1С описан только WebSocket‑клиент (реализовано в платформе, см. WebSocket‑клиент в v8.3.27), но публичного серверного метода нативного веб‑сервера для отправки бинарных фреймов не указано. [1]
  • Сообщения сообщества/статей явно указывают, что до последних версий платформа не имела встроенной поддержки WebSocket‑сервера и обычно используют прокси/внешние компоненты (NativeAPI/внешние компоненты) для работы с WebSocket (в т.ч. бинарными данными). [2][3]

Если нужно, могу:

  • посмотреть конкретную версию платформы (укажите точную версию 1С), чтобы перепроверить релиз‑ноты/спецификации на предмет появления серверного метода, и привести точную сигнатуру, если она появилась.

Источники:
[1] Описание WebSocket‑клиента в платформе 1С. (v8.1c.ru). [2] Обсуждение отсутствия встроенной поддержки WebSocket в 1С и варианты (Infostart). [3] Статьи/публикации по использованию NativeAPI и внешних компонентов для WebSocket (Infostart).


Не проксировать двоичные данные в текст — реализовать реальную поддержку бинарных WebSocket‑фреймов или явный безопасный фоллбэк

Проверено: нативный веб‑сервер 1С не предоставляет серверного API для отправки бинарных WebSocket‑фреймов, поэтому предложенный патч с вызовом Сокет.ОтправитьДвоичныеДанные некорректен. Вызовы ОтправитьДвоичныеДанные встречаются в кодовой базе и требуют корректной обработки:

  • tools/proxy.os:27,37
  • tests/alltest.os:461,466
  • src/Классы/СоединениеВебСокета.os (реализация) — текущая строка 42–44
  • src/Классы/БрокерСообщенийВебСокетов.os:79,87,95,103
  • src/Классы/ОбработчикСоединений.os:67
  • src/Классы/БрокерСообщенийСобытийСервера.os:70

Действия (выбрать и реализовать один из вариантов):

  • Вариант A (рекомендую): реализовать отправку бинарного фрейма в СоединениеВебСокета на уровне raw‑socket (формирование WebSocket‑фрейма opcode=0x2, запись байтов в сокет без маски для сервера). После этого ОтправитьДвоичныеДанные должна вызывать новый низкоуровневый метод.
  • Вариант B: интегрировать внешнюю компоненту/прокси, которая гарантированно поддерживает бинарные фреймы; вызывать её API только если компонент доступен — иначе явно падать.
  • Вариант C (если A/B невозможны): удалить тихий фоллбэк в ОтправитьСтроку(…) для бинарных данных — вместо этого либо бросать понятное исключение, либо явным образом кодировать бинарный payload в текст (например base64) и помечать формат so, чтобы приёмник декодировал. Молчаливое приведение к строке недопустимо.

Точки изменения: прежде всего — src/Классы/СоединениеВебСокета.os; затем скорректировать брокер/обработчики и тесты в перечисленных файлах. Исправьте и повторно запросите ревью.

🤖 Prompt for AI Agents
В файле src/Классы/СоединениеВебСокета.os строках 42–44: текущая реализация
молча проксирует бинарные данные в ОтправитьСтроку(…), что недопустимо;
реализуйте реальную отправку бинарного WebSocket‑фрейма (вариант A): добавьте
приватный низкоуровневый метод, который формирует WebSocket фрейм с opcode=0x2,
корректной длиной и без маски (для сервера) и пишет полученные байты в сокет;
замените тело процедуры ОтправитьДвоичныеДанные(Сообщение) на вызов нового
метода; затем обновите места вызова (БрокерСообщенийВебСокетов,
ОбработчикСоединений, БрокерСообщенийСобытийСервера, tools/proxy.os,
tests/alltest.os) при необходимости чтобы они работали с бинарным API либо
корректно обрабатывали/транслировали ошибки.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

🧩 Analysis chain

Потенциальная проблема с определением версии платформы

Использование Лев(Новый СистемнаяИнформация().Версия,1) = "2" для определения версии платформы может быть ненадёжным. Версия может начинаться с "2" в разных контекстах (2.0, 20.x, 2x.x).

Рекомендую использовать более точную проверку версии:

-	ИспользоватьНативныйСервер = Не Настройки.ИспользоватьПрикладнойСервер И Лев(Новый СистемнаяИнформация().Версия,1) = "2";
+	СистИнфо = Новый СистемнаяИнформация();
+	МассивВерсии = СтрРазделить(СистИнфо.Версия, ".");
+	ИспользоватьНативныйСервер = Не Настройки.ИспользоватьПрикладнойСервер И 
+		(МассивВерсии.Количество() > 0 И Число(МассивВерсии[0]) >= 2);

Давайте проверим, как используется версия платформы в других местах кодовой базы:


🏁 Script executed:

#!/bin/bash
# Поиск использования СистемнаяИнформация().Версия в кодовой базе
rg -n "СистемнаяИнформация\(\)\.Версия" --type-add 'os:*.os' --type os

Length of output: 315


Исправить ненадёжную проверку версии платформы (Лев(...)= "2")

Лев(Новый СистемнаяИнформация().Версия,1) = "2" ненадёжен — такая проверка встречается в двух местах; заменить на парсинг мажорной версии и числовое сравнение.

Файлы: src/Классы/ФабрикаВебСокетов.os:8, src/Классы/ФабрикаВебСерверов.os:15

Рекомендуемая замена:

-	ИспользоватьНативныйСервер = Не Настройки.ИспользоватьПрикладнойСервер И Лев(Новый СистемнаяИнформация().Версия,1) = "2";
+	СистИнфо = Новый СистемнаяИнформация();
+	МассивВерсии = СтрРазделить(СистИнфо.Версия, ".");
+	ИспользоватьНативныйСервер = Не Настройки.ИспользоватьПрикладнойСервер И 
+		(МассивВерсии.Количество() > 0 И Число(МассивВерсии[0]) >= 2);

Внести одинаковое исправление в оба файла.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ИспользоватьНативныйСервер = Не Настройки.ИспользоватьПрикладнойСервер И Лев(Новый СистемнаяИнформация().Версия,1) = "2";
СистИнфо = Новый СистемнаяИнформация();
МассивВерсии = СтрРазделить(СистИнфо.Версия, ".");
ИспользоватьНативныйСервер = Не Настройки.ИспользоватьПрикладнойСервер И
(МассивВерсии.Количество() > 0 И Число(МассивВерсии[0]) >= 2);

Comment on lines 19 to 23
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

Упрощённая упаковка сообщений

Функция ЗапаковатьСообщениеТекстовоеСообщение просто возвращает сообщение без реальной упаковки в формат WebSocket фрейма. Для нативного сервера это может быть корректно, если упаковка происходит на уровне платформы.

Давайте проверим, как используется эта функция:


🏁 Script executed:

#!/bin/bash
# Проверка использования функции упаковки сообщений
rg "ЗапаковатьСообщениеТекстовоеСообщение" --type-add 'os:*.os' --type os -A 2 -B 2

Length of output: 3149


Мок должен возвращать двоичные данные, как продакшен-функция.

В src/Классы/ШифрованиеВебСокетаМок.os ЗапаковатьСообщениеТекстовоеСообщение сейчас просто делает "Возврат Сообщение;", тогда как в src/Классы/ШифрованиеВебСокета.os сообщение конвертируется в двоичный формат (ПолучитьДвоичныеДанныеИзСтроки). Брокер (src/Классы/БрокерСообщенийВебСокетов.os) передаёт результат в ОтправитьДвоичныеДанные, поэтому исправить: привести мок к тому же формату (вернуть двоичные данные, напр. вызвать ПолучитьДвоичныеДанныеИзСтроки) или явно адаптировать/документировать вызовы и тесты (tests/alltest.os).

🤖 Prompt for AI Agents
В файле src/Классы/ШифрованиеВебСокетаМок.os примерно на строках 19–23 текущая
функция ЗапаковатьСообщениеТекстовоеСообщение просто возвращает исходную строку,
тогда как продакшен-реализация в src/Классы/ШифрованиеВебСокета.os возвращает
двоичные данные; исправьте мок, чтобы он возвращал те же двоичные данные
(например, вызвать ПолучитьДвоичныеДанныеИзСтроки(Сообщение) и вернуть
результат) либо привести его поведение в точное соответствие с
продакшен-версией, чтобы БрокерСообщенийВебСокетов и tests/alltest.os получали
бинарные данные.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
docs/product/index.md (1)

15-15: Замените «голый» URL на Markdown‑ссылку.

Правка устранит предупреждение MD034 и улучшит читабельность.

-Можно оставить тут https://github.com/autumn-library/winow/issues
+Можно оставить в issue‑трекере: [autumn-library/winow/issues](https://github.com/autumn-library/winow/issues)
README.md (2)

9-9: Исправьте стилистику и терминологию в дисклеймере.

Небольшие правки русского языка и терминов: POST‑запросы, «Также», «чтобы», формат настройки.

-А это значит, что при запуске приложения под OneScript версии 2.0 и выше
+Это значит, что при запуске приложения под OneScript версии 2.0 и выше
-Возможны артефакты в обработке пост запросов
+Возможны артефакты при обработке POST‑запросов
-А так же
+Также
-для того, что бы
+для того, чтобы
-в истину
+= Истина

56-60: Уберите «голый» URL и дайте читабельный якорь.

Так будет чище и удовлетворит MD034.

-## Документация
-
-https://autumn-library.github.io/winow/
+## Документация
+
+Полная документация: [autumn-library.github.io/winow](https://autumn-library.github.io/winow/)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between da635e3 and 81e5a96.

📒 Files selected for processing (2)
  • README.md (2 hunks)
  • docs/product/index.md (1 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
README.md

58-58: Bare URL used

(MD034, no-bare-urls)

docs/product/index.md

15-15: Bare URL used

(MD034, no-bare-urls)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (dev) / build (windows-latest, dev)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: test (dev) / build (windows-latest, dev)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)
  • GitHub Check: build (ubuntu-latest, stable)

README.md Outdated
## Disclaimer вашему вниманию

С релиза 0.9.0 добавлена поддержка платформенного объекта `ВебСервер`. А это значит, что при запуске приложения под OneScript версии 2.0 и выше будет использоваться именно он. Возможны артефакты в обработке пост запросов с типом `multipart/form-data`. А так же в этом режиме временно не поддерживаются технологии WebSocket и SSE. Для того, что бы использовать старый механизм под OneScript 2.0 нужно установить настройку `winow.ИспользоватьПрикладнойСервер` в истину.
С релиза 0.9.0 добавлена поддержка платформенного объекта `ВебСервер`. А это значит, что при запуске приложения под OneScript версии 2.0 и выше будет использоваться именно он. Возможны артефакты в обработке пост запросов с типом `multipart/form-data`. А так же в этом режиме временно не поддерживаются технология и SSE. Для того, что бы использовать старый механизм под OneScript 2.0 нужно установить настройку `winow.ИспользоватьПрикладнойСервер` в истину.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

🧩 Analysis chain

Дисклеймер противоречит целям PR и содержит неточность.

Фраза «в этом режиме временно не поддерживаются технология и SSE» конфликтует с задачей PR о нативной поддержке WebSocket на OneScript 2.0 и звучит неоднозначно (какая «технология»?). Предлагаю убрать противоречие и уточнить статус SSE.

-С релиза 0.9.0 добавлена поддержка платформенного объекта `ВебСервер`. А это значит, что при запуске приложения под OneScript версии 2.0 и выше будет использоваться именно он. Возможны артефакты в обработке пост запросов с типом `multipart/form-data`. А так же в этом режиме временно не поддерживаются технология и SSE. Для того, что бы использовать старый механизм под OneScript 2.0 нужно установить настройку `winow.ИспользоватьПрикладнойСервер` в истину.
+С релиза 0.9.0 добавлена поддержка платформенного объекта `ВебСервер`. При запуске приложения на OneScript 2.0+ используется именно он. Возможны артефакты при обработке `multipart/form-data`. 
+
+Поддержка WebSocket в режиме нативного сервера включена. Статус SSE уточните и зафиксируйте в документации (поддерживается/ограничено/временно недоступно).
+
+Чтобы под OneScript 2.0 принудительно использовать прикладной сервер, установите `winow.ИспользоватьПрикладнойСервер = Истина`.

Пожалуйста, подтвердите текущий статус SSE в режиме нативного ВебСервер и, при необходимости, добавьте ссылку на раздел документации.


🏁 Script executed:

#!/bin/bash
# Быстрый поиск по репозиторию для подтверждения статуса SSE/WebSocket и текста README
echo "=== Файлы README ==="
for f in README.md README.MD README; do
  if [ -f "$f" ]; then
    echo "---- $f ----"
    sed -n '1,200p' "$f"
    echo
  fi
done

echo "=== Поиск по ключевым словам ==="
if command -v rg >/dev/null 2>&1; then
  rg -n -i -C2 --hidden --no-ignore 'SSE|Server-?Sent|EventSource' || true
  rg -n -i -C2 --hidden --no-ignore 'WebSocket|ВебСокет|ВебСервер|Веб-?сервер|winow|ПрикладнойСервер|ИспользоватьПрикладнойСервер' || true
  rg -n --hidden --no-ignore 'multipart/form-data' || true
  rg -n '0\.9\.0|0\.9' || true
else
  grep -RIn --exclude-dir=node_modules --exclude-dir=.git -E 'SSE|Server-?Sent|EventSource|WebSocket|ВебСервер|ИспользоватьПрикладнойСервер|multipart/form-data|0\.9\.0|0\.9' . || true
fi

echo "=== Проверка наличия CHANGELOG / docs ==="
[ -f CHANGELOG.md ] && sed -n '1,200p' CHANGELOG.md || echo "CHANGELOG.md не найден"
[ -d docs ] && ls -la docs || echo "docs/ не найден"

Length of output: 78207


Исправьте дисклеймер — README утверждает, что SSE не поддерживается; привести текст в соответствие с реализацией.

В репозитории есть реализация и примеры и для WebSocket, и для SSE — текущая формулировка в README (строка ~9) двусмысленна и неправильно информирует пользователей.

Ключевые места для проверки: README.md:9; docs/product/index.md (разделы про WebSocket и "Работа с механизмом server-sent events", ~1032–1253); example/hwapp/СерверныеСобытия.os и example/hwapp/view/main_sse.html; tests/app/КонтролССЕ.os и tests/app/ССЕКлиент.os; src/Классы/КонтрольСоединенийСерверныхСобытий.os; src/Классы/МенеджерВходящихСоединений.os; src/Классы/НативныйВебСервер.os; src/Классы/ФабрикаВебСокетов.os.

Предлагаемая правка (сжато): заменить текущий блок Disclaimer на текст вида:
"С релиза 0.9.0 добавлена поддержка платформенного объекта ВебСервер. При запуске на OneScript 2.0+ используется нативный сервер. Возможны артефакты при обработке multipart/form-data. Поддержка WebSocket и server-sent events (SSE) реализована — при наличии ограничений укажите их и/или ссылку на документацию. Чтобы принудительно использовать прикладной сервер под OneScript 2.0, установите winow.ИспользоватьПрикладнойСервер = Истина."

Обновите README и, если есть конкретные ограничения по SSE, зафиксируйте их в docs (ссылку укажите из docs/product/index.md).

🤖 Prompt for AI Agents
README.md lines 9: Current disclaimer incorrectly states SSE is unsupported;
update the text to accurately reflect implementation by replacing the block with
the proposed concise paragraph: state that since 0.9.0 a platform object
ВебСервер is used on OneScript 2.0+, that multipart/form-data may exhibit
artifacts, and that WebSocket and server-sent events (SSE) are implemented
(mention any concrete SSE limitations if present and link to
docs/product/index.md for details); also include the instruction to force the
old server via winow.ИспользоватьПрикладнойСервер = Истина; if there are
specific SSE limitations, mirror them into docs/product/index.md (section
"Работа с механизмом server-sent events") and add links from README to that docs
section.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
README.md (1)

13-13: Дисклеймер противоречит цели PR: уточните/исправьте статус SSE и формулировки.

Сейчас сказано, что в нативном режиме SSE временно не поддерживается, но далее по README заявлена поддержка SSE, а цель PR — включить нативный WebSocket. Предлагаю убрать противоречие, заодно поправить стилистику и опечатки.

Прямая правка текста:

-С релиза 0.9.0 добавлена поддержка платформенного объекта `ВебСервер`. А это значит, что при запуске приложения под OneScript версии 2.0 и выше будет использоваться именно он. Возможны артефакты в обработке пост запросов с типом `multipart/form-data`. А так же в этом режиме временно не поддерживаются технология и SSE. Для того, что бы использовать старый механизм под OneScript 2.0 нужно установить настройку `winow.ИспользоватьПрикладнойСервер` в истину.
+С релиза 0.9.0 добавлена поддержка платформенного объекта `ВебСервер`. При запуске приложения на OneScript 2.0+ используется нативный веб‑сервер. Возможны артефакты при обработке `multipart/form-data`.
+
+Поддерживаются WebSocket и server‑sent events (SSE). Если есть ограничения, перечислите их и дайте ссылку на соответствующий раздел документации.
+
+Чтобы под OneScript 2.0 принудительно использовать прикладной сервер, установите `winow.ИспользоватьПрикладнойСервер = Истина`.

Для верификации статуса SSE/WebSocket по репо:

#!/bin/bash
# Проверка упоминаний SSE/WebSocket и ссылок из README
rg -n -i -C2 'SSE|Server-?Sent|EventSource|WebSocket|ВебСокет|КонтрольСоединенийСерверныхСобытий|СерверныеСобытия'
🧹 Nitpick comments (5)
README.md (5)

5-7: Формулировки режимов и грамматика.

Уточните стилистику и грамматику; «обеих версия 1.9 и 2.0» — ошибка.

-Работает в двух режимах:
-- Нативный веб сервер поставляемый движком OneScript (Доступен с версии 2.0)
-- Прикладной веб сервер, написанный поверх TCPСервер. (Доступен на обеих версия 1.9 и 2.0)
+Работает в двух режимах:
+- Нативный веб‑сервер, поставляемый движком OneScript (доступен с версии 2.0).
+- Прикладной веб‑сервер, написанный поверх `TCPСервер` (доступен на обеих версиях 1.9 и 2.0).

3-3: Опечатка/неясная формулировка в слогане.

«веб-фрейворк желудях» звучит как опечатка. Нужен предлог «на» или пояснение термина «Желудь».

Возможные варианты:

  • «Минималистичный веб‑фреймворк на OneScript.»
  • «Минималистичный веб‑фреймворк на “Жёлуде” (внутренний объект),» — если «Желудь» это термин проекта, дайте ссылку/пояснение.

23-23: Исправить голый URL и добавить осмысленный текст ссылки (MD034).

-Можно оставить тут https://github.com/autumn-library/winow/issues
+Пожелания и баг‑репорты — в разделе [Issues](https://github.com/autumn-library/winow/issues).

60-63: Оформить ссылку и добавить якоря на разделы про WebSocket/SSE.

Сейчас — голый URL; лучше сделать явные ссылки на соответствующие разделы документации.

-## Документация
-
-https://autumn-library.github.io/winow/
+## Документация
+
+Главная: https://autumn-library.github.io/winow/
+
+- Раздел про WebSocket: [docs → WebSocket](https://autumn-library.github.io/winow/#/websocket) 
+- Раздел про SSE: [docs → SSE](https://autumn-library.github.io/winow/#/sse)

Если точных якорей нет, добавьте их в сайт документации и обновите ссылки здесь.


64-64: Уровни заголовков: проверьте иерархию.

В документе первый заголовок — уровня H2 (##). Если это не намеренно, поднимите первый заголовок до H1 или приведите уровни к единому стилю.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 81e5a96 and d563107.

📒 Files selected for processing (1)
  • README.md (3 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
README.md

23-23: Bare URL used

(MD034, no-bare-urls)


62-62: Bare URL used

(MD034, no-bare-urls)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)
  • GitHub Check: test (dev) / build (windows-latest, dev)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: test (dev) / build (windows-latest, dev)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
README.md (1)

13-13: Дисклеймер противоречит документации: уточните статус SSE и исправьте формулировки.

README заявляет, что SSE временно не поддерживается в нативном режиме, тогда как в документации SSE описан и приведены примеры. Также исправьте стилистику («POST‑запросов», «чтобы», форматирование настройки).

-С релиза 0.9.0 добавлена поддержка платформенного объекта `ВебСервер`. А это значит, что при запуске приложения под OneScript версии 2.0 и выше будет использоваться именно он. Возможны артефакты в обработке пост запросов с типом `multipart/form-data`. А так же в этом режиме временно не поддерживаются технология SSE. Для того, что бы использовать старый механизм под OneScript 2.0 нужно установить настройку `winow.ИспользоватьПрикладнойСервер` в истину.
+С релиза 0.9.0 добавлена поддержка платформенного объекта `ВебСервер`. При запуске на OneScript 2.0+ по умолчанию используется нативный сервер. Возможны артефакты при обработке `multipart/form-data`.
+
+Поддержка WebSocket включена. Статус SSE в нативном режиме уточните и зафиксируйте в документации (поддерживается/ограничено/временно недоступно) со ссылкой на соответствующий раздел.
+
+Чтобы под OneScript 2.0 принудительно использовать прикладной сервер, установите `winow.ИспользоватьПрикладнойСервер = Истина`.
🧹 Nitpick comments (6)
docs/product/index.md (3)

5-7: Единообразие терминов и грамматики («веб‑сервер», «на обеих версиях»).

Предлагаю правку списка режимов.

- - Нативный веб сервер поставляемый движком OneScript (Доступен с версии 2.0)
- - Прикладной веб сервер, разработанный поверх TCPСервер. (Доступен на обеих версия: 1.9 и 2.0)
+ - Нативный веб‑сервер, поставляемый движком OneScript (доступен с версии 2.0)
+ - Прикладной веб‑сервер, разработанный поверх TCPСервер (доступен на обеих версиях: 1.9 и 2.0)

5-7: Уточнить статус SSE в нативном режиме.

В README дисклеймер утверждает, что SSE временно не поддерживается в нативном режиме, а в документации ниже SSE описан как доступный. Нужна явная пометка, в каких режимах SSE работает/ограничен.

Готов предложить точную формулировку после подтверждения статуса SSE под OneScript 2.0 (нативный ВебСервер).


19-19: Устранить bare URL (MD034).

Оберните ссылку в угловые скобки или используйте формат Markdown‑ссылки.

-Можно оставить тут https://github.com/autumn-library/winow/issues
+Можно оставить тут: <https://github.com/autumn-library/winow/issues>
README.md (3)

3-7: Единообразие терминов и грамматики («веб‑сервер», «на обеих версиях»).

Та же правка, что и в docs: дефис, запятая, падеж.

-Работает в двух режимах:
-- Нативный веб сервер поставляемый движком OneScript (Доступен с версии 2.0)
-- Прикладной веб сервер, разработанный поверх TCPСервер. (Доступен на обеих версия: 1.9 и 2.0)
+Работает в двух режимах:
+- Нативный веб‑сервер, поставляемый движком OneScript (доступен с версии 2.0)
+- Прикладной веб‑сервер, разработанный поверх TCPСервер (доступен на обеих версиях: 1.9 и 2.0)

23-23: Устранить bare URL (MD034).

-Можно оставить тут https://github.com/autumn-library/winow/issues
+Можно оставить тут: <https://github.com/autumn-library/winow/issues>

60-66: Оформить ссылку на документацию и заголовки.

Замените голый URL на Markdown‑ссылку.

-## Документация
-
-https://autumn-library.github.io/winow/
+## Документация
+
+[autumn-library.github.io/winow](https://autumn-library.github.io/winow/)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d563107 and dbf25b7.

📒 Files selected for processing (2)
  • README.md (3 hunks)
  • docs/product/index.md (2 hunks)
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
README.md

23-23: Bare URL used

(MD034, no-bare-urls)


62-62: Bare URL used

(MD034, no-bare-urls)

docs/product/index.md

19-19: Bare URL used

(MD034, no-bare-urls)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
  • GitHub Check: build (ubuntu-latest, stable)
  • GitHub Check: test (dev) / build (windows-latest, dev)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: build (ubuntu-latest, stable)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (dev) / build (windows-latest, dev)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/Модули/СостоянияВебСокетов.os (3)

2-10: Неэффективная реализация через Выполнить() вместо прямого обращения к перечислению.

Использование Выполнить() для получения значения из перечисления СостояниеВебСокета.Открыт создает ненужные накладные расходы на выполнение и снижает производительность. Прямое обращение к перечислению будет более эффективным и безопасным.

Примените следующие изменения для оптимизации:

-Функция Открыт() Экспорт
-
-	СостояниеСокетОткрыт = Неопределено;
-	
-	Выполнить("СостояниеСокетОткрыт = СостояниеВебСокета.Открыт");
-
-	Возврат СостояниеСокетОткрыт;
-	
-КонецФункции
+Функция Открыт() Экспорт
+
+	Возврат СостояниеВебСокета.Открыт;
+	
+КонецФункции

4-6: Потенциальная проблема безопасности при использовании Выполнить().

Использование Выполнить() с жестко заданной строкой кода может создать потенциальные уязвимости безопасности и усложнить статический анализ кода. Рекомендуется избегать динамического выполнения кода там, где это не является необходимым.


2-10: Не удалять обёртку без правки вызовов.

Найдены вызовы обёртки — обновление/удаление модуля нужно делать вместе с правкой этих мест:

  • src/Классы/ПодпискаНаВебСокетНативная.os — ОбработкаСообщений(): _Соединение.Сокет.Состояние = СостоянияВебСокетов.Открыт()
  • src/Классы/СоединениеВебСокета.os — Функция СокетАктивен(): Возврат Сокет.Состояние = СостоянияВебСокетов.Открыт()
  • src/Модули/СостоянияВебСокетов.os — определение Открыт()

Рекомендация: либо оставить модуль-обёртку, либо одновременно заменить вызовы на прямое СостояниеВебСокета.Открыт и удалить модуль.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between dbf25b7 and 0fb083a.

📒 Files selected for processing (3)
  • src/Классы/ПодпискаНаВебСокетНативная.os (1 hunks)
  • src/Классы/СоединениеВебСокета.os (1 hunks)
  • src/Модули/СостоянияВебСокетов.os (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/Классы/ПодпискаНаВебСокетНативная.os
  • src/Классы/СоединениеВебСокета.os
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: build (ubuntu-latest, stable)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)
  • GitHub Check: test (stable) / build (macos-latest, stable)
  • GitHub Check: test (dev) / build (windows-latest, dev)
  • GitHub Check: test (stable) / build (windows-latest, stable)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: test (stable) / build (macos-latest, stable)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: test (stable) / build (windows-latest, stable)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)
  • GitHub Check: test (dev) / build (windows-latest, dev)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: build (ubuntu-latest, stable)

@sonar-openbsl-ru-qa-bot
Copy link

Failed Quality Gate failed

  • 25.70% Coverage on New Code (is less than 80.00%)
  • 21.21% Duplicated Lines (%) on New Code (is greater than 3.00%)
  • 50 New Issues (is greater than 0)

Project ID: winow

View in SonarQube

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/alltest.os (2)

415-433: Gitleaks: ложное срабатывание на Sec-WebSocket-Key

Детектор видит "Generic API Key" (подсказка указывает на строку 424), хотя это стандартный тестовый ключ рукопожатия. Чтобы не шумело в пайплайне:

  • либо разбейте значение на части (как в дифе выше),
  • либо генерируйте ключ на лету и вычисляйте Accept,
  • либо добавьте allowlist‑правило в конфиг gitleaks для этого кейса.

742-743: Уберите закомментированные вызовы из конца файла

Закомментированные "ПередЗапускомТеста();" и "Должен_ПроверитьРукопожатиеВебСокета();" вводят в заблуждение и бессмысленны в автозапуске. Лишний шум в диффах.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0fb083a and 944998e.

📒 Files selected for processing (1)
  • tests/alltest.os (2 hunks)
🧰 Additional context used
🪛 Gitleaks (8.27.2)
tests/alltest.os

[high] 424-424: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (14)
  • GitHub Check: test (dev) / build (windows-latest, dev)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (stable) / build (macos-latest, stable)
  • GitHub Check: test (stable) / build (windows-latest, stable)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)
  • GitHub Check: build (ubuntu-latest, stable)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)
  • GitHub Check: test (stable) / build (windows-latest, stable)
  • GitHub Check: test (stable) / build (macos-latest, stable)
  • GitHub Check: build (ubuntu-latest, stable)
  • GitHub Check: test (dev) / build (windows-latest, dev)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
tests/alltest.os (4)

425-442: Хендшейк: добавьте CRLF-CRLF, не хардкодьте ключ/Accept, уберите лишние заголовки
Соберите запрос программно, вычислите Accept из Sec-WebSocket-Key и зашифруйте ключ от детекторов секретов.

-	ТекстЗапроса = "GET /socket/ws HTTP/1.1
-					|Host: localhost:3333
-					|User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:107.0) Gecko/20100101 Firefox/107.0
-					|Accept: */*
-					|Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
-					|Accept-Encoding: gzip, deflate, br
-					|Sec-WebSocket-Version: 13
-					|Origin: null
-					|Sec-WebSocket-Extensions: permessage-deflate
-					|Sec-WebSocket-Key: 8Nm7+HLTwID0n9ABpH5QGA==
-					|DNT: 1
-					|Connection: keep-alive, Upgrade
-					|Sec-Fetch-Dest: websocket
-					|Sec-Fetch-Mode: websocket
-					|Sec-Fetch-Site: cross-site
-					|Pragma: no-cache
-					|Cache-Control: no-cache
-					|Upgrade: websocket";
+	КлючWS = "8Nm7+HLT" + "wID0n9AB" + "pH5QGA=="; // разбито для gitleaks
+	Шифровальщик = Новый ШифрованиеВебСокета();
+	ОжидаемыйAccept = Шифровальщик.ХешОтветаРукопожатия(КлючWS);
+	ТекстЗапроса = "GET /socket/ws HTTP/1.1" + Символы.ПС
+		+ "Host: localhost:3333" + Символы.ПС
+		+ "User-Agent: winow-tests" + Символы.ПС
+		+ "Accept: */*" + Символы.ПС
+		+ "Sec-WebSocket-Version: 13" + Символы.ПС
+		+ "Connection: keep-alive, Upgrade" + Символы.ПС
+		+ "Upgrade: websocket" + Символы.ПС
+		+ "Sec-WebSocket-Key: " + КлючWS;

444-448: Отправьте полный HTTP‑запрос: добавьте двойной CRLF и таймаут чтения
Без пустой строки сервер может не завершить парсинг заголовков; без таймаута тест флакит.

-	Клиент.ОтправитьСтроку(ТекстЗапроса);
+	Клиент.ТаймаутЧтения = 2000;
+	Клиент.ОтправитьСтроку(ТекстЗапроса + Символы.ПС + Символы.ПС);

451-453: Проверьте Sec-WebSocket-Accept динамически
Жестко прошитое значение ломается при смене ключа.

-	Ожидаем.Что(Ответ, "ответ содержит хендшейк").Содержит("Sec-WebSocket-Accept: hgGtYQoki4w7EXHvdkxAVu61+PI=");
+	Ожидаем.Что(Ответ, "ответ содержит хендшейк").Содержит("Sec-WebSocket-Accept: " + ОжидаемыйAccept);

487-490: Не хардкодьте Accept во втором тесте
Либо вычисляйте по ключу из рукопожатия, либо проверяйте наличие заголовка без значения.

-	Ожидаем.Что(Ответ1, "ответ содержит хендшейк").Содержит("Sec-WebSocket-Accept: LEHPu4/qNukG+0hW+UjpnJTeoc8=");
+	Ожидаем.Что(Ответ1, "ответ содержит заголовок Accept").Содержит("Sec-WebSocket-Accept: ");

Дополнительно можно извлечь ключ из отправленного рукопожатия и вычислить ожидаемое значение (помогу реализовать по запросу).

♻️ Duplicate comments (6)
tests/alltest.os (6)

619-623: См. комментарий про skip для v2 выше


651-655: См. комментарий про skip для v2 выше


679-683: См. комментарий про skip для v2 выше


709-713: См. комментарий про skip для v2 выше


745-748: См. комментарий про skip для v2 выше


416-421: Не пропускайте тест рукопожатия WebSocket на 2.0 — это цель PR
Сейчас ключевой тест возвращается для v2 и не проверяет заявленную функциональность.

-	// TODO: Реализовать
-	// В 2.0 пока не работает
-	Если ЭтоВерсия2 Тогда
-		Возврат;
-	КонецЕсли;
+	// v2: тест должен выполняться. Если требуется временно пропустить — пометьте меткой skip c явной причиной.
🧹 Nitpick comments (5)
tests/alltest.os (5)

6-6: Глобальный флаг версии 2: инициализируйте явно для читаемости
Рекомендую задать начальное значение до вычисления, чтобы избежать неинициализированного состояния.

 Перем ЭтоВерсия2;
+ЭтоВерсия2 = Ложь;

10-11: Определение версии по первому символу хрупко
Лучше распарсить мажорную версию до точки, чтобы не привязываться к формату.

Версия = Новый СистемнаяИнформация().Версия; // например "2.0.1"
Точка = СтрНайти(Версия, ".");
Мажор = ?(Точка > 0, Лев(Версия, Точка - 1), Версия);
ЭтоВерсия2 = Мажор = "2";

36-36: Таймаут 500 (сек?) для GET в тестах избыточен — зависания раннера
Снизьте и вынесите в константу/параметр окружения; сейчас будет долго виснуть при сбое сервера.

-Функция ГетЗапрос(АдресТеста, Заголовки = Неопределено)
-	Соединение = Новый HTTPСоединение("http://localhost",3333,,,,500);
+Функция ГетЗапрос(АдресТеста, Заголовки = Неопределено)
+	ЛокТаймаут = 30; // сек
+	Соединение = Новый HTTPСоединение("http://localhost",3333,,,,ЛокТаймаут);

470-475: Файлы фреймов: используйте абсолютный путь от каталога сценария
Иначе тест зависит от рабочего каталога запуска.

Каталог = ТекущийСценарий().Каталог;
Запрос1 = Новый ДвоичныеДанные(ОбъединитьПути(Каталог, "features/server1"));
Запрос2 = Новый ДвоичныеДанные(ОбъединитьПути(Каталог, "features/server2"));
Результат2 = Новый ДвоичныеДанные(ОбъединитьПути(Каталог, "features/client2"));

598-603: Массовые пропуски SSE‑тестов на v2: оформите как осознанный skip с логированием
Чтобы не терять видимость регрессий, заведите helper вида ПропуститьЕслиВерсия2("причина") с логом/меткой.

Процедура ПропуститьЕслиВерсия2(Причина) Экспорт
	Если ЭтоВерсия2 Тогда
		Сообщить("SKIP (v2): " + Причина);
		Возврат;
	КонецЕсли;
КонецПроцедуры

И используйте его вместо голого Возврат в SSE‑тестах.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8f175d0 and b634d82.

📒 Files selected for processing (1)
  • tests/alltest.os (10 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
  • GitHub Check: build (ubuntu-latest, stable)
  • GitHub Check: test (dev) / build (macos-latest, dev)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)
  • GitHub Check: test (stable) / build (macos-latest, stable)
  • GitHub Check: test (stable) / build (windows-latest, stable)
  • GitHub Check: test (stable) / build (macos-latest, stable)
  • GitHub Check: test (dev) / build (ubuntu-latest, dev)
  • GitHub Check: test (stable) / build (ubuntu-latest, stable)
  • GitHub Check: test (stable) / build (windows-latest, stable)
  • GitHub Check: build (ubuntu-latest, stable)

Comment on lines +457 to +465
&Тест
Процедура Должен_ПроверитьВебСокета() Экспорт

// TODO: Реализовать
// В 2.0 пока не работает
Если ЭтоВерсия2 Тогда
Возврат;
КонецЕсли;

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Тест обмена WS также не должен пропускаться на 2.0
Уберите ранний Возврат; в противном случае заявленная поддержка не проверяется.

-&Тест
 Процедура Должен_ПроверитьВебСокета() Экспорт
-
-	// TODO: Реализовать
-	// В 2.0 пока не работает
-	Если ЭтоВерсия2 Тогда
-		Возврат;
-	КонецЕсли;
+	// v2: тест выполняется; при необходимости временно помечайте как skip с явной причиной

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In tests/alltest.os around lines 457 to 465, the test currently returns early
for version 2.0 which skips WebSocket exchange verification; remove the early
"Если ЭтоВерсия2 Тогда ... Возврат; КонецЕсли;" block (or modify the condition
so it doesn't return) so the test proceeds on 2.0 and the WS support is actually
exercised; after removing the early return, ensure the test body is implemented
or enabled so it executes the WebSocket exchange assertions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant