1
0
mirror of https://github.com/vbondarevsky/Connector.git synced 2024-11-24 08:42:15 +02:00

Прозрачно сжимать тело исходящего запроса #38

This commit is contained in:
Vladimir Bondarevskiy 2020-04-25 21:17:35 +03:00
parent 7de0a0b4b3
commit 99efcc00a3
No known key found for this signature in database
GPG Key ID: E3B220A09083E7A2
3 changed files with 100 additions and 21 deletions

View File

@ -20,6 +20,7 @@
- Отправка данных формы (полей формы), `application/x-www-form-urlencoded`
- Отправка данных формы (полей формы и файлов), `multipart/form-data`
- Прозрачная поддержка ответов, закодированных `GZip`
- Сжатие тела запроса `GZip`
- `Basic`, `Digest` и `AWS4-HMAC-SHA256` аутентификация
- Автоматическое разрешение редиректов
- Установка и чтение Cookies
@ -221,8 +222,27 @@ XML =
Результат = КоннекторHTTP.КакДвоичныеДанные(КоннекторHTTP.Get("http://httpbin.org/image/png"));
```
## GZip-декодирование
## GZip-кодирование тела запроса
**Коннектор** может автоматически сжимать тело запроса `GZip`.
Для этого нужно добавить заголовок `Content-Encoding` = `gzip`.
**Примечание**: сервер должен быть настроен соответствующим образом, чтобы распаковывать входящие запросы.
```bsl
Json = Новый Структура;
Json.Вставить("field", "value");
Json.Вставить("field2", "value2");
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Encoding", "gzip");
Результат = КоннекторHTTP.PostJson("http://httpbin.org/anything", Json, Новый Структура("Заголовки", Заголовки));
```
## GZip-декодирование тела ответа
По умолчанию **Коннектор** просит сервер кодировать ответы в формате `GZip`.
**Примечание**: любое кодирование тела ответа можно отключить, задав заголовок
`Accept-Encoding` = `identity`.
Декодирование выполняется прозрачным образом в методах `GetJson`, `PostJson`, `PutJson`, `DeleteJson`, `КакJson`, `КакТекст`, `КакДвоичныеДанные`.
```bsl
Результат = КоннекторHTTP.GetJson("http://httpbin.org/gzip");

View File

