上云无忧 > 文档中心 > 百度智能云云数据库 TableStorage C++开发示例
云数据库 TableStorage
百度智能云云数据库 TableStorage C++开发示例

文档简介:
我们在写下边的示例代码时,为了简单清楚,便于理解,忽略了一些错误处理,用户基于以下示例开发的时候,可以自行补齐。 生成认证字符串: 在访问云数据库 TableStorage 时,每个访问都需要使用用户的AK/SK生成认证字符串来进行身份认证,参考百度智能云鉴权认证机制和百度智能云认证字符串生成代码示例。
*此产品及展示信息均由百度智能云官方提供。免费试用 咨询热线:400-826-7010,为您提供专业的售前咨询,让您快速了解云产品,助您轻松上云! 微信咨询
  免费试用、价格特惠

我们在写下边的示例代码时,为了简单清楚,便于理解,忽略了一些错误处理,用户基于以下示例开发的时候,可以自行补齐。

生成认证字符串

在访问云数据库 TableStorage 时,每个访问都需要使用用户的AK/SK生成认证字符串来进行身份认证,参考百度智能云鉴权认证机制和百度智能云认证字符串生成代码示例。

// 我们在这里定义了一个HttpRequest结构体,在后续的demo中我们会使用到此结构体
struct HttpRequest {
    HttpRequest() {
        // 只支持ContentType为json
        headers["Content-Type"] = "application/json";
    }
    std::string method;
    std::string path;
    std::map<std::string, std::string> headers;
    std::map<std::string, std::string> params;
    std::string body;
};

生成认证字符串的c++函数定义如下。

我们在这里定义了一个根据HttpRequest生成认证字符串的函数,实现见本页最下方的百度智能云认证字符串C++实现,其它语言的实现可参考百度智能云认证字符串生成代码示例。

std::string gen_authorization(const HttpRequest& request, int timestamp);

创建Instance

当用户开通云数据库 TableStorage 服务后,需要先创建一个instance。

create instance demo
void create_instance() {
    // 获取当前时间戳
    time_t timestamp = time(NULL);
    // 初始化HttpRequest
    HttpRequest http_request;
    // 方法为PUT表示创建资源
    http_request.method = "PUT";
    // 将创建名为ins_demo的instance
    http_request.path = "/v1/instance/ins_demo";
    // 注意Http请求中的x-bce-date与生成认证字符串的时间需一致
    http_request.headers["x-bce-date"] = utcfromtimestamp(timestamp);
    http_request.headers["Host"] = "bts.bd.baidubce.com";
    http_request.headers["Authorization"] = gen_authorization(http_request, timestamp);
 
    // 使用curl发送请求
    CURL* curl = curl_easy_init();
    struct curl_slist* curl_headers = NULL;
    // 填充header
    for (auto const& item : http_request.headers) {
        std::string header = item.first + ":" + item.second;
        curl_headers = curl_slist_append(curl_headers, header.c_str());
    }
    // 拼接Url
    std::string url("http://bts.bd.baidubce.com");
    url.append(http_request.path);
    // 设置Url
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    // 设置headers
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers);
    // 设置method
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, http_request.method.c_str());
    // 发送请求
    curl_easy_perform(curl);
    // 解析http返回码
    long http_code = -1;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    // 清理curl
    curl_easy_cleanup(curl);
}

创建Table

用户在创建好Instance后,就可以在Instance中创建表了,下边的示例是创建一张默认结构的表,如果用户对于表结构有特别需求,可参考API参考增加参数。

void create_table() {
    // 获取当前时间戳
    time_t timestamp = time(NULL);
    // 初始化HttpRequest
    HttpRequest http_request;
    // 方法为PUT表示创建资源
    http_request.method = "PUT";
    // 将在ins_demo中创建名为table_demo的table
    http_request.path = "/v1/instance/ins_demo/table/table_demo";
    // 注意Http请求中的x-bce-date与生成认证字符串的时间需一致
    http_request.headers["x-bce-date"] = utcfromtimestamp(timestamp);
    http_request.headers["Host"] = "bts.bd.baidubce.com";
    http_request.headers["Authorization"] = gen_authorization(http_request, timestamp);
 
    // 使用curl发送请求
    CURL* curl = curl_easy_init();
    struct curl_slist* curl_headers = NULL;
    // 填充header
    for (auto const& item : http_request.headers) {
        std::string header = item.first + ":" + item.second;
        curl_headers = curl_slist_append(curl_headers, header.c_str());
    }
    // 拼接Url
    std::string url("http://bts.bd.baidubce.com");
    url.append(http_request.path);
    // 设置Url
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    // 设置headers
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers);
    // 设置method
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, http_request.method.c_str());
    // 发送请求
    curl_easy_perform(curl);
    // 解析http返回码
    long http_code = -1;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    // 清理curl
    curl_easy_cleanup(curl);
}

