Giter Club home page Giter Club logo

connector's Introduction

Публикация на Инфостарт

The library is translated into English (README)

Quality Gate Status Stars Release

Коннектор: удобный HTTP-клиент для 1С:Предприятие 8

В мире python очень популярна библиотека для работы с HTTP запросами - Requests (автор: Kenneth Reitz). Библиотека берет на себя всю рутину работы с HTTP запросами. Буквально в одну строку можно получать данные, отправлять, не заботясь о необходимости конструирования URL, кодирования данных и т.п. В общем библиотека очень мощная и проста в использовании.

Коннектор - это "Requests" для мира 1С.

Бибилиотека полностью переведена на английский язык (см. здесь).

Возможности

Основные возможности библиотеки:

  • Передача параметров в строку запроса (в URL)
  • Удобная работа с запросами и ответами в формате JSON
  • Отправка данных формы (полей формы), application/x-www-form-urlencoded
  • Отправка данных формы (полей формы и файлов), multipart/form-data
  • Прозрачная поддержка ответов, закодированных GZip
  • Сжатие тела запроса GZip
  • Basic, Digest и AWS4-HMAC-SHA256 аутентификация
  • Автоматическое разрешение редиректов
  • Установка и чтение Cookies
  • Работа в рамках сессии с сохранением состояния (cookies, аутентификация и пр.)
  • Переиспользование HTTPСоединение в рамках сессии
  • Настраиваемые повторные попытки соединения/отправки запроса с экспоненциальной задержкой
  • Работает в т.ч. и на мобильной платформе
  • И многое другое

Требования

  • Платформа 8.3.10 и выше.
  • Мобильная платформа (проверено только на 8.3.15)

Использование

Скопируйте общий модуль к себе в конфигурацию.

Пример мощи библиотеки

Чем же хороша библиотека? Давай уже покажи пример.

Получим данные JSON с помощью GET-запроса:

Вот так это делается стандартными средствами 1С

ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Неопределено, Новый СертификатыУдостоверяющихЦентровОС);
Соединение = Новый HTTPСоединение("api.github.com", 443,,,, 30, ЗащищенноеСоединение);	
Запрос = Новый HTTPЗапрос("/events");
Ответ = Соединение.Получить(Запрос);
Поток = Ответ.ПолучитьТелоКакПоток();
Кодировка = "utf-8"; // ну допустим мы знаем что там такая кодировка

Ридер = Новый ЧтениеJSON;
Ридер.ОткрытьПоток(Поток, Кодировка); // Кодировка в заголовке ответа
Результат = ПрочитатьJSON(Ридер);
Ридер.Закрыть();

А вот так с помощью Коннектора

Результат = КоннекторHTTP.GetJson("https://api.github.com/events");

Все! В Результат будет десериализованный из JSON ответ сервера. При этом:

  • Библиотека сама разбила URL на составляющие
  • Установила защищенное соединение
  • Определила кодировку ответа из заголовков
  • Десериализовала JSON

И это достаточно простой пример. Всю мощь библиотеки рассмотрим далее.

Передача параметров в строку запроса (в URL)

Работать с параметрами запроса очень просто:

ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("name", СтрРазделить("Иванов,Петров", ","));
ПараметрыЗапроса.Вставить("salary", Формат(100000, "ЧГ="));

Ответ = КоннекторHTTP.GetJson("https://httpbin.org/anything/params", ПараметрыЗапроса);	

Поддерживается передача нескольких значений для одного параметра, достаточно указать в качестве значения Массив (см. name).

Параметры можно задать:

  • Явно в URL
  • Передать в параметре ПараметрыЗапроса
  • Скомбинировать оба варианта

Результат будет один и тот же:

  • Коннектор подставит параметры в URL в виде пар ключ=значение
  • Закодирует строку URL, используя URLEncoding
  • Выполнит запрос

Итоговое значение URL можно получить из свойства ответа URL

Ответ = КоннекторHTTP.Get("https://httpbin.org/anything/params", ПараметрыЗапроса);

Ответ.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

Произвольные HTTP заголовки

В основных сценариях использования библиотеки заголовки формируются автоматически. При необходимости произвольные заголовки можно задать через параметр ДополнительныеПараметры, свойство Заголовки.

Заголовки = Новый Соответствие;
Заголовки.Вставить("X-My-Header", "Hello!!!");
Результат = КоннекторHTTP.GetJson("http://httpbin.org/headers", Неопределено, Новый Структура("Заголовки", Заголовки));

Работа с JSON

Для облегчения работы с JSON есть методы: GetJson, PostJson, PutJson, DeleteJson. Запросы отправляются в формате JSON, ответы - JSON прочитанный в Соответствие/Структура.

Результат = КоннекторHTTP.GetJson("http://httpbin.org/get");
Результат = КоннекторHTTP.PostJson("http://httpbin.org/post", Новый Структура("Название", "КоннекторHTTP"));
Результат = КоннекторHTTP.PutJson("http://httpbin.org/put", Новый Структура("Название", "КоннекторHTTP"));
Результат = КоннекторHTTP.DeleteJson("http://httpbin.org/delete", Новый Структура("Название", "КоннекторHTTP"));

Сериализация в JSON и десериализация из JSON настраиваются с помощью параметров в ДополнительныеПараметры.ПараметрыПреобразованияJSON.

Отправка данных формы

Отправить данные формы очень просто. Передаем данные (Структура или Соответствие) в метод POST и все.

Данные = Новый Структура;
Данные.Вставить("comments", "Постучать в дверь");
Данные.Вставить("custemail", "[email protected]");
Данные.Вставить("custname", "Вася");
Данные.Вставить("custtel", "112");
Данные.Вставить("delivery", "20:20");
Данные.Вставить("size", "medium");
Данные.Вставить("topping", СтрРазделить("bacon,mushroom", ","));

Ответ = КоннекторHTTP.Post("http://httpbin.org/post", Данные);

Данные будут закодированы, заголовку Content-Type автоматически будет установлено значение application/x-www-form-urlencoded.

Отправка файла

Для отправки файла нужно сформировать описание файла и передать его в параметр ДополнительныеПараметры.Файлы.

Файлы = Новый Структура;
Файлы.Вставить("Имя", "f1");
Файлы.Вставить("ИмяФайла", "file1.txt");
Файлы.Вставить("Данные", Base64Значение("0J/RgNC40LLQtdGCINCc0LjRgCE="));
Файлы.Вставить("Тип", "text/plain");

Результат = КоннекторHTTP.Post("https://httpbin.org/post", Неопределено, Новый Структура("Файлы", Файлы));

Файл будет закодирован в теле запроса, заголовку Content-Type автоматически установлено значение multipart/form-data.

Отправка файлов и данных формы

Для отправки данных формы и файлов в одном запросе нужно сформировать описание файлов и данных формы и передать их в параметрах ДополнительныеПараметры.Файлы, ДополнительныеПараметры.Данные.

Файлы = Новый Массив;
Файлы.Добавить(Новый Структура("Имя,Данные,ИмяФайла", "f1", Base64Значение("ZmlsZTE="), "file1.txt"));
Файлы.Добавить(Новый Структура("Имя,Данные,ИмяФайла", "f2", Base64Значение("ZmlsZTI="), "file2.txt"));

Данные = Новый Структура("field1,field2", "value1", "Значение2");

Результат = КоннекторHTTP.Post("https://httpbin.org/post", Неопределено, Новый Структура("Файлы,Данные", Файлы, Данные));

Файлы и данные формы будут закодированы в теле запроса, заголовку Content-Type автоматически установлено значение multipart/form-data.

Отправка произвольных данных

Чтобы отправить произвольные данные (Строка, ДвоичныеДанные) их нужно передать в параметре Данные.

XML = 
"<?xml version=""1.0"" encoding=""utf-8""?>
|<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
|  <soap:Body>
|    <GetCursOnDate xmlns=""http://web.cbr.ru/"">
|      <On_date>2019-07-05</On_date>
|    </GetCursOnDate>
|  </soap:Body>
|</soap:Envelope>";
    
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "text/xml; charset=utf-8");
Заголовки.Вставить("SOAPAction", "http://web.cbr.ru/GetCursOnDate");
Ответ = КоннекторHTTP.Post(
    "https://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx",
    XML, 
    Новый Структура("Заголовки", Заголовки));

Содержимое ответа

Методы, которые не заканчиваются на Json, возвращают ответ в виде Структура:

  • ВремяВыполнения - Число - время выполнения запроса в миллисекундах
  • Cookies - cookies полученные с сервера
  • Заголовки - HTTP заголовки ответа
  • ЭтоПостоянныйРедирект - признак постоянного редиректа
  • ЭтоРедирект - признак редиректа
  • Кодировка - кодировка текста ответа
  • Тело - тело ответа
  • КодСостояния - код состояния ответа
  • URL - итоговый URL, по которому был выполнен запрос

Получить данные из ответа в виде JSON, текста или двоичных данных можно с помощью соответствующих методов, описанных ниже.

Чтение ответа как JSON

Получить данные из ответа в виде десериализованного JSON можно с помощью метода КакJson.

Результат = КоннекторHTTP.КакJson(КоннекторHTTP.Get("http://httpbin.org/get"));

Чтение ответа как Текст

Получить данные из ответа в виде текста можно с помощью метода КакТекст.

Результат = КоннекторHTTP.КакТекст(КоннекторHTTP.Get("http://httpbin.org/encoding/utf8"));

