Skip to content

Commit 675efbb

Browse files
committed
hrw4u: Sync Python transpiler and add roundtrip tests
Extract hrw4u-specific changes from #12825. Fixes issues in the Python transpiler found during C++ parser development, normalizes autest .conf rules for bidirectional conversion, and adds roundtrip tests verifying hrw4u<->conf equivalence.
1 parent efeeffa commit 675efbb

62 files changed

Lines changed: 1186 additions & 219 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

tests/gold_tests/pluginTest/header_rewrite/rules/complex_logics.conf

Lines changed: 67 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@
1414
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1515
# See the License for the specific language governing permissions and
1616
# limitations under the License.
17-
1817
# All rules use SEND_RESPONSE_HDR_HOOK so set-header operates on the
1918
# response that the client sees. CLIENT-HEADER and CLIENT-URL:PATH
2019
# conditions always refer to the original client request regardless of hook.
21-
2220
# ---- Test: GROUP with [OR] on GROUP:END ----
2321
# hrw4u: if (inbound.req.X-Group-A) || inbound.req.X-Group-B
2422
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
@@ -28,128 +26,128 @@ cond %{GROUP}
2826
cond %{GROUP:END} [OR]
2927
cond %{CLIENT-HEADER:X-Group-B} ="" [NOT]
3028
set-header X-Group-Or-Result "matched"
29+
# ---- Test: GROUP with [AND] on GROUP:END (explicit) ----
30+
# hrw4u: if (inbound.req.X-And-A) && inbound.req.X-And-B
3131

32-
# ---- Test: GROUP with [AND] on GROUP:END (explicit) ----
33-
# hrw4u: if (inbound.req.X-And-A) && inbound.req.X-And-B
3432
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
3533
cond %{CLIENT-URL:PATH} /\/logic\/group-and$/ [AND]
3634
cond %{GROUP}
3735
cond %{CLIENT-HEADER:X-And-A} ="" [NOT]
3836
cond %{GROUP:END} [AND]
3937
cond %{CLIENT-HEADER:X-And-B} ="" [NOT]
4038
set-header X-Group-And-Result "matched"
39+
# ---- Test: GROUP with [NOT] on GROUP:END ----
40+
# hrw4u: if !(inbound.req.X-Not-A && inbound.req.X-Not-B)
4141

42-
# ---- Test: GROUP with [NOT] on GROUP:END ----
43-
# hrw4u: if !(inbound.req.X-Not-A && inbound.req.X-Not-B)
4442
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
4543
cond %{CLIENT-URL:PATH} /\/logic\/group-not$/ [AND]
4644
cond %{GROUP}
47-
cond %{CLIENT-HEADER:X-Not-A} ="" [NOT]
45+
cond %{CLIENT-HEADER:X-Not-A} ="" [AND,NOT]
4846
cond %{CLIENT-HEADER:X-Not-B} ="" [NOT]
4947
cond %{GROUP:END} [NOT]
5048
set-header X-Group-Not-Result "matched"
49+
# ---- Test: Nested GROUPs with mixed OR/AND ----
50+
# hrw4u: if inbound.req.X-Outer-A && (inbound.req.X-Inner-A || inbound.req.X-Inner-B)
5151

52-
# ---- Test: Nested GROUPs with mixed OR/AND ----
53-
# hrw4u: if inbound.req.X-Outer-A && (inbound.req.X-Inner-A || inbound.req.X-Inner-B)
5452
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
5553
cond %{CLIENT-URL:PATH} /\/logic\/nested-group$/ [AND]
56-
cond %{CLIENT-HEADER:X-Outer-A} ="" [NOT]
54+
cond %{CLIENT-HEADER:X-Outer-A} ="" [AND,NOT]
5755
cond %{GROUP}
58-
cond %{CLIENT-HEADER:X-Inner-A} ="" [NOT,OR]
56+
cond %{CLIENT-HEADER:X-Inner-A} ="" [OR,NOT]
5957
cond %{CLIENT-HEADER:X-Inner-B} ="" [NOT]
6058
cond %{GROUP:END}
6159
set-header X-Nested-Group-Result "matched"
60+
# ---- Test: Two GROUPs with OR between them ----
61+
# hrw4u: if (inbound.req.X-Left-A && inbound.req.X-Left-B) || (inbound.req.X-Right-A && inbound.req.X-Right-B)
6262