向Table写入数据

用户创建好Table后,就可以向Table写入数据。

void insert() {
    // 获取当前时间戳
    time_t timestamp = time(NULL);
    // 初始化HttpRequest
    HttpRequest http_request;
    // 方法为PUT表示创建资源,即写入数据
    http_request.method = "PUT";
    // 将向ins_demo中的表table_demo中写入一行数据
    http_request.path = "/v1/instance/ins_demo/table/table_demo/row";
    // 拼接写入的数据,为json格式,并且数据要经过UrlEncode
    // 写入rowkey(主键)为"www.baidu.com/0"的两列数据:col1,值为"val1",col2,值为"val2"
    http_request.body =
        "{"
            "\"rowkey\":\"www.baidu.com%2F0\","
            "\"cells\":["
            "{"
                "\"column\":\"col1\","
                "\"value\":\"val1\""
            "},"
            "{"
                "\"column\":\"col2\","
                "\"value\":\"val2\""
            "}"
        "]}";
    // 注意Http请求中的x-bce-date与生成认证字符串的时间需一致
    http_request.headers["x-bce-date"] = utcfromtimestamp(timestamp);
    http_request.headers["Host"] = "bts.bd.baidubce.com";
    http_request.headers["Content-Length"] = std::to_string(http_request.body.size());
    http_request.headers["Authorization"] = gen_authorization(http_request, timestamp);
 
    // 使用curl发送请求
    CURL* curl = curl_easy_init();
    struct curl_slist* curl_headers = NULL;
    // 填充header
    for (auto const& item : http_request.headers) {
        std::string header = item.first + ":" + item.second;
        curl_headers = curl_slist_append(curl_headers, header.c_str());
    }
    // 拼接Url
    std::string url("http://bts.bd.baidubce.com");
    url.append(http_request.path);
    // 设置Url
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    // 设置headers
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers);
    // 设置method
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, http_request.method.c_str());
    // 设置body
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, http_request.body.c_str());
    // 发送请求
    curl_easy_perform(curl);
    // 解析http返回码
    long http_code = -1;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    // 清理curl
    curl_easy_cleanup(curl);
}

从Table读取数据

一般来说,读取数据时,用户需要解析所读取的内容,所以我们在读示例里增加了curl获取返回内容的代码。用户可以指定rowkey从Table中读取数据。

// curl回调方法,用于读出返回的content,即body内容
size_t content_data(void* buffer, size_t size, size_t nmemb, void* userp) {
    *((std::string*)userp) = *((std::string*)userp) +
                            std::string((const char*)buffer, size * nmemb);
    return size * nmemb;
}
// curl回调方法,用于读出返回的header
size_t header_data(void* buffer, size_t size, size_t nmemb, void* userp) {
    *((std::string*)userp) = *((std::string*)userp) +
                            std::string((const char*)buffer, size * nmemb);
    return size * nmemb;
}
 
