Skip to content

hrw4u is a new header_rewrite configuration DSL #12221

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
539 changes: 539 additions & 0 deletions doc/admin-guide/configuration/hrw4u.en.rst

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions doc/admin-guide/configuration/index.en.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ Proxy Cache Configuration
transparent-forward-proxying.en
hierarchical-caching.en
proxy-protocol.en
hrw4u.en
87 changes: 87 additions & 0 deletions tools/hrw4u/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Makefile to make docker images
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
BUILD_DIR:=build
DIST_DIR:=dist
PKG_DIR:=$(BUILD_DIR)/hrw4u
VENV_NAME:=hrw4u
ANTLR=antlr
PYTHON_VERSION=3.11.8

# Source files
SCRIPT_FILE=scripts/hrw4u

SRC_FILES=src/visitor.py \
src/symbols.py \
src/validation.py \
src/errors.py \
src/states.py \
src/types.py
GRAMMAR_FILE=grammar/hrw4u.g4

ANTLR_FILES=$(PKG_DIR)/hrw4uLexer.py \
$(PKG_DIR)/hrw4uParser.py \
$(PKG_DIR)/hrw4uVisitor.py \
$(PKG_DIR)/hrw4u.interp \
$(PKG_DIR)/hrw4u.tokens \
$(PKG_DIR)/hrw4uLexer.tokens

COPIED_SRC_FILES=$(patsubst src/%, $(PKG_DIR)/%, $(SRC_FILES))

.PHONY: all gen test clean build package env setup-deps activate update

all: gen

copy-src: $(COPIED_SRC_FILES)

$(PKG_DIR)/%: src/%
@mkdir -p $(PKG_DIR)
cp $< $@

gen: $(ANTLR_FILES) copy-src

$(ANTLR_FILES): $(GRAMMAR_FILE)
@mkdir -p $(PKG_DIR)
cd grammar && $(ANTLR) -Dlanguage=Python3 -visitor -no-listener -o ../$(PKG_DIR) hrw4u.g4
cp $(SRC_FILES) $(PKG_DIR)
cp $(SCRIPT_FILE) $(PKG_DIR)/__main__.py
touch $(PKG_DIR)/__init__.py

test:
pytest --tb=short tests

build: gen
pyinstaller --onefile --name hrw4u --strip scripts/hrw4u

package: gen
@echo "==> Building pip package for $(hrw4u)..."
python3 -m build --wheel --outdir $(DIST_DIR)

clean:
rm -rf build dist __pycache__ *.spec *.egg-info
find tests -name '__pycache__' -type d -exec rm -r {} +

env:
pyenv install -s $(PYTHON_VERSION)
pyenv virtualenv -f $(PYTHON_VERSION) $(VENV_NAME)
pyenv local $(VENV_NAME)

setup-deps: env
$(PYTHON) -m pip install -r requirements.txt

activate:
@echo "Run: pyenv activate $(VENV_NAME)"
37 changes: 37 additions & 0 deletions tools/hrw4u/bootstrap.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env bash
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set -e

VENV_NAME="hrw4u"

eval "$(pyenv init --path)"
eval "$(pyenv init -)"
# eval "$(pyenv virtualenv-init -)"

echo "==> Creating virtualenv $VENV_NAME..."
pyenv virtualenv "$VENV_NAME"

echo "==> Activating virtualenv..."
pyenv activate "$VENV_NAME"

echo "==> Installing dependencies..."
pip install --upgrade pip
pip install -r requirements.txt

echo "==> Done. To activate manually: pyenv activate $VENV_NAME"
219 changes: 219 additions & 0 deletions tools/hrw4u/grammar/hrw4u.g4
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

grammar hrw4u;

// -----------------------------
// Lexer Rules
// -----------------------------
VAR : 'VAR';
IF : 'if';
ELSE : 'else';
IN : 'in';
TRUE : [tT][rR][uU][eE];
FALSE : [fF][aA][lL][sS][eE];
WITH : 'with';
BREAK : 'break';

