Pull to refresh
0

Опыт передачи файлов большого объема по защищенному протоколу из 1С на сайт

Reading time5 min
Views20K
передача файлов большого объема по защищенному протоколу из 1С на сайт
Во время создания очередной B2B-системы на этапе интеграции 1С: Предприятие 8.2 с web — интерфейсом возникла необходимость безопасной передачи файлов больших размеров из 1С в web.
Для решения этой задачи был выбран протокол SFTP, как надежный и не имеющий ограничений по размеру передаваемого файла.
Во встроенном языке 1С: Предприятие 8.2 отсутствуют функции для передачи данных через SFTP, поэтому пришлось искать прикладные средства. На интернет-ресурсах, посвященных программированию 1С, есть примеры удачного использования freeware утилит типа WinSCP. Для использования данного способа необходимо из встроенного языка 1С выполнить запуск утилиты с параметрами командной строки.

Пример запуска утилиты WinCSP из 1С:

КомандаВыгрузки = Символ(34)+Строка(ПутьКПапкеХранилищаФТПФайлов)+"\"+ "WinSCP.com"+Символ(34)+"/script="+Символ(34)+Строка(ПутьКПапкеХранилищаФТПФайлов)+Символ(34)+"\script.txt "+"/parameter "+Символ(34)+Адрес+Символ(34)+" "+
Символ(34)+Ключ+Символ(34)+" "+Символ(34) + Подпапка + Символ(34) + " " + 
Символ(34) + ИмяФайлаОтправки + Символ(34);


Минусом такого решения является отсутствие возможности контроля ошибок запуска и выполнения из встроенного языка 1С. В связи с этим было принято решение написать внешнюю DLL компоненту для 1С: Предприятие 8.2.

Платформа 1С: Предприятие поддерживает две технологии создания внешних компонент Native API и COM. Выбор пал на Native API, так как компоненты, созданные по этой технологии работают как на клиенте, так и на сервере 1С. Используя материалы диска ИТС о технологии создания внешних компонент и open source библиотеки С++, был создан файл SftpExtension.dll (Скачать исходники можно тут).

Создание компоненты DLL

1. Для использования в компоненте протокола SFTP мы использовали две библиотеки.
— libssh http://www.libssh2.org/ (Скачиваем “git clone git://git.libssh2.org/libssh2.git”)
— openssl http://www.openssl.org/ (Скачиваем архив openssl-1.0.1c.tar.gz от сюда)
Подключаем библиотеки к проекту.

2. Каждый объект компоненты должен наследоваться от абстрактного класса IcomponentBase и IlanguageInterface.
  • IcomponentBase — реализует основные методы компоненты.
  • IlanguageInterface — служит для локализации методов и свойств 1С и С++ через определения массивов соответствий и методов акцессоров GetMethodName, GetPropName.

Часть кода компоненты описывающая возможность вызова функций С++ из 1С на русском языке:
При этом можно использовать другие языки.

static wchar_t *g_MethodNames[] = { L"SendFile",L"StartSession", L"EndSession", L"IsSessionStart",L"SetSshHost",L"SetSshLogin",L"SetSshPass",L"SetSftpPath",L"SetLocalPath"};


static wchar_t *g_MethodNamesRu[] = { 
L"ПослатьФайл",L"НачатьСессию",L"ЗакончитьСессию",L"ЕслиСессияНачата",
		L"УстановитьХост",L"УстановитьЛогин",L"УстановитьПароль", L"УстановитьУдаленныйПуть",L"УстановитьЛокальныйПуть"};



const WCHAR_T* SftpExtension::GetMethodName(const long lMethodNum, const long lMethodAlias)
{ 
    if (lMethodNum >= eMethLast)
        return NULL;

    wchar_t *wsCurrentName = NULL;
    WCHAR_T *wsMethodName = NULL;
    int iActualSize = 0;

    switch(lMethodAlias)
    {
    case 0: // First language
        wsCurrentName = g_MethodNames[lMethodNum];
        break;
       case 1: // Second language
        wsCurrentName = g_MethodNamesRu[lMethodNum];
        break;
    default: 
        return 0;
   }

    iActualSize = wcslen(wsCurrentName)+1;

    if (m_iMemory && wsCurrentName)
    {
        if(m_iMemory->AllocMemory((void**)&wsMethodName, iActualSize * sizeof(WCHAR_T)))
            ::convToShortWchar(&wsMethodName, wsCurrentName, iActualSize);
    }

    return wsMethodName;
}