void query() {
    // 获取当前时间戳
    time_t timestamp = time(NULL);
    // 初始化HttpRequest
    HttpRequest http_request;
    // 方法为GET表示获取资源
    http_request.method = "GET";
    // 将向ins_demo中的table_demo读取一条数据
    http_request.path = "/v1/instance/ins_demo/table/table_demo/row";
    // 拼接单条读请求,为json格式,并且数据要经过UrlEncode
    // 读取rowkey(主键)为"www.baidu.com/0"的两列数据:col1和col2
    // 如果需要读整行数据,则只需要设置rowkey即可
    http_request.body =
        "{"
            "\"rowkey\":\"www.baidu.com%2F0\","
            "\"cells\":["
            "{"
                "\"column\":\"col1\""
            "},"
            "{"
                "\"column\":\"col2\""
            "}"
        "]}";
    // 注意Http请求中的x-bce-date与生成认证字符串的时间需一致
    http_request.headers["x-bce-date"] = utcfromtimestamp(timestamp);
    http_request.headers["Host"] = "bts.bd.baidubce.com";
    http_request.headers["Content-Length"] = std::to_string(http_request.body.size());
    http_request.headers["Authorization"] = gen_authorization(http_request, timestamp);
 
    // 使用curl发送请求
    CURL* curl = curl_easy_init();
    struct curl_slist* curl_headers = NULL;
    // 填充header
    for (auto const& item : http_request.headers) {
        std::string header = item.first + ":" + item.second;
        curl_headers = curl_slist_append(curl_headers, header.c_str());
    }
    // 拼接Url
    std::string url("http://bts.bd.baidubce.com");
    url.append(http_request.path);
    // 设置Url
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    // 设置headers
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers);
    // 设置method
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, http_request.method.c_str());
    // 设置body
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, http_request.body.c_str());
    // 设置返回的header,content
    // 如果你不需要解析header和content,则不需要做此设置,返回的content也会直接打印到标准输出
    std::string header;
    std::string content;
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, content_data);
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &content);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &header);
    // 发送请求
    curl_easy_perform(curl);
    // 解析http返回码
    long http_code = -1;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    // 清理curl
    curl_easy_cleanup(curl);
    // 打印返回的header内容
    printf("query response header: %s.\n", header.c_str());
    // 打印返回的content内容,为json格式,具体可参考api文档
    // 如果你需要对返回的内容做下一步处理,可以将此content按json格式解析后作为后续使用
    printf("query result: %s.\n", content.c_str());
}

用户可以范围扫描数据。

// curl回调方法,用于读出返回的content,即body内容
size_t content_data(void* buffer, size_t size, size_t nmemb, void* userp) {
    *((std::string*)userp) = *((std::string*)userp) +
                            std::string((const char*)buffer, size * nmemb);
    return size * nmemb;
}
// curl回调方法,用于读出返回的header
size_t header_data(void* buffer, size_t size, size_t nmemb, void* userp) {
    *((std::string*)userp) = *((std::string*)userp) +
                            std::string((const char*)buffer, size * nmemb);
    return size * nmemb;
}
 
void scan() {
    // 获取当前时间戳
    time_t timestamp = time(NULL);
    // 初始化HttpRequest
    HttpRequest http_request;
    // 方法为GET表示获取资源
    http_request.method = "GET";
    // 将向ins_demo中的table_demo读取数据
    http_request.path = "/v1/instance/ins_demo/table/table_demo/rows";
    // 拼接范围读请求,为json格式,并且数据要经过UrlEncode
    // 读取rowkey(主键)范围为[www.baidu.com/0, www.baidu.com/9)数据,并且读取其中两列:col1和col2
    // 注意includeStart和includeStop为区间的开闭,本示例中,区间为前闭后开
    // limit为1表示只返回第一行这个区间内的数据
    // rowkey区间和其它参数,用户可以参考api文档,按需配置
    http_request.body =
        "{"
            "\"startRowkey\":\"www.baidu.com%2F0\","
            "\"includeStart\":true,"
            "\"stopRowkey\":\"www.baidu.com%2F9\","
            "\"includeStop\":false,"
            "\"selector\":["
            "{"
                "\"column\":\"col1\""
            "},"
            "{"
                "\"column\":\"col2\""
            "}],"
            "\"limit\":1"
        "}";
    // 注意Http请求中的x-bce-date与生成认证字符串的时间需一致
    http_request.headers["x-bce-date"] = utcfromtimestamp(timestamp);
    http_request.headers["Host"] = "bts.bd.baidubce.com";
    http_request.headers["Content-Length"] = std::to_string(http_request.body.size());
    http_request.headers["Authorization"] = gen_authorization(http_request, timestamp);
 
    // 使用curl发送请求
    CURL* curl = curl_easy_init();
    struct curl_slist* curl_headers = NULL;
    // 填充header
    for (auto const& item : http_request.headers) {
        std::string header = item.first + ":" + item.second;
        curl_headers = curl_slist_append(curl_headers, header.c_str());
    }
    // 拼接Url
    std::string url("http://bts.bd.baidubce.com");
    url.append(http_request.path);
    // 设置Url
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    // 设置headers
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers);
    // 设置method
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, http_request.method.c_str());
    // 设置body
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, http_request.body.c_str());
    // 设置返回的header,content
    // 如果你不需要解析header和content,则不需要做此设置,返回的content也会直接打印到标准输出
    std::string header;
    std::string content;
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, content_data);
    curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, header_data);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &content);
    curl_easy_setopt(curl, CURLOPT_HEADERDATA, &header);
    // 发送请求
    curl_easy_perform(curl);
    // 解析http返回码
    long http_code = -1;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    // 清理curl
    curl_easy_cleanup(curl);
    // 打印返回的header内容
    printf("query response header: %s.\n", header.c_str());
    // 打印返回的content内容,为json格式,具体可参考api文档
    // 如果你需要对返回的内容做下一步处理,可以将此content按json格式解析后作为后续使用
    printf("query result: %s.\n", content.c_str());
}

