Commits


relayd: strip Content-Length for chunked messages RFC 9112 section 6.1 requires an intermediary that forwards a message carrying Transfer-Encoding to remove any received Content-Length first. relayd already parses the body as chunked in this case, but previously left Content-Length in the header tree, so the backend could receive both framing fields and choose a different message boundary. When chunked framing is selected, remove Content-Length before header emission; this preserves relayd's chunked body handling while avoiding CL.TE ambiguity downstream. Reproted by: Stuart Thomas OK: rsaodwski@


relayd: reject obs-fold to prevent parser differentials (RFC 9112 5.2) Replace silent kv_extend normalisation with an unconditional reject. RFC 9112 5.2 permits rejection; it is safer than SP replacement for a forwarding proxy and handles both request and response direction. kv_extend is therefore no longer required. Reported by Stuart Thomas, OK kirill@


relayd: add support for the MKCALENDAR HTTP method relayd is missing this method from the WebDAV/CalDAV extensions. This causes issues when using relayd as a reverse proxy in front of CalDAV servers like Nextcloud. OK kirill@


usr.sbin/relayd: handle HTTP responses without bodies RFC 9112 section 6.3 specifies that responses to HEAD requests, and responses with 1xx, 204, or 304 status codes, are terminated by the empty line after the header section regardless of Content-Length or Transfer-Encoding. They cannot contain a message body or trailer section. Teach relayd to apply that framing rule before deciding whether a response body is bounded. Otherwise relayd treats these responses as unbounded, adds Connection: close, and can forward both the backend's Connection: keep-alive and its own Connection: close. Tweaks and OK: rsadowski@


relayd: error check bsearch in relay_httperror_byid() If relay_httperror_byid() is passed a HTTP error code not in the table this would result in a NULL deref. The intent is that the code fall back to "Unknown error" on NULL return. From Jan Schreiber


relayd: fix NULL check for strdup() Due to a copy-paste error, relay_lookup_query() would check the wrong kv member for NULL. From Jan Schreiber


Move HTTP start-line logic to a dedicated function This is a structural refactoring with no functional change. OK kirill


Standardize logging with bgpd OK claudio@


fix missing initialisation It is possible that "request_method" is checked without having been initialised in line 439. OK kirill@ stsp@


relayd: fix relay_http_time() to emit GMT times again The HTTP standard RFC 9110 requires GMT, in HTTP-date. We used to do this until a recent modification to localtime.c changed GMT to UTC. sync from httpd


Fix regression introduced in previous causing HEAD requests to be erroneously rejected as malformed. ok chrisz@


Keep Content-length header in HEAD responses. ok millert@


cleanup unused variable


relay_read_http: strip out Content-Length if we strip the body too We should not forward Content-Length if the body is not also forwarded.


relay_read_http: defer header parsing until after line continuation Wait until we have a complete line before parsing the Content-Length, Transfer-Encoding and Host headers. This prevents potential request smuggling attacks. Filtering already happens after header line continuation has been performed. Reported by Ben Kallus. OK claudio@


relay_read_http: tighten up header parsing 1) reject headers with embedded NULs 2) reject headers with invalid characters in the name 3) reject Transfer-Encoding with values other than "chunked" 4) reject chunk values containing non-hex characters 5) reject Content-Length values of "+0" or "-0" 6) reject requests without a ' ' and headers without a ':' Reported by Ben Kallus, OK bluhm@


{en,de}queing -> {en,de}queuing; from paul tagliamonte


do not duplicate "Connection: close" headers and only add it if its not a websockets response. Reported by Marcus MERIGHI and Jonathon Fletcher, this fix is by Jonathon, Thanks! ok claudio@


The output of server_root_strip() is a string. Use the correct format "%s". Same for the output of relay_expand_http(). with and ok claudio@ Found by Cedric Tessier, thanks!


Responses to HEAD requests must not have a message body (even though they have a Content-Length header). HTTP RFC 7231 section 4.3.2. found by niklas@, claudio@ agrees.


Add 'strip' directive Feedback by Olivier Cherrier, Hiltjo Posthuma, Mischa OK benno@


Replace TAILQ concatenation loop with TAILQ_CONCAT OK millert@, florian@


Don't "forward to <table>" when a "forward to destination" address is set. This matches the documented behaviour. On matching "forward to <table>" filter rules the "forward to destination" address is unset, so that in that case the "forward to <table>" rule is still used. OK benno@, regression tests still passing.


Add a new macro called $HOST that expands to the Host header's value or falls back to the same value as $SERVER_ADDR in case the Host header is not available. ok reyk@


Add Connection: close when switching to "unlimited" reading mode. Ask the server to close the connection after the request since we don't read any further request headers. This fixes an issue with OPTIONS and optional body, as well as similar cases. Reported and tested by Rivo Nurges OK benno@