63-
# ---- Test: Two GROUPs with OR between them ----
64-
# hrw4u: if (inbound.req.X-Left-A && inbound.req.X-Left-B) || (inbound.req.X-Right-A && inbound.req.X-Right-B)
6563
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
6664
cond %{CLIENT-URL:PATH} /\/logic\/two-groups$/ [AND]
6765
cond %{GROUP}
68-
cond %{CLIENT-HEADER:X-Left-A} ="" [NOT]
66+
cond %{CLIENT-HEADER:X-Left-A} ="" [AND,NOT]
6967
cond %{CLIENT-HEADER:X-Left-B} ="" [NOT]
7068
cond %{GROUP:END} [OR]
7169
cond %{GROUP}
72-
cond %{CLIENT-HEADER:X-Right-A} ="" [NOT]
70+
cond %{CLIENT-HEADER:X-Right-A} ="" [AND,NOT]
7371
cond %{CLIENT-HEADER:X-Right-B} ="" [NOT]
7472
cond %{GROUP:END}
7573
set-header X-Two-Groups-Result "matched"
74+
# ---- Test: GROUP inside if/elif/else ----
75+
# hrw4u:
76+
# if inbound.req.X-Branch == "alpha" && (inbound.req.X-Sub-A || inbound.req.X-Sub-B)
77+
# -> "alpha"
78+
# elif inbound.req.X-Branch == "beta"
79+
# -> "beta"
80+
# else
81+
# -> "other"
7682

