1
0
mirror of https://github.com/alei1180/curlone.git synced 2025-10-10 00:01:52 +02:00

feat: Добавление конструктора программного кода 1С

This commit is contained in:
Dmitry Ivanov
2024-11-06 21:45:39 +03:00
parent 19b40b2675
commit 544dcd9cc7
6 changed files with 478 additions and 23 deletions

17
NOTICES Normal file
View File

@@ -0,0 +1,17 @@
License for src/Классы/internal/Классы/ПарсерURL.os (https://github.com/vbondarevsky/1connector)
--------------------------------------
Copyright 2019-2020 Vladimir Bondarevskiy
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,9 +1,10 @@
Описание.Имя("curlto1c")
.Версия("1.0.0")
.ВключитьФайл("src/os")
.ВключитьФайл("test")
.ВключитьФайл("tests")
.ВключитьФайл("packagedef")
.РазработкаЗависитОт("logos")
.РазработкаЗависитОт("asserts")
.ЗависитОт("tokenizer")
.ЗависитОт("cli")
.ЗависитОт("logos")
.РазработкаЗависитОт("1testrunner")
.РазработкаЗависитОт("tokenizer")
.РазработкаЗависитОт("asserts")

View File

@@ -0,0 +1,185 @@
// Copyright 2019-2020 Vladimir Bondarevskiy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Перем Схема Экспорт; // Схема
Перем Аутентификация Экспорт; // Параметры аутентификации
Перем Сервер Экспорт; // Сервер
Перем Порт Экспорт; // Порт
Перем Путь Экспорт; // Путь на сервере
Перем ПараметрыЗапроса Экспорт; // Часть адреса после ?
Перем Фрагмент Экспорт; // Часть адреса после #
Перем ПутьСПараметрами Экспорт;
Процедура ПриСозданииОбъекта(Знач URL)
Схема = "";
Аутентификация = Новый Структура("Пользователь, Пароль", "", "");
Сервер = "";
Порт = "";
Путь = "";
ПараметрыЗапроса = Новый Соответствие;
Фрагмент = "";
РазобратьURL(URL);
КонецПроцедуры
Процедура РазобратьURL(Знач URL)
ДопустимыеСхемы = СтрРазделить("http,https", ",");
URLБезСхемы = URL;
РазбитьСтрокуПоРазделителю(Схема, URLБезСхемы, "://");
Если ДопустимыеСхемы.Найти(НРег(Схема)) <> Неопределено Тогда
URL = URLБезСхемы;
Иначе
Схема = "";
КонецЕсли;
Результат = РазделитьПоПервомуНайденномуРазделителю(URL, СтрРазделить("/,?,#", ","));
URL = Результат[0];
Если ЗначениеЗаполнено(Результат[2]) Тогда
ПутьСПараметрами = Результат[2] + Результат[1];
Путь = ПутьСПараметрами;
КонецЕсли;
АутентификацияСтрока = "";
РазбитьСтрокуПоРазделителю(АутентификацияСтрока, URL, "@");
Если ЗначениеЗаполнено(АутентификацияСтрока) Тогда
АутентификацияЧасти = СтрРазделить(АутентификацияСтрока, ":");
Аутентификация.Пользователь = АутентификацияЧасти[0];
Если АутентификацияЧасти.Количество() > 1 Тогда
Аутентификация.Пароль = АутентификацияЧасти[1];
КонецЕсли;
КонецЕсли;
// IPv6
РазбитьСтрокуПоРазделителю(Сервер, URL, "]");
Если ЗначениеЗаполнено(Сервер) Тогда
Сервер = Сервер + "]";
КонецЕсли;
URL = СтрЗаменить(URL, "/", "");
РазбитьСтрокуПоРазделителю(Порт, URL, ":", Истина);
Если Не ЗначениеЗаполнено(Сервер) Тогда
Сервер = URL;
КонецЕсли;
Если ЗначениеЗаполнено(Порт) Тогда
Порт = Число(Порт);
Иначе
Порт = 0;
КонецЕсли;
РазбитьСтрокуПоРазделителю(Фрагмент, Путь, "#", Истина);
ЗаполнитьПараметрыЗапроса(Путь);
Если Не ЗначениеЗаполнено(Схема) Тогда
Схема = "http";
КонецЕсли;
Если Не ЗначениеЗаполнено(Путь) Тогда
Путь = "/";
КонецЕсли;
Если Не ЗначениеЗаполнено(ПутьСПараметрами) Тогда
ПутьСПараметрами = "/";
КонецЕсли;
КонецПроцедуры
Процедура ЗаполнитьПараметрыЗапроса(Путь)
Запрос = "";
РазбитьСтрокуПоРазделителю(Запрос, Путь, "?", Истина);
РазбитьСтрокуПоРазделителю(Запрос, Путь, "?", Истина);
Для Каждого СтрокаКлючРавноПараметр Из СтрРазделить(Запрос, "&", Ложь) Цикл
СтрокаКлючРавноПараметр = РаскодироватьСтроку(
СтрокаКлючРавноПараметр, СпособКодированияСтроки.URLВКодировкеURL);
ПозицияРавно = СтрНайти(СтрокаКлючРавноПараметр, "=");
Если ПозицияРавно = 0 Тогда
Ключ = СтрокаКлючРавноПараметр;
Значение = Неопределено;
Иначе
Ключ = Лев(СтрокаКлючРавноПараметр, ПозицияРавно - 1);
Значение = Сред(СтрокаКлючРавноПараметр, ПозицияРавно + 1);
КонецЕсли;
Если ПараметрыЗапроса.Получить(Ключ) <> Неопределено Тогда
Если ТипЗнч(ПараметрыЗапроса[Ключ]) = Тип("Массив") Тогда
ПараметрыЗапроса[Ключ].Добавить(Значение);
Иначе
Значения = Новый Массив;
Значения.Добавить(ПараметрыЗапроса[Ключ]);
Значения.Добавить(Значение);
ПараметрыЗапроса[Ключ] = Значения;
КонецЕсли;
Иначе
ПараметрыЗапроса.Вставить(Ключ, Значение);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура РазбитьСтрокуПоРазделителю(ИзвлекаемаяЧасть, ОстальнаяЧасть, Разделитель, Инверсия = Ложь)
Индекс = СтрНайти(ОстальнаяЧасть, Разделитель);
Если Индекс Тогда
ИзвлекаемаяЧасть = Лев(ОстальнаяЧасть, Индекс - 1);
ОстальнаяЧасть = Сред(ОстальнаяЧасть, Индекс + СтрДлина(Разделитель));
Если Инверсия Тогда
ДляОбмена = ИзвлекаемаяЧасть;
ИзвлекаемаяЧасть = ОстальнаяЧасть;
ОстальнаяЧасть = ДляОбмена;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Функция РазделитьПоПервомуНайденномуРазделителю(Строка, Разделители)
МинимальныйИндекс = СтрДлина(Строка);
ПервыйРазделитель = "";
Для Каждого Разделитель Из Разделители Цикл
Индекс = СтрНайти(Строка, Разделитель);
Если Индекс = 0 Тогда
Продолжить;
КонецЕсли;
Если Индекс < МинимальныйИндекс Тогда
МинимальныйИндекс = Индекс;
ПервыйРазделитель = Разделитель;
КонецЕсли;
КонецЦикла;
Результат = Новый Массив;
Если ЗначениеЗаполнено(ПервыйРазделитель) Тогда
Результат.Добавить(Лев(Строка, МинимальныйИндекс - 1));
Результат.Добавить(Сред(Строка, МинимальныйИндекс + СтрДлина(ПервыйРазделитель)));
Результат.Добавить(ПервыйРазделитель);
Иначе
Результат.Добавить(Строка);
Результат.Добавить("");
Результат.Добавить(Неопределено);
КонецЕсли;
Возврат Результат;
КонецФункции

View File

@@ -1,21 +1,80 @@
#Использовать logos
#Использовать cli
Перем Лог;
Перем мКоманднаяСтрока;
Перем Конструктор;
Процедура ПриСозданииОбъекта(КоманднаяСтрока)
УстановитьКоманднуюСтроку(КоманднаяСтрока);
КонецПроцедуры
#Область ПрограммныйИнтерфейс
Процедура УстановитьКоманднуюСтроку(КоманднаяСтрока) Экспорт
мКоманднаяСтрока = КоманднаяСтрока;
КонецПроцедуры
Функция ПолучитьПрограммныйКод() Экспорт
Функция Конвертировать(КоманднаяСтрока, пКонструктор = Неопределено) Экспорт
Если пКонструктор = Неопределено Тогда
Конструктор = Новый КонстуркторПрограммногоКода1С();
Иначе
Конструктор = пКонструктор;
КонецЕсли;
Парсер = Новый ПарсерКонсольнойКоманды();
АргументыКоманд = Парсер.Распарсить(КоманднаяСтрока);
Приложение = Новый КонсольноеПриложение("curl", "", ЭтотОбъект);
Приложение.УстановитьСпек("[URL...] [OPTIONS] [URL...]");
Приложение.Аргумент("URL", "", "Адрес ресурса").ТМассивСтрок();
Приложение.Опция("H header", "", "Заголовок").ТМассивСтрок();
Приложение.Опция("u user", "", "Заголовок").ТСтрока();
Приложение.УстановитьОсновноеДействие(ЭтотОбъект);
Для Каждого АргументыКоманды Из АргументыКоманд Цикл
Если Не (НРег(АргументыКоманды[0]) = "curl") Тогда
ВызватьИсключение "Команда должна начинаться с ""curl""";
КонецЕсли;
АргументыКоманды.Удалить(0);
Приложение.Запустить(АргументыКоманды);
КонецЦикла;
Возврат Конструктор.Собрать();
КонецФункции
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Процедура ВыполнитьКоманду(Команда) Экспорт
МассивURL = Команда.ЗначениеАргумента("URL");
Для Каждого АдресРесурса Из МассивURL Цикл
Конструктор.ДобавитьURL(АдресРесурса);
КонецЦикла;
Конструктор.УстановитьЗаголовки(РазобратьЗаголовки(Команда));
КонецПроцедуры
Функция РазобратьЗаголовки(Команда)
Заголовки = Новый Соответствие;
МассивЗаголовков = Команда.ЗначениеОпции("H");
Для Каждого Строка Из МассивЗаголовков Цикл
Имя = "";
Значение = "";
ПозицияДвоеточия = СтрНайти(Строка, ":");
Если ПозицияДвоеточия Тогда
Имя = СокрЛП(Сред(Строка, 1, ПозицияДвоеточия - 1));
Значение = СокрЛП(Сред(Строка, ПозицияДвоеточия + 1));
Иначе
Имя = Строка;
КонецЕсли;
Заголовки.Вставить(Имя, Значение);
КонецЦикла;
Возврат Заголовки;
КонецФункции
Процедура Инит()
@@ -23,4 +82,10 @@
КонецПроцедуры
Инит();
#КонецОбласти
#Область Инициализация
Инит();
#КонецОбласти

View File

@@ -0,0 +1,170 @@
#Использовать "../internal"
Перем Результат;
Перем МассивURL;
Перем Заголовки;
Перем Метод;
Процедура ПриСозданииОбъекта()
Результат = "";
МассивURL = Новый Массив;
Заголовки = Новый Соответствие();
Метод = "GET";
КонецПроцедуры
Функция Собрать() Экспорт
Результат = "";
Для Каждого URL Из МассивURL Цикл
ВывестиHTTPЗапрос(URL);
КонецЦикла;
Возврат СокрЛП(Результат);
КонецФункции
Функция ДобавитьURL(URL) Экспорт
МассивURL.Добавить(URL);
КонецФункции
Функция УстановитьМетод(пМетод) Экспорт
Метод = пМетод;
КонецФункции
Функция УстановитьЗаголовки(пЗаголовки) Экспорт
Заголовки = пЗаголовки;
КонецФункции
Функция ПолучитьПорт(СтруктураURL)
Порт = СтруктураURL.Порт;
Если Не ЗначениеЗаполнено(Порт) Тогда
Если СтруктураURL.Схема = "https" Тогда
Порт = 443;
Иначе
Порт = 80;
КонецЕсли;
КонецЕсли;
Возврат Формат(Порт, "ЧГ=");
КонецФункции
Функция ВывестиHTTPСоединение(СтруктураURL)
ИмяПараметра = "Соединение";
ИмяПараметраЗащищенноеСоединение = ВывестиЗащищенноеСоединение(СтруктураURL);
ПараметрыФункции = Новый Массив;
ПараметрыФункции.Добавить(ОбернутьКавычками(СтруктураURL.Сервер));
ПараметрыФункции.Добавить(ПолучитьПорт(СтруктураURL));
ПараметрыФункции.Добавить(""); // Пользователь
ПараметрыФункции.Добавить(""); // Пароль
ПараметрыФункции.Добавить(""); // Прокси
ПараметрыФункции.Добавить(""); // Таймаут
ПараметрыФункции.Добавить(ИмяПараметраЗащищенноеСоединение);
ВывестиСтроку(СтрШаблон(ИмяПараметра + " = Новый HTTPСоединение(%1);", ПараметрыФункцииВСтроку(ПараметрыФункции, Истина)));
ВывестиПустуюСтроку();
Возврат ИмяПараметра;
КонецФункции
Функция ВывестиЗащищенноеСоединение(СтруктураURL)
ИмяПараметра = "ЗащищенноеСоединение";
Если СтруктураURL.Схема = "https" Тогда
ВывестиСтроку(ИмяПараметра + " = Новый ЗащищенноеСоединениеOpenSSL();");
Иначе
ИмяПараметра = "";
КонецЕсли;
Возврат ИмяПараметра;
КонецФункции
Функция ВывестиЗаголовки()
ИмяПараметра = "Заголовки";
ВывестиСтроку(ИмяПараметра + " = Новый Соответствие();");
Для Каждого Заголовок Из Заголовки Цикл
СтрокаЗаголовка = СтрШаблон("%1.Вставить(""%2"", ""%3"");",
ИмяПараметра, Заголовок.Ключ, ЭкранироватьКавычки(Заголовок.Значение));
ВывестиСтроку(СтрокаЗаголовка);
КонецЦикла;
ВывестиПустуюСтроку();
Возврат ИмяПараметра;
КонецФункции
Процедура ВывестиHTTPЗапрос(URL)
СтруктураURL = Новый ПарсерURL(URL);
ИмяПараметра = ВывестиЗаголовки();
ИмяПараметраHTTPСоединение = ВывестиHTTPСоединение(СтруктураURL);
ИмяПараметраHTTPЗапрос = "HTTPЗапрос";
ИмяПараметраHTTPОтвет = "HTTPОтвет";
ИмяВыходногоФайла = "";
ПараметрыФункции = Новый Массив;
ПараметрыФункции.Добавить(ОбернутьКавычками(СтруктураURL.ПутьСПараметрами));
ПараметрыФункции.Добавить(ИмяПараметра);
ВывестиСтроку(СтрШаблон("HTTPЗапрос = Новый HTTPЗапрос(%1);", ПараметрыФункцииВСтроку(ПараметрыФункции)));
ПараметрыФункции = Новый Массив;
ПараметрыФункции.Добавить(ОбернутьКавычками(Метод));
ПараметрыФункции.Добавить(ИмяПараметраHTTPЗапрос);
Если ЗначениеЗаполнено(ИмяВыходногоФайла) Тогда
ПараметрыФункции.Добавить(ИмяВыходногоФайла);
КонецЕсли;
ВывестиСтроку(СтрШаблон("%1 = %2.ВызватьHTTPМетод(%3);",
ИмяПараметраHTTPОтвет,
ИмяПараметраHTTPСоединение,
ПараметрыФункцииВСтроку(ПараметрыФункции)));
ВывестиПустуюСтроку();
КонецПроцедуры
Процедура ВывестиСтроку(Строка)
Результат = Результат + Строка + Символы.ПС;
КонецПроцедуры
Процедура ВывестиПустуюСтроку()
Результат = Результат + Символы.ПС;
КонецПроцедуры
Функция ПараметрыФункцииВСтроку(ПараметрыФункции, ПереноситьКаждыйПараметр = Ложь)
Если ПереноситьКаждыйПараметр Тогда
Разделитель = "," + Символы.ПС + Символы.Таб;
Иначе
Разделитель = ", ";
КонецЕсли;
Возврат СокрЛП(СтрСоединить(ПараметрыФункции, Разделитель));
КонецФункции
Функция ОбернутьКавычками(Значение)
Возврат СтрШаблон("""%1""", ЭкранироватьКавычки(Значение))
КонецФункции
Функция ЭкранироватьКавычки(Строка)
Возврат СтрЗаменить(Строка, """", """""");
КонецФункции

View File

@@ -10,7 +10,7 @@
СписокТестов = Новый Массив;
СписокТестов.Добавить("ТестДолжен_ПолучитьПрограммныйКод");
СписокТестов.Добавить("ТестДолжен_ПолучитьПрограммныйКод");
Возврат СписокТестов;
@@ -30,15 +30,32 @@
КонецПроцедуры
Процедура ТестДолжен_ПолучитьПрограммныйКод() Экспорт
Процедура ТестДолжен_ПолучитьПрограммныйКод() Экспорт
КоманднаяСтрока = "curl ^""https://curl.se/^"" ^
| -H ^""accept: text/html^"" ^
| -H ^""accept-language: ru,en-US;q=0.9,en;q=0.8^""";
ПрограммныйКод = "...";
КонсольнаяКоманда = "curl 'https://example.com?param1=value1' \
| -H 'accept: text/html' \
| -H 'accept-language: ru,en-US;q=0.9,en;q=0.8' \
| -H 'user-agent: curl'";
Конвертор = Новый КонвертерКоманднойСтрокиCURL(КоманднаяСтрока);
Результат = Конвертор.ПолучитьПрограммныйКод();
ПрограммныйКод = "Заголовки = Новый Соответствие();
|Заголовки.Вставить(""accept"", ""text/html"");
|Заголовки.Вставить(""accept-language"", ""ru,en-US;q=0.9,en;q=0.8"");
|Заголовки.Вставить(""user-agent"", ""curl"");
|
|ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
|Соединение = Новый HTTPСоединение(""example.com"",
| 443,
| ,
| ,
| ,
| ,
| ЗащищенноеСоединение);
|
|HTTPЗапрос = Новый HTTPЗапрос(""?param1=value1"", Заголовки);
|HTTPОтвет = Соединение.ВызватьHTTPМетод(""GET"", HTTPЗапрос);";
КонвертерКомандыCURL = Новый КонвертерКомандыCURL();
Результат = КонвертерКомандыCURL.Конвертировать(КонсольнаяКоманда, Новый КонстуркторПрограммногоКода1С());
Ожидаем.Что(Результат).Равно(ПрограммныйКод);