This is an automated email from the ASF dual-hosted git repository. cmcfarlen pushed a commit to branch 10.2.x in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit f6a61a5709db059adf7aec1d331eab97442d9fbd Author: Leif Hedstrom <[email protected]> AuthorDate: Tue Mar 17 09:12:52 2026 -0700 hrw4u: Fix section placement for hookless rules in u4wrh (#12956) Old header_rewrite rules without an explicit hook condition default to REMAP. When u4wrh converted these, the section opened inside the if-block instead of wrapping it. Also emit comments inline inside if-blocks instead of deferring them to after the section closes, and remove the now-unused deferred comment machinery. In the forward direction, indent block-level comments at the statement level. Co-Authored-By: Keele Clendenin (cherry picked from commit 627f5071ea83c1a2c06292e4abdb2daaa17e4119) --- tools/hrw4u/src/hrw_visitor.py | 38 +++++++++++++--------- tools/hrw4u/src/visitor.py | 2 +- tools/hrw4u/tests/data/conds/exceptions.txt | 2 ++ tools/hrw4u/tests/data/conds/no-hook.input.txt | 6 ++++ tools/hrw4u/tests/data/conds/no-hook.output.txt | 3 ++ .../tests/data/examples/all-nonsense.output.txt | 8 ++--- 6 files changed, 39 insertions(+), 20 deletions(-) diff --git a/tools/hrw4u/src/hrw_visitor.py b/tools/hrw4u/src/hrw_visitor.py index 3dbdfd6208..2878da0be2 100644 --- a/tools/hrw4u/src/hrw_visitor.py +++ b/tools/hrw4u/src/hrw_visitor.py @@ -57,7 +57,8 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor): self._if_depth = 0 # Track nesting depth of if blocks self._in_elif_mode = False self._just_closed_nested = False - self._deferred_comments: list[str] = [] + + self._pre_section_if_start: int | None = None @lru_cache(maxsize=128) def _cached_percent_parsing(self, pct_text: str) -> tuple[str, str | None]: @@ -84,12 +85,6 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor): self._in_group = False self._group_terms.clear() - def _flush_deferred_comments(self) -> None: - """Emit comments that were deferred while inside a rule's if-block.""" - for comment in self._deferred_comments: - self.output.append(comment) - self._deferred_comments.clear() - def _start_new_section(self, section_type: SectionType) -> None: """Start a new section, handling continuation of existing sections.""" with self.debug_context(f"start_section {section_type.value}"): @@ -100,12 +95,10 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor): self.emit("}") self._if_depth -= 1 self._reset_condition_state() - self._flush_deferred_comments() if self.output and self.output[-1] != "": self.output.append("") return - prev = bool(self.output) had_section = self._section_opened self._close_if_and_section() self._reset_condition_state() @@ -113,8 +106,6 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor): if had_section and self.output and self.output[-1] != "": self.output.append("") - self._flush_deferred_comments() - self._section_label = section_type self.emit(f"{section_type.value} {{") self._section_opened = True @@ -162,7 +153,6 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor): for line in ctx.line(): self.visit(line) self._close_if_and_section() - self._flush_deferred_comments() var_declarations = self.symbol_resolver.get_var_declarations() if var_declarations: @@ -178,9 +168,7 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor): with self.debug_context("visitCommentLine"): comment_text = ctx.COMMENT().getText() self._flush_pending_condition() - if self._if_depth > 0: - self._deferred_comments.append(comment_text) - elif self._section_opened: + if self._if_depth > 0 or self._section_opened: self.emit(comment_text) else: self.output.append(comment_text) @@ -407,10 +395,27 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor): def _ensure_section_open(self, section_label: SectionType) -> None: """Ensure a section is open for statements.""" if not self._section_opened: + relocated_lines = None + relocated_if_depth = 0 + if self._if_depth > 0 and self._pre_section_if_start is not None: + relocated_lines = self.output[self._pre_section_if_start:] + relocated_if_depth = self._if_depth + self.output = self.output[:self._pre_section_if_start] + self.stmt_indent -= self._if_depth + self._if_depth = 0 + self._pre_section_if_start = None + self.emit(f"{section_label.value} {{") self._section_opened = True self.increase_indent() + if relocated_lines: + indent_prefix = " " * SystemDefaults.INDENT_SPACES + for line in relocated_lines: + self.output.append(indent_prefix + line if line.strip() else line) + self._if_depth = relocated_if_depth + self.stmt_indent += relocated_if_depth + def _start_elif_mode(self) -> None: """Handle elif line transitions.""" # After endif, we need to close the parent if-statement @@ -432,6 +437,9 @@ class HRWInverseVisitor(u4wrhVisitor, BaseHRWVisitor): def _start_if_block(self, condition_expr: str) -> None: """Start a new if block.""" + if not self._section_opened and self._pre_section_if_start is None: + self._pre_section_if_start = len(self.output) + if self._in_elif_mode: self.emit(f"}} elif {condition_expr} {{") self._in_elif_mode = False diff --git a/tools/hrw4u/src/visitor.py b/tools/hrw4u/src/visitor.py index 90ea932e68..68182fb2b9 100644 --- a/tools/hrw4u/src/visitor.py +++ b/tools/hrw4u/src/visitor.py @@ -830,7 +830,7 @@ class HRW4UVisitor(hrw4uVisitor, BaseHRWVisitor): with self.debug_context("visitCommentLine"): comment_text = ctx.COMMENT().getText() self.debug(f"preserving comment: {comment_text}") - self.output.append(comment_text) + self.emit_line(comment_text, self.stmt_indent) def visitStatement(self, ctx) -> None: with self.debug_context("visitStatement"), self.trap(ctx): diff --git a/tools/hrw4u/tests/data/conds/exceptions.txt b/tools/hrw4u/tests/data/conds/exceptions.txt index 86e44106ba..fd12cfd4a0 100644 --- a/tools/hrw4u/tests/data/conds/exceptions.txt +++ b/tools/hrw4u/tests/data/conds/exceptions.txt @@ -5,3 +5,5 @@ implicit-cmp.input: u4wrh # Double negation !(x != y) emits GROUP/GROUP:END [NOT] pairs; reverse can't reconstruct the original form double-negation.input: hrw4u +# Old format without explicit hook defaults to REMAP; hrw4u always emits explicit sections +no-hook.input: u4wrh diff --git a/tools/hrw4u/tests/data/conds/no-hook.input.txt b/tools/hrw4u/tests/data/conds/no-hook.input.txt new file mode 100644 index 0000000000..603acdb71a --- /dev/null +++ b/tools/hrw4u/tests/data/conds/no-hook.input.txt @@ -0,0 +1,6 @@ +REMAP { + if inbound.req.Debug { + # to return the debug header if http header debug: on + inbound.req.@DebugHeader = "TRUE"; + } +} diff --git a/tools/hrw4u/tests/data/conds/no-hook.output.txt b/tools/hrw4u/tests/data/conds/no-hook.output.txt new file mode 100644 index 0000000000..c57dcec7e5 --- /dev/null +++ b/tools/hrw4u/tests/data/conds/no-hook.output.txt @@ -0,0 +1,3 @@ +cond %{CLIENT-HEADER:Debug} ="" [NOT] +# to return the debug header if http header debug: on +set-header @DebugHeader "TRUE" diff --git a/tools/hrw4u/tests/data/examples/all-nonsense.output.txt b/tools/hrw4u/tests/data/examples/all-nonsense.output.txt index bb15eb068e..c8672c1f28 100644 --- a/tools/hrw4u/tests/data/examples/all-nonsense.output.txt +++ b/tools/hrw4u/tests/data/examples/all-nonsense.output.txt @@ -93,7 +93,7 @@ cond %{GROUP} cond %{GROUP:END} skip-remap TRUE no-op [L] -# like [L] + # like [L] cond %{READ_REQUEST_HDR_HOOK} [AND] # Header presence / equality and capture groups @@ -132,9 +132,9 @@ cond %{GROUP} cond %{GROUP:END} counter "write_methods_seen" set-state-int8 0 42 -# assign int8 + # assign int8 set-state-int16 0 6553 -# assign int16 + # assign int16 cond %{SEND_REQUEST_HDR_HOOK} [AND] # Use server URL information to adjust Host header @@ -174,7 +174,7 @@ elif cond %{CACHE} ("miss","skipped") cond %{GROUP:END} set-header X-Cache "%{CACHE}" -# echo the value + # echo the value # Status transforms + reason cond %{READ_RESPONSE_HDR_HOOK} [AND]
