Как вы используете boost / beast для анализа и извлечения полезной нагрузки из запроса HTTP POST? - PullRequest
3 голосов
/ 10 января 2020

Я пытаюсь понять, как обрабатывать содержимое HTTP-запроса POST с помощью библиотеки Boost Beast. Я немного изменил пример расширенного сервера Boost Beast , чтобы получить представление о вещах.

Я добавил следующие строки в метод handle_request () в примере (непосредственно перед строкой 155 ):

    if ( req.method() == http::verb::post)
    {
      std::cout << req << std::endl;
    }

Я создал простой тестовый файл с именем foobar.dat, содержащий следующее:

This is a test!

Я отправляю его на сервер с помощью этой команды curl:

curl -F 'test=@foobar.dat' http://localhost:8080

, что приводит к следующему выводу с сервера:

POST / HTTP/1.1Host: localhost:8080
User-Agent: curl/7.58.0
Accept: */*
Content-Length: 218
Content-Type: multipart/form-data; boundary=------------------------9c747f078ebbe880

--------------------------9c747f078ebbe880
Content-Disposition: form-data; name="test"; filename="foobar.dat"
Content-Type: application/octet-stream

This is a test!

--------------------------9c747f078ebbe880--

Итак, у меня есть сервер, получающий ожидаемое сообщение.

Если я немного изменю свой тест на следующее Я могу извлечь поля заголовка индивидуально, а также тело в одном большом буфере.

    if ( req.method() == http::verb::post)
    {
      std::cout << "Fields:" << std::endl;

      int field_count = 0;
      for(auto const& field : req)
          std::cout << "Field#"
                    << ++field_count << " : " << field.name() << " = " << field.value() << std::endl;

      std::cout << "Body:" << std::endl;
      int body_count = 0;
      for(auto it = boost::asio::buffer_sequence_begin(req.body().data());
          it != boost::asio::buffer_sequence_end(req.body().data()); ++it)
      {
        // This is the next buffer in the sequence
        boost::asio::const_buffer const buffer = *it;

        std::string body(boost::asio::buffer_cast<const char*>(buffer));
        std::cout << "Buffer#" << ++body_count << " = " << body << std::endl;
      }
    }

Создает следующий вывод:

Fields:
Field#1 : Host = localhost:8080
Field#2 : User-Agent = curl/7.58.0
Field#3 : Accept = */*
Field#4 : Content-Length = 218
Field#5 : Content-Type = multipart/form-data; boundary=------------------------5510ea3ec81b8585
Body:
Buffer#1 = --------------------------5510ea3ec81b8585
Content-Disposition: form-data; name="test"; filename="foobar.dat"
Content-Type: application/octet-stream

This is a test!

--------------------------5510ea3ec81b8585--

Большинство примеров, которые я нашел, демонстрируют, как создавать ответы и запросы, используя Boost Beast, но я не могу найти каких-либо четких примеров того, что нужно делать для анализа содержимого и разделения различных компонентов сообщения.

В частности, как использовать Boost Beast для извлечения и разделения имени («test»), имени файла («foobar.dat») и содержимого файла («Это тест!») Из тело для дальнейшей обработки сообщения? Или в этот момент необходимо самому анализировать данные в теле сообщения?

...