Introduce QGrpcMetadata

Introduce alias to std::multimap names QGrpcMetadata, to represent
additional HTTP headers, that can be added to channel and call options.
Then channel implementations can use QGrpcMetadata and append all
metadata do each call (TODO).

Task-number: QTBUG-111037
Change-Id: Ie16e658407a57a5f44bc1a0ff54dcb3ca8b06fe1
Reviewed-by: Alexey Edelev <alexey.edelev@qt.io>
This commit is contained in:
Konrad Kujawa 2023-05-12 13:50:30 +02:00
parent 9592fb0caa
commit 4235684288
8 changed files with 79 additions and 1 deletions

View File

@ -5,7 +5,6 @@
#include "simplechatengine.h" #include "simplechatengine.h"
#include <QGrpcHttp2Channel> #include <QGrpcHttp2Channel>
#include <QGrpcUserPasswordCredentials>
#include <QDebug> #include <QDebug>
#include <QFile> #include <QFile>

View File

@ -14,6 +14,7 @@ qt_internal_add_module(Grpc
qgrpcuserpasswordcredentials.h qgrpcuserpasswordcredentials.cpp qgrpcuserpasswordcredentials.h qgrpcuserpasswordcredentials.cpp
qgrpccalloptions.h qgrpccalloptions.cpp qgrpccalloptions.h qgrpccalloptions.cpp
qgrpcchanneloptions.h qgrpcchanneloptions.cpp qgrpcchanneloptions.h qgrpcchanneloptions.cpp
qgrpcmetadata.h
qtgrpcglobal.h qtgrpcglobal_p.h qtgrpcglobal.cpp qtgrpcglobal.h qtgrpcglobal_p.h qtgrpcglobal.cpp
GENERATE_CPP_EXPORTS GENERATE_CPP_EXPORTS
LIBRARIES LIBRARIES

View File

@ -27,6 +27,7 @@ public:
std::optional<std::chrono::milliseconds> deadline; std::optional<std::chrono::milliseconds> deadline;
std::shared_ptr<QGrpcCallCredentials> credentials; std::shared_ptr<QGrpcCallCredentials> credentials;
std::optional<qint64> maxRetryAttempts; std::optional<qint64> maxRetryAttempts;
QGrpcMetadata metadata;
}; };
/*! /*!
@ -87,6 +88,15 @@ QGrpcCallOptions &QGrpcCallOptions::withMaxRetryAttempts(qint64 maxRetryAttempts
return *this; return *this;
} }
/*!
Sets \a metadata for a call and returns updated QGrpcCallOptions object.
*/
QGrpcCallOptions &QGrpcCallOptions::withMetadata(const QGrpcMetadata &metadata)
{
dPtr->metadata = metadata;
return *this;
}
/*! /*!
Returns deadline value for a call. Returns deadline value for a call.
@ -117,4 +127,14 @@ std::optional<qint64> QGrpcCallOptions::maxRetryAttempts() const
return dPtr->maxRetryAttempts; return dPtr->maxRetryAttempts;
} }
/*!
Returns metadata used for a call.
If value was not set returns empty QGrpcMetadata.
*/
QGrpcMetadata QGrpcCallOptions::metadata() const
{
return dPtr->metadata;
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -6,6 +6,7 @@
#include <QtCore/QUrl> #include <QtCore/QUrl>
#include <QtGrpc/QGrpcCallCredentials> #include <QtGrpc/QGrpcCallCredentials>
#include <QtGrpc/qgrpcmetadata.h>
#include <QtGrpc/qtgrpcglobal.h> #include <QtGrpc/qtgrpcglobal.h>
#include <chrono> #include <chrono>
@ -28,10 +29,12 @@ public:
QGrpcCallOptions &withDeadline(std::chrono::milliseconds deadline); QGrpcCallOptions &withDeadline(std::chrono::milliseconds deadline);
QGrpcCallOptions &withCredentials(std::shared_ptr<QGrpcCallCredentials> credentials); QGrpcCallOptions &withCredentials(std::shared_ptr<QGrpcCallCredentials> credentials);
QGrpcCallOptions &withMaxRetryAttempts(qint64 maxRetryAttempts); QGrpcCallOptions &withMaxRetryAttempts(qint64 maxRetryAttempts);
QGrpcCallOptions &withMetadata(const QGrpcMetadata &metadata);
std::optional<std::chrono::milliseconds> deadline() const; std::optional<std::chrono::milliseconds> deadline() const;
std::optional<QGrpcCredentialMap> credentials() const; std::optional<QGrpcCredentialMap> credentials() const;
std::optional<qint64> maxRetryAttempts() const; std::optional<qint64> maxRetryAttempts() const;
QGrpcMetadata metadata() const;
private: private:
std::unique_ptr<QGrpcCallOptionsPrivate> dPtr; std::unique_ptr<QGrpcCallOptionsPrivate> dPtr;

View File

@ -27,6 +27,7 @@ public:
std::optional<std::chrono::milliseconds> deadline; std::optional<std::chrono::milliseconds> deadline;
std::shared_ptr<QGrpcChannelCredentials> credentials; std::shared_ptr<QGrpcChannelCredentials> credentials;
std::optional<QStringList> credentialList; std::optional<QStringList> credentialList;
QGrpcMetadata metadata;
#if QT_CONFIG(ssl) #if QT_CONFIG(ssl)
std::optional<QSslConfiguration> sslConfiguration; std::optional<QSslConfiguration> sslConfiguration;
#endif #endif
@ -100,6 +101,15 @@ QGrpcChannelOptions &QGrpcChannelOptions::withCredentialList(const QStringList &
return *this; return *this;
} }
/*!
Sets \a metadata for a call and returns updated QGrpcCallOptions object.
*/
QGrpcChannelOptions &QGrpcChannelOptions::withMetadata(const QGrpcMetadata &metadata)
{
dPtr->metadata = metadata;
return *this;
}
/*! /*!
Returns deadline value for every call on the channel. Returns deadline value for every call on the channel.
@ -140,6 +150,16 @@ std::optional<QStringList> QGrpcChannelOptions::credentialList() const
} }
#if QT_CONFIG(ssl) #if QT_CONFIG(ssl)
/*!
Returns metadata used for a call.
If value was not set returns empty QGrpcMetadata.
*/
QGrpcMetadata QGrpcChannelOptions::metadata() const
{
return dPtr->metadata;
}
/*! /*!
Sets SSL configuration with \a sslConfiguration and returns updated QGrpcChannelOptions object. Sets SSL configuration with \a sslConfiguration and returns updated QGrpcChannelOptions object.
*/ */

