QGrpc{Call,Channel}Options: add 'filterServerMetadata'

This option enables to control the filtering of the received server
metadata. Both options provide it as optional<bool>, so that
QAbstractGrpcChannel implementations should choose a reasonable default.

This has not been provided to the QQml*Options, as there is currently no
available API to access the server metadata.

[ChangeLog][QGrpc{Call,Channel}Options] Added the filterServerMetadata
property.

Task-number: QTBUG-138363
Change-Id: I325a3b4f6e68d63f0828a6deb1a7be883247614b
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
Dennis Oberst 2025-07-08 15:21:24 +02:00
parent 7695e0fc90
commit 25782e8866
9 changed files with 108 additions and 0 deletions

View File

@ -272,6 +272,33 @@ QGrpcCallOptions &QGrpcCallOptions::addMetadata(QByteArrayView key, QByteArrayVi
return *this;
}
/*!
\include qgrpccommonoptions.cpp filterServerMetadata
\sa QGrpcChannelOptions::filterServerMetadata()
*/
std::optional<bool> QGrpcCallOptions::filterServerMetadata() const noexcept
{
Q_D(const QGrpcCallOptions);
return d->filterServerMetadata();
}
/*!
\include qgrpccommonoptions.cpp setFilterServerMetadata
\note Setting this field \b{overrides} the corresponding channel options
field see \l{QGrpcChannelOptions::setFilterServerMetadata()}
\sa QGrpcChannelOptions::setFilterServerMetadata()
*/
QGrpcCallOptions &QGrpcCallOptions::setFilterServerMetadata(bool value)
{
if (d_ptr->filterServerMetadata() == value)
return *this;
d_ptr.detach();
Q_D(QGrpcCallOptions);
d->setFilterServerMetadata(value);
return *this;
}
#ifndef QT_NO_DEBUG_STREAM
/*!
\since 6.8

View File

@ -64,6 +64,9 @@ public:
setMetadata(std::initializer_list<std::pair<QByteArray, QByteArray>> list);
Q_GRPC_EXPORT QGrpcCallOptions &addMetadata(QByteArrayView key, QByteArrayView value);
[[nodiscard]] Q_GRPC_EXPORT std::optional<bool> filterServerMetadata() const noexcept;
Q_GRPC_EXPORT QGrpcCallOptions &setFilterServerMetadata(bool value);
private:
QExplicitlySharedDataPointer<QGrpcCallOptionsPrivate> d_ptr;

View File

@ -281,6 +281,34 @@ QGrpcChannelOptions &QGrpcChannelOptions::addMetadata(QByteArrayView key, QByteA
return *this;
}
/*!
\include qgrpccommonoptions.cpp filterServerMetadata
\sa QGrpcCallOptions::filterServerMetadata()
*/
std::optional<bool> QGrpcChannelOptions::filterServerMetadata() const noexcept
{
Q_D(const QGrpcChannelOptions);
return d->filterServerMetadata();
}
/*!
\include qgrpccommonoptions.cpp setFilterServerMetadata
\include qgrpcchanneloptions.cpp channel-note
\l{QGrpcCallOptions::filterServerMetadata}
\sa QGrpcCallOptions::setFilterServerMetadata()
*/
QGrpcChannelOptions &QGrpcChannelOptions::setFilterServerMetadata(bool value)
{
if (filterServerMetadata() == value)
return *this;
d_ptr.detach();
Q_D(QGrpcChannelOptions);
d->setFilterServerMetadata(value);
return *this;
}
/*!
\since 6.8

View File

@ -70,6 +70,9 @@ public:
setMetadata(std::initializer_list<std::pair<QByteArray, QByteArray>> list);
Q_GRPC_EXPORT QGrpcChannelOptions &addMetadata(QByteArrayView key, QByteArrayView value);
[[nodiscard]] Q_GRPC_EXPORT std::optional<bool> filterServerMetadata() const noexcept;
Q_GRPC_EXPORT QGrpcChannelOptions &setFilterServerMetadata(bool value);
[[nodiscard]] Q_GRPC_EXPORT QGrpcSerializationFormat serializationFormat() const;
Q_GRPC_EXPORT QGrpcChannelOptions &
setSerializationFormat(const QGrpcSerializationFormat &format);

View File

@ -161,4 +161,36 @@ bool QGrpcCommonOptions::containsMetadata(QByteArrayView key, QByteArrayView val
return std::find(f, l, value) != l;
}
/*!
//! [filterServerMetadata]
\since 6.11
Returns \c true if protocol-related server metadata is excluded from the
result. Returns \c false to include all metadata received from the server.
If this field is unset, returns an empty \c {std::optional}.
\sa setFilterServerMetadata()
//! [filterServerMetadata]
*/
std::optional<bool> QGrpcCommonOptions::filterServerMetadata() const noexcept
{
return m_filterServerMetadata;
}
/*!
//! [setFilterServerMetadata]
\since 6.11
If \a value is \c true, protocol-related metadata defined by the gRPC
transport (such as reserved \c{grpc-} keys) will be excluded. If \a value
is \c false, all metadata received from the server will be included.
\sa filterServerMetadata()
*/
void QGrpcCommonOptions::setFilterServerMetadata(bool value)
{
m_filterServerMetadata = value;
}
QT_END_NAMESPACE

View File

@ -50,12 +50,16 @@ public:
void addMetadata(QByteArray &&key, QByteArray &&value);
bool containsMetadata(QByteArrayView key, QByteArrayView value) const;
std::optional<bool> filterServerMetadata() const noexcept;
void setFilterServerMetadata(bool value);
private:
std::optional<std::chrono::milliseconds> m_timeout;
QMultiHash<QByteArray, QByteArray> m_metadata;
#if QT_DEPRECATED_SINCE(6, 13)
QHash<QByteArray, QByteArray> m_deprecatedMetadata;
#endif
std::optional<bool> m_filterServerMetadata;
};
namespace QtGrpcPrivate {

View File

@ -21,6 +21,7 @@ private Q_SLOTS:
#endif
void propertyMetadata() const { common.propertyMetadata(); }
void propertyDeadline() const { common.propertyDeadline(); }
void propertyFilterServerMetadata() const { common.propertyFilterServerMetadata(); }
void streamsToDebug() const { common.streamsToDebug(); }
private:

View File

@ -24,6 +24,7 @@ private Q_SLOTS:
#endif
void propertyMetadata() const { common.propertyMetadata(); }
void propertyDeadline() const { common.propertyDeadline(); }
void propertyFilterServerMetadata() const { common.propertyFilterServerMetadata(); }
void streamsToDebug() const { common.streamsToDebug(); }
void propertySerializationFormat() const;

View File

@ -231,6 +231,15 @@ QT_WARNING_POP
QCOMPARE_EQ(o1.deadlineTimeout(), Dur);
QCOMPARE_NE(o1.deadlineTimeout(), o1Detach.deadlineTimeout());
}
void propertyFilterServerMetadata() const
{
T o1;
QCOMPARE_EQ(o1.filterServerMetadata(), std::nullopt);
auto o1Detach = o1;
o1.setFilterServerMetadata(true);
QCOMPARE_NE(o1.filterServerMetadata(), o1Detach.filterServerMetadata());
QCOMPARE_EQ(o1.filterServerMetadata(), std::optional<bool>(true));
}
void streamsToDebug() const
{
T o;