Почему после обновления платформы 1С перестали работать HTTP GET запросы и как исправить ошибку Failure when receiving data from the peer?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

Обновление технологической платформы «1С:Предприятие» — важный и регулярный процесс, необходимый для получения новых функций и исправлений безопасности. Однако иногда этот процесс приносит неожиданные «сюрпризы» разработчикам, особенно в механизмах интеграции. Одной из распространенных проблем, с которой мы сталкиваемся при переходе с версий 8.3.10–8.3.18 на современные релизы (8.3.21, 8.3.22 и выше), является внезапный отказ работы HTTP-запросов, которые годами функционировали исправно.

В этой статье мы подробно разберем ситуацию, когда после обновления платформы перестают работать HTTPЗапрос с методами GET, и 1С возвращает ошибку "Ошибка работы с Интернет: Failure when receiving data from the peer". Мы проанализируем причины этого поведения, выясним, почему диагностика через Fiddler может вводить в заблуждение, и рассмотрим правильный подход к написанию кода интеграции, например, с использованием аутентификации по JWT-токену или валидатора OpenAPI-схем.

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

Рассмотрим типичный сценарий. У нас есть конфигурация (например, УПП или самописная база), которая обменивается данными с внешним API, например, для заполнения контрагентов по ИНН или создания счетов через POST-запросы. Код обмена прост и стабилен. После обновления платформы (например, с 8.3.11 до 8.3.22) исходящие запросы перестают выполняться.

При этом мы наблюдаем следующие странности:

  1. POST-запросы к тому же хосту (например, для получения токена авторизации RuStore или JWT-токена) проходят успешно.
  2. GET-запросы падают с ошибкой обрыва соединения или невозможности получения данных.
  3. Брандмауэры и прокси на сервере отключены или настроены корректно.
  4. Самое удивительное: если мы пытаемся отладить запрос, запустив Fiddler (или другой сниффер трафика) и пустив трафик через него, запросы из 1С внезапно начинают работать!

Такое поведение часто ставит в тупик: кажется, что проблема «плавающая» или зависит от какой-то магии сети. Однако причина кроется в строгом следовании стандартам HTTP в новых версиях платформы.

Техническая причина: обновление libcurl и стандарты RFC

Чтобы понять суть проблемы, нам нужно заглянуть «под капот» платформы 1С. Для реализации HTTP-соединений платформа использует популярную открытую библиотеку libcurl. В версиях платформы 8.3.21+ разработчики 1С обновили встроенную версию этой библиотеки, а также библиотек OpenSSL.

Более новые версии libcurl стали строже относиться к соблюдению спецификаций протокола HTTP (RFC 7231). Согласно стандартам, метод GET предназначен для получения данных и семантически не должен содержать тела запроса (Body). Хотя стандарт жестко не запрещает наличие тела, многие современные веб-серверы и промежуточные узлы считают GET-запрос с телом некорректным и разрывают соединение.

Ранее старые версии платформы (и старая libcurl) «прощали» разработчикам установку тела в GET-запросах, даже если это тело было пустой строкой. Теперь же механизмы работают иначе.

Анализ проблемного кода

Давайте посмотрим на пример кода, который вызывал ошибку. Обратите внимание на создание и настройку объекта HTTPЗапрос.


// Создание соединения
Соединение = Новый HTTPСоединение(Выборка.Хост, , , , , , Новый ЗащищенноеСоединениеOpenSSL());

СтрокаЗапроса = Выборка.СтрокаЗапроса;
// ... логика подготовки строки ...

Запрос = Новый HTTPЗапрос(СтрокаЗапроса, Заголовки);
ТелоЗапроса = Выборка.ТелоЗапроса; // Часто здесь пустая строка для GET

// ... логика подготовки тела ...

// ВОТ ЗДЕСЬ КРОЕТСЯ ОШИБКА
Запрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

// Выполнение запроса
Ответ = Соединение.ВызватьHTTPМетод(?(Выборка.МетодЗапроса = 0, "GET", "POST"), Запрос);

Разберем, что здесь происходит не так. Разработчик написал универсальный код, который обрабатывает и GET, и POST запросы. В переменной ТелоЗапроса для GET-запроса обычно содержится пустая строка "".

Метод УстановитьТелоИзСтроки выполняет следующие действия:

  1. Устанавливает содержимое тела запроса.
  2. Автоматически добавляет или корректирует заголовки, связанные с контентом (например, Content-Type и, что важнее, Content-Length).

В новых версиях платформы вызов УстановитьТелоИзСтроки, даже с пустой строкой, сигнализирует библиотеке libcurl о том, что у запроса есть тело (пусть и нулевой длины). Это приводит к формированию пакета, который сервер воспринимает как ошибочный для метода GET, и соединение сбрасывается с ошибкой Failure when receiving data from the peer.

Почему запрос работал через Fiddler?

