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
2422cond %{SEND_RESPONSE_HDR_HOOK} [AND]
@@ -28,128 +26,128 @@ cond %{GROUP}
2826cond %{GROUP:END} [OR]
2927cond %{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
3432cond %{SEND_RESPONSE_HDR_HOOK} [AND]
3533cond %{CLIENT-URL:PATH} /\/logic\/group-and$/ [AND]
3634cond %{GROUP}
3735 cond %{CLIENT-HEADER:X-And-A} ="" [NOT]
3836cond %{GROUP:END} [AND]
3937cond %{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)
4442cond %{SEND_RESPONSE_HDR_HOOK} [AND]
4543cond %{CLIENT-URL:PATH} /\/logic\/group-not$/ [AND]
4644cond %{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]
4947cond %{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)
5452cond %{SEND_RESPONSE_HDR_HOOK} [AND]
5553cond %{CLIENT-URL:PATH} /\/logic\/nested-group$/ [AND]
56- cond %{CLIENT-HEADER:X-Outer-A} ="" [NOT]
54+ cond %{CLIENT-HEADER:X-Outer-A} ="" [AND, NOT]
5755cond %{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]
6058cond %{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)
6563cond %{SEND_RESPONSE_HDR_HOOK} [AND]
6664cond %{CLIENT-URL:PATH} /\/logic\/two-groups$/ [AND]
6765cond %{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]
7068cond %{GROUP:END} [OR]
7169cond %{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]
7472cond %{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"
11083cond %{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)
129127cond %{SEND_RESPONSE_HDR_HOOK} [AND]
130128cond %{CLIENT-URL:PATH} /\/logic\/complex-and-or$/ [AND]
131129cond %{GROUP}
132- cond %{CLIENT-HEADER:X-P} ="" [NOT,OR ]
130+ cond %{CLIENT-HEADER:X-P} ="" [OR,NOT ]
133131 cond %{CLIENT-HEADER:X-Q} ="" [NOT]
134132cond %{GROUP:END} [AND]
135133cond %{GROUP}
136- cond %{CLIENT-HEADER:X-R} ="" [NOT,OR ]
134+ cond %{CLIENT-HEADER:X-R} ="" [OR,NOT ]
137135 cond %{CLIENT-HEADER:X-S} ="" [NOT]
138136cond %{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"
143141cond %{SEND_RESPONSE_HDR_HOOK} [AND]
144142cond %{CLIENT-URL:PATH} /\/logic\/ip-group-or$/ [AND]
145143cond %{GROUP}
146144 cond %{IP:CLIENT} {127.0.0.0/8}
147145cond %{GROUP:END} [OR]
148146cond %{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
153151cond %{SEND_RESPONSE_HDR_HOOK} [AND]
154152cond %{GROUP}
155153 cond %{CLIENT-URL:PATH} /\/logic\/group-first$/
0 commit comments