Функция написана при решении задачи отказа от curl в пользу инструментов, встроенных в язык 1С.
Возможности:
-
Получение xml от УТМ ЕГАИС в виде файла на диске
-
Отправка xml в УТМ ЕГАИС и получение ответного xml
-
Реализованы 2 метода отправки: curl и HTTPЗапрос. curl.exe должен лежать в директории C:\temp\
Пример использования:
Запрос реквизитов контрагента
- Формируем файл (client.xml):
<ns:Documents Version="1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns="http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01"
xmlns:oref="http://fsrar.ru/WEGAIS/ClientRef"
xmlns:qp="http://fsrar.ru/WEGAIS/QueryParameters">
<ns:Owner>
<ns:FSRAR_ID>00040218</ns:FSRAR_ID>
</ns:Owner>
<ns:Document> (5.1)
<ns:QueryClients>
<qp:Parameters>
<qp:Parameter>
<qp:Name>ИНН</qp:Name>
<qp:Value>1681000049<</qp:Value>
</qp:Parameter>
</qp:Parameters>
</ns:QueryClients>
</ns:Document>
</ns:Documents>
- Запускаем обработку. Заполняем поля:
-
URI: 10.10.10.10:8080/opt/in. вместо 10.10.10.10 указываем адрес компьютера с установленным УТМ
-
Путь к файлу ответа - путь к файлу, в котороый будет записан ответ УТМ. Файл может не существовать, но папка должна быть
-
Команда - GET
-
Метод отправки - выбрать любой
-
- Проверяем очередь входящих (URI: 10.10.10.10:8080/opt/in)
- Через некоторое время увидим ответ от УТМ:
-
<ns:Documents xmlns:rc="http://fsrar.ru/WEGAIS/ReplyClient" xmlns:oref="http://fsrar.ru/WEGAIS/ClientRef" xmlns:ns="http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01"> <ns:Owner> <ns:FSRAR_ID>3463047</ns:FSRAR_ID> </ns:Owner> <ns:Document> <ns:ReplyClient> <rc:Clients> <rc:Client xmlns:rc="http://fsrar.ru/WEGAIS/ReplyClient" xmlns:oref="http://fsrar.ru/WEGAIS/ClientRef"> <oref:ClientRegId>010000005339</oref:ClientRegId> <oref:INN>5256044729</oref:INN> <oref:KPP>526332001</oref:KPP> <oref:FullName>ООО ЦДА "Сомелье"</oref:FullName> <oref:ShortName>ООО "ЦДА "СОМЕЛЬЕ"</oref:ShortName> <oref:address> <oref:Country>643</oref:Country> <oref:RegionCode>52</oref:RegionCode> <oref:description> РОССИЯ,603127,НИЖЕГОРОДСКАЯ ОБЛ,,Нижний Новгород г,СОРМОВСКИЙ РАЙОН,Федосеенко ул,46А,ЛИТЕР К4, 1 ЭТАЖ,ПОМЕЩЕНИЕ №№ 19, 20, 21, 22 </oref:description> </oref:address> <oref:State>Active</oref:State> </rc:Client> <rc:Client xmlns:rc="http://fsrar.ru/WEGAIS/ReplyClient" xmlns:oref="http://fsrar.ru/WEGAIS/ClientRef"> <oref:ClientRegId>030000039632</oref:ClientRegId> <oref:INN>5256044729</oref:INN> <oref:KPP>525601001</oref:KPP> <oref:FullName> Общество с ограниченной ответственностью Центр дистрибуции алкоголя "Сомелье" </oref:FullName> <oref:ShortName>ООО ЦДА "Сомелье"</oref:ShortName> <oref:address> <oref:Country>643</oref:Country> <oref:RegionCode>52</oref:RegionCode> <oref:description> Россия, 603147,Нижегородская обл,Юлиуса Фучика ул,Нижний Новгород г,43 А, </oref:description> </oref:address> <oref:State>Active</oref:State> </rc:Client> </rc:Clients> </ns:ReplyClient> </ns:Document> </ns:Documents>
Спасибо desarz за публикацию HTTP POST запрос к УТМ системы ЕГАИС.
// Функция выполняет HTTP запрос curl`ом либо 1С HTTPЗапросом
// Параметры:
// URI - Строка - адрес для отправки запроса вида
// [http://]<ip>[:<port>][/<url>],
// пример: 10.10.10.1:8080/opt/in/ActWriteOff
//
// Команда - Строка - "GET" | "POST" | "DELETE" -
// метод http запроса
//
// ПутьКФайлуОтправки - Строка – путь к отправляемому файлу,
// пример: c:\temp\query.xml
//
// ПутьКФайлуОтвета - Строка - путь к файлу, в который будет записан ответ
// пример: c:\temp\reply.xml
//
// Таймаут - Число - максимальное время выполнения операции в секундах
//
// ТолькоCurl - Булево - флаг принудительного использования curl.exe
//
// Возвращаемое значение:
// Булево - Истина: запрос успешно выполнен,
// Ложь: запрос не выполнен
//
Функция ВыполнитьHTTPЗапрос(val URI, Команда = "POST", ПутьКФайлуОтвета, ПутьКФайлуОтправки = "", Таймаут = 120, ТолькоCurl = Ложь) Экспорт
// Разбор URI
Попытка
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.MultiLine = Ложь;
RegExp.Global = Ложь;
RegExp.IgnoreCase = Истина;
ШаблонIP = "(\d+\.\d+\.\d+\.\d+)";
ШаблонПорт = "\d+\.\d+\.\d+\.\d+:(\d+)";
ШаблонURI = "\d+(\/.*)";
RegExp.Pattern = ШаблонIP; Рез=RegExp.Execute(URI);
Если Рез.Count = 1 Тогда
IP = Рез.item(0).value;
Иначе
ВызватьИсключение "Ошибка разбора URI. Не удалось определить IP. URI: " + URI;
КонецЕсли;
RegExp.Pattern = ШаблонПорт; Рез=RegExp.Execute(URI);
Если Рез.Count = 1 Тогда
Порт = Рез.item(0).SubMatches.Item(0);
Иначе
Порт = "8080";
КонецЕсли;
RegExp.Pattern = ШаблонURI; Рез=RegExp.Execute(URI);
Если Рез.Count = 1 Тогда
АдресСкрипта = Рез.item(0).SubMatches.Item(0);
Иначе
АдресСкрипта = "";
ВызватьИсключение "Ошибка разбора URI. Не удалось определить АдресСкрипта. URI: " + URI;
КонецЕсли;
Исключение
Сообщить(ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
Если ТолькоCurl Тогда
СтрокаКоманды = "cmd /c c:\temp\curl.exe --max-time " + Таймаут;
Если Команда = "GET" Тогда
СтрокаКоманды = СтрокаКоманды + " -X GET %1 > %2";
СтрокаКоманды = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаКоманды, uri, ПутьКФайлуОтвета);
ИначеЕсли Команда = "POST" Тогда
СтрокаКоманды = СтрокаКоманды + " -F ""xml_file=@%1"" %2 > %3";
СтрокаКоманды = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаКоманды, ПутьКФайлуОтправки, uri, ПутьКФайлуОтвета);
ИначеЕсли Команда = "DELETE" Тогда
Возврат Ложь; // TODO
КонецЕсли;
Попытка
ЗапуститьПриложение(СтрокаКоманды, "C:\temp\", Истина);
Исключение
Сообщить(ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
Возврат Истина;
Иначе
Если Команда = "GET" Тогда
Попытка
НТТР = Новый HTTPСоединение(IP, Число(Порт),,,,Таймаут);
Ответ = НТТР.Получить(Новый HTTPЗапрос(АдресСкрипта),ПутьКФайлуОтвета);
Если Ответ.КодСостояния = 200 Тогда
Возврат Истина;
Иначе
Сообщить("Код ответа сервера: " + Ответ.КодСостояния);
Возврат Ложь;
КонецЕсли;
Исключение
Сообщить(ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
КонецЕсли;
Попытка
Boundary = СтрЗаменить(Новый УникальныйИдентификатор,"-","");
ИмяФайлаДляЗагрузки = ПутьКФайлуОтправки;//КаталогВременныхФайлов() + Boundary + "select.xml";
ИмяФайлаОтвета = КаталогВременныхФайлов() + Boundary + "answer.xml"; // Имя файла ответа на POST запрос
ИмяФайлаОтправки = КаталогВременныхФайлов() + Boundary + "post.txt";
//Определяем массив для процедуры ОбъединитьФайлы
МассивФайловДляОбъединения = Новый Массив;
//Формируем начальный фрагмент файла POST-запроса
ИмяФайлаОтправкиНачало = ПолучитьИмяВременногоФайла("txt");
ФайлОтправкиНачало = Новый ЗаписьТекста(ИмяФайлаОтправкиНачало, КодировкаТекста.ANSI, Символы.ПС, Ложь);
//Определяем раздел двоичных данных
ФайлОтправкиНачало.ЗаписатьСтроку("--" + Boundary);
//Указываем имя файла для передачи
ФайлОтправкиНачало.ЗаписатьСтроку("Content-Disposition: form-data; name=""xml_file""; filename=""" + "select.xml" + """");
//Указываем тип передаваемых данных.
ФайлОтправкиНачало.ЗаписатьСтроку("Content-Type: text/xml; charset=utf-8");
ФайлОтправкиНачало.ЗаписатьСтроку("");
ФайлОтправкиНачало.Закрыть();
МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиНачало);
МассивФайловДляОбъединения.Добавить(ИмяФайлаДляЗагрузки);
//Формируем конечный фрагмент файла POST-запроса
ИмяФайлаОтправкиКонец = ПолучитьИмяВременногоФайла("txt");
ФайлОтправкиКонец = Новый ЗаписьТекста(ИмяФайлаОтправкиКонец, КодировкаТекста.ANSI, Символы.ПС, Ложь);
//Завершение раздела двоичных данных
ФайлОтправкиКонец.ЗаписатьСтроку(Символы.ПС);
ФайлОтправкиКонец.ЗаписатьСтроку("--" + Boundary + "--");
ФайлОтправкиКонец.Закрыть();
МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиКонец); // !!! 3 добавление в массив
//Теперь сформированные фрагменты сообщения для сервера объединяем в один файл POST-запроса
ОбъединитьФайлы(МассивФайловДляОбъединения, ИмяФайлаОтправки);
ЗаголовокHTTP = Новый Соответствие();
//Укажем формат данных Content-Type
ЗаголовокHTTP.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);
Если ЗначениеЗаполнено(ПутьКФайлуОтправки) Тогда
//Укажем длину POST-запроса Content-Length
ФайлОтправки = Новый Файл(ИмяФайлаОтправки);
РазмерФайлаОтправки = XMLСтрока(ФайлОтправки.Размер());
ЗаголовокHTTP.Вставить("Content-Length", РазмерФайлаОтправки);
КонецЕсли;
СерверПриемник = IP;
НТТР = Новый HTTPСоединение(СерверПриемник, Число(Порт),,,,Таймаут);
Попытка
//Формируем HTTP запрос
ЗапросHTTP = Новый HTTPЗапрос(АдресСкрипта, ЗаголовокHTTP);
//Ответ от сервера получим в возвращаемом значении типа HTTPОтвет
ЗапросHTTP.УстановитьИмяФайлаТела(ИмяФайлаОтправки); //Устанавливает имя файла, из которого будет прочитано тело POST-запроса.
//Ответ от сервера получим в возвращаемом значении типа HTTPОтвет
ОтветHTTP = НТТР.ОтправитьДляОбработки(ЗапросHTTP, ИмяФайлаОтвета);
Исключение
ЗапросHTTP = Неопределено;
Сообщить("Неудачная попытка соединения с " + СерверПриемник + ": " + ОписаниеОшибки());
Возврат Ложь;
КонецПопытки;
//Разрушаем объект HTTP-запроса для освобождения файла POST-запроса.
//В противном случае при попытке удаления файла получим ошибку совместного доступа.
ЗапросHTTP = Неопределено;
Возврат Истина;
Исключение
ЗапросHTTP = Неопределено;
Сообщить(ОписаниеОшибки(),СтатусСообщения.Внимание);
Возврат Ложь;
КонецПопытки;
КонецЕсли;
КонецФункции
Пример xml файла для отправки (client.xml):
<?xml version="1.0" encodmg="UTF-8"?> <ns:Documents Version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns="http://fsrar.ru/WEGAIS/WB_DOC_SINGLE_01" xmlns:oref="http://fsrar.ru/WEGAIS/ClientRef" xmlns:qp="http://fsrar.ru/WEGAIS/QueryParameters"> <ns:Owner> <ns:FSRAR_ID>00040218</ns:FSRAR_ID> </ns:Owner> <ns:Document> (5.1) <ns:QueryClients> <qp:Parameters> <qp:Parameter> <qp:Name>ИНН</qp:Name> <qp:Value>1681000049<</qp:Value> </qp:Parameter> </qp:Parameters> </ns:QueryClients> </ns:Document> </ns:Documents>