From b28e03cc2d728d75df03d4c22184a81c0e6b808f Mon Sep 17 00:00:00 2001 From: Dmitry Ivanov Date: Mon, 20 Jan 2025 18:47:40 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80?= =?UTF-8?q?=D0=B6=D0=BA=D0=B8=20=D0=BE=D0=BF=D1=86=D0=B8=D0=B9=20-F,=20--f?= =?UTF-8?q?orm,=20--form-string=20=D0=B4=D0=BB=D1=8F=20=D0=BA=D0=BE=D0=BD?= =?UTF-8?q?=D0=BD=D0=B5=D0=BA=D1=82=D0=BE=D1=80=D0=B0=20(#38)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...0\232\320\276\320\264\320\2601\320\241.os" | 30 ++- ...65\320\272\321\202\320\276\321\200HTTP.os" | 230 ++++++++++++++-- ...74\320\260\320\275\320\264\321\213CURL.os" | 254 ++++++++++++++---- ...20\277\321\200\320\276\321\201\320\260.os" | 6 +- ...36\320\277\321\206\320\270\320\270Form.os" | 165 ++++++++++++ ...20\242\320\265\320\272\321\201\321\202.os" | 49 +++- ...20\271\320\244\320\260\320\271\320\273.os" | 43 ++- ...20\276\320\232\320\276\320\264\320\260.os" | 101 ++++--- ...\320\276\320\264\320\2601\320\241_test.os" | 8 +- ...0\272\321\202\320\276\321\200HTTP_test.os" | 241 ++++++++++++++++- ...0\260\320\275\320\264\321\213CURL_test.os" | 30 +++ 11 files changed, 1020 insertions(+), 137 deletions(-) create mode 100644 "src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\321\201\320\265\321\200\320\227\320\275\320\260\321\207\320\265\320\275\320\270\321\217\320\236\320\277\321\206\320\270\320\270Form.os" diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\2601\320\241.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\2601\320\241.os" index 7229ec6..9056f68 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\2601\320\241.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\2601\320\241.os" @@ -166,6 +166,10 @@ Процедура ДобавитьЧтениеФайлов() + Если ОписаниеЗапроса.ОтправлятьКакMultipartFormData Тогда + Возврат; + КонецЕсли; + ТребуетсяЧтениеФайловТелаЗапроса = Не МетодУстановкиТелаЗапроса = "ИзФайла"; ФайлыДляЧтения = Новый Массив(); @@ -197,6 +201,10 @@ Процедура ДобавитьДанныеЗапроса() + Если ОписаниеЗапроса.ОтправлятьКакMultipartFormData Тогда + Возврат; + КонецЕсли; + ТелоЗапросаСтрока = ""; ТелоЗапроса = КоллекцияПрограммногоКода.СборкаДанныхЗапросаВСтроку( НазначенияПередаваемыхДанных.ТелоЗапроса, @@ -344,6 +352,10 @@ Процедура ДобавитьПоследовательнуюОтправкуФайлов(ОписаниеРесурса) + Если ОписаниеЗапроса.ОтправлятьКакMultipartFormData Тогда + Возврат; + КонецЕсли; + ДлинаИмениФайлаВКомментарии = 100; ВсеФайлы = Новый Массив(); @@ -368,7 +380,7 @@ НомерФайла = НомерФайла + 1; Если КоличествоФайлов > 1 Тогда - ИмяФайла = Лев(ПередаваемыйФайл.ИмяФайла, ДлинаИмениФайлаВКомментарии); + ИмяФайла = Лев(ПередаваемыйФайл.ПолноеИмяФайла, ДлинаИмениФайлаВКомментарии); Конструктор .ДобавитьПустуюСтроку() .ДобавитьКомментарий("Передача файла %1. %2", НомерФайла, ИмяФайла); @@ -376,14 +388,14 @@ СтруктураURL = Новый ПарсерURL(ОписаниеРесурса.URL); Если ПередаваемыйФайл.ДобавлятьИмяФайлаКURL Тогда - СтруктураURL.Путь = ОбщегоНазначения.ДополнитьИменемФайлаПутьURL(ПередаваемыйФайл.ИмяФайла, СтруктураURL.Путь); + СтруктураURL.Путь = ОбщегоНазначения.ДополнитьИменемФайлаПутьURL(ПередаваемыйФайл.ПолноеИмяФайла, СтруктураURL.Путь); КонецЕсли; ДобавитьHTTPЗапрос(СтруктураURL); Конструктор.ДобавитьСтроку("%1.УстановитьИмяФайлаТела(%2);", ИмяПараметраHTTPЗапрос, - Конструктор.ПараметрВСтроку(ПередаваемыйФайл.ИмяФайла)); + Конструктор.ПараметрВСтроку(ПередаваемыйФайл.ПолноеИмяФайла)); ДобавитьВызовHTTPМетода(ОписаниеРесурса); @@ -503,7 +515,7 @@ Конструктор.ДобавитьСтроку("%1%2.УстановитьИмяФайлаТела(%3);", ?(ЭтоПервыйФайл, "", "// "), ИмяПараметраHTTPЗапрос, - Конструктор.ПараметрВСтроку(ПередаваемыйФайл.ИмяФайла)); + Конструктор.ПараметрВСтроку(ПередаваемыйФайл.ПолноеИмяФайла)); ЭтоПервыйФайл = Ложь; @@ -589,13 +601,13 @@ КонецЕсли; Если ПередаваемыйФайл.ДобавлятьИмяФайлаКURL Тогда - АдресРесурса = ОбщегоНазначения.ДополнитьИменемФайлаПутьURL(ПередаваемыйФайл.ИмяФайла, СтруктураURL.Путь); + АдресРесурса = ОбщегоНазначения.ДополнитьИменемФайлаПутьURL(ПередаваемыйФайл.ПолноеИмяФайла, СтруктураURL.Путь); Иначе АдресРесурса = СтруктураURL.Путь; КонецЕсли; ПараметрыФункции = Новый Массив; - ПараметрыФункции.Добавить(Конструктор.ПараметрВСтроку(ПередаваемыйФайл.ИмяФайла)); + ПараметрыФункции.Добавить(Конструктор.ПараметрВСтроку(ПередаваемыйФайл.ПолноеИмяФайла)); ПараметрыФункции.Добавить(Конструктор.ПараметрВСтроку(АдресРесурса)); Конструктор.ДобавитьСтроку("%1.Записать(%2);", @@ -667,8 +679,10 @@ Прервать; КонецЕсли; КонецЦикла; - - Если КоличествоФайлов > 1 Или ЕстьТекстовоеТелоЗапроса Тогда + + Если ОписаниеЗапроса.ОтправлятьКакMultipartFormData Тогда + МетодУстановкиТелаЗапроса = ""; + ИначеЕсли КоличествоФайлов > 1 Или ЕстьТекстовоеТелоЗапроса Тогда МетодУстановкиТелаЗапроса = "ИзСтроки"; ИначеЕсли КоличествоФайлов = 1 И Не ЕстьТекстовоеТелоЗапроса Тогда МетодУстановкиТелаЗапроса = "ИзФайла"; diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\260\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200HTTP.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\260\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200HTTP.os" index e6dd654..e08c593 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\260\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200HTTP.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\260\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200HTTP.os" @@ -18,6 +18,7 @@ Перем ИмяПараметраПрокси; // Строка Перем ИмяПараметраДополнительныеПараметры; // Строка Перем ИмяПараметраДанныеЗапроса; // Строка +Перем ИмяПараметраФайлы; // Строка Перем ИмяПараметраПараметрыЗапроса; // Строка Перем ИмяПараметраURL; // Строка @@ -52,6 +53,7 @@ ДобавитьПрокси(); ДобавитьЧтениеФайлов(); ДобавитьДанныеЗапроса(); + ДобавитьФайлы(); ДобавитьПараметрыЗапроса(); ДобавитьЗапросы(); @@ -130,6 +132,7 @@ ИмяПараметраПрокси = "Прокси"; ИмяПараметраДополнительныеПараметры = "ДополнительныеПараметры"; ИмяПараметраДанныеЗапроса = "Данные"; + ИмяПараметраФайлы = "Файлы"; ИмяПараметраПараметрыЗапроса = "ПараметрыЗапроса"; ИмяПараметраURL = "URL"; @@ -202,8 +205,12 @@ Если ВозможнаПередачаДанныхЧерезСоответствие(НазначениеДанных) Тогда - ДобавитьТекстовыеДанныеЗапросаЧерезСоответствие(НазначениеДанных, ИмяПараметраДанныеЗапроса); - ДанныеЗапросаСборка = ИмяПараметраДанныеЗапроса; + ДобавитьДанныеЗапросаЧерезСоответствие(НазначениеДанных, ИмяПараметраДанныеЗапроса, ДанныеЗапросаСборка); + + ИначеЕсли ОписаниеЗапроса.ОтправлятьКакMultipartFormData Тогда + + ТекстОшибки = "Данные формы невозможно передать в структурированный объект для отправки в КоннекторHTTP"; + ИсходящиеОшибки.Добавить(ОбщегоНазначения.НоваяОшибка(ТекстОшибки)); Иначе @@ -222,17 +229,29 @@ Возврат; КонецЕсли; - ДобавитьТекстовыеДанныеЗапросаЧерезСоответствие(НазначениеДанных, ИмяПараметраПараметрыЗапроса); + ДобавитьДанныеЗапросаЧерезСоответствие(НазначениеДанных, ИмяПараметраПараметрыЗапроса); КонецПроцедуры -Процедура ДобавитьТекстовыеДанныеЗапросаЧерезСоответствие(Назначение, ИмяПараметра) +Процедура ДобавитьДанныеЗапросаЧерезСоответствие(Назначение, ИмяПараметра, РезультатСборка = "") - РазделительКлючаИЗначения = "="; + КонструкторДанных = Новый КонструкторПрограммногоКода(); - Конструктор - .ДобавитьПустуюСтроку() - .ДобавитьСтроку("%1 = Новый Соответствие();", ИмяПараметра); + ДобавитьДанныеЗапросаИзТекстовыхДанныхЧерезСоответствие(КонструкторДанных, Назначение, ИмяПараметра); + ДобавитьДанныеЗапросаИзПрочитанныхФайловЧерезСоответствие(КонструкторДанных, Назначение, ИмяПараметра); + + Если Не КонструкторДанных.Пустой() Тогда + Конструктор + .ДобавитьПустуюСтроку() + .ДобавитьСтроку("%1 = Новый Соответствие();", ИмяПараметра) + .ДобавитьСтроку(КонструкторДанных.ПолучитьРезультат()); + + РезультатСборка = ИмяПараметра; + КонецЕсли; + +КонецПроцедуры + +Процедура ДобавитьДанныеЗапросаИзТекстовыхДанныхЧерезСоответствие(КонструкторДанных, Назначение, ИмяПараметра) Для Каждого ПередаваемыйТекст Из ОписаниеЗапроса.ОтправляемыеТекстовыеДанные Цикл @@ -240,21 +259,19 @@ Продолжить; КонецЕсли; - ИндексРазделителя = СтрНайти(ПередаваемыйТекст.Значение, РазделительКлючаИЗначения); - - Если ИндексРазделителя > 0 Тогда - Ключ = Сред(ПередаваемыйТекст.Значение, 1, ИндексРазделителя - 1); - Значение = Сред(ПередаваемыйТекст.Значение, ИндексРазделителя + 1); + Если ЗначениеЗаполнено(ПередаваемыйТекст.ИмяПоля) Тогда + Ключ = ПередаваемыйТекст.ИмяПоля; + Значение = ПередаваемыйТекст.Значение; Иначе Ключ = ПередаваемыйТекст.Значение; - Значение = Неопределено; + Значение = ""; КонецЕсли; ПараметрыМетода = Новый Массив(); ПараметрыМетода.Добавить(Конструктор.ПараметрВСтроку(Ключ)); ПараметрыМетода.Добавить(Конструктор.НеобязательныйПараметрВСтроку(Значение)); - Конструктор.ДобавитьСтроку("%1.Вставить(%2);", + КонструкторДанных.ДобавитьСтроку("%1.Вставить(%2);", ИмяПараметра, Конструктор.ПараметрыФункцииВСтроку(ПараметрыМетода)); @@ -262,6 +279,76 @@ КонецПроцедуры +Процедура ДобавитьДанныеЗапросаИзПрочитанныхФайловЧерезСоответствие(КонструкторДанных, Назначение, ИмяПараметра) + + ЗначенияПолей = Новый Соответствие(); + Для Каждого ПрочитанныйФайл Из ПрочитанныеФайлы Цикл + + ПередаваемыйФайл = ПрочитанныйФайл.ПередаваемыйФайл; + + Если Не ПередаваемыйФайл.Назначение = Назначение + Или Не ПередаваемыйФайл.ПрочитатьСодержимое Тогда + Продолжить; + КонецЕсли; + + ИмяПоля = ПередаваемыйФайл.ИмяПоля; + Если ЗначенияПолей[ИмяПоля] = Неопределено Тогда + + ЗначенияПолей.Вставить(ИмяПоля, ПрочитанныйФайл.ИмяПеременной); + + ИначеЕсли ТипЗнч(ЗначенияПолей[ИмяПоля]) = Тип("Массив") Тогда + + ЗначенияПолей[ИмяПоля].Добавить(ПрочитанныйФайл.ИмяПеременной); + + Иначе + + МассивЗначений = Новый Массив(); + МассивЗначений.Добавить(ЗначенияПолей[ИмяПоля]); + МассивЗначений.Добавить(ПрочитанныйФайл.ИмяПеременной); + + ЗначенияПолей.Вставить(ИмяПоля, МассивЗначений); + + КонецЕсли; + + КонецЦикла; + + Для Каждого Данные Из ЗначенияПолей Цикл + + ИмяПоля = Данные.Ключ; + + Если ТипЗнч(Данные.Значение) = Тип("Массив") Тогда + + МассивПеременныхФайлов = Данные.Значение; + + КонструкторДанных.ДобавитьСтроку("%1.Вставить(%2, Новый Массив());", + ИмяПараметра, + КонструкторДанных.ПараметрВСтроку(ИмяПоля)); + + Для Каждого ИмяПеременнойФайла Из МассивПеременныхФайлов Цикл + КонструкторДанных.ДобавитьСтроку("%1[%2].Добавить(%3));", + ИмяПараметра, + КонструкторДанных.ПараметрВСтроку(ИмяПоля), + КонструкторДанных.ПараметрВСтроку(ИмяПеременнойФайла)); + КонецЦикла; + + Иначе + + ИмяПеременнойФайла = Данные.Значение; + + ПараметрыМетода = Новый Массив(); + ПараметрыМетода.Добавить(КонструкторДанных.ПараметрВСтроку(ИмяПоля)); + ПараметрыМетода.Добавить(ИмяПеременнойФайла); + + КонструкторДанных.ДобавитьСтроку("%1.Вставить(%2);", + ИмяПараметра, + КонструкторДанных.ПараметрыФункцииВСтроку(ПараметрыМетода)); + + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + Процедура ДобавитьТекстовыеДанныеЗапросаЧерезСтроку(НазначениеДанных, ИмяПараметра, РезультатСборка) Сборка = КоллекцияПрограммногоКода.СборкаДанныхЗапросаВСтроку( @@ -283,6 +370,71 @@ КонецПроцедуры +Процедура ДобавитьФайлы() + + Если Не ОписаниеЗапроса.ОтправлятьКакMultipartFormData Тогда + Возврат; + КонецЕсли; + + Назначение = НазначенияПередаваемыхДанных.ТелоЗапроса; + КонструкторФайлов = Новый КонструкторПрограммногоКода(); + + Для Каждого ПередаваемыйФайл Из ОписаниеЗапроса.Файлы Цикл + + Если Не ПередаваемыйФайл.Назначение = Назначение + Или ПередаваемыйФайл.ПрочитатьСодержимое Тогда + Продолжить; + КонецЕсли; + + КонструкторФайлов + .ДобавитьПустуюСтроку() + .ДобавитьСтроку("Файл = Новый Структура();") + .ДобавитьСтроку("Файл.Вставить(""Имя"", %1);", КонструкторФайлов.ПараметрВСтроку(ПередаваемыйФайл.ИмяПоля)); + + Если ЗначениеЗаполнено(ПередаваемыйФайл.ИмяФайла) Тогда + КонструкторФайлов.ДобавитьСтроку("Файл.Вставить(""ИмяФайла"", %1);", + КонструкторФайлов.ПараметрВСтроку(ПередаваемыйФайл.ИмяФайла)); + КонецЕсли; + + КонструкторФайлов.ДобавитьСтроку( + "Файл.Вставить(""Данные"", Новый ДвоичныеДанные(%1));", + КонструкторФайлов.ПараметрВСтроку(ПередаваемыйФайл.ПолноеИмяФайла)); + + Если ЗначениеЗаполнено(ПередаваемыйФайл.ТипMIME) Тогда + КонструкторФайлов.ДобавитьСтроку( + "Файл.Вставить(""Тип"", %1);", + КонструкторФайлов.ПараметрВСтроку(ПередаваемыйФайл.ТипMIME)); + КонецЕсли; + + Если ЗначениеЗаполнено(ПередаваемыйФайл.Заголовки) Тогда + КонструкторФайлов.ДобавитьСтроку("Файл.Вставить(""Заголовки"", Новый Соответствие());"); + + Для Каждого Заголовок Из ПередаваемыйФайл.Заголовки Цикл + ПараметрыМетода = Новый Массив(); + ПараметрыМетода.Добавить(КонструкторФайлов.ПараметрВСтроку(Заголовок.Ключ)); + ПараметрыМетода.Добавить(КонструкторФайлов.ПараметрВСтроку(Заголовок.Значение)); + + КонструкторФайлов.ДобавитьСтроку( + "Файл.Заголовки.Вставить(%1);", + КонструкторФайлов.ПараметрыФункцииВСтроку(ПараметрыМетода)); + КонецЦикла; + КонецЕсли; + + КонструкторФайлов.ДобавитьСтроку("Файлы.Добавить(Файл);"); + + КонецЦикла; + + Если Не КонструкторФайлов.Пустой() Тогда + Состояние.ЕстьФайлыMultipart = Истина; + + Конструктор + .ДобавитьПустуюСтроку() + .ДобавитьСтроку("%1 = Новый Массив();", ИмяПараметраФайлы) + .ДобавитьСтроку(КонструкторФайлов.ПолучитьРезультат()); + КонецЕсли; + +КонецПроцедуры + Процедура ДобавитьПоследовательнуюОтправкуДвоичныхДанныхРесурса(ОписаниеРесурса) ДлинаИмениФайлаВКомментарии = 100; @@ -309,7 +461,7 @@ НомерФайла = НомерФайла + 1; Если КоличествоФайлов > 1 Тогда - ИмяФайла = Лев(ПередаваемыйФайл.ИмяФайла, ДлинаИмениФайлаВКомментарии); + ИмяФайла = Лев(ПередаваемыйФайл.ПолноеИмяФайла, ДлинаИмениФайлаВКомментарии); Конструктор .ДобавитьПустуюСтроку() .ДобавитьКомментарий("Передача файла %1. %2", НомерФайла, ИмяФайла); @@ -317,12 +469,12 @@ СтруктураURL = Новый ПарсерURL(ОписаниеРесурса.URL); Если ПередаваемыйФайл.ДобавлятьИмяФайлаКURL Тогда - СтруктураURL.Путь = ОбщегоНазначения.ДополнитьИменемФайлаПутьURL(ПередаваемыйФайл.ИмяФайла, СтруктураURL.Путь); + СтруктураURL.Путь = ОбщегоНазначения.ДополнитьИменемФайлаПутьURL(ПередаваемыйФайл.ПолноеИмяФайла, СтруктураURL.Путь); КонецЕсли; Конструктор.ДобавитьСтроку("%1 = Новый ДвоичныеДанные(%2);", ИмяПараметраДанныеЗапроса, - Конструктор.ПараметрВСтроку(ПередаваемыйФайл.ИмяФайла)); + Конструктор.ПараметрВСтроку(ПередаваемыйФайл.ПолноеИмяФайла)); ДобавитьВызовМетода(ОписаниеРесурса, СтруктураURL, ИмяПараметраДанныеЗапроса); @@ -525,6 +677,7 @@ ДобавитьПовторныеПопыткиВДополнительныеПараметры(КонструкторДопПараметров); ДобавитьПараметрыЗапросаВДополнительныеПараметры(КонструкторДопПараметров, ОписаниеРесурса); ДобавитьДанныеВДополнительныеПараметры(КонструкторДопПараметров, ОписаниеРесурса, ДанныеЗапроса); + ДобавитьФайлыВДополнительныеПараметры(КонструкторДопПараметров); Если Не КонструкторДопПараметров.Пустой() Тогда Состояние.ЕстьДополнительныеПараметры = Истина; @@ -639,6 +792,16 @@ КонецПроцедуры +Процедура ДобавитьФайлыВДополнительныеПараметры(КонструкторДопПараметров) + + Если Состояние.ЕстьФайлыMultipart Тогда + КонструкторДопПараметров.ДобавитьСтроку("%1.Вставить(""Файлы"", %2);", + ИмяПараметраДополнительныеПараметры, + ИмяПараметраФайлы); + КонецЕсли; + +КонецПроцедуры + Процедура ДобавитьРазрешениеПеренаправленийВДополнительныеПараметры(КонструкторДопПараметров) Если ОписаниеЗапроса.ЗапретитьПеренаправление Тогда @@ -674,25 +837,45 @@ Функция ВозможнаПередачаДанныхЧерезСоответствие(Назначение) - РазделительКлючаИЗначения = "="; + ЭтоДанныеMultipart = ОписаниеЗапроса.ОтправлятьКакMultipartFormData + И Назначение = НазначенияПередаваемыхДанных.ТелоЗапроса; Для Каждого ПередаваемыйТекст Из ОписаниеЗапроса.ОтправляемыеТекстовыеДанные Цикл + Если Не ПередаваемыйТекст.Назначение = Назначение Тогда Продолжить; КонецЕсли; + ОтсутствуетИмяПоля = ПередаваемыйТекст.ИмяПоля = ""; + Если ОтсутствуетИмяПоля Тогда + Возврат Ложь; + КонецЕсли; + РазделительОтличенОтАмперсанда = Не ПередаваемыйТекст.РазделительТелаЗапроса = "&"; - ОтсутствуетИмяПараметра = Лев(ПередаваемыйТекст.Значение, 1) = РазделительКлючаИЗначения; - - Если РазделительОтличенОтАмперсанда Или ОтсутствуетИмяПараметра Тогда + Если РазделительОтличенОтАмперсанда И Не ЭтоДанныеMultipart Тогда Возврат Ложь; КонецЕсли; + КонецЦикла; Для Каждого ПрочитанныйФайл Из ПрочитанныеФайлы Цикл - Если ПрочитанныйФайл.ПередаваемыйФайл.Назначение = Назначение Тогда + + ПередаваемыйФайл = ПрочитанныйФайл.ПередаваемыйФайл; + + Если Не ПередаваемыйФайл.Назначение = Назначение Тогда + Продолжить; + КонецЕсли; + + ОтсутствуетИмяПоля = ПередаваемыйФайл.ИмяПоля = ""; + Если ОтсутствуетИмяПоля Тогда + Возврат Ложь; + КонецЕсли; + + РазделительОтличенОтАмперсанда = Не ПередаваемыйФайл.РазделительТелаЗапроса = "&"; + Если РазделительОтличенОтАмперсанда И Не ЭтоДанныеMultipart Тогда Возврат Ложь; КонецЕсли; + КонецЦикла; Возврат Истина; @@ -762,6 +945,7 @@ Результат.Вставить("ПереданоТелоЗапроса", ОписаниеЗапроса.ПереданоТелоЗапроса()); Результат.Вставить("ПереданаСтрокаЗапроса", ОписаниеЗапроса.ПереданаСтрокаЗапроса()); Результат.Вставить("ЕстьЗаголовки", Ложь); + Результат.Вставить("ЕстьФайлыMultipart", Ложь); Результат.Вставить("ЕстьДополнительныеПараметры", Ложь); Результат.Вставить("ВызванМетодПоТекущемуURL", Ложь); Результат.Вставить("ТипАутентификации", ПолучитьТипАутентификации()); diff --git "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\262\320\265\321\200\321\202\320\265\321\200\320\232\320\276\320\274\320\260\320\275\320\264\321\213CURL.os" "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\262\320\265\321\200\321\202\320\265\321\200\320\232\320\276\320\274\320\260\320\275\320\264\321\213CURL.os" index 7f1fa5e..ca0cd2a 100644 --- "a/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\262\320\265\321\200\321\202\320\265\321\200\320\232\320\276\320\274\320\260\320\275\320\264\321\213CURL.os" +++ "b/src/core/\320\232\320\273\320\260\321\201\321\201\321\213/\320\232\320\276\320\275\320\262\320\265\321\200\321\202\320\265\321\200\320\232\320\276\320\274\320\260\320\275\320\264\321\213CURL.os" @@ -143,7 +143,7 @@ Процедура ПрочитатьМетодЗапроса(Команда) - ЕстьДанныеPOST = (ЕстьОпцииГруппыData(Команда) ИЛИ ЕстьОпции(команда, "json")); + ЕстьДанныеPOST = ЕстьОпцииГруппыData(Команда) Или ЕстьОпцииГруппыForm(Команда); ЕстьМетодGET = ЗначениеОпции(Команда, "get") = Истина; ЕстьМетодPOST = ЗначениеОпции(Команда, "get") = Ложь И ЕстьДанныеPOST; @@ -408,12 +408,16 @@ Процедура ПрочитатьДанныеДляОтправки(Команда) + ПроверитьДанные(Команда); + ПрочитатьData(Команда); ПрочитатьDataRaw(Команда); ПрочитатьDataBinary(Команда); ПрочитатьDataUrlencode(Команда); ПрочитатьUploadFile(Команда); ПрочитатьОпициюJson(Команда); + ПрочитатьForm(Команда); + ПрочитатьFormString(Команда); КонецПроцедуры @@ -424,7 +428,10 @@ Для Каждого Данные Из МассивДанных Цикл + ПозицияРавенства = СтрНайти(Данные, "="); + Если Лев(Данные, 1) = "@" Тогда + ИмяФайла = Сред(Данные, 2); ПередаваемыйФайл = Новый ПередаваемыйФайл(ИмяФайла, Назначение); @@ -432,9 +439,22 @@ ПередаваемыйФайл.УдалятьПереносыСтрок = Истина; ОписаниеЗапроса.Файлы.Добавить(ПередаваемыйФайл); + + ИначеЕсли ПозицияРавенства > 0 Тогда + + ИмяПоля = Сред(Данные, 1, ПозицияРавенства - 1); + Значение = Сред(Данные, ПозицияРавенства + 1); + + ПередаваемыйТекст = Новый ПередаваемыйТекст(Значение, Назначение); + ПередаваемыйТекст.ИмяПоля = ИмяПоля; + + ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйТекст); + Иначе + ПередаваемыйТекст = Новый ПередаваемыйТекст(Данные, Назначение); ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйТекст); + КонецЕсли; КонецЦикла; @@ -478,34 +498,49 @@ Назначение = НазначениеПередаваемыхДанных(Команда); Для Каждого Данные Из МассивДанных Цикл + ПозицияРавенства = СтрНайти(Данные, "="); ПозицияСобачки = СтрНайти(Данные, "@"); + Если ПозицияРавенства > 0 Тогда - Ключ = Сред(Данные, 1, ПозицияРавенства - 1); + + ИмяПоля = Сред(Данные, 1, ПозицияРавенства - 1); Значение = Сред(Данные, ПозицияРавенства + 1); - - Значение = КодироватьСтроку(Значение, СпособКодированияСтроки.URLВКодировкеURL); - Если ЗначениеЗаполнено(Ключ) Тогда - Значение = СтрШаблон("%1=%2", Ключ, Значение); + + ПередаваемыйТекст = Новый ПередаваемыйТекст(Значение, Назначение); + ПередаваемыйТекст.КодироватьЗначение = Истина; + + Если Не ПустаяСтрока(ИмяПоля) Тогда + ПередаваемыйТекст.ИмяПоля = ИмяПоля; КонецЕсли; - ПередаваемыйТекст = Новый ПередаваемыйТекст(Значение, Назначение); ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйТекст); + ИначеЕсли ПозицияСобачки > 0 Тогда - Ключ = Сред(Данные, 1, ПозицияСобачки - 1); + + ИмяПоля = Сред(Данные, 1, ПозицияСобачки - 1); ИмяФайла = СокрЛП(Сред(Данные, ПозицияСобачки + 1)); ПередаваемыйФайл = Новый ПередаваемыйФайл(ИмяФайла, Назначение); - ПередаваемыйФайл.Ключ = Ключ; + ПередаваемыйФайл.ИмяПоля = ИмяПоля; ПередаваемыйФайл.ПрочитатьСодержимое = Истина; ПередаваемыйФайл.КодироватьСодержимое = Истина; + + Если Не ПустаяСтрока(ИмяПоля) Тогда + ПередаваемыйФайл.ИмяПоля = ИмяПоля; + КонецЕсли; ОписаниеЗапроса.Файлы.Добавить(ПередаваемыйФайл); + Иначе - Значение = КодироватьСтроку(Данные, СпособКодированияСтроки.URLВКодировкеURL); - ПередаваемыйТекст = Новый ПередаваемыйТекст(Значение, Назначение); + + ПередаваемыйТекст = Новый ПередаваемыйТекст(Данные, Назначение); + ПередаваемыйТекст.КодироватьЗначение = Истина; + ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйТекст); + КонецЕсли; + КонецЦикла; КонецПроцедуры @@ -579,6 +614,92 @@ КонецПроцедуры +Процедура ПрочитатьForm(Команда) + + МассивДанных = ЗначениеОпции(Команда, "form"); // -f, --Form + Назначение = НазначенияПередаваемыхДанных.ТелоЗапроса; + + Если МассивДанных.Количество() > 0 Тогда + ОписаниеЗапроса.ОтправлятьКакMultipartFormData = Истина; + КонецЕсли; + + Для Каждого Данные Из МассивДанных Цикл + + Парсер = Новый ПарсерЗначенияОпцииForm(); + ДанныеПоляФормы = Парсер.Распарсить(Данные); + + Если ДанныеПоляФормы.Значение = Неопределено Тогда + ТекстОшибки = СтрШаблон("В опции -F (--form) некорректно указано значение: '%1'", Данные); + ИсходящиеОшибки.Добавить(ОбщегоНазначения.НоваяКритичнаяОшибка(ТекстОшибки)); + Возврат; + КонецЕсли; + + ПервыйСимвол = Лев(ДанныеПоляФормы.Значение, 1); + ЭтоФайл = ПервыйСимвол = "@" Или ПервыйСимвол = "<"; + + Если ЭтоФайл Тогда + ПолноеИмяФайла = Сред(ДанныеПоляФормы.Значение, 2); + + ПередаваемыйЭлемент = Новый ПередаваемыйФайл(ПолноеИмяФайла, Назначение); + ПередаваемыйЭлемент.ПрочитатьСодержимое = ПервыйСимвол = "<"; + ОписаниеЗапроса.Файлы.Добавить(ПередаваемыйЭлемент); + + ИмяФайла = ДанныеПоляФормы.Параметры["filename"]; + Если Не ИмяФайла = Неопределено Тогда + ПередаваемыйЭлемент.ИмяФайла = ИмяФайла; + КонецЕсли; + Иначе + ПередаваемыйЭлемент = Новый ПередаваемыйТекст(ДанныеПоляФормы.Значение, Назначение); + ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйЭлемент); + КонецЕсли; + + ПередаваемыйЭлемент.ИмяПоля = ДанныеПоляФормы.ИмяПоля; + ПередаваемыйЭлемент.Заголовки = ДанныеПоляФормы.Параметры["headers"]; + + ТипMIME = ДанныеПоляФормы.Параметры["type"]; + Если Не ТипMIME = Неопределено Тогда + ПередаваемыйЭлемент.ТипMIME = ТипMIME; + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Процедура ПрочитатьFormString(Команда) + + МассивДанных = ЗначениеОпции(Команда, "form-string"); + Назначение = НазначенияПередаваемыхДанных.ТелоЗапроса; + + Если МассивДанных.Количество() > 0 Тогда + ОписаниеЗапроса.ОтправлятьКакMultipartFormData = Истина; + КонецЕсли; + + Для Каждого Данные Из МассивДанных Цикл + + ПозицияРавенства = СтрНайти(Данные, "="); + + Если ПозицияРавенства = 0 Тогда + ТекстОшибки = СтрШаблон("В опции --form-string некорректно указано значение: '%1'", Данные); + ИсходящиеОшибки.Добавить(ОбщегоНазначения.НоваяКритичнаяОшибка(ТекстОшибки)); + Возврат; + КонецЕсли; + + ИмяПоля = Сред(Данные, 1, ПозицияРавенства - 1); + Значение = Сред(Данные, ПозицияРавенства + 1); + + Если ПустаяСтрока(ИмяПоля) Тогда + ИмяПоля = "null"; + КонецЕсли; + + ПередаваемыйТекст = Новый ПередаваемыйТекст(Значение, Назначение); + ПередаваемыйТекст.ИмяПоля = ИмяПоля; + + ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйТекст); + + КонецЦикла; + +КонецПроцедуры + Процедура ПрочитатьСертификатКлиента(Команда) СертификатКлиента = ПоследнееЗначениеОпции(Команда, "E"); @@ -628,37 +749,38 @@ КодироватьЗначение = Не НачинаетсяСПлюса; Если ПозицияРавенства > 0 Тогда - Ключ = Сред(Данные, 1, ПозицияРавенства - 1); - ПараметрЗапроса = Сред(Данные, ПозицияРавенства + 1); - Если КодироватьЗначение Тогда - ПараметрЗапроса = КодироватьСтроку(ПараметрЗапроса, СпособКодированияСтроки.URLВКодировкеURL); - КонецЕсли; + ИмяПоля = Сред(Данные, 1, ПозицияРавенства - 1); + Значение = Сред(Данные, ПозицияРавенства + 1); - Если ЗначениеЗаполнено(Ключ) Тогда - ПараметрЗапроса = СтрШаблон("%1=%2", Ключ, ПараметрЗапроса); + ПередаваемыйТекст = Новый ПередаваемыйТекст(Значение, НазначенияПередаваемыхДанных.СтрокаЗапроса); + ПередаваемыйТекст.КодироватьЗначение = КодироватьЗначение; + + Если Не ПустаяСтрока(ИмяПоля) Тогда + ПередаваемыйТекст.ИмяПоля = ИмяПоля; КонецЕсли; - ПередаваемыйТекст = Новый ПередаваемыйТекст(ПараметрЗапроса, НазначенияПередаваемыхДанных.СтрокаЗапроса); ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйТекст); + ИначеЕсли ПозицияСобачки > 0 И Не НачинаетсяСПлюса Тогда - Ключ = Сред(Данные, 1, ПозицияСобачки - 1); + + ИмяПоля = Сред(Данные, 1, ПозицияСобачки - 1); ИмяФайла = СокрЛП(Сред(Данные, ПозицияСобачки + 1)); ПередаваемыйФайл = Новый ПередаваемыйФайл(ИмяФайла, НазначенияПередаваемыхДанных.СтрокаЗапроса); - ПередаваемыйФайл.Ключ = Ключ; + ПередаваемыйФайл.ИмяПоля = ИмяПоля; ПередаваемыйФайл.ПрочитатьСодержимое = Истина; ПередаваемыйФайл.КодироватьСодержимое = Истина; ОписаниеЗапроса.Файлы.Добавить(ПередаваемыйФайл); + Иначе - ПараметрЗапроса = Данные; - Если КодироватьЗначение Тогда - ПараметрЗапроса = КодироватьСтроку(Данные, СпособКодированияСтроки.URLВКодировкеURL); - КонецЕсли; - ПередаваемыйТекст = Новый ПередаваемыйТекст(ПараметрЗапроса, НазначенияПередаваемыхДанных.СтрокаЗапроса); + ПередаваемыйТекст = Новый ПередаваемыйТекст(Данные, НазначенияПередаваемыхДанных.СтрокаЗапроса); + ПередаваемыйТекст.КодироватьЗначение = КодироватьЗначение; + ОписаниеЗапроса.ОтправляемыеТекстовыеДанные.Добавить(ПередаваемыйТекст); + КонецЕсли; КонецЦикла; @@ -832,6 +954,8 @@ ДобавитьПоддерживаемуюОпциюВКонсольноеПриложение("no-location", "", "Запрещает перенаправления").ТМассивБулево(); ДобавитьПоддерживаемуюОпциюВКонсольноеПриложение("retry", 0, "Количество повторных попыток").ТМассивЧисел(); ДобавитьПоддерживаемуюОпциюВКонсольноеПриложение("retry-max-time", 0, "Максимальное время повторов").ТМассивЧисел(); + ДобавитьПоддерживаемуюОпциюВКонсольноеПриложение("F form", "Передаваемые данные по HTTP POST (multipart/form-data)").ТМассивСтрок(); + ДобавитьПоддерживаемуюОпциюВКонсольноеПриложение("form-string", "Передаваемые данные по HTTP POST без интерпретации спецтальных сиволов (multipart/form-data)").ТМассивСтрок(); // Неподдерживаемые ДобавитьНеподдерживаемуюОпциюВКонсольноеПриложение("abstract-unix-socket").ТМассивСтрок(); @@ -881,9 +1005,7 @@ ДобавитьНеподдерживаемуюОпциюВКонсольноеПриложение("fail-early").ТМассивБулево(); ДобавитьНеподдерживаемуюОпциюВКонсольноеПриложение("fail-with-body").ТМассивБулево(); ДобавитьНеподдерживаемуюОпциюВКонсольноеПриложение("false-start").ТМассивБулево(); - ДобавитьНеподдерживаемуюОпциюВКонсольноеПриложение("F form").ТМассивСтрок(); ДобавитьНеподдерживаемуюОпциюВКонсольноеПриложение("form-escape").ТМассивБулево(); - ДобавитьНеподдерживаемуюОпциюВКонсольноеПриложение("form-string").ТМассивСтрок(); ДобавитьНеподдерживаемуюОпциюВКонсольноеПриложение("ftp-account").ТМассивСтрок(); ДобавитьНеподдерживаемуюОпциюВКонсольноеПриложение("ftp-alternative-to-user").ТМассивСтрок(); ДобавитьНеподдерживаемуюОпциюВКонсольноеПриложение("ftp-create-dirs").ТМассивБулево(); @@ -1092,30 +1214,6 @@ Возврат Опция; КонецФункции -Функция ЕстьОпции(Команда, Опции) - Для Каждого Опция Из СтрРазделить(Опции, ",") Цикл - Если ЗначениеЗаполнено(ЗначениеОпции(Команда, Опция)) Тогда - Возврат Истина; - КонецЕсли; - КонецЦикла; - Возврат Ложь; -КонецФункции - -Функция ЕстьОпцииГруппыData(Команда) - Возврат ЕстьОпции(Команда, "d,data,data-raw,data-binary,data-urlencode,data-ascii"); -КонецФункции - -Функция ПоследнееЗначениеОпции(Команда, ИмяОпции) - МассивЗначений = ЗначениеОпции(Команда, ИмяОпции); - Если ТипЗнч(МассивЗначений) = Тип("Массив") И МассивЗначений.Количество() Тогда - Возврат МассивЗначений[МассивЗначений.ВГраница()]; - КонецЕсли; -КонецФункции - -Функция ЗначениеОпции(Команда, ИмяОпции) - Возврат Команда.ЗначениеОпции(ИмяОпции); -КонецФункции - Процедура ОбработатьАргументыКоманды(АргументыКоманды, НомерКоманды, КоличествоКоманд) ПроверитьЧтоКомандаНачинаетсяСCurl(АргументыКоманды, НомерКоманды, КоличествоКоманд); @@ -1243,6 +1341,30 @@ КонецПроцедуры +Процедура ПроверитьДанные(Команда) + + ШаблонОдновременнаяПередача = "Одновременная передача опций %1 и %2 запрещена"; + + Если ЕстьОпцииГруппыData(Команда) И ЕстьОпцииГруппыForm(Команда) Тогда + ТекстОшибки = СтрШаблон(ШаблонОдновременнаяПередача, "-d (--data)", "-F (--form)"); + ИсходящиеОшибки.Добавить(ОбщегоНазначения.НоваяКритичнаяОшибка(ТекстОшибки)); + Возврат; + КонецЕсли; + + Если ЕстьОпцииГруппыForm(Команда) И ЗначениеОпции(Команда, "head") = Истина Тогда + ТекстОшибки = СтрШаблон(ШаблонОдновременнаяПередача, "-I (--head)", "-F (--form)"); + ИсходящиеОшибки.Добавить(ОбщегоНазначения.НоваяКритичнаяОшибка(ТекстОшибки)); + Возврат; + КонецЕсли; + + Если ЕстьОпции(Команда, "upload-file") И ЕстьОпцииГруппыForm(Команда) Тогда + ТекстОшибки = СтрШаблон(ШаблонОдновременнаяПередача, "-T (--upload-file)", "-F (--form)"); + ИсходящиеОшибки.Добавить(ОбщегоНазначения.НоваяКритичнаяОшибка(ТекстОшибки)); + Возврат; + КонецЕсли; + +КонецПроцедуры + Процедура ВывестиРазделительКоманд(Результат, НомерКоманды, КоличествоКоманд) Если КоличествоКоманд = 1 Тогда @@ -1271,6 +1393,34 @@ КонецПроцедуры +Функция ЕстьОпции(Команда, Опции) + Для Каждого Опция Из СтрРазделить(Опции, ",") Цикл + Если ЗначениеЗаполнено(ЗначениеОпции(Команда, Опция)) Тогда + Возврат Истина; + КонецЕсли; + КонецЦикла; + Возврат Ложь; +КонецФункции + +Функция ЕстьОпцииГруппыData(Команда) + Возврат ЕстьОпции(Команда, "d,data,data-raw,data-binary,data-urlencode,data-ascii,json"); +КонецФункции + +Функция ЕстьОпцииГруппыForm(Команда) + Возврат ЕстьОпции(Команда, "F,form,form-string"); +КонецФункции + +Функция ПоследнееЗначениеОпции(Команда, ИмяОпции) + МассивЗначений = ЗначениеОпции(Команда, ИмяОпции); + Если ТипЗнч(МассивЗначений) = Тип("Массив") И МассивЗначений.Количество() Тогда + Возврат МассивЗначений[МассивЗначений.ВГраница()]; + КонецЕсли; +КонецФункции + +Функция ЗначениеОпции(Команда, ИмяОпции) + Возврат Команда.ЗначениеОпции(ИмяОпции); +КонецФункции + // Используется для отключения вывода справки cli Процедура Заглушка(Значение = Неопределено) Экспорт diff --git "a/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265\320\227\320\260\320\277\321\200\320\276\321\201\320\260.os" "b/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265\320\227\320\260\320\277\321\200\320\276\321\201\320\260.os" index b5c7174..76dcbbe 100644 --- "a/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265\320\227\320\260\320\277\321\200\320\276\321\201\320\260.os" +++ "b/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\236\320\277\320\270\321\201\320\260\320\275\320\270\320\265\320\227\320\260\320\277\321\200\320\276\321\201\320\260.os" @@ -1,8 +1,10 @@ +// BSLLS:ExportVariables-off + Перем АдресаРесурсов Экспорт; // Массив из Структура // - URL - Строка - Адрес ресурса // - Метод - Строка - Метод // - ИмяВыходногоФайла - Строка - Имя выходного файла - // - Файлы - Массив из см. ПередаваемыйФайл - Файлы + // - Файлы - Массив из см. ПередаваемыйФайл - Файлы для HTTP PUT или FTP Перем Заголовки Экспорт; // Соответствие из КлючИЗначение Перем ИмяПользователя Экспорт; // Строка Перем ПарольПользователя Экспорт; // Строка @@ -24,6 +26,7 @@ Перем ЗапретитьПеренаправление Экспорт; // Булево Перем МаксимальноеКоличествоПовторов Экспорт; // Число Перем МаксимальноеВремяПовторов Экспорт; // Число +Перем ОтправлятьКакMultipartFormData Экспорт; // Булево // Максимальное время ожидания на выполнение запроса Перем Таймаут Экспорт; // Число @@ -100,6 +103,7 @@ ЗапретитьПеренаправление = Ложь; МаксимальноеКоличествоПовторов = 0; МаксимальноеВремяПовторов = 0; + ОтправлятьКакMultipartFormData = Ложь; КонецПроцедуры Функция ЕстьДанныеПоНазначению(Назначение) Экспорт diff --git "a/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\321\201\320\265\321\200\320\227\320\275\320\260\321\207\320\265\320\275\320\270\321\217\320\236\320\277\321\206\320\270\320\270Form.os" "b/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\321\201\320\265\321\200\320\227\320\275\320\260\321\207\320\265\320\275\320\270\321\217\320\236\320\277\321\206\320\270\320\270Form.os" new file mode 100644 index 0000000..7a7d73b --- /dev/null +++ "b/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\260\321\200\321\201\320\265\321\200\320\227\320\275\320\260\321\207\320\265\320\275\320\270\321\217\320\236\320\277\321\206\320\270\320\270Form.os" @@ -0,0 +1,165 @@ +#Использовать tokenizer + +Перем Спецификация; // Массив +Перем МассивПараметров; // Массив из Структура: + // * Имя - Строка - Имя параметра + // * Значение - Строка, Неопределено - значение параметра +Перем ИмяПараметра; // Строка +Перем БылРазделитель; // Булево +Перем ЗначениеПараметра; // Строка, Неопределено + +#Область ПрограммныйИнтерфейс + +// Парсит значение опции -F (--form) +// +// Параметры: +// Строка - Строка - Значение опции +// +// Возвращаемое значение: +// Структура: +// * ИмяПоля - Строка - Имя поля +// * Значение - Строка - Значение поля +// * Параметры - Соответствие из КлючИЗначение: +// ** Ключ - Строка - Имя параметра. Например: type, filename, headers +// ** Значение - Строка, Соответствие - Значение параметра. Тип Соответствие только для параметра headers +Функция Распарсить(Строка) Экспорт + + МассивПараметров = Новый Массив(); + + Токенайзер = Новый Токенайзер(Спецификация); + Токенайзер.Инит(Строка); + + ИмяПараметра = ""; + ЗначениеПараметра = Неопределено; + ОткрытаДвойнаяКавычка = Ложь; + БылРазделитель = Ложь; + + Пока Токенайзер.ЕстьЕщеТокены() Цикл + + Токен = Токенайзер.СледующийТокен(); + + Если Токен = Неопределено Тогда + Прервать; + КонецЕсли; + + ТипТокена = Токен.ТипТокена(); + + Если ТипТокена = "ДвойнаяКавычка" Тогда + ОткрытаДвойнаяКавычка = Не ОткрытаДвойнаяКавычка; + + Если Не ОткрытаДвойнаяКавычка Тогда + ПроверитьИДобавитьПараметр(); + КонецЕсли; + ИначеЕсли ОткрытаДвойнаяКавычка Или ТипТокена = "Строка" Тогда + ДополнитьЗначениемТокена(Токен); + ИначеЕсли ТипТокена = "ТочкаСЗапятой" Тогда + ПроверитьИДобавитьПараметр(); + ИначеЕсли ТипТокена = "Равенство" Тогда + БылРазделитель = Истина; + ЗначениеПараметра = ""; + КонецЕсли; + + КонецЦикла; + + ПроверитьИДобавитьПараметр(); + + Возврат ПодготовитьРезультат(); + +КонецФункции + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +Процедура ПриСозданииОбъекта() + + Спецификация = Новый Массив(); + Спецификация.Добавить(Новый СпецификацияТокенСимвол("""", "ДвойнаяКавычка")); + Спецификация.Добавить(Новый СпецификацияТокенСимвол(";", "ТочкаСЗапятой")); + Спецификация.Добавить(Новый СпецификацияТокенСимвол("=", "Равенство")); + Спецификация.Добавить(Новый СпецификацияТокенРегулярноеВыражение(Новый РегулярноеВыражение("[^=;""]+"), "Строка")); + +КонецПроцедуры + +Функция ПодготовитьРезультат() + + Результат = Новый Структура("ИмяПоля, Значение, Параметры", "", "", Новый Соответствие()); + + Если МассивПараметров.Количество() = 0 Тогда + Возврат Результат; + КонецЕсли; + + Результат.ИмяПоля = СокрЛП(МассивПараметров[0].Имя); + Результат.Значение = СокрЛП(МассивПараметров[0].Значение); + Результат.Параметры.Вставить("headers", Новый Соответствие()); + + Если ПустаяСтрока(Результат.ИмяПоля) Тогда + Результат.ИмяПоля = "null"; + КонецЕсли; + + Для Индекс = 1 По МассивПараметров.ВГраница() Цикл + Параметр = МассивПараметров[Индекс]; + + Имя = НРег(СокрЛП(Параметр.Имя)); + Значение = СокрЛП(Параметр.Значение); + + Если Имя = "headers" Тогда + ДобавитьЗаголовок(Результат.Параметры["headers"], Значение); + Иначе + Результат.Параметры.Вставить(Имя, Значение); + КонецЕсли; + КонецЦикла; + + Возврат Результат; + +КонецФункции + +Процедура ДобавитьЗаголовок(Заголовки, СтрокаЗаголовка) + + ПозицияДвоеточия = СтрНайти(СтрокаЗаголовка, ":"); + + Если ПозицияДвоеточия Тогда + Имя = Сред(СтрокаЗаголовка, 1, ПозицияДвоеточия - 1); + Значение = СокрЛП(Сред(СтрокаЗаголовка, ПозицияДвоеточия + 1)); + Иначе + Имя = СтрокаЗаголовка; + Значение = ""; + КонецЕсли; + + Заголовки.Вставить(Имя, Значение); + +КонецПроцедуры + +Процедура ДополнитьЗначениемТокена(Токен) + + Если БылРазделитель Тогда + + Если ЗначениеПараметра = Неопределено Тогда + ЗначениеПараметра = ""; + КонецЕсли; + + ЗначениеПараметра = ЗначениеПараметра + Токен.Значение(); + + Иначе + + ИмяПараметра = ИмяПараметра + Токен.Значение(); + + КонецЕсли; + +КонецПроцедуры + +Процедура ПроверитьИДобавитьПараметр() + + Если Не БылРазделитель Тогда + Возврат; + КонецЕсли; + + МассивПараметров.Добавить(Новый Структура("Имя, Значение", ИмяПараметра, СокрЛП(ЗначениеПараметра))); + + ИмяПараметра = ""; + БылРазделитель = Ложь; + ЗначениеПараметра = Неопределено; + +КонецПроцедуры + +#КонецОбласти \ No newline at end of file diff --git "a/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\265\321\200\320\265\320\264\320\260\320\262\320\260\320\265\320\274\321\213\320\271\320\242\320\265\320\272\321\201\321\202.os" "b/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\265\321\200\320\265\320\264\320\260\320\262\320\260\320\265\320\274\321\213\320\271\320\242\320\265\320\272\321\201\321\202.os" index da7a34c..9d8c63d 100644 --- "a/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\265\321\200\320\265\320\264\320\260\320\262\320\260\320\265\320\274\321\213\320\271\320\242\320\265\320\272\321\201\321\202.os" +++ "b/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\265\321\200\320\265\320\264\320\260\320\262\320\260\320\265\320\274\321\213\320\271\320\242\320\265\320\272\321\201\321\202.os" @@ -1,11 +1,52 @@ +// BSLLS:ExportVariables-off + +// Имя поля на форме или в строке запроса +Перем ИмяПоля Экспорт; // Строка, Неопределено + +// Текстовое значение Перем Значение Экспорт; // Строка + +// Назначение текста Перем Назначение Экспорт; // см. НазначенияПередаваемыхДанных + +// Кодировать значение +Перем КодироватьЗначение Экспорт; // Булево + +// Разделитель при формировании тела запроса или строки запроса Перем РазделительТелаЗапроса Экспорт; // Строка -Процедура ПриСозданииОбъекта(пЗначение, пНазначение) +// MIME-тип файла (multipart/form-data) +Перем ТипMIME Экспорт; // Строка + +// HTTP заголовки запроса (multipart/form-data) +Перем Заголовки Экспорт; // Соответствие + +Функция ПолноеЗначение(Разделитель = "=") Экспорт + + Если КодироватьЗначение Тогда + НовоеЗначение = КодироватьСтроку(Значение, СпособКодированияСтроки.КодировкаURL); + Иначе + НовоеЗначение = Значение; + КонецЕсли; + + Если ИмяПоля <> Неопределено Тогда + ПолноеЗначение = СтрШаблон("%1%2%3", ИмяПоля, Разделитель, НовоеЗначение); + Иначе + ПолноеЗначение = НовоеЗначение; + КонецЕсли; + + Возврат ПолноеЗначение; + +КонецФункции + +Процедура ПриСозданииОбъекта(ТекстовоеЗначение, НазначениеТекста) - Значение = пЗначение; - Назначение = пНазначение; + ИмяПоля = Неопределено; + Значение = ТекстовоеЗначение; + Назначение = НазначениеТекста; + КодироватьЗначение = Ложь; РазделительТелаЗапроса = "&"; + ТипMIME = ""; + Заголовки = Новый Соответствие(); -КонецПроцедуры \ No newline at end of file +КонецПроцедуры diff --git "a/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\265\321\200\320\265\320\264\320\260\320\262\320\260\320\265\320\274\321\213\320\271\320\244\320\260\320\271\320\273.os" "b/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\265\321\200\320\265\320\264\320\260\320\262\320\260\320\265\320\274\321\213\320\271\320\244\320\260\320\271\320\273.os" index 3b87b02..3ef68d8 100644 --- "a/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\265\321\200\320\265\320\264\320\260\320\262\320\260\320\265\320\274\321\213\320\271\320\244\320\260\320\271\320\273.os" +++ "b/src/internal/\320\232\320\273\320\260\321\201\321\201\321\213/\320\237\320\265\321\200\320\265\320\264\320\260\320\262\320\260\320\265\320\274\321\213\320\271\320\244\320\260\320\271\320\273.os" @@ -1,23 +1,54 @@ -Перем ИмяФайла Экспорт; // Строка +// BSLLS:ExportVariables-off + +// Полный путь к файлу на устройстве +Перем ПолноеИмяФайла Экспорт; // Строка + +// Назначение файла Перем Назначение Экспорт; // см. НазначенияПередаваемыхДанных + +// Отправляет этот файл в отдельности от других данных Перем ОтправлятьОтдельно Экспорт; // Булево + +// Читает текстовое содержимое файла Перем ПрочитатьСодержимое Экспорт; // Булево + +// Кодирует содержимое файла после чтения Перем КодироватьСодержимое Экспорт; // Булево + +// Удалять переносы строк Перем УдалятьПереносыСтрок Экспорт; // Булево + +// Разделитель при формировании тела запроса или строки запроса Перем РазделительТелаЗапроса Экспорт; // Строка + +// Добавлять, по возможности, имя файла к URL Перем ДобавлятьИмяФайлаКURL Экспорт; // Булево -Перем Ключ Экспорт; // Строка -Процедура ПриСозданииОбъекта(пИмяФайла = "", пНазначение = Неопределено) +// Имя поля на форме или в строке запроса +Перем ИмяПоля Экспорт; // Строка + +// Имя файла (multipart/form-data) +Перем ИмяФайла Экспорт; // Строка + +// MIME-тип файла (multipart/form-data) +Перем ТипMIME Экспорт; // Строка + +// HTTP заголовки запроса (multipart/form-data) +Перем Заголовки Экспорт; // Соответствие + +Процедура ПриСозданииОбъекта(ПутьКФайлу = "", НазначениеФайла = Неопределено) - ИмяФайла = пИмяФайла; - Назначение = пНазначение; + ПолноеИмяФайла = ПутьКФайлу; + Назначение = НазначениеФайла; ОтправлятьОтдельно = Ложь; ПрочитатьСодержимое = Ложь; КодироватьСодержимое = Ложь; УдалятьПереносыСтрок = Ложь; РазделительТелаЗапроса = "&"; ДобавлятьИмяФайлаКURL = Ложь; - Ключ = ""; + ИмяПоля = ""; + ИмяФайла = ""; + ТипMIME = ""; + Заголовки = Новый Соответствие(); КонецПроцедуры \ No newline at end of file diff --git "a/src/internal/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\320\276\320\273\320\273\320\265\320\272\321\206\320\270\321\217\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\260.os" "b/src/internal/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\320\276\320\273\320\273\320\265\320\272\321\206\320\270\321\217\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\260.os" index 2ac0d90..a35def5 100644 --- "a/src/internal/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\320\276\320\273\320\273\320\265\320\272\321\206\320\270\321\217\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\260.os" +++ "b/src/internal/\320\234\320\276\320\264\321\203\320\273\320\270/\320\232\320\276\320\273\320\273\320\265\320\272\321\206\320\270\321\217\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\260.os" @@ -30,16 +30,11 @@ |%1 = КодироватьСтроку(%1, СпособКодированияСтроки.URLВКодировкеURL);"; КонецЕсли; - Если ЗначениеЗаполнено(ПередаваемыйФайл.Ключ) Тогда - Шаблон = Шаблон + " - |%1 = """ + ПередаваемыйФайл.Ключ + "="" + %1;"; - КонецЕсли; - ИмяПеременной = "ТекстовыеДанныеФайла_" + Формат(НомерФайла, "ЧГ="); Конструктор.ДобавитьСтроку(Шаблон, ИмяПеременной, - Конструктор.ПараметрВСтроку(ПередаваемыйФайл.ИмяФайла)); + Конструктор.ПараметрВСтроку(ПередаваемыйФайл.ПолноеИмяФайла)); ПрочитанныйФайл = Новый Структура(); ПрочитанныйФайл.Вставить("ПередаваемыйФайл", ПередаваемыйФайл); @@ -76,7 +71,7 @@ МассивТекстовыхДанных.Добавить(Разделитель); КонецЕсли; - МассивТекстовыхДанных.Добавить(ПередаваемыйТекст.Значение); + МассивТекстовыхДанных.Добавить(ПередаваемыйТекст.ПолноеЗначение()); НуженРазделитель = Истина; КонецЦикла; @@ -93,27 +88,36 @@ Продолжить; КонецЕсли; + Если ЗначениеЗаполнено(ПередаваемыйФайл.ИмяПоля) Тогда + Префикс = ПередаваемыйФайл.ИмяПоля + "="; + ПрефиксВКоде = Конструктор.ПараметрВСтроку(Префикс) + " + "; + Иначе + Префикс = ""; + ПрефиксВКоде = ""; + КонецЕсли; + + ИмяПеременной = ПрочитанныйФайл.ИмяПеременной; Разделитель = ПередаваемыйФайл.РазделительТелаЗапроса; Если НуженРазделитель Тогда Если Не ПустаяСтрока(Разделитель) Тогда Текст = СтрШаблон(КонкатенацияСПереносомСтрокиИРазделителя, - ПередаваемыйФайл.РазделительТелаЗапроса, - ПрочитанныйФайл.ИмяПеременной); + ПередаваемыйФайл.РазделительТелаЗапроса + Префикс, + ИмяПеременной); - ЧастиКода.Добавить(Текст); + ЧастиКода.Добавить(Текст); Иначе - Текст = СтрШаблон(КонкатенацияСПереносомСтроки, ПрочитанныйФайл.ИмяПеременной); + Текст = СтрШаблон(КонкатенацияСПереносомСтроки, ПрефиксВКоде + ИмяПеременной); ЧастиКода.Добавить(Текст); КонецЕсли; Иначе - ЧастиКода.Добавить(ПрочитанныйФайл.ИмяПеременной); + ЧастиКода.Добавить(ПрефиксВКоде + ИмяПеременной); КонецЕсли; @@ -148,8 +152,10 @@ Функция СборкаАдресаРесурса(СтруктураURL, ТекстовыеДанные = Неопределено, ПрочитанныеФайлы = Неопределено) Экспорт Конструктор = Новый КонструкторПрограммногоКода(); - КонкатенацияСПереносомСтрокиИАмперсандом = " - | + ""&"" + "; + + РазделительПараметров = "&"; + КонкатенацияСПереносомСтрокиИРазделителем = " + | + ""%1"" + "; КонкатенацияСПереносомСтроки = " | + "; @@ -171,23 +177,43 @@ Если ПараметрыЗапроса.Количество() И Не ПустаяСтрока(ПередаваемыйТекст.РазделительТелаЗапроса) Тогда ПараметрыЗапроса.Добавить(ПередаваемыйТекст.РазделительТелаЗапроса); КонецЕсли; - ПараметрыЗапроса.Добавить(ПередаваемыйТекст.Значение); + ПараметрыЗапроса.Добавить(ПередаваемыйТекст.ПолноеЗначение()); КонецЕсли; КонецЦикла; КонецЕсли; // Параметры запроса из файлов - ПараметрыЗапросаИзФайлов = Новый Массив(); + ПараметрыЗапросаИзФайловСтрокой = ""; Если Не ПрочитанныеФайлы = Неопределено Тогда Для Каждого ПрочитанныйФайл Из ПрочитанныеФайлы Цикл - Если ПрочитанныйФайл.ПередаваемыйФайл.Назначение = НазначенияПередаваемыхДанных.СтрокаЗапроса Тогда - ПараметрыЗапросаИзФайлов.Добавить(ПрочитанныйФайл.ИмяПеременной); + + ПередаваемыйФайл = ПрочитанныйФайл.ПередаваемыйФайл; + + Если ПередаваемыйФайл.Назначение = НазначенияПередаваемыхДанных.СтрокаЗапроса Тогда + Если ЗначениеЗаполнено(ПередаваемыйФайл.ИмяПоля) Тогда + Префикс = ПередаваемыйФайл.ИмяПоля + "="; + ПрефиксВКоде = Конструктор.ПараметрВСтроку(Префикс) + " + "; + Иначе + Префикс = ""; + ПрефиксВКоде = ""; + КонецЕсли; + + ИмяПеременной = ПрочитанныйФайл.ИмяПеременной; + + Если ПараметрыЗапросаИзФайловСтрокой = "" Тогда + ПараметрыЗапросаИзФайловСтрокой = ПрефиксВКоде + ИмяПеременной; + Иначе + ПараметрыЗапросаИзФайловСтрокой = ПараметрыЗапросаИзФайловСтрокой + + СтрШаблон(КонкатенацияСПереносомСтрокиИРазделителем, РазделительПараметров + Префикс) + + ИмяПеременной; + КонецЕсли; КонецЕсли; + КонецЦикла; КонецЕсли; + // Сборка адреса ПараметрыЗапросаСтрокой = СтрСоединить(ПараметрыЗапроса); - ПараметрыЗапросаИзФайловСтрокой = СтрСоединить(ПараметрыЗапросаИзФайлов, КонкатенацияСПереносомСтрокиИАмперсандом); ЕстьПараметрыЗапроса = Не ПустаяСтрока(ПараметрыЗапросаСтрокой) Или Не ПустаяСтрока(ПараметрыЗапросаИзФайловСтрокой); ПерваяЧасть = СтруктураURL.Путь @@ -206,30 +232,39 @@ Иначе - ВозможноОднойСтрокой = ПустаяСтрока(ВтораяЧасть) - И СтрЧислоСтрок(ПараметрыЗапросаИзФайловСтрокой) = 1; + ВозможноОднойСтрокой = ПустаяСтрока(ВтораяЧасть) И СтрЧислоСтрок(ПараметрыЗапросаИзФайловСтрокой) = 1; Если ВозможноОднойСтрокой Тогда Результат = "" - + Конструктор.ПараметрВСтроку(ПерваяЧасть + ?(ПустаяСтрока(ПараметрыЗапросаСтрокой), "", "&")) + + Конструктор.ПараметрВСтроку(ПерваяЧасть + ?(ПустаяСтрока(ПараметрыЗапросаСтрокой), "", РазделительПараметров)) + " + " + ПараметрыЗапросаИзФайловСтрокой; Иначе - Результат = "" - + Конструктор.ПараметрВСтроку(ПерваяЧасть) - - + ?(ПустаяСтрока(ПараметрыЗапросаСтрокой), - КонкатенацияСПереносомСтроки, - КонкатенацияСПереносомСтрокиИАмперсандом) - - + ПараметрыЗапросаИзФайловСтрокой + Результат = Конструктор.ПараметрВСтроку(ПерваяЧасть); + + Если ПустаяСтрока(ПараметрыЗапросаСтрокой) Тогда + Результат = Результат + + КонкатенацияСПереносомСтроки + + ПараметрыЗапросаИзФайловСтрокой; + ИначеЕсли Лев(ПараметрыЗапросаИзФайловСтрокой, 1) = """" Тогда + Результат = Результат + + КонкатенацияСПереносомСтроки + + """" + РазделительПараметров + + Сред(ПараметрыЗапросаИзФайловСтрокой, 2); + Иначе + Результат = Результат + + СтрШаблон(КонкатенацияСПереносомСтрокиИРазделителем, РазделительПараметров) + + ПараметрыЗапросаИзФайловСтрокой; + КонецЕсли; - + ?(Не ПустаяСтрока(ВтораяЧасть), - КонкатенацияСПереносомСтроки + Конструктор.ПараметрВСтроку(ВтораяЧасть), - ""); + Если Не ПустаяСтрока(ВтораяЧасть) Тогда + Результат = Результат + + КонкатенацияСПереносомСтроки + + Конструктор.ПараметрВСтроку(ВтораяЧасть); + КонецЕсли; КонецЕсли; diff --git "a/tests/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\2601\320\241_test.os" "b/tests/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\2601\320\241_test.os" index f673177..29f17dd 100644 --- "a/tests/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\2601\320\241_test.os" +++ "b/tests/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\2601\320\241_test.os" @@ -387,14 +387,13 @@ |ЧтениеТекста = Новый ЧтениеТекста(""file""); |ТекстовыеДанныеФайла_1 = ЧтениеТекста.Прочитать(); |ТекстовыеДанныеФайла_1 = КодироватьСтроку(ТекстовыеДанныеФайла_1, СпособКодированияСтроки.URLВКодировкеURL); - |ТекстовыеДанныеФайла_1 = ""name="" + ТекстовыеДанныеФайла_1; | |ЧтениеТекста = Новый ЧтениеТекста(""fileonly""); |ТекстовыеДанныеФайла_2 = ЧтениеТекста.Прочитать(); |ТекстовыеДанныеФайла_2 = КодироватьСтроку(ТекстовыеДанныеФайла_2, СпособКодированияСтроки.URLВКодировкеURL); | |ТелоЗапроса = ""name=val&encodethis%26"" - | + ""&"" + ТекстовыеДанныеФайла_1 + | + ""&name="" + ТекстовыеДанныеФайла_1 | + ""&"" + ТекстовыеДанныеФайла_2; | |Соединение = Новый HTTPСоединение(""example.com"", 80); @@ -748,7 +747,7 @@ КонсольнаяКоманда = "curl http://example.com \ | --url-query name=val \ - | --url-query =encodethis& \ + | --url-query '=encodethis&' \ | --url-query name@file \ | --url-query @fileonly \ | --url-query '+name=%20foo' \ @@ -757,7 +756,6 @@ ПрограммныйКод = "ЧтениеТекста = Новый ЧтениеТекста(""file""); |ТекстовыеДанныеФайла_1 = ЧтениеТекста.Прочитать(); |ТекстовыеДанныеФайла_1 = КодироватьСтроку(ТекстовыеДанныеФайла_1, СпособКодированияСтроки.URLВКодировкеURL); - |ТекстовыеДанныеФайла_1 = ""name="" + ТекстовыеДанныеФайла_1; | |ЧтениеТекста = Новый ЧтениеТекста(""fileonly""); |ТекстовыеДанныеФайла_2 = ЧтениеТекста.Прочитать(); @@ -766,7 +764,7 @@ |Соединение = Новый HTTPСоединение(""example.com"", 80); | |АдресРесурса = ""?name=val&encodethis%26&name=%20foo&@not-a-file"" - | + ""&"" + ТекстовыеДанныеФайла_1 + | + ""&name="" + ТекстовыеДанныеФайла_1 | + ""&"" + ТекстовыеДанныеФайла_2; |HTTPЗапрос = Новый HTTPЗапрос(АдресРесурса); | diff --git "a/tests/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\260\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200HTTP_test.os" "b/tests/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\260\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200HTTP_test.os" index b8fcc53..f5efc9d 100644 --- "a/tests/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\260\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200HTTP_test.os" +++ "b/tests/\320\223\320\265\320\275\320\265\321\200\320\260\321\202\320\276\321\200\320\237\321\200\320\276\320\263\321\200\320\260\320\274\320\274\320\275\320\276\320\263\320\276\320\232\320\276\320\264\320\260\320\232\320\276\320\275\320\275\320\265\320\272\321\202\320\276\321\200HTTP_test.os" @@ -294,14 +294,13 @@ ПрограммныйКод = "ЧтениеТекста = Новый ЧтениеТекста(""file""); |ТекстовыеДанныеФайла_1 = ЧтениеТекста.Прочитать(); |ТекстовыеДанныеФайла_1 = КодироватьСтроку(ТекстовыеДанныеФайла_1, СпособКодированияСтроки.URLВКодировкеURL); - |ТекстовыеДанныеФайла_1 = ""name="" + ТекстовыеДанныеФайла_1; | |ЧтениеТекста = Новый ЧтениеТекста(""fileonly""); |ТекстовыеДанныеФайла_2 = ЧтениеТекста.Прочитать(); |ТекстовыеДанныеФайла_2 = КодироватьСтроку(ТекстовыеДанныеФайла_2, СпособКодированияСтроки.URLВКодировкеURL); | |Данные = ""name=val&encodethis%26"" - | + ""&"" + ТекстовыеДанныеФайла_1 + | + ""&name="" + ТекстовыеДанныеФайла_1 | + ""&"" + ТекстовыеДанныеФайла_2; | |Результат = КоннекторHTTP.Post(""http://example.com"", Данные);"; @@ -530,7 +529,7 @@ КонсольнаяКоманда = "curl http://example.com \ | --url-query name=val \ - | --url-query =encodethis& \ + | --url-query '=encodethis&' \ | --url-query name@file \ | --url-query @fileonly \ | --url-query '+name=%20foo' \ @@ -539,14 +538,13 @@ ПрограммныйКод = "ЧтениеТекста = Новый ЧтениеТекста(""file""); |ТекстовыеДанныеФайла_1 = ЧтениеТекста.Прочитать(); |ТекстовыеДанныеФайла_1 = КодироватьСтроку(ТекстовыеДанныеФайла_1, СпособКодированияСтроки.URLВКодировкеURL); - |ТекстовыеДанныеФайла_1 = ""name="" + ТекстовыеДанныеФайла_1; | |ЧтениеТекста = Новый ЧтениеТекста(""fileonly""); |ТекстовыеДанныеФайла_2 = ЧтениеТекста.Прочитать(); |ТекстовыеДанныеФайла_2 = КодироватьСтроку(ТекстовыеДанныеФайла_2, СпособКодированияСтроки.URLВКодировкеURL); | |URL = ""http://example.com?name=val&encodethis%26&name=%20foo&@not-a-file"" - | + ""&"" + ТекстовыеДанныеФайла_1 + | + ""&name="" + ТекстовыеДанныеФайла_1 | + ""&"" + ТекстовыеДанныеФайла_2; | |Результат = КоннекторHTTP.Get(URL);"; @@ -1047,4 +1045,237 @@ Ожидаем.Что(Результат).Равно(ПрограммныйКод); +КонецПроцедуры + +&Тест +Процедура ТестДолжен_ПроверитьПроверитьПередачуДанныхMultipart() Экспорт + + КонсольнаяКоманда = "curl http://example.com/ -F name=John -F shoesize=11 + |curl http://example.com/ -F profile=@portrait.jpg + |curl http://example.com/ -F profile=@portrait.jpg --form brief=@file.pdf + |curl http://example.com/ -F file=@part1 --form file=@part2 + |curl http://example.com/ -F name=John -F profile=@portrait.jpg + |curl http://example.com/ -F story=