aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/man3/Makefile1
-rw-r--r--doc/man3/http_strcasecmp.352
-rw-r--r--http.c26
-rw-r--r--include/libweb/http.h1
4 files changed, 80 insertions, 0 deletions
diff --git a/doc/man3/Makefile b/doc/man3/Makefile
index ffdbf16..160476f 100644
--- a/doc/man3/Makefile
+++ b/doc/man3/Makefile
@@ -28,6 +28,7 @@ OBJECTS = \
$(DESTDIR)$(man3dir)/http_encode_url.3 \
$(DESTDIR)$(man3dir)/http_free.3 \
$(DESTDIR)$(man3dir)/http_response_add_header.3 \
+ $(DESTDIR)$(man3dir)/http_strcasecmp.3 \
$(DESTDIR)$(man3dir)/http_strncasecmp.3 \
$(DESTDIR)$(man3dir)/http_update.3
diff --git a/doc/man3/http_strcasecmp.3 b/doc/man3/http_strcasecmp.3
new file mode 100644
index 0000000..3542ba8
--- /dev/null
+++ b/doc/man3/http_strcasecmp.3
@@ -0,0 +1,52 @@
+.TH HTTP_STRCASECMP 3 2026-02-27 0.6.0 "libweb Library Reference"
+
+.SH NAME
+http_strcasecmp \- compare two strings ignoring case as "POSIX" locale
+
+.SH SYNOPSIS
+.LP
+.nf
+#include <libweb/http.h>
+.P
+char *http_strcasecmp(const char *\fIs1\fP, const char *\fIs2\fP, size_t \fIn\fP);
+.fi
+
+.SH DESCRIPTION
+The
+.IR http_strcasecmp ()
+function compares two strings as done by
+.IR strcasecmp (3),
+but forces the use of the "POSIX" locale, so that characters are converted
+to lowercase with
+.IR tolower_l (3),
+rather than relying on the locale configured by the system.
+
+This makes
+.IR http_strcasecmp ()
+ideal to compare HTTP headers, which must be checked without case sensitivity
+according to RFC 9110.
+
+.SH RETURN VALUE
+If the comparison is successful, zero is returned. If the two strings
+are not equal (case ignored) or any of their characters could not be converted
+by
+.IR tolower_l(3) ,
+a positive integer is returned.
+Otherwise, a negative integer is returned.
+
+.SH ERRORS
+No errors are defined.
+
+.SH SEE ALSO
+.BR libweb_http (7),
+.BR http_strncasecmp (3).
+
+.B https://www.rfc-editor.org/rfc/rfc9110#name-field-names
+
+.SH COPYRIGHT
+Copyright (C) 2023-2026 libweb contributors
+.P
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
diff --git a/http.c b/http.c
index c3c36b2..451ec88 100644
--- a/http.c
+++ b/http.c
@@ -2975,6 +2975,32 @@ end:
return ret;
}
+int http_strcasecmp(const char *s1, const char *s2)
+{
+ 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;
+ }
+
+ while (*s1 && *s2)
+ if (tolower_l(*s1++, l) != tolower_l(*s2++, l))
+ {
+ ret = 1;
+ goto end;
+ }
+
+ ret = !!*s1 || !!*s2;
+end:
+ if (l != (locale_t)0)
+ freelocale(l);
+
+ return ret;
+}
+
int http_strncasecmp(const char *s1, const char *s2, const size_t n)
{
int ret = -1;
diff --git a/include/libweb/http.h b/include/libweb/http.h
index 41e1dce..4548efc 100644
--- a/include/libweb/http.h
+++ b/include/libweb/http.h
@@ -150,6 +150,7 @@ char *http_cookie_create(const char *key, const char *value,
const struct tm *exp);
char *http_encode_url(const char *url);
int http_decode_url(const char *url, bool spaces, char **out);
+int http_strcasecmp(const char *s1, const char *s2);
int http_strncasecmp(const char *s1, const char *s2, size_t n);
#endif /* HTTP_H */