При этом можно указать кодировку в соответствующем параметре. Если параметр не указан, то Коннектор возьмет значение кодировки из заголовков (если она там есть).

Чтение ответа как ДвоичныеДанные

Метод КакДвоичныеДанные преобразует ответ в ДвоичныеДанные.

Результат = КоннекторHTTP.КакДвоичныеДанные(КоннекторHTTP.Get("http://httpbin.org/image/png"));

Чтение ответа XML как XDTO

Метод КакXDTO преобразует ответ XML в ОбъектXDTO.

Результат = КоннекторHTTP.КакXDTO(Ответ);

GZip-кодирование тела запроса

Коннектор может автоматически сжимать тело запроса GZip. Для этого нужно добавить заголовок Content-Encoding = gzip.

Примечание: сервер должен быть настроен соответствующим образом, чтобы распаковывать входящие запросы.

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, КакТекст, КакДвоичныеДанные.

Результат = КоннекторHTTP.GetJson("http://httpbin.org/gzip");

Таймаут

Таймаут можно задать в параметре ДополнительныеПараметры.Таймаут.

Ответ = КоннекторHTTP.Get("https://httpbin.org/delay/10", Неопределено, Новый Структура("Таймаут", 1));

Значение по умолчанию - 30 сек.

Basic-аутентификация

Параметры Basic-аутентификации можно передать в параметре ДополнительныеПараметры.Аутентификация

Аутентификация = Новый Структура("Пользователь, Пароль", "user", "pass");
Результат = КоннекторHTTP.GetJson(
    "https://httpbin.org/basic-auth/user/pass",
    Неопределено,
    Новый Структура("Аутентификация", Аутентификация));

или в URL

Результат = КоннекторHTTP.GetJson("https://user:[email protected]/basic-auth/user/pass");

Digest-аутентификация

Параметры Digest-аутентификации можно передать в параметре ДополнительныеПараметры.Аутентификация. При этом Тип нужно установить в значение Digest.

Аутентификация = Новый Структура("Пользователь, Пароль, Тип", "user", "pass", "Digest");
Результат = КоннекторHTTP.GetJson(
    "https://httpbin.org/digest-auth/auth/user/pass",
    Неопределено,
    Новый Структура("Аутентификация", Аутентификация));

AWS4-HMAC-SHA256-аутентификация

Параметры AWS4-HMAC-SHA256-аутентификации можно передать в параметре ДополнительныеПараметры.Аутентификация. При этом Тип нужно установить в значение AWS4-HMAC-SHA256 и задать свойства: ИдентификаторКлючаДоступа, СекретныйКлюч, Сервис, Регион.

Аутентификация = Новый Структура;
Аутентификация.Вставить("Тип", "AWS4-HMAC-SHA256");
Аутентификация.Вставить("ИдентификаторКлючаДоступа", "AKIAU00002SQ4MT");
Аутентификация.Вставить("СекретныйКлюч", "МойСекретныйКлюч");
Аутентификация.Вставить("Регион", "ru-central1");
Аутентификация.Вставить("Сервис", "s3");

Файл = Новый ДвоичныеДанные("my_file.txt");

Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "text/plain");
Заголовки.Вставить("x-amz-meta-author", "Vladimir Bondarevskiy");
Заголовки.Вставить("Expect", "100-continue");

ДополнительныеПараметры = Новый Структура;
ДополнительныеПараметры.Вставить("Заголовки", Заголовки);
ДополнительныеПараметры.Вставить("Аутентификация", Аутентификация);
ДополнительныеПараметры.Вставить("Таймаут", 300);
Ответ = КоннекторHTTP.Put("https://test.storage.yandexcloud.net/my_file.txt", Файл, ДополнительныеПараметры);

Доступ через прокси-сервер

Настройки прокси можно передать в параметре ДополнительныеПараметры.Прокси.

Прокси = Новый ИнтернетПрокси;
Прокси.Установить("http", "192.168.1.51", 8192);
Результат = КоннекторHTTP.GetJson("http://httpbin.org/headers", Неопределено, Новый Структура("Прокси", Прокси));

Если в конфигурации используется БСП, то настройки прокси по умолчанию берутся из БСП.

Поддерживаемые HTTP методы

Для GET, OPTIONS, HEAD, POST, PUT, PATCH, DELETE есть соответствующие методы. Для любого из HTTP-методов можно отправить запрос через вызов метода ВызватьМетод.

Редиректы (Перенаправления)