@ -17,7 +17,7 @@
//
// URL: https://github.com/vbondarevsky/Connector
// e-mail: vbondarevsky@gmail.com
// Версия: 1.4.0
// Версия: 1.4.1
//
// Требования: платформа 1С версии 8.3.10 и выше
@ -36,7 +36,7 @@
// ДополнительныеПараметры - Структура - см. описание параметра в ВызватьМетодВСеансе.
//
// Возвращаемое значение:
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
//
Функция Get(URL, ПараметрыЗапроса = Неопределено, ДополнительныеПараметры = Неопределено) Экспорт
@ -53,7 +53,7 @@
// ДополнительныеПараметры - Структура - см. описание параметра в ВызватьМетодВСеансе.
//
// Возвращаемое значение:
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
//
Функция Options(URL, ДополнительныеПараметры = Неопределено) Экспорт
@ -70,7 +70,7 @@
// ДополнительныеПараметры - Структура - см. описание параметра в ВызватьМетодВСеансе.
//
// Возвращаемое значение:
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
//
Функция Head(URL, ДополнительныеПараметры = Неопределено) Экспорт
@ -88,7 +88,7 @@
// ДополнительныеПараметры - Структура - см. описание параметра в ВызватьМетодВСеансе.
//
// Возвращаемое значение:
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
//
Функция Post(URL, Данные = Неопределено, ДополнительныеПараметры = Неопределено) Экспорт
@ -124,7 +124,7 @@
// ДополнительныеПараметры - Структура - см. описание параметра в ВызватьМетодВСеансе.
//
// Возвращаемое значение:
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
//
Функция Patch(URL, Данные = Неопределено, ДополнительныеПараметры = Неопределено) Экспорт
@ -142,7 +142,7 @@
// ДополнительныеПараметры - Структура - см. описание параметра в ВызватьМетодВСеансе.
//
// Возвращаемое значение:
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
//
Функция Delete(URL, Данные = Неопределено, ДополнительныеПараметры = Неопределено) Экспорт
@ -247,7 +247,7 @@
// ДополнительныеПараметры - Структура - см. описание параметра в ВызватьМетодВСеансе.
//
// Возвращаемое значение:
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
// Структура - ответ на выполненный запрос. См. описание возвращаемого значения в ВызватьМетодВСеансе.
//
Функция ВызватьМетод(Метод, URL, ДополнительныеПараметры = Неопределено) Экспорт
@ -296,7 +296,7 @@
// Строка - ответ сервера в виде текста.
//
Функция КакТекст(Ответ, Кодировка = Неопределено) Экспорт
Если Не ЗначениеЗаполнено(Кодировка) Тогда
Кодировка = Ответ.Кодировка;
КонецЕсли;
@ -324,7 +324,7 @@
//
Функция КакДвоичныеДанные(Ответ) Экспорт
Возврат РаспаковатьОтвет(Ответ);
Возврат РаспаковатьОтвет(Ответ);
КонецФункции
@ -755,13 +755,13 @@
ЧтениеДанных.КопироватьВ(ЗаписьДанных, РазмерСжатыхДанных);
ЗаписьДанных.Закрыть();
ЗаписьДанных = Новый ЗаписьДанных(ПотокZip);
ЗаписьДанных = Новый ЗаписьДанных(ПотокZip);
CRC32 = ЧтениеДанных.ПрочитатьЦелое32();
РазмерНесжатыхДанных = ЧтениеДанных.ПрочитатьЦелое32();
ЧтениеДанных.Закрыть();
ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ZipDD(CRC32, РазмерСжатыхДанных, РазмерНесжатыхДанных));
ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ZipDD(CRC32, РазмерСжатыхДанных, РазмерНесжатыхДанных));
ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ZipCDH(CRC32, РазмерСжатыхДанных, РазмерНесжатыхДанных));
ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ZipEOCD(РазмерСжатыхДанных));
ЗаписьДанных.Закрыть();
@ -1295,6 +1295,9 @@
КонецЕсли;
HTTPЗапрос.Заголовки = ПодготовленныйЗапрос.Заголовки;
УпаковатьЗапрос(HTTPЗапрос);
ПодготовленныйЗапрос.Вставить("HTTPЗапрос", HTTPЗапрос);
КонецПроцедуры
@ -1305,7 +1308,7 @@
Если Не ЗначениеЗаполнено(ПодготовленныйЗапрос.Аутентификация) Тогда
СтруктураURL = РазобратьURL(ПодготовленныйЗапрос.URL);
Если ЗначениеЗаполнено(СтруктураURL.Аутентификация) Тогда
ПодготовленныйЗапрос.Аутентификация = СтруктураURL.Аутентификация;
ПодготовленныйЗапрос.Аутентификация = СтруктураURL.Аутентификация;
КонецЕсли;
КонецЕсли;
@ -1499,7 +1502,7 @@
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат Cookies;
@ -2501,6 +2504,17 @@
КонецФункции
Процедура УпаковатьЗапрос(Запрос)
Заголовок = ПолучитьЗначениеЗаголовка("content-encoding", Запрос.Заголовки);
Если Заголовок <> Ложь Тогда
Если НРег(Заголовок) = "gzip" Тогда
Запрос.УстановитьТелоИзДвоичныхДанных(ЗаписатьGZip(Запрос.ПолучитьТелоКакДвоичныеДанные()));
КонецЕсли;
КонецЕсли;
КонецПроцедуры
#Область ПараметрыПоУмолчанию
Функция ЗаголовкиПоУмолчанию()

View File

