Merge pull request #26 from Stivo182/main

Поддержка опций --data-urlencode, --data-ascii
This commit is contained in:
Dmitry Ivanov
2024-11-12 22:35:50 +03:00
committed by GitHub
4 changed files with 187 additions and 41 deletions
@@ -4,8 +4,12 @@
Перем ИмяПользователя Экспорт; // Строка
Перем ПарольПользователя Экспорт; // Строка
Перем ОтправляемыеТекстовыеДанные Экспорт; // Массив из Строка
Перем ОтправляемыеТекстовыеДанныеИзФайла Экспорт; // Массив из Строка
Перем ОтправляемыеДвоичныеДанныеИзФайла Экспорт; // Массив из Строка
Перем Файлы Экспорт; // Массив из Структура:
// - ИмяФайла - Строка
// - ПрочитатьСодержимое - Булево
// - КодироватьСодержимое - Булево
// - УдалятьПереводыСтрок - Булево
// - Ключ - Строка
Перем ПередаватьОтправляемыеДанныеВСтрокуЗапроса Экспорт; // Булево
Перем ИмяФайлаСертификатаКлиента Экспорт; // Строка
Перем ПарольСертификатаКлиента Экспорт; // Строка
@@ -19,8 +23,7 @@
ИмяПользователя = "";
ПарольПользователя = "";
ОтправляемыеТекстовыеДанные = Новый Массив;
ОтправляемыеТекстовыеДанныеИзФайла = Новый Массив;
ОтправляемыеДвоичныеДанныеИзФайла = Новый Массив;
Файлы = Новый Массив;
ПередаватьОтправляемыеДанныеВСтрокуЗапроса = Ложь;
ИмяФайлаСертификатаКлиента = "";
ПарольСертификатаКлиента = "";
@@ -152,26 +152,43 @@
ИменаПеременныхОтправляемыхТекстовыхДанныхИзФайла.Очистить();
Если ОписаниеЗапроса.ПередаватьОтправляемыеДанныеВСтрокуЗапроса Тогда
МассивФайлов = Новый Массив;
ОбщегоНазначения.ДополнитьМассив(МассивФайлов, ОписаниеЗапроса.ОтправляемыеТекстовыеДанныеИзФайла);
ОбщегоНазначения.ДополнитьМассив(МассивФайлов, ОписаниеЗапроса.ОтправляемыеДвоичныеДанныеИзФайла);
Иначе
МассивФайлов = ОписаниеЗапроса.ОтправляемыеТекстовыеДанныеИзФайла;
КонецЕсли;
НомерФайла = 1;
Для Каждого ПутьКФайлу Из МассивФайлов Цикл
Для Каждого ОписаниеФайла Из ОписаниеЗапроса.Файлы Цикл
Если Не (ОписаниеФайла.ПрочитатьСодержимое
Или ОписаниеЗапроса.ПередаватьОтправляемыеДанныеВСтрокуЗапроса) Тогда
Продолжить;
КонецЕсли;
ИмяПараметра = "ТекстовыеДанныеИзФайла_" + Формат(НомерФайла, "ЧГ=");
ВывестиПустуюСтроку();
ВывестиСтроку(СтрШаблон(
"ТекстовыйДокумент = Новый ТекстовыйДокумент();
Шаблон = "ТекстовыйДокумент = Новый ТекстовыйДокумент();
|ТекстовыйДокумент.Прочитать(%2);
|%1 = ТекстовыйДокумент.ПолучитьТекст();
|%1 = ТекстовыйДокумент.ПолучитьТекст();";
Если ОписаниеФайла.УдалятьПереводыСтрок Тогда
Шаблон = Шаблон + "
|%1 = СтрЗаменить(%1, Символы.ПС, """");
|%1 = СтрЗаменить(%1, Символы.ВК, """");", ИмяПараметра, ОбернутьКавычками(ПутьКФайлу)));
|%1 = СтрЗаменить(%1, Символы.ВК, """");";
КонецЕсли;
Если ОписаниеФайла.КодироватьСодержимое Тогда
Шаблон = Шаблон + "
|%1 = КодироватьСтроку(%1, СпособКодированияСтроки.URLВКодировкеURL);";
КонецЕсли;
Если ЗначениеЗаполнено(ОписаниеФайла.Ключ) Тогда
Шаблон = Шаблон + "
|%1 = """ + ОписаниеФайла.Ключ + "="" + %1;";
КонецЕсли;
Текст = СтрШаблон(Шаблон,
ИмяПараметра,
ОбернутьКавычками(ОписаниеФайла.ИмяФайла));
ВывестиСтроку(Текст);
ИменаПеременныхОтправляемыхТекстовыхДанныхИзФайла.Добавить(ИмяПараметра);
@@ -296,12 +313,19 @@
КонецЕсли;
ЭтоПервыйФайл = Истина;
Для Каждого ПутьКФайлу Из ОписаниеЗапроса.ОтправляемыеДвоичныеДанныеИзФайла Цикл
Для Каждого ОписаниеФайла Из ОписаниеЗапроса.Файлы Цикл
Если ОписаниеФайла.ПрочитатьСодержимое Тогда
Продолжить;
КонецЕсли;
ВывестиСтроку(СтрШаблон("%1%2.УстановитьИмяФайлаТела(%3);",
?(ЭтоПервыйФайл, "", "// "),
ИмяПараметраHTTPЗапрос,
ОбернутьКавычками(ПутьКФайлу)));
ОбернутьКавычками(ОписаниеФайла.ИмяФайла)));
ЭтоПервыйФайл = Ложь;
КонецЦикла;
КонецПроцедуры
@@ -24,16 +24,17 @@
Приложение.Опция("H header", "", "HTTP заголовок").ТМассивСтрок();
Приложение.Опция("X request", "", "Метод запроса").ТСтрока();
Приложение.Опция("u user", "", "Пользователь и пароль").ТСтрока();
Приложение.Опция("d data", "", "Передаваемые данные по HTTP POST").ТМассивСтрок();
Приложение.Опция("d data data-ascii", "", "Передаваемые данные по HTTP POST").ТМассивСтрок();
Приложение.Опция("data-raw", "", "Передаваемые данные по HTTP POST без интерпретации символа @").ТМассивСтрок();
Приложение.Опция("data-binary", "", "Передаваемые двоичные данные по HTTP POST").ТМассивСтрок();
Приложение.Опция("data-urlencode", "", "Передаваемые данные по HTTP POST с URL кодированием").ТМассивСтрок();
Приложение.Опция("T upload-file", "", "Загружаемый файл").ТМассивСтрок();
Приложение.Опция("G get", Ложь, "Данные из опций -d и--data-... добавляются в URL как строка запроса").Флаговый();
Приложение.Опция("I head", Ложь, "Получение заголовков").Флаговый();
Приложение.Опция("E cert", "", "Сертификат клиента").ТМассивСтрок();
Приложение.Опция("ca-native", Ложь, "Использование сертификатов УЦ из системного хранилища сертификатов операционной системы").Флаговый();
Приложение.Опция("cacert", "", "Файл сертификатов удостоверяющих центров").ТМассивСтрок();
Приложение.УстановитьОсновноеДействие(ЭтотОбъект);
Если АргументыКоманд.Количество() = 0 Тогда
@@ -69,7 +70,7 @@
ПрочитатьURL(Команда);
ПрочитатьЗаголовки(Команда);
ПрочитатьПользователя(Команда);
ПрочитатьТекстовыеДанныеДляОтправки(Команда);
ПрочитатьДанныеДляОтправки(Команда);
ПрочитатьМетодЗапроса(Команда);
ПрочитатьПризнакПередачиОтправляемыхДанныхВСтрокуЗапроса(Команда);
ПрочитатьСертификатКлиента(Команда);
@@ -165,44 +166,111 @@
КонецЕсли
КонецПроцедуры
Процедура ПрочитатьТекстовыеДанныеДляОтправки(Команда)
// -d, --data
МассивДанных = Команда.ЗначениеОпции("d");
Процедура ПрочитатьДанныеДляОтправки(Команда)
ПрочитатьData(Команда);
ПрочитатьDataRaw(Команда);
ПрочитатьDataBinary(Команда);
ПрочитатьDataUrlencode(Команда);
ПрочитатьUploadFile(Команда);
КонецПроцедуры
Процедура ПрочитатьData(Команда)
МассивДанных = Команда.ЗначениеОпции("d"); // -d, --data
Для Каждого Данные Из МассивДанных Цикл
Если Лев(Данные, 1) = "@" Тогда
ПутьКФайлу = Сред(Данные, 2);
ОписаниеЗапроса.ОтправляемыеТекстовыеДанныеИзФайла.Добавить(ПутьКФайлу);
ИмяФайла = Сред(Данные, 2);
ПередаваемыеДанные = ОписаниеПередаваемогоФайла();
ПередаваемыеДанные.ИмяФайла = ИмяФайла;
ПередаваемыеДанные.ПрочитатьСодержимое = Истина;
ПередаваемыеДанные.УдалятьПереводыСтрок = Истина;
ОписаниеЗапроса.Файлы.Добавить(ПередаваемыеДанные);
Иначе
ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(Данные);
КонецЕсли;
КонецЦикла;
// --data-raw
КонецПроцедуры
Процедура ПрочитатьDataRaw(Команда)
МассивДанных = Команда.ЗначениеОпции("data-raw");
Для Каждого Данные Из МассивДанных Цикл
ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(Данные);
КонецЦикла;
// --data-binary
МассивДанных = Команда.ЗначениеОпции("data-binary");
Для Каждого ПутьКФайлу Из МассивДанных Цикл
Если Лев(ПутьКФайлу, 1) = "@" Тогда
ПутьКФайлу = Сред(ПутьКФайлу, 2);
КонецЕсли;
КонецПроцедуры
ОписаниеЗапроса.ОтправляемыеДвоичныеДанныеИзФайла.Добавить(ПутьКФайлу);
Процедура ПрочитатьDataBinary(Команда)
МассивДанных = Команда.ЗначениеОпции("data-binary");
Для Каждого ИмяФайла Из МассивДанных Цикл
Если Лев(ИмяФайла, 1) = "@" Тогда
ИмяФайла = Сред(ИмяФайла, 2);
КонецЕсли;
ПередаваемыеДанные = ОписаниеПередаваемогоФайла();
ПередаваемыеДанные.ИмяФайла = ИмяФайла;
ОписаниеЗапроса.Файлы.Добавить(ПередаваемыеДанные);
КонецЦикла;
// T, --upload-file
МассивДанных = Команда.ЗначениеОпции("T");
КонецПроцедуры
Процедура ПрочитатьDataUrlencode(Команда)
МассивДанных = Команда.ЗначениеОпции("data-urlencode");
Для Каждого Данные Из МассивДанных Цикл
ОписаниеЗапроса.ОтправляемыеДвоичныеДанныеИзФайла.Добавить(Данные);
ПозицияРавенства = СтрНайти(Данные, "=");
ПозицияСобачки = СтрНайти(Данные, "@");
Если ПозицияРавенства > 0 Тогда
Ключ = Сред(Данные, 1, ПозицияРавенства - 1);
Значение = Сред(Данные, ПозицияРавенства + 1);
ПередаваемыеДанные = КодироватьСтроку(Значение, СпособКодированияСтроки.URLВКодировкеURL);
Если ЗначениеЗаполнено(Ключ) Тогда
ПередаваемыеДанные = СтрШаблон("%1=%2", Ключ, ПередаваемыеДанные);
КонецЕсли;
ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыеДанные);
ИначеЕсли ПозицияСобачки > 0 Тогда
Ключ = Сред(Данные, 1, ПозицияСобачки - 1);
ИмяФайла = СокрЛП(Сред(Данные, ПозицияСобачки + 1));
ПередаваемыеДанные = ОписаниеПередаваемогоФайла();
ПередаваемыеДанные.Ключ = Ключ;
ПередаваемыеДанные.ИмяФайла = ИмяФайла;
ПередаваемыеДанные.ПрочитатьСодержимое = Истина;
ПередаваемыеДанные.КодироватьСодержимое = Истина;
ОписаниеЗапроса.Файлы.Добавить(ПередаваемыеДанные);
Иначе
ПередаваемыеДанные = КодироватьСтроку(Данные, СпособКодированияСтроки.URLВКодировкеURL);
ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыеДанные);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура ПрочитатьUploadFile(Команда)
МассивДанных = Команда.ЗначениеОпции("T"); // T, --upload-file
Для Каждого ИмяФайла Из МассивДанных Цикл
ОписаниеФайла = ОписаниеПередаваемогоФайла();
ОписаниеФайла.ИмяФайла = ИмяФайла;
ОписаниеЗапроса.Файлы.Добавить(ОписаниеФайла);
КонецЦикла;
КонецПроцедуры
@@ -261,7 +329,17 @@
КонецФункции
Функция ЕстьОпцииГруппыData(Команда)
Возврат ЕстьОпции(Команда, "d,data,data-raw,data-binary");
Возврат ЕстьОпции(Команда, "d,data,data-raw,data-binary,data-urlencode,data-ascii");
КонецФункции
Функция ОписаниеПередаваемогоФайла()
ОписаниеФайла = Новый Структура();
ОписаниеФайла.Вставить("ИмяФайла", """");
ОписаниеФайла.Вставить("ПрочитатьСодержимое", Ложь);
ОписаниеФайла.Вставить("КодироватьСодержимое", Ложь);
ОписаниеФайла.Вставить("УдалятьПереводыСтрок", Ложь);
ОписаниеФайла.Вставить("Ключ", "");
Возврат ОписаниеФайла;
КонецФункции
#КонецОбласти
@@ -13,6 +13,7 @@
СписокТестов.Добавить("ТестДолжен_ПроверитьПередачуМетода");
СписокТестов.Добавить("ТестДолжен_ПроверитьПередачуПользователя");
СписокТестов.Добавить("ТестДолжен_ПроверитьПередачуТекстовыхДанных");
СписокТестов.Добавить("ТестДолжен_ПроверитьПередачуТекстовыхДанныхСКодированием");
СписокТестов.Добавить("ТестДолжен_ПроверитьПередачуДвоичныхДанныхDataBinary");
СписокТестов.Добавить("ТестДолжен_ПроверитьПередачуДвоичныхДанныхUploadFile");
СписокТестов.Добавить("ТестДолжен_ПроверитьНеизменностьПереданногоЗаголовкаContentType");
@@ -98,7 +99,7 @@
КонсольнаяКоманда = "curl 'https://example.com' \
| -d param1=value1 \
| -d 'парам2=значение2' \
| --data-ascii 'парам2=значение2' \
| --data 'param3=value3' \
| --data @path-to-file1 \
| --data @path-to-file2 \
@@ -207,6 +208,46 @@
КонецПроцедуры
Процедура ТестДолжен_ПроверитьПередачуТекстовыхДанныхСКодированием() Экспорт
КонсольнаяКоманда = "curl 'http://example.com' \
| --data-urlencode name=val \
| --data-urlencode =encodethis \
| --data-urlencode name@file \
| --data-urlencode @fileonly";
ПрограммныйКод = "Заголовки = Новый Соответствие();
|Заголовки.Вставить(""Content-Type"", ""application/x-www-form-urlencoded"");
|
|Соединение = Новый HTTPСоединение(""example.com"", 80);
|
|ТекстовыйДокумент = Новый ТекстовыйДокумент();
|ТекстовыйДокумент.Прочитать(""file"");
|ТекстовыеДанныеИзФайла_1 = ТекстовыйДокумент.ПолучитьТекст();
|ТекстовыеДанныеИзФайла_1 = КодироватьСтроку(ТекстовыеДанныеИзФайла_1, СпособКодированияСтроки.URLВКодировкеURL);
|ТекстовыеДанныеИзФайла_1 = ""name="" + ТекстовыеДанныеИзФайла_1;
|
|ТекстовыйДокумент = Новый ТекстовыйДокумент();
|ТекстовыйДокумент.Прочитать(""fileonly"");
|ТекстовыеДанныеИзФайла_2 = ТекстовыйДокумент.ПолучитьТекст();
|ТекстовыеДанныеИзФайла_2 = КодироватьСтроку(ТекстовыеДанныеИзФайла_2, СпособКодированияСтроки.URLВКодировкеURL);
|
|HTTPЗапрос = Новый HTTPЗапрос(""/"", Заголовки);
|
|ТелоЗапроса = ""name=val&encodethis""
| + ""&"" + ТекстовыеДанныеИзФайла_1
| + ""&"" + ТекстовыеДанныеИзФайла_2;
|
|HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса);
|HTTPОтвет = Соединение.ВызватьHTTPМетод(""POST"", HTTPЗапрос);";
КонвертерКомандыCURL = Новый КонвертерКомандыCURL();
Результат = КонвертерКомандыCURL.Конвертировать(КонсольнаяКоманда, Новый ГенераторПрограммногоКода1С());
Ожидаем.Что(Результат).Равно(ПрограммныйКод);
КонецПроцедуры
Процедура ТестДолжен_ПроверитьМножественноеИспользованиеUrl() Экспорт
КонсольнаяКоманда = "curl https://example1.com \