删除Table中数据

用户也可以指定rowkey删除Table中的某行数据。

void remove() {
    // 获取当前时间戳
    time_t timestamp = time(NULL);
    // 初始化HttpRequest
    HttpRequest http_request;
    // 方法为DELETE表示删除资源
    http_request.method = "DELETE";
    // 将删除ins_demo中的表table_demo中的一行数据
    http_request.path = "/v1/instance/ins_demo/table/table_demo/row";
    // 拼接写入的数据,为json格式,并且数据要经过UrlEncode
    // 删除rowkey(主键)为"www.baidu.com/0"的两列数据:col1,值为"val1",col2,值为"val2"
    // 如果要将整行,则不需要设置cells,只需设置rowkey即可
    http_request.body =
        "{"
            "\"rowkey\":\"www.baidu.com%2F0\","
            "\"cells\":["
            "{"
                "\"column\":\"col1\","
                "\"value\":\"val1\""
            "},"
            "{"
                "\"column\":\"col2\","
                "\"value\":\"val2\""
            "}"
        "]}";
    // 注意Http请求中的x-bce-date与生成认证字符串的时间需一致
    http_request.headers["x-bce-date"] = utcfromtimestamp(timestamp);
    http_request.headers["Host"] = "bts.bd.baidubce.com";
    http_request.headers["Content-Length"] = std::to_string(http_request.body.size());
    http_request.headers["Authorization"] = gen_authorization(http_request, timestamp);
 
    // 使用curl发送请求
    CURL* curl = curl_easy_init();
    struct curl_slist* curl_headers = NULL;
    // 填充header
    for (auto const& item : http_request.headers) {
        std::string header = item.first + ":" + item.second;
        curl_headers = curl_slist_append(curl_headers, header.c_str());
    }
    // 拼接Url
    std::string url("http://bts.bd.baidubce.com");
    url.append(http_request.path);
    // 设置Url
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    // 设置headers
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers);
    // 设置method
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, http_request.method.c_str());
    // 设置body
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, http_request.body.c_str());
    // 发送请求
    curl_easy_perform(curl);
    // 解析http返回码
    long http_code = -1;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    // 清理curl
    curl_easy_cleanup(curl);
}

删除Table

用户如果不再使用某张表,则可将其删除,其中的数据也会清理。

void drop_table() {
    // 获取当前时间戳
    time_t timestamp = time(NULL);
    // 初始化HttpRequest
    HttpRequest http_request;
    // 方法为DELETE表示删除资源
    http_request.method = "DELETE";
    // 将删除ins_demo中名为table_demo的table
    http_request.path = "/v1/instance/ins_demo/table/table_demo";
    // 注意Http请求中的x-bce-date与生成认证字符串的时间需一致
    http_request.headers["x-bce-date"] = utcfromtimestamp(timestamp);
    http_request.headers["Host"] = "bts.bd.baidubce.com";
    http_request.headers["Authorization"] = gen_authorization(http_request, timestamp);
 
    // 使用curl发送请求
    CURL* curl = curl_easy_init();
    struct curl_slist* curl_headers = NULL;
    // 填充header
    for (auto const& item : http_request.headers) {
        std::string header = item.first + ":" + item.second;
        curl_headers = curl_slist_append(curl_headers, header.c_str());
    }
    // 拼接Url
    std::string url("http://bts.bd.baidubce.com");
    url.append(http_request.path);
    // 设置Url
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    // 设置headers
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers);
    // 设置method
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, http_request.method.c_str());
    // 发送请求
    curl_easy_perform(curl);
    // 解析http返回码
    long http_code = -1;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    // 清理curl
    curl_easy_cleanup(curl);
}

删除Instance

当用户不再使用某个Instance时,可将其删除,但需要注意的是,被删除的Instance必需是空的,即其中没有表存在,否则会拒绝删除操作。

