1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2025-08-10 22:41:43 +02:00

FTP: Доработка компоненты

This commit is contained in:
Anton Titovets
2025-07-17 19:50:40 +03:00
parent fb484d478e
commit 5ac0ceb2c9
16 changed files with 460 additions and 85 deletions

View File

@@ -42,6 +42,12 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "2.9.0" version = "2.9.0"
@@ -334,10 +340,11 @@ dependencies = [
] ]
[[package]] [[package]]
name = "opi_mysql" name = "opi_ftp"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"addin1c", "addin1c",
"base64",
"native-tls", "native-tls",
"serde", "serde",
"serde_json", "serde_json",

View File

@@ -1,5 +1,5 @@
[package] [package]
name = "opi_mysql" name = "opi_ftp"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
@@ -20,3 +20,4 @@ serde_json = "1.0"
serde = { version = "1.0.217", features = ["derive"] } serde = { version = "1.0.217", features = ["derive"] }
native-tls = "0.2.14" native-tls = "0.2.14"
socks = "0.3.4" socks = "0.3.4"
base64 = "0.22.1"

View File

@@ -1,15 +1,13 @@
"MAIN ---" "MAIN ---"
linux-vdso.so.1 (0x00007ffec07be000) linux-vdso.so.1 (0x00007ffe6f8db000)
libssl.so.3 => /lib64/libssl.so.3 (0x000075673a000000) libssl.so.3 => /lib64/libssl.so.3 (0x00007032ad000000)
libcrypto.so.3 => /lib64/libcrypto.so.3 (0x0000756739800000) libcrypto.so.3 => /lib64/libcrypto.so.3 (0x00007032ac800000)
libm.so.6 => /lib64/libm.so.6 (0x0000756739400000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007032ac400000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000756739000000) libc.so.6 => /lib64/libc.so.6 (0x00007032ac000000)
libc.so.6 => /lib64/libc.so.6 (0x0000756738c00000) libdl.so.2 => /lib64/libdl.so.2 (0x00007032abc00000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000756738800000) /lib64/ld-linux-x86-64.so.2 (0x00007032ad400000)
/lib64/ld-linux-x86-64.so.2 (0x000075673a600000) libz.so.1 => /lib64/libz.so.1 (0x00007032ab800000)
libz.so.1 => /lib64/libz.so.1 (0x0000756738400000)
GLIBC_2.2.5 GLIBC_2.2.5
GLIBC_2.3 GLIBC_2.3
GLIBC_2.3.4 GLIBC_2.3.4
GLIBC_2.14 GLIBC_2.14
GLIBC_2.17

View File

@@ -1,8 +1,8 @@
@echo off @echo off
:: Установить переменную :: Установить переменную
set CARGO_NAME=opi_mysql set CARGO_NAME=opi_ftp
set LIB_NAME=OPI_MySQL set LIB_NAME=OPI_FTP
set ADDIN_DIR=%~dp0 set ADDIN_DIR=%~dp0
set FOLV=true set FOLV=true

View File

