Download raw body.
relayd: handle HEAD responses as bodyless
On Sat May 16, 2026 at 04:20:45PM +0200, Kirill A. Korinsky wrote:
> On Thu, 07 May 2026 18:45:59 +0200,
> Kirill A. Korinsky <kirill@korins.ky> wrote:
> >
> > On Thu, 07 May 2026 07:22:56 +0200,
> > Rafael Sadowski <rafael@sizeofvoid.org> wrote:
> > >
> > > On Thu May 07, 2026 at 03:17:06AM +0200, Kirill A. Korinsky wrote:
> > > > 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.
> > >
> > > I think here is more:
> > >
> > > "Any response to a HEAD request and any response with a 1xx
> > > (Informational), 204 (No Content), or 304 (Not Modified) status code is
> > > always terminated by the first empty line after the header fields,
> > > regardless of the header fields present in the message, and thus cannot
> > > contain a message body or trailer section."
> > > -- https://www.rfc-editor.org/rfc/rfc9112.html
> > >
> >
> > Yes, I missed that. That leads to this diff with your tweaks.
> >
>
> Anyone?
Sorry, I completely forgot about that. OK rsadowski
>
> 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 16:42:51 -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 headers_only = 0;
> enum httpmethod request_method = HTTP_METHOD_NONE;
>
> getmonotime(&con->se_tv_last);
> @@ -480,6 +481,16 @@ relay_read_http(struct bufferevent *bev,
>
> connection_close = kv_find_value(&desc->http_headers,
> "Connection", "close", ",");
> + /*
> + * RFC 9112 section 6.3: these responses end at the empty
> + * line after the header section. 101 upgrades become streams.
> + */
> + headers_only = cre->dir == RELAY_DIR_RESPONSE && !ws_response &&
> + (request_method == HTTP_METHOD_HEAD ||
> + (desc->http_status >= 100 && desc->http_status < 200) ||
> + desc->http_status == 204 || desc->http_status == 304);
> + if (headers_only)
> + cre->toread = 0;
>
> switch (desc->http_method) {
> case HTTP_METHOD_CONNECT:
> @@ -539,7 +550,7 @@ relay_read_http(struct bufferevent *bev,
> bev->readcb = relay_read_http;
> break;
> }
> - if (desc->http_chunked) {
> + if (desc->http_chunked && !headers_only) {
> /* Chunked transfer encoding */
> cre->toread = TOREAD_HTTP_CHUNK_LENGTH;
> bev->readcb = relay_read_httpchunks;
>
>
> --
> wbr, Kirill
>
relayd: handle HEAD responses as bodyless