From 46bce56bfb1e98033c4fe954a3be2f8b661e00c0 Mon Sep 17 00:00:00 2001 From: Dennis Oberst Date: Fri, 18 Jul 2025 16:13:31 +0200 Subject: [PATCH] Http2Handler: construct initial headers in initialization list This patch follows C++ best practices. Refactor the 'prepareInitialRequest' function to directly return the constructed headers so that we can use them in the initializer list. Ref: https://isocpp.org/wiki/faq/ctors#init-lists Pick-to: 6.10 6.9 6.8 Change-Id: I095d9ecc3574b8ad1ed344d16701102d2c79df92 Reviewed-by: Alexey Edelev --- src/grpc/qgrpchttp2channel.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/grpc/qgrpchttp2channel.cpp b/src/grpc/qgrpchttp2channel.cpp index d3382ae7..2043205e 100644 --- a/src/grpc/qgrpchttp2channel.cpp +++ b/src/grpc/qgrpchttp2channel.cpp @@ -271,13 +271,12 @@ public: void deadlineTimeout(); private: - void prepareInitialRequest(QGrpcOperationContext *operationContext, - QGrpcHttp2ChannelPrivate *channel); + [[nodiscard]] HPack::HttpHeader constructInitialHeaders() const; [[nodiscard]] QGrpcHttp2ChannelPrivate *channelPriv() const; [[nodiscard]] QGrpcHttp2Channel *channel() const; - HPack::HttpHeader m_initialHeaders; std::weak_ptr m_operation; + HPack::HttpHeader m_initialHeaders; QQueue m_queue; QPointer m_stream; ExpectedData m_expectedData; @@ -378,7 +377,8 @@ private: Http2Handler::Http2Handler(const std::shared_ptr &operation, QGrpcHttp2ChannelPrivate *parent, bool endStream) - : QObject(parent), m_operation(operation), m_endStreamAtFirstData(endStream) + : QObject(parent), m_operation(operation), m_initialHeaders(constructInitialHeaders()), + m_endStreamAtFirstData(endStream) { auto *channelOpPtr = operation.get(); QObject::connect(channelOpPtr, &QGrpcOperationContext::cancelRequested, this, @@ -391,7 +391,8 @@ Http2Handler::Http2Handler(const std::shared_ptr &operati } QObject::connect(channelOpPtr, &QGrpcOperationContext::finished, &m_deadlineTimer, &QTimer::stop); - prepareInitialRequest(channelOpPtr, parent); + + writeMessage(channelOpPtr->argument()); } Http2Handler::~Http2Handler() @@ -506,10 +507,9 @@ QGrpcOperationContext *Http2Handler::operation() const return m_operation.lock().get(); } -// Prepares the initial headers and enqueues the initial message. +// Builds HTTP/2 headers for the initial gRPC request. // The headers are sent once the HTTP/2 connection is established. -void Http2Handler::prepareInitialRequest(QGrpcOperationContext *operationContext, - QGrpcHttp2ChannelPrivate *channel) +HPack::HttpHeader Http2Handler::constructInitialHeaders() const { const static QByteArray AuthorityHeader(":authority"); const static QByteArray MethodHeader(":method"); @@ -527,10 +527,13 @@ void Http2Handler::prepareInitialRequest(QGrpcOperationContext *operationContext + QSysInfo::productType().toUtf8() + '/' + QSysInfo::productVersion().toUtf8() + ')'); - const auto &channelOptions = channel->q_ptr->channelOptions(); + const auto &channelOptions = channel()->channelOptions(); + const auto *operationContext = operation(); + const auto *channel = channelPriv(); + QByteArray service{ operationContext->service() }; QByteArray method{ operationContext->method() }; - m_initialHeaders = HPack::HttpHeader{ + auto headers = HPack::HttpHeader{ { AuthorityHeader, channel->authorityHeader() }, { MethodHeader, MethodValue }, { PathHeader, QByteArray('/' + service + '/' + method) }, @@ -542,21 +545,21 @@ void Http2Handler::prepareInitialRequest(QGrpcOperationContext *operationContext { TEHeader, TEValue }, }; - auto iterateMetadata = [this](const auto &metadata) { + auto iterateMetadata = [&headers](const auto &metadata) { for (const auto &[key, value] : metadata.asKeyValueRange()) { const auto lowerKey = key.toLower(); if (lowerKey == AuthorityHeader || lowerKey == MethodHeader || lowerKey == PathHeader || lowerKey == SchemeHeader || lowerKey == ContentTypeHeader) { continue; } - m_initialHeaders.emplace_back(lowerKey, value); + headers.emplace_back(lowerKey, value); } }; iterateMetadata(channelOptions.metadata(QtGrpc::MultiValue)); iterateMetadata(operationContext->callOptions().metadata(QtGrpc::MultiValue)); - writeMessage(operationContext->argument()); + return headers; } QGrpcHttp2ChannelPrivate *Http2Handler::channelPriv() const