Haproxy removes the “Reason-Phrase” from the HTTP response status code.
I created a very basic php script to test this, the output is simply status code 400 with a reason phrase.
<?php
header(“HTTP/1.1 400 (The image exceeds the maximum width of 500px. Please adjust the image.)”);
When the request goes directly to the apache webserver I can see this using developer console in Chrome (Network -> Headers) and I get:
Status Code: 400 (The image exceeds the maximum width of 500px. Please adjust the image.)
When the Apache web server is proxied through Haproxy i get only the status code
Status Code: 400
So either there is a setting missing in my config to allow this or simply does not work. I have tried it on Haproxy 1.8, 1.9, 2.0 and 2.1 and I get the same problem.
Can anyone help?
I cannot reproduce, in both 1.8.23
and 2.2-dev8-786752-32
I see the response untouched:
* Trying 10.0.0.33...
* TCP_NODELAY set
* Connected to dev.lan.ltri.eu (10.0.0.33) port 80 (#0)
> GET /http-long-reason.php HTTP/1.1
> Host: dev.lan.ltri.eu
> User-Agent: curl/7.55.1
> Accept: */*
>
< HTTP/1.1 400 (The image exceeds the maximum width of 500px. Please adjust the image.)
< Server: nginx/1.14.0 (Ubuntu)
< Date: Tue, 23 Jun 2020 16:46:03 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< X-Hey: This-is-haproxy-speaking
<
* Connection #0 to host dev.lan.ltri.eu left intact
Can you provide the entire haproxy configuration and the entire output of curl -v
against Apache directly and vs haproxy?
Thanks for the response!
Ok, so you are right curl -v works fine, I can see the phrase but I cannot see it in Chrome, Firefox or Edge where we want to display this message to the end user.
Maybe this is a bug in those browsers, but it affects all of them! And only when my web server is proxied through Haproxy?
As you requested my HAproxy Config (I stripped it down to basics to try and solve this but this config creates the same problem in all those browsers)
Running V2.0.15
global
daemon
defaults
mode http
frontend general_frontend_web
mode http
bind *:80
use_backend backend_web
backend backend_web
balance roundrobin
server meetingorganizer1 meetingorganizer1:80 #disabled
Browser are the first thing I checked, it was displayed just fine.
A end user will never check the developer console in the browser for a specific HTTP response header reason.
Also, using long error message as HTTP response is completely unusual. HTTP response reasons are supposed to be short, like 2 or 3 words without any special characters.
Application level errors need to be in the HTTP payload instead.
On closer inspection I found it works when I drop my SSL configuration so something is wrong there. I will investigate
Also you are right about long error messages, I spoke to the developers about that and they want a third party service to upload these images to our system and then it dynamically generates a page for the end user.
None the less the problem is still there. Here is my config with ssl config:
global
daemon
maxconn 60 # Sets the maximum per-process number of concurrent connections to <number>.
maxsslconn 60 # Sets the maximum per-process number of concurrent SSL connections to <number>.
maxconnrate 60 # Sets the maximum per-process number of connections per second to <number>.
maxsslrate 60 # Sets the maximum per-process number of SSL sessions per second to <number>.
# intermediate configuration, tweak to your needs
ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
ssl-default-server-options no-sslv3 no-tlsv10 no-tlsv11 no-tls-tickets
ssl-dh-param-file /usr/local/etc/haproxy/cert/dhparam.pem
defaults
mode http
frontend general_frontend_web
mode http
#option forwardfor
bind *:80
# Wildcard cert
bind *:443 ssl crt /usr/local/etc/haproxy/cert/private/cert.pem alpn h2,http/1.1
use_backend backend_web
redirect scheme https code 301 if !{ ssl_fc }
backend backend_web
balance roundrobin
server meetingorganizer1 meetingorganizer1:80 #disabled
There is no reason phrase in HTTP/2. I guess you perform HTTP/2 requests from your browser.
2 Likes
Changed the bind like so:
bind *:443 ssl crt /usr/local/etc/haproxy/cert/private/cert.pem alpn http/1.1
This now works, have to see if we really want to default to http1.1.
Thanks, I had no idea this was not in HTTP2.0