1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2025-03-19 21:17:55 +02:00

PXY: Доработка Multipart

This commit is contained in:
Anton Titovets 2025-02-04 19:32:04 +03:00
parent c0dd4d768e
commit d28ef45a9b
2 changed files with 45 additions and 147 deletions

View File

@ -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"]) Тогда
ВызватьИсключение ТекстИсключения;
Иначе
Возврат СтруктураВозврата;
КонецЕсли;
КонецФункции
#КонецОбласти
#КонецОбласти

View File

@ -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_ПреобразованиеТипов.ПолучитьСтроку(ТекущееЗначение);
КотелПараметров.Вставить(ТекущееЗначение, ИВФ);
КотелПараметров.Вставить(ТекущийКлюч, ТекущееЗначение);
КонецЕсли;
КонецЦикла;