commit d52be4b
uint
·
2026-01-28 19:25:06 +0000 UTC
parent 85547c2
tighten utils
1 files changed,
+73,
-38
+73,
-38
1@@ -35,60 +35,95 @@ const char* cistrstr(const char* hay, const char* nee)
2 return NULL;
3 }
4
5-int hdr_get_value(char out[512], const char* hdr, const char* key)
6+static int ci_key_match(const char* a, const char* b, size_t n)
7 {
8- char pat1[64];
9- char pat2[64];
10- char pat3[64];
11+ for (size_t i = 0; i < n; i++) {
12+ unsigned char ca = (unsigned char)a[i];
13+ unsigned char cb = (unsigned char)b[i];
14+ if (tolower(ca) != tolower(cb))
15+ return 0;
16+ }
17+ return 1;
18+}
19
20- /* build patterns like "\nXXXX:" "\rXXXX:" "XXXX:" */
21- if (snprintf(pat1, sizeof(pat1), "\n%s:", key) >= (int)sizeof(pat1))
22- return -1;
23- if (snprintf(pat2, sizeof(pat2), "\r%s:", key) >= (int)sizeof(pat2))
24- return -1;
25- if (snprintf(pat3, sizeof(pat3), "%s:", key) >= (int)sizeof(pat3))
26+int hdr_get_value(char out[512], const char* hdr, const char* key)
27+{
28+ size_t klen = strlen(key);
29+ if (!hdr || !key || klen == 0)
30 return -1;
31
32- const char* p = cistrstr(hdr, pat1);
33- if (!p)
34- p = cistrstr(hdr, pat2);
35- if (!p)
36- p = cistrstr(hdr, pat3);
37- if (!p)
38- return -1;
39+ const char* p = hdr;
40
41- p = strchr(p, ':');
42- if (!p)
43+ /* skip request line */
44+ const char* eol = strstr(p, "\r\n");
45+ if (!eol)
46 return -1;
47- p++;
48-
49- while (*p == ' ' || *p == '\t')
50- p++;
51+ p = eol + 2;
52+
53+ for (;;) {
54+ if (p[0] == '\r' && p[1] == '\n')
55+ break; /* end of headers */
56+
57+ const char* line_end = strstr(p, "\r\n");
58+ if (!line_end)
59+ break;
60+
61+ const char* colon = memchr(p, ':', (size_t)(line_end - p));
62+ if (colon) {
63+ size_t n = (size_t)(colon - p);
64+
65+ if (n == klen && ci_key_match(p, key, klen)) {
66+ const char* v = colon + 1;
67+ while (*v == ' ' || *v == '\t')
68+ v++;
69+
70+ size_t outn = 0;
71+ while (v < line_end) {
72+ if (outn + 1 >= 512)
73+ return -1;
74+ out[outn++] = *v++;
75+ }
76+ out[outn] = '\0';
77+
78+ if (outn == 0)
79+ return -1;
80+
81+ return 0;
82+ }
83+ }
84
85- size_t n = 0;
86- while (*p && *p != '\r' && *p != '\n') {
87- if (n + 1 >= 512)
88- return -1;
89- out[n++] = *p++;
90+ p = line_end + 2;
91 }
92- out[n] = '\0';
93
94- if (n == 0)
95- return -1;
96-
97- return 0;
98+ return -1;
99 }
100
101 int join_path(char* out, size_t outsz, const char* a, const char* b)
102 {
103- int n = snprintf(out, outsz, "%s/%s", a, b);
104- if (n < 0)
105+ if (!out || outsz == 0 || !a || !b)
106 return -1;
107
108- if ((size_t)n >= outsz)
109- return -1;
110+ if (a[0] == '\0') {
111+ int n = snprintf(out, outsz, "%s", b);
112+ if (n < 0 || (size_t)n >= outsz)
113+ return -1;
114+ return 0;
115+ }
116
117- return 0;
118+ if (b[0] == '\0') {
119+ int n = snprintf(out, outsz, "%s", a);
120+ if (n < 0 || (size_t)n >= outsz)
121+ return -1;
122+ return 0;
123+ }
124+
125+ size_t al = strlen(a);
126+
127+ /* avoid double slashes */
128+ if (a[al - 1] == '/')
129+ return snprintf(out, outsz, "%s%s", a, b) < (int)outsz ? 0 : -1;
130+
131+ return snprintf(out, outsz, "%s/%s", a, b) < (int)outsz ? 0 : -1;
132 }
133
134 int write_all(int fd, const void* buf, size_t n)