@ -26,19 +26,22 @@
Тест_ПараметрыЗаписиJson();
Тест_URLБезСхемы();
Тест_ПередачаПараметровВСтрокуЗапроса();
Тест_ПередачаПараметровВСтрокуЗапросаКомбинированный();
Тест_ПередачаПараметровВСтрокуЗапросаКомбинированный();
Тест_РезультатКакJsonGet();
Тест_РезультатКакJsonPost();
Тест_РезультатКакДвоичныеДанные();
Тест_РезультатКакТекст();
Тест_ПередачаПроизвольныхЗаголовков();
Тест_ПередачаПроизвольныхЗаголовков();
Тест_ОтправкаДанныхФормы();
Тест_ОтправкаJson();
Тест_Таймаут();
Тест_BasicAuth();
Тест_DigestAuth();
#Если Не МобильноеПриложениеСервер Тогда
Тест_ОтправитьGZip();
Тест_ПолучитьGZip();
Тест_УпаковатьGZip();
Тест_РаспаковатьGZip();
#КонецЕсли
Тест_GetJson();
Тест_PostJson();
@ -52,7 +55,7 @@
Тест_GetОтключенныйРедирект();
Тест_РедиректСУказаниемURL();
Тест_Ошибка404();
Тест_РаботаССессиями();
Тест_РаботаССессиями();
Тест_Options();
Тест_Head();
Тест_Delete();
@ -275,7 +278,7 @@
ПараметрыЗапроса.Вставить("salary", Формат(100000, "ЧГ="));
ПараметрыЗапроса.Вставить("time", "01:47");
Ответ = КоннекторHTTP.Get("https://httpbin.org/anything/params", ПараметрыЗапроса);
Ответ = КоннекторHTTP.Get("https://httpbin.org/anything/params", ПараметрыЗапроса);
Результат = КоннекторHTTP.КакJson(Ответ);
УтверждениеВерно(Ответ.URL, "https://httpbin.org/anything/params?name=%D0%98%D0%B2%D0%B0%D0%BD%D0%BE%D0%B2&name=%D0%9F%D0%B5%D1%82%D1%80%D0%BE%D0%B2&salary=100000&time=01%3A47");
@ -294,7 +297,7 @@
ПараметрыЗапроса.Вставить("name", СтрРазделить("Иванов,Петров", ","));
ПараметрыЗапроса.Вставить("salary", Формат(100000, "ЧГ="));
Результат = КоннекторHTTP.GetJson("https://httpbin.org/anything/params?post=Программист", ПараметрыЗапроса);
Результат = КоннекторHTTP.GetJson("https://httpbin.org/anything/params?post=Программист", ПараметрыЗапроса);
УтверждениеВерно(Результат["args"]["salary"], "100000");
УтверждениеВерно(Результат["args"]["post"], "Программист");
@ -375,7 +378,7 @@
УтверждениеВерно(Результат["form"]["comments"], "Постучать в дверь");
УтверждениеВерно(Результат["form"]["custemail"], "vasya@mail.ru");
УтверждениеВерно(Результат["form"]["delivery"], "20:20");
УтверждениеВерно(Результат["form"]["custtel"], "112");
УтверждениеВерно(Результат["form"]["custtel"], "112");
ТестПройден("Тест_ОтправкаДанныхФормы");
@ -420,7 +423,27 @@
ТестПройден("Тест_ПолучитьGZip");
КонецПроцедуры
Процедура Тест_ОтправитьGZip()
Json = Новый Структура;
Json.Вставить("field", "value");
Json.Вставить("field2", "value2");
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Encoding", "gzip");
Результат = КоннекторHTTP.PostJson("http://httpbin.org/anything", Json, Новый Структура("Заголовки", Заголовки));
ТелоЗапроса = ПолучитьДвоичныеДанныеИзBase64Строки(СтрРазделить(Результат["data"], ",")[1]);
ИсходноеЗначение = КоннекторHTTP.JsonВОбъект(КоннекторHTTP.ПрочитатьGZip(ТелоЗапроса));
УтверждениеВерно(Результат["headers"]["Content-Encoding"], "gzip");
УтверждениеВерно(ИсходноеЗначение["field"], Json["field"]);
УтверждениеВерно(ИсходноеЗначение["field2"], Json["field2"]);
ТестПройден("Тест_ОтправитьGZip");
КонецПроцедуры
Процедура Тест_BasicAuth()
Результат = КоннекторHTTP.GetJson("https://user:pass@httpbin.org/basic-auth/user/pass");
@ -866,6 +889,28 @@
КонецПроцедуры
Процедура Тест_УпаковатьGZip()
ИсходныеДанные = ПолучитьДвоичныеДанныеИзСтроки("Привет, Мир!", КодировкаТекста.UTF8, Ложь);
СжатыеДанные = ПолучитьДвоичныеДанныеИзBase64Строки("H4sIAAAAAAAA/wEVAOr/0J/RgNC40LLQtdGCLCDQnNC40YAhilS6PhUAAAA=");
УтверждениеВерно(КоннекторHTTP.ЗаписатьGZip(ИсходныеДанные), СжатыеДанные);
ТестПройден("Тест_УпаковатьGZip");
КонецПроцедуры
Процедура Тест_РаспаковатьGZip()
СжатыеДанные = ПолучитьДвоичныеДанныеИзBase64Строки("H4sIAAAAAAAA/wEVAOr/0J/RgNC40LLQtdGCLCDQnNC40YAhilS6PhUAAAA=");
Данные = КоннекторHTTP.ПрочитатьGZip(СжатыеДанные);
УтверждениеВерно(ПолучитьСтрокуИзДвоичныхДанных(Данные, КодировкаТекста.UTF8), "Привет, Мир!");
ТестПройден("Тест_РаспаковатьGZip");
КонецПроцедуры
#КонецОбласти
Функция ИзвлечьExecution(Ответ)