Этот момент часто сбивает с толку. Fiddler работает как Man-in-the-Middle (MITM) прокси. Схема работы выглядит так:

  1. 1С отправляет «некорректный» запрос в Fiddler.
  2. Fiddler принимает его, разбирает на составляющие.
  3. Fiddler пересобирает запрос заново, чтобы отправить его на реальный сервер.

В процессе пересборки Fiddler часто «нормализует» запрос. Видя, что это GET-запрос и тело пустое, он может автоматически удалить лишние заголовки Content-Length или само тело, делая запрос валидным. Сервер получает корректный запрос от Fiddler и отвечает успешно. Это создает иллюзию, что проблема не в 1С, а в сети.

Решение проблемы

Для исправления ситуации мы должны гарантировать, что для метода GET мы вообще не трогаем тело запроса. Нам необходимо явно разделить логику подготовки запроса в зависимости от HTTP-метода.

Перепишем наш код, добавив проверку. Мы не должны вызывать методы установки тела (ни УстановитьТелоИзСтроки, ни УстановитьТелоИзДвоичныхДанных), если мы готовим GET-запрос.

Правильный алгоритм действий:


// Инициализация соединения и заголовков
Соединение = Новый HTTPСоединение(Хост, , , , , , Новый ЗащищенноеСоединениеOpenSSL());
Запрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);

// Определяем метод запроса (например, "GET" или "POST")
МетодЗапроса = "GET"; // В реальном коде берем из параметров

// ВАЖНО: Устанавливаем тело только если это НЕ GET запрос
Если МетодЗапроса <> "GET" Тогда
    
    // Подготовка тела нужна только для POST, PUT, PATCH
    ТелоЗапроса = ПолучитьJSONТело(); 
    Запрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
    
КонецЕсли;

// Выполняем запрос
Попытка
    Ответ = Соединение.ВызватьHTTPМетод(МетодЗапроса, Запрос);
Исключение
    // Обработка ошибок соединения
    ЗаписьЖурналаРегистрации("HTTPОшибка", УровеньЖурналаРегистрации.Ошибка, , , ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;

Таким образом, для GET-запроса объект HTTPЗапрос останется «чистым» в плане контента, библиотека libcurl не добавит лишних заголовков, и сервер корректно обработает обращение.

Дополнительные проблемы при обновлении: SSL и TLS

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

Новые версии платформы (и обновленный OpenSSL внутри) по умолчанию отключают поддержку устаревших протоколов шифрования (SSLv3, TLS 1.0, TLS 1.1). Если API, к которому вы обращаетесь, находится на старом сервере, не поддерживающем TLS 1.2 или TLS 1.3, вы также получите ошибку соединения (часто Connection closed или ошибки SSL handshake).

Как это проверить и исправить:

  1. Проверьте целевой ресурс через браузер или онлайн-сервисы проверки SSL, чтобы узнать, какие протоколы он поддерживает.
  2. Если сервер поддерживает только старые протоколы (что небезопасно), единственным решением на стороне 1С (без понижения безопасности всей платформы через конфиги) является обновление настроек веб-сервера получателя.
  3. Также обратите внимание на валидность сертификатов. Новая платформа строже проверяет цепочки сертификатов. Если используются самоподписанные сертификаты, их корневые сертификаты обязательно должны быть добавлены в файл cacert.pem, используемый платформой 1С.

Использование Технологического журнала (ТЖ) 1С для диагностики

Если приведенное решение с телом запроса не помогло, или ошибка сохраняется, нам необходимо заглянуть глубже. Для этого используем Технологический журнал (ТЖ) 1С, который также можно экспортировать в Elastic для углубленного анализа.

Настроим сбор логов события NETWORK. Это позволит увидеть низкоуровневые ошибки библиотеки libcurl.

Пример настройки logcfg.xml для отлова сетевых ошибок:


<log location="C:\Logs\NetworkError" history="24">
    <event>
        <eq property="name" value="NETWORK"/>
    </event>
    <property name="all"/>
</log>

В полученных логах ищите свойства Descr или Error. Там могут быть указания на конкретные коды ошибок SSL (например, SEC_E_ALGORITHM_MISMATCH) или HTTP-протокола, которые точно укажут на причину разрыва соединения.

Заключение

Обновление платформы — это шаг вперед к безопасности и стандартам, но он требует от нас пересмотра старого кода. Основные выводы для стабильной работы HTTP-запросов в современных версиях 1С:

  1. Никогда не вызывайте УстановитьТелоИзСтроки для GET-запросов, даже с пустой строкой. Используйте условие Если.
  2. Помните, что работа через Fiddler не гарантирует, что запрос сформирован идеально верно, так как прокси может исправлять ошибки «на лету».
  3. Учитывайте ужесточение требований к SSL/TLS сертификатам и протоколам.

Применяя эти правила, вы сможете избежать простоев в интеграции и обеспечить стабильную работу обменов данными.

← На главную