Boost Beast: как создать непоследовательный ответ с настраиваемым телом, если длина содержимого недоступна?

Я пытаюсь реализовать пользовательский тип тела, который будет содержать проанализированный объект дерева JSON. Задача кажется довольно естественной, но я не могу найти способ генерировать не фрагментированные HTTP-сообщения, содержащие JSON, используя Beast. У меня есть клиент / сервер REST, реализованный путем обертывания libmicrohttpd и libcurl, но я бы предпочел перейти на Boost Beast.

Проблема, насколько я понимаю, в том, что тип тела size(value_type const&) Метод получает ссылку на значение тела, которое нужно сериализовать (в моем случае это объект дерева JSON), но нет способа определить точную длину строкового JSON без его фактического преобразования в строку. Однако, если я удалю size() Метод, Зверь думает, что я прошу кодирование передачи по частям. Конечно, нет ничего плохого в кусочном кодировании как таковом, но для меня это может означать исправление некоторых сценариев автоматизации и мониторинга, не говоря уже об интеграционных тестах.

Я хотел бы назначить объект JSON сообщению, которое я готовлю, и затем Beast спросить писатель, не body::size() для размера полезной нагрузки. Это кажется мне логичным, поскольку фактическое тело HTTP-сообщения (сериализованный JSON) весьма отличается от живого объекта JSON в памяти, и это Тело :: писатель кто производит байты тела для передачи. Я ошибся?

Во всяком случае, вы думаете, есть отлично способ решить эту проблему?

Заранее спасибо за ваше время и усилия!

С Уважением,
Влад

2

Решение

Спасибо за добрые слова, и я очень рад, что система настройки кузова привлекла к себе внимание! Большая часть того, что вы написали в вопросе, правильная. Если вы хотите, чтобы Beast установил поле Content-Length при вызове message::prepare_payload то вы должны предоставить правильную реализацию в Body::size, BodyWriter не создается до момента сериализации. Наиболее естественным решением этой проблемы является недопущение Body::size и пусть Beast использует чанкованное Transfer-Encoding при сериализации вашего типа телосложения. Я также должен отметить, что когда вы сериализуете JSON, лучше, если вы будете делать это по очереди в авторе, а не конвертировать все это в строку. Это цель иметь объект записи, чтобы поддерживать промежуточное состояние и допускать последовательную сериализацию. В противном случае вы должны выделить память для всего сериализованного представления, что менее эффективно.

Обновить:

body::size() а также message::prepare_payload не предназначены для использования так, как вы хотите. Если я понимаю, что вы хотите сделать, то эта функция должна обработать это:

/** Prepare a message with a JSON payload.

This function accepts ownership of a message with a JSON body
and converts the JSON to string, returning a new message with
a string body. The Content-Length field is set on the new
message. All other fields are transferred over unmodified.
*/
template<
bool isRequest,
class Allocator>
message<
isRequest,
string_body,
basic_fields<Allocator>>
prepare(
message<
isRequest,
json_body,
basic_fields<Allocator>>&& m)
{
message<
isRequest,
string_body,
basic_fields<Allocator>> result{
std::move(m.base()),
json_to_string(m.body())};
result.prepare_payload();
return result;
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]