void drop_instance() {
    // 获取当前时间戳
    time_t timestamp = time(NULL);
    // 初始化HttpRequest
    HttpRequest http_request;
    // 方法为DELETE表示删除资源
    http_request.method = "DELETE";
    // 将删除名为ins_demo的instance
    http_request.path = "/v1/instance/ins_demo";
    // 注意Http请求中的x-bce-date与生成认证字符串的时间需一致
    http_request.headers["x-bce-date"] = utcfromtimestamp(timestamp);
    http_request.headers["Host"] = "bts.bd.baidubce.com";
    http_request.headers["Authorization"] = gen_authorization(http_request, timestamp);
 
    // 使用curl发送请求
    CURL* curl = curl_easy_init();
    struct curl_slist* curl_headers = NULL;
    // 填充header
    for (auto const& item : http_request.headers) {
        std::string header = item.first + ":" + item.second;
        curl_headers = curl_slist_append(curl_headers, header.c_str());
    }
    // 拼接Url
    std::string url("http://bts.bd.baidubce.com");
    url.append(http_request.path);
    // 设置Url
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    // 设置headers
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, curl_headers);
    // 设置method
    curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, http_request.method.c_str());
    // 发送请求
    curl_easy_perform(curl);
    // 解析http返回码
    long http_code = -1;
    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
    // 清理curl
    curl_easy_cleanup(curl);
}

百度智能云认证字符串C++实现

