BUG/MINOR: httpclient: allow to replace the host header

This patch allows to replace the host header generated by the
httpclient instead of adding a new one, resulting in the server replying
an error 400.

The host header is now generated from the uri only if it wasn't found in
the list of headers.

Also add a new request in the VTC file to test this.

This patch must be backported in 2.5.
This commit is contained in:
William Lallemand 2021-11-24 15:38:17 +01:00
parent 27f88a9059
commit f03b53c81d
3 changed files with 37 additions and 12 deletions

View File

@ -1,10 +1,12 @@
local vtc_port = 0
local vtc_port2 = 0
local vtc_port3 = 0
core.register_service("fakeserv", "http", function(applet)
vtc_port = applet.headers["vtcport"][0]
vtc_port2 = applet.headers["vtcport2"][0]
vtc_port3 = applet.headers["vtcport3"][0]
core.Info("APPLET START")
local response = "OK"
applet:add_header("Server", "haproxy/webstats")
@ -38,6 +40,10 @@ local function cron()
local httpclient2 = core.httpclient()
local response2 = httpclient2:post{url="http://127.0.0.1:" .. vtc_port2, body=body}
core.Info("Third httpclient request")
local httpclient3 = core.httpclient()
local response3 = httpclient3:get{url="http://127.0.0.1:" .. vtc_port3, headers={ [ "Host" ] = { "foobar.haproxy.local" } }}
end
core.register_task(cron)

View File

@ -28,6 +28,14 @@ server s2 {
expect req.bodylen == 54000
} -start
server s3 {
rxreq
txresp -bodylen 54000
expect req.method == "GET"
expect req.http.host == "foobar.haproxy.local"
} -start
haproxy h1 -conf {
global
lua-load ${testdir}/lua_httpclient.lua
@ -44,7 +52,7 @@ haproxy h1 -conf {
} -start
client c0 -connect ${h1_fe1_sock} {
txreq -url "/" -hdr "vtcport: ${s1_port}" -hdr "vtcport2: ${s2_port}"
txreq -url "/" -hdr "vtcport: ${s1_port}" -hdr "vtcport2: ${s2_port}" -hdr "vtcport3: ${s3_port}"
rxresp
expect resp.status == 200
} -run
@ -52,3 +60,4 @@ client c0 -connect ${h1_fe1_sock} {
server s1 -wait
server s2 -wait
server s3 -wait

View File

@ -265,6 +265,8 @@ int httpclient_req_gen(struct httpclient *hc, const struct ist url, enum http_me
int err_code = 0;
struct ist meth_ist, vsn;
unsigned int flags = HTX_SL_F_VER_11 | HTX_SL_F_NORMALIZED_URI | HTX_SL_F_HAS_SCHM;
int i;
int foundhost = 0;
if (meth >= HTTP_METH_OTHER)
goto error;
@ -282,21 +284,29 @@ int httpclient_req_gen(struct httpclient *hc, const struct ist url, enum http_me
}
sl->info.req.meth = meth;
/* Add Host Header from URL */
if (!htx_add_header(htx, ist("Host"), ist("h")))
goto error;
if (!http_update_host(htx, sl, url))
goto error;
for (i = 0; hdrs && hdrs[i].n.len; i++) {
/* Don't check the value length because a header value may be empty */
if (isttest(hdrs[i].v) == 0)
continue;
/* add the headers and EOH */
if (hdrs) {
if (!htx_add_all_headers(htx, hdrs))
goto error;
} else {
if (!htx_add_endof(htx, HTX_BLK_EOH))
if (isteqi(hdrs[i].n, ist("host")))
foundhost = 1;
if (!htx_add_header(htx, hdrs[i].n, hdrs[i].v))
goto error;
}
if (!foundhost) {
/* Add Host Header from URL */
if (!htx_add_header(htx, ist("Host"), ist("h")))
goto error;
if (!http_update_host(htx, sl, url))
goto error;
}
if (!htx_add_endof(htx, HTX_BLK_EOH))
goto error;
if (isttest(payload)) {
/* add the payload if it can feat in the buffer, no need to set
* the Content-Length, the data will be sent chunked */