aboutsummaryrefslogtreecommitdiff
path: root/http.c
diff options
context:
space:
mode:
authorXavier Del Campo Romero <xavi92@disroot.org>2026-02-27 12:30:45 +0100
committerXavier Del Campo Romero <xavi92@disroot.org>2026-02-27 16:28:52 +0100
commitd783e794c2fa6a9e6bffff9f41cdb7e8033bf3c3 (patch)
treedd7d835b79db8d9ed1c5cdfdbc82f8f3d694ba95 /http.c
parentfca0679e438e1cf8a3db9047f57d3b2363ab417e (diff)
Add http_strncasecmp(3)
POSIX.1-2008 does not any locale-specific version of strncasecmp(3), so conversions to lowercase depend on the system locale. Since HTTP header fields must be checked without case sensitivity and not depend on the system locale, a specialised function that forces the "POSIX" locale is required.
Diffstat (limited to 'http.c')
-rw-r--r--http.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/http.c b/http.c
index 261dcc0..c3c36b2 100644
--- a/http.c
+++ b/http.c
@@ -4,6 +4,7 @@
#include <dynstr.h>
#include <sys/types.h>
#include <unistd.h>
+#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <locale.h>
@@ -1592,13 +1593,18 @@ static int process_header(struct http_ctx *const h, const char *const line,
const struct header *const hdr = &headers[i];
int ret;
- if (!strncasecmp(line, hdr->header, n))
+ if ((ret = http_strncasecmp(line, hdr->header, n)))
{
- if ((ret = hdr->f(h, value)))
+ if (ret < 0)
+ {
+ fprintf(stderr, "%s: http_strncasecmp failed\n", __func__);
return ret;
-
- break;
+ }
}
+ else if ((ret = hdr->f(h, value)))
+ return ret;
+ else
+ break;
}
return append_header(h, line, n, value);
@@ -2968,3 +2974,30 @@ end:
return ret;
}
+
+int http_strncasecmp(const char *s1, const char *s2, const size_t n)
+{
+ int ret = -1;
+ const locale_t l = newlocale(LC_CTYPE_MASK, "POSIX", (locale_t)0);
+
+ if (l == (locale_t)0)
+ {
+ fprintf(stderr, "%s: newlocale(3): %s\n", __func__, strerror(errno));
+ goto end;
+ }
+
+ for (size_t i = 0; i < n; i++, s1++, s2++)
+ if (!*s1 || !*s2 || tolower_l(*s1, l) != tolower_l(*s2, l))
+ {
+ ret = 1;
+ goto end;
+ }
+
+ ret = 0;
+
+end:
+ if (l != (locale_t)0)
+ freelocale(l);
+
+ return ret;
+}