HTTP-запросы
Общая информация
- Клиент — некоторая система, которая инициирует соединение и посылает запрос.
- Сервер — программное обеспечение, которое ожидает установку соединения от клиента, получает запрос, выполняет некоторые действия и возвращает ответ клиенту.
В основе HTTP-взаимодействия лежит понятие URI (или URL в более простом варианте) — универсального идентификатора ресурса, который описан к стандарте RFC 3986. Взаимодействие осуществляется с помощью запросов. Каждый запрос содержит несколько частей: стартовую строку (определяет тип сообщения), заголовки (определяют параметры запроса) и тело сообщения (дополнительные данные запроса). Тело сообщения может быть пустым.
метод uri HTTP/версия
Здесь:
- метод — действие, которое сервер должен выполнить с ресурсом, указанным с помощью URI. Состоит из любых символов US-ASCII (кроме управляющих символов и разделителей). Название метода может быть любым, но рекомендуется использовать методы, описанные в спецификации HTTP 1.1 (RFC 2616).
- uri — путь к конкретному ресурсу на сервере. Запрос будет выполняться над данными, которые адресуются указанным URI. Если используемый в запросе метод не требует указания ресурса, вместо URI пишется символ «*».
- версия — версия HTTP-протокола. В настоящий момент это версия 1.1.
HTTP/версия код-состояния пояснение
Здесь:- версия — номер версии HTTP-протокола, аналогично стартовой строке запроса. В настоящий момент это версия 1.1.
- код-состояния — описывает результат выполнения запроса.
- пояснение — текстовое описание результата выполнения запроса. Данный текст не содержит символов перевода строки и возврата каретки.
- общие заголовки — используются как в запросах, так и в ответах;
- заголовки запроса — используются только в запросах;
- заголовки ответа — используются только в ответах;
- заголовки сущностей — сопровождают каждую сущность сообщений, используются как в запросах, так и в ответах.
Таким образом, HTTP-взаимодействие выполняется следующим образом:
- Клиент устанавливает соединение с сервером.
- Клиент создает запрос и отправляет его серверу.
- Сервер принимает запрос и пытается его выполнить.
- По результатам выполнения запроса сервер формирует ответ и отправляет его клиенту.
- Клиент получает ответ и анализирует содержащийся в нем код состояния, после чего принимает решение о дальнейших действиях.
«1С:Исполнитель» может выступать только в качестве клиента для протокола HTTP.
Методы HTTP-запроса
Метод | Описание |
---|---|
CONNECT | Устанавливает двустороннюю связь с запрошенным ресурсом. Может использоваться для открытия туннеля. |
DELETE | Удаляет указанный ресурс. |
GET | Позволяет запросить содержимое какого-либо ресурса или выполнить какое-либо действие. |
HEAD | Позволяет получить метаданные, проверить наличие какого-либо ресурса или узнать, что изменилось с момента последнего обращения. Ответ сервера не содержит тела. |
OPTIONS | Используется для определения возможностей веб-сервера или параметров соединения для конкретного ресурса. |
PATCH | Аналогичен запросу PUT, но применяется к фрагменту данных ресурса. |
POST | Отправляет данные на сервер для обработки. |
PUT | Создает новый ресурс или заменяет представление целевого ресурса данными, указанными в теле запроса. |
TRACE | Возвращает полученный запрос обратно клиенту. Позволяет клиенту узнать, что добавляют или изменяют в оригинальном запросе промежуточные узлы (через которые проходит запрос). |
Коды состояния
Код | Класс | Описание |
---|---|---|
1хх | Информационный | Информирует о процессе передачи запроса. |
2хх | Успех | Информирует об успешном выполнении запроса. |
3хх | Перенаправление | Сообщает клиенту о том, что запрос необходимо выполнить с другими параметрами. Заголовки ответа содержат информацию о том, что надо изменить в запросе. |
4хх | Ошибка клиента | Указывает, что запрос клиента содержит ошибку. |
5хх | Ошибка сервера | Указывает, что во время выполнения запроса на сервере произошла ошибка. |
Кодирование URL-адреса в «ЗапросHttp»
В адресе запроса могут содержаться символы, использование которых недопустимо в URI. Для успешного выполнения такого запроса недопустимые символы должны быть закодированы с помощью символа «%». Однако разработчик не всегда может гарантировать кодирование всех недопустимых символов. В результате в адресе запроса могут встречаться как допустимые символы, так и закодированные и незакодированные недопустимые символы.
Чтобы обеспечить успешное выполнение запроса, ЗапросHttp сохраняет все существующие закодированные представления символов во входящей строке и кодирует недопустимые символы. Входящая строка адреса обрабатывается следующим образом: если за символом процента (%) следует значение, допустимое для кода символа (два шестнадцатеричных значения), то считается, что это код символа. Иначе считается, что это знак процента, который будет закодирован как %25.
Входящий URL-адрес разделяется на группы, каждая из которых кодируется отдельно. Группы адреса соответствуют описанию стандарта RFC3986: схема (scheme), основание (authority), путь (path), запрос (query), фрагмент (fragment):
Допустимыми являются все разделители внутри сегментов, которые указаны в стандарте RFC 3986: «!», «&», «'», «+», «*», «$», «(», «)», «,», «;», «=». Также для сегментов «запрос» и «фрагмент» допустимы символы «/» и «?».
Символы, которые являются разделителями сегментов, не меняются: «:», «/», «?», «#», «[», «]», «@». Не меняются и разрешенные к использованию во всех частях URL-адреса символы «-», «.», «_», «~».
Если во входящей строке представлены символы национальных алфавитов (то есть не латиница, в частности русские буквы), то они также кодируются. Если такие символы встречаются в доменной части строки, то выполняется IDN-кодирование. Если они присутствуют в других частях URL, то выполняется процентное кодирование.
https://yandex.ru/maps%2F%3Ftest1%2Ftest 2%5Ctest3\test4
— исходный адрес запроса.https://yandex.ru/maps%2F%3Ftest1%2Ftest%202%5Ctest3%5Ctest4
— адрес запроса после преобразования: пробел и обратная косая черта закодированы.http://test.ru/search=aa%2Faa
— исходный адрес запроса.http://test.ru/search=aa%2Faa
— адрес запроса после преобразования: текст не изменился, так как после процента идет допустимый код символа.http://test.ru/search=100%
— исходный адрес запроса.http://test.ru/search=100%25
— адрес запроса после преобразования: знак процента закодирован.
Пример IDN-кодирования:
http://яндекс.рф
— исходный
адрес запроса.http://xn--d1acpjx3f.xn--p1ai
— адрес запроса после
преобразования.
Объектная модель
Рассмотрим объектную модель, предоставляемую «1С:Исполнителем» для поддержки клиент-серверного взаимодействия с использованием HTTP-запросов.
В основе модели выступает тип КлиентHttp, содержащий базовые параметры HTTP-взаимодействия. Экземпляр этого типа можно получить из свойства глобального контекста КлиентHttp.
Экземпляр КлиентHttp может создавать новые экземпляры этого типа, если вам требуется работать с несколькими серверами. Данные экземпляры получают все параметры из базового экземпляра, кроме тех параметров, которые можно изменить при создании копии. Другими словами, создается измененная копия родительского экземпляра. Про такую возможность создания нового экземпляра на базе существующего говорят, что существующий экземпляр выступает в роли фабрики. Экземпляр типа КлиентHttp, предоставляемый «1С:Исполнителем», называется базовым экземпляром.
пер МойКлиент = КлиентHttp.СБазовымUrl("http://example.com")
«1С:Исполнитель» поддерживает односторонний (с аутентификацией сервера) и двусторонний (с аутентификацией сервера и клиента) TLS.
- Пример использования одностороннего TLS
-
знч СертификатСервиса = новый ЦифровойСертификат( новый Файл("service.cer").ОткрытьПотокЧтения().ПрочитатьКакБайты()) знч СертификатыСервера = новый ХранилищеPkcs12() СертификатыСервера.ДобавитьСертификат("some.api.ru", СертификатСервиса) знч ПараметрыЗащиты = новый ПараметрыЗащищенногоСоединения(СертификатыСервера) знч Клиент = КлиентHttp.СПараметрамиЗащиты(ПараметрыЗащиты) знч Запрос = Клиент.ЗапросGet("https://some.api.ru/action") исп Результат = Запрос.Выполнить()
- Пример использования двустороннего TLS
-
знч СертификатСервиса = новый ЦифровойСертификат( новый Файл("service.cer").ОткрытьПотокЧтения().ПрочитатьКакБайты()) знч СертификатыСервера = новый ХранилищеPkcs12() СертификатыСервера.ДобавитьСертификат("some.api.ru", СертификатСервиса) знч КлючиКлиента = новый ХранилищеPkcs12(новый Файл("client.pfx").ОткрытьПотокЧтения().ПрочитатьКакБайты()) знч ПараметрыЗащиты = новый ПараметрыЗащищенногоСоединения(СертификатыСервера, КлючиКлиента, "key-password") знч Клиент = КлиентHttp.СПараметрамиЗащиты(ПараметрыЗащиты) знч Запрос = Клиент.ЗапросGet("https://some.api.ru/action") исп Результат = Запрос.Выполнить()
Если вы хотите установить защищенное HTTPS-соединение для отправки запросов к серверу, использующему протокол TLS с шифрованием по ГОСТ, используйте метод СКриптоПроTls(). Для работы этого метода убедитесь, что у вас установлены модули КриптоПро.
- Пример использования двустороннего TLS ГОСТ
-
знч ДоверенныеСертификаты = новый ХранилищеJks() ДоверенныеСертификаты.ДобавитьСертификат( "demo", новый ЦифровойСертификат(Ресурс{demo.cer}.ОткрытьПотокЧтения().ПрочитатьКакБайты()) ) ДоверенныеСертификаты.ДобавитьСертификат( "demo.CA", новый ЦифровойСертификат(Ресурс{demo.CA.cer}.ОткрытьПотокЧтения().ПрочитатьКакБайты()) ) знч Параметры = новый ПараметрыЗащищенногоСоединения( ДоверенныеСертификаты, новый ХранилищеКриптоПро(), "key-password" ) знч Клиент = КлиентHttp.СКриптоПроTls() .СПараметрамиЗащиты(Параметры) знч Запрос = Клиент.ЗапросGet("https://website-address.ru") .ДобавитьЗаголовок("Заголовок", "Значение") исп Ответ = Запрос.Выполнить()
Теперь, когда у вас есть экземпляр, выступающий в роли клиента, вам необходимо получить экземпляр типа ЗапросHttp, чтобы отправить запрос на сервер и получить от него ответ. Ответ сервера поступает в виде экземпляра типа ОтветHttp.
Если вы хотите выполнить запрос, описанный в стандарте HTTP 1.1, то можете использовать метод КлиентHttp.ЗапросGet() или аналогичные ему (все поддерживаемые имена HTTP-методов перечислены в таблице выше). В этом случае в метод необходимо передать только URI на сервере, к которому будет применяться запрос.
пер Запрос = МойКлиент.ЗапросGet("/path/resource?param1=value1¶m2=value")
пер Запрос = МойКлиент.СоздатьЗапрос("GET", "/path/resource?param1=value1¶m2=value")
После получения экземпляра типа ЗапросHttp вы можете указать ему нужные заголовки, задав их явно или переопределив уже существующие. Для этого используйте свойство ЗапросHttp.Заголовки, которое предоставляет доступ ко всей коллекции заголовков запроса. Свойство имеет тип ЗаголовкиHttp.
Тип ЗапросHttp позволяет работать как с одним заголовком (методы ДобавитьЗаголовок(), УстановитьЗаголовок(), УдалитьЗаголовок()), так и с несколькими заголовками сразу (методы ДобавитьЗаголовки(), УстановитьЗаголовки(), ОчиститьЗаголовки()). С помощью перечисленных методов нельзя изменять заголовки Content-Type и Transfer-Encoding. Для изменения заголовка Content-Type предназначен метод УстановитьТипСодержимого(). Для указания информации о клиентском приложении (заголовок User-Agent) предназначен метод УстановитьUserAgent().
- УстановитьТело(Тело: Строка): ЗапросHttp — устанавливает тело запроса из строки.
- УстановитьТело(Поток: ПотокЧтения): ЗапросHttp — устанавливает тело запроса из потока. Запрос выполняется с использованием механизма Chunked transfer encoding. Чтение переданного потока осуществляется только в момент вызова метода ЗапросHttp.Выполнить(). После выполнения запроса поток закрывается.
- УстановитьТело(Поток: ПотокЧтения, Размер: РазмерБайтов|Число): ЗапросHttp — устанавливает тело запроса из потока. Чтение переданного потока осуществляется только в момент вызова метода ЗапросHttp.Выполнить(). После выполнения запроса поток закрывается.
- УстановитьТело(Файл: Файл): ЗапросHttp — устанавливает тело запроса из файла. Чтение переданного файла осуществляется только в момент вызова метода ЗапросHttp.Выполнить().
После того как наш запрос готов, его необходимо выполнить. Для этого служит метод ЗапросHttp.Выполнить(). Внутри вызова этого метода выполняются все действия HTTP-взаимодействия. Результат вызова помещается в экземпляр типа ОтветHttp, который содержит полученные от сервера данные.