Почему HTTP-сервис 1С на IIS возвращает ошибку при отправке XML-данных больше 1.2 Мб и как это исправить?

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

При разработке интеграционных решений на базе HTTP-сервисов 1С программисты часто сталкиваются с коварной проблемой: при передаче небольших пакетов данных сервис работает безупречно, но как только объем XML-данных превышает «порог» примерно в 1.2–1.3 Мб (около 1296 Кб), клиентские приложения внезапно перестают получать ответ. Браузер Chrome выдает ошибку «Не удается получить доступ к сайту» (Connection Reset), а утилита Postman рапортует о невозможности получить данные: «Could not get any response».

Самое загадочное в этой ситуации — поведение логов веб-сервера IIS. Если мы проанализируем файл логов IIS, то обнаружим, что веб-сервер регистрирует успешную обработку запроса со статус-кодом 200 OK. Получается парадокс: система 1С отработала без ошибок, IIS считает, что успешно отдал данные, но клиент на другом конце сетевого провода остался ни с чем. Выясним причину этой проблемы и подробно разберем несколько эффективных способов её решения.

Почему происходит обрыв соединения на уровне IIS?

Проанализируем физику процесса взаимодействия платформы 1С, веб-сервера IIS и сетевого клиента. Проблема кроется в архитектурных особенностях взаимодействия модуля расширения веб-сервера 1С (wsisapi.dll) и IIS. Когда размер ответа превышает определенный лимит (обычно около 1 Мб), в работу вступают встроенные оптимизаторы и защитные механизмы IIS, которые некорректно обрабатывают динамические потоки данных. Происходит аварийный сброс TCP-соединения (так называемый TCP RST), из-за чего клиент видит сетевую ошибку, хотя сам веб-сервер считает транзакцию завершенной.

Рассмотрим по шагам основные причины возникновения этого сбоя и способы их устранения.

Решение 1. Отключение динамического сжатия контента на IIS

По умолчанию в IIS включена функция динамического сжатия содержимого (Dynamic Content Compression). Веб-сервер пытается сжать генерируемый 1С XML-пакет «на лету» с помощью алгоритма GZIP перед отправкой клиенту.

Когда размер динамического XML-ответа переваливает за отметку 1 Мб, модуль сжатия IIS из-за особенностей работы с wsisapi.dll не может корректно выделить буфер под динамический поток. Происходит внутренний сбой в рабочем процессе IIS (w3wp.exe), приводящий к немедленному закрытию сетевого сокета. При этом заголовок ответа со статусом 200 веб-сервер отправить успевает, что и фиксируется в его логах.

Чтобы отключить динамическое сжатие для вашей публикации 1С, выполним следующие действия:

  1. Откройте Диспетчер служб IIS (IIS Manager).
  2. В дереве подключений выберите ваш сайт или конкретное виртуальное приложение (публикацию базы 1С).
  3. В центральной части окна («Просмотр функций») найдите и откройте раздел «Сжатие» (Compression).
  4. Снимите флажок с пункта «Включить динамическое сжатие содержимого» (Enable dynamic content compression).
  5. Примените изменения и выполните перезапуск IIS (команда iisreset в командной строке от имени администратора).

Если сжатие трафика для вашей системы критично, рекомендуется осуществлять его силами самой 1С (например, упаковывать XML в ZIP-архив средствами платформы) либо использовать внешние прокси-серверы (например, Nginx), установленные перед IIS, которые гораздо стабильнее справляются со сжатием динамических потоков данных.

Решение 2. Переход от Chunked Transfer Encoding к фиксированному Content-Length в коде 1С

При стандартном формировании ответа в 1С разработчики часто используют метод УстановитьТелоИзСтроки(). Посмотрим на типичный пример кода, который может приводить к ошибкам при больших объемах данных:


// Проблемный вариант формирования ответа
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/xml; charset=utf-8");
Ответ.УстановитьТелоИзСтроки(СтрокаXML, КодировкаТекста.UTF8);
Возврат Ответ;

