【腾讯云】存储桶API

环境qt 5.12.8

开发资料

请求签名 :对象存储 请求签名-API 文档-文档中心-腾讯云

公共请求头部:对象存储 请求签名-API 文档-文档中心-腾讯云

测试api签名工具:COS工具集

需要使用到Object接口的get接口从存储桶下载内容、put接口上传内容到存储桶指定位置;Bucket接口的get接口获取桶中指定目录的子文件列表。

参考泉哥的文档,上传和下载内容测试通过

Qt腾讯云对象存储上传实现及问题解析-CSDN博客

获取子文件列表用上面的方法不行,根据腾讯云的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,不然肯能会有崩溃。

相关推荐
格发许可优化管理系统1 小时前
EB-Cable许可管理在云计算环境中的应用
云计算
AugustShuai3 小时前
阿里云Kafka分区清理
阿里云·kafka·云计算
PawSQL4 小时前
PawSQL for TDSQL:腾讯云TDSQL数据库性能优化全攻略
数据库·sql·性能优化·腾讯云·pawsql
渲染101专业云渲染15 小时前
安全保障:渲染101如何守护用户数据?
云计算·电脑·动画·blender·houdini
weixin_3077791318 小时前
PySpark实现导出两个包含多个Parquet数据文件的S3目录里的对应值的差异值分析
python·数据分析·spark·云计算
黑客KKKing18 小时前
云计算VS网络安全,应该怎么选?
网络·安全·web安全·云计算
kaede20 小时前
使用Yarn创建Grafana模板的完整指南
linux·云计算
黑石云1 天前
边缘计算的业务种类划分
云计算
m0_694845571 天前
使用服务器搭建开源问答平台Answer
linux·运维·服务器·游戏·开源·云计算