Коннектор по умолчанию автоматически разрешает редиректы. Например, попробуем получить результат поиска в Яндексе (http://ya.ru).

Результат = КоннекторHTTP.Get("http://ya.ru/", Новый Структура("q", "удаление кеша метаданных инфостарт"));

Что по факту произойдет при выполнении этого запроса:

  • Коннектор выполнит запрос к URL http://ya.ru/
  • Сервер попросит выполнить запрос используя https, т.е. вернет код статуса 302 и значение заголовка Location=https://ya.ru/?q=...
  • Коннектор выполнит перезапрос, используя схему https
  • Cервер попросит выполнить запрос, используя другой URL, т.е. вернет код статуса 302 и значение заголовка Location=https://yandex.ru/search/?text=...
  • Коннектор выполнит перезапрос, используя URL https://yandex.ru/search/?text=...
  • Cервер наконец-то вернет результат в виде html

Отключить автоматический редирект можно с помощью параметра ДополнительныеПараметры.РазрешитьПеренаправление.

Проверка серверного сертификата SSL

Нужно ли проверять сертификат сервера и какие корневые сертификаты для этого использовать можно задать через параметр ДополнительныеПараметры.ПроверятьSSL.

Результат = КоннекторHTTP.Get("https://my_super_secret_server.ru/", Новый Структура("ПроверятьSSL", Ложь));

Клиентские сертификаты

Клиентский сертификат можно задать через параметр ДополнительныеПараметры.КлиентскийСертификатSSL.

КлиентскийСертификатSSL = Новый СертификатКлиентаФайл("my_cert.p12", "123");
Результат = КоннекторHTTP.Get("https://my_super_secret_server.ru/", Новый Структура("КлиентскийСертификатSSL", КлиентскийСертификатSSL));

Работа с Cookies

Коннектор извлекает cookies из заголовков Set-Cookie ответа сервера для дальнейшего использования. Полученные cookies можно посмотреть в свойстве ответа Cookies.

Передать произвольные cookies на сервер можно с помощью параметра ДополнительныеПараметры.Cookies.

Cookies = Новый Массив;
Cookies.Добавить(Новый Структура("Наименование,Значение", "k1", Строка(Новый УникальныйИдентификатор)));
Cookies.Добавить(Новый Структура("Наименование,Значение", "k2", Строка(Новый УникальныйИдентификатор)));
Ответ = КоннекторHTTP.Get("http://httpbin.org/cookies", Неопределено, Новый Структура("Cookies", Cookies));

Работа в рамках сессии

Коннектор позволяет работать с сервером в рамках сессии, т.е. сохраняет состояние между вызовами. Для этого нужно:

  • Создать объект Сессия методом СоздатьСессию
  • При каждом вызове передавать созданный объект в параметр Сессия

Например, попробуем получить с сайта releases.1c.ru список обновлений.

Сессия = КоннекторHTTP.СоздатьСессию();
Ответ = КоннекторHTTP.Get("https://releases.1c.ru/total", Неопределено, Неопределено, Сессия);

Данные = Новый Структура;
Данные.Вставить("execution", ИзвлечьExecution(Ответ));
Данные.Вставить("username", Логин);
Данные.Вставить("password", Пароль);
Данные.Вставить("_eventId", "submit");
Данные.Вставить("geolocation", "");
Данные.Вставить("submit", "Войти");
Данные.Вставить("rememberMe", "on");

Ответ = КоннекторHTTP.Post(Ответ.URL, Данные, Неопределено, Сессия);

Что при этом произойдет:

  • Коннектор выполнит GET запрос к URL https://releases.1c.ru/total
  • Сервер попросит выполнить запрос к URL https://login.1c.ru/login?service=https%3A%2F%2Freleases.1c.ru%2Fpublic%2Fsecurity_check
  • Коннектор сохранит полученные cookies и выполнит GET запрос к URL https://releases.1c.ru/total
  • Сервер вернет форму, в которой нужно авторизоваться
  • Извлечем данные из формы и отправим их на сервер вместе с нашим логином и паролем
  • Коннектор выполнит POST запрос и отправит данные формы и ранее полученные cookies
  • Сервер проверит параметры формы и если все хорошо, то выдаст тикет и попросит выполнить запрос к URL https://releases.1c.ru/total
  • Коннектор выполнит GET запрос к URL https://releases.1c.ru/total и передаст установленные ранее cookies
  • Сервер вернет нужный нам результат в виде html

Далее используя Сессия можно выполнять запросы к серверу и скачивать обновления.

Повторные попытки соединения/отправки запроса

Коннектор может автоматически выполнять повторные попытки соединения/отправки запроса с задержкой. Это бывает полезно если:

  • Соединение нестабильное
  • Сервер перегружен и может "пятисотить"
  • Сервер находится на обслуживании (перезагрузка, изменение конфигов, обновление и т.п.)
  • Сервер ограничивает количество запросов от клиента

Включить повторы можно с помощью параметра ДополнительныеПараметры.МаксимальноеКоличествоПовторов, задав значение больше 0.

Параметр ДополнительныеПараметры.МаксимальноеВремяПовторов позволяет ограничить суммарное время (таймауты + задержки между попытками). Значение по умолчанию: 10 мин.

Длительность задержки между попытками:

  • Растет экспоненциально (1 сек, 2 сек, 4 сек, 8 сек, 16 сек, ...). Можно регулировать с помощью параметра ДополнительныеПараметры.КоэффициентЭкспоненциальнойЗадержки
  • Для кодов состояний 413, 429 или 503 в качестве задержки используется значение заголовка Retry-After (длительность в секундах или конкретная дата).

Параметр ДополнительныеПараметры.ПовторятьДляКодовСостояний позволяет задать коды состояний, при которых нужно выполнять повтор. Если параметр не задан, повтор будет выполняться для всех кодов состояний >=500.

ДополнительныеПараметры = Новый Структура;
ДополнительныеПараметры.Вставить("МаксимальноеКоличествоПовторов", 5);
ДополнительныеПараметры.Вставить("Заголовки", Заголовки);
    
URL = "http://127.0.0.1:5000/retry_after_date";
Ответ = КоннекторHTTP.Get(URL, Неопределено, ДополнительныеПараметры);

connector's People

Contributors

alexandr-yang avatar artesk avatar asosnoviy avatar bapho-bush avatar blizd avatar daabramov avatar korotovskih avatar kuntashov avatar leemuar avatar petypen avatar plebedevv avatar slaxxals avatar thedonrad avatar trumanleks avatar unalt avatar vbondarevsky avatar zeegin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

connector's Issues

Учитывать expires для cookies

Set-Cookie: login=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0, login=test; expires=Tue, 26-Nov-2019 02:35:14 GMT

Сохранить в хранилище cookies нужно значение test

Упорядочение параметров в URL

Коннектор принимает в качестве параметров в URL структуру или соответствие, которые не гарантируют порядок следования элементов. Возникают проблемы при взаимодействии с API, для которых порядок параметров в URL имеет значение.

Отправка запроса портит переданные настройки, что мешает в некоторых случаях

При выполнении кода:

Сервер = "https://jsonplaceholder.typicode.com/";

Настройки = Новый Структура; 
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type","application/json");
Настройки.Вставить("Заголовки", Заголовки);
//ПараметрыЗапроса = Новый Структура("username, password", "anonymous", "hrgesf7HDR67Bd");
ПараметрыЗапроса = "{""username"":""anonymous"",""password"":""anonymous""}";

НастройкиКопия = ЗначениеИзСтрокиВнутр(ЗначениеВСтрокуВнутр(Настройки));
Результат = КоннекторHTTP.Post(Сервер + "posts", ПараметрыЗапроса, НастройкиКопия);

Запись = Новый ЗаписьJSON();
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, Настройки);
Дамп1 = Запись.Закрыть();
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, НастройкиКопия);
Дамп2 = Запись.Закрыть();