View File

@ -6,6 +6,7 @@
#include <QtCore/QUrl> #include <QtCore/QUrl>
#include <QtGrpc/QGrpcChannelCredentials> #include <QtGrpc/QGrpcChannelCredentials>
#include <QtGrpc/qgrpcmetadata.h>
#include <QtGrpc/qtgrpcglobal.h> #include <QtGrpc/qtgrpcglobal.h>
#if QT_CONFIG(ssl) #if QT_CONFIG(ssl)
@ -34,11 +35,13 @@ public:
QGrpcChannelOptions &withDeadline(std::chrono::milliseconds deadline); QGrpcChannelOptions &withDeadline(std::chrono::milliseconds deadline);
QGrpcChannelOptions &withCredentials(std::shared_ptr<QGrpcChannelCredentials> credentials); QGrpcChannelOptions &withCredentials(std::shared_ptr<QGrpcChannelCredentials> credentials);
QGrpcChannelOptions &withCredentialList(const QStringList &credentialList); QGrpcChannelOptions &withCredentialList(const QStringList &credentialList);
QGrpcChannelOptions &withMetadata(const QGrpcMetadata &metadata);
QUrl host() const; QUrl host() const;
std::optional<std::chrono::milliseconds> deadline() const; std::optional<std::chrono::milliseconds> deadline() const;
std::optional<QGrpcCredentialMap> credentials() const; std::optional<QGrpcCredentialMap> credentials() const;
std::optional<QStringList> credentialList() const; std::optional<QStringList> credentialList() const;
QGrpcMetadata metadata() const;
#if QT_CONFIG(ssl) #if QT_CONFIG(ssl)
QGrpcChannelOptions &withSslConfiguration(const QSslConfiguration &sslConfiguration); QGrpcChannelOptions &withSslConfiguration(const QSslConfiguration &sslConfiguration);

View File

@ -86,6 +86,19 @@ constexpr char GrpcStatusHeader[] = "grpc-status";
constexpr char GrpcStatusMessageHeader[] = "grpc-message"; constexpr char GrpcStatusMessageHeader[] = "grpc-message";
constexpr qsizetype GrpcMessageSizeHeaderSize = 5; constexpr qsizetype GrpcMessageSizeHeaderSize = 5;
static void addMetadataToRequest(QNetworkRequest *request, const QGrpcMetadata &channelMetadata,
const QGrpcMetadata &callMetadata)
{
auto iterateMetadata = [&request](const auto &metadata) {
for (const auto &[key, value] : std::as_const(metadata)) {
request->setRawHeader(key, value);
}
};
iterateMetadata(channelMetadata);
iterateMetadata(callMetadata);
}
struct QGrpcHttp2ChannelPrivate struct QGrpcHttp2ChannelPrivate
{ {
struct ExpectedData struct ExpectedData
@ -121,6 +134,8 @@ struct QGrpcHttp2ChannelPrivate
for (const auto &[key, value] : credentials->toStdMap()) for (const auto &[key, value] : credentials->toStdMap())
request.setRawHeader(key, value.toString().toUtf8()); request.setRawHeader(key, value.toString().toUtf8());
} }
addMetadataToRequest(&request, channelOptions.metadata(), callOptions.metadata());
request.setAttribute(QNetworkRequest::Http2DirectAttribute, true); request.setAttribute(QNetworkRequest::Http2DirectAttribute, true);
QByteArray msg(GrpcMessageSizeHeaderSize, '\0'); QByteArray msg(GrpcMessageSizeHeaderSize, '\0');

17
src/grpc/qgrpcmetadata.h Normal file
View File

@ -0,0 +1,17 @@
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
#ifndef QGRPCMETADATA_H
#define QGRPCMETADATA_H
#include <QtGrpc/qtgrpcglobal.h>
#include <unordered_map>
QT_BEGIN_NAMESPACE
using QGrpcMetadata = std::unordered_multimap<QByteArray, QByteArray>;
QT_END_NAMESPACE
#endif // QGRPCMETADATA_H