77-
# ---- Test: GROUP inside if/elif/else ----
78-
# hrw4u:
79-
# if inbound.req.X-Branch == "alpha" && (inbound.req.X-Sub-A || inbound.req.X-Sub-B)
80-
# -> "alpha"
81-
# elif inbound.req.X-Branch == "beta"
82-
# -> "beta"
83-
# else
84-
# -> "other"
85-
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
86-
cond %{CLIENT-URL:PATH} /\/logic\/if-group$/ [AND]
87-
if
88-
cond %{CLIENT-HEADER:X-Branch} ="alpha"
89-
cond %{GROUP}
90-
cond %{CLIENT-HEADER:X-Sub-A} ="" [NOT,OR]
91-
cond %{CLIENT-HEADER:X-Sub-B} ="" [NOT]
92-
cond %{GROUP:END}
93-
set-header X-If-Group-Result "alpha"
94-
elif
95-
cond %{CLIENT-HEADER:X-Branch} ="beta"
96-
set-header X-If-Group-Result "beta"
97-
else
98-
set-header X-If-Group-Result "other"
99-
endif
100-
101-
# ---- Test: GROUP with OR inside nested if ----
102-
# hrw4u:
103-
# if inbound.req.X-Outer == "yes"
104-
# if (inbound.req.X-Case-A || inbound.req.X-Case-B)
105-
# -> "inner-match"
106-
# else
107-
# -> "inner-miss"
108-
# else
109-
# -> "outer-miss"
11083
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
111-
cond %{CLIENT-URL:PATH} /\/logic\/nested-if-group$/ [AND]
112-
if
113-
cond %{CLIENT-HEADER:X-Outer} ="yes"
114-
if
84+
cond %{CLIENT-URL:PATH} /\/logic\/if-group$/
85+
if
86+
cond %{CLIENT-HEADER:X-Branch} ="alpha" [AND]
11587
cond %{GROUP}
116-
cond %{CLIENT-HEADER:X-Case-A} ="" [NOT,OR]
117-
cond %{CLIENT-HEADER:X-Case-B} ="" [NOT]
88+
cond %{CLIENT-HEADER:X-Sub-A} ="" [OR,NOT]
89+
cond %{CLIENT-HEADER:X-Sub-B} ="" [NOT]
11890
cond %{GROUP:END}
119-
set-header X-Nested-If-Result "inner-match"
120-
else
121-
set-header X-Nested-If-Result "inner-miss"
122-
endif
123-
else
124-
set-header X-Nested-If-Result "outer-miss"
125-
endif
91+
set-header X-If-Group-Result "alpha"
92+
elif
93+
cond %{CLIENT-HEADER:X-Branch} ="beta"
94+
set-header X-If-Group-Result "beta"
95+
else
96+
set-header X-If-Group-Result "other"
97+
endif
98+
# ---- Test: GROUP with OR inside nested if ----
99+
# hrw4u:
100+
# if inbound.req.X-Outer == "yes"
101+
# if (inbound.req.X-Case-A || inbound.req.X-Case-B)
102+
# -> "inner-match"
103+
# else
104+
# -> "inner-miss"
105+
# else
106+
# -> "outer-miss"
107+
108+
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
109+
cond %{CLIENT-URL:PATH} /\/logic\/nested-if-group$/
110+
if
111+
cond %{CLIENT-HEADER:X-Outer} ="yes"
112+
if
113+
cond %{GROUP}
114+
cond %{CLIENT-HEADER:X-Case-A} ="" [OR,NOT]
115+
cond %{CLIENT-HEADER:X-Case-B} ="" [NOT]
116+
cond %{GROUP:END}
117+
set-header X-Nested-If-Result "inner-match"
118+
else
119+
set-header X-Nested-If-Result "inner-miss"
120+
endif
121+
else
122+
set-header X-Nested-If-Result "outer-miss"
123+
endif
124+
# ---- Test: Complex expression: (A OR B) AND (C OR D) ----
125+
# hrw4u: if (inbound.req.X-P || inbound.req.X-Q) && (inbound.req.X-R || inbound.req.X-S)
126126

127-
# ---- Test: Complex expression: (A OR B) AND (C OR D) ----
128-
# hrw4u: if (inbound.req.X-P || inbound.req.X-Q) && (inbound.req.X-R || inbound.req.X-S)
129127
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
130128
cond %{CLIENT-URL:PATH} /\/logic\/complex-and-or$/ [AND]
131129
cond %{GROUP}
132-
cond %{CLIENT-HEADER:X-P} ="" [NOT,OR]
130+
cond %{CLIENT-HEADER:X-P} ="" [OR,NOT]
133131
cond %{CLIENT-HEADER:X-Q} ="" [NOT]
134132
cond %{GROUP:END} [AND]
135133
cond %{GROUP}
136-
cond %{CLIENT-HEADER:X-R} ="" [NOT,OR]
134+
cond %{CLIENT-HEADER:X-R} ="" [OR,NOT]
137135
cond %{CLIENT-HEADER:X-S} ="" [NOT]
138136
cond %{GROUP:END}
139137
set-header X-Complex-Result "matched"
138+
# ---- Test: IP:CLIENT in GROUP with [OR]
139+
# hrw4u: if (inbound.ip in {127.0.0.0/8}) || inbound.req.X-Outer == "true"
140140

141-
# ---- Test: IP:CLIENT in GROUP with [OR]
142-
# hrw4u: if (inbound.ip in {127.0.0.0/8}) || inbound.req.X-Outer == "true"
143141
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
144142
cond %{CLIENT-URL:PATH} /\/logic\/ip-group-or$/ [AND]
145143
cond %{GROUP}
146144
cond %{IP:CLIENT} {127.0.0.0/8}
147145
cond %{GROUP:END} [OR]
148146
cond %{CLIENT-HEADER:X-Outer} ="true"
149147
set-header X-Ip-Group-Or-Result "matched"
148+
# ---- Test: GROUP as first condition after hook ----
149+
# hrw4u: if (inbound.url.path ~ /\/logic\/group-first$/) && inbound.req.X-First-A
150150

