源文件api_request.c
的具体内容如下:
#include "api_request.h"
// 回调函数,用于处理请求头
size_t request_header_callback(void *ptr, size_t size, size_t nmemb, void *userdata)
{
size_t realsize = size * nmemb;
printf("发送的请求头:
%.*s
", (int)realsize, (char *)ptr);
return realsize;
}
// 回调函数,用于处理请求体
size_t request_body_callback(void *ptr, size_t size, size_t nmemb, void *userdata)
{
size_t realsize = size * nmemb;
printf("发送的请求体:
%.*s
", (int)realsize, (char *)ptr);
return realsize;
}
// 回调函数,用于处理响应头
size_t response_header_callback(void *ptr, size_t size, size_t nmemb, void *userdata)
{
size_t realsize = size * nmemb;
printf("收到的响应头:
%.*s
", (int)realsize, (char *)ptr);
return realsize;
}
// 回调函数,用于处理响应体
size_t response_body_callback(void *ptr, size_t size, size_t nmemb, void *userdata)
{
size_t realsize = size * nmemb;
printf("收到的响应体:
%.*s
", (int)realsize, (char *)ptr);
return realsize;
}
// HMAC - SHA256计算
unsigned char *hmacSHA256(const unsigned char *key, size_t key_len, const unsigned char *content, size_t content_len)
{
static unsigned char hmac_result[EVP_MAX_MD_SIZE];
unsigned int hmac_len;
HMAC(EVP_sha256(), key, (int)key_len, content, (int)content_len, hmac_result, &hmac_len);
return hmac_result;
}
// 获取签名密钥
unsigned char *getSignedKey(const char *secretKey, const char *date, const char *region, const char *service)
{
unsigned char kDate[EVP_MAX_MD_SIZE];
unsigned char kRegion[EVP_MAX_MD_SIZE];
unsigned char kService[EVP_MAX_MD_SIZE];
unsigned char *result;
result = hmacSHA256((const unsigned char *)secretKey, strlen(secretKey), (const unsigned char *)date, strlen(date));
memcpy(kDate, result, EVP_MAX_MD_SIZE);
result = hmacSHA256(kDate, EVP_MAX_MD_SIZE, (const unsigned char *)region, strlen(region));
memcpy(kRegion, result, EVP_MAX_MD_SIZE);
result = hmacSHA256(kRegion, EVP_MAX_MD_SIZE, (const unsigned char *)service, strlen(service));
memcpy(kService, result, EVP_MAX_MD_SIZE);
return hmacSHA256(kService, EVP_MAX_MD_SIZE, (const unsigned char *)"request", strlen("request"));
}
// SHA256哈希计算
char *hashSHA256(const unsigned char *content, size_t len)
{
static char hex_output[SHA256_DIGEST_LENGTH * 2 + 1];
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, content, len);
SHA256_Final(hash, &sha256);
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
{
sprintf(&hex_output[i * 2], "%02x", (unsigned int)hash[i]);
}
return hex_output;
}
// 构建规范字符串
void buildCanonicalString(const char *method, const char *queryString, const char *host, const char *date, const char *payload, char *canonicalString)
{
char headerList[MAX_LEN];
// 检查snprintf的返回值,确保没有缓冲区溢出
if (snprintf(headerList, MAX_LEN, "host:%s
x-content-sha256:%s
x-date:%s
", host, payload, date) >= MAX_LEN)
{
fprintf(stderr, "headerList buffer overflow
");
return;
}
if (snprintf(canonicalString, MAX_LEN * 2, "%s
%s
%s
%s
%s
%s", method, "/", queryString, headerList, "host;x-content-sha256;x-date", payload) >= MAX_LEN * 2)
{
fprintf(stderr, "canonicalString buffer overflow
");
return;
}
}
// 构建签名字符串
void buildSignString(const char *date, const char *authDate, const char *hashedCanonicalString, char *signString)
{
char credentialScope[MAX_LEN];
if (snprintf(credentialScope, MAX_LEN, "%s/%s/%s/request", authDate, Region, Service) >= MAX_LEN)
{
fprintf(stderr, "credentialScope buffer overflow
");
return;
}
if (snprintf(signString, MAX_LEN * 2, "HMAC-SHA256
%s
%s
%s", date, credentialScope, hashedCanonicalString) >= MAX_LEN * 2)
{
fprintf(stderr, "signString buffer overflow
");
return;
}
}
// 构建认证请求头
void buildAuthorization(const char *authDate, const char *signString, char *authorization)
{
unsigned char *signedKey = getSignedKey(SecretAccessKey, authDate, Region, Service);
unsigned char *hmac_result = hmacSHA256(signedKey, EVP_MAX_MD_SIZE, (const unsigned char *)signString, strlen(signString));
char signature[SHA256_DIGEST_LENGTH * 2 + 1] = {0};
for (int i = 0; i < 32; i++)
{
sprintf(&signature[i * 2], "%02x", (unsigned int)hmac_result[i]);
}
char credentialScope[MAX_LEN];
if (snprintf(credentialScope, MAX_LEN, "%s/%s/%s/request", authDate, Region, Service) >= MAX_LEN)
{
fprintf(stderr, "credentialScope buffer overflow
");
return;
}
int len = snprintf(authorization, MAX_LEN, "HMAC-SHA256 Credential=%s/%s, SignedHeaders=host;x-content-sha256;x-date, Signature=%s",
AccessKeyID, credentialScope, signature);
if (len >= MAX_LEN)
{
fprintf(stderr, "authorization buffer overflow
");
return;
}
}
// 构建请求体JSON字符串
void buildQueryLLMGenerateBody(const char *msgid, int useStream , char *requestBody)
{
json_object *root = json_object_new_object();
if (root == NULL)
{
fprintf(stderr, "Failed to create json_object
");
return;
}
json_object_object_add(root, "UseStream", json_object_new_boolean (useStream));
json_object_object_add(root, "MsgID", json_object_new_string (msgid));
const char *json_str = json_object_to_json_string(root);
if (json_str == NULL)
{
fprintf(stderr, "Failed to convert json_object to string
");
json_object_put(root);
return;
}
// 检查strcpy的目标缓冲区大小
if (strlen(json_str) + 1 > MAX_LEN)
{
fprintf(stderr, "requestBody buffer overflow
");
json_object_put(root);
return;
}
strcpy(requestBody, json_str);
json_object_put(root);
}
// 构建请求体JSON字符串
void buildCheckLLMPromptBody(const char *content, int contentType, const char *host, int msgClass, const char *region, char *requestBody)
{
json_object *root = json_object_new_object();
if (root == NULL)
{
fprintf(stderr, "Failed to create json_object
");
return;
}
json_object_object_add(root, "content", json_object_new_string(content));
json_object_object_add(root, "contentType", json_object_new_int(contentType));
json_object_object_add(root, "host", json_object_new_string(host));
json_object_object_add(root, "msgClass", json_object_new_int(msgClass));
json_object_object_add(root, "region", json_object_new_string(region));
const char *json_str = json_object_to_json_string(root);
if (json_str == NULL)
{
fprintf(stderr, "Failed to convert json_object to string
");
json_object_put(root);
return;
}
// 检查strcpy的目标缓冲区大小
if (strlen(json_str) + 1 > MAX_LEN)
{
fprintf(stderr, "requestBody buffer overflow
");
json_object_put(root);
return;
}
strcpy(requestBody, json_str);
json_object_put(root);
}
// 执行curl请求
int performCurlRequest(CURL *curl, const char *url, const char *requestBody, struct curl_slist *headers)
{
CURLcode res;
// 设置请求方法
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
// 设置请求的URL
curl_easy_setopt(curl, CURLOPT_URL, url);
// 设置请求体
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, requestBody);
// 设置请求头
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
// 设置回调函数处理响应
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, request_body_callback);
// 设置响应体回调函数
curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, response_body_callback);
// 执行请求
res = curl_easy_perform(curl);
// 检查请求是否成功
if (res != CURLE_OK)
{
fprintf(stderr, "curl_easy_perform() failed: %s
", curl_easy_strerror(res));
}
return res;
}
// 初始化curl相关设置
CURL *initCurl()
{
CURL *curl = curl_easy_init();
if (!curl)
{
fprintf(stderr, "Failed to initialize curl
");
}
return curl;
}
// 构建请求地址
void buildRequestAddress(const char *endpoint, const char *queryString, char *requestAddr, size_t size)
{
if (snprintf(requestAddr, size, "https://%s/%s?%s", endpoint, "", queryString) >= size)
{
fprintf(stderr, "requestAddr buffer overflow
");
}
}
// 构建查询字符串
void buildQueryString(const char *action, const char *version, char *queryString, size_t size)
{
if (snprintf(queryString, size, "Action=%s&Version=%s", action, version) >= size)
{
fprintf(stderr, "queryString buffer overflow
");
}
}
// 构建签名相关材料
void buildSignatureMaterials(char *date, char *authDate, const char *requestBody, char *payload, size_t payloadSize)
{
time_t now = time(NULL);
struct tm *tm_info = gmtime(&now);
if (strftime(date, 64, "%Y%m%dT%H%M%SZ", tm_info) == 0)
{
fprintf(stderr, "Failed to format date
");
}
strncpy(authDate, date, 8);
authDate[8] = '�';
strcpy(payload, hashSHA256((const unsigned char *)requestBody, strlen(requestBody)));
}