Skip to content

Commit d4fac35

Browse files
committed
hrwu is a new header_rewrite configuration DSL
Currently as an external compiler, hopefully later integrated into the plugin itself.
1 parent 9ebd639 commit d4fac35

File tree

125 files changed

+2964
-0
lines changed

Some content is hidden

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

125 files changed

+2964
-0
lines changed

doc/admin-guide/configuration/hrw4u.en.rst

Lines changed: 509 additions & 0 deletions
Large diffs are not rendered by default.

doc/admin-guide/configuration/index.en.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ Proxy Cache Configuration
3333
transparent-forward-proxying.en
3434
hierarchical-caching.en
3535
proxy-protocol.en
36+
hrw4u.en

tools/hrw4u/Makefile

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Makefile to make docker images
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
BUILD_DIR:=build
19+
DIST_DIR:=dist
20+
PKG_DIR:=$(BUILD_DIR)/hrw4u
21+
VENV_NAME:=hrw4u
22+
ANTLR=antlr
23+
PYTHON_VERSION=3.11.8
24+
25+
# Source files
26+
SCRIPT_FILE=scripts/hrw4u
27+
28+
SRC_FILES=src/visitor.py \
29+
src/symbols.py \
30+
src/validation.py \
31+
src/errors.py \
32+
src/states.py
33+
GRAMMAR_FILE=grammar/hrw4u.g4
34+
35+
ANTLR_FILES=$(PKG_DIR)/hrw4uLexer.py \
36+
$(PKG_DIR)/hrw4uParser.py \
37+
$(PKG_DIR)/hrw4uVisitor.py \
38+
$(PKG_DIR)/hrw4u.interp \
39+
$(PKG_DIR)/hrw4u.tokens \
40+
$(PKG_DIR)/hrw4uLexer.tokens
41+
42+
COPIED_SRC_FILES=$(patsubst src/%, $(PKG_DIR)/%, $(SRC_FILES))
43+
44+
.PHONY: all gen test clean build package env setup-deps activate update
45+
46+
all: gen
47+
48+
copy-src: $(COPIED_SRC_FILES)
49+
50+
$(PKG_DIR)/%: src/%
51+
@mkdir -p $(PKG_DIR)
52+
cp $< $@
53+
54+
gen: $(ANTLR_FILES) copy-src
55+
56+
$(ANTLR_FILES): $(GRAMMAR_FILE)
57+
@mkdir -p $(PKG_DIR)
58+
@cd grammar && $(ANTLR) -Dlanguage=Python3 -visitor -no-listener -o ../$(PKG_DIR) hrw4u.g4
59+
cp $(SRC_FILES) $(PKG_DIR)
60+
cp $(SCRIPT_FILE) $(PKG_DIR)/__main__.py
61+
touch $(PKG_DIR)/__init__.py
62+
63+
test:
64+
pytest --tb=short tests
65+
66+
build: gen
67+
pyinstaller --onefile --name hrw4u --strip scripts/hrw4u
68+
69+
package: gen
70+
@echo "==> Building pip package for $(hrw4u)..."
71+
python3 -m build --wheel --outdir $(DIST_DIR)
72+
73+
clean:
74+
rm -rf build dist __pycache__ *.spec *.egg-info
75+
find tests -name '__pycache__' -type d -exec rm -r {} +
76+
77+
env:
78+
pyenv install -s $(PYTHON_VERSION)
79+
pyenv virtualenv -f $(PYTHON_VERSION) $(VENV_NAME)
80+
pyenv local $(VENV_NAME)
81+
82+
setup-deps: env
83+
$(PYTHON) -m pip install -r requirements.txt
84+
85+
activate:
86+
@echo "Run: pyenv activate $(VENV_NAME)"

tools/hrw4u/bootstrap.sh

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
set -e
20+
21+
VENV_NAME="hrw4u"
22+
23+
eval "$(pyenv init --path)"
24+
eval "$(pyenv init -)"
25+
# eval "$(pyenv virtualenv-init -)"
26+
27+
echo "==> Creating virtualenv $VENV_NAME..."
28+
pyenv virtualenv "$VENV_NAME"
29+
30+
echo "==> Activating virtualenv..."
31+
pyenv activate "$VENV_NAME"
32+
33+
echo "==> Installing dependencies..."
34+
pip install --upgrade pip
35+
pip install -r requirements.txt
36+
37+
echo "==> Done. To activate manually: pyenv activate $VENV_NAME"

