Skip to content

Commit

Permalink
feat: Поддержка опций -F, --form для генератора кода 1С (#180)
Browse files Browse the repository at this point in the history
  • Loading branch information
Stivo182 authored Feb 23, 2025
1 parent c484449 commit e829d61
Show file tree
Hide file tree
Showing 4 changed files with 745 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// BSLLS:LatinAndCyrillicSymbolInWord-off

#Использовать "../../internal"

Перем Конструктор; // см. КонструкторПрограммногоКода
Expand All @@ -21,6 +23,7 @@
Перем ИмяПараметраHTTPОтвет; // Строка
Перем ИмяПараметраПрокси; // Строка
Перем ИмяПараметраТелоЗапросаСтрока; // Строка
Перем ИмяПараметраРазделительДанныхMultipart; // Строка

#Область ПрограммныйИнтерфейс

Expand Down Expand Up @@ -48,6 +51,8 @@
ПрочитанныеФайлы.Очистить();

ОпределитьМетодУстановкиТелаЗапроса();

ДобавитьРазделительДанныхMultipart();
ДобавитьЗаголовки();
ДобавитьЧтениеФайлов();
ДобавитьДанныеЗапроса();
Expand Down Expand Up @@ -116,7 +121,10 @@
|list-only
|basic
|ntlm
|negotiate";
|negotiate
|F
|form
|form-string";

Возврат СтрРазделить(ПоддерживаемыеОпции, Символы.ПС, Ложь);

Expand Down Expand Up @@ -144,11 +152,24 @@
ИмяПараметраHTTPОтвет = "HTTPОтвет";
ИмяПараметраПрокси = "Прокси";
ИмяПараметраТелоЗапросаСтрока = "ТелоЗапроса";
ИмяПараметраРазделительДанныхMultipart = "РазделительMultipart";

ПрочитанныеФайлы = Новый Массив();

КонецПроцедуры

Процедура ДобавитьРазделительДанныхMultipart()

Если Не ОписаниеЗапроса.ОтправлятьКакMultipartFormData Тогда
Возврат;
КонецЕсли;

Конструктор.ДобавитьСтроку(
"%1 = СтрЗаменить(Новый УникальныйИдентификатор, ""-"", """");",
ИмяПараметраРазделительДанныхMultipart);

КонецПроцедуры

Процедура ДобавитьЗаголовки()

ИнициализированыЗаголовки = Ложь;
Expand All @@ -166,9 +187,11 @@
КонецЦикла;

ДобавитьЗаголовокAuthorization(ЛокальныйКонструктор);
ДобавитьЗаголовокContentTypeMultipart(ЛокальныйКонструктор);

Если Не ЛокальныйКонструктор.Пустой() Тогда
Конструктор
.ДобавитьПустуюСтроку()
.ДобавитьСтроку("%1 = Новый Соответствие();", ИмяПараметраЗаголовки)
.ДобавитьСтроку(ЛокальныйКонструктор.ПолучитьРезультат());

Expand All @@ -187,13 +210,21 @@

КонецПроцедуры

Процедура ДобавитьЧтениеФайлов()
Если ОписаниеЗапроса.ОтправлятьКакMultipartFormData Тогда
Процедура ДобавитьЗаголовокContentTypeMultipart(Конструктор)

Если Не ОписаниеЗапроса.ОтправлятьКакMultipartFormData Тогда
Возврат;
КонецЕсли;

Конструктор.ДобавитьСтроку("%1.Вставить(""Content-Type"", ""multipart/form-data; boundary="" + %2);",
ИмяПараметраЗаголовки,
ИмяПараметраРазделительДанныхMultipart);

КонецПроцедуры

Процедура ДобавитьЧтениеФайлов()

ТребуетсяЧтениеФайловТелаЗапроса = Не МетодУстановкиТелаЗапроса = "ИзФайла";
ТребуетсяЧтениеФайловТелаЗапроса = Не МетодУстановкиТелаЗапроса = "Файл";

ФайлыДляЧтения = Новый Массив();
Для Каждого ПередаваемыйФайл Из ОписаниеЗапроса.Файлы Цикл
Expand Down Expand Up @@ -529,12 +560,13 @@

ДобавитьУстановкуТелаЗапросаТекстовымиДанными();
ДобавитьУстановкуТелаЗапросаИзФайла(ОписаниеРесурса);
ДобавитьЗаписьДанныхВПотокMultipart();

КонецПроцедуры

Процедура ДобавитьУстановкуТелаЗапросаТекстовымиДанными()

Если Не МетодУстановкиТелаЗапроса = "ИзСтроки" Тогда
Если Не МетодУстановкиТелаЗапроса = "Строка" Тогда
Возврат;
КонецЕсли;

Expand All @@ -546,7 +578,7 @@

Процедура ДобавитьУстановкуТелаЗапросаИзФайла(ОписаниеРесурса)

Если Не МетодУстановкиТелаЗапроса = "ИзФайла" Тогда
Если Не МетодУстановкиТелаЗапроса = "Файл" Тогда
Возврат;
КонецЕсли;

Expand Down Expand Up @@ -574,6 +606,147 @@

КонецПроцедуры

Процедура ДобавитьЗаписьДанныхВПотокMultipart()

Если Не ОписаниеЗапроса.ОтправлятьКакMultipartFormData Тогда
Возврат;
КонецЕсли;

КонструкторЗаписиДанных = Новый КонструкторПрограммногоКода();
ИмяПараметраРазделитель = ИмяПараметраРазделительДанныхMultipart;

// Данные формы
Для Каждого ПередаваемыйТекст Из ОписаниеЗапроса.ОтправляемыеТекстовыеДанные Цикл

Если Не ПередаваемыйТекст.Назначение = НазначенияПередаваемыхДанных.ТелоЗапроса Тогда
Продолжить;
КонецЕсли;

КонструкторЗаписиДанных
.ДобавитьКомментарий(
"Начало %1", ПередаваемыйТекст.ИмяПоля)
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(""--"" + %1 + РазделительСтрок);", ИмяПараметраРазделитель)
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(""Content-Disposition: form-data; name=""""%1"""""" + РазделительСтрок);",
ПередаваемыйТекст.ИмяПоля);

Если ЗначениеЗаполнено(ПередаваемыйТекст.ТипMIME) Тогда
КонструкторЗаписиДанных.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(""Content-Type: %1"" + РазделительСтрок);",
ПередаваемыйТекст.ТипMIME)
КонецЕсли;

ДобавитьЗаголовкиВЗаписьДанныхMultipart(КонструкторЗаписиДанных, ПередаваемыйТекст.Заголовки);

КонструкторЗаписиДанных
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(РазделительСтрок);")
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(""%1"" + РазделительСтрок);", ПередаваемыйТекст.Значение)
.ДобавитьКомментарий(
"Конец %1", ПередаваемыйТекст.ИмяПоля);

КонецЦикла;

// Данные формы, прочитанные из файлов
Для Каждого ПрочитанныйФайл Из ПрочитанныеФайлы Цикл

ПередаваемыйФайл = ПрочитанныйФайл.ПередаваемыйФайл;

Если Не ПередаваемыйФайл.Назначение = НазначенияПередаваемыхДанных.ТелоЗапроса Тогда
Продолжить;
КонецЕсли;

КонструкторЗаписиДанных
.ДобавитьКомментарий(
"Начало %1", ПередаваемыйФайл.ИмяПоля)
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(""--"" + %1 + РазделительСтрок);", ИмяПараметраРазделитель)
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(""Content-Disposition: form-data; name=""""%1"""""" + РазделительСтрок);",
ПередаваемыйФайл.ИмяПоля);

Если ЗначениеЗаполнено(ПередаваемыйФайл.ТипMIME) Тогда
КонструкторЗаписиДанных.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(""Content-Type: %1"" + РазделительСтрок);",
ПередаваемыйФайл.ТипMIME)
КонецЕсли;

ДобавитьЗаголовкиВЗаписьДанныхMultipart(КонструкторЗаписиДанных, ПередаваемыйФайл.Заголовки);

КонструкторЗаписиДанных
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(РазделительСтрок);")
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(%1 + РазделительСтрок);", ПрочитанныйФайл.ИмяПеременной)
.ДобавитьКомментарий(
"Конец %1", ПередаваемыйФайл.ИмяПоля);

КонецЦикла;

// Файлы
Для Каждого ПередаваемыйФайл Из ОписаниеЗапроса.Файлы Цикл

Если Не ПередаваемыйФайл.Назначение = НазначенияПередаваемыхДанных.ТелоЗапроса
Или ПередаваемыйФайл.ПрочитатьСодержимое Тогда
Продолжить;
КонецЕсли;

КонструкторЗаписиДанных
.ДобавитьКомментарий(
"Начало %1", ПередаваемыйФайл.ИмяПоля)
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(""--"" + %1 + РазделительСтрок);", ИмяПараметраРазделитель)
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(""Content-Disposition: form-data; name=""""%1""""; filename=""""%2"""""" + РазделительСтрок);",
ПередаваемыйФайл.ИмяПоля,
ПередаваемыйФайл.ИмяФайла)
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(""Content-Type: %1"" + РазделительСтрок);",
?(ЗначениеЗаполнено(ПередаваемыйФайл.ТипMIME), ПередаваемыйФайл.ТипMIME, "application/octet-stream"));

ДобавитьЗаголовкиВЗаписьДанныхMultipart(КонструкторЗаписиДанных, ПередаваемыйФайл.Заголовки);

КонструкторЗаписиДанных
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(РазделительСтрок);")
.ДобавитьСтроку(
"ЗаписьДанных.Записать(Новый ДвоичныеДанные(""%1""));",
ПередаваемыйФайл.ПолноеИмяФайла)
.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(РазделительСтрок);")
.ДобавитьКомментарий(
"Конец %1", ПередаваемыйФайл.ИмяПоля);

КонецЦикла;

Если КонструкторЗаписиДанных.Пустой() Тогда
Возврат;
КонецЕсли;

Конструктор
.ДобавитьСтроку("Поток = %1.ПолучитьТелоКакПоток();", ИмяПараметраHTTPЗапрос)
.ДобавитьПустуюСтроку()
.ДобавитьСтроку("РазделительСтрок = Символы.ВК + Символы.ПС;")
.ДобавитьСтроку("ЗаписьДанных = Новый ЗаписьДанных(Поток, , , """", """");")
.ДобавитьСтроку(КонструкторЗаписиДанных.ПолучитьРезультат())
.ДобавитьСтроку("ЗаписьДанных.ЗаписатьСтроку(""--"" + %1 + ""--"" + РазделительСтрок);", ИмяПараметраРазделитель)
.ДобавитьСтроку("ЗаписьДанных.Закрыть();");

КонецПроцедуры

Процедура ДобавитьЗаголовкиВЗаписьДанныхMultipart(КонструкторЗаписиДанных, Заголовки)

Для Каждого Строка Из Заголовки Цикл
КонструкторЗаписиДанных.ДобавитьСтроку(
"ЗаписьДанных.ЗаписатьСтроку(""%1: %2"" + РазделительСтрок);",
Строка.Ключ,
Строка.Значение)
КонецЦикла;

КонецПроцедуры

Процедура ДобавитьFTPСоединение(СтруктураURL)

Если ЗначениеЗаполнено(ОписаниеЗапроса.FTPАдресОбратногоСоединения)
Expand Down Expand Up @@ -732,11 +905,11 @@
КонецЦикла;

Если ОписаниеЗапроса.ОтправлятьКакMultipartFormData Тогда
МетодУстановкиТелаЗапроса = "";
МетодУстановкиТелаЗапроса = "Поток";
ИначеЕсли КоличествоФайлов > 1 Или ЕстьТекстовоеТелоЗапроса Тогда
МетодУстановкиТелаЗапроса = "ИзСтроки";
МетодУстановкиТелаЗапроса = "Строка";
ИначеЕсли КоличествоФайлов = 1 И Не ЕстьТекстовоеТелоЗапроса Тогда
МетодУстановкиТелаЗапроса = "ИзФайла";
МетодУстановкиТелаЗапроса = "Файл";
Иначе
МетодУстановкиТелаЗапроса = "";
КонецЕсли;
Expand Down
46 changes: 39 additions & 7 deletions src/core/Классы/КонвертерКомандыCURL.os
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
Перем ТекущаяКоманда; // см. КомандаПриложения
Перем ОписаниеОпций; // Соответствие
Перем КаталогСохраненияФайлов; // Строка
Перем MIMEТипыРасширенийФайлов; // Соответствие, Неопределено

#Область ПрограммныйИнтерфейс

Expand Down Expand Up @@ -712,6 +713,7 @@
Возврат;
КонецЕсли;

ТипMIME = ДанныеПоляФормы.Параметры["type"];
ПервыйСимвол = Лев(ДанныеПоляФормы.Значение, 1);
ЭтоФайл = ПервыйСимвол = "@" Или ПервыйСимвол = "<";

Expand All @@ -725,20 +727,31 @@
ИмяФайла = ДанныеПоляФормы.Параметры["filename"];
Если Не ИмяФайла = Неопределено Тогда
ПередаваемыйЭлемент.ИмяФайла = ИмяФайла;
КонецЕсли;
Иначе
ПередаваемыйЭлемент.ИмяФайла = Новый Файл(ПолноеИмяФайла).Имя;
КонецЕсли;

Если Не ТипMIME = Неопределено Тогда
ПередаваемыйЭлемент.ТипMIME = ТипMIME;
ИначеЕсли Не ПередаваемыйЭлемент.ПрочитатьСодержимое Тогда
ТипMIME = MIMEТипПоРасширениюФайла(Новый Файл(ПередаваемыйЭлемент.ПолноеИмяФайла).Расширение);
Если Не ТипMIME = Неопределено Тогда
ПередаваемыйЭлемент.ТипMIME = ТипMIME;
КонецЕсли;
КонецЕсли;
Иначе
ПередаваемыйЭлемент = Новый ПередаваемыйТекст(ДанныеПоляФормы.Значение, Назначение);
ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйЭлемент);

Если Не ТипMIME = Неопределено Тогда
ПередаваемыйЭлемент.ТипMIME = ТипMIME;
КонецЕсли;

ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйЭлемент);
КонецЕсли;

ПередаваемыйЭлемент.ИмяПоля = ДанныеПоляФормы.ИмяПоля;
ПередаваемыйЭлемент.Заголовки = ДанныеПоляФормы.Параметры["headers"];

ТипMIME = ДанныеПоляФормы.Параметры["type"];
Если Не ТипMIME = Неопределено Тогда
ПередаваемыйЭлемент.ТипMIME = ТипMIME;
КонецЕсли;

КонецЦикла;

КонецПроцедуры
Expand Down Expand Up @@ -1657,6 +1670,25 @@
Возврат ТекущаяКоманда.ЗначениеОпции(ИмяОпции);
КонецФункции

Функция MIMEТипПоРасширениюФайла(Расширение)

Если MIMEТипыРасширенийФайлов = Неопределено Тогда
MIMEТипыРасширенийФайлов = Новый Соответствие();
MIMEТипыРасширенийФайлов.Вставить(".gif", "image/gif");
MIMEТипыРасширенийФайлов.Вставить(".jpg", "image/jpeg");
MIMEТипыРасширенийФайлов.Вставить(".jpeg", "image/jpeg");
MIMEТипыРасширенийФайлов.Вставить(".png", "image/png");
MIMEТипыРасширенийФайлов.Вставить(".svg", "image/svg+xml");
MIMEТипыРасширенийФайлов.Вставить(".txt", "text/plain");
MIMEТипыРасширенийФайлов.Вставить(".htm", "text/html");
MIMEТипыРасширенийФайлов.Вставить(".html", "application/pdf");
MIMEТипыРасширенийФайлов.Вставить(".xml", "application/xml");
КонецЕсли;

Возврат MIMEТипыРасширенийФайлов[НРег(Расширение)];

КонецФункции

// Используется для отключения вывода справки cli
Процедура Заглушка(Значение = Неопределено) Экспорт

Expand Down
Loading

0 comments on commit e829d61

Please sign in to comment.