1
0
mirror of https://github.com/alei1180/curlone.git synced 2025-11-25 23:01:55 +02:00

feat: Представление тела запроса из строки JSON в объект языка

This commit is contained in:
Dmitry Ivanov
2025-03-21 20:22:30 +03:00
parent 61daf412e4
commit d1b30ebe02
7 changed files with 283 additions and 12 deletions

View File

@@ -239,6 +239,7 @@
Процедура ДобавитьДанныеЗапроса()
ДанныеЗапросаСборка = "";
Состояние.ТелоЗапросаВJSON = Ложь;
Если Не Состояние.ПереданоТелоЗапроса Тогда
Возврат;
@@ -284,12 +285,14 @@
ДобавитьДанныеЗапросаИзПрочитанныхФайловЧерезСоответствие(КонструкторДанных, Назначение, ИмяПараметра);
Если Не КонструкторДанных.Пустой() Тогда
Конструктор
.ДобавитьПустуюСтроку()
.ДобавитьСтроку("%1 = Новый Соответствие();", ИмяПараметра)
.ДобавитьСтроку(КонструкторДанных.ПолучитьРезультат());
РезультатСборка = ИмяПараметра;
КонецЕсли;
КонецПроцедуры
@@ -399,16 +402,44 @@
ОписаниеЗапроса.ОтправляемыеТекстовыеДанные,
ПрочитанныеФайлы);
Если ЗначениеЗаполнено(Сборка) Тогда
Если СтрЧислоСтрок(Сборка) = 1 Тогда
РезультатСборка = Сборка;
Иначе
Если Не ЗначениеЗаполнено(Сборка) Тогда
Возврат;
КонецЕсли;
ТипКонтента = НРег(ОписаниеЗапроса.ЗначениеЗаголовка("Content-Type"));
Если СтрНайти(ТипКонтента, "application/json") Тогда
ТекстJson = Сред(Сборка, 2, СтрДлина(Сборка) - 2);
ТекстJson = СтрЗаменить(ТекстJson, Символы.ПС + "|", Символы.ПС);
ТекстJson = СтрЗаменить(ТекстJson, """""", """");
Результат = ОбщегоНазначения.ПопытатьсяПрочитатьJSON(ТекстJson);
Если Не Результат = Неопределено Тогда
Конструктор
.ДобавитьПустуюСтроку()
.ДобавитьСтроку("%1 = %2;", ИмяПараметра, Сборка);
.ДобавитьСоответствие(Результат, ИмяПараметра);
РезультатСборка = ИмяПараметра;
Состояние.ТелоЗапросаВJSON = Истина;
Возврат;
КонецЕсли;
КонецЕсли;
Если СтрЧислоСтрок(Сборка) = 1 Тогда
РезультатСборка = Сборка;
Иначе
Конструктор
.ДобавитьПустуюСтроку()
.ДобавитьСтроку("%1 = %2;", ИмяПараметра, Сборка);
РезультатСборка = ИмяПараметра;
КонецЕсли;
КонецПроцедуры
@@ -732,7 +763,7 @@
ИначеЕсли ВозможноПередатьДанныеЗапросаВПараметрыФункцииВызоваМетода(ОписаниеРесурса.Метод) Тогда
ПараметрыФункции.Добавить(URLСборка);
ПараметрыФункции.Добавить(ДанныеЗапроса);
ПараметрыФункции.Добавить(?(Не Состояние.ТелоЗапросаВJSON, ДанныеЗапроса, Неопределено));
ИначеЕсли ОписаниеРесурса.Метод = "HEAD" Или ОписаниеРесурса.Метод = "OPTIONS" Тогда
@@ -909,12 +940,24 @@
Процедура ДобавитьДанныеВДополнительныеПараметры(КонструкторДопПараметров, ОписаниеРесурса, ДанныеЗапроса)
Если ЗначениеЗаполнено(ДанныеЗапроса)
И Не ВозможноПередатьДанныеЗапросаВПараметрыФункцииВызоваМетода(ОписаниеРесурса.Метод) Тогда
Если Не ЗначениеЗаполнено(ДанныеЗапроса) Тогда
Возврат;
КонецЕсли;
Если Состояние.ТелоЗапросаВJSON Тогда
КонструкторДопПараметров.ДобавитьСтроку(
"%1.Вставить(""Json"", %2);",
ИмяПараметраДополнительныеПараметры,
ДанныеЗапроса);
ИначеЕсли Не ВозможноПередатьДанныеЗапросаВПараметрыФункцииВызоваМетода(ОписаниеРесурса.Метод) Тогда
КонструкторДопПараметров.ДобавитьСтроку(
"%1.Вставить(""{t(Параметр.Данные)}"", %2);",
ИмяПараметраДополнительныеПараметры,
ДанныеЗапроса);
КонецЕсли;
КонецПроцедуры
@@ -959,7 +1002,14 @@
КонецПроцедуры
Функция ВозможноПередатьДанныеЗапросаВПараметрыФункцииВызоваМетода(Метод)
Возврат Метод = "POST" Или Метод = "PUT" Или Метод = "PATCH" Или Метод = "DELETE";
Возврат (
Метод = "POST"
Или Метод = "PUT"
Или Метод = "PATCH"
Или Метод = "DELETE"
);
КонецФункции
Функция ВозможноПередатьПараметрыЗапросаВПараметрыФункцииВызоваМетода(Метод)
@@ -1012,13 +1062,16 @@
КонецФункции
Функция ПередаваемыеЗаголовки()
Заголовки = Новый Соответствие();
Для Каждого Заголовок Из ОписаниеЗапроса.Заголовки Цикл
Если ПередаватьЗаголовок(Заголовок) Тогда
Заголовки.Вставить(Заголовок.Ключ, Заголовок.Значение);
КонецЕсли;
КонецЦикла;
Возврат Заголовки;
КонецФункции
Функция ПередаватьЗаголовок(Заголовок)
@@ -1040,6 +1093,7 @@
КонецФункции
Функция НовоеСостояние()
Результат = Новый Структура();
Результат.Вставить("ПереданоТелоЗапроса", ОписаниеЗапроса.ПереданоТелоЗапроса());
@@ -1048,8 +1102,10 @@
Результат.Вставить("ЕстьФайлыMultipart", Ложь);
Результат.Вставить("ЕстьДополнительныеПараметры", Ложь);
Результат.Вставить("ВызванМетодПоТекущемуURL", Ложь);
Результат.Вставить("ТелоЗапросаВJSON", Ложь);
Возврат Результат;
КонецФункции
Функция ИмяФункцииБиблиотекиПоМетоду(Метод)

View File

@@ -85,23 +85,146 @@
КонецФункции
Функция ПараметрВСтроку(Значение) Экспорт
Тип = ТипЗнч(Значение);
Если Тип = Тип("Строка") Тогда
Возврат СтрШаблон("""%1""", ЭкранироватьКавычки(Значение));
ИначеЕсли Тип = Тип("Число") Тогда
Возврат Формат(Значение, "ЧРД=.; ЧН=0; ЧГ=");
ИначеЕсли Тип = Тип("Булево") Тогда
Возврат Формат(Значение, "БЛ=Ложь; БИ=Истина");
ИначеЕсли Тип = Тип("Дата") Тогда
Если НачалоДня(Значение) = Значение Тогда
Возврат Формат(Значение, "ДФ='''Дата(''yyyy, M, d'')'''");
Иначе
Возврат Формат(Значение, "ДФ='''Дата(''yyyy, M, d, H, m, s'')'''");
КонецЕсли;
Иначе
Возврат "";
КонецЕсли;
КонецФункции
Функция НеобязательныйПараметрВСтроку(Значение) Экспорт
Если ЗначениеЗаполнено(Значение) Тогда
Возврат ПараметрВСтроку(Значение);
КонецЕсли;
Возврат "";
КонецФункции
Функция ДобавитьСоответствие(Соответствие, ИмяПараметра) Экспорт
ДобавитьСтроку("%1 = Новый Соответствие();", ИмяПараметра);
ДобавитьЭлементыСоответствия(Соответствие, ИмяПараметра);
Возврат ЭтотОбъект;
КонецФункции
Функция ДобавитьЭлементыСоответствия(Соответствие, ИмяПараметра) Экспорт
Для Каждого КлючИЗначение Из Соответствие Цикл
ТипЗначения = ТипЗнч(КлючИЗначение.Значение);
Если ТипЗначения = Тип("Соответствие") Тогда
ДобавитьСтроку(
"%1.{t(Соответствие.Вставить)}(%2, Новый Соответствие());",
ИмяПараметра,
ПараметрВСтроку(КлючИЗначение.Ключ)
);
Путь = СтрШаблон("%1[""%2""]", ИмяПараметра, КлючИЗначение.Ключ);
ДобавитьЭлементыСоответствия(КлючИЗначение.Значение, Путь);
ИначеЕсли ТипЗначения = Тип("Массив") Тогда
ДобавитьСтроку(
"%1.{t(Соответствие.Вставить)}(%2, Новый Массив());",
ИмяПараметра,
ПараметрВСтроку(КлючИЗначение.Ключ)
);
Путь = СтрШаблон("%1[""%2""]", ИмяПараметра, КлючИЗначение.Ключ);
ДобавитьЭлементыМассива(КлючИЗначение.Значение, Путь);
Иначе
МассивПараметров = Новый Массив();
МассивПараметров.Добавить(ПараметрВСтроку(КлючИЗначение.Ключ));
МассивПараметров.Добавить(ПараметрВСтроку(КлючИЗначение.Значение));
ДобавитьСтроку(
"%1.{t(Соответствие.Вставить)}(%2);",
ИмяПараметра,
ПараметрыФункцииВСтроку(МассивПараметров)
);
КонецЕсли;
КонецЦикла;
Возврат ЭтотОбъект;
КонецФункции
Функция ДобавитьМассив(Массив, ИмяПараметра) Экспорт
ДобавитьСтроку("%1 = Новый Массив();", ИмяПараметра);
ДобавитьЭлементыМассива(Массив, ИмяПараметра);
Возврат ЭтотОбъект;
КонецФункции
Функция ДобавитьЭлементыМассива(Массив, ИмяПараметра) Экспорт
ИндексЭлемента = 0;
Для Каждого Значение Из Массив Цикл
ТипЗначения = ТипЗнч(Значение);
Если ТипЗначения = Тип("Соответствие") Тогда
ДобавитьСтроку("%1.{t(Массив.Добавить)}(Новый Соответствие());", ИмяПараметра);
Путь = СтрШаблон("%1[%2]", ИмяПараметра, Формат(ИндексЭлемента, "ЧН=0; ЧГ="));
ДобавитьЭлементыСоответствия(Значение, Путь);
ИначеЕсли ТипЗначения = Тип("Массив") Тогда
ДобавитьСтроку("%1.{t(Массив.Добавить)}(Новый Массив());", ИмяПараметра);
Путь = СтрШаблон("%1[%2]", ИмяПараметра, Формат(ИндексЭлемента, "ЧН=0; ЧГ="));
ДобавитьЭлементыМассива(Значение, Путь);
Иначе
ДобавитьСтроку("%1.{t(Массив.Добавить)}(%2);", ИмяПараметра, ПараметрВСтроку(Значение));
КонецЕсли;
ИндексЭлемента = ИндексЭлемента + 1;
КонецЦикла;
Возврат ЭтотОбъект;
КонецФункции
#КонецОбласти

View File

@@ -62,6 +62,7 @@
НуженРазделитель = Ложь;
МассивТекстовыхДанных = Новый Массив();
Для Каждого ПередаваемыйТекст Из ТекстовыеДанные Цикл
Если Не ПередаваемыйТекст.Назначение = НазначениеДанных Тогда
Продолжить;
КонецЕсли;
@@ -74,6 +75,7 @@
МассивТекстовыхДанных.Добавить(ПередаваемыйТекст.ПолноеЗначение());
НуженРазделитель = Истина;
КонецЦикла;
Если МассивТекстовыхДанных.Количество() Тогда
@@ -122,6 +124,7 @@
КонецЕсли;
НуженРазделитель = Истина;
КонецЦикла;
Возврат СтрСоединить(ЧастиКода);

View File

@@ -1,17 +1,21 @@
#Область ПрограммныйИнтерфейс
Процедура ДополнитьМассив(МассивПриемник, МассивИсточник) Экспорт
Для Каждого Значение Из МассивИсточник Цикл
МассивПриемник.Добавить(Значение);
КонецЦикла;
КонецПроцедуры
Функция НайтиВСоответствииПоКлючуБезУчетаРегистра(Соответствие, Ключ) Экспорт
Для Каждого КлючИЗначение Из Соответствие Цикл
Если НРег(КлючИЗначение.Ключ) = НРег(Ключ) Тогда
Возврат КлючИЗначение.Значение;
КонецЕсли;
КонецЦикла;
КонецФункции
Функция ДобавитьКонечныйРазделительПути(Знач ПутьКаталога) Экспорт
@@ -73,7 +77,27 @@
КонецФункции
Функция ПопытатьсяПрочитатьJSON(Строка) Экспорт
Попытка
ЧтениеJSON = Новый ЧтениеJSON();
ЧтениеJSON.УстановитьСтроку(Строка);
Результат = ПрочитатьJSON(ЧтениеJSON, Истина);
ЧтениеJSON.Закрыть();
Возврат Результат;
Исключение
Возврат Неопределено;
КонецПопытки
КонецФункции
Функция ЕстьКритичныеОшибки(Ошибки) Экспорт
Для Каждого Ошибка Из Ошибки Цикл
Если Ошибка.Критичная Тогда
Возврат Истина;
@@ -81,6 +105,7 @@
КонецЦикла;
Возврат Ложь;
КонецФункции
Функция НоваяКритичнаяОшибка(Текст) Экспорт

View File

@@ -9,6 +9,7 @@
Ложь = False
# Глобальные функции и процедуры
Дата = Date
СтрЗаменить = StrReplace
НайтиФайлы = FindFiles
КодироватьСтроку = EncodeString

View File

@@ -9,6 +9,7 @@
Ложь = Ложь
# Глобальные функции и процедуры
Дата = Дата
СтрЗаменить = СтрЗаменить
НайтиФайлы = НайтиФайлы
КодироватьСтроку = КодироватьСтроку

View File

@@ -833,10 +833,14 @@
|Заголовки.Вставить(""Content-Type"", ""application/json"");
|Заголовки.Вставить(""Accept"", ""application/json"");
|
|Данные = Новый Соответствие();
|Данные.Вставить(""drink"", ""coffe"");
|
|ДополнительныеПараметры = Новый Структура();
|ДополнительныеПараметры.Вставить(""Заголовки"", Заголовки);
|ДополнительныеПараметры.Вставить(""Json"", Данные);
|
|Результат = КоннекторHTTP.Post(""http://example.com"", ""{""""drink"""": """"coffe""""}"", ДополнительныеПараметры);";
|Результат = КоннекторHTTP.Post(""http://example.com"", , ДополнительныеПараметры);";
ПроверитьКонвертациюБезОшибок(КонсольнаяКоманда, ПрограммныйКод);
@@ -853,10 +857,14 @@
|Заголовки.Вставить(""Content-Type"", ""application/json"");
|Заголовки.Вставить(""Accept"", ""application/json"");
|
|Данные = Новый Соответствие();
|Данные.Вставить(""drink"", ""coffe"");
|
|ДополнительныеПараметры = Новый Структура();
|ДополнительныеПараметры.Вставить(""Заголовки"", Заголовки);
|ДополнительныеПараметры.Вставить(""Json"", Данные);
|
|Результат = КоннекторHTTP.Post(""http://example.com"", ""{""""drink"""": """"coffe""""}"", ДополнительныеПараметры);";
|Результат = КоннекторHTTP.Post(""http://example.com"", , ДополнительныеПараметры);";
ПроверитьКонвертациюБезОшибок(КонсольнаяКоманда, ПрограммныйКод);
@@ -888,6 +896,60 @@
КонецПроцедуры
&Тест
Процедура ТестДолжен_ПроверитьПередачуДанныхВJsonИзData() Экспорт
КонсольнаяКоманда = "curl http://example.com \
|-H 'Content-Type: application/json' \
|--data '{
| ""title"": ""Sample Slide Show"",
| ""date"": ""2024-04-13T08:30:00Z"",
| ""author"": ""Yours Truly"",
| ""pages"": 450,
| ""slides"": [
| {
| ""type"": ""all"", ""title"": ""Wake up to WonderWidgets!""
| },
| {
| ""type"": ""all"",
| ""title"": ""Overview"",
| ""items"": [
| ""Why <em>WonderWidgets</em> are great"",
| ""Who <em>buys</em> WonderWidgets""
| ]
| }
| ]
|}'";
ПрограммныйКод = "Заголовки = Новый Соответствие();
|Заголовки.Вставить(""Content-Type"", ""application/json"");
|
|Данные = Новый Соответствие();
|Данные.Вставить(""title"", ""Sample Slide Show"");
|Данные.Вставить(""date"", Дата(2024, 4, 13, 8, 30, 0));
|Данные.Вставить(""author"", ""Yours Truly"");
|Данные.Вставить(""pages"", 450);
|Данные.Вставить(""slides"", Новый Массив());
|Данные[""slides""].Добавить(Новый Соответствие());
|Данные[""slides""][0].Вставить(""type"", ""all"");
|Данные[""slides""][0].Вставить(""title"", ""Wake up to WonderWidgets!"");
|Данные[""slides""].Добавить(Новый Соответствие());
|Данные[""slides""][1].Вставить(""type"", ""all"");
|Данные[""slides""][1].Вставить(""title"", ""Overview"");
|Данные[""slides""][1].Вставить(""items"", Новый Массив());
|Данные[""slides""][1][""items""].Добавить(""Why <em>WonderWidgets</em> are great"");
|Данные[""slides""][1][""items""].Добавить(""Who <em>buys</em> WonderWidgets"");
|
|ДополнительныеПараметры = Новый Структура();
|ДополнительныеПараметры.Вставить(""Заголовки"", Заголовки);
|ДополнительныеПараметры.Вставить(""Json"", Данные);
|
|Результат = КоннекторHTTP.Post(""http://example.com"", , ДополнительныеПараметры);";
ПроверитьКонвертациюБезОшибок(КонсольнаяКоманда, ПрограммныйКод);
КонецПроцедуры
&Тест
Процедура ТестДолжен_ПроверитьUserAgent() Экспорт