diff --git "a/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP/Ext/Module.bsl" "b/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP/Ext/Module.bsl" index 411cf30..6df1ece 100644 --- "a/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP/Ext/Module.bsl" +++ "b/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP/Ext/Module.bsl" @@ -54,6 +54,15 @@ Возврат ТекущаяУниверсальнаяДата(); КонецФункции +// Возвращает текущий Unix Timestamp +// +// Возвращаемое значение: +// Число - количество секунд, прошедших с 01.01.1970 по текущее время UTC +// +Функция ВременнаяМеткаUnix() Экспорт + Возврат ТекущаяУниверсальнаяДата() - КлиентHTTPПовтИсп.ЭпохаUnix(); +КонецФункции + // Возвращает раскодированный URI в URL кодировке // // Параметры: @@ -73,7 +82,7 @@ // КонтекстВыполненияАдресВХ - Строка - адрес контекста выполнения запроса во временном хранилище // // Возвращаемое значение: -// Строка - значение заголовка Digest-авторизации +// Строка - значение заголовка Digest-аутентификации // Функция ЗаголовокDigest(Знач Конфигурация, Знач КонтекстВыполненияАдресВХ) Экспорт КонтекстВыполнения = ПолучитьИзВременногоХранилища(КонтекстВыполненияАдресВХ); @@ -81,7 +90,7 @@ Параметры = Конфигурация.ДополнительныеПараметры.Сессия.ПараметрыDigest; Аутентификация = Конфигурация.ДополнительныеПараметры.Аутентификация; - АдресРесурсаСПараметрами = Конфигурация.ДанныеURI.АдресРесурса + Конфигурация.Параметры; + ПутьСПараметрами = Конфигурация.ДанныеURI.Путь + Конфигурация.ПараметрыСтрокой; АлгоритмХеширования = НРег(Параметры.algorithm); УникальныйКлючКлиента = Лев(СтрЗаменить(НРег(Новый УникальныйИдентификатор), "-", ""), 16); @@ -98,8 +107,8 @@ A2 = ?( КачествоЗащиты = "auth-int", - СтрШаблон("%1:%2:%3", КонтекстВыполнения.Метод, АдресРесурсаСПараметрами, ХешСтрока(КонтекстВыполнения.Данные, АлгоритмХеширования)), - СтрШаблон("%1:%2", КонтекстВыполнения.Метод, АдресРесурсаСПараметрами) + СтрШаблон("%1:%2:%3", КонтекстВыполнения.Метод, ПутьСПараметрами, ХешСтрока(КонтекстВыполнения.Данные, АлгоритмХеширования)), + СтрШаблон("%1:%2", КонтекстВыполнения.Метод, ПутьСПараметрами) ); HA2 = ХешСтрока(A2, АлгоритмХеширования); @@ -134,7 +143,7 @@ Конфигурация.ДополнительныеПараметры.Аутентификация.Пользователь, Параметры.realm, Параметры.nonce, - АдресРесурсаСПараметрами, + ПутьСПараметрами, Ответ ) ); @@ -152,7 +161,219 @@ Возврат СтрСоединить(фРезультат); КонецФункции -// Возвращает коллекцию раскодированных строк +// Возвращает заголовки AWS4-аутентификации +// +// Параметры: +// Метод - Строка - имя HTTP-метода +// Конфигурация - Структура - конфигурация выполнения запроса +// ДанныеАдресВХ - Строка - адрес данных тела запроса во временном хранилище +// +// Возвращаемое значение: +// Массив - заголовки AWS4-аутентификации +// +Функция ЗаголовкиAWS4(Знач Метод, Знач Конфигурация, Знач ДанныеАдресВХ) Экспорт + фРезультат = Новый Массив; + + Данные = ПолучитьИзВременногоХранилища(ДанныеАдресВХ); + УдалитьИзВременногоХранилища(ДанныеАдресВХ); + + ЗаголовокAmzContent = ХешСтрока(Данные, ХешФункция.SHA256); + + СпецификацияЗапроса = "aws4_request"; + АлгоритмШифрования = "AWS4-HMAC-SHA256"; + Аутентификация = Конфигурация.ДополнительныеПараметры.АвторизоватьсяAWS4; + Регион = ?(ПустаяСтрока(Аутентификация.Регион), КлиентHTTPПовтИсп.РегионAWSПоУмолчанию(), Аутентификация.Регион); + ТУД = ТекущаяУниверсальнаяДата(); + ЗаголовокAmzDate = Формат(ТУД, "ДФ=yyyyMMddTHHmmssZ"); + ДатаДействия = Формат(ТУД, "ДФ=yyyyMMdd"); + + фРезультат.Добавить(Новый Структура("Ключ, Значение", "X-Amz-Date", ЗаголовокAmzDate)); + фРезультат.Добавить(Новый Структура("Ключ, Значение", "X-Amz-Content-Sha256", ЗаголовокAmzContent)); + + СписокЗаголовков = СписокЗаголовковAWS4(Конфигурация.Заголовки, фРезультат); + ПодписываемыеЗаголовки = ПодписываемыеЗаголовкиAWS4(СписокЗаголовков); + + ЧастиСтроки = Новый Массив; + ЧастиСтроки.Добавить(Метод); + ЧастиСтроки.Добавить(Конфигурация.ДанныеURI.Путь); + ЧастиСтроки.Добавить(КаноническиеПараметрыAWS4(Конфигурация.Параметры)); + ЧастиСтроки.Добавить(КаноническиеЗаголовкиAWS4(СписокЗаголовков)); + ЧастиСтроки.Добавить(ПодписываемыеЗаголовки); + ЧастиСтроки.Добавить(ЗаголовокAmzContent); + КаноническийЗапрос = СтрСоединить(ЧастиСтроки, Символы.ПС); + + ЧастиСтроки = Новый Массив; + ЧастиСтроки.Добавить(ДатаДействия); + ЧастиСтроки.Добавить(Регион); + ЧастиСтроки.Добавить(Аутентификация.Сервис); + ЧастиСтроки.Добавить(СпецификацияЗапроса); + ОбластьДействия = СтрСоединить(ЧастиСтроки, "/"); + + ЧастиСтроки = Новый Массив; + ЧастиСтроки.Добавить(АлгоритмШифрования); + ЧастиСтроки.Добавить(ЗаголовокAmzDate); + ЧастиСтроки.Добавить(ОбластьДействия); + ЧастиСтроки.Добавить(ХешСтрока(КаноническийЗапрос, ХешФункция.SHA256)); + СтрокаДляПодписи = СтрСоединить(ЧастиСтроки, Символы.ПС); + + Подпись = HMAC256(ПолучитьДвоичныеДанныеИзСтроки("AWS4" + Аутентификация.СекретныйКлюч), ПолучитьДвоичныеДанныеИзСтроки(ДатаДействия)); + Подпись = HMAC256(Подпись, ПолучитьДвоичныеДанныеИзСтроки(Регион)); + Подпись = HMAC256(Подпись, ПолучитьДвоичныеДанныеИзСтроки(Аутентификация.Сервис)); + Подпись = HMAC256(Подпись, ПолучитьДвоичныеДанныеИзСтроки(СпецификацияЗапроса)); + Подпись = НРег(ПолучитьHexСтрокуИзДвоичныхДанных(HMAC256(Подпись, ПолучитьДвоичныеДанныеИзСтроки(СтрокаДляПодписи)))); + + фРезультат.Добавить(Новый Структура( + "Ключ, Значение", + КлиентHTTPПовтИсп.ЗаголовокТипАутентификации(), + СтрШаблон( + "%1 Credential=%2/%3, SignedHeaders=%4, Signature=%5", + АлгоритмШифрования, + Аутентификация.КлючДоступа, + ОбластьДействия, + ПодписываемыеЗаголовки, + Подпись + ) + )); + + Возврат Новый ФиксированныйМассив(фРезультат); +КонецФункции + +// Возвращает значение заголовка Hawk-аутентификации +// Расчёт подписи содержимого тела запроса не обязателен для Hawk-аутентификации. +// +// Параметры: +// Метод - Строка - имя HTTP-метода +// Конфигурация - Структура - конфигурация выполнения запроса +// ДанныеАдресВХ - Строка, Неопределено - адрес данных тела запроса во временном хранилище (необязательный) +// +// Возвращаемое значение: +// Строка - значение заголовка Hawk-аутентификации +// +Функция ЗаголовокHawk(Знач Метод, Конфигурация, Знач ДанныеАдресВХ = Неопределено) Экспорт + фРезультат = Новый Массив; + + ПодписьТела = ""; + Если ДанныеАдресВХ <> Неопределено Тогда + Данные = ПолучитьИзВременногоХранилища(ДанныеАдресВХ); + УдалитьИзВременногоХранилища(ДанныеАдресВХ); + + ПодписьТела = ПодписьТелаHawk( + Данные, + КлиентHTTPКлиентСервер.ТипMIMEИзЗаголовков(Конфигурация.Заголовки) + ); + КонецЕсли; + + Аутентификация = Конфигурация.ДополнительныеПараметры.АвторизоватьсяHawk; + ДополнительныеДанные = НормализованныеДополнительныеДанныеHawk(Аутентификация.Дополнение); + РазовоеСлово = НовоеРазовоеСлово(); + ВременнаяМетка = XMLСтрока(ВременнаяМеткаUnix()); + + ЧастиСтроки = Новый Массив; + ЧастиСтроки.Добавить("hawk.1.header"); + ЧастиСтроки.Добавить(ВременнаяМетка); + ЧастиСтроки.Добавить(РазовоеСлово); + ЧастиСтроки.Добавить(Метод); + ЧастиСтроки.Добавить(Конфигурация.ДанныеURI.Путь); + ЧастиСтроки.Добавить(НРег(Конфигурация.ДанныеURI.Сервер)); + ЧастиСтроки.Добавить(XMLСтрока(Конфигурация.ДанныеURI.Порт)); + ЧастиСтроки.Добавить(ПодписьТела); + ЧастиСтроки.Добавить(ДополнительныеДанные); + + Если НЕ ПустаяСтрока(Аутентификация.ИдентификаторПриложения) Тогда + ЧастиСтроки.Добавить(Аутентификация.ИдентификаторПриложения); + ЧастиСтроки.Добавить(Аутентификация.Делегирование); + КонецЕсли; + + ЧастиСтроки.Добавить(""); + + Подпись = Base64Строка(HMAC256( + ПолучитьДвоичныеДанныеИзСтроки(Аутентификация.Ключ), + ПолучитьДвоичныеДанныеИзСтроки(СтрСоединить(ЧастиСтроки, Символы.ПС)) + )); + + фРезультат.Добавить(СтрШаблон("Hawk id=""%1"", ts=""%2"", nonce=""%3""", Аутентификация.Идентификатор, ВременнаяМетка, РазовоеСлово)); + Если ПодписьТела <> "" Тогда + фРезультат.Добавить(СтрШаблон("hash=""%1""", ПодписьТела)); + КонецЕсли; + Если ДополнительныеДанные <> "" Тогда + фРезультат.Добавить(СтрШаблон("ext=""%1""", ДополнительныеДанные)); + КонецЕсли; + фРезультат.Добавить(СтрШаблон("mac=""%1""", Подпись)); + Если НЕ ПустаяСтрока(Аутентификация.ИдентификаторПриложения) Тогда + фРезультат.Добавить(СтрШаблон("app=""%1""", Аутентификация.ИдентификаторПриложения)); + Если НЕ ПустаяСтрока(Аутентификация.Делегирование) Тогда + фРезультат.Добавить(СтрШаблон("dlg=""%1""", Аутентификация.Делегирование)); + КонецЕсли; + КонецЕсли; + + Аутентификация = Новый Структура(Аутентификация); + Аутентификация.Вставить("РазовоеСлово", РазовоеСлово); + Аутентификация.Вставить("ВременнаяМетка", ВременнаяМетка); + + Конфигурация.ДополнительныеПараметры.АвторизоватьсяHawk = Новый ФиксированнаяСтруктура(Аутентификация); + + Возврат СтрСоединить(фРезультат, ", "); +КонецФункции + +// Возвращает результат валидации ответа сервера по указанному заголовку (Hawk аутентификация) +// Если валидация прошла успешно, вернётся Истина. +// +// Параметры: +// ЗначениеЗаголовка - Строка - значение заголовка ответа сервера с данными Hawk аутентификации +// КонтекстHawk - Структура - данные Hawk аутентификации запроса +// ДанныеАдресВХ - Строка - адрес данных тела ответа и MIME-типа во временном хранилище +// ОписаниеОшибки - Строка - описание ошибки валидации ответа +// +// Возвращаемое значение: +// Булево - результат валидации +// +Функция ОтветСЗаголовкомHawkКорректен(Знач ЗначениеЗаголовка, Знач КонтекстHawk, Знач ДанныеАдресВХ, ОписаниеОшибки) Экспорт + ДанныеСервера = ДанныеЗаголовкаОтветаHawk(ЗначениеЗаголовка); + + ПодписьТела = ""; + Если ДанныеСервера.ПодписьТела <> "" Тогда + Данные = ПолучитьИзВременногоХранилища(ДанныеАдресВХ); + ПодписьТела = ПодписьТелаHawk(Данные.Тело, Данные.ТипMIME); + КонецЕсли; + УдалитьИзВременногоХранилища(ДанныеАдресВХ); + + Если ПодписьТела <> ДанныеСервера.ПодписьТела Тогда + ОписаниеОшибки = СтрШаблон("Не совпадают подписи тела ответа: рассчитана '%1', получена '%2'", ПодписьТела, ДанныеСервера.ПодписьТела); + Возврат Ложь; + КонецЕсли; + + ЧастиСтроки = Новый Массив; + ЧастиСтроки.Добавить("hawk.1.response"); + ЧастиСтроки.Добавить(КонтекстHawk.ВременнаяМетка); + ЧастиСтроки.Добавить(КонтекстHawk.РазовоеСлово); + ЧастиСтроки.Добавить(КонтекстHawk.Метод); + ЧастиСтроки.Добавить(КонтекстHawk.Путь); + ЧастиСтроки.Добавить(НРег(КонтекстHawk.Хост)); + ЧастиСтроки.Добавить(XMLСтрока(КонтекстHawk.Порт)); + ЧастиСтроки.Добавить(ПодписьТела); + ЧастиСтроки.Добавить(ДанныеСервера.Дополнение); + + Если НЕ ПустаяСтрока(КонтекстHawk.ИдентификаторПриложения) Тогда + ЧастиСтроки.Добавить(КонтекстHawk.ИдентификаторПриложения); + ЧастиСтроки.Добавить(КонтекстHawk.Делегирование); + КонецЕсли; + + ЧастиСтроки.Добавить(""); + + Подпись = Base64Строка(HMAC256( + ПолучитьДвоичныеДанныеИзСтроки(КонтекстHawk.Ключ), + ПолучитьДвоичныеДанныеИзСтроки(СтрСоединить(ЧастиСтроки, Символы.ПС)) + )); + + Если Подпись <> ДанныеСервера.Подпись Тогда + ОписаниеОшибки = СтрШаблон("Не совпадают подписи ответа: рассчитана '%1', получена '%2'", Подпись, ДанныеСервера.Подпись); + Возврат Ложь; + КонецЕсли; + + Возврат Истина; +КонецФункции + +// (УСТАРЕЛО) Возвращает коллекцию раскодированных строк // // Параметры: // КоллекцияСтрок - Структура - коллекция строк для раскодирования (обрабатываются только значения) @@ -175,7 +396,31 @@ Возврат фРезультат; КонецФункции -// Возвращает коллекцию кодированных строк +// Возвращает множество раскодированных строк способом КодировкаURL +// +// Параметры: +// МножествоСтрок - Соответствие - множество строк для раскодирования +// +// Возвращаемое значение: +// Соответствие - множество раскодированных строк +// +Функция РаскодированныеСтрокиURL(Знач МножествоСтрок) Экспорт + Возврат РаскодированныеСтрокиСпособом(МножествоСтрок, СпособКодированияСтроки.КодировкаURL); +КонецФункции + +// Возвращает множество раскодированных строк способом URLВКодировкеURL +// +// Параметры: +// МножествоСтрок - Соответствие - множество строк для раскодирования +// +// Возвращаемое значение: +// Соответствие - множество раскодированных строк +// +Функция РаскодированныеСтрокиURLвURL(Знач МножествоСтрок) Экспорт + Возврат РаскодированныеСтрокиСпособом(МножествоСтрок, СпособКодированияСтроки.URLВКодировкеURL); +КонецФункции + +// (УСТАРЕЛО) Возвращает коллекцию кодированных строк // // Параметры: // КоллекцияСтрок - Структура - коллекция строк для кодирования (обрабатываются только значения) @@ -198,6 +443,30 @@ Возврат фРезультат; КонецФункции +// Возвращает множество кодированных строк способом КодировкаURL +// +// Параметры: +// МножествоСтрок - Соответствие - множество строк для кодирования +// +// Возвращаемое значение: +// Соответствие - множество кодированных строк +// +Функция КодированныеСтрокиURL(Знач МножествоСтрок) Экспорт + Возврат КодированныеСтрокиСпособом(МножествоСтрок, СпособКодированияСтроки.КодировкаURL); +КонецФункции + +// Возвращает множество кодированных строк способом URLВКодировкеURL +// +// Параметры: +// МножествоСтрок - Соответствие - множество строк для кодирования +// +// Возвращаемое значение: +// Соответствие - множество кодированных строк +// +Функция КодированныеСтрокиURLвURL(Знач МножествоСтрок) Экспорт + Возврат КодированныеСтрокиСпособом(МножествоСтрок, СпособКодированияСтроки.URLВКодировкеURL); +КонецФункции + // Возвращает коллекцию раскодированных полей HTML-Формы // // Параметры: @@ -374,8 +643,11 @@ // собирать значение печеньки пока не придёт знак (ТипТокена В {1, 2}) его записать Действие.ЗаписатьЗначениеПеченьки = Ложь; Действие.СобиратьЗначениеПеченьки = Истина; - СостояниеПеченьки.Построитель.Добавить(СостояниеПеченьки.Объект.Значение + ЧастьОписанияПеченья(ОписанияПеченья.Исходное, СостояниеЧтения)); - СостояниеПеченьки.Построитель.Добавить(СостояниеЧтения.Токен.Токен); + ЧастиОписания = ЧастьОписанияПеченья(ОписанияПеченья.Исходное, СостояниеЧтения); + Если НЕ ПустаяСтрока(ЧастиОписания) Тогда + СостояниеПеченьки.Построитель.Добавить(СостояниеПеченьки.Объект.Значение + ЧастиОписания); + СостояниеПеченьки.Построитель.Добавить(СостояниеЧтения.Токен.Токен); + КонецЕсли; СостояниеЧтения.Позиция = СостояниеЧтения.Токен.Позиция + 1; ПереключитьСостояниеДКА(СостояниеДКА); КонецПроцедуры @@ -552,6 +824,10 @@ КонецПроцедуры Функция ЧастьОписанияПеченья(Знач ОписаниеПеченьки, Знач СостояниеЧтения, Знач Смещение = 0) + Если СостояниеЧтения.Токен.Позиция - СостояниеЧтения.Позиция + Смещение < 1 Тогда + Возврат ""; + КонецЕсли; + Возврат Сред( ОписаниеПеченьки, СостояниеЧтения.Позиция, @@ -659,7 +935,7 @@ КонецФункции Функция ХешСтрока(Знач Данные, Знач Алгоритм) - ТипФункции = ТипХешФункции(Алгоритм); + ТипФункции = ?(ТипЗнч(Алгоритм) = Тип("ХешФункция"), Алгоритм, ТипХешФункции(Алгоритм)); Если ТипЗнч(Данные) = Тип("Строка") Тогда Данные = ПолучитьДвоичныеДанныеИзСтроки(Данные, КлиентHTTPПовтИсп.КодировкаUTF8(), Ложь); @@ -683,4 +959,209 @@ Возврат фРезультат; КонецФункции + +Функция РаскодированныеСтрокиСпособом(Знач МножествоСтрок, Знач Способ) + фРезультат = Новый Соответствие; + + Для Каждого КЗ Из МножествоСтрок Цикл + фРезультат.Вставить(КЗ.Ключ, РаскодироватьСтроку(КЗ.Ключ, Способ)); + КонецЦикла; + + Возврат фРезультат; +КонецФункции + +Функция КодированныеСтрокиСпособом(Знач МножествоСтрок, Знач Способ) + фРезультат = Новый Соответствие; + + Для Каждого КЗ Из МножествоСтрок Цикл + фРезультат.Вставить(КЗ.Ключ, КодироватьСтроку(КЗ.Ключ, Способ)); + КонецЦикла; + + Возврат фРезультат; +КонецФункции + +Функция НовоеРазовоеСлово() + фРезультат = Новый Массив; + + База = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + ДлинаБазы = СтрДлина(База); + ГСЧ = Новый ГенераторСлучайныхЧисел(13); + Для я = 1 По 32 Цикл + Позиция = ГСЧ.СлучайноеЧисло(1, ДлинаБазы); + фРезультат.Добавить(Сред(База, Позиция, 1)); + КонецЦикла; + + Возврат СтрСоединить(фРезультат); +КонецФункции + +Функция HMAC256(Знач Ключ, Знач Данные) + АлгоритмХеширования = ХешФункция.SHA256; + РазмерБлока = 64; + Если Ключ.Размер() > РазмерБлока Тогда + Хеширование = Новый ХешированиеДанных(АлгоритмХеширования); + Хеширование.Добавить(Ключ); + + Ключ = Хеширование.ХешСумма; + КонецЕсли; + + ВнутренняяОснова = Новый БуферДвоичныхДанных(РазмерБлока); + ВнешняяОснова = Новый БуферДвоичныхДанных(РазмерБлока); + Для Позиция = 0 По РазмерБлока - 1 Цикл + ВнутренняяОснова.Установить(Позиция, 54); // 0x36 + ВнешняяОснова.Установить(Позиция, 92); // 0x5C + КонецЦикла; + + Буфер = Новый БуферДвоичныхДанных(РазмерБлока); + Буфер.Записать(0, ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(Ключ)); + + ВнутреннийКлюч = Буфер.Скопировать(); + ВнутреннийКлюч.ЗаписатьПобитовоеИсключительноеИли(0, ВнутренняяОснова); + + ВнешнийКлюч = Буфер; + ВнешнийКлюч.ЗаписатьПобитовоеИсключительноеИли(0, ВнешняяОснова); + + ВнутреннийХеш = Новый ХешированиеДанных(АлгоритмХеширования); + ВнешнийХеш = Новый ХешированиеДанных(АлгоритмХеширования); + + ВнутреннийХеш.Добавить(ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(ВнутреннийКлюч)); + ВнешнийХеш.Добавить(ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(ВнешнийКлюч)); + + Если ЗначениеЗаполнено(Данные) Тогда + ВнутреннийХеш.Добавить(Данные); + КонецЕсли; + + ВнешнийХеш.Добавить(ВнутреннийХеш.ХешСумма); + + Возврат ВнешнийХеш.ХешСумма; +КонецФункции + +Функция КаноническиеПараметрыAWS4(Знач ПараметрыЗапроса) + фРезультат = Новый Массив; + + СписокПараметров = Новый СписокЗначений; + Для Каждого Параметр Из ПараметрыЗапроса Цикл + Ключ = КодироватьСтроку(КлиентHTTPСлужебный.ФорматированноеИмяПараметраЗапроса(Параметр.Ключ), СпособКодированияСтроки.URLВКодировкеURL); + Если ПустаяСтрока(Ключ) Тогда + Продолжить; + КонецЕсли; + Если Параметр.Значение.Количество() = 0 Тогда + СписокПараметров.Добавить(Ключ); + Продолжить; + КонецЕсли; + Для Каждого Значение Из Параметр.Значение Цикл + СписокПараметров.Добавить(Ключ, КодироватьСтроку(КлиентHTTPСлужебный.ФорматированноеИмяПараметраЗапроса(Значение), СпособКодированияСтроки.URLВКодировкеURL)); + КонецЦикла; + КонецЦикла; + СписокПараметров.СортироватьПоПредставлению(); + СписокПараметров.СортироватьПоЗначению(); + + Для Каждого Параметр Из СписокПараметров Цикл + фРезультат.Добавить(Параметр.Значение + "=" + Параметр.Представление); + КонецЦикла; + + Возврат СтрСоединить(фРезультат, "&"); +КонецФункции + +Функция СписокЗаголовковAWS4(Знач ЗаголовкиЗапроса, Знач ЗаголовкиAWS) + фРезультат = Новый СписокЗначений; + + МножествоЗаголовков = Новый Соответствие; + + Для Каждого Заголовок Из ЗаголовкиЗапроса Цикл + Ключ = НРег(Заголовок.Ключ); + Если Ключ = "host" ИЛИ СтрНачинаетсяС(Ключ, "x-amz-") Тогда + МножествоЗаголовков.Вставить(Ключ, Заголовок.Значение); + КонецЕсли; + КонецЦикла; + Для Каждого Заголовок Из ЗаголовкиAWS Цикл + МножествоЗаголовков.Вставить(НРег(Заголовок.Ключ), Заголовок.Значение); + КонецЦикла; + + Для Каждого Заголовок Из МножествоЗаголовков Цикл + фРезультат.Добавить(Заголовок.Ключ, Заголовок.Значение); + КонецЦикла; + фРезультат.СортироватьПоЗначению(НаправлениеСортировки.Возр); + + Возврат фРезультат; +КонецФункции + +Функция КаноническиеЗаголовкиAWS4(Знач СписокЗаголовков) + фРезультат = Новый Массив; + Для Каждого Заголовок Из СписокЗаголовков Цикл + фРезультат.Добавить(СтрШаблон("%1:%2", Заголовок.Значение, Заголовок.Представление)); + КонецЦикла; + фРезультат.Добавить(""); + + Возврат СтрСоединить(фРезультат, Символы.ПС); +КонецФункции + +Функция ПодписываемыеЗаголовкиAWS4(Знач СписокЗаголовков) + фРезультат = Новый Массив; + Для Каждого Заголовок Из СписокЗаголовков Цикл + фРезультат.Добавить(Заголовок.Значение); + КонецЦикла; + + Возврат СтрСоединить(фРезультат, ";"); +КонецФункции + +Функция НормализованныеДополнительныеДанныеHawk(Знач ДополнительныеДанные) + Возврат СтрЗаменить(СтрЗаменить(ДополнительныеДанные, "\", "\\"), Символы.ПС, "\n"); +КонецФункции + +Функция ПодписьТелаHawk(Знач Данные, Знач ТипКонтента) + Если Данные.Размер() = 0 ИЛИ НЕ ЗначениеЗаполнено(ТипКонтента) Тогда + Возврат ""; + КонецЕсли; + + Поток = Новый ПотокВПамяти; + Запись = Новый ЗаписьДанных(Поток); + + Запись.ЗаписатьСимволы("hawk.1.payload"); + Запись.ЗаписатьБайт(10); // символ '\n' + Запись.ЗаписатьСимволы(НРег(ТипКонтента)); + Запись.ЗаписатьБайт(10); + Запись.Записать(Данные); + Запись.ЗаписатьБайт(10); + + Хеширование = Новый ХешированиеДанных(ХешФункция.SHA256); + Хеширование.Добавить(Поток.ЗакрытьИПолучитьДвоичныеДанные()); + + Возврат Base64Строка(Хеширование.ХешСумма); +КонецФункции + +Функция ДанныеЗаголовкаОтветаHawk(Знач ЗначениеЗаголовка) + фРезультат = Новый Структура("Подпись, ПодписьТела, Дополнение", "", "", ""); + + ПозицияНачала = СтрНайти(ЗначениеЗаголовка, " mac="""); + ПозицияОкончания = 0; + Если ПозицияНачала > 0 Тогда + ПозицияНачала = ПозицияНачала + 6; + ПозицияОкончания = СтрНайти(ЗначениеЗаголовка, """", , ПозицияНачала); + Если ПозицияОкончания > 0 Тогда + фРезультат.Подпись = Сред(ЗначениеЗаголовка, ПозицияНачала, ПозицияОкончания - ПозицияНачала); + КонецЕсли; + КонецЕсли; + + ПозицияНачала = СтрНайти(ЗначениеЗаголовка, " hash="""); + ПозицияОкончания = 0; + Если ПозицияНачала > 0 Тогда + ПозицияНачала = ПозицияНачала + 7; + ПозицияОкончания = СтрНайти(ЗначениеЗаголовка, """", , ПозицияНачала); + Если ПозицияОкончания > 0 Тогда + фРезультат.ПодписьТела = Сред(ЗначениеЗаголовка, ПозицияНачала, ПозицияОкончания - ПозицияНачала); + КонецЕсли; + КонецЕсли; + + ПозицияНачала = СтрНайти(ЗначениеЗаголовка, " ext="""); + ПозицияОкончания = 0; + Если ПозицияНачала > 0 Тогда + ПозицияНачала = ПозицияНачала + 6; + ПозицияОкончания = СтрНайти(ЗначениеЗаголовка, """", , ПозицияНачала); + Если ПозицияОкончания > 0 Тогда + фРезультат.Дополнение = Сред(ЗначениеЗаголовка, ПозицияНачала, ПозицияОкончания - ПозицияНачала); + КонецЕсли; + КонецЕсли; + + Возврат фРезультат; +КонецФункции #КонецОбласти diff --git "a/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\222\321\213\320\267\320\276\320\262\320\241\320\265\321\200\320\262\320\265\321\200\320\260/Ext/Module.bsl" "b/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\222\321\213\320\267\320\276\320\262\320\241\320\265\321\200\320\262\320\265\321\200\320\260/Ext/Module.bsl" index 762dd87..c054f15 100644 --- "a/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\222\321\213\320\267\320\276\320\262\320\241\320\265\321\200\320\262\320\265\321\200\320\260/Ext/Module.bsl" +++ "b/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\222\321\213\320\267\320\276\320\262\320\241\320\265\321\200\320\262\320\265\321\200\320\260/Ext/Module.bsl" @@ -22,6 +22,15 @@ Возврат КлиентHTTP.ТекущаяУниверсальнаяДатаНаСервере(); КонецФункции +// Возвращает текущий Unix Timestamp +// +// Возвращаемое значение: +// Число - количество секунд, прошедших с 01.01.1970 по текущее время UTC +// +Функция ВременнаяМеткаUnix() Экспорт + Возврат КлиентHTTP.ВременнаяМеткаUnix(); +КонецФункции + // Возвращает раскодированный URI // // Параметры: @@ -47,6 +56,51 @@ Возврат КлиентHTTP.ЗаголовокDigest(Конфигурация, КонтекстВыполненияАдресВХ); КонецФункции +// Возвращает заголовки AWS4-аутентификации +// +// Параметры: +// Метод - Строка - имя HTTP-метода +// Конфигурация - Структура - конфигурация выполнения запроса +// ДанныеАдресВХ - Строка - адрес данных тела запроса во временном хранилище +// +// Возвращаемое значение: +// Массив - заголовки AWS4-авторизации +// +Функция ЗаголовкиAWS4(Знач Метод, Знач Конфигурация, Знач ДанныеАдресВХ) Экспорт + Возврат КлиентHTTP.ЗаголовкиAWS4(Метод, Конфигурация, ДанныеАдресВХ); +КонецФункции + +// Возвращает значение заголовка Hawk-аутентификации +// Расчёт подписи содержимого тела запроса не обязателен для Hawk-аутентификации. +// +// Параметры: +// Метод - Строка - имя HTTP-метода +// Конфигурация - Структура - конфигурация выполнения запроса +// ДанныеАдресВХ - Строка, Неопределено - адрес данных тела запроса во временном хранилище (необязательный) +// +// Возвращаемое значение: +// Строка - значение заголовка Hawk-аутентификации +// +Функция ЗаголовокHawk(Знач Метод, Конфигурация, Знач ДанныеАдресВХ = Неопределено) Экспорт + Возврат КлиентHTTP.ЗаголовокHawk(Метод, Конфигурация, ДанныеАдресВХ); +КонецФункции + +// Возвращает результат валидации ответа сервера по указанному заголовку (Hawk аутентификация) +// Если валидация прошла успешно, вернётся Истина. +// +// Параметры: +// ЗначениеЗаголовка - Строка - значение заголовка ответа сервера с данными Hawk аутентификации +// КонтекстHawk - Структура - данные Hawk аутентификации запроса +// ДанныеАдресВХ - Строка - адрес данных тела ответа и MIME-типа во временном хранилище +// ОписаниеОшибки - Строка - описание ошибки валидации ответа +// +// Возвращаемое значение: +// Булево - результат валидации +// +Функция ОтветСЗаголовкомHawkКорректен(Знач ЗначениеЗаголовка, Знач КонтекстHawk, Знач ДанныеАдресВХ, ОписаниеОшибки) Экспорт + Возврат КлиентHTTP.ОтветСЗаголовкомHawkКорректен(ЗначениеЗаголовка, КонтекстHawk, ДанныеАдресВХ, ОписаниеОшибки); +КонецФункции + // Добавляет запись ошибки в журнал регистрации // // Параметры: @@ -58,7 +112,7 @@ КлиентHTTP.ДобавитьЗаписьОшибкиВЖурналРегистрации(Данные, Комментарий, СобытиеВТранзакции); КонецПроцедуры -// Возвращает коллекцию раскодированных строк +// (УСТАРЕЛО) Возвращает коллекцию раскодированных строк // // Параметры: // КоллекцияСтрок - Структура - коллекция строк для раскодирования (обрабатываются только значения) @@ -71,7 +125,31 @@ Возврат КлиентHTTP.РаскодированныеСтроки(КоллекцияСтрок, Способ); КонецФункции -// Возвращает коллекцию кодированных строк +// Возвращает множество раскодированных строк способом КодировкаURL +// +// Параметры: +// МножествоСтрок - Соответствие - множество строк для раскодирования +// +// Возвращаемое значение: +// Соответствие - множество раскодированных строк +// +Функция РаскодированныеСтрокиURL(Знач МножествоСтрок) Экспорт + Возврат КлиентHTTP.РаскодированныеСтрокиURL(МножествоСтрок); +КонецФункции + +// Возвращает множество раскодированных строк способом URLВКодировкеURL +// +// Параметры: +// МножествоСтрок - Соответствие - множество строк для раскодирования +// +// Возвращаемое значение: +// Соответствие - множество раскодированных строк +// +Функция РаскодированныеСтрокиURLвURL(Знач МножествоСтрок) Экспорт + Возврат КлиентHTTP.РаскодированныеСтрокиURLвURL(МножествоСтрок); +КонецФункции + +// (УСТАРЕЛО) Возвращает коллекцию кодированных строк // // Параметры: // КоллекцияСтрок - Структура - коллекция строк для кодирования (обрабатываются только значения) @@ -84,6 +162,30 @@ Возврат КлиентHTTP.ЗакодированныеСтроки(КоллекцияСтрок, Способ); КонецФункции +// Возвращает множество кодированных строк способом КодировкаURL +// +// Параметры: +// МножествоСтрок - Соответствие - множество строк для кодирования +// +// Возвращаемое значение: +// Соответствие - множество кодированных строк +// +Функция КодированныеСтрокиURL(Знач МножествоСтрок) Экспорт + Возврат КлиентHTTP.КодированныеСтрокиURL(МножествоСтрок); +КонецФункции + +// Возвращает множество кодированных строк способом URLВКодировкеURL +// +// Параметры: +// МножествоСтрок - Соответствие - множество строк для кодирования +// +// Возвращаемое значение: +// Соответствие - множество кодированных строк +// +Функция КодированныеСтрокиURLвURL(Знач МножествоСтрок) Экспорт + Возврат КлиентHTTP.КодированныеСтрокиURLвURL(МножествоСтрок); +КонецФункции + // Возвращает коллекцию раскодированных полей HTML-Формы // // Параметры: diff --git "a/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\232\320\273\320\270\320\265\320\275\321\202\320\241\320\265\321\200\320\262\320\265\321\200/Ext/Module.bsl" "b/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\232\320\273\320\270\320\265\320\275\321\202\320\241\320\265\321\200\320\262\320\265\321\200/Ext/Module.bsl" index c6714c2..236ab4b 100644 --- "a/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\232\320\273\320\270\320\265\320\275\321\202\320\241\320\265\321\200\320\262\320\265\321\200/Ext/Module.bsl" +++ "b/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\232\320\273\320\270\320\265\320\275\321\202\320\241\320\265\321\200\320\262\320\265\321\200/Ext/Module.bsl" @@ -17,7 +17,7 @@ // * ИмяФайлаТела - Строка, Неопределено - имя файла, в который было записано тело ответа // Функция Получить(Знач ИдентификаторРесурса, Знач ПараметрыЗапроса = Неопределено, ДополнительныеПараметры = Неопределено) Экспорт - Возврат ВыполнитьЗапросHTTP( + Возврат ВыполненныйЗапросHTTP( КлиентHTTPПовтИсп.МетодGET(), КонфигурацияЗапроса(ИдентификаторРесурса, ПараметрыЗапроса, ДополнительныеПараметры) ); @@ -38,7 +38,7 @@ // * ИмяФайлаТела - Строка, Неопределено - имя файла, в который было записано тело ответа // Функция ПолучитьЗаголовки(Знач ИдентификаторРесурса, Знач ПараметрыЗапроса = Неопределено, ДополнительныеПараметры = Неопределено) Экспорт - Возврат ВыполнитьЗапросHTTP( + Возврат ВыполненныйЗапросHTTP( КлиентHTTPПовтИсп.МетодHEAD(), КонфигурацияЗапроса(ИдентификаторРесурса, ПараметрыЗапроса, ДополнительныеПараметры) ); @@ -64,7 +64,7 @@ ДобавитьРазмерДанныхВЗаголовкиЗапроса(Конфигурация.Заголовки, Конфигурация.ДополнительныеПараметры, Данные); - Возврат ВыполнитьЗапросHTTP(КлиентHTTPПовтИсп.МетодPOST(), Конфигурация, Данные); + Возврат ВыполненныйЗапросHTTP(КлиентHTTPПовтИсп.МетодPOST(), Конфигурация, Данные); КонецФункции // Реализация PUT @@ -87,7 +87,7 @@ ДобавитьРазмерДанныхВЗаголовкиЗапроса(Конфигурация.Заголовки, Конфигурация.ДополнительныеПараметры, Данные); - Возврат ВыполнитьЗапросHTTP(КлиентHTTPПовтИсп.МетодPUT(), Конфигурация, Данные); + Возврат ВыполненныйЗапросHTTP(КлиентHTTPПовтИсп.МетодPUT(), Конфигурация, Данные); КонецФункции // Реализация PATCH @@ -110,7 +110,7 @@ ДобавитьРазмерДанныхВЗаголовкиЗапроса(Конфигурация.Заголовки, Конфигурация.ДополнительныеПараметры, Данные); - Возврат ВыполнитьЗапросHTTP(КлиентHTTPПовтИсп.МетодPATCH(), Конфигурация, Данные); + Возврат ВыполненныйЗапросHTTP(КлиентHTTPПовтИсп.МетодPATCH(), Конфигурация, Данные); КонецФункции // Реализация DELETE @@ -136,7 +136,7 @@ ДобавитьРазмерДанныхВЗаголовкиЗапроса(Конфигурация.Заголовки, Конфигурация.ДополнительныеПараметры, Данные); КонецЕсли; - Возврат ВыполнитьЗапросHTTP(КлиентHTTPПовтИсп.МетодDELETE(), Конфигурация, Данные); + Возврат ВыполненныйЗапросHTTP(КлиентHTTPПовтИсп.МетодDELETE(), Конфигурация, ПолучитьДвоичныеДанныеИзСтроки(Данные, КодировкаИзДопПараметров(Конфигурация.ДополнительныеПараметры))); КонецФункции #Область ДЕКОРАТОРЫ @@ -192,7 +192,7 @@ // Функция ОтправитьФайл(Знач ИдентификаторРесурса, Знач Данные, ДополнительныеПараметры = Неопределено, Знач ПараметрыЗапроса = Неопределено) Экспорт Если НЕ Данные.Существует() Тогда - ВызватьИсключение СтрШаблон("Файл %1 не существует", Данные.ПолноеИмя); + ВызватьИсключение СтрШаблон("Файл не обнаружен '%1'", Данные.ПолноеИмя); КонецЕсли; Если ДополнительныеПараметры = Неопределено Тогда @@ -359,7 +359,7 @@ // Функция ЗаписатьФайл(Знач ИдентификаторРесурса, Знач Данные, ДополнительныеПараметры = Неопределено, Знач ПараметрыЗапроса = Неопределено) Экспорт Если НЕ Данные.Существует() Тогда - ВызватьИсключение СтрШаблон("Файл %1 не существует", Данные.ПолноеИмя); + ВызватьИсключение СтрШаблон("Файл не обнаружен '%1'", Данные.ПолноеИмя); КонецЕсли; Если ДополнительныеПараметры = Неопределено Тогда @@ -430,7 +430,7 @@ // Функция ИзменитьФайл(Знач ИдентификаторРесурса, Знач Данные, ДополнительныеПараметры = Неопределено, Знач ПараметрыЗапроса = Неопределено) Экспорт Если НЕ Данные.Существует() Тогда - ВызватьИсключение СтрШаблон("Файл %1 не существует", Данные.ПолноеИмя); + ВызватьИсключение СтрШаблон("Файл не обнаружен '%1'", Данные.ПолноеИмя); КонецЕсли; Если ДополнительныеПараметры = Неопределено Тогда @@ -602,6 +602,20 @@ Возврат КлиентHTTPКлиентСервер; КонецФункции +// Отмена требования попытки преобразования тела полученного ответа +// +// Параметры: +// ДополнительныеПараметры - Структура - конфигурация выполнения запроса +// +// Возвращаемое значение: +// ОбщийМодуль.КлиентHTTPКлиентСервер - модуль вызова функции +// +Функция ТелоОтветаКакДвоичныеДанные(ДополнительныеПараметры) Экспорт + ДополнительныеПараметры.Удалить("ПрочитатьТелоОтветаКак"); + + Возврат КлиентHTTPКлиентСервер; +КонецФункции + // Требование попытки преобразования тела полученного ответа в текст // // Параметры: @@ -758,6 +772,30 @@ Возврат КлиентHTTPКлиентСервер; КонецФункции +// Требование принудительно переключаться на метод GET для кодов перенаправления 301 и 302 +// +// Параметры: +// ДополнительныеПараметры - Структура - конфигурация выполнения запроса +// КакGET - Булево - установить переключение на GET (необязательный) +// +// Возвращаемое значение: +// ОбщийМодуль.КлиентHTTPКлиентСервер - модуль вызова функции +// +Функция ПеренаправленияКакGET(ДополнительныеПараметры, Знач КакGET = Истина) Экспорт + СессияАктивирована = ДополнительныеПараметры.Свойство("Сессия"); + Если КакGET Тогда + Если НЕ СессияАктивирована Тогда + ИспользоватьСессию(ДополнительныеПараметры); + КонецЕсли; + + ДополнительныеПараметры.Сессия.Вставить("ПеренаправлениеКакGET"); + ИначеЕсли СессияАктивирована Тогда + ДополнительныеПараметры.Сессия.Удалить("ПеренаправлениеКакGET"); + КонецЕсли; + + Возврат КлиентHTTPКлиентСервер; +КонецФункции + // Установка Basic-авторизации // // Параметры: @@ -819,7 +857,65 @@ // ОбщийМодуль.КлиентHTTPКлиентСервер - модуль вызова функции // Функция УстановитьBearerАвторизацию(ДополнительныеПараметры, Знач Токен) Экспорт - ДополнительныеПараметры.Вставить("Аутентификация", ОбъектАутентификации("Bearer", Токен, "")); + ДополнительныеПараметры.Вставить("Аутентификация", ОбъектАутентификацииBearer(Токен)); + + Возврат КлиентHTTPКлиентСервер; +КонецФункции + +// Установка AWS4-авторизации +// +// Параметры: +// ДополнительныеПараметры - Структура - конфигурация выполнения запроса +// КлючДоступа - Строка - AWS ключ доступа +// СекретныйКлюч - Строка - AWS секретный ключ +// Регион - Строка - AWS регион получателя запроса (необязательный) +// Сервис - Строка - AWS сервис получателя запроса (необязательный) +// +// Возвращаемое значение: +// ОбщийМодуль.КлиентHTTPКлиентСервер - модуль вызова функции +// +Функция УстановитьAWS4Авторизацию(ДополнительныеПараметры, Знач КлючДоступа, Знач СекретныйКлюч, Знач Регион = "", Знач Сервис = "") Экспорт + ДополнительныеПараметры.Вставить( + "Аутентификация", + ОбъектАутентификацииAWS4(КлючДоступа, СекретныйКлюч, СокрЛП(Регион), СокрЛП(Сервис)) + ); + + Возврат КлиентHTTPКлиентСервер; +КонецФункции + +// Установка Hawk-авторизации +// +// Параметры: +// ДополнительныеПараметры - Структура - конфигурация выполнения запроса +// Идентификатор - Строка - ID аутентификации +// Ключ - Строка - секретный ключ +// Дополнение - Строка - (ext) специфические данные клиента (необязательный) +// ИдентификаторПриложения - Строка - (app) идентификатор приложения (необязательный) +// Делегирование - Строка - (dlg) выданный идентификатор приложения (необязательный) +// +// Возвращаемое значение: +// ОбщийМодуль.КлиентHTTPКлиентСервер - модуль вызова функции +// +Функция УстановитьHawkАвторизацию(ДополнительныеПараметры, Знач Идентификатор, Знач Ключ, Знач Дополнение = "", Знач ИдентификаторПриложения = "", Знач Делегирование = "") Экспорт + ДополнительныеПараметры.Вставить( + "Аутентификация", + ОбъектАутентификацииHawk(Идентификатор, Ключ, СокрЛП(Дополнение), СокрЛП(ИдентификаторПриложения), СокрЛП(Делегирование)) + ); + + Возврат КлиентHTTPКлиентСервер; +КонецФункции + +// Установка пользовательского значения заголовка "User-Agent" +// +// Параметры: +// ДополнительныеПараметры - Структура - конфигурация выполнения запроса +// АгентПользователя - Строка - значение для заголовка User-Agent +// +// Возвращаемое значение: +// ОбщийМодуль.КлиентHTTPКлиентСервер - модуль вызова функции +// +Функция УстановитьАгентаПользователя(ДополнительныеПараметры, Знач АгентПользователя) Экспорт + ДополнительныеПараметры.Вставить("АгентПользователя", СокрЛП(АгентПользователя)); Возврат КлиентHTTPКлиентСервер; КонецФункции @@ -1157,18 +1253,38 @@ Функция ПараметрыЗапросаСтрокой(Знач Параметры) Экспорт фРезультат = Новый Массив; + ПараметрыИдентификатора = Новый Массив; + МножествоСтрок = Новый Соответствие; Для Каждого КЗ Из Параметры Цикл - ИмяПараметра = ФорматированноеИмяПараметраЗапроса(КЗ.Ключ); - Если ПустаяСтрока(ИмяПараметра) Тогда + Параметр = Новый Структура("Ключ, Значение", КлиентHTTPСлужебный.ФорматированноеИмяПараметраЗапроса(КЗ.Ключ), ""); + Если ПустаяСтрока(Параметр.Ключ) Тогда + Продолжить; + КонецЕсли; + МножествоСтрок.Вставить(Параметр.Ключ); + Если КЗ.Значение.Количество() = 0 Тогда + ПараметрыИдентификатора.Добавить(Параметр); Продолжить; КонецЕсли; Для Каждого ЗначениеПараметра Из КЗ.Значение Цикл - ФЗП = СокрЛП(ФорматированноеЗначениеПараметраЗапроса(ЗначениеПараметра)); - фРезультат.Добавить(ИмяПараметра + ?(ФЗП = "", "", "=") + ФЗП); + Параметр.Значение = КлиентHTTPСлужебный.ФорматированноеЗначениеПараметраЗапроса(ЗначениеПараметра); + Если Параметр.Значение <> "" Тогда + МножествоСтрок.Вставить(Параметр.Значение); + КонецЕсли; + + ПараметрыИдентификатора.Добавить(Параметр); КонецЦикла; КонецЦикла; + МножествоСтрок = КлиентHTTPВызовСервера.КодированныеСтрокиURLвURL(МножествоСтрок); + + Для Каждого Параметр Из ПараметрыИдентификатора Цикл + ИмяПараметра = МножествоСтрок.Получить(Параметр.Ключ); + ЗначениеПараметра = МножествоСтрок.Получить(Параметр.Значение); + + фРезультат.Добавить(ИмяПараметра + ?(ЗначениеПараметра = "", "", "=") + ЗначениеПараметра); + КонецЦикла; + Возврат ?(фРезультат.Количество() = 0, "", "?" + СтрСоединить(фРезультат, "&")); КонецФункции @@ -1197,6 +1313,48 @@ ОбъединитьПеченье(КонфигурацияПриемник.Сессия.Печенье, КонфигурацияИсточник.Сессия.Печенье, Заменять); КонецПроцедуры +// Возвращает значение заголовка по имени +// +// Параметры: +// ИмяЗаголовка - Строка - имя заголовка +// Заголовки - Соответствие - коллекция заголовков +// +// Возвращаемое значение: +// Строка, Неопределено - значение заголовка +// +Функция ЗначениеЗаголовка(Знач ИмяЗаголовка, Знач Заголовки) Экспорт + фРезультат = Неопределено; + ИмяЗаголовка = НРег(ИмяЗаголовка); + + Для Каждого КЗ Из Заголовки Цикл + Если НРег(КЗ.Ключ) = ИмяЗаголовка Тогда + фРезультат = КЗ.Значение; + Прервать; + КонецЕсли; + КонецЦикла; + + Возврат фРезультат; +КонецФункции + +// Возвращает значение заголовка Cookie для идентификатора ресурса +// +// Параметры: +// ИдентификаторРесурса - Строка, Структура - URI сервиса либо объект идентификатора ресурса +// ДополнительныеПараметры - Структура - конфигурация выполнения запроса +// +// Возвращаемое значение: +// Строка, Неопределено - значение заголовка Cookie +// +Функция ЗначениеЗаголовкаCookieРесурса(Знач ИдентификаторРесурса, Знач ДополнительныеПараметры) Экспорт + Если НЕ ДополнительныеПараметры.Свойство("Сессия") Тогда + Возврат Неопределено; + КонецЕсли; + + ДанныеURI = СтруктураИдентификатораРесурса(ИдентификаторРесурса); + + Возврат ЗначениеЗаголовкаCookie(ДанныеURI, ДополнительныеПараметры.Сессия); +КонецФункции + // Возвращает MIME-тип из заголовков // // Параметры: @@ -1206,7 +1364,7 @@ // Строка, Неопределено - значение заголовка Content-Type // Функция ТипMIMEИзЗаголовков(Знач Заголовки) Экспорт - ТипКонтента = ЗначениеЗаголовка("Content-Type", Заголовки); + ТипКонтента = ЗначениеЗаголовка(КлиентHTTPПовтИсп.ЗаголовокТипКонтента(), Заголовки); Если ТипКонтента = Неопределено Тогда Возврат Неопределено; КонецЕсли; @@ -1225,7 +1383,7 @@ // Строка, Неопределено - значение charset заголовка Content-Type // Функция КодировкаИзЗаголовков(Знач Заголовки) Экспорт - ТипКонтента = ЗначениеЗаголовка("Content-Type", Заголовки); + ТипКонтента = ЗначениеЗаголовка(КлиентHTTPПовтИсп.ЗаголовокТипКонтента(), Заголовки); Если ТипКонтента = Неопределено Тогда Возврат Неопределено; КонецЕсли; @@ -1234,30 +1392,74 @@ Возврат ?(ПозицияКодировки = 0, Неопределено, Сред(ТипКонтента, ПозицияКодировки + 8)); КонецФункции + +// Возвращает результат валидации ответа сервера по указанному заголовку (Hawk аутентификация) +// +// Параметры: +// Ответ - Структура - объект ответа сервера +// ИмяЗаголовка - Строка - имя заголовка ответа сервера с данными Hawk аутентификации +// ОписаниеОшибки - Строка - описание ошибки валидации ответа +// +// Возвращаемое значение: +// Строка, Неопределено - значение charset заголовка Content-Type +// +Функция ОтветСЗаголовкомHawkКорректен(Знач Ответ, Знач ИмяЗаголовка, ОписаниеОшибки) Экспорт + Если НЕ Ответ.КонтекстВыполнения.Свойство("АутентификацияHawk") Тогда + ОписаниеОшибки = "Отсутствует контекст Hawk аутентификации"; + Возврат Ложь; + КонецЕсли; + Если Ответ.КодСостояния < 200 ИЛИ Ответ.КодСостояния > 299 Тогда + Возврат Истина; + КонецЕсли; + Если ТипЗнч(Ответ.Тело) <> Тип("ДвоичныеДанные") Тогда + ОписаниеОшибки = "Валидация доступна только для ответа с телом типа ДвоичныеДанные"; + Возврат Ложь; + КонецЕсли; + + ЗначениеЗаголовкаHawk = ЗначениеЗаголовка(ИмяЗаголовка, Ответ.Заголовки); + Если ЗначениеЗаголовкаHawk = Неопределено Тогда + ОписаниеОшибки = "В ответе отсутствует заголовок Hawk аутентификации"; + Возврат Ложь; + КонецЕсли; + + Данные = Новый Структура( + "Тело, ТипMIME", + Ответ.Тело, + ЗначениеЗаголовка(КлиентHTTPПовтИсп.ЗаголовокТипКонтента(), Ответ.Заголовки) + ); + + Возврат КлиентHTTPВызовСервера.ОтветСЗаголовкомHawkКорректен( + ЗначениеЗаголовкаHawk, + Ответ.КонтекстВыполнения.АутентификацияHawk, + ПоместитьВоВременноеХранилище(Данные, Новый УникальныйИдентификатор), + ОписаниеОшибки + ); +КонецФункции #КонецОбласти #Область СлужебныеПроцедурыИФункции -Функция ВыполнитьЗапросHTTP(Знач Метод, Знач Конфигурация, Знач Данные = Неопределено, Знач НомерПеренаправления = 0) +Функция ВыполненныйЗапросHTTP(Знач Метод, Знач Конфигурация, Знач Данные = Неопределено, Знач НомерПеренаправления = 0) + Контекст = КонтекстВыполнения(Метод, НомерПеренаправления, Данные); + + ПрименитьAWS4Аутентификацию(Метод, Данные, Конфигурация); + ПрименитьHawkАутентификацию(Метод, Данные, Конфигурация, Контекст); + Соединение = НовоеHTTPСоединениеСПереиспользованием(Конфигурация); Запрос = Новый HTTPЗапрос(АдресРесурсаЗапроса(Конфигурация), Конфигурация.Заголовки); - Если Метод = КлиентHTTPПовтИсп.МетодPOST() ИЛИ Метод = КлиентHTTPПовтИсп.МетодPUT() ИЛИ Метод = КлиентHTTPПовтИсп.МетодDELETE() Тогда - Если ТипЗнч(Данные) = Тип("Строка") Тогда - Запрос.УстановитьТелоИзСтроки(Данные, КодировкаИзДопПараметров(Конфигурация.ДополнительныеПараметры)); - Иначе - Запрос.УстановитьТелоИзДвоичныхДанных(Данные); - КонецЕсли; + Если МетодПодразумеваетТелоЗапроса(Метод) Тогда + Запрос.УстановитьТелоИзДвоичныхДанных(Данные); КонецЕсли; Возврат ОбработанныйОтвет( Соединение.ВызватьHTTPМетод(Метод, Запрос, ИмяВыходногоФайлаИзДопПараметров(Конфигурация.ДополнительныеПараметры)), Конфигурация, - КонтекстВыполнения(Метод, НомерПеренаправления, Данные) + Контекст ); КонецФункции Функция КонтекстВыполнения(Знач Метод, Знач НомерПеренаправления, Знач Данные) - Возврат Новый ФиксированнаяСтруктура("Метод, НомерПеренаправления, Данные", Метод, НомерПеренаправления, Данные); + Возврат Новый ФиксированнаяСтруктура("Метод, НомерПеренаправления, Данные, Значения", Метод, НомерПеренаправления, Данные, Новый Структура); КонецФункции Функция КонфигурацияЗапроса(Знач ИдентификаторРесурса, Знач ПараметрыЗапроса = Неопределено, ДополнительныеПараметры = Неопределено) @@ -1269,10 +1471,49 @@ КонецЕсли; ДанныеURI = СтруктураИдентификатораРесурса(ИдентификаторРесурса); - Параметры = ОбъединениеПараметровЗапросаВСтроку(ДанныеURI.Параметры, ПараметрыЗапроса); + Параметры = ОбъединениеПараметровЗапроса(ДанныеURI.Параметры, ПараметрыЗапроса); + ПараметрыСтрокой = ПараметрыЗапросаСтрокой(Параметры); Заголовки = ЗаголовкиЗапроса(ДанныеURI, ДополнительныеПараметры); - Возврат Новый Структура("ДанныеURI, Параметры, Заголовки, ДополнительныеПараметры", ДанныеURI, Параметры, Заголовки, ДополнительныеПараметры); + Возврат Новый Структура("ДанныеURI, Параметры, ПараметрыСтрокой, Заголовки, ДополнительныеПараметры", ДанныеURI, Параметры, ПараметрыСтрокой, Заголовки, ДополнительныеПараметры); +КонецФункции + +Функция МетодПодразумеваетТелоЗапроса(Знач Метод) + Возврат Метод = КлиентHTTPПовтИсп.МетодPOST() + ИЛИ Метод = КлиентHTTPПовтИсп.МетодPUT() + ИЛИ Метод = КлиентHTTPПовтИсп.МетодDELETE() + ИЛИ Метод = КлиентHTTPПовтИсп.МетодPATCH(); +КонецФункции + +Функция СоставляющиеАдресаРесурса(Знач АдресРесурса) + фРезультат = Новый Структура("Путь, Параметры, Фрагмент", "/", НовыеПараметрыЗапроса(), ""); + + АдресРесурса = СокрЛП(АдресРесурса); + Если АдресРесурса = "" ИЛИ АдресРесурса = "/" Тогда + Возврат фРезультат; + КонецЕсли; + Если НЕ СтрНачинаетсяС(АдресРесурса, "/") Тогда + АдресРесурса = "/" + АдресРесурса; + КонецЕсли; + + ДлинаАдресаРесурса = СтрДлина(АдресРесурса); + ПозицияОкончанияПути = ДлинаАдресаРесурса; + ПозицияСимволаПараметров = СтрНайти(АдресРесурса, "?"); + ПозицияСимволаФрагмента = СтрНайти(АдресРесурса, "#", , ?(ПозицияСимволаПараметров = 0, 1, ПозицияСимволаПараметров)); + ПозицияОкончанияПути = ?(ПозицияСимволаПараметров = 0, ПозицияСимволаФрагмента, ПозицияСимволаПараметров); + + фРезультат.Путь = Лев( + АдресРесурса, + ?( + ПозицияОкончанияПути = 0, + ДлинаАдресаРесурса, + ПозицияОкончанияПути - 1 + ) + ); + фРезультат.Параметры = ПараметрыИдентификатора(АдресРесурса, ПозицияСимволаПараметров, ПозицияСимволаФрагмента); + фРезультат.Фрагмент = ?(ПозицияСимволаФрагмента = 0, "", Сред(АдресРесурса, ПозицияСимволаФрагмента + 1)); + + Возврат фРезультат; КонецФункции Функция ДлинаСхемыИдентификатораРесурса(ДанныеURI, Знач ИдентификаторРесурса) @@ -1292,12 +1533,16 @@ Возврат фРезультат; КонецФункции -Процедура РазобратьОснованиеИдентификатораРесурса(ДанныеURI, Знач ИдентификаторРесурса, Знач ПозицияНачала, ПозицияОкончания) +Процедура РазобратьОснованиеИдентификатораРесурса(ДанныеURI, Знач ИдентификаторРесурса, Знач ПозицияНачала, ПозицияПараметров, ПозицияФрагмента) ОписаниеТипаЧисло = Новый ОписаниеТипов("Число"); ДлинаИдентификатораРесурса = СтрДлина(ИдентификаторРесурса); ПозицияНачалаАдресаРесурса = СтрНайти(ИдентификаторРесурса, "/", , ПозицияНачала); - ПозицияОкончания = СтрНайти(ИдентификаторРесурса, "?", , ПозицияНачала); + ПозицияПоиска = ?(ПозицияНачалаАдресаРесурса = 0, ПозицияНачала, ПозицияНачалаАдресаРесурса); + ПозицияПараметров = СтрНайти(ИдентификаторРесурса, "?", , ПозицияПоиска); + ПозицияПоиска = ?(ПозицияПараметров = 0, ПозицияПоиска, ПозицияПараметров); + ПозицияФрагмента = СтрНайти(ИдентификаторРесурса, "#", , ПозицияПоиска); + ПозицияОкончания = ?(ПозицияПараметров = 0, ПозицияФрагмента, ПозицияПараметров); Обращение = Сред( ИдентификаторРесурса, @@ -1318,15 +1563,15 @@ Если ПозицияРазделителяАвторизации = 0 Тогда ПозицияРазделителяАвторизации = ДлинаАвторизации + 1; КонецЕсли; + ЗакодированныйПользователь = СокрЛП(Лев(Авторизация, ПозицияРазделителяАвторизации - 1)); + ЗакодированныйПароль = Прав(Авторизация, ДлинаАвторизации - ПозицияРазделителяАвторизации); + МножествоСтрок = Новый Соответствие; + МножествоСтрок.Вставить(ЗакодированныйПользователь); + МножествоСтрок.Вставить(ЗакодированныйПароль); - ЗакодированныеДанные = Новый Структура("Пользователь, Пароль"); - ЗакодированныеДанные.Пользователь = СокрЛП(Лев(Авторизация, ПозицияРазделителяАвторизации - 1)); - ЗакодированныеДанные.Пароль = Прав(Авторизация, ДлинаАвторизации - ПозицияРазделителяАвторизации); - - РаскодированныеДанные = КлиентHTTPВызовСервера.РаскодированныеСтроки(ЗакодированныеДанные); - - ДанныеURI.Пользователь = РаскодированныеДанные.Пользователь; - ДанныеURI.Пароль = РаскодированныеДанные.Пароль; + МножествоСтрок = КлиентHTTPВызовСервера.РаскодированныеСтрокиURLвURL(МножествоСтрок); + ДанныеURI.Пользователь = МножествоСтрок.Получить(ЗакодированныйПользователь); + ДанныеURI.Пароль = МножествоСтрок.Получить(ЗакодированныйПароль); КонецЕсли; ИмяХоста = Прав(Обращение, ДлинаОбращения - ПозицияПослеАвторизации); @@ -1347,7 +1592,7 @@ ДанныеURI.Сервер = ?(ПозицияПорта = 0, ИмяХоста, Лев(ИмяХоста, ПозицияПорта - 1)); Если ПозицияНачалаАдресаРесурса > 0 Тогда - ДанныеURI.АдресРесурса = Сред( + ДанныеURI.Путь = Сред( ИдентификаторРесурса, ПозицияНачалаАдресаРесурса, ?( @@ -1359,17 +1604,27 @@ КонецЕсли; КонецПроцедуры -Функция ПараметрыИдентификатора(Знач ИдентификаторРесурса, Знач ПозицияНачала) Экспорт +Функция ПараметрыИдентификатора(Знач ИдентификаторРесурса, Знач ПозицияНачала, Знач ПозицияОкончания) фРезультат = НовыеПараметрыЗапроса(); + ДлинаИдентификатораРесурса = СтрДлина(ИдентификаторРесурса); ПараметрыСтрока = ?( - ПозицияНачала = 0, + ПозицияНачала = 0 ИЛИ ПозицияНачала = ДлинаИдентификатораРесурса, "", - Сред(ИдентификаторРесурса, ПозицияНачала + 1) + Сред( + ИдентификаторРесурса, + ПозицияНачала + 1, + ?( + ПозицияОкончания = 0, + ДлинаИдентификатораРесурса, + ПозицияОкончания - 1 + ) - ПозицияНачала + ) ); - Параметры = СтрРазделить(ПараметрыСтрока, "&", Ложь); - Для Каждого Параметр Из Параметры Цикл + Параметры = Новый Массив; + МножествоСтрок = Новый Соответствие; + Для Каждого Параметр Из СтрРазделить(ПараметрыСтрока, "&", Ложь) Цикл ПозицияРазделителя = СтрНайти(Параметр, "="); Если ПозицияРазделителя = 0 Тогда ПозицияРазделителя = СтрДлина(Параметр) + 1; @@ -1382,6 +1637,17 @@ ЗначениеПараметра = Сред(Параметр, ПозицияРазделителя + 1); + Параметры.Добавить(Новый Структура("Ключ, Значение", ИмяПараметра, ЗначениеПараметра)); + МножествоСтрок.Вставить(ИмяПараметра); + МножествоСтрок.Вставить(ЗначениеПараметра); + КонецЦикла; + + МножествоСтрок = КлиентHTTPВызовСервера.РаскодированныеСтрокиURLвURL(МножествоСтрок); + + Для Каждого Параметр Из Параметры Цикл + ИмяПараметра = МножествоСтрок.Получить(Параметр.Ключ); + ЗначениеПараметра = МножествоСтрок.Получить(Параметр.Значение); + ДобавитьПараметр(фРезультат, ИмяПараметра, ЗначениеПараметра); КонецЦикла; @@ -1390,34 +1656,39 @@ Функция СтруктураИдентификатораРесурса(Знач ИдентификаторРесурса) фРезультат = Новый Структура( - "Сервер, АдресРесурса, Пользователь, Пароль, Порт, ЗащищенноеСоединение, Параметры", + "Сервер, Путь, Пользователь, Пароль, Порт, ЗащищенноеСоединение, Параметры, Фрагмент", "", // Сервер - "/", // АдресРесурса + "/", // Путь "", // Пользователь "", // Пароль 80, // Порт Ложь, // ЗащищенноеСоединение - Неопределено // Параметры + Неопределено, // Параметры + "" // Фрагмент ); Если ТипЗнч(ИдентификаторРесурса) = Тип("Структура") Тогда + АдресРесурса = СоставляющиеАдресаРесурса(ИдентификаторРесурса.АдресРесурса); фРезультат.Сервер = ИдентификаторРесурса.Сервер; - фРезультат.АдресРесурса = ИдентификаторРесурса.АдресРесурса; + фРезультат.Путь = АдресРесурса.Путь; фРезультат.Порт = ИдентификаторРесурса.Порт; - фРезультат.Параметры = НовыеПараметрыЗапроса(); + фРезультат.Параметры = АдресРесурса.Параметры; фРезультат.ЗащищенноеСоединение = ИдентификаторРесурса.ЗащищенноеСоединение; фРезультат.Пользователь = ИдентификаторРесурса.Пользователь; фРезультат.Пароль = ИдентификаторРесурса.Пароль; + фРезультат.Фрагмент = АдресРесурса.Фрагмент; Возврат фРезультат; КонецЕсли; ПозицияНачалаПоиска = ДлинаСхемыИдентификатораРесурса(фРезультат, ИдентификаторРесурса); - ПозицияНачалаСтрокиПараметров = 0; - РазобратьОснованиеИдентификатораРесурса(фРезультат, ИдентификаторРесурса, ПозицияНачалаПоиска, ПозицияНачалаСтрокиПараметров); + ПозицияСимволаПараметров = 0; + ПозицияСимволаФрагмента = 0; + РазобратьОснованиеИдентификатораРесурса(фРезультат, ИдентификаторРесурса, ПозицияНачалаПоиска, ПозицияСимволаПараметров, ПозицияСимволаФрагмента); - фРезультат.Параметры = ПараметрыИдентификатора(ИдентификаторРесурса, ПозицияНачалаСтрокиПараметров); + фРезультат.Параметры = ПараметрыИдентификатора(ИдентификаторРесурса, ПозицияСимволаПараметров, ПозицияСимволаФрагмента); + фРезультат.Фрагмент = ?(ПозицияСимволаФрагмента = 0, "", Сред(ИдентификаторРесурса, ПозицияСимволаФрагмента + 1)); Возврат фРезультат; КонецФункции @@ -1474,18 +1745,18 @@ ); КонецФункции -Функция ОбъединениеПараметровЗапросаВСтроку(Знач ПараметрыURI, Знач ПараметрыЗапроса) - МножествоПараметров = Новый Соответствие; +Функция ОбъединениеПараметровЗапроса(Знач ПараметрыURI, Знач ПараметрыЗапроса) + фРезультат = Новый Соответствие; Для Каждого КЗ Из ПараметрыURI Цикл - МножествоПараметров.Вставить(КЗ.Ключ, КЗ.Значение); + фРезультат.Вставить(КЗ.Ключ, КЗ.Значение); КонецЦикла; Для Каждого КЗ Из ПараметрыЗапроса Цикл - МножествоПараметров.Вставить(КЗ.Ключ, КЗ.Значение); + фРезультат.Вставить(КЗ.Ключ, КЗ.Значение); КонецЦикла; - Возврат ПараметрыЗапросаСтрокой(МножествоПараметров); + Возврат фРезультат; КонецФункции Функция ЗаголовкиЗапроса(Знач ДанныеURI, ДополнительныеПараметры) @@ -1501,6 +1772,8 @@ КонецЦикла; КонецЕсли; + ДобавитьХостВЗаголовкиЗапроса(фРезультат, ДанныеURI); + ДобавитьАгентаПользователяВЗаголовкиЗапроса(фРезультат, ДополнительныеПараметры); ДобавитьТипКонтентаВЗаголовкиЗапроса(фРезультат, ДополнительныеПараметры); ДобавитьКодировкуВЗаголовкиЗапроса(фРезультат, ДополнительныеПараметры); ДобавитьРазделительПолейФормыВЗаголовкиЗапроса(фРезультат, ДополнительныеПараметры); @@ -1520,23 +1793,47 @@ Возврат ?(ДополнительныеПараметры.Свойство("ИмяВыходногоФайла"), ДополнительныеПараметры.ИмяВыходногоФайла, ""); КонецФункции +Процедура ДобавитьХостВЗаголовкиЗапроса(Заголовки, Знач ДанныеURI) + Хост = КлиентHTTPСлужебный.НормализованныйАдресСервера(ДанныеURI.Сервер); + + Заголовки.Вставить(КлиентHTTPПовтИсп.ЗаголовокХост(), ?( + ЗначениеЗаполнено(ДанныеURI.Порт) + И (ДанныеURI.ЗащищенноеСоединение И ДанныеURI.Порт <> 443 + ИЛИ НЕ ДанныеURI.ЗащищенноеСоединение И ДанныеURI.Порт <> 80), + СтрШаблон("%1:%2", Хост, Формат(ДанныеURI.Порт, "ЧГ=")), + Хост + )); +КонецПроцедуры + +Процедура ДобавитьАгентаПользователяВЗаголовкиЗапроса(Заголовки, Знач ДополнительныеПараметры) + Перем АгентПользователя; + + ДополнительныеПараметры.Свойство("АгентПользователя", АгентПользователя); + Если ЗначениеЗаполнено(АгентПользователя) Тогда + Заголовки.Вставить(КлиентHTTPПовтИсп.ЗаголовокАгентПользователя(), АгентПользователя); + КонецЕсли; +КонецПроцедуры + Процедура ДобавитьТипКонтентаВЗаголовкиЗапроса(Заголовки, Знач ДополнительныеПараметры) Если ДополнительныеПараметры.Свойство("ТипMIME") Тогда - Заголовки.Вставить("Content-Type", ДополнительныеПараметры.ТипMIME); + Заголовки.Вставить(КлиентHTTPПовтИсп.ЗаголовокТипКонтента(), ДополнительныеПараметры.ТипMIME); КонецЕсли; КонецПроцедуры Процедура ДобавитьКодировкуВЗаголовкиЗапроса(Заголовки, Знач ДополнительныеПараметры) - ТекущееЗначение = Заголовки.Получить("Content-Type"); + ТекущееЗначение = Заголовки.Получить(КлиентHTTPПовтИсп.ЗаголовокТипКонтента()); Если ДополнительныеПараметры.Свойство("Кодировка") И ТекущееЗначение <> Неопределено Тогда - Заголовки.Вставить("Content-Type", ТекущееЗначение + "; charset=" + КодировкаИзДопПараметров(ДополнительныеПараметры)); + Заголовки.Вставить( + КлиентHTTPПовтИсп.ЗаголовокТипКонтента(), + ТекущееЗначение + "; charset=" + КодировкаИзДопПараметров(ДополнительныеПараметры) + ); КонецЕсли; КонецПроцедуры Процедура ДобавитьСжатиеВЗаголовкиЗапроса(Заголовки, Знач ДополнительныеПараметры) Если ДополнительныеПараметры.Свойство("СжатиеОтвета") Тогда - Заголовки.Вставить("Accept-Encoding", ДополнительныеПараметры.СжатиеОтвета); + Заголовки.Вставить(КлиентHTTPПовтИсп.ЗаголовокДопустимыеСпособыКодированияОтвета(), ДополнительныеПараметры.СжатиеОтвета); КонецЕсли; КонецПроцедуры @@ -1545,11 +1842,9 @@ Возврат; КонецЕсли; - Если ДополнительныеПараметры.Сессия.Свойство("Печенье") Тогда - Печенье = ПеченьеДляURI(ДанныеURI, ДополнительныеПараметры.Сессия.Печенье); - Если ЗначениеЗаполнено(Печенье) Тогда - Заголовки.Вставить("Cookie", СтрСоединить(Печенье, "; ")); - КонецЕсли; + Значение = ЗначениеЗаголовкаCookie(ДанныеURI, ДополнительныеПараметры.Сессия); + Если ЗначениеЗаполнено(Значение) Тогда + Заголовки.Вставить(КлиентHTTPПовтИсп.ЗаголовокПеченье(), Значение); КонецЕсли; КонецПроцедуры @@ -1568,6 +1863,10 @@ ДополнительныеПараметры.Вставить("АвторизоватьсяDigest"); ИначеЕсли ТипАутентификации = "Bearer" Тогда ДобавитьBearerАутентификациюВЗаголовкиЗапроса(Заголовки, ДополнительныеПараметры.Аутентификация); + ИначеЕсли ТипАутентификации = "AWS4" Тогда + ЗарегистрироватьAWS4Аутентификацию(ДополнительныеПараметры); + ИначеЕсли ТипАутентификации = "Hawk" Тогда + ЗарегистрироватьHawkАутентификацию(ДополнительныеПараметры); Иначе ВызватьИсключение СтрШаблон("Неизвестный тип аутентификации: %1", ТипАутентификации); КонецЕсли; @@ -1576,7 +1875,7 @@ Процедура ДобавитьBasicАутентификациюВЗаголовкиЗапроса(Заголовки, Знач ДанныеАутентификации) СтрокаАутентификации = КлиентHTTPСлужебный.СтрокаBasicАвторизации(ДанныеАутентификации.Пользователь, ДанныеАутентификации.Пароль); - Заголовки.Вставить("Authorization", "Basic " + СтрокаАутентификации); + Заголовки.Вставить(КлиентHTTPПовтИсп.ЗаголовокТипАутентификации(), "Basic " + СтрокаАутентификации); КонецПроцедуры Процедура УстановитьNTLMАутентификацию(ДополнительныеПараметры, Знач ДанныеАутентификации) @@ -1586,23 +1885,82 @@ КонецПроцедуры Процедура ДобавитьBearerАутентификациюВЗаголовкиЗапроса(Заголовки, Знач ДанныеАутентификации) - Заголовки.Вставить("Authorization", "Bearer " + ДанныеАутентификации.Пользователь); + Заголовки.Вставить(КлиентHTTPПовтИсп.ЗаголовокТипАутентификации(), "Bearer " + ДанныеАутентификации.Токен); +КонецПроцедуры + +Процедура ЗарегистрироватьAWS4Аутентификацию(ДополнительныеПараметры) + ДополнительныеПараметры.Вставить("АвторизоватьсяAWS4", ДополнительныеПараметры.Аутентификация); +КонецПроцедуры + +Процедура ЗарегистрироватьHawkАутентификацию(ДополнительныеПараметры) + ДополнительныеПараметры.Вставить("АвторизоватьсяHawk", ДополнительныеПараметры.Аутентификация); КонецПроцедуры +Процедура ПрименитьAWS4Аутентификацию(Знач Метод, Знач Данные, Конфигурация) + Если НЕ Конфигурация.ДополнительныеПараметры.Свойство("АвторизоватьсяAWS4") Тогда + Возврат; + КонецЕсли; + + ДанныеАдресВХ = ПоместитьВоВременноеХранилище(?(Данные = Неопределено, "", Данные), Новый УникальныйИдентификатор); + Для Каждого Заголовок Из КлиентHTTPВызовСервера.ЗаголовкиAWS4(Метод, Конфигурация, ДанныеАдресВХ) Цикл + Конфигурация.Заголовки.Вставить(Заголовок.Ключ, Заголовок.Значение); + КонецЦикла; +КонецПроцедуры + +Процедура ПрименитьHawkАутентификацию(Знач Метод, Знач Данные, Конфигурация, Контекст) + Если НЕ Конфигурация.ДополнительныеПараметры.Свойство("АвторизоватьсяHawk") Тогда + Возврат; + КонецЕсли; + + ДанныеАдресВХ = ?( + Данные = Неопределено, + Неопределено, + ПоместитьВоВременноеХранилище(Данные, Новый УникальныйИдентификатор) + ); + + ЗначениеЗаголовкаHawk = КлиентHTTPВызовСервера.ЗаголовокHawk(Метод, Конфигурация, ДанныеАдресВХ); + Конфигурация.Заголовки.Вставить(КлиентHTTPПовтИсп.ЗаголовокТипАутентификации(), ЗначениеЗаголовкаHawk); + + Контекст.Значения.Вставить("АутентификацияHawk", КонтекстАутентификацииHawk(Контекст, Конфигурация)); +КонецПроцедуры + +Функция КонтекстАутентификацииHawk(Контекст, Конфигурация) + Аутентификация = Конфигурация.ДополнительныеПараметры.АвторизоватьсяHawk; + Возврат Новый ФиксированнаяСтруктура( + "Ключ, Дополнение, ИдентификаторПриложения, Делегирование, Метод, Хост, Порт, Путь, ВременнаяМетка, РазовоеСлово", + Аутентификация.Ключ, + Аутентификация.Дополнение, + Аутентификация.ИдентификаторПриложения, + Аутентификация.Делегирование, + Контекст.Метод, + Конфигурация.ДанныеURI.Сервер, + Конфигурация.ДанныеURI.Порт, + Конфигурация.ДанныеURI.Путь, + Аутентификация.ВременнаяМетка, + Аутентификация.РазовоеСлово + ); +КонецФункции + Процедура ДобавитьРазделительПолейФормыВЗаголовкиЗапроса(Заголовки, Знач ДополнительныеПараметры) - ТекущееЗначение = Заголовки.Получить("Content-Type"); + ТекущееЗначение = Заголовки.Получить(КлиентHTTPПовтИсп.ЗаголовокТипКонтента()); Если ДополнительныеПараметры.Свойство("Разделитель") И ТекущееЗначение <> Неопределено Тогда - Заголовки.Вставить("Content-Type", ТекущееЗначение + "; boundary=" + ДополнительныеПараметры.Разделитель); + Заголовки.Вставить( + КлиентHTTPПовтИсп.ЗаголовокТипКонтента(), + ТекущееЗначение + "; boundary=" + ДополнительныеПараметры.Разделитель + ); КонецЕсли; КонецПроцедуры Процедура ДобавитьРазмерДанныхВЗаголовкиЗапроса(Заголовки, Знач ДополнительныеПараметры, Знач Данные) Если ТипЗнч(Данные) = Тип("ДвоичныеДанные") Тогда - Заголовки.Вставить("Content-Length", XMLСтрока(Данные.Размер())); + Заголовки.Вставить(КлиентHTTPПовтИсп.ЗаголовокРазмерКонтента(), XMLСтрока(Данные.Размер())); ИначеЕсли ТипЗнч(Данные) = Тип("Строка") Тогда Кодировка = КодировкаИзДопПараметров(ДополнительныеПараметры); - Заголовки.Вставить("Content-Length", XMLСтрока(КлиентHTTPСлужебный.РазмерТекстовыхДанных(Данные, Кодировка))); + Заголовки.Вставить( + КлиентHTTPПовтИсп.ЗаголовокРазмерКонтента(), + XMLСтрока(КлиентHTTPСлужебный.РазмерТекстовыхДанных(Данные, Кодировка)) + ); Иначе ВызватьИсключение "Неизвестный тип данных: " + ТипЗнч(Данные); КонецЕсли; @@ -1647,12 +2005,37 @@ ЗаписьДанныхФормы.ЗаписатьСтроку(""); КонецПроцедуры +Функция ПеренаправлениеЗапросаHTTP(Знач НовыйИдентификаторРесурса, Знач Ответ, Знач Конфигурация, Знач КонтекстВыполнения) + Метод = КонтекстВыполнения.Метод; + Данные = КонтекстВыполнения.Данные; + Если ( + Ответ.КодСостояния = КлиентHTTPПовтИсп.КодСостоянияПеремещен() + ИЛИ Ответ.КодСостояния = КлиентHTTPПовтИсп.КодСостоянияНайден() + ) И Конфигурация.ДополнительныеПараметры.Сессия.Свойство("ПеренаправлениеКакGET") + Тогда + Метод = КлиентHTTPПовтИсп.МетодGET(); + Данные = Неопределено; + + Конфигурация.Заголовки.Удалить(КлиентHTTPПовтИсп.ЗаголовокРазмерКонтента()); + КонецЕсли; + + Конфигурация.ДанныеURI = СтруктураИдентификатораРесурса(НовыйИдентификаторРесурса); + Конфигурация.Параметры = ОбъединениеПараметровЗапроса(Конфигурация.ДанныеURI.Параметры, НовыеПараметрыЗапроса()); + Конфигурация.ПараметрыСтрокой = ПараметрыЗапросаСтрокой(Конфигурация.Параметры); + + Возврат ВыполненныйЗапросHTTP(Метод, Конфигурация, Данные, КонтекстВыполнения.НомерПеренаправления + 1); +КонецФункции + +Функция НовыйОбъектОбработанногоОтвета() + Возврат Новый Структура("КодСостояния, Заголовки, Тело, ИмяФайлаТела, КонтекстВыполнения"); +КонецФункции + Функция ОбработанныйОтвет(Знач Ответ, Знач Конфигурация, Знач КонтекстВыполнения) Если НЕ Конфигурация.ДополнительныеПараметры.Свойство("Сессия") Тогда - Возврат ОбъектОбработанногоОтвета(Ответ, Конфигурация.ДополнительныеПараметры); + Возврат ОбъектОбработанногоОтвета(Ответ, Конфигурация.ДополнительныеПараметры, КонтекстВыполнения); КонецЕсли; - Печенье = ЗначениеЗаголовка("Set-Cookie", Ответ.Заголовки); + Печенье = ЗначениеЗаголовка(КлиентHTTPПовтИсп.ЗаголовокОтветаСПеченьем(), Ответ.Заголовки); Если Печенье <> Неопределено Тогда Попытка КлиентHTTPВызовСервера.ПринятьПеченье(Конфигурация.ДополнительныеПараметры.Сессия, Печенье, Конфигурация.ДанныеURI.Сервер); @@ -1668,54 +2051,59 @@ Сессия = Конфигурация.ДополнительныеПараметры.Сессия; НовыйИдентификаторРесурса = ИдентификаторПеренаправления(Ответ.КодСостояния, Ответ.Заголовки); Если ЗначениеЗаполнено(НовыйИдентификаторРесурса) И КонтекстВыполнения.НомерПеренаправления <= Сессия.ПорогПеренаправлений Тогда - Конфигурация.ДанныеURI = СтруктураИдентификатораРесурса(НовыйИдентификаторРесурса); - Конфигурация.Параметры = ОбъединениеПараметровЗапросаВСтроку(Конфигурация.ДанныеURI.Параметры, НовыеПараметрыЗапроса()); - - Возврат ВыполнитьЗапросHTTP(КонтекстВыполнения.Метод, Конфигурация, КонтекстВыполнения.Данные, КонтекстВыполнения.НомерПеренаправления + 1); + Возврат ПеренаправлениеЗапросаHTTP(НовыйИдентификаторРесурса, Ответ, Конфигурация, КонтекстВыполнения); КонецЕсли; Если Ответ.КодСостояния = КлиентHTTPПовтИсп.КодСостоянияНеАвторизовано() И Конфигурация.ДополнительныеПараметры.Свойство("АвторизоватьсяDigest") Тогда - РецептАвторизации = ЗначениеЗаголовка("WWW-Authenticate", Ответ.Заголовки); + РецептАвторизации = ЗначениеЗаголовка(КлиентHTTPПовтИсп.ЗаголовокОтветаМетодыАутентификации(), Ответ.Заголовки); Если СтрНачинаетсяС(НРег(РецептАвторизации), "digest") Тогда КонтекстВыполненияАдресВХ = ПоместитьВоВременноеХранилище(КонтекстВыполнения, Новый УникальныйИдентификатор); Конфигурация.ДополнительныеПараметры.Удалить("АвторизоватьсяDigest"); Сессия.Вставить("ПараметрыDigest", ПараметрыDigest(РецептАвторизации)); - Конфигурация.Заголовки.Вставить("Authorization", КлиентHTTPВызовСервера.ЗаголовокDigest(Конфигурация, КонтекстВыполненияАдресВХ)); + Конфигурация.Заголовки.Вставить( + КлиентHTTPПовтИсп.ЗаголовокТипАутентификации(), + КлиентHTTPВызовСервера.ЗаголовокDigest(Конфигурация, КонтекстВыполненияАдресВХ) + ); - Возврат ВыполнитьЗапросHTTP(КонтекстВыполнения.Метод, Конфигурация, КонтекстВыполнения.Данные, КонтекстВыполнения.НомерПеренаправления + 1); + Возврат ВыполненныйЗапросHTTP(КонтекстВыполнения.Метод, Конфигурация, КонтекстВыполнения.Данные, КонтекстВыполнения.НомерПеренаправления + 1); КонецЕсли; КонецЕсли; - Возврат ОбъектОбработанногоОтвета(Ответ, Конфигурация.ДополнительныеПараметры); + Возврат ОбъектОбработанногоОтвета(Ответ, Конфигурация.ДополнительныеПараметры, КонтекстВыполнения); КонецФункции -Функция ОбъектОбработанногоОтвета(Знач Ответ, Знач ДополнительныеПараметры) - Возврат Новый ФиксированнаяСтруктура( - "КодСостояния, Заголовки, Тело, ИмяФайлаТела", - Ответ.КодСостояния, - Ответ.Заголовки, - ТелоОтвета(Ответ, ДополнительныеПараметры), - Ответ.ПолучитьИмяФайлаТела() - ); +Функция ОбъектОбработанногоОтвета(Знач Ответ, Знач ДополнительныеПараметры, Знач КонтекстВыполнения) + фРезультат = НовыйОбъектОбработанногоОтвета(); + фРезультат.КодСостояния = Ответ.КодСостояния; + фРезультат.Заголовки = Ответ.Заголовки; + фРезультат.Тело = ТелоОтвета(Ответ, ДополнительныеПараметры); + фРезультат.ИмяФайлаТела = Ответ.ПолучитьИмяФайлаТела(); + фРезультат.КонтекстВыполнения = КонтекстВыполнения.Значения; + + Возврат Новый ФиксированнаяСтруктура(фРезультат); КонецФункции Функция ТелоОтвета(Знач Ответ, Знач ДополнительныеПараметры) ДанныеТелаОтвета = ?( - ЗначениеЗаголовка("Content-Encoding", Ответ.Заголовки) = Неопределено, + ЗначениеЗаголовка(КлиентHTTPПовтИсп.ЗаголовокОтветаСжатиеТела(), Ответ.Заголовки) = Неопределено, Ответ.ПолучитьТелоКакДвоичныеДанные(), Декомпрессия(Ответ.ПолучитьТелоКакПоток()) ); - фРезультат = ДанныеТелаОтвета; - - Если НЕ ДополнительныеПараметры.Свойство("ПрочитатьТелоОтветаКак") Тогда - Возврат фРезультат; - КонецЕсли; + Возврат ?( + ДополнительныеПараметры.Свойство("ПрочитатьТелоОтветаКак"), + ПреобразованноеТелоОтвета(Ответ, ДанныеТелаОтвета, ДополнительныеПараметры.ПрочитатьТелоОтветаКак), + ДанныеТелаОтвета + ); +КонецФункции + +Функция ПреобразованноеТелоОтвета(Знач Ответ, Знач ДанныеТелаОтвета, Знач СпособЧтения) Экспорт + Перем фРезультат; Кодировка = КлиентHTTPПовтИсп.КодировкаПоУмолчанию(); - ТипСодержимого = ЗначениеЗаголовка("Content-Type", Ответ.Заголовки); + ТипСодержимого = КлиентHTTPКлиентСервер.ЗначениеЗаголовка(КлиентHTTPПовтИсп.ЗаголовокТипКонтента(), Ответ.Заголовки); Если ТипСодержимого <> Неопределено Тогда ПозицияРазделителя = СтрНайти(ТипСодержимого, ";"); Если ПозицияРазделителя > 0 Тогда @@ -1723,7 +2111,6 @@ КонецЕсли; КонецЕсли; - СпособЧтения = ДополнительныеПараметры.ПрочитатьТелоОтветаКак; Если СпособЧтения.Формат = ФорматТелаОтветаТекст() Тогда фРезультат = ПолучитьСтрокуИзДвоичныхДанных(ДанныеТелаОтвета, Кодировка); ИначеЕсли СпособЧтения.Формат = ФорматТелаОтветаJSON() Тогда @@ -1783,7 +2170,7 @@ Получатель = КлиентHTTPСлужебный.НормализованныйАдресСервера(ДанныеURI.Сервер); ДатаЗапроса = КлиентHTTPВызовСервера.ТекущаяУниверсальнаяДатаНаСервере(); - ВзятьПеченье(фРезультат, Печенье, Получатель, ДатаЗапроса, ДанныеURI.АдресРесурса, ДанныеURI.ЗащищенноеСоединение); + ВзятьПеченье(фРезультат, Печенье, Получатель, ДатаЗапроса, ДанныеURI.Путь, ДанныеURI.ЗащищенноеСоединение); Если фРезультат.Количество() > 0 Тогда Возврат Новый ФиксированныйМассив(фРезультат); КонецЕсли; @@ -1792,7 +2179,7 @@ Пока Части.Количество() > 1 Цикл Получатель = "." + СтрСоединить(Части, "."); - ВзятьПеченье(фРезультат, Печенье, Получатель, ДатаЗапроса, ДанныеURI.АдресРесурса, ДанныеURI.ЗащищенноеСоединение); + ВзятьПеченье(фРезультат, Печенье, Получатель, ДатаЗапроса, ДанныеURI.Путь, ДанныеURI.ЗащищенноеСоединение); Если фРезультат.Количество() > 0 Тогда Прервать; КонецЕсли; @@ -1803,9 +2190,9 @@ Возврат Новый ФиксированныйМассив(фРезультат); КонецФункции -Процедура ВзятьПеченье(ПеченьеПолучателя, Печенье, Знач Получатель, Знач ДатаЗапроса, Знач АдресРесурса, Знач ЗащищенноеСоединение) +Процедура ВзятьПеченье(ПеченьеПолучателя, Печенье, Знач Получатель, Знач ДатаЗапроса, Знач Путь, Знач ЗащищенноеСоединение) ИмяСрок = КлиентHTTPПовтИсп.СвойствоПеченькаСрок(); - ИмяАдресРесурса = КлиентHTTPПовтИсп.СвойствоПеченькаАдресРесурса(); + ИмяПуть = КлиентHTTPПовтИсп.СвойствоПеченькаАдресРесурса(); ИмяЗащищенноеСоединение = КлиентHTTPПовтИсп.СвойствоПеченькаЗащищенноеСоединение(); Печеньки = Печенье.Получить(Получатель); @@ -1821,7 +2208,7 @@ ПеченькиНаУдаление.Добавить(КЗ.Ключ); Продолжить; КонецЕсли; - Если Печенька.Свойство(ИмяАдресРесурса) И НЕ СтрНачинаетсяС(АдресРесурса, Печенька[ИмяАдресРесурса]) Тогда + Если Печенька.Свойство(ИмяПуть) И НЕ СтрНачинаетсяС(Путь, Печенька[ИмяПуть]) Тогда Продолжить; КонецЕсли; Если Печенька.Свойство(ИмяЗащищенноеСоединение) И НЕ ЗащищенноеСоединение Тогда @@ -1857,29 +2244,28 @@ КонецЦикла; КонецПроцедуры -Функция АдресРесурсаЗапроса(Знач Конфигурация) - Возврат Конфигурация.ДанныеURI.АдресРесурса + Конфигурация.Параметры; -КонецФункции - -Функция ЗначениеЗаголовка(Знач ИмяЗаголовка, Знач Заголовки) - фРезультат = Неопределено; - ИмяЗаголовка = НРег(ИмяЗаголовка); +Функция ЗначениеЗаголовкаCookie(Знач ДанныеURI, Знач Сессия) + Если НЕ Сессия.Свойство("Печенье") Тогда + Возврат Неопределено; + КонецЕсли; - Для Каждого КЗ Из Заголовки Цикл - Если НРег(КЗ.Ключ) = ИмяЗаголовка Тогда - фРезультат = КЗ.Значение; - Прервать; - КонецЕсли; - КонецЦикла; + Печенье = ПеченьеДляURI(ДанныеURI, Сессия.Печенье); - Возврат фРезультат; + Возврат ?(ЗначениеЗаполнено(Печенье), СтрСоединить(Печенье, "; "), ""); +КонецФункции + +Функция АдресРесурсаЗапроса(Знач Конфигурация) + Возврат Конфигурация.ДанныеURI.Путь + + Конфигурация.ПараметрыСтрокой + + ?(ПустаяСтрока(Конфигурация.ДанныеURI.Фрагмент), "", "#") + + Конфигурация.ДанныеURI.Фрагмент; КонецФункции Функция ИдентификаторПеренаправления(Знач КодСостояния, Знач Заголовки) Возврат ?( КлиентHTTPПовтИсп.КодыСостоянияПеренаправления().Получить(КодСостояния) = Неопределено, Неопределено, - КлиентHTTPВызовСервера.РаскодированныйИдентификаторРесурса(ЗначениеЗаголовка("Location", Заголовки)) + КлиентHTTPВызовСервера.РаскодированныйИдентификаторРесурса(СокрЛП(ЗначениеЗаголовка(КлиентHTTPПовтИсп.ЗаголовокОтветаПеренаправление(), Заголовки))) ); КонецФункции @@ -1887,6 +2273,26 @@ Возврат Новый ФиксированнаяСтруктура("Тип, Пользователь, Пароль", Тип, Пользователь, Пароль); КонецФункции +Функция ОбъектАутентификацииBearer(Знач Токен) + Возврат Новый ФиксированнаяСтруктура("Тип, Токен", "Bearer", Токен); +КонецФункции + +Функция ОбъектАутентификацииAWS4(Знач КлючДоступа, Знач СекретныйКлюч, Знач Регион, Знач Сервис) + Возврат Новый ФиксированнаяСтруктура("Тип, КлючДоступа, СекретныйКлюч, Регион, Сервис", "AWS4", КлючДоступа, СекретныйКлюч, Регион, Сервис); +КонецФункции + +Функция ОбъектАутентификацииHawk(Знач Идентификатор, Знач Ключ, Знач Дополнение, Знач ИдентификаторПриложения, Знач Делегирование) + Возврат Новый ФиксированнаяСтруктура( + "Тип, Идентификатор, Ключ, Дополнение, ИдентификаторПриложения, Делегирование", + "Hawk", + Идентификатор, + Ключ, + Дополнение, + ИдентификаторПриложения, + Делегирование + ); +КонецФункции + Функция ПараметрыDigest(Знач РецептАвторизации) фРезультат = Новый Структура("algorithm, realm, nonce, qop, opaque"); @@ -1962,14 +2368,6 @@ Возврат фРезультат; КонецФункции -Функция ФорматированноеИмяПараметраЗапроса(Знач Имя) - Возврат СтрЗаменить(ФорматированноеЗначениеПараметраЗапроса(Имя), "=", "%3D"); -КонецФункции - -Функция ФорматированноеЗначениеПараметраЗапроса(Знач Значение) - Возврат СтрЗаменить(СтрЗаменить(СтрЗаменить(Значение, Символы.ПС, ""), "#", "%23"), "&", "%26"); -КонецФункции - Функция СпособЧтенияТелаОтвета(Знач Формат, Знач Параметры = Неопределено) Возврат Новый Структура("Формат, Параметры", Формат, Параметры); КонецФункции diff --git "a/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\237\320\276\320\262\321\202\320\230\321\201\320\277/Ext/Module.bsl" "b/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\237\320\276\320\262\321\202\320\230\321\201\320\277/Ext/Module.bsl" index d731622..9621379 100644 --- "a/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\237\320\276\320\262\321\202\320\230\321\201\320\277/Ext/Module.bsl" +++ "b/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\237\320\276\320\262\321\202\320\230\321\201\320\277/Ext/Module.bsl" @@ -200,6 +200,15 @@ Возврат КлиентHTTPПовтИсп.КодыСостояния().Перенаправления.Найден; КонецФункции +// Возвращает код состояния HTTP-сервера 303 +// +// Возвращаемое значение: +// Число - код состояния +// +Функция КодСостоянияПросмотрДругихРесурсов() Экспорт + Возврат КлиентHTTPПовтИсп.КодыСостояния().Перенаправления.ПросмотрДругихРесурсов; +КонецФункции + // Возвращает код состояния HTTP-сервера 307 // // Возвращаемое значение: @@ -209,6 +218,15 @@ Возврат КлиентHTTPПовтИсп.КодыСостояния().Перенаправления.ВременноеПеренаправление; КонецФункции +// Возвращает код состояния HTTP-сервера 308 +// +// Возвращаемое значение: +// Число - код состояния +// +Функция КодСостоянияПеренаправление() Экспорт + Возврат КлиентHTTPПовтИсп.КодыСостояния().Перенаправления.ПеренаправлениеНаПостояннойОснове; +КонецФункции + // Возвращает код состояния HTTP-сервера 400 // // Возвращаемое значение: @@ -345,9 +363,9 @@ фРезультат = Новый Соответствие; фРезультат.Вставить(КлиентHTTPПовтИсп.КодСостоянияПеремещен(), Истина); фРезультат.Вставить(КлиентHTTPПовтИсп.КодСостоянияНайден(), Истина); - фРезультат.Вставить(КлиентHTTPПовтИсп.КодыСостояния().Перенаправления.ПросмотрДругихРесурсов, Истина); + фРезультат.Вставить(КлиентHTTPПовтИсп.КодСостоянияПросмотрДругихРесурсов(), Истина); фРезультат.Вставить(КлиентHTTPПовтИсп.КодСостоянияВременноеПеренаправление(), Истина); - фРезультат.Вставить(КлиентHTTPПовтИсп.КодыСостояния().Перенаправления.ПеренаправлениеНаПостояннойОснове, Истина); + фРезультат.Вставить(КлиентHTTPПовтИсп.КодСостоянияПеренаправление(), Истина); Возврат Новый ФиксированноеСоответствие(фРезультат); КонецФункции @@ -530,6 +548,15 @@ Возврат КлиентHTTPПовтИсп.ТипыMIME().text.xml; КонецФункции +// Возвращает MIME-тип application/xml +// +// Возвращаемое значение: +// Строка - MIME-тип +// +Функция ТипMIMEApplicationXML() Экспорт + Возврат КлиентHTTPПовтИсп.ТипыMIME().application.xml; +КонецФункции + // Возвращает MIME-тип text/html // // Возвращаемое значение: @@ -703,7 +730,7 @@ Возврат Новый ФиксированноеСоответствие(фРезультат); КонецФункции -// Возвращает кодировку по умолчанию для HTTP-клиента +// Возвращает кодировку по умолчанию для HTTP-клиента (UTF-8) // // Возвращаемое значение: // Строка - кодировка @@ -748,6 +775,15 @@ Возврат "UTF-32"; КонецФункции +// Возвращает кодировку ISO-8859-1 +// +// Возвращаемое значение: +// Строка - кодировка +// +Функция КодировкаISO8859() Экспорт + Возврат "ISO-8859-1"; +КонецФункции + // Возвращает кодировку CESU-8 // // Возвращаемое значение: @@ -793,6 +829,105 @@ Возврат "cp866"; КонецФункции +// Возвращает имя заголовка, содержащего хост сервера +// +// Возвращаемое значение: +// Строка - имя заголовка +// +Функция ЗаголовокХост() Экспорт + Возврат "Host"; +КонецФункции + +// Возвращает имя заголовка, содержащего характеристику пользовательского агента +// +// Возвращаемое значение: +// Строка - имя заголовка +// +Функция ЗаголовокАгентПользователя() Экспорт + Возврат "User-Agent"; +КонецФункции + +// Возвращает имя заголовка, содержащего тип контента +// +// Возвращаемое значение: +// Строка - имя заголовка +// +Функция ЗаголовокТипКонтента() Экспорт + Возврат "Content-Type"; +КонецФункции + +// Возвращает имя заголовка, содержащего размер контента +// +// Возвращаемое значение: +// Строка - имя заголовка +// +Функция ЗаголовокРазмерКонтента() Экспорт + Возврат "Content-Length"; +КонецФункции + +// Возвращает имя заголовка, содержащего данные аутентификации +// +// Возвращаемое значение: +// Строка - имя заголовка +// +Функция ЗаголовокТипАутентификации() Экспорт + Возврат "Authorization"; +КонецФункции + +// Возвращает имя заголовка, содержащего допустимые для клиента способы кодирования тела ответа (обычно, это алгоритмы сжатия) +// +// Возвращаемое значение: +// Строка - имя заголовка +// +Функция ЗаголовокДопустимыеСпособыКодированияОтвета() Экспорт + Возврат "Accept-Encoding"; +КонецФункции + +// Возвращает имя заголовка с Cookie +// +// Возвращаемое значение: +// Строка - имя заголовка +// +Функция ЗаголовокПеченье() Экспорт + Возврат "Cookie"; +КонецФункции + +// Возвращает имя заголовка ответа с Cookie +// +// Возвращаемое значение: +// Строка - имя заголовка +// +Функция ЗаголовокОтветаСПеченьем() Экспорт + Возврат "Set-Cookie"; +КонецФункции + +// Возвращает имя заголовка ответа, содержащего тип сжатия содержимого тела ответа +// +// Возвращаемое значение: +// Строка - имя заголовка +// +Функция ЗаголовокОтветаСжатиеТела() Экспорт + Возврат "Content-Encoding"; +КонецФункции + +// Возвращает имя заголовка ответа с URI перенаправления +// +// Возвращаемое значение: +// Строка - имя заголовка +// +Функция ЗаголовокОтветаПеренаправление() Экспорт + Возврат "Location"; +КонецФункции + +// Возвращает имя заголовка ответа с доступными типами аутентификации +// +// Возвращаемое значение: +// Строка - имя заголовка +// +Функция ЗаголовокОтветаМетодыАутентификации() Экспорт + Возврат "WWW-Authenticate"; +КонецФункции + // Возвращает дату, называемую эпохой Unix // // Возвращаемое значение: @@ -801,6 +936,112 @@ Функция ЭпохаUnix() Экспорт Возврат Дата(1970, 1, 1); КонецФункции + +// Возвращает AWS сервис S3 +// +// Возвращаемое значение: +// Строка - сервис +// +Функция СервисAWSS3() Экспорт + Возврат "s3"; +КонецФункции + +// Возвращает адресный перечень регионов AWS +// +// Возвращаемое значение: +// ФиксированнаяСтруктура - ключи: константы регионов AWS +// +Функция РегионыAWS() Экспорт + фРезультат = Новый Структура; + + Регионы = Новый Массив; + Регионы.Добавить("RU_1"); + Регионы.Добавить("RU_MSK"); + Регионы.Добавить("RU_CENTRAL1"); + Регионы.Добавить("AF_SOUTH_1"); + Регионы.Добавить("AP_EAST_1"); + Регионы.Добавить("AP_NORTHEAST_1"); + Регионы.Добавить("AP_NORTHEAST_2"); + Регионы.Добавить("AP_NORTHEAST_3"); + Регионы.Добавить("AP_SOUTH_1"); + Регионы.Добавить("AP_SOUTH_2"); + Регионы.Добавить("AP_SOUTHEAST_1"); + Регионы.Добавить("AP_SOUTHEAST_2"); + Регионы.Добавить("AP_SOUTHEAST_3"); + Регионы.Добавить("AP_SOUTHEAST_4"); + Регионы.Добавить("AWS_CN_GLOBAL"); + Регионы.Добавить("AWS_GLOBAL"); + Регионы.Добавить("AWS_ISO_B_GLOBAL"); + Регионы.Добавить("AWS_ISO_GLOBAL"); + Регионы.Добавить("AWS_US_GOV_GLOBAL"); + Регионы.Добавить("CA_CENTRAL_1"); + Регионы.Добавить("CN_NORTH_1"); + Регионы.Добавить("CN_NORTHWEST_1"); + Регионы.Добавить("EU_CENTRAL_1"); + Регионы.Добавить("EU_CENTRAL_2"); + Регионы.Добавить("EU_NORTH_1"); + Регионы.Добавить("EU_SOUTH_1"); + Регионы.Добавить("EU_SOUTH_2"); + Регионы.Добавить("EU_WEST_1"); + Регионы.Добавить("EU_WEST_2"); + Регионы.Добавить("EU_WEST_3"); + Регионы.Добавить("ME_CENTRAL_1"); + Регионы.Добавить("ME_SOUTH_1"); + Регионы.Добавить("SA_EAST_1"); + Регионы.Добавить("US_EAST_1"); + Регионы.Добавить("US_EAST_2"); + Регионы.Добавить("US_GOV_EAST_1"); + Регионы.Добавить("US_GOV_WEST_1"); + Регионы.Добавить("US_ISO_EAST_1"); + Регионы.Добавить("US_ISO_WEST_1"); + Регионы.Добавить("US_ISOB_EAST_1"); + Регионы.Добавить("US_WEST_1"); + Регионы.Добавить("US_WEST_2"); + + Для Каждого Регион Из Регионы Цикл + фРезультат.Вставить(Регион, СтрЗаменить(НРег(Регион), "_", "-")); + КонецЦикла; + + Возврат Новый ФиксированнаяСтруктура(фРезультат); +КонецФункции + +#Область AWS_РЕГИОНЫ +// Возвращает AWS регион по умолчанию (ru-1) +// +// Возвращаемое значение: +// Строка - регион +// +Функция РегионAWSПоУмолчанию() Экспорт + Возврат КлиентHTTPПовтИсп.РегионAWSRu1(); +КонецФункции + +// Возвращает AWS регион ru-1 +// +// Возвращаемое значение: +// Строка - регион +// +Функция РегионAWSRu1() Экспорт + Возврат КлиентHTTPПовтИсп.РегионыAWS().RU_1; +КонецФункции + +// Возвращает AWS регион ru-msk-1 +// +// Возвращаемое значение: +// Строка - регион +// +Функция РегионAWSRuMsk() Экспорт + Возврат КлиентHTTPПовтИсп.РегионыAWS().RU_MSK; +КонецФункции + +// Возвращает AWS регион ru-central1 +// +// Возвращаемое значение: +// Строка - регион +// +Функция РегионAWSRuCentral1() Экспорт + Возврат КлиентHTTPПовтИсп.РегионыAWS().RU_CENTRAL1; +КонецФункции +#КонецОбласти #КонецОбласти #Область СлужебныйПрограммныйИнтерфейс @@ -1131,7 +1372,18 @@ Возврат Новый ФиксированнаяСтруктура(фРезультат); КонецФункции -// Возвращает множество допустимых символов имени заголовка HTTP-запроса +// Возвращает строку из допустимых символов имени заголовка HTTP-запроса +// +// Возвращаемое значение: +// Строка - строка из допустимых символов имени заголовка +// +Функция ДопустимыеСимволыИмениЗаголовкаСтрокой() Экспорт + Буквы = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + Возврат Буквы + НРег(Буквы) + "0123456789!#$%&'*+-.^_`|~"; +КонецФункции + +// (УСТАРЕЛО) Возвращает множество допустимых символов имени заголовка HTTP-запроса // // Возвращаемое значение: // ФиксированноеСоответствие - служебный словарь допустимых символов имени заголовка @@ -1139,8 +1391,7 @@ Функция ДопустимыеСимволыИмениЗаголовка() Экспорт фРезультат = Новый Соответствие; - Буквы = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - ДопустимыеСимволы = Буквы + НРег(Буквы) + "0123456789!#$%&'*+-.^_`|~"; + ДопустимыеСимволы = КлиентHTTPПовтИсп.ДопустимыеСимволыИмениЗаголовкаСтрокой(); Для я = 1 По СтрДлина(ДопустимыеСимволы) Цикл фРезультат.Вставить(Сред(ДопустимыеСимволы, я, 1), Истина); diff --git "a/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\241\320\273\321\203\320\266\320\265\320\261\320\275\321\213\320\271/Ext/Module.bsl" "b/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\241\320\273\321\203\320\266\320\265\320\261\320\275\321\213\320\271/Ext/Module.bsl" index b0c732c..6f5cfc8 100644 --- "a/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\241\320\273\321\203\320\266\320\265\320\261\320\275\321\213\320\271/Ext/Module.bsl" +++ "b/src/v1/CommonModules/\320\232\320\273\320\270\320\265\320\275\321\202HTTP\320\241\320\273\321\203\320\266\320\265\320\261\320\275\321\213\320\271/Ext/Module.bsl" @@ -111,6 +111,7 @@ КонецФункции // Возвращает текстовое представление даты RFC 1123 +// Date: Tue, 15-Nov-1994 08:12:31 GMT // // Параметры: // Дата - Дата - конвертируемое значение @@ -126,6 +127,23 @@ ); КонецФункции +// Возвращает текстовое представление даты RFC 7231 (7.1.1.2) +// Date: Tue, 15 Nov 1994 08:12:31 GMT +// +// Параметры: +// Дата - Дата - конвертируемое значение +// +// Возвращаемое значение: +// Строка - дата формата RFC 7231 (7.1.1.2) +// +Функция ДатаВHTTP7231(Знач Дата) Экспорт + Возврат СтрШаблон( + Формат(Дата, "ДФ='""%1"", дд ""%2"" гггг Ч:м:с ""GMT""'"), + ДеньНеделиНаАнглийском(Дата), + МесяцНаАнглийском(Дата) + ); +КонецФункции + // Возвращает преобразованный в ACE-последовательность IDN // // Параметры: @@ -137,6 +155,30 @@ Функция НормализованныйАдресСервера(Знач АдресСервера) Экспорт Возврат КодироватьАдресСервера(НРег(СокрЛП(АдресСервера))); КонецФункции + +// Возвращает имя параметра запроса с экранированием +// +// Параметры: +// Имя - Строка - имя параметра запроса +// +// Возвращаемое значение: +// Строка - экранированное имя параметра запроса +// +Функция ФорматированноеИмяПараметраЗапроса(Знач Имя) Экспорт + Возврат СтрЗаменить(ФорматированноеЗначениеПараметраЗапроса(Имя), "=", "%3D"); +КонецФункции + +// Возвращает значение параметра запроса с экранированием +// +// Параметры: +// Значение - Строка - значение параметра запроса +// +// Возвращаемое значение: +// Строка - экранированное значение параметра запроса +// +Функция ФорматированноеЗначениеПараметраЗапроса(Знач Значение) Экспорт + Возврат СтрЗаменить(СтрЗаменить(СтрЗаменить(СокрЛП(Значение), Символы.ПС, ""), "#", "%23"), "&", "%26"); +КонецФункции #КонецОбласти #Область СлужебныеПроцедурыИФункции diff --git a/src/v1/Configuration.xml b/src/v1/Configuration.xml index 9a9ca3a..ce0a2dc 100644 --- a/src/v1/Configuration.xml +++ b/src/v1/Configuration.xml @@ -49,7 +49,7 @@ Russian Брызгалин Андрей Васильевич (andrew.bryzgalin@gmail.com) - 1.8.0 + 1.9.0 https://github.com/SpaceHead1C/1c_http/releases false false diff --git "a/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\232\320\276\320\275\321\201\321\202\321\200\321\203\320\272\321\202\320\276\321\200\320\230\320\264\320\265\320\275\321\202\320\270\321\204\320\270\320\272\320\260\321\202\320\276\321\200\320\260\320\240\320\265\321\201\321\203\321\200\321\201\320\260/Ext/Form.xml" "b/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\232\320\276\320\275\321\201\321\202\321\200\321\203\320\272\321\202\320\276\321\200\320\230\320\264\320\265\320\275\321\202\320\270\321\204\320\270\320\272\320\260\321\202\320\276\321\200\320\260\320\240\320\265\321\201\321\203\321\200\321\201\320\260/Ext/Form.xml" index 4beed88..54effc0 100644 --- "a/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\232\320\276\320\275\321\201\321\202\321\200\321\203\320\272\321\202\320\276\321\200\320\230\320\264\320\265\320\275\321\202\320\270\321\204\320\270\320\272\320\260\321\202\320\276\321\200\320\260\320\240\320\265\321\201\321\203\321\200\321\201\320\260/Ext/Form.xml" +++ "b/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\232\320\276\320\275\321\201\321\202\321\200\321\203\320\272\321\202\320\276\321\200\320\230\320\264\320\265\320\275\321\202\320\270\321\204\320\270\320\272\320\260\321\202\320\276\321\200\320\260\320\240\320\265\321\201\321\203\321\200\321\201\320\260/Ext/Form.xml" @@ -185,6 +185,21 @@ ПортПриИзменении + + false + false + false + false + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>/</v8:content> + </v8:item> + + + + АдресРесурса @@ -195,12 +210,6 @@ Top false - - - ru - / - - @@ -310,6 +319,52 @@ </InputField> </ChildItems> </UsualGroup> + <UsualGroup name="ГруппаФрагмент" id="47"> + <Title> + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>фрагмент</v8:content> + </v8:item> + + AlwaysHorizontal + None + false + DontUse + + + + false + false + false + false + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>#</v8:content> + </v8:item> + + + + + + Фрагмент + None + + + ru + Фрагмент + + + false + + + + ФрагментПриИзменении + + + + @@ -422,6 +477,21 @@ + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Фрагмент</v8:content> + </v8:item> + + + xs:string + + 0 + Variable + + + @@ -438,6 +508,7 @@ ОК + DontUse diff --git "a/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\232\320\276\320\275\321\201\321\202\321\200\321\203\320\272\321\202\320\276\321\200\320\230\320\264\320\265\320\275\321\202\320\270\321\204\320\270\320\272\320\260\321\202\320\276\321\200\320\260\320\240\320\265\321\201\321\203\321\200\321\201\320\260/Ext/Form/Module.bsl" "b/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\232\320\276\320\275\321\201\321\202\321\200\321\203\320\272\321\202\320\276\321\200\320\230\320\264\320\265\320\275\321\202\320\270\321\204\320\270\320\272\320\260\321\202\320\276\321\200\320\260\320\240\320\265\321\201\321\203\321\200\321\201\320\260/Ext/Form/Module.bsl" index 66cee05..75587f9 100644 --- "a/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\232\320\276\320\275\321\201\321\202\321\200\321\203\320\272\321\202\320\276\321\200\320\230\320\264\320\265\320\275\321\202\320\270\321\204\320\270\320\272\320\260\321\202\320\276\321\200\320\260\320\240\320\265\321\201\321\203\321\200\321\201\320\260/Ext/Form/Module.bsl" +++ "b/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\232\320\276\320\275\321\201\321\202\321\200\321\203\320\272\321\202\320\276\321\200\320\230\320\264\320\265\320\275\321\202\320\270\321\204\320\270\320\272\320\260\321\202\320\276\321\200\320\260\320\240\320\265\321\201\321\203\321\200\321\201\320\260/Ext/Form/Module.bsl" @@ -4,55 +4,63 @@ Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) ОписаниеТипаЧисло = Новый ОписаниеТипов("Число"); - ИР = Параметры.ИдентификаторРесурса; + ИдентификаторРесурса = Параметры.ИдентификаторРесурса; - ЗащищенноеСоединение = СтрНачинаетсяС(ИР, "https://"); + ЗащищенноеСоединение = СтрНачинаетсяС(ИдентификаторРесурса, "https://"); Если ЗащищенноеСоединение Тогда Элементы.ДекорацияСхема.Заголовок = "https://"; КонецЕсли; - ИР = СтрЗаменить(ИР, "https://", ""); - ИР = СтрЗаменить(ИР, "http://", ""); - ПозицияОкончания = СтрНайти(ИР, "?") - 1; - Если ПозицияОкончания < 0 Тогда - ПозицияОкончания = СтрДлина(ИР); + ИдентификаторРесурса = СтрЗаменить(ИдентификаторРесурса, "https://", ""); + ИдентификаторРесурса = СтрЗаменить(ИдентификаторРесурса, "http://", ""); + ПозицияСимволаПараметров = СтрНайти(ИдентификаторРесурса, "?"); + ПозицияСимволаФрагмента = СтрНайти(ИдентификаторРесурса, "#", , ?(ПозицияСимволаПараметров = 0, 1, ПозицияСимволаПараметров)); + Если ПозицияСимволаФрагмента > 0 Тогда + Фрагмент = Сред(ИдентификаторРесурса, ПозицияСимволаФрагмента + 1); КонецЕсли; + ПозицияОкончания = ?(ПозицияСимволаПараметров = 0, ПозицияСимволаФрагмента, ПозицияСимволаПараметров) - 1; + Если ПозицияОкончания > 0 Тогда + ИдентификаторРесурса = Лев(ИдентификаторРесурса, ПозицияОкончания); + КонецЕсли; + ПозицияОкончания = СтрДлина(ИдентификаторРесурса); - ПозицияПослеАвторизации = СтрНайти(ИР, "@"); + ПозицияПослеАвторизации = СтрНайти(ИдентификаторРесурса, "@"); Если ПозицияПослеАвторизации > 0 И ПозицияПослеАвторизации < ПозицияОкончания Тогда - Авторизация = Лев(ИР, ПозицияПослеАвторизации - 1); + Авторизация = Лев(ИдентификаторРесурса, ПозицияПослеАвторизации - 1); ДлинаАвторизации = СтрДлина(Авторизация); ПозицияРазделителяАвторизации = СтрНайти(Авторизация, ":"); Если ПозицияРазделителяАвторизации = 0 Тогда ПозицияРазделителяАвторизации = ДлинаАвторизации + 1; КонецЕсли; - ЗакодированныеДанные = Новый Структура("Пользователь, Пароль"); - ЗакодированныеДанные.Пользователь = СокрЛП(Лев(Авторизация, ПозицияРазделителяАвторизации - 1)); - ЗакодированныеДанные.Пароль = Прав(Авторизация, ДлинаАвторизации - ПозицияРазделителяАвторизации); - РаскодированныеДанные = КлиентHTTP.РаскодированныеСтроки(ЗакодированныеДанные); + ЗакодированныйПользователь = СокрЛП(Лев(Авторизация, ПозицияРазделителяАвторизации - 1)); + ЗакодированныйПароль = Прав(Авторизация, ДлинаАвторизации - ПозицияРазделителяАвторизации); + МножествоСтрок = Новый Соответствие; + МножествоСтрок.Вставить(ЗакодированныйПользователь); + МножествоСтрок.Вставить(ЗакодированныйПароль); - Пользователь = РаскодированныеДанные.Пользователь; - Пароль = РаскодированныеДанные.Пароль; - ИР = Сред(ИР, ПозицияПослеАвторизации + 1); - ПозицияОкончания = СтрДлина(ИР); + МножествоСтрок = КлиентHTTP.РаскодированныеСтрокиURLвURL(МножествоСтрок); + Пользователь = МножествоСтрок.Получить(ЗакодированныйПользователь); + Пароль = МножествоСтрок.Получить(ЗакодированныйПароль); + ИдентификаторРесурса = Сред(ИдентификаторРесурса, ПозицияПослеАвторизации + 1); + ПозицияОкончания = СтрДлина(ИдентификаторРесурса); КонецЕсли; - ПозицияАдресаРесурса = СтрНайти(ИР, "/"); + ПозицияАдресаРесурса = СтрНайти(ИдентификаторРесурса, "/"); Если ПозицияАдресаРесурса > 0 Тогда - АдресРесурса = Сред(ИР, ПозицияАдресаРесурса, ПозицияОкончания - ПозицияАдресаРесурса + 1); + АдресРесурса = Сред(ИдентификаторРесурса, ПозицияАдресаРесурса + 1, ПозицияОкончания - ПозицияАдресаРесурса + 1); ПозицияОкончания = ПозицияАдресаРесурса - 1; КонецЕсли; - ПозицияПорта = СтрНайти(ИР, ":", НаправлениеПоиска.СКонца, ПозицияОкончания); + ПозицияПорта = СтрНайти(ИдентификаторРесурса, ":", НаправлениеПоиска.СКонца, ПозицияОкончания); Если ПозицияПорта > 0 Тогда - Порт = ОписаниеТипаЧисло.ПривестиЗначение(Сред(ИР, ПозицияПорта + 1, ПозицияОкончания)); + Порт = ОписаниеТипаЧисло.ПривестиЗначение(Сред(ИдентификаторРесурса, ПозицияПорта + 1, ПозицияОкончания - ПозицияПорта)); ПозицияОкончания = ПозицияПорта - 1; Иначе Порт = ?(ЗащищенноеСоединение, 443, 80); КонецЕсли; - Сервер = Лев(ИР, ПозицияОкончания); + Сервер = Лев(ИдентификаторРесурса, ПозицияОкончания); КонецПроцедуры &НаКлиенте @@ -73,7 +81,7 @@ Возврат; КонецЕсли; - Закрыть(ИдентификаторРесурса()); + Закрыть(ИдентификаторРесурса() + ?(ПустаяСтрока(Фрагмент), "", "#" + Фрагмент)); КонецПроцедуры #КонецОбласти @@ -121,13 +129,18 @@ Процедура ПарольПриИзменении(Элемент) URI = ИдентификаторРесурса(); КонецПроцедуры + +&НаКлиенте +Процедура ФрагментПриИзменении(Элемент) + URI = ИдентификаторРесурса(); +КонецПроцедуры #КонецОбласти #Область СлужебныеПроцедурыИФункции &НаКлиенте Функция ИдентификаторРесурса() ЧастиURL = Новый Массив; - ЧастиURL.Добавить(Элементы.ДекорацияСхема.Заголовок); + ЧастиURL.Добавить(?(ЗащищенноеСоединение, "https://", "http://")); Если НЕ ПустаяСтрока(Пользователь) Тогда КоллекцияСтрок = Новый Структура("Пользователь, Пароль", Пользователь, Пароль); @@ -155,6 +168,11 @@ ЧастиURL.Добавить(АдресРесурса); + Фрагмент = СокрЛП(Фрагмент); + Если НЕ ПустаяСтрока(Фрагмент) И СтрНачинаетсяС(Фрагмент, "#") Тогда + Фрагмент = СокрЛ(Сред(Фрагмент, 2)); + КонецЕсли; + Возврат СтрСоединить(ЧастиURL); КонецФункции diff --git "a/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\240\320\265\320\264\320\260\320\272\321\202\320\276\321\200\320\242\320\265\320\272\321\201\321\202\320\276\320\262\320\276\320\263\320\276\320\237\320\276\320\273\321\217/Ext/Form.xml" "b/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\240\320\265\320\264\320\260\320\272\321\202\320\276\321\200\320\242\320\265\320\272\321\201\321\202\320\276\320\262\320\276\320\263\320\276\320\237\320\276\320\273\321\217/Ext/Form.xml" index 2dee379..93b1c74 100644 --- "a/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\240\320\265\320\264\320\260\320\272\321\202\320\276\321\200\320\242\320\265\320\272\321\201\321\202\320\276\320\262\320\276\320\263\320\276\320\237\320\276\320\273\321\217/Ext/Form.xml" +++ "b/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\240\320\265\320\264\320\260\320\272\321\202\320\276\321\200\320\242\320\265\320\272\321\201\321\202\320\276\320\262\320\276\320\263\320\276\320\237\320\276\320\273\321\217/Ext/Form.xml" @@ -47,6 +47,9 @@ false + + РедактируемыйТекстИзменениеТекстаРедактирования + @@ -109,5 +112,11 @@ + + + v8ui:Color + v8:Null + + \ No newline at end of file diff --git "a/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\240\320\265\320\264\320\260\320\272\321\202\320\276\321\200\320\242\320\265\320\272\321\201\321\202\320\276\320\262\320\276\320\263\320\276\320\237\320\276\320\273\321\217/Ext/Form/Module.bsl" "b/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\240\320\265\320\264\320\260\320\272\321\202\320\276\321\200\320\242\320\265\320\272\321\201\321\202\320\276\320\262\320\276\320\263\320\276\320\237\320\276\320\273\321\217/Ext/Form/Module.bsl" index 68f59bc..b32b1f8 100644 --- "a/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\240\320\265\320\264\320\260\320\272\321\202\320\276\321\200\320\242\320\265\320\272\321\201\321\202\320\276\320\262\320\276\320\263\320\276\320\237\320\276\320\273\321\217/Ext/Form/Module.bsl" +++ "b/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\240\320\265\320\264\320\260\320\272\321\202\320\276\321\200\320\242\320\265\320\272\321\201\321\202\320\276\320\262\320\276\320\263\320\276\320\237\320\276\320\273\321\217/Ext/Form/Module.bsl" @@ -9,6 +9,17 @@ КонецЕсли; РедактируемыйТекст = Параметры.Текст; + + Если Параметры.ЦветРедактируемогоТекста <> Неопределено Тогда + Элементы.РедактируемыйТекст.ЦветТекста = Параметры.ЦветРедактируемогоТекста; + КонецЕсли; +КонецПроцедуры +#КонецОбласти + +#Область ОбработчикиСобытийПоляРедактируемогоТекста +&НаКлиенте +Процедура РедактируемыйТекстИзменениеТекстаРедактирования(Элемент, Текст, СтандартнаяОбработка) + Элементы.РедактируемыйТекст.ЦветТекста = Новый Цвет; КонецПроцедуры #КонецОбласти diff --git "a/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\244\320\276\321\200\320\274\320\260/Ext/Form.xml" "b/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\244\320\276\321\200\320\274\320\260/Ext/Form.xml" index 506ca56..1f58f73 100644 --- "a/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\244\320\276\321\200\320\274\320\260/Ext/Form.xml" +++ "b/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\244\320\276\321\200\320\274\320\260/Ext/Form.xml" @@ -477,6 +477,7 @@ true true true + AsFile ПараметрыЗапроса <v8:item> @@ -561,115 +562,162 @@ </Table> </ChildItems> </Page> - <Page name="РазделАвторизация" id="125"> + <Page name="РазделАутентификация" id="125"> <Title> <v8:item> <v8:lang>ru</v8:lang> - <v8:content>Авторизация</v8:content> + <v8:content>Аутентификация</v8:content> </v8:item> ru - Раздел авторизация + Раздел аутентификация - + - - ТипАвторизации + <v8:item> <v8:lang>ru</v8:lang> - <v8:content>Тип</v8:content> + <v8:content>Группа тип аутентификации</v8:content> </v8:item> - 15 - false - false - true - false - false - false - false - false - false - false - - - - 0 - - - - ru - Без авторизации - - - Без авторизации - - - - - 0 - - - - ru - Basic - - - Basic - - - - - 0 - - - - ru - NTLM - - - NTLM - - - - - 0 - - - - ru - Digest - - - Digest - - - - - 0 - - - - ru - Bearer - - - Bearer - - - - - - - ТипАвторизацииПриИзменении - - - - ПользовательАвторизации + + + ru + Группа тип аутентификации + + + AlwaysHorizontal + None + false + DontUse + + + + ТипАутентификации + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Тип</v8:content> + </v8:item> + + 15 + false + false + true + false + false + false + false + false + false + false + + + + 0 + + + + ru + Без авторизации + + + Без авторизации + + + + + 0 + + + + ru + Basic + + + Basic + + + + + 0 + + + + ru + NTLM + + + NTLM + + + + + 0 + + + + ru + Digest + + + Digest + + + + + 0 + + + + ru + Bearer + + + Bearer + + + + + 0 + + + + ru + AWS4-HMAC-SHA256 + + + AWS4-HMAC-SHA256 + + + + + 0 + + + + ru + Hawk + + + Hawk + + + + + + + ТипАутентификацииПриИзменении + + + + + + ПользовательАутентификации false <v8:item> @@ -679,30 +727,30 @@ false false - - + + - + false <v8:item> <v8:lang>ru</v8:lang> - <v8:content>Группа пароль авторизации</v8:content> + <v8:content>Группа пароль аутентификации</v8:content> </v8:item> ru - Группа пароль авторизации + Группа пароль аутентификации AlwaysHorizontal None false - + - - ПарольАвторизации + + ПарольАутентификации <v8:item> <v8:lang>ru</v8:lang> @@ -712,42 +760,42 @@ <AutoMaxWidth>false</AutoMaxWidth> <VerticalStretch>false</VerticalStretch> <PasswordMode>true</PasswordMode> - <ContextMenu name="ПарольАвторизацииКонтекстноеМеню" id="134"/> - <ExtendedTooltip name="ПарольАвторизацииРасширеннаяПодсказка" id="135"/> + <ContextMenu name="ПарольАутентификацииКонтекстноеМеню" id="134"/> + <ExtendedTooltip name="ПарольАутентификацииРасширеннаяПодсказка" id="135"/> </InputField> - <Button name="ПоказатьПарольАвторизации" id="138"> + <Button name="ПоказатьПарольАутентификации" id="138"> <Type>UsualButton</Type> <Representation>Picture</Representation> - <CommandName>Form.Command.ПоказатьПарольАвторизации</CommandName> + <CommandName>Form.Command.ПоказатьПарольАутентификации</CommandName> <Picture> <xr:Ref>StdPicture.DataSearch</xr:Ref> <xr:LoadTransparent>true</xr:LoadTransparent> </Picture> - <ExtendedTooltip name="ПоказатьПарольАвторизацииРасширеннаяПодсказка" id="139"/> + <ExtendedTooltip name="ПоказатьПарольАутентификацииРасширеннаяПодсказка" id="139"/> </Button> </ChildItems> </UsualGroup> - <UsualGroup name="ГруппаТокенАвторизации" id="434"> + <UsualGroup name="ГруппаТокенАутентификации" id="434"> <Visible>false</Visible> <Title> <v8:item> <v8:lang>ru</v8:lang> - <v8:content>Группа токен авторизации</v8:content> + <v8:content>Группа токен аутентификации</v8:content> </v8:item> ru - Группа токен авторизации + Группа токен аутентификации AlwaysHorizontal None false - + - - ТокенАвторизации + + ТокенАутентификации <v8:item> <v8:lang>ru</v8:lang> @@ -757,21 +805,264 @@ <AutoMaxWidth>false</AutoMaxWidth> <VerticalStretch>false</VerticalStretch> <PasswordMode>true</PasswordMode> - <ContextMenu name="ТокенАвторизацииКонтекстноеМеню" id="248"/> - <ExtendedTooltip name="ТокенАвторизацииРасширеннаяПодсказка" id="249"/> + <ContextMenu name="ТокенАутентификацииКонтекстноеМеню" id="248"/> + <ExtendedTooltip name="ТокенАутентификацииРасширеннаяПодсказка" id="249"/> + </InputField> + <Button name="ПоказатьТокенАутентификации" id="436"> + <Type>UsualButton</Type> + <Representation>Picture</Representation> + <CommandName>Form.Command.ПоказатьТокенАутентификации</CommandName> + <Picture> + <xr:Ref>StdPicture.DataSearch</xr:Ref> + <xr:LoadTransparent>true</xr:LoadTransparent> + </Picture> + <ExtendedTooltip name="ПоказатьТокенАутентификацииРасширеннаяПодсказка" id="437"/> + </Button> + </ChildItems> + </UsualGroup> + <InputField name="КлючДоступаAWS" id="451"> + <DataPath>AWSКлючДоступа</DataPath> + <Visible>false</Visible> + <Title> + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Ключ доступа</v8:content> + </v8:item> + + false + true + false + + + + + false + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Группа секретный ключ AWS</v8:content> + </v8:item> + + + + ru + Группа секретный ключ AWS + + + AlwaysHorizontal + None + false + + + + AWSСекретныйКлюч + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Секретный ключ</v8:content> + </v8:item> + + false + true + false + true + + - + + AWSРегион + false + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Регион</v8:content> + </v8:item> + + false + true + false + true + false + true + false + false + false + + + + + AWSСервис + false + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Сервис</v8:content> + </v8:item> + + false + true + false + + + ru + например, s3 + + + + + + + HawkИдентификатор + false + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Идентификатор</v8:content> + </v8:item> + + false + true + false + + + + + false + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Группа ключ hawk</v8:content> + </v8:item> + + + + ru + Группа ключ hawk + + + AlwaysHorizontal + None + false + + + + HawkКлюч + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Ключ</v8:content> + </v8:item> + + false + true + false + true + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Секретный ключ</v8:content> + </v8:item> + + + + + + + + HawkДополнение + false + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>ext</v8:content> + </v8:item> + + false + true + false + + + ru + нарпимер, some-app-extra-data + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Специфические данные клиента</v8:content> + </v8:item> + + + + + HawkИдентификаторПриложения + false + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>app</v8:content> + </v8:item> + + false + true + false + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Идентификатор приложения</v8:content> + </v8:item> + + + + + HawkДелегирование + false + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>dlg</v8:content> + </v8:item> + + false + true + false + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Делегированный идентификатор приложения</v8:content> + </v8:item> + + + @@ -795,6 +1086,7 @@ true true true + AsFile ЗаголовкиЗапроса @@ -1029,6 +1321,7 @@ false false true + AsFile ТелоЗапросаДанныеФормы @@ -1180,6 +1473,7 @@ false false true + AsFile ТелоЗапросаДанныеHTMLФормы @@ -1573,6 +1867,7 @@ true true true + AsFile ЗаголовкиОтвета <v8:item> @@ -1715,7 +2010,7 @@ <Presentation> <v8:item> <v8:lang>ru</v8:lang> - <v8:content>HTML</v8:content> + <v8:content>Просмотр</v8:content> </v8:item> </Presentation> <Value xsi:type="xs:string">HTML</Value> @@ -1864,6 +2159,7 @@ <AutoMaxWidth>false</AutoMaxWidth> <AutoMaxHeight>false</AutoMaxHeight> <PictureSize>AutoSize</PictureSize> + <FileDragMode>AsFile</FileDragMode> <ContextMenu name="ОтветКартинкаКонтекстноеМеню" id="314"/> <ExtendedTooltip name="ОтветКартинкаРасширеннаяПодсказка" id="315"/> </PictureField> @@ -2053,6 +2349,7 @@ <v8:content>Группа контекст выполнения</v8:content> </v8:item> </ToolTip> + <Group>AlwaysHorizontal</Group> <Representation>None</Representation> <ShowTitle>false</ShowTitle> <ExtendedTooltip name="ГруппаКонтекстВыполненияРасширеннаяПодсказка" id="359"/> @@ -2126,6 +2423,7 @@ <v8:content>Группа файл тела ответа</v8:content> </v8:item> </ToolTip> + <Group>AlwaysHorizontal</Group> <Representation>None</Representation> <ShowTitle>false</ShowTitle> <ExtendedTooltip name="ГруппаФайлТелаОтветаРасширеннаяПодсказка" id="238"/> @@ -2194,6 +2492,40 @@ + + АгентПользователя + + + ru + Пользовательское значение заголовка "User-Agent" + + + Button + false + true + false + false + false + true + false + false + false + + + ru + значение платформы по умолчанию + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Пользовательское значение заголовка "User-Agent"</v8:content> + </v8:item> + + + <v8:item> @@ -2271,6 +2603,19 @@ <ContextMenu name="ПорогПеренаправленийКонтекстноеМеню" id="210"/> <ExtendedTooltip name="ПорогПеренаправленийРасширеннаяПодсказка" id="211"/> </InputField> + <CheckBoxField name="ПеренаправлениеКакGET" id="489"> + <DataPath>ПеренаправлениеКакGET</DataPath> + <ToolTip> + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Принудительно переключаться на метод GET для кодов перенаправления 301 и 302</v8:content> + </v8:item> + </ToolTip> + <ToolTipRepresentation>Button</ToolTipRepresentation> + <CheckBoxType>Auto</CheckBoxType> + <ContextMenu name="ПеренаправлениеКакGETКонтекстноеМеню" id="490"/> + <ExtendedTooltip name="ПеренаправлениеКакGETРасширеннаяПодсказка" id="491"/> + </CheckBoxField> <CheckBoxField name="ПоддержкаCookie" id="212"> <DataPath>ПоддержкаCookie</DataPath> <Title> @@ -2356,19 +2701,97 @@ <ContextMenu name="НеИспользоватьПроксиДляЛокальныхАдресовКонтекстноеМеню" id="350"/> <ExtendedTooltip name="НеИспользоватьПроксиДляЛокальныхАдресовРасширеннаяПодсказка" id="351"/> </CheckBoxField> - <InputField name="СерверПрокси" id="334"> - <DataPath>СерверПрокси</DataPath> + <UsualGroup name="ГруппаСерверПрокси" id="443"> <Enabled>false</Enabled> - <Title> + <ToolTip> <v8:item> <v8:lang>ru</v8:lang> - <v8:content>Сервер</v8:content> + <v8:content>Сервер прокси</v8:content> </v8:item> - - true - - - + + AlwaysHorizontal + None + false + + + + ПротоколПрокси + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Сервер</v8:content> + </v8:item> + + + + ru + Протокол прокси + + + false + false + true + false + false + false + false + false + false + + + + 0 + + + + ru + https + + + https + + + + + 0 + + + + ru + http + + + http + + + + + + + + СерверПрокси + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Сервер</v8:content> + </v8:item> + + None + + + ru + Сервер прокси + + + false + false + false + true + + + + + ПортПрокси false @@ -2542,6 +2965,7 @@ false true true + AsFile История Add @@ -2939,11 +3363,11 @@ - + <v8:item> <v8:lang>ru</v8:lang> - <v8:content>Тип авторизации</v8:content> + <v8:content>Тип аутентификации</v8:content> </v8:item> @@ -2954,11 +3378,11 @@ - + <v8:item> <v8:lang>ru</v8:lang> - <v8:content>Пользователь авторизации</v8:content> + <v8:content>Пользователь аутентификации</v8:content> </v8:item> @@ -2969,11 +3393,11 @@ - + <v8:item> <v8:lang>ru</v8:lang> - <v8:content>Пароль авторизации</v8:content> + <v8:content>Пароль аутентификации</v8:content> </v8:item> @@ -3242,11 +3666,11 @@ - + <v8:item> <v8:lang>ru</v8:lang> - <v8:content>Токен авторизации</v8:content> + <v8:content>Токен аутентификации</v8:content> </v8:item> @@ -3664,6 +4088,182 @@ xs:boolean + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Протокол прокси</v8:content> + </v8:item> + + + xs:string + + 5 + Variable + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Регион AWS</v8:content> + </v8:item> + + + xs:string + + 100 + Variable + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Секретный ключ AWS</v8:content> + </v8:item> + + + xs:string + + 1000 + Variable + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Сервис AWS</v8:content> + </v8:item> + + + xs:string + + 100 + Variable + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Ключ доступа AWS</v8:content> + </v8:item> + + + xs:string + + 1000 + Variable + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Ключ Hawk</v8:content> + </v8:item> + + + xs:string + + 0 + Variable + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Идентификатор Hawk</v8:content> + </v8:item> + + + xs:string + + 0 + Variable + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Дополнительные данные Hawk</v8:content> + </v8:item> + + + xs:string + + 0 + Variable + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Идентификатор приложения Hawk</v8:content> + </v8:item> + + + xs:string + + 0 + Variable + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Делегирование Hawk</v8:content> + </v8:item> + + + xs:string + + 0 + Variable + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Агент пользователя</v8:content> + </v8:item> + + + xs:string + + 0 + Variable + + + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Перенаправление как GET</v8:content> + </v8:item> + + + xs:boolean + + @@ -3880,20 +4480,20 @@ F7 ВыполнитьЗапрос - + <v8:item> <v8:lang>ru</v8:lang> - <v8:content>Показать пароль авторизации</v8:content> + <v8:content>Показать пароль аутентификации</v8:content> </v8:item> ru - Показать пароль авторизации + Показать пароль аутентификации - ПоказатьПарольАвторизации + ПоказатьПарольАутентификации @@ -4096,20 +4696,50 @@ </ToolTip> <Action>ПоказатьПарольПрокси</Action> </Command> - <Command name="ПоказатьТокенАвторизации" id="16"> + <Command name="ПоказатьТокенАутентификации" id="16"> + <Title> + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Показать токен аутентификации</v8:content> + </v8:item> + + + + ru + Показать токен аутентификации + + + ПоказатьТокенАутентификации + + + + <v8:item> + <v8:lang>ru</v8:lang> + <v8:content>Показать секретный ключ</v8:content> + </v8:item> + + + + ru + Показать секретный ключ + + + ПоказатьСекретныйКлючAWS + + <v8:item> <v8:lang>ru</v8:lang> - <v8:content>Показать токен авторизации</v8:content> + <v8:content>Показать ключ</v8:content> </v8:item> ru - Показать токен авторизации + Показать ключ hawk - ПоказатьТокенАвторизации + ПоказатьКлючHawk diff --git "a/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\244\320\276\321\200\320\274\320\260/Ext/Form/Module.bsl" "b/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\244\320\276\321\200\320\274\320\260/Ext/Form/Module.bsl" index d26a4d3..47e05c7 100644 --- "a/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\244\320\276\321\200\320\274\320\260/Ext/Form/Module.bsl" +++ "b/src/v1/DataProcessors/\320\232\320\276\320\275\321\201\320\276\320\273\321\214\320\232\320\273\320\270\320\265\320\275\321\202\320\260HTTP/Forms/\320\244\320\276\321\200\320\274\320\260/Ext/Form/Module.bsl" @@ -18,15 +18,20 @@ ПоддержкаCookie = Ложь; ПорогПеренаправлений = 10; + Для Каждого КЗ Из КлиентHTTPПовтИсп.РегионыAWS() Цикл + Элементы.РегионAWS.СписокВыбора.Добавить(КЗ.Значение); + КонецЦикла; + РазделыКонсоли = Элементы.РазделыКонсоли.СписокВыбора[0]; Схема = Элементы.Схема.СписокВыбора[0]; - ТипАвторизации = Элементы.ТипАвторизации.СписокВыбора[0]; + ТипАутентификации = Элементы.ТипАутентификации.СписокВыбора[0]; ТипТелаЗапроса = Элементы.ТипТелаЗапроса.СписокВыбора[0].Значение; ТипТелаЗапросаКакЕсть = Элементы.ТипТелаЗапросаКакЕсть.СписокВыбора[0]; ФорматТелаОтвета = Элементы.ФорматТелаОтвета.СписокВыбора[0]; + ПротоколПрокси = Элементы.ПротоколПрокси.СписокВыбора[0]; ИдентификаторРесурса = "https://ya.ru"; - Дополнительно = Новый Структура("Сессия, История", Новый Структура("Печенье", Новый Соответствие), Новый Соответствие); + Дополнительно = Новый Структура("Сессия, История", НоваяСессия(), Новый Соответствие); КонецПроцедуры #КонецОбласти @@ -48,26 +53,48 @@ КонецПроцедуры &НаКлиенте -Процедура ТипАвторизацииПриИзменении(Элемент) +Процедура ТипАутентификацииПриИзменении(Элемент) + ТипАутентификацииСписокВыбора = Элементы.ТипАутентификации.СписокВыбора; ОтображатьПользовательПароль = ( - ТипАвторизации = Элементы.ТипАвторизации.СписокВыбора[1].Значение - ИЛИ ТипАвторизации = Элементы.ТипАвторизации.СписокВыбора[2].Значение - ИЛИ ТипАвторизации = Элементы.ТипАвторизации.СписокВыбора[3].Значение + ТипАутентификации = ТипАутентификацииСписокВыбора[1].Значение + ИЛИ ТипАутентификации = ТипАутентификацииСписокВыбора[2].Значение + ИЛИ ТипАутентификации = ТипАутентификацииСписокВыбора[3].Значение ); - ОтображатьТокен = (ТипАвторизации = Элементы.ТипАвторизации.СписокВыбора[4].Значение); + ОтображатьТокен = (ТипАутентификации = ТипАутентификацииСписокВыбора[4].Значение); + ОтображатьAWS4 = (ТипАутентификации = ТипАутентификацииСписокВыбора[5].Значение); + ОтображатьHawk = (ТипАутентификации = ТипАутентификацииСписокВыбора[6].Значение); + + Элементы.ПоказатьПарольАутентификации.Пометка = Истина; + + ПоказатьПарольАутентификации(Неопределено); + + Элементы.ПользовательАутентификации.Видимость = ОтображатьПользовательПароль; + Элементы.ГруппаПарольАутентификации.Видимость = ОтображатьПользовательПароль; - Элементы.ПоказатьПарольАвторизации.Пометка = Истина; + Элементы.ПоказатьТокенАутентификации.Пометка = Истина; - ИзменитьРежимОтображенияПароля(Элементы.ПоказатьПарольАвторизации, Элементы.ПарольАвторизации); + ПоказатьТокенАутентификации(Неопределено); - Элементы.ПользовательАвторизации.Видимость = ОтображатьПользовательПароль; - Элементы.ГруппаПарольАвторизации.Видимость = ОтображатьПользовательПароль; + Элементы.ГруппаТокенАутентификации.Видимость = ОтображатьТокен; - Элементы.ПоказатьТокенАвторизации.Пометка = Истина; + Элементы.ПоказатьСекретныйКлючAWS.Пометка = Истина; - ИзменитьРежимОтображенияПароля(Элементы.ПоказатьТокенАвторизации, Элементы.ТокенАвторизации); + ПоказатьСекретныйКлючAWS(Неопределено); - Элементы.ГруппаТокенАвторизации.Видимость = ОтображатьТокен; + Элементы.КлючДоступаAWS.Видимость = ОтображатьAWS4; + Элементы.ГруппаСекретныйКлючAWS.Видимость = ОтображатьAWS4; + Элементы.РегионAWS.Видимость = ОтображатьAWS4; + Элементы.СервисAWS.Видимость = ОтображатьAWS4; + + Элементы.ПоказатьКлючHawk.Пометка = Истина; + + ПоказатьКлючHawk(Неопределено); + + Элементы.ИдентификаторHawk.Видимость = ОтображатьHawk; + Элементы.ГруппаКлючHawk.Видимость = ОтображатьHawk; + Элементы.ДополнениеHawk.Видимость = ОтображатьHawk; + Элементы.ИдентификаторПриложенияHawk.Видимость = ОтображатьHawk; + Элементы.ДелегированиеHawk.Видимость = ОтображатьHawk; КонецПроцедуры &НаКлиенте @@ -173,13 +200,23 @@ КонецПроцедуры &НаКлиенте -Процедура ПоказатьПарольАвторизации(Команда) - ИзменитьРежимОтображенияПароля(Элементы.ПоказатьПарольАвторизации, Элементы.ПарольАвторизации); +Процедура ПоказатьПарольАутентификации(Команда) + ИзменитьРежимОтображенияПароля(Элементы.ПоказатьПарольАутентификации, Элементы.ПарольАутентификации); КонецПроцедуры &НаКлиенте -Процедура ПоказатьТокенАвторизации(Команда) - ИзменитьРежимОтображенияПароля(Элементы.ПоказатьТокенАвторизации, Элементы.ТокенАвторизации); +Процедура ПоказатьТокенАутентификации(Команда) + ИзменитьРежимОтображенияПароля(Элементы.ПоказатьТокенАутентификации, Элементы.ТокенАутентификации); +КонецПроцедуры + +&НаКлиенте +Процедура ПоказатьСекретныйКлючAWS(Команда) + ИзменитьРежимОтображенияПароля(Элементы.ПоказатьСекретныйКлючAWS, Элементы.СекретныйКлючAWS); +КонецПроцедуры + +&НаКлиенте +Процедура ПоказатьКлючHawk(Команда) + ИзменитьРежимОтображенияПароля(Элементы.ПоказатьКлючHawk, Элементы.КлючHawk); КонецПроцедуры &НаКлиенте @@ -195,7 +232,7 @@ ОткрытьФорму( "Обработка.КонсольКлиентаHTTP.Форма.РедакторТекстовогоПоля", - Новый Структура("ЗаголовокФормы", "Команда curl"), + ПараметрыОткрытияФормыКомандыCurl(КомандаCurlЗапросаКонсоли()), ЭтотОбъект, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца @@ -553,7 +590,7 @@ &НаКлиенте Процедура ИспользоватьПроксиПриИзменении(Элемент) - Элементы.СерверПрокси.Доступность = ИспользоватьПрокси; + Элементы.ГруппаСерверПрокси.Доступность = ИспользоватьПрокси; Элементы.ПортПрокси.Доступность = ИспользоватьПрокси; Элементы.ПользовательПрокси.Доступность = ИспользоватьПрокси; Элементы.ГруппаПарольПрокси.Доступность = ИспользоватьПрокси; @@ -599,21 +636,33 @@ ОбъектИстории = Дополнительно.История.Получить(Стр.ВременнаяМетка); #Область Заполнение_конфигурации_Консоли - ВыполнятьНаСервере = НЕ ОбъектИстории.ВыполнятьНаСервере; - ТелоОтветаВФайл = ОбъектИстории.ТелоОтветаВФайл; - ИмяФайлаТелаОтвета = ОбъектИстории.ИмяФайлаТелаОтвета; - ПоддержкаСжатогоОтвета = ОбъектИстории.ПоддержкаСжатогоОтвета; - ИспользоватьСессию = ОбъектИстории.ИспользоватьСессию; - Дополнительно.Сессия = ОбъектИстории.Сессия; - ПорогПеренаправлений = ОбъектИстории.ПорогПеренаправлений; - ПоддержкаCookie = ОбъектИстории.ПоддержкаCookie; - ИспользоватьПрокси = ОбъектИстории.ИспользоватьПрокси; - НеИспользоватьПроксиДляЛокальныхАдресов = ОбъектИстории.НеИспользоватьПроксиДляЛокальныхАдресов; - СерверПрокси = ОбъектИстории.СерверПрокси; - ПортПрокси = ОбъектИстории.ПортПрокси; - ПользовательПрокси = ОбъектИстории.ПользовательПрокси; - ПарольПрокси = ОбъектИстории.ПарольПрокси; - ИспользоватьАутентификациюОСПрокси = ОбъектИстории.ИспользоватьАутентификациюОСПрокси; + ОбъектИстории.Свойство("ВыполнятьНаСервере", ВыполнятьНаСервере); + ОбъектИстории.Свойство("ТелоОтветаВФайл", ТелоОтветаВФайл); + ОбъектИстории.Свойство("ИмяФайлаТелаОтвета", ИмяФайлаТелаОтвета); + ОбъектИстории.Свойство("ПоддержкаСжатогоОтвета", ПоддержкаСжатогоОтвета); + ОбъектИстории.Свойство("АгентПользователя", АгентПользователя); + ОбъектИстории.Свойство("ИспользоватьСессию", ИспользоватьСессию); + ОбъектИстории.Свойство("Сессия", Дополнительно.Сессия); + ОбъектИстории.Свойство("ПорогПеренаправлений", ПорогПеренаправлений); + ОбъектИстории.Свойство("ПеренаправлениеКакGET", ПеренаправлениеКакGET); + ОбъектИстории.Свойство("ПоддержкаCookie", ПоддержкаCookie); + ОбъектИстории.Свойство("ИспользоватьПрокси", ИспользоватьПрокси); + ОбъектИстории.Свойство("НеИспользоватьПроксиДляЛокальныхАдресов", НеИспользоватьПроксиДляЛокальныхАдресов); + ОбъектИстории.Свойство("ПротоколПрокси", ПротоколПрокси); + ОбъектИстории.Свойство("СерверПрокси", СерверПрокси); + ОбъектИстории.Свойство("ПортПрокси", ПортПрокси); + ОбъектИстории.Свойство("ПользовательПрокси", ПользовательПрокси); + ОбъектИстории.Свойство("ПарольПрокси", ПарольПрокси); + ОбъектИстории.Свойство("ИспользоватьАутентификациюОСПрокси", ИспользоватьАутентификациюОСПрокси); + + ВыполнятьНаСервере = НЕ ВыполнятьНаСервере; + + Если Дополнительно.Сессия = Неопределено Тогда + Дополнительно.Сессия = НоваяСессия(); + КонецЕсли; + Если НЕ ЗначениеЗаполнено(ПротоколПрокси) Тогда + ПротоколПрокси = Элементы.ПротоколПрокси.СписокВыбора[0]; + КонецЕсли; ИзменитьКонтекстВыполненияЗапроса(); ИспользоватьСессиюПриИзменении(Неопределено); @@ -621,46 +670,63 @@ #КонецОбласти #Область Заполнение_запроса - ИдентификаторРесурса = ОбъектИстории.URI; + ОбъектИстории.Свойство("URI", ИдентификаторРесурса); ИдентификаторРесурсаПриИзменении(Неопределено); - Схема = ОбъектИстории.Схема; + ОбъектИстории.Свойство("Схема", Схема); ЗаголовкиЗапроса.Очистить(); - Для Каждого ЗаголовокЗапроса Из ОбъектИстории.ЗаголовкиЗапроса Цикл + ЗаголовкиИзИстории = Неопределено; + ОбъектИстории.Свойство("ЗаголовкиЗапроса", ЗаголовкиИзИстории); + Для Каждого ЗаголовокЗапроса Из ?(ЗаголовкиИзИстории = Неопределено, Новый Массив, ЗаголовкиИзИстории) Цикл ЗаполнитьЗначенияСвойств(ЗаголовкиЗапроса.Добавить(), ЗаголовокЗапроса); КонецЦикла; - ТипАвторизации = ОбъектИстории.ТипАвторизации; - ПользовательАвторизации = ОбъектИстории.ПользовательАвторизации; - ПарольАвторизации = ОбъектИстории.ПарольАвторизации; - ТокенАвторизации = ОбъектИстории.ТокенАвторизации; - - ТипАвторизацииПриИзменении(Неопределено); - - ТипТелаЗапроса = ОбъектИстории.ТипТелаЗапроса; - ТелоЗапросаТекст = ОбъектИстории.ТелоЗапросаТекст; - ТелоЗапросаФайл = ОбъектИстории.ТелоЗапросаФайл; - Разделитель = ОбъектИстории.Разделитель; + ОбъектИстории.Свойство("ТипАутентификации", ТипАутентификации); + ОбъектИстории.Свойство("ПользовательАутентификации", ПользовательАутентификации); + ОбъектИстории.Свойство("ПарольАутентификации", ПарольАутентификации); + ОбъектИстории.Свойство("ТокенАутентификации", ТокенАутентификации); + ОбъектИстории.Свойство("AWSКлючДоступа", AWSКлючДоступа); + ОбъектИстории.Свойство("AWSСекретныйКлюч", AWSСекретныйКлюч); + ОбъектИстории.Свойство("AWSРегион", AWSРегион); + ОбъектИстории.Свойство("AWSСервис", AWSСервис); + ОбъектИстории.Свойство("HawkИдентификатор", HawkИдентификатор); + ОбъектИстории.Свойство("HawkКлюч", HawkКлюч); + ОбъектИстории.Свойство("HawkДополнение", HawkДополнение); + ОбъектИстории.Свойство("HawkИдентификаторПриложения", HawkИдентификаторПриложения); + ОбъектИстории.Свойство("HawkДелегирование", HawkДелегирование); + + ТипАутентификацииПриИзменении(Неопределено); + + ОбъектИстории.Свойство("ТипТелаЗапроса", ТипТелаЗапроса); + ОбъектИстории.Свойство("ТелоЗапросаТекст", ТелоЗапросаТекст); + ОбъектИстории.Свойство("ТелоЗапросаФайл", ТелоЗапросаФайл); + ОбъектИстории.Свойство("Разделитель", Разделитель); ТипТелаЗапросаПриИзменении(Неопределено); ТелоЗапросаДанныеФормы.Очистить(); - Для Каждого ЭлементФормы Из ОбъектИстории.ТелоФорма Цикл + ТелоФормаИзИстории = Неопределено; + ОбъектИстории.Свойство("ТелоФорма", ТелоФормаИзИстории); + Для Каждого ЭлементФормы Из ?(ТелоФормаИзИстории = Неопределено, Новый Массив, ТелоФормаИзИстории) Цикл ЗаполнитьЗначенияСвойств(ТелоЗапросаДанныеФормы.Добавить(), ЭлементФормы); КонецЦикла; ТелоЗапросаДанныеHTMLФормы.Очистить(); - Для Каждого ЭлементФормы Из ОбъектИстории.ТелоHTMLФорма Цикл + ТелоHTMLФормаИзИстории = Неопределено; + ОбъектИстории.Свойство("ТелоHTMLФорма", ТелоHTMLФормаИзИстории); + Для Каждого ЭлементФормы Из ?(ТелоHTMLФормаИзИстории = Неопределено, Новый Массив, ТелоHTMLФормаИзИстории) Цикл ЗаполнитьЗначенияСвойств(ТелоЗапросаДанныеHTMLФормы.Добавить(), ЭлементФормы); КонецЦикла; #КонецОбласти #Область Заполнение_ответа - ВремяВыполнения = ОбъектИстории.ВремяВыполнения; + ОбъектИстории.Свойство("ВремяВыполнения", ВремяВыполнения); - ОбработатьОтвет(ОбъектИстории.Ответ); + Если ОбъектИстории.Свойство("Ответ") Тогда + ОбработатьОтвет(ОбъектИстории.Ответ); + КонецЕсли; #КонецОбласти РазделыКонсоли = Элементы.РазделыКонсоли.СписокВыбора[0].Значение; @@ -988,6 +1054,7 @@ ВывестиТелоОтветаJSON(ТекстТелаОтвета); ОтобразитьКартинкуТелаОтвета(ТипMIMEОтвета); + ПроверитьОтветHawk(Ответ); Элементы.ОтветHTML.Документ.Body.InnerHTML = ОтветHTML; КонецПроцедуры @@ -1087,6 +1154,29 @@ ПопробоватьОтобразитьКартинку(Неопределено); КонецПроцедуры +&НаКлиенте +Процедура ПроверитьОтветHawk(Знач Ответ) + Если ТипАутентификации <> Элементы.ТипАутентификации.СписокВыбора[6].Значение Тогда // Hawk + Возврат; + КонецЕсли; + Если Цел(Ответ.КодСостояния / 100) <> 2 Тогда // 2хх + Возврат; + КонецЕсли; + Если КлиентHTTPКлиентСервер.ЗначениеЗаголовка("Server-Authorization", Ответ.Заголовки) = Неопределено Тогда + СообщитьПользователю("В ответе отсутствует заголовок верефикации 'Server-Authorization'"); + КонецЕсли; + + ОписаниеОшибки = ""; + Если НЕ КлиентHTTPКлиентСервер.ОтветСЗаголовкомHawkКорректен(Ответ, "Server-Authorization", ОписаниеОшибки) Тогда + СообщитьПользователю(ОписаниеОшибки); + КонецЕсли; +КонецПроцедуры + +&НаКлиентеНаСервереБезКонтекста +Функция НоваяСессия() + Возврат Новый Структура("Печенье", Новый Соответствие); +КонецФункции + &НаКлиенте Процедура ДобавитьВИсторию(Знач Ответ) ТекущийМомент = ТекущаяУниверсальнаяДатаВМиллисекундах(); @@ -1135,6 +1225,7 @@ ОбъектОтвета.Вставить("Тело", Ответ.Тело); ОбъектОтвета.Вставить("Заголовки", Ответ.Заголовки); ОбъектОтвета.Вставить("ИмяФайлаТела", Ответ.ИмяФайлаТела); + ОбъектОтвета.Вставить("КонтекстВыполнения", Ответ.КонтекстВыполнения); ОбъектИстории = Новый Структура; ОбъектИстории.Вставить("Дата", ТекущаяДата()); @@ -1145,10 +1236,19 @@ ОбъектИстории.Вставить("URN", URN); ОбъектИстории.Вставить("ВремяВыполнения", ВремяВыполнения); ОбъектИстории.Вставить("Ответ", ОбъектОтвета); - ОбъектИстории.Вставить("ТипАвторизации", ТипАвторизации); - ОбъектИстории.Вставить("ПользовательАвторизации", ПользовательАвторизации); - ОбъектИстории.Вставить("ПарольАвторизации", ПарольАвторизации); - ОбъектИстории.Вставить("ТокенАвторизации", ТокенАвторизации); + ОбъектИстории.Вставить("ТипАутентификации", ТипАутентификации); + ОбъектИстории.Вставить("ПользовательАутентификации", ПользовательАутентификации); + ОбъектИстории.Вставить("ПарольАутентификации", ПарольАутентификации); + ОбъектИстории.Вставить("ТокенАутентификации", ТокенАутентификации); + ОбъектИстории.Вставить("AWSКлючДоступа", AWSКлючДоступа); + ОбъектИстории.Вставить("AWSСекретныйКлюч", AWSСекретныйКлюч); + ОбъектИстории.Вставить("AWSРегион", AWSРегион); + ОбъектИстории.Вставить("AWSСервис", AWSСервис); + ОбъектИстории.Вставить("HawkИдентификатор", HawkИдентификатор); + ОбъектИстории.Вставить("HawkКлюч", HawkКлюч); + ОбъектИстории.Вставить("HawkДополнение", HawkДополнение); + ОбъектИстории.Вставить("HawkИдентификаторПриложения", HawkИдентификаторПриложения); + ОбъектИстории.Вставить("HawkДелегирование", HawkДелегирование); ОбъектИстории.Вставить("ЗаголовкиЗапроса", Заголовки); ОбъектИстории.Вставить("ТипТелаЗапроса", ТипТелаЗапроса); ОбъектИстории.Вставить("Разделитель", Разделитель); @@ -1160,12 +1260,15 @@ ОбъектИстории.Вставить("ТелоОтветаВФайл", ТелоОтветаВФайл); ОбъектИстории.Вставить("ИмяФайлаТелаОтвета", ИмяФайлаТелаОтвета); ОбъектИстории.Вставить("ПоддержкаСжатогоОтвета", ПоддержкаСжатогоОтвета); + ОбъектИстории.Вставить("АгентПользователя", АгентПользователя); ОбъектИстории.Вставить("ИспользоватьСессию", ИспользоватьСессию); ОбъектИстории.Вставить("Сессия", Дополнительно.Сессия); ОбъектИстории.Вставить("ПорогПеренаправлений", ПорогПеренаправлений); + ОбъектИстории.Вставить("ПеренаправлениеКакGET", ПеренаправлениеКакGET); ОбъектИстории.Вставить("ПоддержкаCookie", ПоддержкаCookie); ОбъектИстории.Вставить("ИспользоватьПрокси", ИспользоватьПрокси); ОбъектИстории.Вставить("НеИспользоватьПроксиДляЛокальныхАдресов", НеИспользоватьПроксиДляЛокальныхАдресов); + ОбъектИстории.Вставить("ПротоколПрокси", ПротоколПрокси); ОбъектИстории.Вставить("СерверПрокси", СерверПрокси); ОбъектИстории.Вставить("ПортПрокси", ПортПрокси); ОбъектИстории.Вставить("ПользовательПрокси", ПользовательПрокси); @@ -1195,14 +1298,24 @@ Функция ПараметрыИдентификатораСПорядком(Знач ИдентификаторРесурса, Знач ПозицияНачала) фРезультат = Новый Структура("Параметры, Порядок", Новый Соответствие, Новый Массив); - ПараметрыСтрока = ?( - ПозицияНачала = 0, - "", - Сред(ИдентификаторРесурса, ПозицияНачала + 1) + Если ПозицияНачала = 0 Тогда + Возврат фРезультат; + КонецЕсли; + + ПозицияОкончания = СтрНайти(ИдентификаторРесурса, "#", , ПозицияНачала); + ПараметрыСтрока = Сред( + ИдентификаторРесурса, + ПозицияНачала + 1, + ?( + ПозицияОкончания = 0, + СтрДлина(ИдентификаторРесурса), + ПозицияОкончания - 1 + ) - ПозицияНачала ); - ПараметрыИдентификатора = СтрРазделить(ПараметрыСтрока, "&", Ложь); - Для Каждого Параметр Из ПараметрыИдентификатора Цикл + ПараметрыИдентификатора = Новый Массив; + МножествоСтрок = Новый Соответствие; + Для Каждого Параметр Из СтрРазделить(ПараметрыСтрока, "&", Ложь) Цикл ПозицияРазделителя = СтрНайти(Параметр, "="); Если ПозицияРазделителя = 0 Тогда ПозицияРазделителя = СтрДлина(Параметр) + 1; @@ -1215,6 +1328,16 @@ ЗначениеПараметра = Прав(Параметр, СтрДлина(Параметр) - ПозицияРазделителя); + ПараметрыИдентификатора.Добавить(Новый Структура("Ключ, Значение", ИмяПараметра, ЗначениеПараметра)); + МножествоСтрок.Вставить(ИмяПараметра); + МножествоСтрок.Вставить(ЗначениеПараметра); + КонецЦикла; + + МножествоСтрок = РаскодированныеСтрокиURLвURL(МножествоСтрок); + + Для Каждого Параметр Из ПараметрыИдентификатора Цикл + ИмяПараметра = МножествоСтрок.Получить(Параметр.Ключ); + ЗначениеПараметра = МножествоСтрок.Получить(Параметр.Значение); ЗначенияПараметра = фРезультат.Параметры.Получить(ИмяПараметра); Если ЗначенияПараметра = Неопределено Тогда ЗначенияПараметра = Новый Соответствие; @@ -1297,12 +1420,14 @@ ВызватьИсключение "Не удалось разобрать URI"; КонецЕсли; - ПозицияНачалаСтрокиПараметров = СтрНайти(ИдентификаторРесурса, "?", , ПозицияНачалаПоиска); + ПозицияСимволаПараметров = СтрНайти(ИдентификаторРесурса, "?", , ПозицияНачалаПоиска); + ПозицияСимволаФрагмента = СтрНайти(ИдентификаторРесурса, "#", , ?(ПозицияСимволаПараметров = 0, 1, ПозицияСимволаПараметров)); + ПозицияОкончания = ?(ПозицияСимволаПараметров = 0, ПозицияСимволаФрагмента, ПозицияСимволаПараметров); НовыйИдентификатор = ?( - ПозицияНачалаСтрокиПараметров = 0, + ПозицияОкончания = 0, ИдентификаторРесурса, - Лев(ИдентификаторРесурса, ПозицияНачалаСтрокиПараметров - 1) + Лев(ИдентификаторРесурса, ПозицияОкончания - 1) ); ПараметрыИдентификатора = Новый Массив; @@ -1318,7 +1443,12 @@ ПараметрыИдентификатора.Добавить(Новый Структура("Ключ, Значение", Стр.Ключ, ЗначениеПараметра)); КонецЦикла; - ИдентификаторРесурса = НовыйИдентификатор + КлиентHTTPКлиентСервер.ПараметрыЗапросаСтрокой(ПараметрыИдентификатора); + ИдентификаторРесурса = СтрШаблон( + "%1%2%3", + НовыйИдентификатор, + КлиентHTTPКлиентСервер.ПараметрыЗапросаСтрокой(ПараметрыИдентификатора), + ?(ПозицияСимволаФрагмента = 0, "", Сред(ИдентификаторРесурса, ПозицияСимволаФрагмента)) + ); КонецПроцедуры &НаКлиенте @@ -1342,15 +1472,19 @@ УстановитьЗаголовкиЗапроса(фРезультат); - ТипАвторизацииСписокВыбора = Элементы.ТипАвторизации.СписокВыбора; - Если ТипАвторизации = ТипАвторизацииСписокВыбора[1].Значение Тогда // Basic - КлиентHTTPКлиентСервер.УстановитьBasicАвторизацию(фРезультат, ПользовательАвторизации, ПарольАвторизации); - ИначеЕсли ТипАвторизации = ТипАвторизацииСписокВыбора[2].Значение Тогда // NTLM - КлиентHTTPКлиентСервер.УстановитьNTLMАвторизацию(фРезультат, ПользовательАвторизации, ПарольАвторизации); - ИначеЕсли ТипАвторизации = ТипАвторизацииСписокВыбора[3].Значение Тогда // Digest - КлиентHTTPКлиентСервер.УстановитьDigestАвторизацию(фРезультат, ПользовательАвторизации, ПарольАвторизации); - ИначеЕсли ТипАвторизации = ТипАвторизацииСписокВыбора[4].Значение Тогда // Bearer - КлиентHTTPКлиентСервер.УстановитьBearerАвторизацию(фРезультат, ТокенАвторизации); + ТипАутентификацииСписокВыбора = Элементы.ТипАутентификации.СписокВыбора; + Если ТипАутентификации = ТипАутентификацииСписокВыбора[1].Значение Тогда // Basic + КлиентHTTPКлиентСервер.УстановитьBasicАвторизацию(фРезультат, ПользовательАутентификации, ПарольАутентификации); + ИначеЕсли ТипАутентификации = ТипАутентификацииСписокВыбора[2].Значение Тогда // NTLM + КлиентHTTPКлиентСервер.УстановитьNTLMАвторизацию(фРезультат, ПользовательАутентификации, ПарольАутентификации); + ИначеЕсли ТипАутентификации = ТипАутентификацииСписокВыбора[3].Значение Тогда // Digest + КлиентHTTPКлиентСервер.УстановитьDigestАвторизацию(фРезультат, ПользовательАутентификации, ПарольАутентификации); + ИначеЕсли ТипАутентификации = ТипАутентификацииСписокВыбора[4].Значение Тогда // Bearer + КлиентHTTPКлиентСервер.УстановитьBearerАвторизацию(фРезультат, ТокенАутентификации); + ИначеЕсли ТипАутентификации = ТипАутентификацииСписокВыбора[5].Значение Тогда // AWS4-HMAC-SHA256 + КлиентHTTPКлиентСервер.УстановитьAWS4Авторизацию(фРезультат, AWSКлючДоступа, AWSСекретныйКлюч, AWSРегион, AWSСервис); + ИначеЕсли ТипАутентификации = ТипАутентификацииСписокВыбора[6].Значение Тогда // Hawk + КлиентHTTPКлиентСервер.УстановитьHawkАвторизацию(фРезультат, HawkИдентификатор, HawkКлюч, HawkДополнение, HawkИдентификаторПриложения, HawkДелегирование); КонецЕсли; Если ИспользоватьПрокси Тогда @@ -1369,7 +1503,8 @@ Если ИспользоватьСессию Тогда КлиентHTTPКлиентСервер .ИспользоватьСессию(фРезультат) - .УстановитьПорогПеренаправлений(фРезультат, ПорогПеренаправлений); + .УстановитьПорогПеренаправлений(фРезультат, ПорогПеренаправлений) + .ПеренаправленияКакGET(фРезультат, ПеренаправлениеКакGET); Если ПоддержкаCookie Тогда КлиентHTTPКлиентСервер.СкопироватьПеченье(фРезультат, Дополнительно); @@ -1380,6 +1515,10 @@ КлиентHTTPКлиентСервер.УстановитьСжатиеОтветаGZIP(фРезультат); КонецЕсли; + Если НЕ ПустаяСтрока(АгентПользователя) Тогда + КлиентHTTPКлиентСервер.УстановитьАгентаПользователя(фРезультат, АгентПользователя); + КонецЕсли; + Если ТелоОтветаВФайл Тогда Если ПустаяСтрока(ИмяФайлаТелаОтвета) Тогда Элементы.Основная.ТекущаяСтраница = Элементы.СтраницаНастройки; @@ -1542,25 +1681,22 @@ КонецПроцедуры &НаКлиенте -Процедура СообщитьПользователю(Знач Текст, Знач Поле) +Процедура СообщитьПользователю(Знач Текст, Знач Поле = Неопределено) Сообщение = Новый СообщениеПользователю; Сообщение.Текст = Текст; - Сообщение.Поле = Поле; + + Если Поле <> Неопределено Тогда + Сообщение.Поле = Поле; + КонецЕсли; + Сообщение.Сообщить(); КонецПроцедуры &НаКлиенте Функция ИсправленноеИмяЗаголовкаЗапроса(Знач Имя) - фРезультат = Новый Массив; - ДопустимыеСимволы = КлиентHTTPПовтИсп.ДопустимыеСимволыИмениЗаголовка(); - - Для я = 1 По СтрДлина(Имя) Цикл - СимволИмениЗаголовка = Сред(Имя, я, 1); - - фРезультат.Добавить(?(ДопустимыеСимволы.Получить(СимволИмениЗаголовка) = Неопределено, "-", СимволИмениЗаголовка)); - КонецЦикла; + НедопустимыеСимволы = СтрСоединить(СтрРазделить(Имя, КлиентHTTPПовтИсп.ДопустимыеСимволыИмениЗаголовкаСтрокой(), Ложь)); - Возврат СтрСоединить(фРезультат); + Возврат СтрСоединить(СтрРазделить(Имя, НедопустимыеСимволы), "-"); // заменили все недопустимые символы на "-" КонецФункции &НаКлиенте @@ -1578,6 +1714,7 @@ Элементы.ВремяВыполнения.Формат = СтрШаблон("ЧДЦ=%1; ЧС=%2; ЧН='0 мс'; ЧГ=; ЧФ='Ч %3'", Точность, Сдвиг, Единицы); КонецПроцедуры +#Область Кодогенерация &НаКлиенте Процедура ДобавитьВКодЗапросаИдентификаторРесурса(Построитель) ПозицияПараметровЗапроса = СтрНайти(ИдентификаторРесурса, "?"); @@ -1625,7 +1762,7 @@ Процедура ДобавитьВКодЗапросаИспользованиеСессии(Построитель, ЕстьДополнительныеПараметры) Если ИспользоватьСессию Тогда Построитель.Добавить(" .ИспользоватьСессию(ДополнительныеПараметры)"); - Построитель.Добавить(СтрШаблон(" .УстановитьПорогПеренаправлений(ДополнительныеПараметры, %1)", XMLСтрока(ПорогПеренаправлений))); + Построитель.Добавить(СтрШаблон(" .УстановитьПорогПеренаправлений(ДополнительныеПараметры, %1)", ПорогПеренаправлений)); ЕстьДополнительныеПараметры = Истина; КонецЕсли; @@ -1671,38 +1808,87 @@ КонецПроцедуры &НаКлиенте -Процедура ДобавитьВКодЗапросаАвторизацию(Построитель, ЕстьДополнительныеПараметры) - ТипАвторизацииСписокВыбора = Элементы.ТипАвторизации.СписокВыбора; - Если ТипАвторизации = ТипАвторизацииСписокВыбора[1].Значение Тогда // Basic +Процедура ДобавитьВКодЗапросаАутентификацию(Построитель, ЕстьДополнительныеПараметры) + ТипАутентификацииСписокВыбора = Элементы.ТипАутентификации.СписокВыбора; + Если ТипАутентификации = ТипАутентификацииСписокВыбора[1].Значение Тогда // Basic Построитель.Добавить(СтрШаблон( " .УстановитьBasicАвторизацию(ДополнительныеПараметры, ""%1"", ""%2"")", - ПользовательАвторизации, - ПарольАвторизации + ПользовательАутентификации, + ПарольАутентификации )); ЕстьДополнительныеПараметры = Истина; - ИначеЕсли ТипАвторизации = ТипАвторизацииСписокВыбора[2].Значение Тогда // NTLM + ИначеЕсли ТипАутентификации = ТипАутентификацииСписокВыбора[2].Значение Тогда // NTLM Построитель.Добавить(СтрШаблон( " .УстановитьNTLMАвторизацию(ДополнительныеПараметры, ""%1"", ""%2"")", - ПользовательАвторизации, - ПарольАвторизации + ПользовательАутентификации, + ПарольАутентификации )); ЕстьДополнительныеПараметры = Истина; - ИначеЕсли ТипАвторизации = ТипАвторизацииСписокВыбора[3].Значение Тогда // Digest + ИначеЕсли ТипАутентификации = ТипАутентификацииСписокВыбора[3].Значение Тогда // Digest Построитель.Добавить(СтрШаблон( " .УстановитьDigestАвторизацию(ДополнительныеПараметры, ""%1"", ""%2"")", - ПользовательАвторизации, - ПарольАвторизации + ПользовательАутентификации, + ПарольАутентификации )); ЕстьДополнительныеПараметры = Истина; - ИначеЕсли ТипАвторизации = ТипАвторизацииСписокВыбора[4].Значение Тогда // Bearer + ИначеЕсли ТипАутентификации = ТипАутентификацииСписокВыбора[4].Значение Тогда // Bearer Построитель.Добавить(СтрШаблон( " .УстановитьBearerАвторизацию(ДополнительныеПараметры, ""%1"")", - ТокенАвторизации + ТокенАутентификации + )); + + ЕстьДополнительныеПараметры = Истина; + ИначеЕсли ТипАутентификации = ТипАутентификацииСписокВыбора[5].Значение Тогда // AWS4-HMAC-SHA256 + ЧастиСтроки = Новый Массив; + ЧастиСтроки.Добавить(СтрШаблон( + " .УстановитьAWS4Авторизацию(ДополнительныеПараметры, ""%1"", ""%2""", + AWSКлючДоступа, + AWSСекретныйКлюч + )); + Если НЕ ПустаяСтрока(AWSРегион) Тогда + ЧастиСтроки.Добавить(СтрШаблон(", ""%1""", AWSРегион)); + КонецЕсли; + Если НЕ ПустаяСтрока(AWSСервис) Тогда + ЧастиСтроки.Добавить(?( + ПустаяСтрока(AWSРегион), + СтрШаблон(", , ""%1""", AWSСервис), + СтрШаблон(", ""%1""", AWSСервис) + )); + КонецЕсли; + ЧастиСтроки.Добавить(")"); + + Построитель.Добавить(СтрСоединить(ЧастиСтроки, "")); + + ЕстьДополнительныеПараметры = Истина; + ИначеЕсли ТипАутентификации = ТипАутентификацииСписокВыбора[6].Значение Тогда // Hawk + ЧастиСтроки = Новый Массив; + ЧастиСтроки.Добавить(СтрШаблон( + " .УстановитьHawkАвторизацию(ДополнительныеПараметры, ""%1"", ""%2""", + HawkИдентификатор, + HawkКлюч )); + ОкончанияСтроки = Новый Массив; + ОкончанияСтроки.Добавить(СокрЛП(HawkДополнение)); + ОкончанияСтроки.Добавить(СокрЛП(HawkИдентификаторПриложения)); + ОкончанияСтроки.Добавить(СокрЛП(HawkДелегирование)); + Для я = 0 По 2 Цикл + Если ОкончанияСтроки[ОкончанияСтроки.ВГраница()] <> "" Тогда + Прервать; + КонецЕсли; + + ОкончанияСтроки.Удалить(ОкончанияСтроки.ВГраница()); + КонецЦикла; + + Для Каждого Окончание Из ОкончанияСтроки Цикл + ЧастиСтроки.Добавить(?(Окончание = "", "", СтрШаблон("""%1""", СокрЛП(Окончание)))); + КонецЦикла; + + Построитель.Добавить(СтрСоединить(ЧастиСтроки, ", ") + ")"); + ЕстьДополнительныеПараметры = Истина; КонецЕсли; КонецПроцедуры @@ -2133,7 +2319,7 @@ ДобавитьВКодЗапросаПараметры(ЧастиКода, ЕстьПараметрыЗапроса); ДобавитьВКодЗапросаЗаголовки(ЧастиКода, ЕстьДополнительныеПараметры); ДобавитьВКодЗапросаСжатиеОтвета(ЧастиКода, ЕстьДополнительныеПараметры); - ДобавитьВКодЗапросаАвторизацию(ЧастиКода, ЕстьДополнительныеПараметры); + ДобавитьВКодЗапросаАутентификацию(ЧастиКода, ЕстьДополнительныеПараметры); ДобавитьВКодЗапросаФайлТелаОтвета(ЧастиКода, ЕстьДополнительныеПараметры, ТребуетсяИмяФайлаТелаОтвета); ДобавитьВКодЗапросаМетод(ЧастиКода, ЕстьТекстТелаЗапроса, ЕстьПоляФормы, ТекстПолейФормы, ФайлыПолейФормы, ЕстьПараметрыЗапроса, ЕстьДополнительныеПараметры); ДобавитьВКодЗапросаИнициализациюПолейФормы(ЧастиКода, ТекстПолейФормы, ФайлыПолейФормы); @@ -2161,7 +2347,353 @@ Функция КавычкиВТексте1С(Знач Текст) Возврат СтрЗаменить(Текст, """", """"""); КонецФункции +#КонецОбласти + +#Область ГенерацияКомандыCurl +&НаКлиенте +Функция ЭкранированиеАпострофаUnix(Знач Текст) + Возврат СтрЗаменить(Текст, "'", "'\''") +КонецФункции + +&НаКлиенте +Функция ЭкранированиеСимволовЗначенияПоляФормы(Знач Текст, Знач ЭкранироватьОбратныйСлеш) + Возврат СтрЗаменить( + ЭкранированиеАпострофаUnix( + ?( + ЭкранироватьОбратныйСлеш, + СтрЗаменить(Текст, "\", "\\"), + Текст + ) + ), """", "\""" + ); +КонецФункции + +&НаКлиенте +Процедура ЗаполнитьПользователяИПарольCurlКоманды(ЧастиКоманды) + Если НЕ ЗначениеЗаполнено(ПользовательАутентификации) Тогда + Возврат; + КонецЕсли; + + ЧастиАутентификации = Новый Массив; + + ЧастиКоманды.Добавить("-u"); + ЧастиАутентификации.Добавить(ПользовательАутентификации); + ЧастиАутентификации.Добавить(ПарольАутентификации); + ЧастиКоманды.Добавить(СтрШаблон("'%1'", ЭкранированиеАпострофаUnix(СтрСоединить(ЧастиАутентификации, ":")))); +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьAWS4CurlКоманды(ЧастиКоманды) + ЧастиАутентификации = Новый Массив; + + ЧастиКоманды.Добавить("-u"); + ЧастиАутентификации.Добавить(AWSКлючДоступа); + ЧастиАутентификации.Добавить(AWSСекретныйКлюч); + ЧастиКоманды.Добавить(СтрШаблон("'%1'", ЭкранированиеАпострофаUnix(СтрСоединить(ЧастиАутентификации, ":")))); + + ЧастиКоманды.Добавить("--aws-sigv4"); + ЧастиАутентификации.Очистить(); + ЧастиАутентификации.Добавить("aws:amz"); + Если НЕ ПустаяСтрока(AWSРегион) Тогда + ЧастиАутентификации.Добавить(AWSРегион); + Если НЕ ПустаяСтрока(AWSСервис) Тогда + ЧастиАутентификации.Добавить(AWSСервис); + КонецЕсли; + КонецЕсли; + + ЧастиКоманды.Добавить(СтрШаблон("'%1'", ЭкранированиеАпострофаUnix(СтрСоединить(ЧастиАутентификации, ":")))); +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьАутентификациюCurlКоманды(ЧастиКоманды) + Если ТипАутентификации = Элементы.ТипАутентификации.СписокВыбора[1].Значение Тогда // Basic + ЗаполнитьПользователяИПарольCurlКоманды(ЧастиКоманды); + ЧастиКоманды.Добавить("--basic"); + ИначеЕсли ТипАутентификации = Элементы.ТипАутентификации.СписокВыбора[2].Значение Тогда // NTLM + ЗаполнитьПользователяИПарольCurlКоманды(ЧастиКоманды); + ЧастиКоманды.Добавить("--ntlm"); + ИначеЕсли ТипАутентификации = Элементы.ТипАутентификации.СписокВыбора[3].Значение Тогда // Digest + ЗаполнитьПользователяИПарольCurlКоманды(ЧастиКоманды); + ЧастиКоманды.Добавить("--digest"); + ИначеЕсли ТипАутентификации = Элементы.ТипАутентификации.СписокВыбора[4].Значение Тогда // Bearer + ЧастиКоманды.Добавить("--oauth2-bearer"); + ЧастиКоманды.Добавить(СтрШаблон("'%1'", ЭкранированиеАпострофаUnix(ТокенАутентификации))); + ИначеЕсли ТипАутентификации = Элементы.ТипАутентификации.СписокВыбора[5].Значение Тогда // AWS4-HMAC-SHA256 + ЗаполнитьAWS4CurlКоманды(ЧастиКоманды); + КонецЕсли; +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьПолеФормыCurlКоманды(ЧастиКоманды, Знач Поле) + ТипMIME = ""; + ИмяФайла = ""; + ЭкранироватьОбратныйСлеш = Истина; + ТипыДанныхФормыФайл = Элементы.ТелоЗапросаДанныеФормы.ПодчиненныеЭлементы.ДанныеФормыТип.СписокВыбора[1].Значение; + + ЧастиПоляФормы = Новый Массив; + ЧастиПоляФормы.Добавить(ЭкранированиеАпострофаUnix(Поле.Ключ)); + ЧастиПоляФормы.Добавить("="); + Если Поле.Тип = ТипыДанныхФормыФайл Тогда + ЧастиПоляФормы.Добавить("@"); + + ФайлПоля = Новый Файл(Поле.Значение); + ИмяФайла = ФайлПоля.Имя; + ТипMIME = КлиентHTTPСлужебный.ТипMIMEРасширенияФайла(ФайлПоля.Расширение); + ЭкранироватьОбратныйСлеш = ?(ВыполнятьНаСервере, РазделительПутиСервера(), ПолучитьРазделительПутиКлиента()) <> "\"; + КонецЕсли; + + ЧастиПоляФормы.Добавить(""""); + ЧастиПоляФормы.Добавить(ЭкранированиеСимволовЗначенияПоляФормы(Поле.Значение, ЭкранироватьОбратныйСлеш)); + + Если НЕ ПустаяСтрока(ИмяФайла) Тогда + ЧастиПоляФормы.Добавить(";filename="); + ЧастиПоляФормы.Добавить(ИмяФайла); + КонецЕсли; + Если НЕ ПустаяСтрока(ТипMIME) Тогда + ЧастиПоляФормы.Добавить(";type="); + ЧастиПоляФормы.Добавить(ТипMIME); + КонецЕсли; + + ЧастиПоляФормы.Добавить(""""); + + ЧастиКоманды.Добавить("-F"); + ЧастиКоманды.Добавить(СтрШаблон("'%1'", СтрСоединить(ЧастиПоляФормы, ""))); +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьДанныеФормыCurlКоманды(ЧастиКоманды, ОтобразитьPOST, ПредопределенныеЗаголовки) + Если ТелоЗапросаДанныеФормы.Количество() = 0 Тогда + ОтобразитьPOST = Истина; + Возврат; + КонецЕсли; + + Для Каждого Стр Из ТелоЗапросаДанныеФормы Цикл + ЗаполнитьПолеФормыCurlКоманды(ЧастиКоманды, Стр); + КонецЦикла; + + ПредопределенныеЗаголовки.Добавить( + Новый Структура("Ключ, Значение", "Content-Type", "multipart/form-data; boundary=" + Разделитель) + ); +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьДанныеHTMLФормыCurlКоманды(ЧастиКоманды, ОтобразитьPOST, ПредопределенныеЗаголовки) + Если ТелоЗапросаДанныеHTMLФормы.Количество() = 0 Тогда + ОтобразитьPOST = Истина; + Возврат; + КонецЕсли; + + ПоляФормы = Новый Массив; + Для Каждого Стр Из ТелоЗапросаДанныеHTMLФормы Цикл + ЧастиКоманды.Добавить("--data-urlencode"); + ЧастиКоманды.Добавить(СтрШаблон("'%1=%2'", КодированныйТекстВURL(Стр.Ключ), ЭкранированиеАпострофаUnix(Стр.Значение))); + КонецЦикла; + + ПредопределенныеЗаголовки.Добавить(Новый Структура("Ключ, Значение", "Content-Type", "application/x-www-form-urlencoded")); +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьТекстовыеДанныеCurlКоманды(ЧастиКоманды, ОтобразитьPOST) + Если ПустаяСтрока(ТелоЗапросаТекст) Тогда + ОтобразитьPOST = Истина; + Возврат; + КонецЕсли; + + ЧастиКоманды.Добавить("--data-raw"); + ЧастиКоманды.Добавить(СтрШаблон("'%1'", ЭкранированиеАпострофаUnix(ТелоЗапросаТекст))); +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьДанныеФайлаCurlКоманды(ЧастиКоманды, ОтобразитьPOST, ПредопределенныеЗаголовки) + Если ПустаяСтрока(ТелоЗапросаФайл) Тогда + ОтобразитьPOST = Истина; + Возврат; + КонецЕсли; + + ЧастиКоманды.Добавить("--data-binary"); + ЧастиКоманды.Добавить(СтрШаблон("@""%1""", ЭкранированиеАпострофаUnix(ТелоЗапросаФайл))); + + ФайлТела = Новый Файл(ТелоЗапросаФайл); + ТипMIME = КлиентHTTPСлужебный.ТипMIMEРасширенияФайла(ФайлТела.Расширение); + + ПредопределенныеЗаголовки.Добавить(Новый Структура("Ключ, Значение", "Content-Type", ТипMIME)); +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьТелоЗапросаCurlКоманды(ЧастиКоманды, ОтобразитьPOST, ПредопределенныеЗаголовки) + Если ТипТелаЗапроса = Элементы.ТипТелаЗапроса.СписокВыбора[1].Значение Тогда // multipart/form-data + ЗаполнитьДанныеФормыCurlКоманды(ЧастиКоманды, ОтобразитьPOST, ПредопределенныеЗаголовки); + ИначеЕсли ТипТелаЗапроса = Элементы.ТипТелаЗапроса.СписокВыбора[2].Значение Тогда // application/x-www-form-urlencoded + ЗаполнитьДанныеHTMLФормыCurlКоманды(ЧастиКоманды, ОтобразитьPOST, ПредопределенныеЗаголовки); + ИначеЕсли ТипТелаЗапроса = Элементы.ТипТелаЗапроса.СписокВыбора[3].Значение Тогда // Текст + ЗаполнитьТекстовыеДанныеCurlКоманды(ЧастиКоманды, ОтобразитьPOST); + ИначеЕсли ТипТелаЗапроса = Элементы.ТипТелаЗапроса.СписокВыбора[4].Значение Тогда // Файл + ЗаполнитьДанныеФайлаCurlКоманды(ЧастиКоманды, ОтобразитьPOST, ПредопределенныеЗаголовки); + Иначе + ОтобразитьPOST = Истина; + КонецЕсли; +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьФайлОтветаCurlКоманды(ЧастиКоманды) + Если НЕ (ТелоОтветаВФайл И ЗначениеЗаполнено(ИмяФайлаТелаОтвета)) Тогда + Возврат; + КонецЕсли; + + ЧастиКоманды.Добавить("-o"); + ЧастиКоманды.Добавить(СтрШаблон("""%1""", ИмяФайлаТелаОтвета)); +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьПроксиCurlКоманды(ЧастиКоманды) + Если НЕ (ИспользоватьПрокси И ЗначениеЗаполнено(СерверПрокси)) Тогда + Возврат; + КонецЕсли; + + ЧастиПрокси = Новый Массив; + + Если ЗначениеЗаполнено(ПользовательПрокси) Тогда + ЧастиПрокси.Добавить(ПользовательПрокси); + ЧастиПрокси.Добавить(ПарольПрокси); + + ЧастиКоманды.Добавить(?(ИспользоватьАутентификациюОСПрокси, "--proxy-ntlm", "--proxy-basic")); + ЧастиКоманды.Добавить("--proxy-user"); + ЧастиКоманды.Добавить(СтрШаблон("'%1'", СтрЗаменить(СтрСоединить(ЧастиПрокси, ":"), "'", "'\''"))); + КонецЕсли; + + ЧастиПрокси.Очистить(); + ЧастиПрокси.Добавить(ПротоколПрокси); + ЧастиПрокси.Добавить("://"); + ЧастиПрокси.Добавить(СерверПрокси); + + Если ЗначениеЗаполнено(ПортПрокси) Тогда + ЧастиПрокси.Добавить(":"); + ЧастиПрокси.Добавить(ПортПрокси); + КонецЕсли; + + ЧастиКоманды.Добавить("-x"); + ЧастиКоманды.Добавить(СтрСоединить(ЧастиПрокси, "")); +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьСессиюCurlКоманды(ЧастиКоманды, ЧастиСложнойОпции) + Если НЕ ИспользоватьСессию Тогда + Возврат; + КонецЕсли; + + Если ЗначениеЗаполнено(ПорогПеренаправлений) Тогда + ЧастиКоманды.Добавить("--max-redirs"); + ЧастиКоманды.Добавить(ПорогПеренаправлений); + КонецЕсли; + + ЧастиСложнойОпции.Добавить("L"); + + Если ПоддержкаCookie Тогда + ЗначениеCookie = КлиентHTTPКлиентСервер.ЗначениеЗаголовкаCookieРесурса(ИдентификаторРесурса, Дополнительно); + Если ЗначениеЗаполнено(ЗначениеCookie) Тогда + ЧастиКоманды.Добавить("-b"); + ЧастиКоманды.Добавить(СтрШаблон("'%1'", ЭкранированиеАпострофаUnix(ЗначениеCookie))); + КонецЕсли; + КонецЕсли; +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьСжатиеCurlКоманды(ЧастиКоманды) + Если ПоддержкаСжатогоОтвета Тогда + ЧастиКоманды.Добавить("--compressed"); + КонецЕсли; +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьЗаголовкиCurlКоманды(ЧастиКоманды, Знач ПредопределенныеЗаголовки) + Для Каждого Стр Из ПредопределенныеЗаголовки Цикл + ЧастиКоманды.Добавить("-H"); + ЧастиКоманды.Добавить( + СтрШаблон("'%1: %2'", ЭкранированиеАпострофаUnix(Стр.Ключ), ЭкранированиеАпострофаUnix(Стр.Значение)) + ); + КонецЦикла; + + Для Каждого Стр Из ЗаголовкиЗапроса Цикл + Если НЕ Стр.Активно Тогда + Продолжить; + КонецЕсли; + + ЧастиКоманды.Добавить("-H"); + ЧастиКоманды.Добавить( + СтрШаблон("'%1: %2'", ЭкранированиеАпострофаUnix(Стр.Ключ), ЭкранированиеАпострофаUnix(Стр.Значение)) + ); + КонецЦикла; +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьСхемуЗапросаCurlКоманды(ЧастиКоманды, ЧастиСложнойОпции, Знач ОтобразитьPOST) + СхемаСписокВыбора = Элементы.Схема.СписокВыбора; + Если Схема = СхемаСписокВыбора[0].Значение И НЕ ОтобразитьPOST Тогда // GET + ЧастиКоманды.Добавить(СтрШаблон("-X %1", Схема)); + ИначеЕсли Схема = СхемаСписокВыбора[1].Значение И ОтобразитьPOST Тогда // POST + ЧастиКоманды.Добавить(СтрШаблон("-X %1", Схема)); + ИначеЕсли Схема = СхемаСписокВыбора[4].Значение Тогда // HEAD + ЧастиСложнойОпции.Добавить("I"); + ИначеЕсли Схема = СхемаСписокВыбора[2].Значение // PUT + ИЛИ Схема = СхемаСписокВыбора[3].Значение // DELETE + ИЛИ Схема = СхемаСписокВыбора[5].Значение // PATCH + Тогда + ЧастиКоманды.Добавить(СтрШаблон("-X %1", Схема)); + КонецЕсли; +КонецПроцедуры + +&НаКлиенте +Процедура ЗаполнитьЧастиРазделаКомандыCurl(ЧастиКоманды, Знач РазделКоманды) + Для Каждого Часть Из РазделКоманды Цикл + ЧастиКоманды.Добавить(Часть); + КонецЦикла; +КонецПроцедуры + +&НаКлиенте +Функция КомандаCurlЗапросаКонсоли() + ЧастиСложнойОпции = Новый Массив; + ПредопределенныеЗаголовки = Новый Массив; + ОтобразитьPOST = Ложь; + + РазделыКоманды = Новый Структура( + "Аутентификация, Тело, СохранениеОтветаВФайл, Прокси, Сессия, Сжатие, Заголовки, Схема", + Новый Массив, Новый Массив, Новый Массив, Новый Массив, Новый Массив, Новый Массив, Новый Массив, Новый Массив + ); + + ЗаполнитьАутентификациюCurlКоманды(РазделыКоманды.Аутентификация); + ЗаполнитьТелоЗапросаCurlКоманды(РазделыКоманды.Тело, ОтобразитьPOST, ПредопределенныеЗаголовки); + ЗаполнитьФайлОтветаCurlКоманды(РазделыКоманды.СохранениеОтветаВФайл); + ЗаполнитьПроксиCurlКоманды(РазделыКоманды.Прокси); + ЗаполнитьСессиюCurlКоманды(РазделыКоманды.Сессия, ЧастиСложнойОпции); + ЗаполнитьСжатиеCurlКоманды(РазделыКоманды.Сжатие); + ЗаполнитьЗаголовкиCurlКоманды(РазделыКоманды.Заголовки, ПредопределенныеЗаголовки); + ЗаполнитьСхемуЗапросаCurlКоманды(РазделыКоманды.Схема, ЧастиСложнойОпции, ОтобразитьPOST); + + ЧастиКоманды = Новый Массив; + ЧастиКоманды.Добавить("curl"); + + Если ЧастиСложнойОпции.Количество() > 0 Тогда + ЧастиСложнойОпции.Вставить(0, "-"); + ЧастиКоманды.Добавить(СтрСоединить(ЧастиСложнойОпции, "")); + КонецЕсли; + + ЗаполнитьЧастиРазделаКомандыCurl(ЧастиКоманды, РазделыКоманды.Схема); + + ЧастиКоманды.Добавить(КодированныйURIВURL(ИдентификаторРесурса)); + + ЗаполнитьЧастиРазделаКомандыCurl(ЧастиКоманды, РазделыКоманды.Аутентификация); + ЗаполнитьЧастиРазделаКомандыCurl(ЧастиКоманды, РазделыКоманды.Заголовки); + ЗаполнитьЧастиРазделаКомандыCurl(ЧастиКоманды, РазделыКоманды.Тело); + ЗаполнитьЧастиРазделаКомандыCurl(ЧастиКоманды, РазделыКоманды.Прокси); + ЗаполнитьЧастиРазделаКомандыCurl(ЧастиКоманды, РазделыКоманды.СохранениеОтветаВФайл); + ЗаполнитьЧастиРазделаКомандыCurl(ЧастиКоманды, РазделыКоманды.Сжатие); + ЗаполнитьЧастиРазделаКомандыCurl(ЧастиКоманды, РазделыКоманды.Сессия); + + Возврат СтрСоединить(ЧастиКоманды, " "); +КонецФункции +#КонецОбласти +#Область ИмпортPostman &НаКлиенте Процедура ПрочитатьФайлИмпорта(Знач ИмяФайлаИмпорта, Отказ, ОписаниеОшибки) ФайлИмпорта = Новый Файл(ИмяФайлаИмпорта); @@ -2294,48 +2826,60 @@ &НаКлиенте Функция ИдентификаторРесурсаИмпортаPostman(Знач Запрос, Знач ЗначенияШаблонов) - ИдентификаторРесурсаИмпорт = ЗначениеПеременнойИмпортаPostman(Запрос["url"]["raw"], ЗначенияШаблонов); + ИдентификаторРесурсаИмпорт = ?( + Запрос["url"] = Неопределено, + "", + ЗначениеПеременнойИмпортаPostman(Запрос["url"]["raw"], ЗначенияШаблонов) + ); Возврат ?(ПустаяСтрока(ИдентификаторРесурсаИмпорт), "http://", ИдентификаторРесурсаИмпорт); КонецФункции &НаКлиенте -Функция АвторизацияИмпортаPostman(Знач Запрос, Знач ЗначенияШаблонов) - Перем НайденныйТипАвторизации; +Функция АутентификацияИмпортаPostman(Знач Запрос, Знач ЗначенияШаблонов) + Перем НайденныйТипАутентификации; - фРезультат = Новый Структура("Тип, Пользователь, Пароль, Токен", Элементы.ТипАвторизации.СписокВыбора[0], "", "", ""); + ТипАутентификацииСписокВыбора = Элементы.ТипАутентификации.СписокВыбора; + + фРезультат = Новый Структура( + "Тип, Пользователь, Пароль, Токен, РегионAWS, СервисAWS, ДополнениеHawk, ИдентификаторПриложенияHawk, ДелегированиеHawk", + ТипАутентификацииСписокВыбора[0], "", "", "", "", "", "", "", "" + ); - ОбъектАвторизации = Запрос["auth"]; - Если ОбъектАвторизации = Неопределено Тогда + ОбъектАутентификации = Запрос["auth"]; + Если ОбъектАутентификации = Неопределено Тогда Возврат фРезультат; КонецЕсли; - ТипАвторизацииИмпорт = ВРег(ОбъектАвторизации["type"]); - Для Каждого ЭлементТиповАвторизации Из Элементы.ТипАвторизации.СписокВыбора Цикл - Если ВРег(ЭлементТиповАвторизации.Значение) = ТипАвторизацииИмпорт Тогда - НайденныйТипАвторизации = ЭлементТиповАвторизации; + ТипАутентификацииИмпорт = ВРег(ОбъектАутентификации["type"]); + Для Каждого ЭлементТиповАутентификации Из ТипАутентификацииСписокВыбора Цикл + Если ВРег(ЭлементТиповАутентификации.Значение) = ТипАутентификацииИмпорт Тогда + НайденныйТипАутентификации = ЭлементТиповАутентификации; Прервать; КонецЕсли; КонецЦикла; + Если НайденныйТипАутентификации = Неопределено И ТипАутентификацииИмпорт = "AWSV4" Тогда + НайденныйТипАутентификации = ТипАутентификацииСписокВыбора[5]; // AWS4-HMAC-SHA256 + КонецЕсли; - Если НайденныйТипАвторизации = Неопределено Тогда + Если НайденныйТипАутентификации = Неопределено Тогда Возврат фРезультат; КонецЕсли; - фРезультат.Тип = НайденныйТипАвторизации; + фРезультат.Тип = НайденныйТипАутентификации; - Имена = СтрРазделить("Пароль,Пользователь,Токен", ","); - ИменаИмпорт = СтрРазделить("password,username,token", ","); - ПараметрыАвторизации = Новый Соответствие; + Имена = СтрРазделить("Пароль,Пользователь,Токен,Пользователь,Пароль,РегионAWS,СервисAWS,Пользователь,Пароль,ДополнениеHawk,ИдентификаторПриложенияHawk,ДелегированиеHawk", ","); + ИменаИмпорт = СтрРазделить("password,username,token,accesskey,secretkey,region,service,authid,authkey,extradata,app,delegation", ","); + ПараметрыАутентификации = Новый Соответствие; Для я = 0 По Имена.ВГраница() Цикл - ПараметрыАвторизации.Вставить(ИменаИмпорт[я], Имена[я]); + ПараметрыАутентификации.Вставить(ИменаИмпорт[я], Имена[я]); КонецЦикла; - ПараметрыАвторизацииИмпорт = ОбъектАвторизации[ОбъектАвторизации["type"]]; - Для Каждого ПараметрАвторизацииИмпорт Из ПараметрыАвторизацииИмпорт Цикл - ИмяПараметраАвторизации = ПараметрыАвторизации.Получить(НРег(ПараметрАвторизацииИмпорт["key"])); - Если ИмяПараметраАвторизации <> Неопределено Тогда - фРезультат[ИмяПараметраАвторизации] = ЗначениеПеременнойИмпортаPostman(ПараметрАвторизацииИмпорт["value"], ЗначенияШаблонов); + ПараметрыАутентификацииИмпорт = ОбъектАутентификации[ОбъектАутентификации["type"]]; + Для Каждого ПараметрАутентификацииИмпорт Из ПараметрыАутентификацииИмпорт Цикл + ИмяПараметраАутентификации = ПараметрыАутентификации.Получить(НРег(ПараметрАутентификацииИмпорт["key"])); + Если ИмяПараметраАутентификации <> Неопределено Тогда + фРезультат[ИмяПараметраАутентификации] = ЗначениеПеременнойИмпортаPostman(ПараметрАутентификацииИмпорт["value"], ЗначенияШаблонов); КонецЕсли; КонецЦикла; @@ -2433,17 +2977,35 @@ Возврат; КонецЕсли; - АвторизацияИмпорт = АвторизацияИмпортаPostman(Запрос, ЗначенияШаблонов); + АутентификацияИмпорт = АутентификацияИмпортаPostman(Запрос, ЗначенияШаблонов); ТелоЗапросаИмпорт = ТелоЗапросаИмпортаPostman(Запрос, ЗначенияШаблонов); Схема = СхемаИмпорт; ИдентификаторРесурса = ИдентификаторРесурсаИмпортаPostman(Запрос, ЗначенияШаблонов); - ТипАвторизации = АвторизацияИмпорт.Тип; - Если ТипАвторизации <> Элементы.ТипАвторизации.СписокВыбора[0] Тогда - ПользовательАвторизации = АвторизацияИмпорт.Пользователь; - ПарольАвторизации = АвторизацияИмпорт.Пароль; - ТокенАвторизации = АвторизацияИмпорт.Токен; + ТипАутентификации = АутентификацияИмпорт.Тип.Значение; + Если ТипАутентификации <> Элементы.ТипАутентификации.СписокВыбора[0].Значение Тогда + СписокТиповАутентификации = Элементы.ТипАутентификации.СписокВыбора; + Если ТипАутентификации = СписокТиповАутентификации[1].Значение // Basic + ИЛИ ТипАутентификации = СписокТиповАутентификации[2].Значение // NTLM + ИЛИ ТипАутентификации = СписокТиповАутентификации[3].Значение // Digest + Тогда + ПользовательАутентификации = АутентификацияИмпорт.Пользователь; + ПарольАутентификации = АутентификацияИмпорт.Пароль; + ИначеЕсли ТипАутентификации = СписокТиповАутентификации[4].Значение Тогда // Bearer + ТокенАутентификации = АутентификацияИмпорт.Токен; + ИначеЕсли ТипАутентификации = СписокТиповАутентификации[5].Значение Тогда // AWS4-HMAC-SHA256 + AWSКлючДоступа = АутентификацияИмпорт.Пользователь; + AWSСекретныйКлюч = АутентификацияИмпорт.Пароль; + AWSРегион = АутентификацияИмпорт.РегионAWS; + AWSСервис = АутентификацияИмпорт.СервисAWS; + ИначеЕсли ТипАутентификации = СписокТиповАутентификации[6].Значение Тогда // Hawk + HawkИдентификатор = АутентификацияИмпорт.Пользователь; + HawkКлюч = АутентификацияИмпорт.Пароль; + HawkДополнение = АутентификацияИмпорт.ДополнениеHawk; + HawkИдентификаторПриложения = АутентификацияИмпорт.ИдентификаторПриложенияHawk; + HawkДелегирование = АутентификацияИмпорт.ДелегированиеHawk; + КонецЕсли; КонецЕсли; ЗаголовкиЗапроса.Очистить(); @@ -2469,7 +3031,7 @@ КонецЕсли; ИдентификаторРесурсаПриИзменении(Неопределено); - ТипАвторизацииПриИзменении(Неопределено); + ТипАутентификацииПриИзменении(Неопределено); ТипТелаЗапросаПриИзменении(Неопределено); РазделыКонсоли = Элементы.РазделыКонсоли.СписокВыбора[0]; @@ -2499,7 +3061,9 @@ Возврат фРезультат; КонецФункции +#КонецОбласти +#Область ИмпортКомандыCurl &НаКлиенте Функция ОпцииКомандыCurl() фРезультат = Новый Соответствие; @@ -2531,6 +3095,7 @@ фРезультат.Вставить("--ntlm", Ложь); фРезультат.Вставить("--ntlm-wb", Ложь); фРезультат.Вставить("--oauth2-bearer", Истина); + фРезультат.Вставить("--aws-sigv4", Истина); фРезультат.Вставить("--compressed", Ложь); фРезультат.Вставить("--compressed-ssh", Ложь); фРезультат.Вставить("--tr-encoding", Ложь); @@ -2571,11 +3136,6 @@ Возврат Текст; КонецФункции -&НаСервереБезКонтекста -Функция КодированныйТекстВURL(Знач Текст) - Возврат КодироватьСтроку(Текст, СпособКодированияСтроки.КодировкаURL); -КонецФункции - &НаКлиенте Процедура РазделитьСложнуюОпциюCurl(Токен, ЧастиКоманды, ДопустимыеОпции, Отказ, ОписаниеОшибки) Для я = 3 По СтрДлина(Токен) Цикл @@ -2706,14 +3266,14 @@ &НаКлиенте Функция НовыйОбъектДанныхCurl() Возврат Новый Структура( - "Схема, ТолькоЗаголовки, Заголовки, ПоляФормы, ПоляHTMLФормы, ПоляКакПараметры, Авторизация, ИспользоватьРедиректы, КоличествоРедиректов, ПоддержкаСжатогоОтвета, ИмяФайлаТелаОтвета, НормализоватьИдентификаторРесурса, Прокси, BasicАвторизацияПрокси", + "Схема, ТолькоЗаголовки, Заголовки, ПоляФормы, ПоляHTMLФормы, ПоляКакПараметры, Аутентификация, ИспользоватьРедиректы, КоличествоРедиректов, ПоддержкаСжатогоОтвета, ИмяФайлаТелаОтвета, НормализоватьИдентификаторРесурса, Прокси, BasicАутентификацияПрокси", Неопределено, Ложь, Новый Массив, Новый Массив, Новый Массив, Ложь, - Новый Структура("Тип, Пользователь, Пароль, Токен", Элементы.ТипАвторизации.СписокВыбора[0], "", "", ""), + Новый Структура("Тип, Пользователь, Пароль, Токен, РегионAWS, СервисAWS", Элементы.ТипАутентификации.СписокВыбора[0], "", "", "", "", ""), Ложь, Неопределено, Ложь, @@ -2906,19 +3466,41 @@ КонецПроцедуры &НаКлиенте -Процедура ОбработатьДанныеАвторизацииCurl(ДанныеИмпорта, Знач Опция) +Процедура ОбработатьДанныеАутентификацииCurl(ДанныеИмпорта, Знач Опция) ЗначениеОпции = Опция.Значение; Если НЕ ЗначениеЗаполнено(ЗначениеОпции) Тогда Возврат; КонецЕсли; - ЧастиПоля = СтрРазделить(ЗначениеОпции, ":"); - Пользователь = ЧастиПоля[0]; + ЧастиЗначения = СтрРазделить(ЗначениеОпции, ":"); + Пользователь = ЧастиЗначения[0]; - ЧастиПоля.Удалить(0); + ЧастиЗначения.Удалить(0); - ДанныеИмпорта.Авторизация.Пользователь = Пользователь; - ДанныеИмпорта.Авторизация.Пароль = СтрСоединить(ЧастиПоля, ":"); + ДанныеИмпорта.Аутентификация.Пользователь = Пользователь; + ДанныеИмпорта.Аутентификация.Пароль = СтрСоединить(ЧастиЗначения, ":"); +КонецПроцедуры + +&НаКлиенте +Процедура ОбработатьДанныеАутентификацииAWSCurl(ДанныеИмпорта, Знач Опция) + ЗначениеОпции = Опция.Значение; + Если НЕ ЗначениеЗаполнено(ЗначениеОпции) Тогда + Возврат; + КонецЕсли; + + ЧастиЗначения = СтрРазделить(ЗначениеОпции, ":"); + Если ЧастиЗначения.Количество() < 2 ИЛИ ЧастиЗначения[0] <> "aws" ИЛИ ЧастиЗначения[1] <> "amz" Тогда + Возврат; + КонецЕсли; + + ДанныеИмпорта.Аутентификация.Тип = Элементы.ТипАутентификации.СписокВыбора[5]; + + Если ЧастиЗначения.Количество() > 2 Тогда + ДанныеИмпорта.Аутентификация.РегионAWS = ЧастиЗначения[2]; + КонецЕсли; + Если ЧастиЗначения.Количество() > 3 Тогда + ДанныеИмпорта.Аутентификация.СервисAWS = ЧастиЗначения[3]; + КонецЕсли; КонецПроцедуры &НаКлиенте @@ -2944,15 +3526,18 @@ ПозицияРазделителя = ПозицияОкончанияАутентификации; КонецЕсли; - ЗакодированныеДанные = Новый Структура("Пользователь, Пароль"); - ЗакодированныеДанные.Пользователь = СокрЛП(Лев(ЗначениеОпции, ПозицияРазделителя - 1)); - ЗакодированныеДанные.Пароль = Прав( + ЗакодированныйПользователь = СокрЛП(Лев(ЗначениеОпции, ПозицияРазделителя - 1)); + ЗакодированныйПароль = Прав( Лев(ЗначениеОпции, ПозицияОкончанияАутентификации - 1), ПозицияОкончанияАутентификации - ПозицияРазделителя - 1 ); - РаскодированныеДанные = РаскодированныеСтроки(ЗакодированныеДанные); - Прокси.Пользователь = РаскодированныеДанные.Пользователь; - Прокси.Пароль = РаскодированныеДанные.Пароль; + МножествоСтрок = Новый Соответствие; + МножествоСтрок.Вставить(ЗакодированныйПользователь); + МножествоСтрок.Вставить(ЗакодированныйПароль); + + МножествоСтрок = РаскодированныеСтрокиURLвURL(МножествоСтрок); + Прокси.Пользователь = МножествоСтрок.Получить(ЗакодированныйПользователь); + Прокси.Пароль = МножествоСтрок.Получить(ЗакодированныйПароль); КонецЕсли; ПозицияОкончанияАутентификации = ПозицияОкончанияАутентификации + 1; @@ -2996,16 +3581,18 @@ ИначеЕсли ИмяОпции = "-H" ИЛИ ИмяОпции = "--header" Тогда ОбработатьЗаголовокCurl(ДанныеИмпорта, Опция); ИначеЕсли ИмяОпции = "-u" ИЛИ ИмяОпции = "--user" Тогда - ОбработатьДанныеАвторизацииCurl(ДанныеИмпорта, Опция); + ОбработатьДанныеАутентификацииCurl(ДанныеИмпорта, Опция); ИначеЕсли ИмяОпции = "--basic" Тогда - ДанныеИмпорта.Авторизация.Тип = Элементы.ТипАвторизации.СписокВыбора[1]; + ДанныеИмпорта.Аутентификация.Тип = Элементы.ТипАутентификации.СписокВыбора[1]; ИначеЕсли ИмяОпции = "--digest" Тогда - ДанныеИмпорта.Авторизация.Тип = Элементы.ТипАвторизации.СписокВыбора[3]; + ДанныеИмпорта.Аутентификация.Тип = Элементы.ТипАутентификации.СписокВыбора[3]; ИначеЕсли ИмяОпции = "--ntlm" ИЛИ ИмяОпции = "--ntlm-wb" Тогда - ДанныеИмпорта.Авторизация.Тип = Элементы.ТипАвторизации.СписокВыбора[2]; + ДанныеИмпорта.Аутентификация.Тип = Элементы.ТипАутентификации.СписокВыбора[2]; ИначеЕсли ИмяОпции = "--oauth2-bearer" Тогда - ДанныеИмпорта.Авторизация.Тип = Элементы.ТипАвторизации.СписокВыбора[4]; - ДанныеИмпорта.Авторизация.Токен = Опция.Значение; + ДанныеИмпорта.Аутентификация.Тип = Элементы.ТипАутентификации.СписокВыбора[4]; + ДанныеИмпорта.Аутентификация.Токен = Опция.Значение; + ИначеЕсли ИмяОпции = "--aws-sigv4" Тогда + ОбработатьДанныеАутентификацииAWSCurl(ДанныеИмпорта, Опция); ИначеЕсли ИмяОпции = "-L" ИЛИ ИмяОпции = "--location" ИЛИ ИмяОпции = "--location-trusted" Тогда ДанныеИмпорта.ИспользоватьРедиректы = Истина; ИначеЕсли ИмяОпции = "--max-redirs" Тогда @@ -3024,7 +3611,7 @@ ИначеЕсли ИмяОпции = "-x" ИЛИ ИмяОпции = "--proxy" Тогда ОбработатьДанныеПрокси(ДанныеИмпорта, Опция, Отказ, ОписаниеОшибки); ИначеЕсли ИмяОпции = "--proxy-basic" Тогда - ДанныеИмпорта.BasicАвторизацияПрокси = Истина; + ДанныеИмпорта.BasicАутентификацияПрокси = Истина; ИначеЕсли ИмяОпции = "-:" ИЛИ ИмяОпции = "--next" Тогда Отказ = Истина; ОписаниеОшибки = "команда с множественными запросами не допускается"; @@ -3187,11 +3774,23 @@ ИдентификаторРесурса = ЧастиКоманды.ИдентификаторРесурса; Схема = ДанныеИмпорта.Схема; - ТипАвторизации = ДанныеИмпорта.Авторизация.Тип; - Если ТипАвторизации <> Элементы.ТипАвторизации.СписокВыбора[0].Значение Тогда - ПользовательАвторизации = ДанныеИмпорта.Авторизация.Пользователь; - ПарольАвторизации = ДанныеИмпорта.Авторизация.Пароль; - ТокенАвторизации = ДанныеИмпорта.Авторизация.Токен; + ТипАутентификации = ДанныеИмпорта.Аутентификация.Тип; + Если ТипАутентификации <> Элементы.ТипАутентификации.СписокВыбора[0].Значение Тогда + СписокТиповАутентификации = Элементы.ТипАутентификации.СписокВыбора; + Если ТипАутентификации = СписокТиповАутентификации[1].Значение // Basic + ИЛИ ТипАутентификации = СписокТиповАутентификации[2].Значение // NTLM + ИЛИ ТипАутентификации = СписокТиповАутентификации[3].Значение // Digest + Тогда + ПользовательАутентификации = ДанныеИмпорта.Аутентификация.Пользователь; + ПарольАутентификации = ДанныеИмпорта.Аутентификация.Пароль; + ИначеЕсли ТипАутентификации = СписокТиповАутентификации[4].Значение Тогда // Bearer + ТокенАутентификации = ДанныеИмпорта.Аутентификация.Токен; + ИначеЕсли ТипАутентификации = СписокТиповАутентификации[5].Значение Тогда // AWS4-HMAC-SHA256 + AWSКлючДоступа = ДанныеИмпорта.Аутентификация.Пользователь; + AWSСекретныйКлюч = ДанныеИмпорта.Аутентификация.Пароль; + AWSРегион = ДанныеИмпорта.Аутентификация.РегионAWS; + AWSСервис = ДанныеИмпорта.Аутентификация.СервисAWS; + КонецЕсли; КонецЕсли; ЗаголовкиЗапроса.Очистить(); @@ -3238,12 +3837,12 @@ ПортПрокси = ДанныеИмпорта.Прокси.Порт; ПользовательПрокси = ДанныеИмпорта.Прокси.Пользователь; ПарольПрокси = ДанныеИмпорта.Прокси.Пароль; - ИспользоватьАутентификациюОСПрокси = НЕ ДанныеИмпорта.BasicАвторизацияПрокси; + ИспользоватьАутентификациюОСПрокси = НЕ ДанныеИмпорта.BasicАутентификацияПрокси; НеИспользоватьПроксиДляЛокальныхАдресов = Ложь; КонецЕсли; ИдентификаторРесурсаПриИзменении(Неопределено); - ТипАвторизацииПриИзменении(Неопределено); + ТипАутентификацииПриИзменении(Неопределено); ТипТелаЗапросаПриИзменении(Неопределено); ИспользоватьПроксиПриИзменении(Неопределено); @@ -3251,6 +3850,7 @@ РазделыКонсолиПриИзменении(Неопределено); КонецПроцедуры +#КонецОбласти &НаКлиенте Функция ОбработанныйПутьКФайлу(Знач ПутьКФайлу) @@ -3288,8 +3888,8 @@ КонецФункции &НаСервереБезКонтекста -Функция РаскодированныйИдентификаторРесурса(Знач Текст) - Возврат КлиентHTTP.РаскодированныйИдентификаторРесурса(Текст); +Функция РаскодированныеСтрокиURLвURL(Знач МножествоСтрок) + Возврат КлиентHTTP.РаскодированныеСтрокиURLвURL(МножествоСтрок); КонецФункции &НаСервереБезКонтекста @@ -3297,11 +3897,40 @@ Возврат КлиентHTTP.РаскодированныеСтроки(КоллекцияСтрок); КонецФункции +&НаСервереБезКонтекста +Функция КодированныйТекстВURL(Знач Текст) + Возврат КодироватьСтроку(Текст, СпособКодированияСтроки.КодировкаURL); +КонецФункции + +&НаСервереБезКонтекста +Функция КодированныйURIВURL(Знач URI) + Кодировано = КодироватьСтроку(URI, СпособКодированияСтроки.URLВКодировкеURL); + Позиция = СтрНайти(Кодировано, "?"); + Если Позиция = 0 Тогда + Позиция = СтрДлина(Кодировано) + 1; + КонецЕсли; + + Возврат РаскодироватьСтроку( + Лев(Кодировано, Позиция-1), + СпособКодированияСтроки.URLВКодировкеURL + ) + Сред( + Кодировано, + Позиция, + СтрДлина(Кодировано) - Позиция + 1 + ); +КонецФункции + +&НаСервереБезКонтекста +Функция РазделительПутиСервера() + Возврат ПолучитьРазделительПутиСервера(); +КонецФункции + &НаКлиенте Процедура ИзменитьКонтекстВыполненияЗапроса() Элементы.ИмяФайлаТелаОтвета.КнопкаВыбора = ВыполнятьНаСервере; Элементы.ТелоЗапросаФайл.КнопкаВыбора = ВыполнятьНаСервере; Элементы.ДанныеФормыЗначение.КнопкаВыбора = ВыполнятьНаСервере; + Элементы.ДанныеФормыЗначение.КнопкаОткрытия = НЕ ВыполнятьНаСервере; ВыполнятьНаСервере = НЕ ВыполнятьНаСервере; ЗаголовокКонтекстаВыполнения = ?( ВыполнятьНаСервере, @@ -3322,6 +3951,11 @@ Возврат ЗначениеИзСтрокиВнутр(СтрокаВнутр); КонецФункции +&НаКлиенте +Функция ПараметрыОткрытияФормыКомандыCurl(Знач Текст) + Возврат Новый Структура("Текст, ЗаголовокФормы, ЦветРедактируемогоТекста", Текст, "Команда curl", WebЦвета.Серебряный); +КонецФункции + #Область ОБРАТНЫЕ_ВЫЗОВЫ &НаКлиенте Процедура КонструкторURIЗавершение(Результат, ДополнительныеПараметры) Экспорт