При использовании метода УстановитьТелоИзСтроки() веб-сервер не знает заранее точный размер генерируемого контента в байтах. Поэтому IIS отправляет данные клиенту по частям (чанками), автоматически добавляя заголовок Transfer-Encoding: chunked. Передача больших объемов данных чанками через ISAPI-расширение 1С часто блокируется сетевыми экранами, антивирусами или защитными модулями самого IIS, расценивающими такой поток как потенциальную угрозу безопасности.

Для решения этой проблемы перепишем логику формирования тела ответа в 1С. Мы принудительно преобразуем XML-строку в двоичные данные. В этом случае платформа самостоятельно вычислит точный размер пакета в байтах и передаст его в заголовке Content-Length, полностью исключая использование потоковой передачи (chunked).

Рассмотрим правильный пример реализации кода в 1С:


// Оптимальный вариант формирования ответа
Ответ = Новый HTTPСервисОтвет(200);
Ответ.Заголовки.Вставить("Content-Type", "application/xml; charset=utf-8");

// Преобразуем строковый XML в ДвоичныеДанные
ДвоичныеДанныеОтвета = ПолучитьДвоичныеДанныеИзСтроки(СтрокаXML, КодировкаТекста.UTF8, Истина);

// Устанавливаем двоичные данные в тело ответа
Ответ.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеОтвета);
Возврат Ответ;

Применение этого несложного приема позволяет веб-серверу IIS передавать данные единым пакетом с четко определенным размером, что кардинально повышает стабильность доставки XML-документов большого объема.

Решение 3. Изменение разрядности пула приложений IIS

Если публикация вашей информационной базы работает в 32-разрядном пуле приложений IIS (или в настройках пула включена опция поддержки 32-битных приложений), рабочий процесс w3wp.exe сталкивается с жесткими ограничениями операционной системы на выделение непрерывных участков оперативной памяти.

При формировании тяжелых XML-структур в памяти 1С реальный объем потребляемой RAM может в 5–10 раз превышать итоговый размер файла на диске из-за создания сложных объектных моделей (DOM). При достижении размера XML-строки в ~1.2 Мб процесс веб-сервера может столкнуться с фрагментацией адресного пространства памяти и «тихо» оборвать сетевую сессию.

Проанализируем настройки вашего IIS и выполним следующие изменения:

  1. Откройте Диспетчер служб IIS и перейдите в раздел «Пулы приложений» (Application Pools).
  2. Найдите пул приложений, который обслуживает вашу публикацию 1С, нажмите на него правой кнопкой мыши и выберите «Дополнительные параметры» (Advanced Settings).
  3. Найдите параметр «Разрешены 32-разрядные приложения» (Enable 32-Bit Applications) и убедитесь, что он установлен в значение False.
  4. Убедитесь, что в сопоставлении обработчиков для вашей публикации используется 64-битная версия библиотеки расширения 1С: путь должен вести в папку C:\Program Files\1cv8\..., а не в C:\Program Files (x86)\1cv8\....

Решение 4. Исключение ложных срабатываний систем безопасности (DPI и Antivirus)

Нередко виновниками обрыва соединения на объемах более 1 Мб выступают системы глубокого анализа пакетов (DPI), брандмауэры или локальное антивирусное ПО, установленное на сервере. Большие объемы XML-структур, передаваемые единым непрерывным потоком, могут распознаваться защитными системами как попытка атаки типа «XML Entity Expansion» или «XML Injection».

Для локализации проблемы выполним следующие диагностические действия:

Решение 5. Установка актуальной версии платформы 1С

Стоит также помнить о возможных внутренних ошибках самой платформы 1С. В истории развития технологической платформы 1С:Предприятие 8.3 были зафиксированы релизы (в частности, в ветках 8.3.11–8.3.12), в которых сериализация больших объемов данных в HTTP-сервисах приводила к аварийному завершению сеанса связи. Начиная с версии 8.3.13, данные платформенные баги были успешно устранены разработчиками фирмы «1С».

Если все предыдущие настройки IIS выполнены верно, но ошибка сохраняется, настоятельно рекомендуем обновить технологическую платформу 1С:Предприятие на сервере до актуального стабильного релиза.

← На главную