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)