REGEX : '/' ( '\\/' | ~[/\r\n] )* '/' ;
STRING : '"' ( '\\' . | ~["\\\r\n] )* '"' ;

IPV4_LITERAL
: (OCTET '.' OCTET '.' OCTET '.' OCTET ('/' IPV4_CIDR)?)
| (OCTET '.' OCTET '.' OCTET '/' IPV4_CIDR)
| (OCTET '.' OCTET '/' IPV4_CIDR)
| (OCTET '/' IPV4_CIDR)
;

IPV6_LITERAL : (HEXDIGIT+ ':')+ HEXDIGIT+ ('/' IPV6_CIDR)?
| '::' (HEXDIGIT+ ':')* HEXDIGIT+ ('/' IPV6_CIDR)?
| (HEXDIGIT+ ':')+ ':' ('/' IPV6_CIDR)?
;

fragment OCTET : [0-9] [0-9]? [0-9]? ;
fragment HEXDIGIT : [0-9a-fA-F] ;

fragment IPV4_CIDR : [1-9]
| [1-2][0-9]
| '3'[0-2]
;

fragment IPV6_CIDR : '3'[3-9]
| [4-9][0-9]
| '1'[0-1][0-9]
| '12'[0-8]
;

IDENT : [a-zA-Z_][a-zA-Z0-9_@.-]* ;
NUMBER : [0-9]+ ;
LPAREN : '(';
RPAREN : ')';
LBRACE : '{';
RBRACE : '}';
LBRACKET : '[';
RBRACKET : ']';
EQUALS : '==';
EQUAL : '=';
NEQ : '!=';
GT : '>';
LT : '<';
AND : '&&';
OR : '||';
TILDE : '~';
NOT_TILDE : '!~';
COLON : ':';
COMMA : ',';
SEMICOLON : ';';

COMMENT : '#' ~[\r\n]* -> skip ;
WS : [ \t\r\n]+ -> skip ;

// -----------------------------
// Parser Rules
// -----------------------------
program
: section+ EOF
;

section
: VAR COLON variables
| name=IDENT COLON (conditionalBlock | statementList)
;

statementList
: statement+
;

variables
: variableDecl*
;

variableDecl
: name=IDENT COLON typeName=IDENT SEMICOLON
;

conditionalBlock
: ifStatement elseClause?
| block
;

ifStatement
: IF condition block
| IF LPAREN condition RPAREN block
;

elseClause
: ELSE block
;

block
: LBRACE statement* RBRACE
;

statement
: lhs=IDENT EQUAL value SEMICOLON
| op=IDENT SEMICOLON
| functionCall SEMICOLON
| BREAK SEMICOLON
;

condition
: logicalExpression
;

logicalExpression
: logicalExpression OR logicalTerm
| logicalTerm
;

logicalTerm
: logicalTerm AND logicalFactor
| logicalFactor
;

logicalFactor
: '!' logicalFactor
| LPAREN logicalExpression RPAREN
| functionCall
| comparison
| ident=IDENT
| TRUE
| FALSE
;

comparison
: comparable (EQUALS | NEQ | GT | LT) value modifier?
| comparable (TILDE | NOT_TILDE) regex modifier?
| comparable IN set modifier?
| comparable IN iprange
;

modifier
: WITH modifierList
;

modifierList
: mods+=IDENT (COMMA mods+=IDENT)*
;

comparable
: ident=IDENT
| functionCall
;

functionCall
: funcName=IDENT LPAREN argumentList? RPAREN
;

argumentList
: value (COMMA value)*
;

regex
: REGEX
;

set
: LBRACKET value (COMMA value)* RBRACKET
;

ip
: ipv4
| ipv6
;

ipv4
: IPV4_LITERAL
;

ipv6
: IPV6_LITERAL
;

iprange
: LBRACE ip (COMMA ip)* RBRACE
;

value
: number=NUMBER
| str=STRING
| TRUE
| FALSE
| ident=IDENT
| ip
| iprange
;
28 changes: 28 additions & 0 deletions tools/hrw4u/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[build-system]
requires = ["setuptools", "wheel"]
build-backend = "setuptools.build_meta"
[tool.pytest.ini_options]
markers = [
"invalid: marks tests expected to fail input parsing",
"hooks: marks tests for all hooks",
"conds: marks tests for all conditions",
"ops: marks tests for all operators",
"vars: marks tests for all variables",
"examples: marks tests for all header_rewrite docs examples",
]
19 changes: 19 additions & 0 deletions tools/hrw4u/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
antlr4-python3-runtime
pytest
pyinstaller
Loading