如何修改C libcurl代码验证Webhook消息发送状态及JSON错误?
解决Discord Webhook JSON无效错误及请求状态验证
你遇到的错误:
{"code": 50109, "message": "The request body contains invalid JSON."}
核心原因是my_description中的特殊字符(比如双引号、反斜杠)破坏了JSON结构,加上原代码仅检查curl请求是否发送成功,未验证Webhook的业务处理结果。以下是修改后的完整代码:
#include <stdio.h> #include <curl/curl.h> #include <string.h> #include <stdlib.h> #define nullptr ((void*)0) // 响应体接收缓冲区 typedef struct { char *data; size_t size; } ResponseBuffer; // curl写回调函数,用于接收响应体 static size_t write_callback(void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; ResponseBuffer *buf = (ResponseBuffer *)userp; char *ptr = realloc(buf->data, buf->size + realsize + 1); if(!ptr) { fprintf(stderr, "内存分配失败\n"); return 0; } buf->data = ptr; memcpy(&(buf->data[buf->size]), contents, realsize); buf->size += realsize; buf->data[buf->size] = '\0'; return realsize; } // JSON特殊字符转义函数 void escape_json_string(const char *input, char *output, size_t output_size) { if(!input || !output || output_size == 0) return; size_t in_idx = 0, out_idx = 0; while(input[in_idx] != '\0' && out_idx < output_size - 1) { switch(input[in_idx]) { case '"': if(out_idx + 2 > output_size - 1) break; output[out_idx++] = '\\'; output[out_idx++] = '"'; break; case '\\': if(out_idx + 2 > output_size - 1) break; output[out_idx++] = '\\'; output[out_idx++] = '\\'; break; case '\n': if(out_idx + 2 > output_size - 1) break; output[out_idx++] = '\\'; output[out_idx++] = 'n'; break; case '\r': if(out_idx + 2 > output_size - 1) break; output[out_idx++] = '\\'; output[out_idx++] = 'r'; break; case '\t': if(out_idx + 2 > output_size - 1) break; output[out_idx++] = '\\'; output[out_idx++] = 't'; break; default: output[out_idx++] = input[in_idx]; break; } in_idx++; } output[out_idx] = '\0'; } int main() { char message[65500]; int max_len = sizeof(message); CURL *curl; CURLcode res; long http_code = 0; char webhook[] = "DISCORD_WEBHOOK"; char my_description[] = "Description with \"quotes\" and \\backslashes\\"; char escaped_desc[65500]; // 转义描述中的JSON特殊字符 escape_json_string(my_description, escaped_desc, sizeof(escaped_desc)); // 生成合法的JSON snprintf(message, max_len, "{\"username\": \"Test\",\"embeds\":[{\"description\": \"%s\"}]}", escaped_desc); // 初始化响应缓冲区 ResponseBuffer response_buf = {NULL, 0}; curl = curl_easy_init(); if(curl) { struct curl_slist* headers = nullptr; headers = curl_slist_append(headers, "Content-Type: application/json"); if(!headers) { fprintf(stderr, "创建HTTP头失败\n"); curl_easy_cleanup(curl); return 1; } // 设置curl选项 curl_easy_setopt(curl, CURLOPT_URL, webhook); curl_easy_setopt(curl, CURLOPT_POSTFIELDS, message); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); // 设置响应体接收回调 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_buf); // 禁止信号处理,避免程序中断 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L); // 执行请求 res = curl_easy_perform(curl); // 获取HTTP响应码 curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); // 处理请求结果 if(res != CURLE_OK) { fprintf(stderr, "请求发送失败: %s\n", curl_easy_strerror(res)); } else { if(http_code == 200 || http_code == 204) { printf("消息发送成功\n"); } else { fprintf(stderr, "Webhook处理失败,HTTP状态码: %ld\n", http_code); if(response_buf.data) { fprintf(stderr, "错误详情: %s\n", response_buf.data); } } } // 清理资源 curl_slist_free_all(headers); curl_easy_cleanup(curl); } else { fprintf(stderr, "curl初始化失败\n"); } // 释放响应缓冲区 if(response_buf.data) { free(response_buf.data); } return 0; }
关键修改说明:
- JSON转义:新增
escape_json_string函数,处理双引号、反斜杠等特殊字符,确保生成的JSON格式合法,从根源解决50109错误。 - 响应体捕获:通过
write_callback函数收集Webhook返回的响应内容,方便查看具体错误信息。 - HTTP状态码验证:使用
curl_easy_getinfo获取HTTP响应码,Discord Webhook成功时返回200或204,非此状态则判定为业务错误。 - 完善错误处理:区分curl请求失败(如网络问题)和Webhook业务失败(如JSON无效),分别打印对应的错误信息。
- 资源清理:确保所有动态分配的资源(如响应缓冲区、curl头列表)都被正确释放,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Moga Onamil
相关产品推荐
相关产品推荐

