init
This commit is contained in:
commit
e54390a9f8
85 files changed
+29923
No files matched your search
@@ -0,0 +1,112 @@
|
||||
/* test_http.c - HTTP 层纯逻辑测试(不联网) */
|
||||
#include "http.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static int failures = 0;
|
||||
static int checks = 0;
|
||||
|
||||
#define CHECK(cond, ...) \
|
||||
do { \
|
||||
checks++; \
|
||||
if (!(cond)) { \
|
||||
failures++; \
|
||||
printf(" ✗ %s:%d: ", __FILE__, __LINE__); \
|
||||
printf(__VA_ARGS__); \
|
||||
printf("\n"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("重试判定:只重试服务端明确报错的情况");
|
||||
|
||||
/* 应当重试 */
|
||||
long retryable[] = { 408, 409, 429, 500, 502, 503, 504 };
|
||||
for (size_t i = 0; i < sizeof retryable / sizeof retryable[0]; i++)
|
||||
CHECK(http_status_retryable(retryable[i]) == 1,
|
||||
"HTTP %ld 应当可重试", retryable[i]);
|
||||
|
||||
/* 绝不应当重试:这些是确定性错误,重试只是浪费时间和钱 */
|
||||
long permanent[] = { 400, 401, 403, 404, 405, 413, 415, 422, 501,
|
||||
200, 201, 204, 301, 0, -1 };
|
||||
for (size_t i = 0; i < sizeof permanent / sizeof permanent[0]; i++)
|
||||
CHECK(http_status_retryable(permanent[i]) == 0,
|
||||
"HTTP %ld 不应重试", permanent[i]);
|
||||
|
||||
/* 默认策略与上限的合理性 */
|
||||
HttpRetry def = HTTP_RETRY_DEFAULT;
|
||||
HttpRetry none = HTTP_RETRY_NONE;
|
||||
CHECK(def.max_retries > 0, "默认应当会重试");
|
||||
CHECK(none.max_retries == 0, "HTTP_RETRY_NONE 应当不重试");
|
||||
CHECK(HTTP_MAX_BODY >= 1024 * 1024, "响应体上限不该小到影响正常使用");
|
||||
CHECK(HTTP_MAX_ERRBODY < HTTP_MAX_BODY, "错误体上限应远小于正文上限");
|
||||
|
||||
/* ---- 调试输出的密钥脱敏 ---- */
|
||||
puts("--verbose 输出脱敏");
|
||||
{
|
||||
const char *key = "sk-0f114e3dac8249f0a36fd8fd5c517360";
|
||||
char *buf = NULL;
|
||||
size_t sz = 0;
|
||||
FILE *f = open_memstream(&buf, &sz);
|
||||
|
||||
/* 这条正是曾经漏出去的:libcurl 的 HTTP/2 调试行走的是 CURLINFO_TEXT,
|
||||
* 不是 HEADER_OUT,所以只处理 HEADER_OUT 的做法根本挡不住 */
|
||||
const char *h2 = "== Info: [HTTP/2] [1] [authorization: Bearer sk-0f114e3dac8249f0a36fd8fd5c517360]\n";
|
||||
http_write_redacted(f, h2, strlen(h2), key);
|
||||
|
||||
/* 整块请求头(HEADER_OUT 是整块传来的,不是逐行) */
|
||||
const char *hdrs = "POST /v1/chat/completions HTTP/2\r\n"
|
||||
"Authorization: Bearer sk-0f114e3dac8249f0a36fd8fd5c517360\r\n"
|
||||
"Content-Type: application/json\r\n";
|
||||
http_write_redacted(f, hdrs, strlen(hdrs), key);
|
||||
|
||||
/* 其它内容不能被改动 */
|
||||
const char *plain = "== Info: TLSv1.3 (IN), TLS handshake, Finished (20):\n";
|
||||
http_write_redacted(f, plain, strlen(plain), key);
|
||||
|
||||
/* 没有密钥时原样输出 */
|
||||
http_write_redacted(f, "no key here\n", 12, "");
|
||||
|
||||
fclose(f);
|
||||
CHECK(strstr(buf, key) == NULL, "输出里不应残留完整密钥");
|
||||
CHECK(strstr(buf, "<已隐藏>") != NULL, "应替换为占位符");
|
||||
CHECK(strstr(buf, "[HTTP/2]") != NULL, "HTTP/2 调试行本身应保留");
|
||||
CHECK(strstr(buf, "Authorization: Bearer <已隐藏>") != NULL,
|
||||
"请求头里的密钥应脱敏: %.200s", buf);
|
||||
CHECK(strstr(buf, "TLS handshake") != NULL, "其它调试信息不能被误改");
|
||||
CHECK(strstr(buf, "no key here") != NULL, "无密钥时原样输出");
|
||||
/* 一次替换必须整段吃掉,不能留下半个密钥 */
|
||||
CHECK(strstr(buf, "0f114e3dac") == NULL, "不应留下密钥片段");
|
||||
free(buf);
|
||||
}
|
||||
|
||||
puts("\n空请求体:POST 分支也要扛得住 body == NULL");
|
||||
{
|
||||
/* body 允许为 NULL(http_probe 就是这么调的),但 POST 分支以前写的是
|
||||
* 无条件的 strlen(body) —— 传 NULL 会在 curl_easy_setopt 期间就段错误。
|
||||
*
|
||||
* 这里故意用一个格式非法的 URL:libcurl 会在真正联网之前就拒绝它,
|
||||
* 所以本测试仍然不碰网络。而 strlen(NULL) 发生在设置 POSTFIELDS 期间、
|
||||
* curl_easy_perform 之前,也就是说旧代码在这里必崩 —— 这个断言对旧
|
||||
* 代码是有效的回归守卫,不是走过场。 */
|
||||
static const HttpRetry no_retry = HTTP_RETRY_NONE;
|
||||
char errbuf[256] = "";
|
||||
int attempts = 0;
|
||||
long status = 0;
|
||||
|
||||
http_global_init();
|
||||
int rc = http_post(":::", "sk-test", NULL, 5, 0, &no_retry,
|
||||
NULL, &status, &attempts, errbuf, sizeof errbuf);
|
||||
http_global_cleanup();
|
||||
|
||||
CHECK(rc == -1, "非法 URL 应当返回 -1(实际返回 %d)", rc);
|
||||
CHECK(errbuf[0] != '\0', "失败时必须给出错误说明");
|
||||
}
|
||||
|
||||
printf("\n%d 项检查,%d 项失败\n", checks, failures);
|
||||
return failures ? 1 : 0;
|
||||
}
|
||||
Reference in new issue
Block a user