3. Для вызова необходимой функции из компоненты используется метод CallAsFunc из интерфейса IcomponentBase. При вызове методов из компоненты 1С, вызывается этот С++ метод.

В качестве параметров метода используются:
  • lMethodNum – номер метода в массиве соответствий.
  • pvarRetValue – указатель на выходные параметры.
  • paParams — параметры из метода в 1С.
  • lSizeArray – размер массива, если входной параметр массив.


bool SftpExtension::CallAsFunc(const long lMethodNum,
                tVariant* pvarRetValue,tVariant* paParams, const long lSizeArray){

switch(lMethodNum){

		case eMethSendFile: 
		{	
		
			if (!lSizeArray || !paParams)
					return false;

			this->local_path = toChar(paParams);			
			WriteToServer(status, this->local_path); //
			pvarRetValue->pstrVal = status; //status

			pvarRetValue->strLen = strlen(pvarRetValue->pstrVal);
			TV_VT(pvarRetValue) = VTYPE_PSTR;
	            
			ret = true;
			break;
		}	}
return ret;
}


4. В нашем примере из 1С можно выполнять 4 метода, которым соответствуют С++ методы в DLL компоненте.

1С (методы) С++ методы
НачатьСессию()
Предварительно нужно определить параметры авторизации(хост, связку логин, пароль – либо rsa ключи, путь на удалённом сервере).
Поэтому функция НачатьСессию обрастает свойствами: Хост, Логин, Пароль, УдаленныйПуть
StartSSHSession(status,this->ssh_host,this->ssh_login,this->ssh_pass);
StartSftpSession(status,this->sftp_path)
ПослатьФайл(“Путь и имя файла на клиентской машине”)
WriteToServer(const char * &status, const char *loclfile)
ЕслиСессияНачата() isSessionStart()
ЗакончитьСессию() endSession() – завершает SFTP сеанс и SSH сеанс


5. В С++ нужно определить параметры доступа(чтение/запись) к созданным свойствам за это отвечают два метода IsPropReadable и IsPropWritable.

bool SftpExtension::IsPropReadable(const long lPropNum)
{
	switch(lPropNum)
	{ 
  	case ePropSshHost:
        	return true; 
	default:
    	return false;
	} 
	return false;}


Таблица соотношений свойств 1С и С++
1С(свойства) С++ свойства
Хост ssh_host
Логин ssh_login
Пароль ssh_pass
УдаленныйПуть Sftp_path


Готовую библиотеку можно скачать тут.

Работа с компонентой во встроенном языке 1С

1. Выполняем подключение и создаем объект внешней компоненты, с помощью стандартных команд встроенного языка 1С.

ПодключитьВнешнююКомпоненту("C:\SftpExtension\SftpExtension.dll","Компонента",ТипВнешнейКомпоненты.Native);
Компонента = Новый("AddIn.Компонента.SftpExtension");


2. Заполняем 4 свойства объекта компоненты Хост, Логин, Пароль, УдаленныйПуть.
Компонента.Хост = "192.168.0.1";
Компонента.Логин = "root";
Компонента.Пароль = "123";
Компонента.УдаленныйПуть = "/var/www/company/data/www/import/data.xml";


3. Открываем сессию соединения
Компонента.НачатьСессию();


4. Отправляем файл
Компонента.ПослатьФайл("C:\data.xml");


5. Отправляем следующий файл, с проверкой открыта ли сессия соединения.
Если Компонента.СессияНачата() Тогда
      Компонента.ПослатьФайл("C:\data2.xml");
Иначе
   Компонента.НачатьСессию();
   Компонента.ПослатьФайл("C:\data2.xml");
КонецЕсли;


6. После отправки файлов закрываем сессию
Компонента.ЗакончитьСессию();


В результате выполнения успешно был передан файл с C:\data2.xml в /var/www/company/data/www/import/data.xml.


Используемые материалы
Литература:
Мануал по созданию компоненты
Библиотеки для работы по SFTP:


Вывод: данная реализация позволяет передавать файлы из 1С: Предприятие 8.2. большого размера по защищенному протоколу SFTP. Плюс появляется возможность переносить часть функционала из 1С во внешнюю компоненту, что защищает написанный код и позволяет реализовывать дополнительный, не доступный 1С функционал.
Tags:
Hubs:
+5
Comments13

Articles

Information

Website
centrobit.ru
Registered
Founded
Employees
11–30 employees
Location
Россия