1
Fork 0

case-insensitive header name check and allow empty values

This commit is contained in:
Jan-Erik Rediger 2024-06-03 20:54:47 +02:00
parent f3a96257c7
commit 71f5648aa4

View file

@ -1,3 +1,4 @@
use ascii;
use bufio; use bufio;
use encoding::utf8; use encoding::utf8;
use fmt; use fmt;
@ -12,7 +13,8 @@ export type header = [](str, str);
// be canonicalized by the caller. // be canonicalized by the caller.
export fn header_add(head: *header, name: str, val: str) void = { export fn header_add(head: *header, name: str, val: str) void = {
assert(len(name) >= 1 && len(val) >= 1); assert(len(name) >= 1 && len(val) >= 1);
append(head, (strings::dup(name), strings::dup(val))); let name = ascii::strlower(name);
append(head, (name, strings::dup(val)));
}; };
// Sets the value of a given HTTP header, removing any previous values. The name // Sets the value of a given HTTP header, removing any previous values. The name
@ -26,7 +28,7 @@ export fn header_set(head: *header, name: str, val: str) void = {
// the given name, all matching headers are removed. // the given name, all matching headers are removed.
export fn header_del(head: *header, name: str) void = { export fn header_del(head: *header, name: str) void = {
for (let i = 0z; i < len(head); i += 1) { for (let i = 0z; i < len(head); i += 1) {
if (head[i].0 == name) { if (ascii::strcasecmp(head[i].0, name) == 0) {
free(head[i].0); free(head[i].0);
free(head[i].1); free(head[i].1);
delete(head[i]); delete(head[i]);
@ -40,7 +42,7 @@ export fn header_del(head: *header, name: str) void = {
export fn header_get(head: *header, name: str) str = { export fn header_get(head: *header, name: str) str = {
for (let i = 0z; i < len(head); i += 1) { for (let i = 0z; i < len(head); i += 1) {
const (key, val) = head[i]; const (key, val) = head[i];
if (key == name) { if (ascii::strcasecmp(key, name) == 0) {
return val; return val;
}; };
}; };
@ -96,7 +98,7 @@ fn read_header(head: *header, scan: *bufio::scanner) (void | io::error | protoer
let (name, val) = strings::cut(item, ":"); let (name, val) = strings::cut(item, ":");
val = strings::trim(val); val = strings::trim(val);
if (val == "") { if (val == "") {
return protoerr; continue;
}; };
// TODO: validate field-name // TODO: validate field-name