c/test/http_api.c · 3459 字节 · 下载原文
/* http_api.c —— `Lib/c/http.h` 这个**手写头**的判据。
* http_api.c — criterion for the **hand-written** header `Lib/c/http.h`.
*
* ## 为什么单独立一个
* ## Why a dedicated probe
*
* 手写头**没有自动闸门盯着**(GenLib 对 C 走 `ReuseCHeader`:只读、不生成)。同族的
* `Lib/c/net.h` 就这么漂过 6 处(4 个源码里根本不存在的函数 + 2 处签名不符),
* 症状是「**include 之后编得过、链接时才炸**」—— 最难查的那一类。
* ⇒ 这里问三件事:**头里的声明能不能编过**、**声明的名字链得到库标签吗**、**返回语义对不对**。
*
* Hand-written headers have **no gate watching them**. The sibling `Lib/c/net.h` drifted by 6 items
* (4 nonexistent functions + 2 wrong signatures) and the symptom is "compiles after the include,
* blows up at link time". So this asks: does the declaration compile, does the name resolve to a
* library label, and is the return semantics right.
*
* ## 判据(**不依赖网络**)
* ## Criteria (no network needed)
*
* 本库有一条**确定性契约**:端口 443 或 `https://` 开头 ⇒ **立刻返回 `HTTP_E_HTTPS`(-2)、一个字节都不发**
* (VM 里没有 TLS)。它不需要真的连出去,正好拿来当判据。
* The library has one **deterministic contract** — port 443 or an `https://` prefix returns
* `HTTP_E_HTTPS` (-2) immediately, sending nothing — which needs no real connection, so it is the criterion.
*
* 跑法(桌面,秒级):
* dotnet scripts/vmlcli/bin/Release/net10.0/vmlcli.dll third_party/vml/Examples/c/test/http_api.c
*/
#include <http.h>
int fails = 0;
void ck(char* name, int got, int want) {
if (got == want) {
printf("OK %s = %d\n", name, got);
} else {
printf("FAIL %s: got %d, want %d\n", name, got, want);
fails = fails + 1;
}
}
int main(void) {
char buf[256];
int rc;
/* ① 端口 443 ⇒ 立刻 HTTP_E_HTTPS(一个字节都不发)—— 这条同时证明
* ①`http_get` 这个**名字链到了库标签**(链不上就是"未定义的函数")、②常量的值是 -2。 */
rc = http_get("example.com", 443, "/", buf, 256);
ck("https by port", rc, HTTP_E_HTTPS);
/* ② path 以 `https://` 开头 ⇒ 同样 */
rc = http_get("example.com", 80, "https://example.com/", buf, 256);
ck("https by url", rc, HTTP_E_HTTPS);
/* ③ 错误码 → 文字:能写进缓冲区且非空(返回值的口径不在这里钉) */
buf[0] = 0;
rc = http_error_text(HTTP_E_HTTPS, buf, 256);
if (buf[0] == 0) {
printf("FAIL http_error_text 什么也没写出来\n");
fails = fails + 1;
} else {
printf("OK http_error_text = %s\n", buf);
}
/* ④ 上一次请求的结果会被记下来 —— ⚠ `http_last_error()` 是**最近一次请求**的错误码,
* 不是"从没发过请求"的初值(第一版就在这里把期望值写成了 0,实测是 -2:
* 前面那次 `https by port` 刚失败过)。失败时没有状态码 ⇒ `last_status` 是 0。 */
ck("last_error(after https)", http_last_error(), HTTP_E_HTTPS);
ck("last_status(after fail)", http_last_status(), 0);
printf("HTTP_API %s (fails=%d)\n", fails == 0 ? "PASS" : "FAIL", fails);
return fails;
}