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 <QGrpcHttp2Channel>
#include <QGrpcUserPasswordCredentials>
#include <QDebug>
#include <QFile>

View File

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

View File

@ -27,6 +27,7 @@ public:
std::optional<std::chrono::milliseconds> deadline;
std::shared_ptr<QGrpcCallCredentials> credentials;
std::optional<qint64> maxRetryAttempts;
QGrpcMetadata metadata;
};
/*!
@ -87,6 +88,15 @@ QGrpcCallOptions &QGrpcCallOptions::withMaxRetryAttempts(qint64 maxRetryAttempts
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.
@ -117,4 +127,14 @@ std::optional<qint64> QGrpcCallOptions::maxRetryAttempts() const
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

View File

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

View File

@ -27,6 +27,7 @@ public:
std::optional<std::chrono::milliseconds> deadline;
std::shared_ptr<QGrpcChannelCredentials> credentials;
std::optional<QStringList> credentialList;
QGrpcMetadata metadata;
#if QT_CONFIG(ssl)
std::optional<QSslConfiguration> sslConfiguration;
#endif
@ -100,6 +101,15 @@ QGrpcChannelOptions &QGrpcChannelOptions::withCredentialList(const QStringList &
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.
@ -140,6 +150,16 @@ std::optional<QStringList> QGrpcChannelOptions::credentialList() const
}
#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.
*/

View File

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

View File

@ -86,6 +86,19 @@ constexpr char GrpcStatusHeader[] = "grpc-status";
constexpr char GrpcStatusMessageHeader[] = "grpc-message";
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 ExpectedData
@ -121,6 +134,8 @@ struct QGrpcHttp2ChannelPrivate
for (const auto &[key, value] : credentials->toStdMap())
request.setRawHeader(key, value.toString().toUtf8());
}
addMetadataToRequest(&request, channelOptions.metadata(), callOptions.metadata());
request.setAttribute(QNetworkRequest::Http2DirectAttribute, true);
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