Создание простого HTTP-клиента с использованием Proxygen

Создание простого HTTP-клиента с использованием Proxygen

8 июня 2022 г.

Эта статья о proxygen — библиотеке, используемой для создания всех видов серверов. Он имеет открытый исходный код и поддерживается Meta. Изначально фреймворк задумывался как набор инструментов для разработки прокси. Следовательно, проксиген. Однако в этой библиотеке гораздо больше.

В первой статье этой серии мы рассмотрим разработку самого простого из возможных HTTP-клиентов. Здесь много движущихся частей, поэтому я предпочитаю сводить сложность к минимуму и сосредотачиваться только на том, что важно. Если вы читаете это, у вас, вероятно, есть голова на плечах, и вы сможете расширить это самостоятельно.

Во-первых, давайте начнем с очень общей архитектуры proxygen. Данные либо читаются из сокета, либо записываются в сокет. Затем у нас есть HTTPSession, который использует HTTPCodec для чтения/записи данных в/из сокета. Каждая HTTPSession будет иметь одну или несколько HTTPTransactions. Каждая HTTPTransaction взаимодействует с обработчиком при получении/отправке данных. Вы можете увидеть это на изображении ниже.

Proxygen architecture (taken from proxygen GitHub repo)

Этот очень простой, но мощный набор абстракций позволяет обрабатывать все виды других протоколов, таких как HTTP2, HTTP3/QUIC/SPDY, включая собственные «домашние» протоколы. Но прежде чем вы начнете работать с любым из них, вы, вероятно, захотите создать самое простое приложение, чтобы убедиться, что проект настроен правильно и что вы понимаете все соответствующие концепции. Лично я считаю, что это самая сложная часть. Несмотря на то, что proxygen поставляется со своим собственным скриптом сборки и набором примеров, я не нашел его самым «дружественным». Porxygen в значительной степени зависит от некоторых других библиотек (например, folly, libevent, glog, gflags…), поэтому вам необходимо убедиться, что они также присутствуют в вашей системе. Вы также можете настроить используемый компилятор и/или компоновщик. Мне лично нравится использовать компилятор clang и набор инструментов, который идет с ним.

Чтобы помочь с вышеуказанными проблемами, я создал репозиторий, который делает следующее:

* вводит большинство зависимостей в виде подмодулей git * предоставляет скрипт сборки для сборки всех зависимостей * реализует простой HTTP-клиент (KissClient, Kiss означает keep it stupid simple) * содержит инструкции по сборке клиента

==Предостережение: в настоящее время проект работает только на Linux. На данный момент у меня нет планов заставить его работать на MacOS X или Windows. Сказав это, я готов принять запрос на вытягивание.==

Этого репозитория должно быть достаточно, чтобы вы могли создать свой собственный проект на его основе

проксиген.

== Если у вас возникнут какие-либо проблемы, откройте задачу (https://gitlab.com/ technologysoup/starter-kits/hello-proxygen/-/issues) или свяжитесь с нами через Discord (https://discord.gg/vFbZFzMmDK< /а>)==

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

https://gitlab.com/technologysoup/starter-kits/hello- proxygen/-/tree/main/src/kiss_client

KissClient — это класс, в котором мы реализуем клиент. Он расширяет два других класса — proxygen::HTTPConnector::Callback и proxygen::HTTPTransactionHandler.

proxygen::HTTPConnector используется для установления новых соединений HTTP или HTTPS, а proxygen::HTTPConnector::Callback определяет объект обратного вызова, который будет получать результаты. Объект обратного вызова имеет методы connectSuccess и connectError.

HTTPTransaction представляет одну пару запрос/ответ в HTTP-подобном протоколе. Он работает с транспортом и обработчиком для обработки входящих и исходящих данных.

Когда сеанс установлен, connectSuccess вызывается с объектом сеанса, который, в свою очередь, используется для получения нового HTTPTransaction. Этот объект транзакции (txn_) используется для отправки заголовков и тела.

Как только клиент завершит отправку контента (заголовки + тело), ​​сервер отправит ответ. В этот момент будут вызываться хуки, которые реализованы как часть интерфейса HTTPTransactionHandler - onHeadersComplete, onBody, onEOM, и т. д.

Подводя итог, последовательность событий такова:

  1. Приложение создает обратный вызов и объект обработчика.
  2. Затем приложение создает HTTPConnector, передавая ему обратный вызов и подключается к адресу.
  3. После успешного установления соединения с помощью перехватчиков обратного вызова создается HTTPSession.
  4. Сеанс используется для создания новой HTTP-транзакции. HTTPTransaction инициализируется с помощью объекта handler.
  5. Транзакция используется для отправки запроса на сервер.
  6. После получения ответа сервера вызываются перехватчики handler.
  7. Когда сеанс простаивает (это означает, что между клиентом и сервером больше нечего обменивать), сеанс закрывается.

И это все. У нас есть рабочий HTTP-клиент. Вы можете проверить это, запустив какой-нибудь сервер или используя netcat.

$ ./hello-proxygen
I0606 23:00:19.731132 1463353 kiss_client.cc:44] Sending request for http://localhost:4586
I0606 23:00:19.731266 1463353 kiss_client.cc:21] Got headers for http://localhost:4586.
I0606 23:00:19.731276 1463353 kiss_client.cc:24] Got body for http://localhost:4586.
I0606 23:00:19.731279 1463353 kiss_client.cc:31] Got EOM for http://localhost:4586.

В следующей статье я планирую показать, как сделать простой HTTP-сервер.

Если у вас есть какие-либо вопросы, не стесняйтесь оставлять комментарии ниже.


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE