diff --git a/src/addins/ftp/Cargo.lock b/src/addins/ftp/Cargo.lock index 9473a841a7..0e75e3b8a8 100644 --- a/src/addins/ftp/Cargo.lock +++ b/src/addins/ftp/Cargo.lock @@ -42,6 +42,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "2.9.0" @@ -334,10 +340,11 @@ dependencies = [ ] [[package]] -name = "opi_mysql" +name = "opi_ftp" version = "0.1.0" dependencies = [ "addin1c", + "base64", "native-tls", "serde", "serde_json", diff --git a/src/addins/ftp/Cargo.toml b/src/addins/ftp/Cargo.toml index 1a375c67df..1ff0c51caf 100644 --- a/src/addins/ftp/Cargo.toml +++ b/src/addins/ftp/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "opi_mysql" +name = "opi_ftp" version = "0.1.0" edition = "2021" @@ -19,4 +19,5 @@ suppaftp = { version = "6.3.0", features = ["native-tls", "secure"] } serde_json = "1.0" serde = { version = "1.0.217", features = ["derive"] } native-tls = "0.2.14" -socks = "0.3.4" \ No newline at end of file +socks = "0.3.4" +base64 = "0.22.1" \ No newline at end of file diff --git a/src/addins/ftp/dependencies.log b/src/addins/ftp/dependencies.log index 211e097424..7ebb19bef1 100644 --- a/src/addins/ftp/dependencies.log +++ b/src/addins/ftp/dependencies.log @@ -1,15 +1,13 @@ "MAIN ---" - linux-vdso.so.1 (0x00007ffec07be000) - libssl.so.3 => /lib64/libssl.so.3 (0x000075673a000000) - libcrypto.so.3 => /lib64/libcrypto.so.3 (0x0000756739800000) - libm.so.6 => /lib64/libm.so.6 (0x0000756739400000) - libpthread.so.0 => /lib64/libpthread.so.0 (0x0000756739000000) - libc.so.6 => /lib64/libc.so.6 (0x0000756738c00000) - libdl.so.2 => /lib64/libdl.so.2 (0x0000756738800000) - /lib64/ld-linux-x86-64.so.2 (0x000075673a600000) - libz.so.1 => /lib64/libz.so.1 (0x0000756738400000) + linux-vdso.so.1 (0x00007ffe6f8db000) + libssl.so.3 => /lib64/libssl.so.3 (0x00007032ad000000) + libcrypto.so.3 => /lib64/libcrypto.so.3 (0x00007032ac800000) + libpthread.so.0 => /lib64/libpthread.so.0 (0x00007032ac400000) + libc.so.6 => /lib64/libc.so.6 (0x00007032ac000000) + libdl.so.2 => /lib64/libdl.so.2 (0x00007032abc00000) + /lib64/ld-linux-x86-64.so.2 (0x00007032ad400000) + libz.so.1 => /lib64/libz.so.1 (0x00007032ab800000) GLIBC_2.2.5 GLIBC_2.3 GLIBC_2.3.4 GLIBC_2.14 -GLIBC_2.17 diff --git a/src/addins/ftp/release.bat b/src/addins/ftp/release.bat index 6ae71a3ea4..868cee2295 100644 --- a/src/addins/ftp/release.bat +++ b/src/addins/ftp/release.bat @@ -1,8 +1,8 @@ @echo off :: Установить переменную -set CARGO_NAME=opi_mysql -set LIB_NAME=OPI_MySQL +set CARGO_NAME=opi_ftp +set LIB_NAME=OPI_FTP set ADDIN_DIR=%~dp0 set FOLV=true diff --git a/src/addins/ftp/src/component/mod.rs b/src/addins/ftp/src/component/mod.rs index 3374da9062..1f374a39cf 100644 --- a/src/addins/ftp/src/component/mod.rs +++ b/src/addins/ftp/src/component/mod.rs @@ -1,4 +1,5 @@ mod ftp_client; +mod tcp_establish; use addin1c::{name, Variant}; use crate::core::getset; @@ -11,13 +12,13 @@ use crate::component::ftp_client::FtpClient; use std::net::TcpStream; use std::sync::{Arc, Mutex, MutexGuard}; use std::time::Duration; -use socks::{Socks4Stream, Socks5Stream}; // МЕТОДЫ КОМПОНЕНТЫ ------------------------------------------------------------------------------- // Синонимы pub const METHODS: &[&[u16]] = &[ name!("Connect"), + name!("Close"), name!("UpdateSettings"), name!("UpdateProxy"), name!("SetTLS"), @@ -28,9 +29,11 @@ pub const METHODS: &[&[u16]] = &[ pub fn get_params_amount(num: usize) -> usize { match num { 0 => 0, - 1 => 1, + 1 => 0, 2 => 1, - 3 => 3, + 3 => 1, + 4 => 3, + 5 => 0, _ => 0, } } @@ -42,15 +45,16 @@ pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box Box::new(obj.initialize()), - 1 => { + 1 => Box::new(obj.close_connection()), + 2 => { let json_string = params[0].get_string().unwrap_or("".to_string()); Box::new(obj.update_settings(&json_string)) }, - 2 => { + 3 => { let json_string = params[0].get_string().unwrap_or("".to_string()); Box::new(obj.update_proxy(&json_string)) }, - 3 => { + 4 => { let use_tls = params[0].get_bool().unwrap_or(false); let accept_invalid_certs = params[1].get_bool().unwrap_or(false); @@ -59,7 +63,7 @@ pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box { + 5 => { Box::new(match obj.get_client(){ Ok(c) => c.get_welcome_msg(), Err(e) => process_error(e.as_str()) @@ -182,7 +186,6 @@ impl AddIn { Err(e) => return process_error(&e.to_string()), }; - self.proxy_server = json_struct.server; self.proxy_port = json_struct.port; self.proxy_login = json_struct.login; @@ -199,7 +202,7 @@ impl AddIn { return process_error("Address must be initialized"); } - let tcp_stream = match self.create_tcp_connection() { + let tcp_stream = match tcp_establish::create_tcp_connection(self) { Ok(stream) => stream, Err(e) => return e, }; @@ -266,53 +269,7 @@ impl AddIn { } } - fn create_tcp_connection(&self) -> Result { - if let (Some(proxy_server), Some(proxy_port), Some(proxy_type)) = - (&self.proxy_server, &self.proxy_port, &self.proxy_type) - { - - let target_addr = (self.domain.as_str(), self.port); - let proxy_addr = format!("{}:{}", proxy_server, proxy_port); - - match proxy_type.to_lowercase().as_str() { - "socks5" => self.connect_via_socks5(&proxy_addr, target_addr), - "socks4" => self.connect_via_socks4(&proxy_addr, target_addr), - _ => Err(process_error("Unsupported proxy type")), - } - } else { - self.connect_direct() - } - } - - fn connect_via_socks5(&self, proxy_addr: &str, target_addr: (&str, u16)) -> Result { - - let stream = if let (Some(user), Some(pass)) = (&self.proxy_login, &self.proxy_password) { - Socks5Stream::connect_with_password(proxy_addr, target_addr, user, pass) - } else { - Socks5Stream::connect(proxy_addr, target_addr) - }; - - stream.map(|s| s.into_inner()) - .map_err(|e| process_error(&format!("SOCKS5 error: {}", e))) - } - - fn connect_via_socks4(&self, proxy_addr: &str, target_addr: (&str, u16)) -> Result { - - let stream = if let Some(user) = &self.proxy_login { - Socks4Stream::connect(proxy_addr, target_addr, user) - } else { - Socks4Stream::connect(proxy_addr, target_addr, "") - }; - - stream.map(|s| s.into_inner()) - .map_err(|e| process_error(&format!("SOCKS4 error: {}", e))) - } - - fn connect_direct(&self) -> Result { - let addr = format!("{}:{}", &self.domain, &self.port); - TcpStream::connect(&addr).map_err(|e| process_error(&format!("Direct connection error: {}", e))) - } pub fn close_connection(&mut self) -> String { if let Some(client) = self.client.take() { @@ -394,6 +351,8 @@ pub fn process_error(e: &str) -> String{ // Обработка удаления объекта impl Drop for AddIn { - fn drop(&mut self) {} + fn drop(&mut self) { + self.close_connection(); + } } diff --git a/src/addins/ftp/src/component/tcp_establish.rs b/src/addins/ftp/src/component/tcp_establish.rs new file mode 100644 index 0000000000..bf480d5db6 --- /dev/null +++ b/src/addins/ftp/src/component/tcp_establish.rs @@ -0,0 +1,123 @@ +use std::io::{BufRead, BufReader, Write}; +use std::net::TcpStream; +use crate::component::AddIn; +use crate::component::process_error; +use socks::{Socks4Stream, Socks5Stream}; +use base64::{Engine as _, engine::general_purpose}; + +pub fn create_tcp_connection(obj: &AddIn) -> Result { + + if let (Some(proxy_server), Some(proxy_port), Some(proxy_type)) = + (&obj.proxy_server, &obj.proxy_port, &obj.proxy_type) + { + + let target_addr = (obj.domain.as_str(), obj.port); + let proxy_addr = format!("{}:{}", proxy_server, proxy_port); + + match proxy_type.to_lowercase().as_str() { + "socks5" => connect_via_socks5(obj, &proxy_addr, target_addr), + "socks4" => connect_via_socks4(obj, &proxy_addr, target_addr), + "http" => connect_via_http_proxy(obj, &proxy_addr, target_addr), + _ => Err(process_error("Unsupported proxy type")), + } + } else { + connect_direct(obj) + } +} + +fn connect_via_socks5(obj: &AddIn, proxy_addr: &str, target_addr: (&str, u16)) -> Result { + + let stream = if let (Some(user), Some(pass)) = (&obj.proxy_login, &obj.proxy_password) { + Socks5Stream::connect_with_password(proxy_addr, target_addr, user, pass) + } else { + Socks5Stream::connect(proxy_addr, target_addr) + }; + + stream.map(|s| s.into_inner()) + .map_err(|e| process_error(&format!("SOCKS5 error: {}", e))) +} + +fn connect_via_socks4(obj: &AddIn, proxy_addr: &str, target_addr: (&str, u16)) -> Result { + + let stream = if let Some(user) = &obj.proxy_login { + Socks4Stream::connect(proxy_addr, target_addr, user) + } else { + Socks4Stream::connect(proxy_addr, target_addr, "") + }; + + stream.map(|s| s.into_inner()) + .map_err(|e| process_error(&format!("SOCKS4 error: {}", e))) +} + +fn connect_via_http_proxy( + obj: &AddIn, + proxy_addr: &str, + target_addr: (&str, u16), +) -> Result { + + let mut stream = TcpStream::connect(proxy_addr) + .map_err(|e| process_error(&format!("Failed to connect to HTTP proxy: {}", e)))?; + + // CONNECT + let host_port = format!("{}:{}", target_addr.0, target_addr.1); + let request = format!( + "CONNECT {} HTTP/1.1\r\nHost: {}\r\n", + host_port, host_port + ); + + // Auth + if let (Some(user), Some(pass)) = (&obj.proxy_login, &obj.proxy_password) { + + let auth = general_purpose::STANDARD.encode(&format!("{}:{}", user, pass)); + let auth_line = format!("Proxy-Authorization: Basic {}\r\n", auth); + let request = request + &auth_line + "\r\n"; + + stream.write_all(request.as_bytes()) + .map_err(|e| process_error(&format!("Failed to send CONNECT request: {}", e)))?; + } else { + + stream.write_all(request.as_bytes()) + .map_err(|e| process_error(&format!("Failed to send CONNECT request: {}", e)))?; + stream.write_all(b"\r\n") + .map_err(|e| process_error(&format!("Failed to send CONNECT end: {}", e)))?; + } + + // Response + let reader = BufReader::new(&stream); + let mut lines = reader.lines(); + + // Первая строка: статус + let status_line = match lines.next() { + Some(Ok(line)) => line, + _ => return Err(process_error("Empty or invalid response from proxy")), + }; + + if !status_line.starts_with("HTTP/") { + return Err(process_error(&format!("Invalid HTTP response: {}", status_line))); + } + + let parts: Vec<&str> = status_line.split_whitespace().collect(); + if parts.len() < 2 { + return Err(process_error("Malformed HTTP status line")); + } + + match parts[1] { + "200" => {} + "407" => return Err(process_error("Proxy authentication required")), + code => return Err(process_error(&format!("Unexpected HTTP proxy response code: {}", code))), + } + + for line in lines { + let line = line.map_err(|e| process_error(&format!("Error reading header: {}", e)))?; + if line.is_empty() { + break; + } + } + + Ok(stream) +} + +fn connect_direct(obj: &AddIn) -> Result { + let addr = format!("{}:{}", &obj.domain, &obj.port); + TcpStream::connect(&addr).map_err(|e| process_error(&format!("Direct connection error: {}", e))) +} \ No newline at end of file diff --git a/src/addins/mysql/dependencies.log b/src/addins/mysql/dependencies.log index 211e097424..a5fba6b2e1 100644 --- a/src/addins/mysql/dependencies.log +++ b/src/addins/mysql/dependencies.log @@ -1,13 +1,13 @@ "MAIN ---" - linux-vdso.so.1 (0x00007ffec07be000) - libssl.so.3 => /lib64/libssl.so.3 (0x000075673a000000) - libcrypto.so.3 => /lib64/libcrypto.so.3 (0x0000756739800000) - libm.so.6 => /lib64/libm.so.6 (0x0000756739400000) - libpthread.so.0 => /lib64/libpthread.so.0 (0x0000756739000000) - libc.so.6 => /lib64/libc.so.6 (0x0000756738c00000) - libdl.so.2 => /lib64/libdl.so.2 (0x0000756738800000) - /lib64/ld-linux-x86-64.so.2 (0x000075673a600000) - libz.so.1 => /lib64/libz.so.1 (0x0000756738400000) + linux-vdso.so.1 (0x00007fffd6965000) + libssl.so.3 => /lib64/libssl.so.3 (0x0000781f44600000) + libcrypto.so.3 => /lib64/libcrypto.so.3 (0x0000781f43e00000) + libm.so.6 => /lib64/libm.so.6 (0x0000781f43a00000) + libpthread.so.0 => /lib64/libpthread.so.0 (0x0000781f43600000) + libc.so.6 => /lib64/libc.so.6 (0x0000781f43200000) + libdl.so.2 => /lib64/libdl.so.2 (0x0000781f42e00000) + /lib64/ld-linux-x86-64.so.2 (0x0000781f44c00000) + libz.so.1 => /lib64/libz.so.1 (0x0000781f42a00000) GLIBC_2.2.5 GLIBC_2.3 GLIBC_2.3.4 diff --git a/src/en/OInt/addins/OPI_MySQL.zip b/src/en/OInt/addins/OPI_MySQL.zip index a0b45a239e..ff7b07fdc4 100644 Binary files a/src/en/OInt/addins/OPI_MySQL.zip and b/src/en/OInt/addins/OPI_MySQL.zip differ diff --git a/src/en/OPI/src/CommonTemplates/OPI_FTP/Template.addin b/src/en/OPI/src/CommonTemplates/OPI_FTP/Template.addin index 81619ee51b..2956c1a2c8 100644 Binary files a/src/en/OPI/src/CommonTemplates/OPI_FTP/Template.addin and b/src/en/OPI/src/CommonTemplates/OPI_FTP/Template.addin differ diff --git a/src/en/OPI/src/CommonTemplates/OPI_MySQL/Template.addin b/src/en/OPI/src/CommonTemplates/OPI_MySQL/Template.addin index a0b45a239e..ff7b07fdc4 100644 Binary files a/src/en/OPI/src/CommonTemplates/OPI_MySQL/Template.addin and b/src/en/OPI/src/CommonTemplates/OPI_MySQL/Template.addin differ diff --git a/src/ru/OInt/addins/OPI_MySQL.zip b/src/ru/OInt/addins/OPI_MySQL.zip index a0b45a239e..ff7b07fdc4 100644 Binary files a/src/ru/OInt/addins/OPI_MySQL.zip and b/src/ru/OInt/addins/OPI_MySQL.zip differ diff --git a/src/ru/OPI/src/CommonModules/OPI_FTP/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_FTP/Module.bsl index 29d5a13f4d..c2fc053f78 100644 --- a/src/ru/OPI/src/CommonModules/OPI_FTP/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_FTP/Module.bsl @@ -1,4 +1,4 @@ -// OneScript: ./OInt/core/Modules/OPI_FTP.os +// OneScript: ./OInt/core/Modules/OPI_FTP.os // Lib: FTP // CLI: ftp // Keywords: ftp, ftps @@ -49,7 +49,7 @@ // Открывает FTP соединение с указанными настройками // // Параметры: -// НастройкиFTP - Структура Из КлючИЗначение - Настройки FTP. См. ПолучитьНастройкиFTP - set +// НастройкиFTP - Структура Из КлючИЗначение - Настройки FTP. См. ПолучитьНастройкиСоединения - set // Прокси - Структура Из КлючИЗначение - Настройки прокси, если необходимо. См ПолучитьНастройкиПрокси - proxy // Tls - Структура Из КлючИЗначение - Настройки TLS, если необходимо. См. ПолучитьНастройкиTls - tls // @@ -84,10 +84,74 @@ Результат = Коннектор.Connect(); Результат = OPI_Инструменты.JSONВСтруктуру(Результат); - Возврат Результат; + Возврат ?(Результат["result"], Коннектор, Результат); КонецФункции +// Получить конфигурацию соединения +// Формирует полную структуру настроек соединения, которая может быть использована вместо самого соединения при вызове других функций +// +// Примечание: +// Может быть передана в качестве параметра `Соединение` в других функциях вместо настоящего соединения из функции `ОткрытьСоединение`.^^ +// При этом новое соединение будет открыто и закрыто в рамках вызываемой функции +// Не рекомендуется использовать конфигурацию соединения при множественных обращениях к серверу FTP.^^ +// Данный фунционал предназначен, в первую очередь для CLI версии ОПИ, где хранение соединения между вызовами невозможно +// +// Параметры: +// НастройкиFTP - Структура Из КлючИЗначение - Настройки FTP. См. ПолучитьНастройкиСоединения - set +// Прокси - Структура Из КлючИЗначение - Настройки прокси, если необходимо. См ПолучитьНастройкиПрокси - proxy +// Tls - Структура Из КлючИЗначение - Настройки TLS, если необходимо. См. ПолучитьНастройкиTls - tls +// +// Возвращаемое значение: +// Структура Из КлючИЗначение - Структура настроек соединения +Функция ПолучитьКонфигурациюСоединиения(Знач НастройкиFTP, Знач Прокси = Неопределено, Знач Tls = Неопределено) Экспорт + + СтруктураКонфигурации = Новый Структура; + + OPI_Инструменты.ДобавитьПоле("set" , НастройкиFTP, "Коллекция", СтруктураКонфигурации); + OPI_Инструменты.ДобавитьПоле("proxy", Прокси , "Коллекция", СтруктураКонфигурации); + OPI_Инструменты.ДобавитьПоле("tls" , Tls , "Коллекция", СтруктураКонфигурации); + + Возврат СтруктураКонфигурации; + +КонецФункции + +// Закрыть соединение !NOCLI +// Явно закрывает переданное соединение +// +// Параметры: +// Соединение - Произвольный - Объект компоненты с открытым соединением - conn +// +// Возвращаемое значение: +// Структура Из КлючИЗначение - Результат закрытия соединения +Функция ЗакрытьСоединение(Знач Соединение) Экспорт + + ПроверитьСоздатьСоединение(Соединение); + Результат = Соединение.Close(); + + Возврат Результат; + +КонецФункции + +Функция ПолучитьПриветственноеСообщение(Знач Соединение) Экспорт + + ЗакрыватьСоединение = ПроверитьСоздатьСоединение(Соединение); + + Если Не ЭтоКоннектор(Соединение) Тогда + Результат = Соединение; + Иначе + Результат = Соединение.GetWelcomeMsg(); + Результат = OPI_Инструменты.JsonВСтруктуру(Результат); + КонецЕсли; + + Если ЗакрыватьСоединение Тогда + Результат.Вставить("close_connection", ЗакрытьСоединение(Соединение)); + КонецЕсли; + + Возврат Результат; + +КонецФункции + // Это коннектор !NOCLI // Проверяет, что значение является объектом внешней компоненты для работы с FTP // @@ -102,6 +166,107 @@ КонецФункции +// Получить настройки соединения +// Формирует структуру настроек подключения FTP +// +// Параметры: +// Домен - Строка - Домен сервера - host +// Порт - Число - Порт сервера - port +// Логин - Строка, Неопределено - Имя пользователя авторизации, если необходимо - login +// Пароль - Строка, Неопределено - Пароль пользователя для авторизации, если необходимо - pass +// Пассивный - Булево - Пассивный режим соединения - passive +// ТаймаутЧтения - Число - Таймаут чтения - rtout +// ТаймаутЗаписи - Число - Таймаут записи - wtout +// +// Возвращаемое значение: +// Структура Из КлючИЗначение - Структура настроек соединения +Функция ПолучитьНастройкиСоединения(Знач Домен + , Знач Порт = 21 + , Знач Логин = Неопределено + , Знач Пароль = Неопределено + , Знач Пассивный = Истина + , Знач ТаймаутЧтения = 120 + , Знач ТаймаутЗаписи = 120) Экспорт + + СтруктураНастроек = Новый Структура; + OPI_Инструменты.ДобавитьПоле("domain" , Домен , "Строка", СтруктураНастроек); + OPI_Инструменты.ДобавитьПоле("port" , Порт , "Число" , СтруктураНастроек); + OPI_Инструменты.ДобавитьПоле("passive" , Пассивный , "Булево", СтруктураНастроек); + OPI_Инструменты.ДобавитьПоле("read_timeout" , ТаймаутЧтения , "Число" , СтруктураНастроек); + OPI_Инструменты.ДобавитьПоле("write_timeout", ТаймаутЗаписи , "Число" , СтруктураНастроек); + + Если Не Логин = Неопределено Тогда + OPI_ПреобразованиеТипов.ПолучитьСтроку(Логин); + СтруктураНастроек.Вставить("login", Логин); + КонецЕсли; + + Если Не Пароль = Неопределено Тогда + OPI_ПреобразованиеТипов.ПолучитьСтроку(Пароль); + СтруктураНастроек.Вставить("password", Пароль); + КонецЕсли; + + //@skip-check constructor-function-return-section + Возврат СтруктураНастроек; + +КонецФункции + +// Получить настройки прокси +// Формирует структуру настроек прокси-сервера для соединения +// +// Параметры: +// Адрес - Строка - Адрес прокси - addr +// Порт - Число - Порт прокси - port +// Вид - Строка - Вид прокси: socks5, socks4, http - type +// Логин - Строка, Неопределено - Логин авторизации, если необходимо - login +// Пароль - Строка, Неопределено - Пароль для авторизации, если необходимо - pass +// +// Возвращаемое значение: +// Структура Из КлючИЗначение - Структура настроек прокси +Функция ПолучитьНастройкиПрокси(Знач Адрес + , Знач Порт + , Знач Вид = "socks5" + , Знач Логин = Неопределено + , Знач Пароль = Неопределено) Экспорт + + СтруктураНастроек = Новый Структура; + OPI_Инструменты.ДобавитьПоле("server" , Адрес, "Строка", СтруктураНастроек); + OPI_Инструменты.ДобавитьПоле("port" , Порт , "Число" , СтруктураНастроек); + OPI_Инструменты.ДобавитьПоле("proxy_type", Вид , "Строка", СтруктураНастроек); + + Если Не Логин = Неопределено Тогда + OPI_ПреобразованиеТипов.ПолучитьСтроку(Логин); + СтруктураНастроек.Вставить("login", Логин); + КонецЕсли; + + Если Не Пароль = Неопределено Тогда + OPI_ПреобразованиеТипов.ПолучитьСтроку(Пароль); + СтруктураНастроек.Вставить("password", Пароль); + КонецЕсли; + + //@skip-check constructor-function-return-section + Возврат СтруктураНастроек; + +КонецФункции + +// Получить настройки TLS +// Формирует настройки для использования TLS при выполнении запросов +// +// Примечание: +// Настройки Tls могут быть установлены только в момент создания соединения: явного, при использовании функции `ОткрытьСоединение`^^ +// или неявного, при передаче настроек +// +// Параметры: +// ОтключитьПроверкуСертификатов - Булево - Позволяет работать с некорретными сертификатами, в т.ч. самоподписанными - trust +// ПутьКСертификату - Строка - Путь к корневому PEM файлу сертификата, если его нет в системном хранилище - cert +// +// Возвращаемое значение: +// Структура Из КлючИЗначение - Структура настроек TLS соединения +Функция ПолучитьНастройкиTls(Знач ОтключитьПроверкуСертификатов, Знач ПутьКСертификату = "") Экспорт + + Возврат OPI_Компоненты.ПолучитьНастройкиTls(ОтключитьПроверкуСертификатов, ПутьКСертификату); + +КонецФункции + #КонецОбласти #КонецОбласти @@ -164,4 +329,53 @@ КонецФункции +Функция ОткрытьСоединениеПоКонфигурации(Знач СтруктураКонфигурации) + + Если ЭтоКоннектор(СтруктураКонфигурации) Тогда + Возврат СтруктураКонфигурации; + КонецЕсли; + + ТекстОшибки = "Передана некорректная конфигурация соединения"; + + Попытка + OPI_ПреобразованиеТипов.ПолучитьКоллекциюКлючИЗначение(СтруктураКонфигурации); + Исключение + + Результат = Новый Соответствие; + Результат.Вставить("result", Ложь); + Результат.Вставить("error" , ТекстОшибки); + Возврат Результат; + + КонецПопытки; + + Если Не OPI_Инструменты.ПолеКоллекцииСуществует(СтруктураКонфигурации, "set") Тогда + + Результат = Новый Соответствие; + Результат.Вставить("result", Ложь); + Результат.Вставить("error" , ТекстОшибки); + Возврат Результат; + + КонецЕсли; + + НастройкиFTP = СтруктураКонфигурации["set"]; + Прокси = OPI_Инструменты.ПолучитьИли(СтруктураКонфигурации, "proxy", Неопределено); + Tls = OPI_Инструменты.ПолучитьИли(СтруктураКонфигурации, "tls", Неопределено); + + Возврат ОткрытьСоединение(НастройкиFTP, Прокси, Tls); + +КонецФункции + +Функция ПроверитьСоздатьСоединение(Соединение) + + Если ЭтоКоннектор(Соединение) Тогда + ЗакрыватьСоединение = Ложь; + Иначе + ЗакрыватьСоединение = Истина; + Соединение = ОткрытьСоединениеПоКонфигурации(Соединение); + КонецЕсли; + + Возврат ЗакрыватьСоединение; + +КонецФункции + #КонецОбласти diff --git a/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl index 5d109ede8f..8e7a00ea75 100644 --- a/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl @@ -1,4 +1,4 @@ -// OneScript: ./OInt/tools/Modules/OPI_ПолучениеДанныхТестов.os +// OneScript: ./OInt/tools/Modules/OPI_ПолучениеДанныхТестов.os // MIT License @@ -55,6 +55,7 @@ Разделы.Вставить("VK" , 5); Разделы.Вставить("Viber" , 5); Разделы.Вставить("Twitter" , 4); + Разделы.Вставить("FTP" , 5); Разделы.Вставить("PostgreSQL" , 5); Разделы.Вставить("MySQL" , 5); Разделы.Вставить("MSSQL" , 5); @@ -96,6 +97,7 @@ Разделы.Вставить("VK" , СтандартныеЗависимости); Разделы.Вставить("Viber" , СтандартныеЗависимости); Разделы.Вставить("Twitter" , СтандартныеЗависимости); + Разделы.Вставить("FTP" , СтандартныеЗависимости); Разделы.Вставить("PostgreSQL" , СтандартныеЗависимости); Разделы.Вставить("MySQL" , СтандартныеЗависимости); Разделы.Вставить("MSSQL" , СтандартныеЗависимости); @@ -159,6 +161,7 @@ Http = "HTTPКлиент"; OpenAI = "OpenAI"; MSSQL = "MSSQL"; + FTP = "FTP"; ТаблицаТестов = Новый ТаблицаЗначений; ТаблицаТестов.Колонки.Добавить("Метод"); @@ -324,6 +327,7 @@ НовыйТест(ТаблицаТестов, "OAI_РаботаСФайлами" , "Работа с файлами" , OpenAI); НовыйТест(ТаблицаТестов, "OAI_РаботаСАудио" , "Работа с аудио" , OpenAI); НовыйТест(ТаблицаТестов, "OAI_РаботаСМоделями" , "Работа с моделями" , OpenAI); + НовыйТест(ТаблицаТестов, "FT_ОсновныеМетоды" , "Основные методы" , FTP); Возврат ТаблицаТестов; diff --git a/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl index f445c5afb2..2e8087c180 100644 --- a/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_Тесты/Module.bsl @@ -1,4 +1,4 @@ -// OneScript: ./OInt/tests/Modules/internal/OPI_Тесты.os +// OneScript: ./OInt/tests/Modules/internal/OPI_Тесты.os // MIT License @@ -2864,6 +2864,21 @@ #КонецОбласти +#Область FTP + +Процедура FT_ОсновныеМетоды() Экспорт + + ПараметрыТеста = Новый Структура; + OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("PG_IP" , ПараметрыТеста); + OPI_ПолучениеДанныхТестов.ПараметрВКоллекцию("PG_Password", ПараметрыТеста); + + FTP_ОткрытьСоединение(ПараметрыТеста); + FTP_ПолучитьПриветственноеСообщение(ПараметрыТеста); + +КонецПроцедуры + +#КонецОбласти + #КонецОбласти #КонецОбласти @@ -24739,6 +24754,60 @@ #КонецОбласти +#Область FTP + +Процедура FTP_ОткрытьСоединение(ПараметрыФункции) + + Домен = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + + // Простое подключение + + НастройкиFTP = OPI_FTP.ПолучитьНастройкиСоединения(Домен, 21); + Результат = OPI_FTP.ОткрытьСоединение(НастройкиFTP); + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ОткрытьСоединение", "FTP"); // SKIP + OPI_ПолучениеДанныхТестов.Проверка_Компонента(Результат, "AddIn.OPI_FTP.Main"); // SKIP + + // Подключение по TLS через прокси + + ДоменFTP = "172.33.0.11"; + АдресПрокси = ПараметрыФункции["PG_IP"]; + + НастройкиFTP = OPI_FTP.ПолучитьНастройкиСоединения(ДоменFTP, 21, Логин, "12we3456!2154"); + НастройкиПрокси = OPI_FTP.ПолучитьНастройкиПрокси(АдресПрокси, 1080, "socks5", "proxyuser", Пароль); + НастройкиTLS = OPI_FTP.ПолучитьНастройкиTls(Истина); + + Результат = OPI_FTP.ОткрытьСоединение(НастройкиFTP, НастройкиПрокси, НастройкиTLS); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ОткрытьСоединение (прокси + tls)", "FTP"); + OPI_ПолучениеДанныхТестов.Проверка_Компонента(Результат, "AddIn.OPI_FTP.Main"); + +КонецПроцедуры + +Процедура FTP_ПолучитьПриветственноеСообщение(ПараметрыФункции) + + Домен = ПараметрыФункции["PG_IP"]; + Логин = "bayselonarrend"; + Пароль = ПараметрыФункции["PG_Password"]; + + НастройкиFTP = OPI_FTP.ПолучитьНастройкиСоединения(Домен, 21, Логин, Пароль); + Соединение = OPI_FTP.ОткрытьСоединение(НастройкиFTP); + + Результат = OPI_FTP.ПолучитьПриветственноеСообщение(Соединение); + + // END + + OPI_ПолучениеДанныхТестов.ЗаписатьЛог(Результат, "ПолучитьПриветственноеСообщение", "FTP"); + OPI_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат); + +КонецПроцедуры + +#КонецОбласти + #КонецОбласти #КонецОбласти diff --git a/src/ru/OPI/src/CommonTemplates/OPI_FTP/Template.addin b/src/ru/OPI/src/CommonTemplates/OPI_FTP/Template.addin index 81619ee51b..2956c1a2c8 100644 Binary files a/src/ru/OPI/src/CommonTemplates/OPI_FTP/Template.addin and b/src/ru/OPI/src/CommonTemplates/OPI_FTP/Template.addin differ diff --git a/src/ru/OPI/src/CommonTemplates/OPI_MySQL/Template.addin b/src/ru/OPI/src/CommonTemplates/OPI_MySQL/Template.addin index a0b45a239e..ff7b07fdc4 100644 Binary files a/src/ru/OPI/src/CommonTemplates/OPI_MySQL/Template.addin and b/src/ru/OPI/src/CommonTemplates/OPI_MySQL/Template.addin differ