1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
varnishtest "haproxy host header: map / redirect tests"
feature cmd "$HAPROXY_PROGRAM -cc 'version_atleast(2.5-dev5) && (feature(PCRE) || feature(PCRE2))'"
feature ignore_unknown_macro
server s1 {
rxreq
expect req.method == "GET"
expect req.http.host == "test1.example.com"
txresp -body "test1 ok"
} -start
server s2 {
rxreq
expect req.method == "GET"
expect req.http.host == "test2.example.com"
txresp -body "test2 ok"
} -start
server s3 {
rxreq
expect req.method == "GET"
expect req.http.host == "test3.example.com"
txresp -body "test3 ok"
} -start
server s4 {
rxreq
expect req.method == "GET"
expect req.http.host == "test1.example.invalid"
txresp -body "test1 after del map ok"
} -start
haproxy h1 -conf {
defaults
mode http
log global
option httplog
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
frontend fe1
bind "fd@${fe1}"
# automatically redirect matching paths from maps but skip rule on no-match
http-request redirect code 301 location %[path,map_str(${testdir}/map_redirect.map)] ignore-empty
# redirect Host: example.org / subdomain.example.org
http-request redirect prefix %[req.hdr(Host),lower,regsub(:\d+$,,),map_str(${testdir}/map_redirect.map)] code 301 if { hdr(Host),lower,regsub(:\d+$,,),map_str(${testdir}/map_redirect.map) -m found }
# set var and redirect in be1
http-request set-var(txn.testvar) req.hdr(Testvar),lower,regsub(:\d+$,,),map_str(${testdir}/map_redirect.map) if { hdr(Testvar),lower,regsub(:\d+$,,),map_str(${testdir}/map_redirect.map) -m found }
# use map to select backend (no default map value)
use_backend %[req.hdr(Host),lower,map_dom(${testdir}/map_redirect-be.map)] if { hdr_dom(Host) -i test1.example.com || hdr_dom(Host) -i test2.example.com }
# use map to select backend with default value(test3_be)
use_backend %[req.hdr(Host),lower,map_dom(${testdir}/map_redirect-be.map,test3_be)] if { hdr_dom(Host) -m end -i example.com }
# use map(after del map test1.example.com) default value(test4_be)
use_backend %[req.hdr(Host),lower,map_dom(${testdir}/map_redirect-be.map,test4_be)] if { hdr_dom(Host) -m end -i example.invalid }
default_backend be1
backend be1
http-request redirect prefix %[var(txn.testvar)] code 301 if { var(txn.testvar) -m found }
http-request deny
backend test1_be
server s1 ${s1_addr}:${s1_port}
backend test2_be
server s2 ${s2_addr}:${s2_port}
backend test3_be
server s3 ${s3_addr}:${s3_port}
backend test4_be
server s4 ${s4_addr}:${s4_port}
} -start
# Check map redirects
client c1 -connect ${h1_fe1_sock} {
txreq -hdr "Host: example.org:8443"
rxresp
expect resp.status == 301
expect resp.http.location ~ "https://www.example.org"
txreq -url /path/to/old/file
rxresp
expect resp.status == 301
expect resp.http.location ~ "/path/to/new/file"
# Closes connection
} -run
client c2 -connect ${h1_fe1_sock} {
txreq -hdr "Host: subdomain.example.org"
rxresp
expect resp.status == 301
expect resp.http.location ~ "https://www.subdomain.example.org"
# Closes connection
} -run
client c3 -connect ${h1_fe1_sock} {
# redirect on Testvar header
txreq -hdr "Testvar: subdomain.example.org"
rxresp
expect resp.status == 301
expect resp.http.location ~ "https://www.subdomain.example.org"
# Closes connection
} -run
client c4 -connect ${h1_fe1_sock} {
txreq -hdr "Host: www.subdomain.example.org"
rxresp
expect resp.status == 403
# Closes connection
} -run
client c5 -connect ${h1_fe1_sock} {
txreq -hdr "Testvar: www.subdomain.example.org"
rxresp
expect resp.status == 403
# Closes connection
} -run
client c6 -connect ${h1_fe1_sock} {
txreq -hdr "Host: :8443example.org"
rxresp
expect resp.status == 403
# Closes connection
} -run
# Check map backend selection
client c7 -connect ${h1_fe1_sock} {
txreq -hdr "Host: test1.example.com"
rxresp
expect resp.status == 200
expect resp.body == "test1 ok"
txreq -hdr "Host: test2.example.com"
rxresp
expect resp.status == 200
expect resp.body == "test2 ok"
txreq -hdr "Host: test3.example.com"
rxresp
expect resp.status == 200
expect resp.body == "test3 ok"
} -run
# cli show maps
haproxy h1 -cli {
send "show map ${testdir}/map_redirect.map"
expect ~ "^0x[a-f0-9]+ example\\.org https://www\\.example\\.org\\n0x[a-f0-9]+ subdomain\\.example\\.org https://www\\.subdomain\\.example\\.org\\n0x[a-f0-9]+ /path/to/old/file /path/to/new/file\n$"
send "show map ${testdir}/map_redirect-be.map"
expect ~ "^0x[a-f0-9]+ test1\\.example\\.com test1_be\\n0x[a-f0-9]+ test1\\.example\\.invalid test1_be\\n0x[a-f0-9]+ test2\\.example\\.com test2_be\\n$"
}
haproxy h1 -cli {
# clear map ${testdir}/map_redirect.map
send "clear map ${testdir}/map_redirect.map"
expect ~ "^\\n"
send "show map ${testdir}/map_redirect.map"
expect ~ "^\\n"
# add map ${testdir}/map_redirect.map
send "add map ${testdir}/map_redirect.map site1_key site1_value"
expect ~ "^\\n"
# add 2 more entries as payload
send "add map ${testdir}/map_redirect.map <<\nsite2_key site2_value\nsite3_key site3_value\n"
expect ~ "^\\n"
send "show map ${testdir}/map_redirect.map"
expect ~ "^0x[a-f0-9]+ site1_key site1_value\\n0x[a-f0-9]+ site2_key site2_value\\n0x[a-f0-9]+ site3_key site3_value\\n$"
# del map ${testdir}/map_redirect-be.map test1.example.{com,invalid}
send "del map ${testdir}/map_redirect-be.map test1.example.com"
expect ~ "^\\n"
send "del map ${testdir}/map_redirect-be.map test1.example.invalid"
expect ~ "^\\n"
send "show map ${testdir}/map_redirect-be.map"
expect ~ "^0x[a-f0-9]+ test2\\.example\\.com test2_be\\n$"
}
# Check map backend after del map
client c6 -connect ${h1_fe1_sock} {
# test1.example.invalid should go to test4_be after del map
txreq -hdr "Host: test1.example.invalid"
rxresp
expect resp.status == 200
expect resp.body == "test1 after del map ok"
} -run
|