Hello,

I accidentally noticed that HAproxy doesn't follow the HTTP standard when it comes to HEAD requests. Using an 'errofile' directive will return whatever is inside, which often means a HTTP header + a body (used to display a nice error page to the end user).

The standard of course forbids this (https://tools.ietf.org/html/rfc7231):
4.3.2. HEAD
   The HEAD method is identical to GET except that the server MUST NOT
   send a message body in the response (i.e., the response terminates at
   the end of the header section).


The easiest fix would be to just ignore errorfile directive on HEAD requests, but that might cause problems for people who, like me, abuse the errorfile directive to rewrite the return error code (and remove the body in the process). If this is the approach we are willing to take, the patch is attached.

The other option I see is to add something like 'force-send' to the errorfile directive for people who are sure they want to send the content on HEAD requests.
>From 14b734e1234513b4ebf22d3292a216ae3a279c32 Mon Sep 17 00:00:00 2001
From: Nenad Merdanovic <ni...@nimzo.info>
Date: Sun, 5 Oct 2014 19:30:38 +0200
Subject: [PATCH] BUG/MINOR: http: Don't send errofile on HTTP HEAD requests

As per HTTP standard, the HEAD responses must not contain a body
and due to that we must not honor the 'errorfile' specified.

See: RFC7231, section 4.3.2.
---
 src/proto_http.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/proto_http.c b/src/proto_http.c
index 89e91a9..3d6af1c 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -784,12 +784,13 @@ static void http_server_error(struct session *s, struct stream_interface *si,
 
 struct chunk *http_error_message(struct session *s, int msgnum)
 {
-	if (s->be->errmsg[msgnum].str)
-		return &s->be->errmsg[msgnum];
-	else if (s->fe->errmsg[msgnum].str)
-		return &s->fe->errmsg[msgnum];
-	else
-		return &http_err_chunks[msgnum];
+	if(s->txn.meth != HTTP_METH_HEAD) {
+		if (s->be->errmsg[msgnum].str)
+			return &s->be->errmsg[msgnum];
+		else if (s->fe->errmsg[msgnum].str)
+			return &s->fe->errmsg[msgnum];
+	}
+	return &http_err_chunks[msgnum];
 }
 
 /*
-- 
2.1.0

Reply via email to