HTTPDNS C SDK+阿里云OSS C++ SDK最佳实践

更新时间:
复制为 MD 格式

通过C SDK接入这篇文档,您已经了解了C SDK导入、配置、解析IP、应用到网络库和接入验证的完整流程,本文主要介绍使用阿里云OSS C++ SDK接入HTTPDNS C SDK的具体方案。

1. 背景说明

阿里云对象存储OSS(Object Storage Service)是一款通用的云存储服务,可让开发者在各类应用中便捷地存储和访问用户头像、图片、音视频等文件。在桌面端,可以通过集成OSS C++ SDK来完成。

为了提升文件传输的稳定性和速度,可以将HTTPDNS C SDKOSS C++ SDK进行结合,对OSS域名进行解析。这可以有效实现域名防劫持和DNS解析加速,从而优化应用访问OSS的网络体验。

2. 准备工作

版本要求

  • HTTPDNS C SDK: >= 2.0.0

  • OSS C++ SDK: >= 1.10.1

2.1 编译 HTTPDNS C SDK

git clone https://github.com/aliyun/alibabacloud-httpdns-c-sdk.git
cd alibabacloud-httpdns-c-sdk
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make
sudo make install

2.2 编译 OSS C++ SDK

git clone https://github.com/aliyun/aliyun-oss-cpp-sdk.git
cd aliyun-oss-cpp-sdk
mkdir build && cd build
cmake ..
make
sudo make install

2.3 配置项目 CMakeLists.txt

在您的项目 CMakeLists.txt 中引入两个 SDK:

# 引入 HTTPDNS C SDK
find_library(HTTPDNS_LIBRARY httpdns_c_sdk_static)
include_directories(${CMAKE_INSTALL_PREFIX}/include/httpdns)

# 引入 OSS C++ SDK
find_library(OSS_LIBRARY alibabacloud-oss-cpp-sdk)
include_directories(${CMAKE_INSTALL_PREFIX}/include)

# 链接库
target_link_libraries(your_target 
    ${HTTPDNS_LIBRARY}
    ${OSS_LIBRARY}
    curl
    pthread
)

3. 集成步骤

步骤一:引入 HTTPDNS 适配器

OSS C++ SDK 提供了 HttpInterceptor 扩展点,允许在 HTTP 请求发送前进行拦截处理。我们通过实现该接口,将 HTTPDNS 解析结果注入到请求中。

下载适配器文件 hdns_oss_interceptor.h,将其复制到您的项目中。该适配器实现了 OSS SDK 的 HttpInterceptor 接口,核心逻辑如下:

void preSendRequest(void *handler, 
                    const std::shared_ptr<OSS::HttpRequest> &request) override {
    // 获取请求域名
    std::string host = request->url().host();
    
    // 使用 HTTPDNS 解析域名
    hdns_list_head_t *results = nullptr;
    hdns_status_t status = hdns_get_result_for_host_sync_with_cache(
        hdnsClient_, host.c_str(), queryType_, nullptr, &results);

    // 获取解析到的 IP
    char ip[HDNS_IP_ADDRESS_STRING_LENGTH] = {0};
    hdns_select_ip_randomly(results, queryType_, ip);

    // 将解析结果注入到请求中
    char resolveEntry[512];
    snprintf(resolveEntry, sizeof(resolveEntry), "%s:%d:%s", host.c_str(), port, ip);
    struct curl_slist *resolveList = curl_slist_append(nullptr, resolveEntry);
    curl_easy_setopt(curl, CURLOPT_RESOLVE, resolveList);
}
说明

适配器文件建议根据实际业务场景进行修改,例如调整解析方式、IP 选择策略或查询类型等。

步骤二:接入 OSS SDK

将适配器集成到 OSS SDK 中,完成 HTTPDNS 的接入。

接入代码示例

#include <iostream>
#include <memory>

// HTTPDNS SDK
extern "C" {
#include "hdns_api.h"
}

// OSS SDK
#include <alibabacloud/oss/OssClient.h>

// HTTPDNS-OSS 适配器
#include "hdns_oss_interceptor.h"

using namespace AlibabaCloud::OSS;

int main() {
    std::string accessKeyId = "your_access_key_id";
    std::string accessKeySecret = "your_access_key_secret";
    std::string endpoint = "oss-cn-hangzhou.aliyuncs.com";

    // ============ 1. 初始化 HTTPDNS ============
    hdns_sdk_init();

    hdns_client_t *hdnsClient = hdns_client_create("your_httpdns_account_id", "your_secret_key");

    // 配置 HTTPDNS 客户端
    hdns_client_set_timeout(hdnsClient, 2000);
    hdns_client_set_using_cache(hdnsClient, true);
    hdns_client_set_using_https(hdnsClient, true);
    hdns_client_enable_expired_ip(hdnsClient, true);
    hdns_client_enable_failover_localdns(hdnsClient, true);
    hdns_client_add_pre_resolve_host(hdnsClient, endpoint.c_str());

    hdns_client_start(hdnsClient);

    // ============ 2. 初始化 OSS 并注入适配器 ============
    InitializeSdk();

    // 创建适配器
    auto hdnsInterceptor = std::make_shared<AlibabaCloud::HDNS::HdnsOssInterceptor>(hdnsClient);

    // 配置 OSS 客户端
    ClientConfiguration conf;
    conf.httpInterceptor = hdnsInterceptor;  // 关键:注入适配器

    // 创建 OSS 客户端
    OssClient ossClient("https://" + endpoint, accessKeyId, accessKeySecret, conf);

    // ============ 3. 使用 OSS 客户端 ============
    auto outcome = ossClient.ListBuckets();
    if (outcome.isSuccess()) {
        std::cout << "请求成功,Bucket 列表:" << std::endl;
        for (const auto &bucket : outcome.result().Buckets()) {
            std::cout << "  - " << bucket.Name() << std::endl;
        }
    } else {
        std::cerr << "请求失败: " << outcome.error().Message() << std::endl;
    }

    // ============ 4. 释放资源 ============
    // 注意:必须先释放 OSS 客户端,再释放 HTTPDNS 客户端
    ShutdownSdk();
    hdns_client_cleanup(hdnsClient);
    hdns_sdk_cleanup();

    return 0;
}
重要

HTTPDNS SDK 初始化必须在 OSS SDK 初始化之前完成;资源释放时,必须先释放 OSS 客户端,再释放 HTTPDNS 客户端。

4. 总结

通过将 HTTPDNS 与 OSS C++ SDK 结合,可以有效防止 DNS 劫持并加速文件传输,提升访问的稳定性和安全性。实现的核心是通过 HttpInterceptor 机制,在 OSS 请求发送前注入 HTTPDNS 的解析结果。

关键注意点

  • HTTPDNS SDK 初始化必须在 OSS SDK 初始化之前完成

  • 资源释放时,必须先释放 OSS 客户端,再释放 HTTPDNS 客户端

  • 如果 HTTPDNS 解析失败,适配器会自动降级到系统 DNS,不影响业务正常运行