tools/hrw4u/grammar/hrw4u.g4

Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
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+
18+
grammar hrw4u;
19+
20+
// -----------------------------
21+
// Lexer Rules
22+
// -----------------------------
23+
VAR : 'VAR';
24+
IF : 'if';
25+
ELSE : 'else';
26+
IN : 'in';
27+
BOOL : 'bool';
28+
INT8 : 'int8';
29+
INT16 : 'int16';
30+
TRUE : 'true';
31+
FALSE : 'false';
32+
WITH : 'with';
33+
BREAK : 'break';
34+
35+
REGEX : '/' ( '\\/' | ~[/\r\n] )* '/' ;
36+
STRING : '"' ( '\\' . | ~["\\\r\n] )* '"' ;
37+
38+
IPV4_LITERAL
39+
: (OCTET '.' OCTET '.' OCTET '.' OCTET ('/' IPV4_CIDR)?)
40+
| (OCTET '.' OCTET '.' OCTET '/' IPV4_CIDR)
41+
| (OCTET '.' OCTET '/' IPV4_CIDR)
42+
| (OCTET '/' IPV4_CIDR)
43+
;
44+
45+
IPV6_LITERAL : (HEXDIGIT+ ':')+ HEXDIGIT+ ('/' IPV6_CIDR)?
46+
| '::' (HEXDIGIT+ ':')* HEXDIGIT+ ('/' IPV6_CIDR)?
47+
| (HEXDIGIT+ ':')+ ':' ('/' IPV6_CIDR)?
48+
;
49+
50+
fragment OCTET : [0-9] [0-9]? [0-9]? ;
51+
fragment HEXDIGIT : [0-9a-fA-F] ;
52+
53+
fragment IPV4_CIDR : [1-9]
54+
| [1-2][0-9]
55+
| '3'[0-2]
56+
;
57+
58+
fragment IPV6_CIDR : '3'[3-9]
59+
| [4-9][0-9]
60+
| '1'[0-1][0-9]
61+
| '12'[0-8]
62+
;
63+
64+
IDENT : [a-zA-Z_][a-zA-Z0-9_@.-]* ;
65+
NUMBER : [0-9]+ ;
66+
LPAREN : '(';
67+
RPAREN : ')';
68+
LBRACE : '{';
69+
RBRACE : '}';
70+
LBRACKET : '[';
71+
RBRACKET : ']';
72+
EQUALS : '==';
73+
EQUAL : '=';
74+
NEQ : '!=';
75+
GT : '>';
76+
LT : '<';
77+
AND : '&&';
78+
OR : '||';
79+
TILDE : '~';
80+
NOT_TILDE : '!~';
81+
COLON : ':';
82+
COMMA : ',';
83+
SEMICOLON : ';';
84+
85+
COMMENT : '#' ~[\r\n]* -> skip ;
86+
WS : [ \t\r\n]+ -> skip ;
87+
88+
// -----------------------------
89+
// Parser Rules
90+
// -----------------------------
91+
program
92+
: section+ EOF
93+
;
94+
95+
section
96+
: VAR COLON variables
97+
| IDENT COLON conditionalBlock
98+
| IDENT COLON statement+
99+
;
100+
101+
variables
102+
: variableDecl*
103+
;
104+
105+
variableDecl
106+
: IDENT COLON type SEMICOLON
107+
;
108+
109+
type
110+
: BOOL
111+
| INT8
112+
| INT16
113+
;
114+
115+
conditionalBlock
116+
: ifStatement elseClause?
117+
| block
118+
;
119+
120+
ifStatement
121+
: IF condition block
122+
| IF LPAREN condition RPAREN block
123+
;
124+
125+
elseClause
126+
: ELSE block
127+
;
128+
129+
block
130+
: LBRACE statement* RBRACE
131+
;
132+
133+
statement
134+
: IDENT EQUAL value SEMICOLON
135+
| IDENT SEMICOLON
136+
| functionCall SEMICOLON
137+
| BREAK SEMICOLON
138+
;
139+
140+
condition
141+
: logicalExpression
142+
;
143+
144+
logicalExpression
145+
: logicalExpression OR logicalTerm
146+
| logicalTerm
147+
;
148+
149+
logicalTerm
150+
: logicalTerm AND logicalFactor
151+
| logicalFactor
152+
;
153+
154+
logicalFactor
155+
: '!' logicalFactor
156+
| LPAREN logicalExpression RPAREN
157+
| functionCall
158+
| comparison
159+
| IDENT
160+
;
161+
162+
comparison
163+
: comparable (EQUALS | NEQ | GT | LT) value modifier?
164+
| comparable (TILDE | NOT_TILDE) regex modifier?
165+
| comparable IN set modifier?
166+
| comparable IN iprange
167+
;
168+
169+
modifier
170+
: WITH modifierList
171+
;
172+
173+
modifierList
174+
: IDENT (COMMA IDENT)*
175+
;
176+
177+
comparable
178+
: IDENT
179+
| functionCall
180+
;
181+
182+
functionCall
183+
: IDENT LPAREN argumentList? RPAREN
184+
;
185+
186+
argumentList
187+
: value (COMMA value)*
188+
;
189+
190+
regex
191+
: REGEX
192+
;
193+
194+
set
195+
: LBRACKET value (COMMA value)* RBRACKET
196+
;
197+
198+
ip
199+
: ipv4
200+
| ipv6
201+
;
202+
203+
ipv4
204+
: IPV4_LITERAL
205+
;
206+
207+
ipv6
208+
: IPV6_LITERAL
209+
;
210+
211+
iprange
212+
: LBRACE ip (COMMA ip)* RBRACE
213+
;
214+
215+
value
216+
: NUMBER
217+
| STRING
218+
| TRUE
219+
| FALSE
220+
| IDENT
221+
| ip
222+
| iprange
223+
;

tools/hrw4u/pyproject.toml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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+
[build-system]
18+
requires = ["setuptools", "wheel"]
19+
build-backend = "setuptools.build_meta"
20+
[tool.pytest.ini_options]
21+
markers = [
22+
"invalid: marks tests expected to fail input parsing",
23+
"hooks: marks tests for all hooks",
24+
"conds: marks tests for all conditions",
25+
"ops: marks tests for all operators",
26+
"vars: marks tests for all variables",
27+
"examples: marks tests for all header_rewrite docs examples",
28+
]

0 commit comments

Comments
 (0)