Видно, что настройки модифицируются. Это ведет к тому, что при последовательном использовании (например post и postjson) одной структуры с настройками возможны проблемы. Собственно, я их и получил, иначе сюда бы не писал.

Типизация параметра Cookies

В СоздатьСессию()
Сессия.Вставить("Cookies", Новый Соответствие);

Но в ПодготовитьЗапрос()
Cookies = ВыбратьЗначение(Неопределено, ДополнительныеПараметры, "Cookies", Новый Массив);
И в ДозаполнитьCookie(Cookies, URL)
Используется условие Если ТипЗнч(Cookies) = Тип("Массив") Тогда

Непонятно зачем использовать массив.

Показывать исходную проблему при ошибке разбора JSON в методе КакJson (GetJson, PostJson, PutJson, DeleteJson)

Здравствуйте! Шикарная библиотека, я даже теперь не боюсь писать код для вызова разных API, поскольку стало супер просто ))

Вот мой мелкий кейс.

  1. Пока сайт (точнее его API) доступно, метод GetJson работает ок, поскольку API отдает Json.
  2. Но если доступ к сайту, например, заблокировать в .htaccess, то он начинает по любому запросу отдавать html, например:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /wp-json/wp/v2/settings
on this server.</p>
</body></html>

=> библиотека крашится в функции JsonВОбъект на строчке Объект = ПрочитатьJSON(, поскольку тело ответа - не json.

Я понимаю, что это не проблема библиотеки - ведь сайт вдруг вместо json начинает отдавать html :) Но м.б. обернуть Объект = ПрочитатьJSON в Попытку/Исключение и вернуть, не знаю, какую-нибудь ошибку?

Тесты требуют наличия действующего аккаунта ИТС

В данный момент чтобы запустить и проверить прохождение тестов, требуется действующий аккаунт ИТС. Это немного усложняет доработку библиотеки, у некоторых разработчиков (типа меня) аккаунта нет.

