diff --git a/src/grpc/qgrpccalloptions.cpp b/src/grpc/qgrpccalloptions.cpp index 4d5c7975..6640a3cb 100644 --- a/src/grpc/qgrpccalloptions.cpp +++ b/src/grpc/qgrpccalloptions.cpp @@ -262,13 +262,13 @@ QGrpcCallOptions::setMetadata(std::initializer_listmetadata(QtGrpc::MultiValue).contains(key, value)) + if (d_ptr->containsMetadata(key, value)) return *this; d_ptr.detach(); Q_D(QGrpcCallOptions); - d->addMetadata(std::move(key), std::move(value)); + d->addMetadata(key.toByteArray(), value.toByteArray()); return *this; } diff --git a/src/grpc/qgrpccalloptions.h b/src/grpc/qgrpccalloptions.h index 7dc072c6..61222fc1 100644 --- a/src/grpc/qgrpccalloptions.h +++ b/src/grpc/qgrpccalloptions.h @@ -62,7 +62,7 @@ public: Q_GRPC_EXPORT QGrpcCallOptions &setMetadata(QMultiHash &&metadata); Q_GRPC_EXPORT QGrpcCallOptions & setMetadata(std::initializer_list> list); - Q_GRPC_EXPORT QGrpcCallOptions &addMetadata(QByteArray key, QByteArray value); + Q_GRPC_EXPORT QGrpcCallOptions &addMetadata(QByteArrayView key, QByteArrayView value); private: QExplicitlySharedDataPointer d_ptr; diff --git a/src/grpc/qgrpcchanneloptions.cpp b/src/grpc/qgrpcchanneloptions.cpp index 79c5592c..e29f5ca7 100644 --- a/src/grpc/qgrpcchanneloptions.cpp +++ b/src/grpc/qgrpcchanneloptions.cpp @@ -271,13 +271,13 @@ QGrpcChannelOptions::setMetadata(std::initializer_listmetadata(QtGrpc::MultiValue).contains(key, value)) + if (d_ptr->containsMetadata(key, value)) return *this; d_ptr.detach(); Q_D(QGrpcChannelOptions); - d->addMetadata(std::move(key), std::move(value)); + d->addMetadata(key.toByteArray(), value.toByteArray()); return *this; } diff --git a/src/grpc/qgrpcchanneloptions.h b/src/grpc/qgrpcchanneloptions.h index 459345b0..c69d9ce6 100644 --- a/src/grpc/qgrpcchanneloptions.h +++ b/src/grpc/qgrpcchanneloptions.h @@ -68,7 +68,7 @@ public: Q_GRPC_EXPORT QGrpcChannelOptions &setMetadata(QMultiHash &&metadata); Q_GRPC_EXPORT QGrpcChannelOptions & setMetadata(std::initializer_list> list); - Q_GRPC_EXPORT QGrpcChannelOptions &addMetadata(QByteArray key, QByteArray value); + Q_GRPC_EXPORT QGrpcChannelOptions &addMetadata(QByteArrayView key, QByteArrayView value); [[nodiscard]] Q_GRPC_EXPORT QGrpcSerializationFormat serializationFormat() const; Q_GRPC_EXPORT QGrpcChannelOptions & diff --git a/src/grpc/qgrpccommonoptions.cpp b/src/grpc/qgrpccommonoptions.cpp index 1694390c..2d75e20e 100644 --- a/src/grpc/qgrpccommonoptions.cpp +++ b/src/grpc/qgrpccommonoptions.cpp @@ -165,4 +165,11 @@ void QGrpcCommonOptions::addMetadata(QByteArray &&key, QByteArray &&value) m_metadataMulti.emplace(std::move(key), std::move(value)); } +bool QGrpcCommonOptions::containsMetadata(QByteArrayView key, QByteArrayView value) const +{ + const auto &md = metadata(QtGrpc::MultiValue); + auto [f, l] = md.equal_range(key); + return std::find(f, l, value) != l; +} + QT_END_NAMESPACE diff --git a/src/grpc/qgrpccommonoptions_p.h b/src/grpc/qgrpccommonoptions_p.h index b53c3f92..ff91aff3 100644 --- a/src/grpc/qgrpccommonoptions_p.h +++ b/src/grpc/qgrpccommonoptions_p.h @@ -47,6 +47,7 @@ public: void setMetadata(const QMultiHash &md); void setMetadata(QMultiHash &&md); void addMetadata(QByteArray &&key, QByteArray &&value); + bool containsMetadata(QByteArrayView key, QByteArrayView value) const; private: std::optional m_timeout; diff --git a/tests/auto/grpc/shared/grpccommonoptions.h b/tests/auto/grpc/shared/grpccommonoptions.h index beac6b56..de176246 100644 --- a/tests/auto/grpc/shared/grpccommonoptions.h +++ b/tests/auto/grpc/shared/grpccommonoptions.h @@ -216,6 +216,10 @@ QT_WARNING_POP auto o5Detach = o5; QByteArray k = "keyB", v = "valB"; o5.addMetadata(k, v); + // Check that exact key-value pairs are discarded no matter the order. + o5.addMetadata("keyA", "valA1"); + o5.addMetadata("keyA", "valA2"); + o5.addMetadata("keyB", "valB"); QCOMPARE_EQ(o5.metadata(QtGrpc::MultiValue), data); QCOMPARE_NE(o5.metadata(QtGrpc::MultiValue), o5Detach.metadata(QtGrpc::MultiValue)); }