При интеграции 1С с внешними веб-сервисами и REST API разработчики часто сталкиваются с задачей передачи файлов через HTTP-протокол. Одной из распространенных проблем является ситуация, когда запрос приходит на сервер с пустым телом или возвращается ошибка соединения Couldn't resolve host name.
В этой статье разберем по шагам, почему возникает эта ошибка, как правильно инициализировать объекты HTTPСоединение и HTTPЗапрос для передачи файлов и какие особенности нужно учитывать при настройке отправки данных.
Выясним причину возникновения ошибки Couldn't resolve host name. Данное сообщение указывает на то, что сетевая подсистема платформы 1С не может определить IP-адрес указанного сервера.
Проанализируем основные причины этой проблемы:
http:// или https:// в первом параметре конструктора HTTPСоединение. Параметр должен содержать только имя хоста (например, mysite.ru) или его IP-адрес.АдресРесурса объекта HTTPЗапрос и начинаться со символа /.Рассмотрим, как правильно формировать объект соединения в коде 1С.
// Неправильное указание адреса сервера:
// Соединение = Новый HTTPСоединение("http://api.mysite.ru");
// Правильное указание адреса сервера:
Сервер = "api.mysite.ru";
Порт = 80;
Соединение = Новый HTTPСоединение(Сервер, Порт);
Если обмен происходит по защищенному протоколу HTTPS, в конструктор HTTPСоединение обязательно передается объект ЗащищенноеСоединениеOpenSSL:
ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("api.mysite.ru", 443, , , , , ЗащищенноеСоединение);
В зависимости от требований принимающего веб-сервера в 1С предусмотрены различные способы установки тела POST-запроса.
Метод УстановитьИмяФайлаТела() считывает содержимое файла напрямую с диска при отправке запроса (RAW POST).
ИмяФайла = "C:\Temp\data.xml";
Запрос = Новый HTTPЗапрос;
Запрос.АдресРесурса = "/api/v1/upload";
Запрос.Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");
Запрос.УстановитьИмяФайлаТела(ИмяФайла);
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Обратите внимание: если код выполняется на стороне сервера 1С (например, в фоновом задании), файл по указанному пути должен быть доступен учетной записи ОС, от имени которой запущен процесс rphost. Файлы из временных папок клиентского сеанса серверу 1С недоступны.
Если файл предварительно необходимо считать в память или получить из хранилища значений, применяется метод УстановитьТелоИзДвоичныхДанных():
ИмяФайла = "C:\Temp\document.pdf";
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ИмяФайла);
Запрос = Новый HTTPЗапрос;
Запрос.АдресРесурса = "/api/v1/upload_file";
Запрос.Заголовки.Вставить("Content-Type", "application/pdf");
Запрос.УстановитьТелоИзДвоичныхДанных(ДвоичныеДанныеФайла);
Ответ = Соединение.ВызватьHTTPМетод("POST", Запрос);
Если принимающий сервис ожидает загрузку файла через веб-форму (формат multipart/form-data), то простой передачи байтов через УстановитьИмяФайлаТела() недостаточно — сервер вернет ошибку или посчитает тело запроса пустым.
Для такой загрузки необходимо вручную сформировать текстовое или бинарное тело запроса с использованием границы разделителя (boundary), заголовков Content-Disposition и Content-Type для каждого элемента формы.
Рассмотрев основные моменты, мы выяснили, что для успешной передачи файлов необходимо исключать префиксы протоколов из имени сервера в HTTPСоединение, корректно указывать адрес ресурса и следить за правами доступа сервера 1С к отправляемым файлам.