Возможно стоит сделать так, чтобы запуск и прохождение теста не зависели от наличия у тестирующего действующего аккаунта ИТС. httpbin вроде умеет работать с куками, его возможностей будет достаточно для того чтобы этот тест сделать?

image

Возможность переопределять дату AWS4 запроса

Не могу придумать реального случая, когда это может пригодиться, кроме отладки. В данный момент всегда берется текущая дата:

ТекущееВремя = ТекущаяУниверсальнаяДата();

Варианты:

  • анализировать заголовки запроса, если в них есть x-amz-date или date - использовать их значение
  • еще один параметр аутентификации^
Аутентификация = Новый Структура;
Аутентификация.Вставить("ДатаЗапроса", Дата(2020, 02, 01));
...

Некорректно формируется подпись AWS4, если порт отличается от стандартного

При получении заголовков для подписи порт, отличный от стандартных 80 и 443, не добавляется к заголовку host, в результате чего получается некорректная подпись

Список.Добавить("host", Сервер);

Проблему можно было бы обойти, добавив собственный заголовок host, но проверка на наличие такого заголовка не срабатывает, если этот заголовок не последний
ЗаголовокHostЕстьВЗапросе = Заголовок = "host";

Не работает клиентский сертификат SSL

Ошибка проверки типа в функции
Сравнивается значение с типом, а не тип значения с типом

Функция ОбъектЗащищенногоСоединения(ДополнительныеПараметры)
	
	Если ДополнительныеПараметры.ПроверятьSSL = Ложь Тогда
		СертификатыУЦ = Неопределено;
	ИначеЕсли ТипЗнч(ДополнительныеПараметры.ПроверятьSSL) = Тип("СертификатыУдостоверяющихЦентровФайл") Тогда
		СертификатыУЦ = ДополнительныеПараметры.ПроверятьSSL;
	Иначе
		СертификатыУЦ = Новый СертификатыУдостоверяющихЦентровОС;
	КонецЕсли;
	КлиентскийСертификат = Неопределено;
	Если ДополнительныеПараметры.КлиентскийСертификатSSL = Тип("СертификатКлиентаФайл") 
		ИЛИ ДополнительныеПараметры.КлиентскийСертификатSSL = Тип("СертификатКлиентаWindows") Тогда
		КлиентскийСертификат = ДополнительныеПараметры.КлиентскийСертификатSSL;
	КонецЕсли;
	
	Возврат Новый ЗащищенноеСоединениеOpenSSL(КлиентскийСертификат, СертификатыУЦ);
	
КонецФункции

должно быть:

Если ТипЗнч(ДополнительныеПараметры.КлиентскийСертификатSSL) = Тип("СертификатКлиентаФайл") 
	ИЛИ ТипЗнч(ДополнительныеПараметры.КлиентскийСертификатSSL) = Тип("СертификатКлиентаWindows") Тогда
	КлиентскийСертификат = ДополнительныеПараметры.КлиентскийСертификатSSL;
КонецЕсли;

Передача параметров-массивов с [] в именах

Возможно, опционально. В общем,

ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("param", СтрРазделить("1,2", ","));

Ответ = КоннекторHTTP.GetJson("https://httpbin.org/anything/params", ПараметрыЗапроса);	

должна быть возможность отправить не только https://httpbin.org/anything/params?param=1&param=2, но и https://httpbin.org/anything/params?param[]=1&param[]=2 (важно для php, например)

Сложные параметры.

Вопрос для рассмотрения.
Я воспользовался данной библиотекой для получения данных их JIRA.
С простыми праметрическими запросами проблем не возникло, но когда пришлось писать запросы с ипользованием jql, то возникли проблемы.
Дело в том, что могут использоваться запросы вида:
\search?jql=project=1200
\search?jql=worklogDate >= 2017-04-01 AND worklogDate <= 2017-05-01
Возникают две проблемы: Форматирование текста запроса и множественные знаки "=".

У Вас в функции РазобратьURL парсятся праметры по "=". В таком случае это приводит к ошибкам. Передача параметров через структуру помогает избежать проблемы, но не полностью, т.к. в процедуре ПодготовитьТелоЗапроса, при получении HTTPЗапрос.АдресРесурса, вызывается РазобратьURL еще раз для уже собранной строки. И она опять ломается.

Я для себя внес изменения:
АдресРесурса подготавливается сразу в функции ПодготовитьЗапрос через функцию ПодготовитьURL (точнее вместо нее).
Пришлось внести исключения в КодироватьПараметрыЗапроса для символов ">", " <" и других. Т.к. JIRA их использует в явном виде.

Сборка проекта в формате cfe для использования впакетном менеджере А1И

