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