From c33c207e811f8b6217c59f57ddbd7f4836a020d0 Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Fri, 10 Jan 2025 02:16:52 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=9E=D0=BF=D1=80=D0=B5=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4?= =?UTF-8?q?=D0=B0=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B0=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20=D0=BA=D0=B0=D0=B6=D0=B4=D0=BE=D0=B3=D0=BE=20URL?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Классы/ГенераторПрограммногоКода1С.os | 22 +--- src/core/Классы/КонвертерКомандыCURL.os | 124 ++++++++++-------- src/internal/Классы/ОписаниеЗапроса.os | 7 +- tests/ГенераторПрограммногоКода1С_test.os | 43 ++++++ tests/КонвертерКомандыCURL_test.os | 2 +- 5 files changed, 122 insertions(+), 76 deletions(-) diff --git a/src/core/Классы/ГенераторПрограммногоКода1С.os b/src/core/Классы/ГенераторПрограммногоКода1С.os index 9c8ffda..6b7f9d3 100644 --- a/src/core/Классы/ГенераторПрограммногоКода1С.os +++ b/src/core/Классы/ГенераторПрограммногоКода1С.os @@ -272,7 +272,7 @@ Для Каждого ПередаваемыйФайл Из ОписаниеЗапроса.Файлы Цикл Если Не (ПередаваемыйФайл.ПрочитатьСодержимое - Или ОписаниеЗапроса.ПередаватьОтправляемыеДанныеВСтрокуЗапроса) Тогда + Или ПередаваемыйФайл.Назначение = НазначенияПередаваемыхДанных.СтрокаЗапроса) Тогда Продолжить; КонецЕсли; @@ -347,8 +347,7 @@ СтрокаЗапроса = СобратьИсходнуюСтрокуЗапроса(СтруктураURL); Для Каждого ПередаваемыйТекст Из ОписаниеЗапроса.ОтправляемыеТекстовыеДанные Цикл - Если ОписаниеЗапроса.ПередаватьОтправляемыеДанныеВСтрокуЗапроса - ИЛИ ПередаваемыйТекст.Назначение = НазначенияПередаваемыхДанных.СтрокаЗапроса Тогда + Если ПередаваемыйТекст.Назначение = НазначенияПередаваемыхДанных.СтрокаЗапроса Тогда СтрокаЗапроса = СтрокаЗапроса + ?(ЗначениеЗаполнено(СтрокаЗапроса), РазделительПараметровЗапроса, "") + ПередаваемыйТекст.Значение; @@ -357,8 +356,7 @@ КодПрочитанныхФайлов = ""; Для Каждого ПрочитанныйФайл Из ПрочитанныеФайлы Цикл - Если ОписаниеЗапроса.ПередаватьОтправляемыеДанныеВСтрокуЗапроса - Или ПрочитанныйФайл.ПередаваемыйФайл.Назначение = НазначенияПередаваемыхДанных.СтрокаЗапроса Тогда + Если ПрочитанныйФайл.ПередаваемыйФайл.Назначение = НазначенияПередаваемыхДанных.СтрокаЗапроса Тогда КодПрочитанныхФайлов = КодПрочитанныхФайлов + ?(КодПрочитанныхФайлов = "", "", КонкатенацияСПереносомСтрокиИАмперсандом) + ПрочитанныйФайл.ИмяПеременной; @@ -401,10 +399,6 @@ Процедура ВывестиИнициализациюТекстовогоТелаЗапроса() - Если ОписаниеЗапроса.ПередаватьОтправляемыеДанныеВСтрокуЗапроса Тогда - Возврат; - КонецЕсли; - ЭлементыТелаЗапросаДляВывода = Новый Массив; КонкатенацияСПереносомСтрокиИРазделителя = " | + ""%1"" + "; @@ -467,10 +461,6 @@ Процедура ВывестиУстановкуТелаЗапросаИзФайлаИВызоваМетодаДляКаждого(ОписаниеРесурса) - Если ОписаниеЗапроса.ПередаватьОтправляемыеДанныеВСтрокуЗапроса Тогда - Возврат; - КонецЕсли; - ДлинаИмениФайлаВКомментарии = 100; ВсеФайлы = Новый Массив(); @@ -523,10 +513,6 @@ КонецПроцедуры Процедура ВывестиУстановкуТелаЗапросаИзФайла(ОписаниеРесурса) - - Если ОписаниеЗапроса.ПередаватьОтправляемыеДанныеВСтрокуЗапроса Тогда - Возврат; - КонецЕсли; Файлы = Новый Массив(); ОбщегоНазначения.ДополнитьМассив(Файлы, ОписаниеЗапроса.Файлы); @@ -555,7 +541,7 @@ Процедура ВывестиВызовHTTPМетода(ОписаниеРесурса) ПараметрыФункции = Новый Массив; - ПараметрыФункции.Добавить(ОбернутьКавычками(ОписаниеЗапроса.Метод)); + ПараметрыФункции.Добавить(ОбернутьКавычками(ОписаниеРесурса.Метод)); ПараметрыФункции.Добавить(ИмяПараметраHTTPЗапрос); ПараметрыФункции.Добавить(ОбернутьКавычками(ОписаниеРесурса.ИмяВыходногоФайла, Истина)); diff --git a/src/core/Классы/КонвертерКомандыCURL.os b/src/core/Классы/КонвертерКомандыCURL.os index 26f1234..ec64e17 100644 --- a/src/core/Классы/КонвертерКомандыCURL.os +++ b/src/core/Классы/КонвертерКомандыCURL.os @@ -120,7 +120,6 @@ ПрочитатьПользователя(Команда); ПрочитатьДанныеДляОтправки(Команда); ПрочитатьМетодЗапроса(Команда); - ПрочитатьПризнакПередачиОтправляемыхДанныхВСтрокуЗапроса(Команда); ПрочитатьСертификатКлиента(Команда); ПрочитатьИспользованиеСертификатыУЦИзХранилищаОС(Команда); ПрочитатьИмяФайлаСертификатовУЦ(Команда); @@ -138,51 +137,61 @@ Процедура ПрочитатьМетодЗапроса(Команда) - Метод = ВРег(ЗначениеОпции(Команда, "X")); - - Если ЗначениеЗаполнено(Метод) Тогда - ОписаниеЗапроса.Метод = Метод; - Возврат; - КонецЕсли; - ЕстьДанныеPOST = (ЕстьОпцииГруппыData(Команда) ИЛИ ЕстьОпции(команда, "json")); ЕстьМетодGET = ЗначениеОпции(Команда, "get") = Истина; ЕстьМетодPOST = ЗначениеОпции(Команда, "get") = Ложь И ЕстьДанныеPOST; - ЕстьМетодPUT = ЕстьОпции(Команда, "T,upload-file"); ЕстьМетодHEAD = ЗначениеОпции(Команда, "head") = Истина; - Если ЕстьМетодPUT Тогда - Если ЕстьМетодGET И ЕстьДанныеPOST Тогда - ТекстОшибки = "PUT и GET"; + Файлы = ЗначениеОпции(Команда, "upload-file"); + КоличествоФайлов = Файлы.Количество(); + НомерРесурса = 0; + Для Каждого ОписаниеРесурса Из ОписаниеЗапроса.АдресаРесурсов Цикл + + НомерРесурса = НомерРесурса + 1; + + Метод = ВРег(ЗначениеОпции(Команда, "X")); + Если ЗначениеЗаполнено(Метод) Тогда + ОписаниеРесурса.Метод = Метод; + Продолжить; + КонецЕсли; + + ЕстьМетодPUT = НомерРесурса <= КоличествоФайлов; + ОшибочныеМетоды = ""; + Если ЕстьМетодPUT Тогда + Если ЕстьМетодGET И ЕстьДанныеPOST Тогда + ОшибочныеМетоды = "PUT и GET"; + ИначеЕсли ЕстьМетодPOST Тогда + ОшибочныеМетоды = "PUT и POST"; + ИначеЕсли ЕстьМетодHEAD Тогда + ОшибочныеМетоды = "PUT и HEAD"; + КонецЕсли; ИначеЕсли ЕстьМетодPOST Тогда - ТекстОшибки = "PUT и POST"; + Если ЕстьМетодHEAD Тогда + ОшибочныеМетоды = "POST и HEAD"; + КонецЕсли; + КонецЕсли; + + Если Не ПустаяСтрока(ОшибочныеМетоды) Тогда + ТекстОшибки = СтрШаблон("Запрещено одновременное использование нескольких HTTP методов %1 для URL %2", + ОшибочныеМетоды, ОписаниеРесурса.URL); + ИсходящиеОшибки.Добавить(ОбщегоНазначения.НоваяОшибка(ТекстОшибки, Истина)); + Возврат; + КонецЕсли; + + Если ЕстьМетодPOST Тогда + Метод = "POST"; + ИначеЕсли ЕстьМетодPUT Тогда + Метод = "PUT"; ИначеЕсли ЕстьМетодHEAD Тогда - ТекстОшибки = "PUT и HEAD"; + Метод = "HEAD"; + Иначе + Метод = "GET"; КонецЕсли; - ИначеЕсли ЕстьМетодPOST Тогда - Если ЕстьМетодHEAD Тогда - ТекстОшибки = "POST и HEAD"; - КонецЕсли; - КонецЕсли; + + ОписаниеРесурса.Метод = Метод; - Если Не ПустаяСтрока(ТекстОшибки) Тогда - ТекстОшибки = "Запрещено одновременное использование нескольких HTTP методов: " + ТекстОшибки; - ИсходящиеОшибки.Добавить(ОбщегоНазначения.НоваяОшибка(ТекстОшибки, Истина)); - Возврат; - КонецЕсли; - - Если ЕстьМетодPOST Тогда - Метод = "POST"; - ИначеЕсли ЕстьМетодPUT Тогда - Метод = "PUT"; - ИначеЕсли ЕстьМетодHEAD Тогда - Метод = "HEAD"; - Иначе - Метод = "GET"; - КонецЕсли; - - ОписаниеЗапроса.Метод = Метод; + КонецЦикла; КонецПроцедуры @@ -391,19 +400,20 @@ Процедура ПрочитатьData(Команда) МассивДанных = ЗначениеОпции(Команда, "d"); // -d, --data + Назначение = НазначениеПередаваемыхДанныхPOST(Команда); Для Каждого Данные Из МассивДанных Цикл Если Лев(Данные, 1) = "@" Тогда ИмяФайла = Сред(Данные, 2); - ПередаваемыйФайл = Новый ПередаваемыйФайл(ИмяФайла, НазначенияПередаваемыхДанных.ТелоЗапроса); + ПередаваемыйФайл = Новый ПередаваемыйФайл(ИмяФайла, Назначение); ПередаваемыйФайл.ПрочитатьСодержимое = Истина; ПередаваемыйФайл.УдалятьПереносыСтрок = Истина; ОписаниеЗапроса.Файлы.Добавить(ПередаваемыйФайл); Иначе - ПередаваемыйТекст = Новый ПередаваемыйТекст(Данные, НазначенияПередаваемыхДанных.ТелоЗапроса); + ПередаваемыйТекст = Новый ПередаваемыйТекст(Данные, Назначение); ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйТекст); КонецЕсли; @@ -414,9 +424,10 @@ Процедура ПрочитатьDataRaw(Команда) МассивДанных = ЗначениеОпции(Команда, "data-raw"); + Назначение = НазначениеПередаваемыхДанныхPOST(Команда); Для Каждого Данные Из МассивДанных Цикл - ПередаваемыйТекст = Новый ПередаваемыйТекст(Данные, НазначенияПередаваемыхДанных.ТелоЗапроса); + ПередаваемыйТекст = Новый ПередаваемыйТекст(Данные, Назначение); ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйТекст); КонецЦикла; @@ -425,12 +436,14 @@ Процедура ПрочитатьDataBinary(Команда) МассивДанных = ЗначениеОпции(Команда, "data-binary"); + Назначение = НазначениеПередаваемыхДанныхPOST(Команда); + Для Каждого ИмяФайла Из МассивДанных Цикл Если Лев(ИмяФайла, 1) = "@" Тогда ИмяФайла = Сред(ИмяФайла, 2); КонецЕсли; - ПередаваемыйФайл = Новый ПередаваемыйФайл(ИмяФайла, НазначенияПередаваемыхДанных.ТелоЗапроса); + ПередаваемыйФайл = Новый ПередаваемыйФайл(ИмяФайла, Назначение); ОписаниеЗапроса.Файлы.Добавить(ПередаваемыйФайл); КонецЦикла; @@ -439,6 +452,8 @@ Процедура ПрочитатьDataUrlencode(Команда) МассивДанных = ЗначениеОпции(Команда, "data-urlencode"); + Назначение = НазначениеПередаваемыхДанныхPOST(Команда); + Для Каждого Данные Из МассивДанных Цикл ПозицияРавенства = СтрНайти(Данные, "="); ПозицияСобачки = СтрНайти(Данные, "@"); @@ -451,13 +466,13 @@ Значение = СтрШаблон("%1=%2", Ключ, Значение); КонецЕсли; - ПередаваемыйТекст = Новый ПередаваемыйТекст(Значение, НазначенияПередаваемыхДанных.ТелоЗапроса); + ПередаваемыйТекст = Новый ПередаваемыйТекст(Значение, Назначение); ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйТекст); ИначеЕсли ПозицияСобачки > 0 Тогда Ключ = Сред(Данные, 1, ПозицияСобачки - 1); ИмяФайла = СокрЛП(Сред(Данные, ПозицияСобачки + 1)); - ПередаваемыйФайл = Новый ПередаваемыйФайл(ИмяФайла, НазначенияПередаваемыхДанных.ТелоЗапроса); + ПередаваемыйФайл = Новый ПередаваемыйФайл(ИмяФайла, Назначение); ПередаваемыйФайл.Ключ = Ключ; ПередаваемыйФайл.ПрочитатьСодержимое = Истина; ПередаваемыйФайл.КодироватьСодержимое = Истина; @@ -465,7 +480,7 @@ ОписаниеЗапроса.Файлы.Добавить(ПередаваемыйФайл); Иначе Значение = КодироватьСтроку(Данные, СпособКодированияСтроки.URLВКодировкеURL); - ПередаваемыйТекст = Новый ПередаваемыйТекст(Значение, НазначенияПередаваемыхДанных.ТелоЗапроса); + ПередаваемыйТекст = Новый ПередаваемыйТекст(Значение, Назначение); ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйТекст); КонецЕсли; КонецЦикла; @@ -476,7 +491,7 @@ МассивДанных = ЗначениеОпции(Команда, "T"); // -T, --upload-file ФигурныеСкобки = "{}"; - + Индекс = -1; Для Каждого Значение Из МассивДанных Цикл Индекс = Индекс + 1; @@ -518,19 +533,20 @@ Процедура ПрочитатьОпициюJson(Команда) МассивДанных = ЗначениеОпции(Команда, "json"); - + Назначение = НазначениеПередаваемыхДанныхPOST(Команда); + Для Каждого Данные Из МассивДанных Цикл Если Лев(Данные, 1) = "@" Тогда ИмяФайла = Сред(Данные, 2); - ПередаваемыйФайл = Новый ПередаваемыйФайл(ИмяФайла, НазначенияПередаваемыхДанных.ТелоЗапроса); + ПередаваемыйФайл = Новый ПередаваемыйФайл(ИмяФайла, Назначение); ПередаваемыйФайл.ПрочитатьСодержимое = Истина; ПередаваемыйФайл.РазделительТелаЗапроса = ""; ОписаниеЗапроса.Файлы.Добавить(ПередаваемыйФайл); Иначе - ПередаваемыйТекст = Новый ПередаваемыйТекст(Данные, НазначенияПередаваемыхДанных.ТелоЗапроса); + ПередаваемыйТекст = Новый ПередаваемыйТекст(Данные, Назначение); ПередаваемыйТекст.РазделительТелаЗапроса = ""; ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйТекст); КонецЕсли; @@ -539,12 +555,6 @@ КонецПроцедуры -Процедура ПрочитатьПризнакПередачиОтправляемыхДанныхВСтрокуЗапроса(Команда) - - ОписаниеЗапроса.ПередаватьОтправляемыеДанныеВСтрокуЗапроса = ЗначениеОпции(Команда, "get"); - -КонецПроцедуры - Процедура ПрочитатьСертификатКлиента(Команда) СертификатКлиента = ПоследнееЗначениеОпции(Команда, "E"); @@ -720,6 +730,14 @@ КонецПроцедуры +Функция НазначениеПередаваемыхДанныхPOST(Команда) + Если ЗначениеОпции(Команда, "get") = Истина Тогда + Возврат НазначенияПередаваемыхДанных.СтрокаЗапроса; + Иначе + Возврат НазначенияПередаваемыхДанных.ТелоЗапроса; + КонецЕсли; +КонецФункции + Функция СоздатьКонсольноеПриложение(ВключатьПоддерживаемые = Истина, ВключатьНеподдерживаемые = Истина) Приложение = Новый КонсольноеПриложение("curl", "", ЭтотОбъект); diff --git a/src/internal/Классы/ОписаниеЗапроса.os b/src/internal/Классы/ОписаниеЗапроса.os index 8051bf0..dc65dc4 100644 --- a/src/internal/Классы/ОписаниеЗапроса.os +++ b/src/internal/Классы/ОписаниеЗапроса.os @@ -1,13 +1,13 @@ Перем АдресаРесурсов Экспорт; // Массив из Структура // - URL - Строка - Адрес ресурса + // - Метод - Строка - Метод // - ИмяВыходногоФайла - Строка - Имя выходного файла + // - Файлы - Массив из см. ПередаваемыйФайл - Файлы Перем Заголовки Экспорт; // Соответствие из КлючИЗначение -Перем Метод Экспорт; // Строка Перем ИмяПользователя Экспорт; // Строка Перем ПарольПользователя Экспорт; // Строка Перем ОтправляемыеТекстовыеДанные Экспорт; // Массив из ПередаваемыйТекст Перем Файлы Экспорт; // Массив из см. ПередаваемыйФайл -Перем ПередаватьОтправляемыеДанныеВСтрокуЗапроса Экспорт; // Булево Перем ИмяФайлаСертификатаКлиента Экспорт; // Строка Перем ПарольСертификатаКлиента Экспорт; // Строка Перем ИспользоватьСертификатыУЦИзХранилищаОС Экспорт; // Булево @@ -30,12 +30,10 @@ Процедура ПриСозданииОбъекта() АдресаРесурсов = Новый Массив; Заголовки = Новый Соответствие(); - Метод = "GET"; ИмяПользователя = ""; ПарольПользователя = ""; ОтправляемыеТекстовыеДанные = Новый Массив; Файлы = Новый Массив; - ПередаватьОтправляемыеДанныеВСтрокуЗапроса = Ложь; ИмяФайлаСертификатаКлиента = ""; ПарольСертификатаКлиента = ""; ИспользоватьСертификатыУЦИзХранилищаОС = Ложь; @@ -62,6 +60,7 @@ Функция НовоеОписаниеРесурса() Описание = Новый Структура(); Описание.Вставить("URL", ""); + Описание.Вставить("Метод", ""); Описание.Вставить("ИмяВыходногоФайла", ""); Описание.Вставить("Файлы", Новый Массив()); Возврат Описание; diff --git a/tests/ГенераторПрограммногоКода1С_test.os b/tests/ГенераторПрограммногоКода1С_test.os index 05af72d..92159b4 100644 --- a/tests/ГенераторПрограммногоКода1С_test.os +++ b/tests/ГенераторПрограммногоКода1С_test.os @@ -20,6 +20,8 @@ СписокТестов.Добавить("ТестДолжен_ПроверитьПередачуФайла"); СписокТестов.Добавить("ТестДолжен_ПроверитьПередачуНесколькихФайловПоОдномуURL"); СписокТестов.Добавить("ТестДолжен_ПроверитьИгнорированиеПередаваемыхФайловПриПревышенииКоличестваURL"); + СписокТестов.Добавить("ТестДолжен_ПроверитьИгнорированиеОпцииGetПриПередачиФайла"); + СписокТестов.Добавить("ТестДолжен_ПроверитьИспользованиеМетодаPUTиGETДляРазныхURL"); СписокТестов.Добавить("ТестДолжен_ПроверитьНеизменностьПереданногоЗаголовкаContentType"); СписокТестов.Добавить("ТестДолжен_ПроверитьМножественноеИспользованиеUrl"); СписокТестов.Добавить("ТестДолжен_ПроверитьПередачуОтправляемыхДанныхВСтрокуЗапроса"); @@ -339,6 +341,47 @@ КонецПроцедуры +Процедура ТестДолжен_ПроверитьИгнорированиеОпцииGetПриПередачиФайла() Экспорт + + КонсольнаяКоманда = "curl --upload-file path/to/file --get http://example.com"; + + ПрограммныйКод = "Соединение = Новый HTTPСоединение(""example.com"", 80); + |HTTPЗапрос = Новый HTTPЗапрос(""/""); + |HTTPЗапрос.УстановитьИмяФайлаТела(""path/to/file""); + | + |HTTPОтвет = Соединение.ВызватьHTTPМетод(""PUT"", HTTPЗапрос);"; + + КонвертерКомандыCURL = Новый КонвертерКомандыCURL(); + Результат = КонвертерКомандыCURL.Конвертировать(КонсольнаяКоманда, Новый ГенераторПрограммногоКода1С()); + + Ожидаем.Что(Результат).Равно(ПрограммныйКод); + +КонецПроцедуры + +Процедура ТестДолжен_ПроверитьИспользованиеМетодаPUTиGETДляРазныхURL() Экспорт + + КонсольнаяКоманда = "curl --upload-file path/to/file http://example1.com http://example2.com"; + + ПрограммныйКод = "// Запрос 1. http://example1.com + |Соединение = Новый HTTPСоединение(""example1.com"", 80); + |HTTPЗапрос = Новый HTTPЗапрос(""/""); + |HTTPЗапрос.УстановитьИмяФайлаТела(""path/to/file""); + | + |HTTPОтвет = Соединение.ВызватьHTTPМетод(""PUT"", HTTPЗапрос); + | + |// Запрос 2. http://example2.com + |Соединение = Новый HTTPСоединение(""example2.com"", 80); + |HTTPЗапрос = Новый HTTPЗапрос(""/""); + | + |HTTPОтвет = Соединение.ВызватьHTTPМетод(""GET"", HTTPЗапрос);"; + + КонвертерКомандыCURL = Новый КонвертерКомандыCURL(); + Результат = КонвертерКомандыCURL.Конвертировать(КонсольнаяКоманда, Новый ГенераторПрограммногоКода1С()); + + Ожидаем.Что(Результат).Равно(ПрограммныйКод); + +КонецПроцедуры + Процедура ТестДолжен_ПроверитьНеизменностьПереданногоЗаголовкаContentType() Экспорт КонсольнаяКоманда = "curl http://example.com \ diff --git a/tests/КонвертерКомандыCURL_test.os b/tests/КонвертерКомандыCURL_test.os index 2518057..6ce7031 100644 --- a/tests/КонвертерКомандыCURL_test.os +++ b/tests/КонвертерКомандыCURL_test.os @@ -167,7 +167,7 @@ Результат = КонвертерКомандыCURL.Конвертировать(КонсольнаяКоманда,, Ошибки); Ожидаем.Что(Ошибки, "Команда не валидна: " + КонсольнаяКоманда).Заполнено(); - Ожидаем.Что(Ошибки[0].Текст).Содержит("Запрещено одновременное использование нескольких HTTP методов:"); + Ожидаем.Что(Ошибки[0].Текст).Содержит("Запрещено одновременное использование нескольких HTTP методов"); Ожидаем.Что(Ошибки[0].Критичная).ЭтоИстина(); КонецЦикла;