From: Kirill A. Korinsky Subject: relayd: handle HEAD responses as bodyless To: OpenBSD tech Date: Thu, 07 May 2026 03:17:06 +0200 tech@, RFC 9110 defines HEAD as GET without response content; RFC 9112 Section 6.3 makes the HTTP/1.1 framing rule explicit: any response to a HEAD request is terminated by the empty line after the header section, regardless of Content-Length or Transfer-Encoding. Follow that semantic in relayd instead of switching the response to an unbounded body and adding Connection: close. This avoids forwarding both Connection: keep-alive from the backend and relayd's added Connection: close. Ok? Index: usr.sbin/relayd/relay_http.c =================================================================== RCS file: /home/cvs/src/usr.sbin/relayd/relay_http.c,v diff -u -p -r1.96 relay_http.c --- usr.sbin/relayd/relay_http.c 2 Apr 2026 13:35:36 -0000 1.96 +++ usr.sbin/relayd/relay_http.c 7 May 2026 01:05:52 -0000 @@ -196,6 +196,7 @@ relay_read_http(struct bufferevent *bev, struct kv *upgrade = NULL, *upgrade_ws = NULL; struct kv *connection_close = NULL; int ws_response = 0; + int head_response = 0; enum httpmethod request_method = HTTP_METHOD_NONE; getmonotime(&con->se_tv_last); @@ -480,6 +481,10 @@ relay_read_http(struct bufferevent *bev, connection_close = kv_find_value(&desc->http_headers, "Connection", "close", ","); + head_response = cre->dir == RELAY_DIR_RESPONSE && + request_method == HTTP_METHOD_HEAD; + if (head_response) + cre->toread = 0; switch (desc->http_method) { case HTTP_METHOD_CONNECT: @@ -539,7 +544,7 @@ relay_read_http(struct bufferevent *bev, bev->readcb = relay_read_http; break; } - if (desc->http_chunked) { + if (desc->http_chunked && !head_response) { /* Chunked transfer encoding */ cre->toread = TOREAD_HTTP_CHUNK_LENGTH; bev->readcb = relay_read_httpchunks; -- wbr, Kirill