Как исправить ошибку «Transferred a partial file» при работе 1С с API Почты России?

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

При интеграции 1С с внешними сервисами, такими как отправка-api.pochta.ru, разработчики часто сталкиваются с ошибкой «Ошибка работы с Интернет: Transferred a partial file». Эта проблема особенно характерна для платформы 1С:Предприятие 8.3.23 и выше при использовании защищенного соединения (HTTPS). В данной статье мы подробно разберем, почему возникает этот сбой, и проанализируем пошаговые методы его устранения. Для локализации подобных сетевых сбоев и детального просмотра отправляемых пакетов пригодится инструмент для перехвата и анализа HTTP-трафика внутри 1С.

Разбор причины 1: Ошибка формирования заголовков авторизации

Проанализируем исходный код. Одной из самых частых причин разрыва соединения сервером является некорректная передача авторизационных данных. Сервер Почты России может сбрасывать сессию сразу после получения заголовков, если их формат не соответствует спецификации, что клиент 1С интерпретирует как «передачу частичного файла». Для быстрой ручной проверки отправляемых заголовков и параметров авторизации без изменения кода конфигурации удобно использовать обработку для тестирования REST API.

Посмотрим на фрагмент кода:


ТокенАвторизации = "AccessToken 123"; 
КлючАвторизации = "Basic 123";        
    
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", "AccessToken " + ТокенАвторизации);
Заголовки.Вставить("X-User-Authorization", "Basic " + КлючАвторизации);

Здесь кроется логическая ловушка: переменная ТокенАвторизации уже содержит префикс AccessToken. При формировании соответствия Заголовки мы добавляем этот префикс еще раз. В результате в HTTP-запрос уходит строка вида AccessToken AccessToken 123. Выясним, как это исправить: необходимо либо убрать префикс из константы, либо не добавлять его при вставке в заголовки.

Разбор причины 2: Маркер последовательности байтов (BOM)

В платформе 1С метод УстановитьТелоИзСтроки по умолчанию может добавлять в начало строки невидимый символ BOM (Byte Order Mark). Многие современные API, включая Почту России, не ожидают увидеть этот маркер в JSON-пакете. Это приводит к расхождению между реальным размером данных и заголовком Content-Length.

Рассмотрим правильный способ установки тела запроса без использования BOM:


// Вместо стандартного вызова:
// HTTPЗапрос.УстановитьТелоИзСтроки(Строчка, "UTF-8");

// Используем явное отключение BOM:
HTTPЗапрос.УстановитьТелоИзСтроки(Строчка, "UTF-8", ИспользованиеByteOrderMark.НеИспользовать);

Это гарантирует, что в поток данных не попадут лишние байты, которые могут запутать SSL-слой при передаче пакетов.

Разбор причины 3: Использование двоичных данных для контроля размера

Иногда автоматический расчет длины контента платформой 1С при работе через УстановитьТелоИзСтроки дает сбой на уровне библиотеки libcurl. Чтобы исключить эту вероятность, мы рекомендуем преобразовывать строку JSON в объект ДвоичныеДанные самостоятельно. Проанализируем этот подход:


ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, Параметры);
СтрочкаJSON = ЗаписьJSON.Закрыть();

// Преобразуем строку в двоичные данные явно
ДанныеДляОтправки = ПолучитьДвоичныеДанныеИзСтроки(СтрочкаJSON, КодировкаТекста.UTF8, Ложь);
HTTPЗапрос.УстановитьТелоИзДвоичныхДанных(ДанныеДляОтправки);

// Дополнительно можно явно указать длину, если ошибка сохраняется
Заголовки.Вставить("Content-Length", СтрЗаменить(Формат(ДанныеДляОтправки.Размер(), "ЧГ=0"), " ", ""));

Такой метод позволяет точно контролировать каждый байт, передаваемый через HTTPСоединение.

Разбор причины 4: Специфика TLS и защищенного соединения

Ошибка «Transferred a partial file» часто связана с тем, что 1С (используя OpenSSL) не может корректно завершить «рукопожатие» (handshake) или согласовать версию протокола TLS. API Почты России требует протокол версии TLS 1.2 или выше.

Если вы используете конструкцию Новый ЗащищенноеСоединениеOpenSSL(неопределено, неопределено), 1С пытается подобрать параметры автоматически. В некоторых случаях помогает явное указание сертификатов системы. Разберем ситуацию: если на сервере, где выполняется код 1С, отсутствуют актуальные корневые сертификаты (например, сертификаты Минцифры или GlobalSign), соединение может обрываться в момент передачи данных.

Рекомендация: Убедитесь, что операционная система сервера обновлена и содержит актуальные корневые сертификаты удостоверяющих центров.

Разбор причины 5: Конфликт с протоколом HTTP/2

В последних релизах платформы (включая 8.3.23) библиотека libcurl может пытаться использовать протокол HTTP/2 по умолчанию. Если сервер Почты России или промежуточный прокси-сервер некорректно обрабатывает переключение протоколов, возникает обрыв соединения.

Выясним решение: попробуйте принудительно заставить соединение закрываться после каждого запроса, добавив заголовок Connection: close. Это предотвратит попытки повторного использования сокета (Keep-Alive), которые часто становятся причиной «partial file».

Заголовки.Вставить("Connection", "close");

Альтернативное решение: Использование WinHTTP

Если штатные средства HTTPСоединение не позволяют обойти ошибку на конкретном релизе платформы, рассмотрим вариант использования COM-объекта WinHttp.WinHttpRequest.5.1. Этот способ работает через системный стек Windows и часто более стабилен при работе с TLS-шифрованием.

Пример реализации через WinHTTP:


WinHttp = Новый COMОбъект("WinHttp.WinHttpRequest.5.1");
WinHttp.Open("POST", "https://" + АдресСервера + УрлСервиса, Ложь);
WinHttp.SetRequestHeader("Authorization", "AccessToken " + ТокенАвторизации);
WinHttp.SetRequestHeader("X-User-Authorization", "Basic " + КлючАвторизации);
WinHttp.SetRequestHeader("Content-Type", "application/json;charset=UTF-8");
WinHttp.Send(СтрочкаJSON);
РезультатТекст = WinHttp.ResponseText;

Этот метод часто служит «спасательным кругом», когда внутренние механизмы 1С конфликтуют с настройками безопасности конкретного API.

Подведем итог: Для исправления ошибки в первую очередь проверьте отсутствие дублирования префиксов в заголовках авторизации и отключите использование BOM. Если это не помогает — переходите на передачу через ДвоичныеДанные и добавьте заголовок Connection: close.

← На главную