haproxy/reg-tests/http-messaging/h1_host_normalization.vtc
Christopher Faulet 8d2514e087 BUG/MINOR: http-htx: Support default path during scheme based normalization
As stated in RFC3986, for an absolute-form URI, an empty path should be
normalized to a path of "/". This is part of scheme based normalization
rules. This kind of normalization is already performed for default ports. So
we might as well deal with the case of empty path.

The associated reg-tests was updated accordingly.

This patch should fix the issue #2573. It may be backported as far as 2.4 if
necessary.
2024-05-24 16:17:24 +02:00

907 lines
18 KiB
Plaintext

varnishtest "H1 authority validation and host normalizarion based on the scheme (rfc3982 6.3.2) or the method (connect)"
feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.6-dev0)'"
feature ignore_unknown_macro
barrier b1 cond 2 -cyclic
syslog S1 -level info {
# C1
recv
expect ~ "^.* uri: GET http://toto:poue@hostname/c1 HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C2
recv
expect ~ "^.* uri: GET http://hostname:8080/c2 HTTP/1.1; host: {hostname:8080}$"
barrier b1 sync
# C3
recv
expect ~ "^.* uri: GET https://hostname/c3 HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C4
recv
expect ~ "^.* uri: GET https://hostname:80/c4 HTTP/1.1; host: {hostname:80}$"
barrier b1 sync
# C5
recv
expect ~ "^.* uri: CONNECT hostname:80 HTTP/1.1; host: {hostname}$"
barrier b1 sync
recv
expect ~ "^.* uri: CONNECT hostname:80 HTTP/1.1; host: {hostname}$"
barrier b1 sync
recv
expect ~ "^.* uri: CONNECT hostname:80 HTTP/1.1; host: {hostname:}$"
barrier b1 sync
# C6
recv
expect ~ "^.* uri: CONNECT hostname:443 HTTP/1.1; host: {hostname}$"
barrier b1 sync
recv
expect ~ "^.* uri: CONNECT hostname:443 HTTP/1.1; host: {hostname}$"
barrier b1 sync
recv
expect ~ "^.* uri: CONNECT hostname:443 HTTP/1.1; host: {hostname:}$"
barrier b1 sync
# C7
recv
expect ~ "^.* uri: CONNECT hostname:8443 HTTP/1.1; host: {hostname:8443}$"
barrier b1 sync
# C8
recv
expect ~ "^.* uri: <BADREQ>; host: $"
barrier b1 sync
# C9
recv
expect ~ "^.* uri: <BADREQ>; host: $"
barrier b1 sync
# C10
recv
expect ~ "^.* uri: <BADREQ>; host: $"
barrier b1 sync
# C11
recv
expect ~ "^.* uri: <BADREQ>; host: $"
barrier b1 sync
# C12
recv
expect ~ "^.* uri: <BADREQ>; host: $"
barrier b1 sync
# C13
recv
expect ~ "^.* uri: <BADREQ>; host: $"
barrier b1 sync
# C14
recv
expect ~ "^.* uri: <BADREQ>; host: $"
barrier b1 sync
# C15
recv
expect ~ "^.* uri: <BADREQ>; host: $"
barrier b1 sync
# C16
recv
expect ~ "^.* uri: <BADREQ>; host: $"
barrier b1 sync
# C17
recv
barrier b1 sync
expect ~ "^.* uri: <BADREQ>; host: $"
# C18
recv
expect ~ "^.* uri: <BADREQ>; host: $"
barrier b1 sync
# C19
recv
expect ~ "^.* uri: <BADREQ>; host: $"
barrier b1 sync
# C20
recv
expect ~ "^.* uri: GET http://hostname/c20 HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C21
recv
expect ~ "^.* uri: GET https://hostname/c21 HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C22
recv
expect ~ "^.* uri: GET http://hostname/c22 HTTP/1.1; host: {hostname:80}$"
barrier b1 sync
# C23
recv
expect ~ "^.* uri: GET https://hostname/c23 HTTP/1.1; host: {hostname:443}$"
barrier b1 sync
# C24
recv
expect ~ "^.* uri: GET http://hostname/c24 HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C25
recv
expect ~ "^.* uri: GET https://hostname/c25 HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C26
recv
expect ~ "^.* uri: GET http://hostname/c26 HTTP/1.1; host: {hostname:}$"
barrier b1 sync
# C27
recv
expect ~ "^.* uri: GET https://hostname/c27 HTTP/1.1; host: {hostname:}$"
barrier b1 sync
# C28
recv
expect ~ "^.* uri: GET http://hostname/c28 HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C29
recv
expect ~ "^.* uri: GET http://hostname/c29 HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C30
recv
expect ~ "^.* uri: GET https://hostname/c30 HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C31
recv
expect ~ "^.* uri: GET https://hostname/c31 HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C32
recv
expect ~ "^.* uri: GET http:/// HTTP/1.1; host: {}$"
barrier b1 sync
# C33
recv
expect ~ "^.* uri: GET https:/// HTTP/1.1; host: {}$"
barrier b1 sync
# C34
recv
expect ~ "^.* uri: GET http:/// HTTP/1.1; host: {}$"
barrier b1 sync
# C35
recv
expect ~ "^.* uri: GET https:/// HTTP/1.1; host: {}$"
barrier b1 sync
# C36
recv
expect ~ "^.* uri: GET http://hostname/ HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C37
recv
expect ~ "^.* uri: GET http://hostname/ HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C38
recv
expect ~ "^.* uri: GET http://hostname/ HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C39
recv
expect ~ "^.* uri: GET https://hostname/ HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C40
recv
expect ~ "^.* uri: GET https://hostname/ HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C41
recv
expect ~ "^.* uri: GET https://hostname/ HTTP/1.1; host: {hostname}$"
barrier b1 sync
# C42
recv
expect ~ "^.* uri: GET http://hostname:81/ HTTP/1.1; host: {hostname:81}$"
barrier b1 sync
# C43
recv
expect ~ "^.* uri: GET https://hostname:444/ HTTP/1.1; host: {hostname:444}$"
} -start
haproxy h1 -conf {
defaults
mode http
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
frontend fe
bind "fd@${fe}"
http-request capture req.hdr(host) len 512
log-format "uri: %r; host: %hr"
log ${S1_addr}:${S1_port} len 2048 local0 debug err
http-request return status 200
} -start
# default port 80 with http scheme => should be normalized
# Be sure userinfo are skipped
client c1 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://toto:poue@hostname:80/c1" \
-hdr "host: hostname:80"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# port 8080 with http scheme => no normalization
client c2 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname:8080/c2" \
-hdr "host: hostname:8080"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# default port 443 with https scheme => should be normalized
client c3 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://hostname:443/c3" \
-hdr "host: hostname:443"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# port 80 with https scheme => no normalization
client c4 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://hostname:80/c4" \
-hdr "host: hostname:80"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# CONNECT on port 80 => should be normalized
client c5 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "hostname:80" \
-hdr "host: hostname:80"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c5 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "hostname:80" \
-hdr "host: hostname"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c5 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "hostname:80" \
-hdr "host: hostname:"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# CONNECT on port 443 => should be normalized
client c6 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "hostname:443" \
-hdr "host: hostname:443"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c6 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "hostname:443" \
-hdr "host: hostname"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c6 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "hostname:443" \
-hdr "host: hostname:"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# CONNECT on port non-default port => no normalization
client c7 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "hostname:8443" \
-hdr "host: hostname:8443"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# host miss-match => error
client c8 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname1/" \
-hdr "host: hostname2"
rxresp
expect resp.status == 400
} -run
# Wait matching on log message
barrier b1 sync
# port miss-match => error
client c9 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname:80/" \
-hdr "host: hostname:81"
rxresp
expect resp.status == 400
} -run
# Wait matching on log message
barrier b1 sync
# no host port with a non-default port in abs-uri => error
client c10 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname:8080/" \
-hdr "host: hostname"
rxresp
expect resp.status == 400
} -run
# Wait matching on log message
barrier b1 sync
# non-default host port with a default in abs-uri => error
client c11 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname/" \
-hdr "host: hostname:81"
rxresp
expect resp.status == 400
} -run
# Wait matching on log message
barrier b1 sync
# miss-match between host headers => error
client c12 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname1/" \
-hdr "host: hostname1" \
-hdr "host: hostname2"
rxresp
expect resp.status == 400
} -run
# Wait matching on log message
barrier b1 sync
# miss-match between host headers but with a normalization => error
client c13 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname1/" \
-hdr "host: hostname1:80" \
-hdr "host: hostname1"
rxresp
expect resp.status == 400
} -run
# Wait matching on log message
barrier b1 sync
# CONNECT authoriy without port => error
client c14 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "hostname" \
-hdr "host: hostname"
rxresp
expect resp.status == 400
} -run
# Wait matching on log message
barrier b1 sync
# host miss-match with CONNECT => error
client c15 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "hostname1:80" \
-hdr "host: hostname2:80"
rxresp
expect resp.status == 400
} -run
# Wait matching on log message
barrier b1 sync
# port miss-match with CONNECT => error
client c16 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "hostname:80" \
-hdr "host: hostname:443"
rxresp
expect resp.status == 400
} -run
# Wait matching on log message
barrier b1 sync
# no host port with non-default port in CONNECT authority => error
client c17 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "hostname:8080" \
-hdr "host: hostname"
rxresp
expect resp.status == 400
} -run
# Wait matching on log message
barrier b1 sync
# no authority => error
client c18 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "/" \
-hdr "host: hostname"
rxresp
expect resp.status == 400
} -run
# Wait matching on log message
barrier b1 sync
# no authority => error
client c19 -connect ${h1_fe_sock} {
txreq \
-req "CONNECT" \
-url "hostname:" \
-hdr "host: hostname"
rxresp
expect resp.status == 400
} -run
# Wait matching on log message
barrier b1 sync
# default port 80 with http scheme but no port for host value => should be normalized
client c20 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname:80/c20" \
-hdr "host: hostname"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# default port 443 with https scheme but no port for host value => should be normalized
client c21 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://hostname:443/c21" \
-hdr "host: hostname"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# http scheme, no port for the authority but default port for host value => no normalization
client c22 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname/c22" \
-hdr "host: hostname:80"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# https scheme, no port for the authority but default port for host value => no normalization
client c23 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://hostname/c23" \
-hdr "host: hostname:443"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# http scheme, empty port for the authority and no port for host value => should be normalized
client c24 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname:/c24" \
-hdr "host: hostname"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# https scheme, empty port for the authority and no port for host value => should be normalized
client c25 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://hostname:/c25" \
-hdr "host: hostname"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# http scheme, no port for the authority and empty port for host value => no normalization
client c26 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname/c26" \
-hdr "host: hostname:"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# https scheme, no port for the authority and empty port for host value => no normalization
client c27 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://hostname/c27" \
-hdr "host: hostname:"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# http scheme, default port for the authority and empty port for host value => should be normalized
client c28 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname:80/c28" \
-hdr "host: hostname:"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# http scheme, empty port for the authority and default port for host value => should be normalized
client c29 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname:/c29" \
-hdr "host: hostname:80"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# https scheme, default port for the authority and empty port for host value => should be normalized
client c30 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://hostname:443/c30" \
-hdr "host: hostname:"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# https scheme, empty port for the authority and default port for host value => should be normalized
client c31 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://hostname:/c31" \
-hdr "host: hostname:443"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# Strange cases
client c32 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://:" \
-hdr "host: :80"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c33 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://:" \
-hdr "host: :443"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
# Strange cases
client c34 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://:" \
-hdr "host: :"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c35 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://:" \
-hdr "host: :"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c36 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname" \
-hdr "host: hostname"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c37 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname:80" \
-hdr "host: hostname"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c38 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname:" \
-hdr "host: hostname"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c39 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://hostname" \
-hdr "host: hostname"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c40 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://hostname:443" \
-hdr "host: hostname"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c41 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://hostname:" \
-hdr "host: hostname"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c42 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "http://hostname:81" \
-hdr "host: hostname:81"
rxresp
expect resp.status == 200
} -run
# Wait matching on log message
barrier b1 sync
client c43 -connect ${h1_fe_sock} {
txreq \
-req "GET" \
-url "https://hostname:444" \
-hdr "host: hostname:444"
rxresp
expect resp.status == 200
} -run
syslog S1 -wait