Существует проблема
Остутствует возможность загружать в базу расширение с модулем Коннектор, в дальнейшем оперативно проверять обновляения и при необходимости загружать свежую версию.

Хотелось бы иметь следующую функциональность
Собрать cfe с префиксом, для минимизации пересечений по имени модуля при использовании в соседних расширениях.

Сформировать описание пакета с сылками на проверки, для того чтобы при работе из 1С можно было получить общую информацию о состоянии пакета.

Дополнительный контекст
Развернуто мысль описал в http://forum.infostart.ru/forum9/topic249947/message2537570/

Как сохранить cookies при редиректе?

Описание проблемы:
Есть запрос к сайту с заголовком "contentType = 'application/json'", сайт делает редирект с кодом 308, но при попытке обратится по новому адресу появляется ошибка из-за того что заголовок contentType поменялся с 'application/json' на 'application/octet-stream'

Возможная причина и решение:

В функции ВызватьHTTPМетод если происходит редирект с кодом отличным от 307 и 308 то из куков удаляются заголовки "content-length,content-type,transfer-encoding" в противном случае по идее они должны остаться, но это не происходит, как решение добавил строку кода НовыйHTTPЗапрос.Заголовки = ПодготовленныйЗапрос.Заголовки;

До изменений:

Если Ответ.КодСостояния <> КодыСостоянияHTTP.ВременноеПеренаправление_307 
	И Ответ.КодСостояния <> КодыСостоянияHTTP.ПостоянноеПеренаправление_308 Тогда
	УдалитьЗаголовки(ПодготовленныйЗапрос.Заголовки, "content-length,content-type,transfer-encoding");
	НовыйHTTPЗапрос.Заголовки = ПодготовленныйЗапрос.Заголовки;
Иначе
	ИсходныйПоток = ПодготовленныйЗапрос.HTTPЗапрос.ПолучитьТелоКакПоток();
	ИсходныйПоток.КопироватьВ(НовыйHTTPЗапрос.ПолучитьТелоКакПоток());
КонецЕсли;

После:

Если Ответ.КодСостояния <> КодыСостоянияHTTP.ВременноеПеренаправление_307 
	И Ответ.КодСостояния <> КодыСостоянияHTTP.ПостоянноеПеренаправление_308 Тогда
	УдалитьЗаголовки(ПодготовленныйЗапрос.Заголовки, "content-length,content-type,transfer-encoding");
	НовыйHTTPЗапрос.Заголовки = ПодготовленныйЗапрос.Заголовки;
Иначе
	ИсходныйПоток = ПодготовленныйЗапрос.HTTPЗапрос.ПолучитьТелоКакПоток();
	ИсходныйПоток.КопироватьВ(НовыйHTTPЗапрос.ПолучитьТелоКакПоток());
	НовыйHTTPЗапрос.Заголовки = ПодготовленныйЗапрос.Заголовки;
КонецЕсли;

Получение тела как строки в новых версиях.

В старых версиях (1.2.3) в структуре ответа был ключ "Ответ", содержащий встроенный объект 1С типа HTTPОтвет. Соответственно, я мог получить строковое тело ответа с как СтруктураОтвета.Ответ.ПолучитьТелоКакСтроку(); В актуальной версии это не работает так как ключа "Ответ" нет.

Прошу уточнить - это плановое изменение или регрессия. Если плановое, то как предполагается работать с текстовыми ответами?

Некорректно формируется AWS4 аутентификация на старых платформах

Портировали Коннектор на более старый режим совместимости - 8.3.11.2867, режим совместимости Версия 8.2.13.

Обнаружили, что некорректно формируется подпись AWS4 в случае когда запрос не содержит параметров (вида ?name=1&action=put)

Формируется неверный канонический запрос, канонические параметры запроса устанавливаются равными "=". Из за этого рассчитывается неверная подпись.

Пример правильного канонического запроса:

GET
/

host:chefstorage.s3.us-east-1.amazonaws.com
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date:20200214T181103Z

host;x-amz-content-sha256;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Пример неправильного канонического запроса, формируемого Коннектором на старой платформе:

GET
/
=
host:chefstorage.s3.us-east-1.amazonaws.com
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date:20200214T181103Z

host;x-amz-content-sha256;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Проблема в функции РазобратьURL(), РазобратьURL("http://localhost/") на старых версиях платформы вернет структуру, ключ "Параметры" которой будет содержать массив с одной пустой строкой

В новых версиях платформы РазобратьURL("http://localhost/") в "Параметры" возвращает пустой массив

В ЗаполнитьПараметрыЗапроса() когда Запрос равен пустой строке, СтрРазделить(Запрос, "&", Ложь) на старых версиях платформы возвращает массив, содержащий одну пустую строку. Из-за такого поведения канонические параметры формируются неверно. В новых версиях платформы СтрРазделить("", "&", Ложь) возвращает пустой массив, там библиотека работает корректно