151-
# ---- Test: GROUP as first condition after hook ----
152-
# hrw4u: if (inbound.url.path ~ /\/logic\/group-first$/) && inbound.req.X-First-A
153151
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
154152
cond %{GROUP}
155153
cond %{CLIENT-URL:PATH} /\/logic\/group-first$/
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
# All rules use SEND_RESPONSE_HDR_HOOK so set-header operates on the
18+
# response that the client sees. CLIENT-HEADER and CLIENT-URL:PATH
19+
# conditions always refer to the original client request regardless of hook.
20+
# ---- Test: GROUP with [OR] on GROUP:END ----
21+
# hrw4u: if (inbound.req.X-Group-A) || inbound.req.X-Group-B
22+
SEND_RESPONSE {
23+
if inbound.url.path ~ /\/logic\/group-or$/ && (inbound.req.X-Group-A) || inbound.req.X-Group-B {
24+
inbound.resp.X-Group-Or-Result = "matched";
25+
# ---- Test: GROUP with [AND] on GROUP:END (explicit) ----
26+
# hrw4u: if (inbound.req.X-And-A) && inbound.req.X-And-B
27+
}
28+
}
29+
30+
SEND_RESPONSE {
31+
if inbound.url.path ~ /\/logic\/group-and$/ && (inbound.req.X-And-A) && inbound.req.X-And-B {
32+
inbound.resp.X-Group-And-Result = "matched";
33+
# ---- Test: GROUP with [NOT] on GROUP:END ----
34+
# hrw4u: if !(inbound.req.X-Not-A && inbound.req.X-Not-B)
35+
}
36+
}
37+
38+
SEND_RESPONSE {
39+
if inbound.url.path ~ /\/logic\/group-not$/ && !(inbound.req.X-Not-A && inbound.req.X-Not-B) {
40+
inbound.resp.X-Group-Not-Result = "matched";
41+
# ---- Test: Nested GROUPs with mixed OR/AND ----
42+
# hrw4u: if inbound.req.X-Outer-A && (inbound.req.X-Inner-A || inbound.req.X-Inner-B)
43+
}
44+
}
45+
46+
SEND_RESPONSE {
47+
if inbound.url.path ~ /\/logic\/nested-group$/ && inbound.req.X-Outer-A && (inbound.req.X-Inner-A || inbound.req.X-Inner-B) {
48+
inbound.resp.X-Nested-Group-Result = "matched";
49+
# ---- Test: Two GROUPs with OR between them ----
50+
# hrw4u: if (inbound.req.X-Left-A && inbound.req.X-Left-B) || (inbound.req.X-Right-A && inbound.req.X-Right-B)
51+
}
52+
}
53+
54+
SEND_RESPONSE {
55+
if inbound.url.path ~ /\/logic\/two-groups$/ && (inbound.req.X-Left-A && inbound.req.X-Left-B) || (inbound.req.X-Right-A && inbound.req.X-Right-B) {
56+
inbound.resp.X-Two-Groups-Result = "matched";
57+
# ---- Test: GROUP inside if/elif/else ----
58+
# hrw4u:
59+
# if inbound.req.X-Branch == "alpha" && (inbound.req.X-Sub-A || inbound.req.X-Sub-B)
60+
# -> "alpha"
61+
# elif inbound.req.X-Branch == "beta"
62+
# -> "beta"
63+
# else
64+
# -> "other"
65+
}
66+
}
67+
68+
SEND_RESPONSE {
69+
if inbound.url.path ~ /\/logic\/if-group$/ {
70+
if inbound.req.X-Branch == "alpha" && (inbound.req.X-Sub-A || inbound.req.X-Sub-B) {
71+
inbound.resp.X-If-Group-Result = "alpha";
72+
} elif inbound.req.X-Branch == "beta" {
73+
inbound.resp.X-If-Group-Result = "beta";
74+
} else {
75+
inbound.resp.X-If-Group-Result = "other";
76+
}
77+
# ---- Test: GROUP with OR inside nested if ----
78+
# hrw4u:
79+
# if inbound.req.X-Outer == "yes"
80+
# if (inbound.req.X-Case-A || inbound.req.X-Case-B)
81+
# -> "inner-match"
82+
# else
83+
# -> "inner-miss"
84+
# else
85+
# -> "outer-miss"
86+
}
87+
}
88+
89+
SEND_RESPONSE {
90+
if inbound.url.path ~ /\/logic\/nested-if-group$/ {
91+
if inbound.req.X-Outer == "yes" {
92+
if (inbound.req.X-Case-A || inbound.req.X-Case-B) {
93+
inbound.resp.X-Nested-If-Result = "inner-match";
94+
} else {
95+
inbound.resp.X-Nested-If-Result = "inner-miss";
96+
}
97+
} else {
98+
inbound.resp.X-Nested-If-Result = "outer-miss";
99+
}
100+
# ---- Test: Complex expression: (A OR B) AND (C OR D) ----
101+
# hrw4u: if (inbound.req.X-P || inbound.req.X-Q) && (inbound.req.X-R || inbound.req.X-S)
102+
}
103+
}
104+
105+
SEND_RESPONSE {
106+
if inbound.url.path ~ /\/logic\/complex-and-or$/ && (inbound.req.X-P || inbound.req.X-Q) && (inbound.req.X-R || inbound.req.X-S) {
107+
inbound.resp.X-Complex-Result = "matched";
108+
# ---- Test: IP:CLIENT in GROUP with [OR]
109+
# hrw4u: if (inbound.ip in {127.0.0.0/8}) || inbound.req.X-Outer == "true"
110+
}
111+
}
112+
113+
SEND_RESPONSE {
114+
if inbound.url.path ~ /\/logic\/ip-group-or$/ && (inbound.ip in {127.0.0.0/8}) || inbound.req.X-Outer == "true" {
115+
inbound.resp.X-Ip-Group-Or-Result = "matched";
116+
# ---- Test: GROUP as first condition after hook ----
117+
# hrw4u: if (inbound.url.path ~ /\/logic\/group-first$/) && inbound.req.X-First-A
118+
}
119+
}
120+
121+
SEND_RESPONSE {
122+
if (inbound.url.path ~ /\/logic\/group-first$/) && inbound.req.X-First-A {
123+
inbound.resp.X-Group-First-Result = "matched";
124+
}
125+
}

tests/gold_tests/pluginTest/header_rewrite/rules/glob_set_redirect.conf

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,10 @@
1414
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1515
# See the License for the specific language governing permissions and
1616
# limitations under the License.
17-
1817
cond %{READ_RESPONSE_HDR_HOOK} [AND]
1918
cond %{ID:REQUEST} =0
20-
set-redirect 301 http://redirect.com/here
19+
set-redirect 301 "http://redirect.com/here"
2120

2221
cond %{SEND_RESPONSE_HDR_HOOK} [AND]
2322
cond %{ID:REQUEST} =1
24-
set-redirect 301 http://redirect.com/here
23+
set-redirect 301 "http://redirect.com/here"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
READ_RESPONSE {
18+
if id.REQUEST == 0 {
19+
set-redirect(301, "http://redirect.com/here");
20+
}
21+
}
22+
23+
SEND_RESPONSE {
24+
if id.REQUEST == 1 {
25+
set-redirect(301, "http://redirect.com/here");
26+
}
27+
}

0 commit comments

Comments
 (0)