@@ -153,9 +153,19 @@ like the following::
153153Which converts any 4xx HTTP status code from the origin server to a 404. A
154154response from the origin with a status of 200 would be unaffected by this rule.
155155
156+ Advanced Conditionals
157+ ---------------------
158+
159+ The header_rewrite plugin supports advanced conditional logic that allows
160+ for more sophisticated rule construction, including branching logic, nested
161+ conditionals, and complex boolean expressions.
162+
163+ else and elif Clauses
164+ ~~~~~~~~~~~~~~~~~~~~~
165+
156166An optional ``else `` clause may be specified, which will be executed if the
157- conditions are not met. The ``else `` clause is specified by starting a new line
158- with the word ``else ``. The following example illustrates this::
167+ conditions are not met. The ``else `` clause is specified by starting a new
168+ line with the word ``else ``. The following example illustrates this::
159169
160170 cond %{STATUS} >399 [AND]
161171 cond %{STATUS} <500
@@ -164,10 +174,12 @@ with the word ``else``. The following example illustrates this::
164174 set-status 503
165175
166176The ``else `` clause is not a condition, and does not take any flags, it is
167- of course optional, but when specified must be followed by at least one operator.
177+ of course optional, but when specified must be followed by at least one
178+ operator.
168179
169- You can also do an ``elif `` (else if) clause, which is specified by starting a new line
170- with the word ``elif ``. The following example illustrates this::
180+ You can also do an ``elif `` (else if) clause, which is specified by
181+ starting a new line with the word ``elif ``. The following example
182+ illustrates this::
171183
172184 cond %{STATUS} >399 [AND]
173185 cond %{STATUS} <500
@@ -178,14 +190,105 @@ with the word ``elif``. The following example illustrates this::
178190 else
179191 set-status 503
180192
181- Keep in mind that nesting the ``else `` and ``elif `` clauses is not allowed, but any
182- number of ``elif `` clauses can be specified. We can consider these clauses are more
183- powerful and flexible ``switch `` statement. In an ``if-elif-else `` rule, only one
184- will evaluate its operators.
193+ Any number of ``elif `` clauses can be specified. We can consider these
194+ clauses are more powerful and flexible ``switch `` statement. In an
195+ ``if-elif-else `` rule, only one will evaluate its operators.
196+
197+ Note that while ``else `` and ``elif `` themselves cannot be directly nested,
198+ you can use ``if ``/``endif `` blocks within ``else `` or ``elif `` operator
199+ sections to achieve nested conditional logic (see `Nested Conditionals with
200+ if/endif `_).
185201
186202Similarly, each ``else `` and ``elif `` have the same implied
187203:ref: `Hook Condition <hook_conditions >` as the initial condition.
188204
205+ Nested Conditionals with if/endif
206+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
207+
208+ For more complex logic requiring nested conditionals, the ``if `` and
209+ ``endif `` pseudo-operators can be used. While ``else `` and ``elif ``
210+ themselves cannot be directly nested, you can use ``if ``/``endif `` blocks
211+ within any operator section (including inside ``else `` or ``elif `` blocks)
212+ to achieve arbitrary nesting depth.
213+
214+ The ``if `` operator starts a new conditional block, and ``endif `` closes
215+ it. Each ``if `` must have a matching ``endif ``. Here's an example::
216+
217+ cond %{READ_RESPONSE_HDR_HOOK} [AND]
218+ cond %{STATUS} >399
219+ if
220+ cond %{HEADER:X-Custom-Error} ="true"
221+ set-header X-Error-Handled "yes"
222+ else
223+ set-header X-Error-Handled "no"
224+ endif
225+ set-status 500
226+
227+ In this example, the nested ``if ``/``endif `` block is only evaluated when
228+ the status is greater than 399. The nested block itself can contain
229+ ``else `` or ``elif `` clauses, and you can nest multiple levels deep::
230+
231+ cond %{READ_RESPONSE_HDR_HOOK}
232+ if
233+ cond %{STATUS} =404
234+ if
235+ cond %{CLIENT-HEADER:User-Agent} /mobile/
236+ set-header X-Error-Type "mobile-404"
237+ else
238+ set-header X-Error-Type "desktop-404"
239+ endif
240+ elif
241+ cond %{STATUS} =500
242+ set-header X-Error-Type "server-error"
243+ endif
244+
245+ GROUP Conditions in Advanced Conditionals
246+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
247+
248+ The `GROUP `_ condition can be combined with advanced conditionals to
249+ create very sophisticated boolean expressions. ``GROUP `` conditions act as
250+ parentheses in your conditional logic, allowing you to mix AND, OR, and NOT
251+ operators in complex ways.
252+
253+ Here's an example combining ``GROUP `` with ``if ``/``endif ``::
254+
255+ cond %{READ_RESPONSE_HDR_HOOK} [AND]
256+ cond %{STATUS} >399
257+ if
258+ cond %{GROUP} [OR]
259+ cond %{CLIENT-HEADER:X-Retry} ="true" [AND]
260+ cond %{METHOD} =GET
261+ cond %{GROUP:END}
262+ cond %{CLIENT-HEADER:X-Force-Cache} ="" [NOT]
263+ set-header X-Can-Retry "yes"
264+ else
265+ set-header X-Can-Retry "no"
266+ endif
267+ set-status 500
268+
269+ This creates the logic: if error status, then set retry header when
270+ ``((X-Retry=true AND METHOD=GET) OR X-Force-Cache header exists) ``.
271+ The GROUP is necessary here to properly combine the two conditions with OR.
272+
273+ You can also use ``GROUP `` with ``else `` and ``elif `` inside nested conditionals::
274+
275+ cond %{SEND_RESPONSE_HDR_HOOK} [AND]
276+ cond %{STATUS} >399
277+ if
278+ cond %{GROUP} [OR]
279+ cond %{HEADER:X-Custom} ="retry" [AND]
280+ cond %{METHOD} =POST
281+ cond %{GROUP:END}
282+ cond %{HEADER:Content-Type} /json/
283+ set-header X-Error-Handler "json-retry"
284+ elif
285+ cond %{METHOD} =GET
286+ set-header X-Error-Handler "get-error"
287+ else
288+ set-header X-Error-Handler "standard"
289+ endif
290+ set-status 500
291+
189292State variables
190293---------------
191294
@@ -923,6 +1026,29 @@ no facility to increment by other amounts, nor is it possible to initialize the
9231026counter with any value other than ``0 ``. Additionally, the counter will reset
9241027whenever |TS | is restarted.
9251028
1029+ if
1030+ ~~
1031+ ::
1032+
1033+ if
1034+ <conditions>
1035+ <operators>
1036+ endif
1037+
1038+ This is a pseudo-operator that enables nested conditional blocks within
1039+ the operator section of a rule. While ``else `` and ``elif `` themselves
1040+ cannot be directly nested, you can use ``if ``/``endif `` blocks within any
1041+ operator section (including inside ``else `` or ``elif `` blocks) to create
1042+ arbitrary nesting depth for complex conditional logic.
1043+
1044+ The ``if `` operator must be preceded by conditions and followed by at
1045+ least one condition or operator. Each ``if `` must have a matching
1046+ ``endif `` to close the block. Within an ``if ``/``endif `` block, you can
1047+ use regular conditions, operators, and even ``else `` and ``elif `` clauses.
1048+
1049+ For detailed usage and examples, see `Nested Conditionals with if/endif `_
1050+ in the `Advanced Conditionals `_ section.
1051+
9261052no-op
9271053~~~~~
9281054::
0 commit comments