环境qt 5.12.8
开发资料
请求签名 :对象存储 请求签名-API 文档-文档中心-腾讯云
公共请求头部:对象存储 请求签名-API 文档-文档中心-腾讯云
测试api签名工具:COS工具集
需要使用到Object接口的get接口从存储桶下载内容、put接口上传内容到存储桶指定位置;Bucket接口的get接口获取桶中指定目录的子文件列表。
参考泉哥的文档,上传和下载内容测试通过
获取子文件列表用上面的方法不行,根据腾讯云的api文档,参考案例四。分析发现,需要提供参数列表,这个列表在前面的object接口的测试中没有使用到。
根据案例,需要在request中设置setRawHeader的Host和Date,以及要给url设置setQuery(就是参数prefix和delimiter)
根据腾讯的测试文档,发现httppatarmeters和httpheader的组成形式是:key值用小写、value值要转成urlencode,直接调用qt的函数QUrl::toPercentEncoding()。
paramters的值如下

header也是是同理,也就是说如下一个是httpparamters,一个是httpheader。前面的计算根据文档,分为一下几步,按照这个步骤来,但是!!!注意哈希算法不一定是用一个。
Sha1-hash可以用qt自带的QCryptographicHash::hash(HttpString.toLocal8Bit(), QCryptographicHash::Sha1).toHex(),但是hmac-sha1我用gtp写的,两个不一样哈。

cpp
bool DataHandle::getListFromCos(const QString relativePath)
{
QNetworkAccessManager *manager = new QNetworkAccessManager();
QString bucketName = "************"; // Bucket 名称
QString prefix = relativePath; // 前缀 ------------ 就是要获取的目前
QString secretId = "****************************"; // SecretId
QString secretKey = "****************************"; //SecretKey
// 构造请求 URL
QString endpoint = QString("https://%1.cos.ap-*****.myqcloud.com").arg(bucketName);
QUrl url(endpoint+"/");
// 构造查询参数
QMap<QString, QString> params;
params.insert("prefix",prefix);//删选以prefix开头的对象
params.insert("delimiter", "/");//以/作为分割
QMap<QString,QString>paramsMap;
for(int j=0; j<params.size(); ++j){
auto key = params.keys().at(j);
paramsMap.insert( key.toLower(),QUrl::toPercentEncoding(params.value(key)));
}
QUrlQuery urlQuery;
for (auto it = params.begin(); it != params.end(); ++it) {
urlQuery.addQueryItem(it.key(), it.value());
}
url.setQuery(urlQuery);
// 构造请求头
QString date = QDateTime::currentDateTimeUtc().toString("ddd, dd MMM yyyy HH:mm:ss") + " GMT";
QNetworkRequest request;
request.setUrl(url);
request.setRawHeader("Host", "scripts-1304552240.cos.ap-shanghai.myqcloud.com");
request.setRawHeader("Date", date.toLocal8Bit()/*"Thu, 06 Mar 2025 07:33:28 GMT"*/);
// 计算 KeyTime
QDateTime startDateTime = QDateTime::currentDateTime();
QDateTime endDateTime = startDateTime.addSecs(3600);
quint64 startTimeS = startDateTime.toSecsSinceEpoch();
quint64 endTimeS = endDateTime.toSecsSinceEpoch();
QString KeyTime = QString("%1;%2").arg(startTimeS).arg(endTimeS);
// qDebug()<<"KeyTime: "<<KeyTime;
// 计算 SignKey
QByteArray SignKey = hmacSha1(secretKey.toLocal8Bit(),KeyTime.toLocal8Bit()).toHex();
// qDebug()<<"SignKey: "<<SignKey;
//合成头列表
QMap<QString,QString>headMap;
for(int i=0; i<request.rawHeaderList().size(); ++i){
auto key = request.rawHeaderList().at(i);
headMap.insert( key.toLower(),QUrl::toPercentEncoding(request.rawHeader(key)));
}
QStringList headerKeys = headMap.keys();
std::sort(headerKeys.begin(), headerKeys.end()); // 确保按字典序排序
QByteArray HeaderList = QString(headMap.keys().join(";")).toLocal8Bit();
QByteArray HttpHeaders;
for(int i=0; i<headMap.size(); ++i){
auto key = headMap.keys().at(i);
HttpHeaders.append(key.toLocal8Bit());
HttpHeaders.append('=');
HttpHeaders.append(headMap.value(key).toLocal8Bit());
if(i != headMap.keys().size() -1)
HttpHeaders.append('&');
}
//合成参数列表
QByteArray UrlParamList = QString(paramsMap.keys().join(";")).toLocal8Bit();
QByteArray HttpParamsHeaders = QByteArray();
for(int i=0; i<paramsMap.size(); ++i){
auto key = paramsMap.keys().at(i);
HttpParamsHeaders.append(key.toLocal8Bit());
HttpParamsHeaders.append('=');
HttpParamsHeaders.append(paramsMap.value(key).toLocal8Bit());
if(i != paramsMap.keys().size() -1)
HttpParamsHeaders.append('&');
}
// qDebug()<<"HttpHeaders : "<<HttpHeaders;
// qDebug()<<"HttpParamsHeaders : "<<HttpParamsHeaders;
// 构造 StringToSign
QString HttpURI = QString("/");
QString HttpString = QString("get\n"+HttpURI+"\n"+HttpParamsHeaders+"\n"+HttpHeaders+"\n");
// qDebug()<<" HttpString :"<<HttpString;
QByteArray httpStringSha1 = QCryptographicHash::hash(HttpString.toLocal8Bit(), QCryptographicHash::Sha1).toHex();
QByteArray StringToSign = QString("sha1\n"+KeyTime+"\n"+httpStringSha1+"\n").toLocal8Bit();
// 计算 Signature
QByteArray Signature = hmacSha1(SignKey,StringToSign).toHex();
// qDebug()<<" StringToSign :"<<StringToSign;
// qDebug()<<" Signature :"<<Signature;
// 构造 Authorization 头
QString authorization = QString("q-sign-algorithm=sha1"
"&q-ak="+secretId+
"&q-sign-time="+KeyTime+
"&q-key-time="+KeyTime+
"&q-header-list="+QString(HeaderList)+
"&q-url-param-list="+QString(UrlParamList)+
"&q-signature=")+QString(Signature);
// qDebug()<<" authorization :"<<authorization;
// 构造 QNetworkRequest
request.setRawHeader("Authorization", authorization.toLocal8Bit());
// 发送请求
QNetworkReply *reply = manager->get(request);
qDebug()<<__FUNCTION__<<__LINE__;
// 处理响应
QObject::connect(reply, &QNetworkReply::finished, [=]() {
qDebug()<<__FUNCTION__<<__LINE__;
if (reply->error() == QNetworkReply::NoError) {
QByteArray responseData = reply->readAll();
qDebug() << "Response:" << responseData;
} else {
qDebug() << "Error:" << reply->errorString();
}
reply->deleteLater();
});
return true;
}
【注意】在linux下一定要记得加函数返回值return,不然肯能会有崩溃。