Для Каждого СтрокаКлючРавноПараметр Из СтрРазделить(Запрос, "&", Ложь) Цикл

Некорректное формирование подписи AWS4 в старых версиях платформы\режима совместимости при пустом теле запроса

Используем библиотеку на платформе 8.3.11.2867, режим совместимости "Версия 8.2.13". Обнаружили, что некорректно формируется подпись AWS в случае когда у запроса нет тела, например ListObjects

Причина - разное поведение функций ПолучитьТелоКак*() объекта HTTPЗапрос

ХешированиеДанных(ХешФункция.SHA256, ПодготовленныйЗапрос.HTTPЗапрос.ПолучитьТелоКакПоток());

В старших версиях платформы в случае, если тело запроса не было установлено, возвращает пустые ДвоичныеДанные, старые же версии платформы - Неопределено. Из-за разных типов рассчитывается разный sha-256 хеш тела запроса

Добавить метод КакXML

Спасибо за такую полезную библиотеку.

Предлагаю добавить новый метод КакXML, который по ответу возвращает XML с помощью ФабрикаXDTO

Библиотека не предназначена для клиентского контекста.

Текущая реализация библиотеки предназначена для серверного контекста. В некоторых случаях это неудобно, например:
-- при встраивании библиотеки во внешние обработки удобно было бы разместить ее в модуле формы
-- в случае клиент-серверного режима 1С Предприятия HTTP запрос будет делать сервер 1С Предприятия а не клиентская машина.

Я взял на себя смелость доработать библиотеку для работы в клиентском контексте. Прогресс есть, даже проходит часть тестов. Результатом работы будет две внешние обработки:

  • обработка КоннекторКлиент в которой будет одна форма в модуле которой будет размещаться библиотека
  • обработка Тесты

@vbondarevsky Владимир, требуется ли материнскому проекту эта доработка? Делать PR?

2020-11-18_20-30-14

GZip-кодирование по-умолчанию

Вопрос для обсуждения

При отправке любого запроса библиотека по-умолчанию шлет заголовок Accept-Encoding: gzip, т.е. всегда запрашивает у сервера сжатые данные. Имеет ли смысл делать такое действие по-умолчанию?

В текущей версии чтобы получить несжатые данные мне как пользователю библиотеки нужно предприниматься какие-то действия (какие?). Возможно, было бы удобно сделать так, чтобы по умолчанию этот заголовок не добавлялся. Возможно, сделать доп параметр, передача которого добавит заголовок при запросе:

Результат = КоннекторHTTP.PostJson("https://httpbin.org/post",, Новый Структура("СжиматьОтвет", Истина));

П.С. Как в текущей версии отключить запрос на сжатие?

Некорректное декодирование параметров запроса

При передачи параметра, содержащего закодированный урл с несколькими "вложенными параметрами" происходит некорректное декодирование.
Например урл: https://www.DOMEN.ru?URL_INNER=http%3A%2F%2Fwww.kuku.ru%2F%3Fs%3D1%26b%3D2&OTHER=1
Будет расценен как: https://www.DOMEN.ru?URL_INNER=http%3A%2F%2Fwww.kuku.ru%2F%3Fs%3D1&OTHER=1&b=2

Авторизация по Api-Key

Привет, подскажи, есть ли возможность создать сессию пользователя имея ключ Api?

То есть авторизовав пользователя по ключу,
мы имеем Токен, который необходимо передавать в другие запросы....

Ошибка кодирования параметров запроса GET

Владимир, прежде всего преогромнейшее спасибо за чудесную библиотеку!

Воспроизведение ошибки:

  1. Ставим точку останова в методе ВызватьHTTPМетод после строки:
    ПодготовленныйЗапрос = ПодготовитьЗапрос(Сессия, Запрос);
  2. Выполним код:
    КоннекторHTTP.GetJson("http://localhost/query", Новый Структура("date", Формат(Дата('20191103'), "ДФ=yyyy-MM-ddTHH:mm:ss.000000")))

В результате в ПодготовленныйЗапрос.HTTPЗапрос.АдресРесурса получим:
/query?date=2019-11-03T00:00:00.000000
Хотя ожидается:
/query?date=2019-11-03T00%3A00%3A00.000000

Где уши: метод КодироватьПараметрыЗапроса, строка:
ЗначениеПараметра = КодироватьСтроку(Значение, СпособКодированияСтроки.URLВКодировкеURL);

Исправление:
-ЗначениеПараметра = КодироватьСтроку(Значение, СпособКодированияСтроки.URLВКодировкеURL);
+ЗначениеПараметра = КодироватьСтроку(Значение, СпособКодированияСтроки.КодировкаURL);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.