Skip to content

Commit b0fceda

Browse files
committed
hrwu is a new header_rewrite configuration DSL
1 parent 9ebd639 commit b0fceda

File tree

177 files changed

+3294
-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.

177 files changed

+3294
-0
lines changed

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

Lines changed: 539 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: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
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+
src/types.py
34+
GRAMMAR_FILE=grammar/hrw4u.g4
35+
36+
ANTLR_FILES=$(PKG_DIR)/hrw4uLexer.py \
37+
$(PKG_DIR)/hrw4uParser.py \
38+
$(PKG_DIR)/hrw4uVisitor.py \
39+
$(PKG_DIR)/hrw4u.interp \
40+
$(PKG_DIR)/hrw4u.tokens \
41+
$(PKG_DIR)/hrw4uLexer.tokens
42+
43+
COPIED_SRC_FILES=$(patsubst src/%, $(PKG_DIR)/%, $(SRC_FILES))
44+
45+
.PHONY: all gen test clean build package env setup-deps activate update
46+
47+
all: gen
48+
49+
copy-src: $(COPIED_SRC_FILES)
50+
51+
$(PKG_DIR)/%: src/%
52+
@mkdir -p $(PKG_DIR)
53+
cp $< $@
54+
55+
gen: $(ANTLR_FILES) copy-src
56+
57+
$(ANTLR_FILES): $(GRAMMAR_FILE)
58+
@mkdir -p $(PKG_DIR)
59+
cd grammar && $(ANTLR) -Dlanguage=Python3 -visitor -no-listener -o ../$(PKG_DIR) hrw4u.g4
60+
cp $(SRC_FILES) $(PKG_DIR)
61+
cp $(SCRIPT_FILE) $(PKG_DIR)/__main__.py
62+
touch $(PKG_DIR)/__init__.py
63+
64+
test:
65+
pytest --tb=short tests
66+
67+
build: gen
68+
pyinstaller --onefile --name hrw4u --strip scripts/hrw4u
69+
70+
package: gen
71+
@echo "==> Building pip package for $(hrw4u)..."
72+
python3 -m build --wheel --outdir $(DIST_DIR)
73+
74+
clean:
75+
rm -rf build dist __pycache__ *.spec *.egg-info
76+
find tests -name '__pycache__' -type d -exec rm -r {} +
77+
78+
env:
79+
pyenv install -s $(PYTHON_VERSION)
80+
pyenv virtualenv -f $(PYTHON_VERSION) $(VENV_NAME)
81+
pyenv local $(VENV_NAME)
82+
83+
setup-deps: env
84+
$(PYTHON) -m pip install -r requirements.txt
85+
86+
activate:
87+
@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: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
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+
TRUE : [tT][rR][uU][eE];
28+
FALSE : [fF][aA][lL][sS][eE];
29+
WITH : 'with';
30+
BREAK : 'break';
31+
32+
REGEX : '/' ( '\\/' | ~[/\r\n] )* '/' ;
33+
STRING : '"' ( '\\' . | ~["\\\r\n] )* '"' ;
34+
35+
IPV4_LITERAL
36+
: (OCTET '.' OCTET '.' OCTET '.' OCTET ('/' IPV4_CIDR)?)
37+
| (OCTET '.' OCTET '.' OCTET '/' IPV4_CIDR)
38+
| (OCTET '.' OCTET '/' IPV4_CIDR)
39+
| (OCTET '/' IPV4_CIDR)
40+
;
41+
42+
IPV6_LITERAL : (HEXDIGIT+ ':')+ HEXDIGIT+ ('/' IPV6_CIDR)?
43+
| '::' (HEXDIGIT+ ':')* HEXDIGIT+ ('/' IPV6_CIDR)?
44+
| (HEXDIGIT+ ':')+ ':' ('/' IPV6_CIDR)?
45+
;
46+
47+
fragment OCTET : [0-9] [0-9]? [0-9]? ;
48+
fragment HEXDIGIT : [0-9a-fA-F] ;
49+
50+
fragment IPV4_CIDR : [1-9]
51+
| [1-2][0-9]
52+
| '3'[0-2]
53+
;
54+
55+
fragment IPV6_CIDR : '3'[3-9]
56+
| [4-9][0-9]
57+
| '1'[0-1][0-9]
58+
| '12'[0-8]
59+
;
60+
61+
IDENT : [a-zA-Z_][a-zA-Z0-9_@.-]* ;
62+
NUMBER : [0-9]+ ;
63+
LPAREN : '(';
64+
RPAREN : ')';
65+
LBRACE : '{';
66+
RBRACE : '}';
67+
LBRACKET : '[';
68+
RBRACKET : ']';
69+
EQUALS : '==';
70+
EQUAL : '=';
71+
NEQ : '!=';
72+
GT : '>';
73+
LT : '<';
74+
AND : '&&';
75+
OR : '||';
76+
TILDE : '~';
77+
NOT_TILDE : '!~';
78+
COLON : ':';
79+
COMMA : ',';
80+
SEMICOLON : ';';
81+
82+
COMMENT : '#' ~[\r\n]* -> skip ;
83+
WS : [ \t\r\n]+ -> skip ;
84+
85+
// -----------------------------
86+
// Parser Rules
87+
// -----------------------------
88+
program
89+
: section+ EOF
90+
;
91+
92+
section
93+
: VAR COLON variables
94+
| name=IDENT COLON (conditionalBlock | statementList)
95+
;
96+
97+
statementList
98+
: statement+
99+
;
100+
101+
variables
102+
: variableDecl*
103+
;
104+
105+
variableDecl
106+
: name=IDENT COLON typeName=IDENT SEMICOLON
107+
;
108+
109+
conditionalBlock
110+
: ifStatement elseClause?
111+
| block
112+
;
113+
114+
ifStatement
115+
: IF condition block
116+
| IF LPAREN condition RPAREN block
117+
;
118+
119+
elseClause
120+
: ELSE block
121+
;
122+
123+
block
124+
: LBRACE statement* RBRACE
125+
;
126+
127+
statement
128+
: lhs=IDENT EQUAL value SEMICOLON
129+
| op=IDENT SEMICOLON
130+
| functionCall SEMICOLON
131+
| BREAK SEMICOLON
132+
;
133+
134+
condition
135+
: logicalExpression
136+
;
137+
138+
logicalExpression
139+
: logicalExpression OR logicalTerm
140+
| logicalTerm
141+
;
142+
143+
logicalTerm
144+
: logicalTerm AND logicalFactor
145+
| logicalFactor
146+
;
147+
148+
logicalFactor
149+
: '!' logicalFactor
150+
| LPAREN logicalExpression RPAREN
151+
| functionCall
152+
| comparison
153+
| ident=IDENT
154+
| TRUE
155+
| FALSE
156+
;
157+
158+
comparison
159+
: comparable (EQUALS | NEQ | GT | LT) value modifier?
160+
| comparable (TILDE | NOT_TILDE) regex modifier?
161+
| comparable IN set modifier?
162+
| comparable IN iprange
163+
;
164+
165+
modifier
166+
: WITH modifierList
167+
;
168+
169+
modifierList
170+
: mods+=IDENT (COMMA mods+=IDENT)*
171+
;
172+
173+
comparable
174+
: ident=IDENT
175+
| functionCall
176+
;
177+
178+
functionCall
179+
: funcName=IDENT LPAREN argumentList? RPAREN
180+
;
181+
182+
argumentList
183+
: value (COMMA value)*
184+
;
185+
186+
regex
187+
: REGEX
188+
;
189+
190+
set
191+
: LBRACKET value (COMMA value)* RBRACKET
192+
;
193+
194+
ip
195+
: ipv4
196+
| ipv6
197+
;
198+
199+
ipv4
200+
: IPV4_LITERAL
201+
;
202+
203+
ipv6
204+
: IPV6_LITERAL
205+
;
206+
207+
iprange
208+
: LBRACE ip (COMMA ip)* RBRACE
209+
;
210+
211+
value
212+
: number=NUMBER
213+
| str=STRING
214+
| TRUE
215+
| FALSE
216+
| ident=IDENT
217+
| ip
218+
| iprange
219+
;

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+
]

tools/hrw4u/requirements.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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+
antlr4-python3-runtime
18+
pytest
19+
pyinstaller

0 commit comments

Comments
 (0)