// 时间戳转为公有云utc时间串的函数
// 例如:1535904000 转换为 2018-09-02T16:00:00Z
inline std::string timestamp_to_utc(time_t timestamp) {
    struct tm* timeinfo = gmtime(&timestamp);
    const int buf_size = 32;
    char buf[buf_size];
    strftime(buf, buf_size, "%FT%TZ", timeinfo);
    return std::string(buf);
}
// UrlEncode实现,except_slash参数表示是否编码'/'
inline std::string uri_encode(const std::string& src, bool except_slash = false) {
    static const char* hex = "0123456789ABCDEF";
    std::string dst = "";
    for (size_t i = 0; i < src.length(); i++) {
        char c = src[i];
        if (isalnum(c) || strchr("-_.~", c)) {
            dst += c;
        } else if (except_slash && c == '/') {
            dst += c;
        } else {
            dst += '%';
            dst += hex[(unsigned char)c >> 4];
            dst += hex[(unsigned char)c & 0xf];
        }
    }
    return dst;
}
// UriEncodeExceptSlash实现
inline std::string uri_encode_except_slash(const std::string& str) {
    return uri_encode(str, true);
}
// 百度智能云认证字符串生成的C++实现
// 其中有一些加密函数由于有公开库,我们这里直接调用,用户可找相应的公开库(如openssl)
// 用户可以参考百度智能云生成认证字符串流程来阅读以下实现代码
std::string gen_authorization(const HttpRequest& request, time_t timestamp) {
    // 1. 生成CanonicalRequest
    std::string http_method = request.method;
    // 1.1 生成CanonicalURI,
    std::string canonical_uri = uri_encode_except_slash(request.path);
    // 1.2 计算CanonicalQueryString
    std::string canonical_query = "";
    // 使用set结构暂存在后续遍历时可以保证天然字典序遍历,如果使用vector暂存需要配合sort按字典序排序
    std::set<std::string> encoded_params;
    // 对params遍历一次对kv做urlencode
    auto params_it = request.params.begin();
    for (; params_it != request.params.end(); ++params_it) {
        if (params_it->first == "authorization" || params_it->first == "Authorization") {
            continue;
        }
        std::string key = uri_encode(params_it->first);
        std::string value = uri_encode(params_it->second);
        encoded_params.insert(key + '=' + value); // 兼容value为空字符串的情形
    }
    // 对params遍历urlencode后的集合,拼接字符串
    auto enc_params_it = encoded_params.begin();
    for (; enc_params_it != encoded_params.end(); ++enc_params_it) {
        if (enc_params_it != encoded_params.begin()) {
            canonical_query += '&';
        }
        canonical_query += *enc_params_it;
    }
    // 1.3 计算CanonicalHeaders
    std::string canonical_header = "";
    // 使用set结构暂存在后续遍历时可以保证天然字典序遍历,如果使用vector暂存需要配合sort按字典序排序
    std::set<std::string> encoded_headers;
    // 对headers遍历一次,对key做转换小写、urlencoded操作,对value做去首尾空格、urlencoded操作
    auto headers_it = request.headers.begin();
    for (; headers_it != request.headers.end(); ++headers_it) {
        // 将key部分转换为全小写
        std::string key = headers_it->first;
        for (size_t i = 0; i < key.length(); ++i) {
            key[i] = ::tolower(key[i]);
        }
        // 将value部分去掉首尾的空白符
        const char* blank_chars = " \n\r\t\v";
        std::string value = headers_it->second;
        value.erase(0, value.find_first_not_of(blank_chars));
        value.erase(value.find_last_not_of(blank_chars) + 1);
        if (value.empty()) {
            continue;
        }
        std::string encoded_key = uri_encode(key);
        std::string encoded_value = uri_encode(value);
        encoded_headers.insert(encoded_key + ':' + encoded_value);
    }
    // 对headers遍历urlencode后的集合,拼接字符串
    auto enc_headers_it = encoded_headers.begin();
    for (; enc_headers_it != encoded_headers.end(); ++enc_headers_it) {
        if (enc_headers_it != encoded_headers.begin()) {
            canonical_header += '\n';
        }
        canonical_header += *enc_headers_it;
    }
    // 拼接生成CanonicalRequest
    std::string canonical_request = http_method + '\n'
                                  + canonical_uri + '\n'
                                  + canonical_query + '\n'
                                  + canonical_header;
    // 2. 生成SigningKey,这里我们直接调用了hmac_sha256函数,用户可以使用任意公开库中的HMAC-SHA256-HEX函数代替
    // 注意使用hmac_sha256函数时参数的顺序
    // 在生成鉴权串时的时间戳一定要和发送请求中Header域中的Date/x-bce-date相同
    // 用户的ak/sk
    const std::string ak = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
    const std::string sk = "ssssssssssssssssssssssssssssssss";
    // 拼接认证字符串前缀 : bce-auth-v1/{accessKeyId}/{timestamp}/{expirationPeriodInSeconds}
    std::string auth_string_prefix = "bce-auth-v1/";
    auth_string_prefix.append(ak + '/');
    auth_string_prefix.append(timestamp_to_utc(timestamp));
    // 认证字符串的超时时间(有效期)为1800秒,用户可以自行设置,时间长意味着效率高,但安全性会降低
    auth_string_prefix.append("/1800");
    std::string sign_key = hmac_sha256(auth_string_prefix, sk);
    // 3. 生成Signature
    std::string sign = hmac_sha256(canonical_request, sign_key);
    // 4. 生成认证字符串,即做拼接
    // 将前缀和Signature拼接得到完整的认证字符串
    // 与签名结果之间为两个”/”,含义是使用默认签名方式,signedHeaders内容留空
    std::string auth = auth_string_prefix + "//" + sign;
    return auth;
}
相似文档
  • 协议生效时间:2019年05月01日。 本服务等级协议(Service Level Agreement,简称“SLA”) 规定了百度智能云向客户提供的云数据库 TableStorage的服务可用性等级指标及赔偿方案。
  • 建表时的数据生存时间和压缩方式如何选择? 数据生成时间是指行数据从最后一次修改的时间算起,在云数据库TableStorage保留的时间。超过数据生存时间的数据会被云数据库TableStorage删除。用户可以根据实际业务的情况合理设置数据生存时间,从而降低占用的存储空间。
  • API/SDK返回401(AuthenticationFailed)如何处理? 用户在使用API对云数据库TableStorage进行任何的操作之前都需要进行身份认证,当身份认证失败时会返回401(AuthenticationFailed)错误码,修复方法是首先确认AK/SK是否配置正确,配置正确之后仍然报401,请参考认证字符串生成协议V1、V2。
  • 云数据库 FusionDB 是一种在线分布式云数据库,提供了简单、快速、高性能、高可靠的大规模并行处理(MPP)数据仓库服务。云数据库 FusionDB 基于开源 Greenplum Database 项目开发,提供了完善的监控、安全管理等功能,同时可以轻松实现在线扩展。
  • 云数据库 FusionDB 可根据用户需要,对节点进行弹性扩容,提升整体分析能力,应对业务以及数据增长等场景。通过增加节点可以线性提高系统的存储和计算能力。云数据库 FusionDB 基于分布式大规模并行处理MPP框架,支持行列混合存储以及压缩存储,业务可按照需求选择最佳存储方案。结合高并发加载、计算能力,提供高性能处理能力。
官方微信
联系客服
400-826-7010
7x24小时客服热线
分享
  • QQ好友
  • QQ空间
  • 微信
  • 微博
返回顶部