@@ -1,4 +1,5 @@
mod ftp_client; mod ftp_client;
mod tcp_establish;
use addin1c::{name, Variant}; use addin1c::{name, Variant};
use crate::core::getset; use crate::core::getset;
@@ -11,13 +12,13 @@ use crate::component::ftp_client::FtpClient;
use std::net::TcpStream; use std::net::TcpStream;
use std::sync::{Arc, Mutex, MutexGuard}; use std::sync::{Arc, Mutex, MutexGuard};
use std::time::Duration; use std::time::Duration;
use socks::{Socks4Stream, Socks5Stream};
// МЕТОДЫ КОМПОНЕНТЫ ------------------------------------------------------------------------------- // МЕТОДЫ КОМПОНЕНТЫ -------------------------------------------------------------------------------
// Синонимы // Синонимы
pub const METHODS: &[&[u16]] = &[ pub const METHODS: &[&[u16]] = &[
name!("Connect"), name!("Connect"),
name!("Close"),
name!("UpdateSettings"), name!("UpdateSettings"),
name!("UpdateProxy"), name!("UpdateProxy"),
name!("SetTLS"), name!("SetTLS"),
@@ -28,9 +29,11 @@ pub const METHODS: &[&[u16]] = &[
pub fn get_params_amount(num: usize) -> usize { pub fn get_params_amount(num: usize) -> usize {
match num { match num {
0 => 0, 0 => 0,
1 => 1, 1 => 0,
2 => 1, 2 => 1,
3 => 3, 3 => 1,
4 => 3,
5 => 0,
_ => 0, _ => 0,
} }
} }
@@ -42,15 +45,16 @@ pub fn cal_func(obj: &mut AddIn, num: usize, params: &mut [Variant]) -> Box<dyn
match num { match num {
0 => Box::new(obj.initialize()), 0 => Box::new(obj.initialize()),
1 => { 1 => Box::new(obj.close_connection()),
2 => {
let json_string = params[0].get_string().unwrap_or("".to_string()); let json_string = params[0].get_string().unwrap_or("".to_string());
Box::new(obj.update_settings(&json_string)) Box::new(obj.update_settings(&json_string))
}, },
2 => { 3 => {
let json_string = params[0].get_string().unwrap_or("".to_string()); let json_string = params[0].get_string().unwrap_or("".to_string());
Box::new(obj.update_proxy(&json_string)) Box::new(obj.update_proxy(&json_string))
}, },
3 => { 4 => {
let use_tls = params[0].get_bool().unwrap_or(false); let use_tls = params[0].get_bool().unwrap_or(false);
let accept_invalid_certs = params[1].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<dyn
Box::new(obj.set_tls(use_tls, accept_invalid_certs, &ca_cert_path)) Box::new(obj.set_tls(use_tls, accept_invalid_certs, &ca_cert_path))
}, },
4 => { 5 => {
Box::new(match obj.get_client(){ Box::new(match obj.get_client(){
Ok(c) => c.get_welcome_msg(), Ok(c) => c.get_welcome_msg(),
Err(e) => process_error(e.as_str()) Err(e) => process_error(e.as_str())
@@ -182,7 +186,6 @@ impl AddIn {
Err(e) => return process_error(&e.to_string()), Err(e) => return process_error(&e.to_string()),
}; };
self.proxy_server = json_struct.server; self.proxy_server = json_struct.server;
self.proxy_port = json_struct.port; self.proxy_port = json_struct.port;
self.proxy_login = json_struct.login; self.proxy_login = json_struct.login;
@@ -199,7 +202,7 @@ impl AddIn {
return process_error("Address must be initialized"); 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, Ok(stream) => stream,
Err(e) => return e, Err(e) => return e,
}; };
@@ -266,53 +269,7 @@ impl AddIn {
} }
} }
fn create_tcp_connection(&self) -> Result<TcpStream, String> {
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<TcpStream, String> {
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<TcpStream, String> {
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<TcpStream, String> {
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 { pub fn close_connection(&mut self) -> String {
if let Some(client) = self.client.take() { if let Some(client) = self.client.take() {
@@ -394,6 +351,8 @@ pub fn process_error(e: &str) -> String{
// Обработка удаления объекта // Обработка удаления объекта
impl Drop for AddIn { impl Drop for AddIn {
fn drop(&mut self) {} fn drop(&mut self) {
self.close_connection();
}
} }

View File

@@ -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<TcpStream, String> {
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<TcpStream, String> {
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<TcpStream, String> {
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<TcpStream, String> {
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<TcpStream, String> {
let addr = format!("{}:{}", &obj.domain, &obj.port);
TcpStream::connect(&addr).map_err(|e| process_error(&format!("Direct connection error: {}", e)))
}

View File

@@ -1,13 +1,13 @@
"MAIN ---" "MAIN ---"
linux-vdso.so.1 (0x00007ffec07be000) linux-vdso.so.1 (0x00007fffd6965000)
libssl.so.3 => /lib64/libssl.so.3 (0x000075673a000000) libssl.so.3 => /lib64/libssl.so.3 (0x0000781f44600000)
libcrypto.so.3 => /lib64/libcrypto.so.3 (0x0000756739800000) libcrypto.so.3 => /lib64/libcrypto.so.3 (0x0000781f43e00000)
libm.so.6 => /lib64/libm.so.6 (0x0000756739400000) libm.so.6 => /lib64/libm.so.6 (0x0000781f43a00000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x0000756739000000) libpthread.so.0 => /lib64/libpthread.so.0 (0x0000781f43600000)
libc.so.6 => /lib64/libc.so.6 (0x0000756738c00000) libc.so.6 => /lib64/libc.so.6 (0x0000781f43200000)
libdl.so.2 => /lib64/libdl.so.2 (0x0000756738800000) libdl.so.2 => /lib64/libdl.so.2 (0x0000781f42e00000)
/lib64/ld-linux-x86-64.so.2 (0x000075673a600000) /lib64/ld-linux-x86-64.so.2 (0x0000781f44c00000)
libz.so.1 => /lib64/libz.so.1 (0x0000756738400000) libz.so.1 => /lib64/libz.so.1 (0x0000781f42a00000)
GLIBC_2.2.5 GLIBC_2.2.5
GLIBC_2.3 GLIBC_2.3
GLIBC_2.3.4 GLIBC_2.3.4

Binary file not shown.

Binary file not shown.

View File

@@ -1,4 +1,4 @@
// OneScript: ./OInt/core/Modules/OPI_FTP.os // OneScript: ./OInt/core/Modules/OPI_FTP.os
// Lib: FTP // Lib: FTP
// CLI: ftp // CLI: ftp
// Keywords: ftp, ftps // Keywords: ftp, ftps
@@ -49,7 +49,7 @@
// Открывает FTP соединение с указанными настройками // Открывает FTP соединение с указанными настройками
// //
// Параметры: // Параметры:
// НастройкиFTP - Структура Из КлючИЗначение - Настройки FTP. См. ПолучитьНастройкиFTP - set // НастройкиFTP - Структура Из КлючИЗначение - Настройки FTP. См. ПолучитьНастройкиСоединения - set
// Прокси - Структура Из КлючИЗначение - Настройки прокси, если необходимо. См ПолучитьНастройкиПрокси - proxy // Прокси - Структура Из КлючИЗначение - Настройки прокси, если необходимо. См ПолучитьНастройкиПрокси - proxy
// Tls - Структура Из КлючИЗначение - Настройки TLS, если необходимо. См. ПолучитьНастройкиTls - tls // Tls - Структура Из КлючИЗначение - Настройки TLS, если необходимо. См. ПолучитьНастройкиTls - tls
// //
@@ -84,6 +84,70 @@
Результат = Коннектор.Connect(); Результат = Коннектор.Connect();
Результат = OPI_Инструменты.JSONВСтруктуру(Результат); Результат = 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", ЗакрытьСоединение(Соединение));
КонецЕсли;
Возврат Результат; Возврат Результат;
КонецФункции КонецФункции
@@ -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);
КонецФункции
Функция ПроверитьСоздатьСоединение(Соединение)
Если ЭтоКоннектор(Соединение) Тогда
ЗакрыватьСоединение = Ложь;
Иначе
ЗакрыватьСоединение = Истина;
Соединение = ОткрытьСоединениеПоКонфигурации(Соединение);
КонецЕсли;
Возврат ЗакрыватьСоединение;
КонецФункции
#КонецОбласти #КонецОбласти

View File

@@ -1,4 +1,4 @@
// OneScript: ./OInt/tools/Modules/OPI_ПолучениеДанныхТестов.os // OneScript: ./OInt/tools/Modules/OPI_ПолучениеДанныхТестов.os
// MIT License // MIT License
@@ -55,6 +55,7 @@
Разделы.Вставить("VK" , 5); Разделы.Вставить("VK" , 5);
Разделы.Вставить("Viber" , 5); Разделы.Вставить("Viber" , 5);
Разделы.Вставить("Twitter" , 4); Разделы.Вставить("Twitter" , 4);
Разделы.Вставить("FTP" , 5);
Разделы.Вставить("PostgreSQL" , 5); Разделы.Вставить("PostgreSQL" , 5);
Разделы.Вставить("MySQL" , 5); Разделы.Вставить("MySQL" , 5);
Разделы.Вставить("MSSQL" , 5); Разделы.Вставить("MSSQL" , 5);
@@ -96,6 +97,7 @@
Разделы.Вставить("VK" , СтандартныеЗависимости); Разделы.Вставить("VK" , СтандартныеЗависимости);
Разделы.Вставить("Viber" , СтандартныеЗависимости); Разделы.Вставить("Viber" , СтандартныеЗависимости);
Разделы.Вставить("Twitter" , СтандартныеЗависимости); Разделы.Вставить("Twitter" , СтандартныеЗависимости);
Разделы.Вставить("FTP" , СтандартныеЗависимости);
Разделы.Вставить("PostgreSQL" , СтандартныеЗависимости); Разделы.Вставить("PostgreSQL" , СтандартныеЗависимости);
Разделы.Вставить("MySQL" , СтандартныеЗависимости); Разделы.Вставить("MySQL" , СтандартныеЗависимости);
Разделы.Вставить("MSSQL" , СтандартныеЗависимости); Разделы.Вставить("MSSQL" , СтандартныеЗависимости);
@@ -159,6 +161,7 @@
Http = "HTTPКлиент"; Http = "HTTPКлиент";
OpenAI = "OpenAI"; OpenAI = "OpenAI";
MSSQL = "MSSQL"; MSSQL = "MSSQL";
FTP = "FTP";
ТаблицаТестов = Новый ТаблицаЗначений; ТаблицаТестов = Новый ТаблицаЗначений;
ТаблицаТестов.Колонки.Добавить("Метод"); ТаблицаТестов.Колонки.Добавить("Метод");
@@ -324,6 +327,7 @@
НовыйТест(ТаблицаТестов, "OAI_РаботаСФайлами" , "Работа с файлами" , OpenAI); НовыйТест(ТаблицаТестов, "OAI_РаботаСФайлами" , "Работа с файлами" , OpenAI);
НовыйТест(ТаблицаТестов, "OAI_РаботаСАудио" , "Работа с аудио" , OpenAI); НовыйТест(ТаблицаТестов, "OAI_РаботаСАудио" , "Работа с аудио" , OpenAI);
НовыйТест(ТаблицаТестов, "OAI_РаботаСМоделями" , "Работа с моделями" , OpenAI); НовыйТест(ТаблицаТестов, "OAI_РаботаСМоделями" , "Работа с моделями" , OpenAI);
НовыйТест(ТаблицаТестов, "FT_ОсновныеМетоды" , "Основные методы" , FTP);
Возврат ТаблицаТестов; Возврат ТаблицаТестов;

View File

@@ -1,4 +1,4 @@
// OneScript: ./OInt/tests/Modules/internal/OPI_Тесты.os // OneScript: ./OInt/tests/Modules/internal/OPI_Тесты.os
// MIT License // 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_ПолучениеДанныхТестов.Проверка_РезультатИстина(Результат);
КонецПроцедуры
#КонецОбласти
#КонецОбласти #КонецОбласти
#КонецОбласти #КонецОбласти