This commit is contained in:
Mateusz Gruszczyński committed 2026-09-29 16:53:26 +02:00
1 parent 5ec14c6157
commit d94bd7609a
11 files changed
+232 -9

No files matched your search

+28 -2
View File
@@ -7,14 +7,40 @@ FREEBSD_RELEASE="${FREEBSD_RELEASE:-15.1-RELEASE}"
DOCKER_IMAGE="${DOCKER_IMAGE:-rustproxy-freebsd15-builder:15.1-rust1.88}"
DOCKER_CACHE_DIR="${DOCKER_CACHE_DIR:-/opt/opn-rustproxy/cache}"
RUN_LINUX_TESTS="${RUN_LINUX_TESTS:-1}"
APPLY_FREEBSD_PATCHES="${APPLY_FREEBSD_PATCHES:-1}"
command -v docker >/dev/null 2>&1 || { echo "Docker is required" >&2; exit 1; }
command -v rsync >/dev/null 2>&1 || { echo "rsync is required" >&2; exit 1; }
[[ -f "$SOURCE_DIR/Cargo.toml" ]] || { echo "Invalid RustProxy source: $SOURCE_DIR" >&2; exit 1; }
mkdir -p "$DOCKER_CACHE_DIR/cargo" "$DOCKER_CACHE_DIR/target" "$ROOT/dist/docker-build"
mkdir -p "$DOCKER_CACHE_DIR/cargo" "$DOCKER_CACHE_DIR/target" "$ROOT/dist/docker-build" "$ROOT/dist/.build-source"
uid="$(id -u)"
gid="$(id -g)"
# Never modify the upstream checkout. FreeBSD/OPNsense-only patches are
# applied to an isolated source copy which exists only for this build.
BUILD_SOURCE_DIR="$SOURCE_DIR"
PATCH_WORK_DIR=""
cleanup_build_source()
{
if [[ -n "$PATCH_WORK_DIR" ]] && [[ -d "$PATCH_WORK_DIR" ]]; then
rm -rf "$PATCH_WORK_DIR"
fi
}
trap cleanup_build_source EXIT
if [[ "$APPLY_FREEBSD_PATCHES" == "1" ]]; then
PATCH_WORK_DIR="$(mktemp -d "$ROOT/dist/.build-source/rustproxy.XXXXXX")"
rsync -a --delete \
--exclude='.git/' \
--exclude='target/' \
"$SOURCE_DIR/" "$PATCH_WORK_DIR/"
"$ROOT/builder/freebsd/apply-patches.sh" "$PATCH_WORK_DIR"
BUILD_SOURCE_DIR="$PATCH_WORK_DIR"
else
echo "FreeBSD/OPNsense source patches disabled (APPLY_FREEBSD_PATCHES=$APPLY_FREEBSD_PATCHES)."
fi
# Rebuild is cheap after the first run because the FreeBSD sysroot layer is cached.
docker build \
--build-arg "FREEBSD_RELEASE=$FREEBSD_RELEASE" \
@@ -27,7 +53,7 @@ run_args=(
--user "$uid:$gid"
-e CARGO_HOME=/cargo
-e CARGO_TARGET_DIR=/target
-v "$SOURCE_DIR:/src:ro"
-v "$BUILD_SOURCE_DIR:/src:ro"
-v "$DOCKER_CACHE_DIR/cargo:/cargo"
-v "$DOCKER_CACHE_DIR/target:/target"
-v "$ROOT/dist/docker-build:/out"
+51
View File
@@ -0,0 +1,51 @@
#!/bin/bash
set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SOURCE_DIR="${1:?usage: apply-patches.sh /path/to/RustProxy-source}"
[[ -f "$SOURCE_DIR/Cargo.toml" ]] || {
echo "Missing Cargo.toml in RustProxy source: $SOURCE_DIR" >&2
exit 1
}
command -v git >/dev/null 2>&1 || { echo "git is required to apply FreeBSD patches" >&2; exit 1; }
command -v python3 >/dev/null 2>&1 || { echo "python3 is required to detect RustProxy version" >&2; exit 1; }
version="$(python3 - "$SOURCE_DIR/Cargo.toml" <<'PY'
import sys
import tomllib
from pathlib import Path
with Path(sys.argv[1]).open('rb') as f:
data = tomllib.load(f)
print(data['package']['version'])
PY
)"
PATCH_DIR="$ROOT/patches/$version"
if [[ ! -d "$PATCH_DIR" ]]; then
echo "No FreeBSD/OPNsense patch set for RustProxy $version; building upstream source unchanged."
exit 0
fi
shopt -s nullglob
patches=("$PATCH_DIR"/*.patch)
if (( ${#patches[@]} == 0 )); then
echo "FreeBSD patch directory is empty for RustProxy $version: $PATCH_DIR" >&2
exit 1
fi
echo "Applying FreeBSD/OPNsense patch set for RustProxy $version to isolated build source..."
for patch_file in "${patches[@]}"; do
patch_name="$(basename "$patch_file")"
if git -C "$SOURCE_DIR" apply --check "$patch_file" 2>/dev/null; then
git -C "$SOURCE_DIR" apply "$patch_file"
echo " applied: $patch_name"
elif git -C "$SOURCE_DIR" apply --reverse --check "$patch_file" 2>/dev/null; then
echo " already present: $patch_name"
else
echo "Patch does not apply cleanly: $patch_name" >&2
echo "RustProxy source version: $version" >&2
exit 1
fi
done
@@ -0,0 +1,75 @@
diff --git a/rust-toolchain.toml b/rust-toolchain.toml
index 05e6ca1..fdda5b9 100644
--- a/rust-toolchain.toml
+++ b/rust-toolchain.toml
@@ -1,4 +1,4 @@
[toolchain]
-channel = "stable"
+channel = "1.88.0"
profile = "minimal"
components = ["rustfmt", "clippy"]
diff --git a/src/cache.rs b/src/cache.rs
index fcd6f36..82332e5 100644
--- a/src/cache.rs
+++ b/src/cache.rs
@@ -3774,9 +3774,10 @@ mod tests {
.unwrap(),
);
h.insert("age", HeaderValue::from_static("3"));
- let plan = plan(StatusCode::OK, &h, &settings, Duration::from_millis(250)).unwrap();
- assert!(plan.initial_age >= Duration::from_secs(10));
- assert!(plan.initial_age < Duration::from_secs(12));
+ let cache_plan =
+ plan(StatusCode::OK, &h, &settings, Duration::from_millis(250)).unwrap();
+ assert!(cache_plan.initial_age >= Duration::from_secs(10));
+ assert!(cache_plan.initial_age < Duration::from_secs(12));
let fresh = plan(
StatusCode::OK,
&headers("max-age=60"),
diff --git a/src/proxy/websocket.rs b/src/proxy/websocket.rs
index a25776e..c1d3519 100644
--- a/src/proxy/websocket.rs
+++ b/src/proxy/websocket.rs
@@ -653,7 +653,11 @@ mod tests {
.unwrap();
request
.extensions_mut()
- .insert("websocket".parse::<h3::ext::Protocol>().unwrap());
+ .insert(
+ "websocket"
+ .parse::<h3::ext::Protocol>()
+ .unwrap_or_else(|_| panic!("websocket is a valid HTTP/3 protocol token")),
+ );
request
}
#[test]
@@ -702,7 +706,11 @@ mod tests {
let mut request = h3_request();
request
.extensions_mut()
- .insert("connect-udp".parse::<h3::ext::Protocol>().unwrap());
+ .insert(
+ "connect-udp"
+ .parse::<h3::ext::Protocol>()
+ .unwrap_or_else(|_| panic!("connect-udp is a valid HTTP/3 protocol token")),
+ );
assert!(validate_h3(&request).is_err());
}
#[test]
diff --git a/tests/http3.rs b/tests/http3.rs
index c5990bc..6f775ea 100644
--- a/tests/http3.rs
+++ b/tests/http3.rs
@@ -14,7 +14,11 @@ fn rfc9220_extended_connect_is_recognized() {
.unwrap();
request
.extensions_mut()
- .insert("websocket".parse::<h3::ext::Protocol>().unwrap());
+ .insert(
+ "websocket"
+ .parse::<h3::ext::Protocol>()
+ .unwrap_or_else(|_| panic!("websocket is a valid HTTP/3 protocol token")),
+ );
assert_eq!(h3_protocol(&request), Some("websocket"));
let handshake = validate_h3(&request).expect("valid RFC 9220 bootstrap");