From d28ef45a9b5e3f1d8b3ed92bf228f40d844f09e3 Mon Sep 17 00:00:00 2001 From: Anton Titovets Date: Tue, 4 Feb 2025 19:32:04 +0300 Subject: [PATCH] =?UTF-8?q?PXY:=20=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=BA=D0=B0=20Multipart?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CommonModules/OPI_Инструменты/Module.bsl | 148 +----------------- .../ObjectModule.bsl | 44 +++++- 2 files changed, 45 insertions(+), 147 deletions(-) diff --git a/src/ru/OPI/src/CommonModules/OPI_Инструменты/Module.bsl b/src/ru/OPI/src/CommonModules/OPI_Инструменты/Module.bsl index f4b25945d7..6bd914e9d2 100644 --- a/src/ru/OPI/src/CommonModules/OPI_Инструменты/Module.bsl +++ b/src/ru/OPI/src/CommonModules/OPI_Инструменты/Module.bsl @@ -1166,52 +1166,20 @@ КонецФункции -#КонецОбласти - -#Область Multipart - -// by Виталий Черкасов (cherkasovvitalik) -// https://infostart.ru/1c/articles/1522786/ - -Функция РазобратьMultipart(Знач Заголовки, Знач Тело) Экспорт +Функция РазобратьMultipart(Знач Форма) Экспорт СоответствиеДанных = Новый Соответствие; - Разделитель = ПолучитьРазделительСоставногоСообщения(Заголовки); + Файлы = Форма.Файлы; + + Для Каждого Поле Из Форма Цикл - Маркеры = Новый Массив(); - Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель)); - Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель + Символы.ПС)); - Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель + Символы.ВК)); - Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель + Символы.ВК + Символы.ПС)); - Маркеры.Добавить(ПолучитьБуферДвоичныхДанныхИзСтроки("==" + Разделитель + "==")); + СоответствиеДанных.Вставить(Поле.Ключ, Поле.Значение); - ЧтениеДанных = Новый ЧтениеДанных(Тело); - ЧтениеДанных.ПропуститьДо(Маркеры); + КонецЦикла; - ОбщийБуферДвоичныхДанных = ЧтениеДанных.ПрочитатьВБуферДвоичныхДанных(); - БуферыДвоичныхДанных = ОбщийБуферДвоичныхДанных.Разделить(Маркеры); + Для Каждого Файл Из Файлы Цикл - Для Каждого Буфер Из БуферыДвоичныхДанных Цикл - - Поток = Новый ПотокВПамяти(Буфер); - ЧтениеЧасти = Новый ЧтениеДанных(Поток); - - ЗаголовкиЧасти = ПрочитатьЗаголовки(ЧтениеЧасти); - ДанныеЧасти = ПолучитьИмяСообщения(ЗаголовкиЧасти); - - ИмяЧасти = ДанныеЧасти["name"]; - ИмяФайла = ДанныеЧасти["filename"]; - - ТекущиеДанные = ЧтениеЧасти.Прочитать().ПолучитьДвоичныеДанные(); - - Если Не ЗначениеЗаполнено(ИмяФайла) Тогда - ТекущиеДанные = ПолучитьСтрокуИзДвоичныхДанных(ТекущиеДанные); - КонецЕсли; - - СоответствиеДанных.Вставить(ИмяЧасти, ТекущиеДанные); - - ЧтениеЧасти.Закрыть(); - Поток.Закрыть(); + СоответствиеДанных.Вставить(Файл.Имя, Файл); КонецЦикла; @@ -1219,106 +1187,6 @@ КонецФункции -Функция ПрочитатьЗаголовки(Чтение) - - Заголовки = Новый Соответствие; - - Пока Истина Цикл - - ТекущаяСтрока = Чтение.ПрочитатьСтроку(); - - Если ТекущаяСтрока = "" Тогда - Прервать; - КонецЕсли; - - Части = СтрРазделить(ТекущаяСтрока, ":"); - - ИмяЗаголовка = СокрЛП(Части[0]); - Значение = СокрЛП(Части[1]); - - Заголовки.Вставить(ИмяЗаголовка, Значение); - - КонецЦикла; - - Возврат Заголовки; - -КонецФункции - -Функция ПолучитьРазделительСоставногоСообщения(Заголовки) - - ТекстИсключения = "Для Multipart-запросов обязательно указание корректного Content-Type с boundary!"; - ТипСодержимого = Заголовки.Получить("Content-Type"); - - Если Не ЗначениеЗаполнено(ТипСодержимого) Тогда - ВызватьИсключение ТекстИсключения; - КонецЕсли; - - Свойства = СтрРазделить(ТипСодержимого, ";", Ложь); - Граница = Неопределено; - - Для Каждого Свойство Из Свойства Цикл - - Части = СтрРазделить(Свойство, "=", Ложь); - ИмяСвойства = СокрЛП(Части[0]); - - Если ИмяСвойства <> "boundary" Тогда - Продолжить; - КонецЕсли; - - Граница = СокрЛП(Части[1]); - Прервать; - - КонецЦикла; - - Если Не ЗначениеЗаполнено(Граница) Тогда - ВызватьИсключение ТекстИсключения; - Иначе - Возврат Граница; - КонецЕсли; - -КонецФункции - -Функция ПолучитьИмяСообщения(Заголовки) - - ТекстИсключения = "Content-Disposition одной из частей не найден или имеет неверный формат!"; - Описание = Заголовки.Получить("Content-Disposition"); - СтруктураВозврата = Новый Структура("name,filename"); - - Если Не ЗначениеЗаполнено(Описание) Тогда - ВызватьИсключение ТекстИсключения; - КонецЕсли; - - Свойства = СтрРазделить(Описание, ";", Ложь); - Имя = Неопределено; - - Для Каждого Свойство Из Свойства Цикл - - Части = СтрРазделить(Свойство, "=", Ложь); - ИмяСвойства = СокрЛП(Части[0]); - ИмяСвойства = нРег(ИмяСвойства); - - Если ИмяСвойства = "name" Тогда - - СтруктураВозврата["name"] = СокрЛП(Части[1]); - - ИначеЕсли ИмяСвойства = "filename"Тогда - - СтруктураВозврата["filename"] = СокрЛП(Части[1]); - - Иначе - Продолжить; - КонецЕсли; - - КонецЦикла; - - Если Не ЗначениеЗаполнено(СтруктураВозврата["name"]) Тогда - ВызватьИсключение ТекстИсключения; - Иначе - Возврат СтруктураВозврата; - КонецЕсли; - -КонецФункции - #КонецОбласти #КонецОбласти diff --git a/src/ru/OPI/src/DataProcessors/OPI_ОбработчикЗапросовПрокси/ObjectModule.bsl b/src/ru/OPI/src/DataProcessors/OPI_ОбработчикЗапросовПрокси/ObjectModule.bsl index 20c694a223..836052e63f 100644 --- a/src/ru/OPI/src/DataProcessors/OPI_ОбработчикЗапросовПрокси/ObjectModule.bsl +++ b/src/ru/OPI/src/DataProcessors/OPI_ОбработчикЗапросовПрокси/ObjectModule.bsl @@ -60,12 +60,24 @@ Результат = ОбработатьЗапрос(Контекст); Исключение - Ошибка = КраткоеПредставлениеОшибки(ИнформацияОбОшибке()); + Информация = ИнформацияОбОшибке(); + Результат = Новый Структура("result,error", Ложь, Информация.Описание); + + Если СтрНайти(Информация.ИсходнаяСтрока, "ВызватьИсключение") = 0 Тогда + + ФайлМодуля = Новый Файл(Информация.ИмяМодуля); + + СтруктураИсключения = Новый Структура; + СтруктураИсключения.Вставить("module", ФайлМодуля.Имя); + СтруктураИсключения.Вставить("row" , Информация.НомерСтроки); + СтруктураИсключения.Вставить("code" , СокрЛП(Информация.ИсходнаяСтрока)); + + Результат.Вставить("exception", СтруктураИсключения); + + КонецЕсли; Контекст.Ответ.КодСостояния = 500; - Результат = Новый Структура("result,error", Ложь, "Исключение OneScript: " + Ошибка); - КонецПопытки; JSON = OPI_Инструменты.JSONСтрокой(Результат); @@ -74,6 +86,7 @@ Контекст.Ответ.Записать(JSON); #КонецЕсли + КонецПроцедуры Функция ОбработатьЗапрос(Контекст) @@ -168,10 +181,11 @@ Запрос = Контекст.Запрос; - Тело = Запрос.Тело; - Заголовки = Запрос.Заголовки; + Если Не ЗначениеЗаполнено(Запрос.Форма) Тогда + ВызватьИсключение "Не найдены данные в формате multipart/form-data!"; + КонецЕсли; - Параметры = OPI_Инструменты.РазобратьMultipart(Тело, Заголовки); + Параметры = OPI_Инструменты.РазобратьMultipart(Запрос.Форма); Возврат ВыполнитьУниверсальнуюОбработку(Контекст, Обработчик, Параметры); @@ -207,9 +221,25 @@ КотелПараметров.Вставить(ТекущийКлюч, ИВФ); + ИначеЕсли ТипЗнч(ТекущееЗначение) = Тип("ФайлФормы") Тогда + + ИВФ = ПолучитьИмяВременногоФайла(); + + ПотокФайла = ТекущееЗначение.ОткрытьПотокЧтения(); + ПотокЗаписи = Новый ФайловыйПоток(ИВФ, РежимОткрытияФайла.ОткрытьИлиСоздать); + + ПотокФайла.КопироватьВ(ПотокЗаписи); + + ПотокФайла.Закрыть(); + ПотокЗаписи.Закрыть(); + + МассивВФ.Добавить(ИВФ); + + КотелПараметров.Вставить(ТекущийКлюч, ИВФ); + Иначе OPI_ПреобразованиеТипов.ПолучитьСтроку(ТекущееЗначение); - КотелПараметров.Вставить(ТекущееЗначение, ИВФ); + КотелПараметров.Вставить(ТекущийКлюч, ТекущееЗначение); КонецЕсли; КонецЦикла;