Skip to content
Merged
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
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ jobs:
- name: Run tests
run: litac test

- name: Build h2spec conformance image
run: docker build --no-cache -f Dockerfile.h2spec -t ring-h2spec .

- name: Run h2spec RFC 7540 conformance
run: docker run --rm --security-opt seccomp=unconfined ring-h2spec /app/entrypoint.sh

test-macos:
name: Test (macOS)
runs-on: macos-latest
Expand Down
68 changes: 68 additions & 0 deletions Dockerfile.h2spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Build ringhttp and run h2spec (RFC 7540 conformance) against it.
#
# docker build -f Dockerfile.h2spec -t ring-h2spec .
# docker run --rm --security-opt seccomp=unconfined ring-h2spec

FROM ubuntu:24.04 AS builder

RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
git \
curl \
liburing-dev \
libcurl4-openssl-dev \
libssl-dev \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*

# Two-stage litac bootstrap (same as Dockerfile.test)
RUN git clone https://github.com/tonysparks/litac-lang /opt/litac-lang

RUN gcc -O2 -o /usr/local/bin/litac_bootstrap \
/opt/litac-lang/bootstrap/litac_linux.c \
-D_CRT_SECURE_NO_WARNINGS -D_DEFAULT_SOURCE \
-I/opt/litac-lang/include \
-I/opt/litac-lang/stdlib/std/http/libcurl/include \
-L/opt/litac-lang/lib \
-lm -lrt -lpthread -lcurl

ENV LITAC_HOME=/opt/litac-lang

RUN mkdir -p /opt/litac-lang/bin/output \
&& cd /opt/litac-lang \
&& litac_bootstrap build \
&& cp /opt/litac-lang/bin/output/litac /usr/local/bin/litac

WORKDIR /build
COPY . .
RUN litac install

# Build the h2spec server (swap in the dedicated entry point)
RUN cp test/h2spec_server_main.lita src/main.lita && litac build

# Build h2spec from source — no ARM64 pre-built binary exists for v2.6.0.
FROM golang:1.22-bookworm AS h2spec-builder
RUN git clone --depth 1 --branch v2.6.0 https://github.com/summerwind/h2spec.git /tmp/h2spec \
&& cd /tmp/h2spec \
&& go build -o /usr/local/bin/h2spec ./cmd/h2spec \
&& rm -rf /tmp/h2spec

# ── runtime ──────────────────────────────────────────────────────────────────
FROM ubuntu:24.04

RUN apt-get update && apt-get install -y --no-install-recommends \
liburing2 \
netcat-openbsd \
&& rm -rf /var/lib/apt/lists/*

EXPOSE 9090

WORKDIR /app
COPY --from=builder /build/bin/ring ./ring
COPY --from=h2spec-builder /usr/local/bin/h2spec /usr/local/bin/h2spec
COPY h2spec_entrypoint.sh ./entrypoint.sh
RUN chmod +x ./ring ./entrypoint.sh

# Default: run the ring server so testcontainers can start + exec into it.
# For standalone use, override with: docker run ring-h2spec /app/entrypoint.sh
CMD ["/app/ring"]
32 changes: 32 additions & 0 deletions h2spec_entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash
# Start the ringhttp server, wait for it, run h2spec, propagate exit code.
set -euo pipefail

PORT=9090
WAIT_SEC=30

echo "==> Starting ringhttp on port $PORT..."
/app/ring &
SERVER_PID=$!

echo "==> Waiting for server (up to ${WAIT_SEC}s)..."
for i in $(seq 1 $WAIT_SEC); do
if nc -z localhost $PORT 2>/dev/null; then
echo " Ready after ${i}s"
break
fi
if [ "$i" -eq "$WAIT_SEC" ]; then
echo "ERROR: server did not start within ${WAIT_SEC}s"
kill "$SERVER_PID" 2>/dev/null || true
exit 1
fi
sleep 1
done

echo "==> Running h2spec against localhost:$PORT..."
h2spec -h localhost -p "$PORT" --timeout 10
EXIT_CODE=$?

kill "$SERVER_PID" 2>/dev/null || true
echo "==> h2spec exited with code $EXIT_CODE"
exit "$EXIT_CODE"
21 changes: 21 additions & 0 deletions run_h2spec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
# Build and run the h2spec conformance suite against ringhttp.
# Usage: ./run_h2spec.sh [--no-cache]
#
# Requires --security-opt seccomp=unconfined for io_uring syscalls.
# Exit code mirrors h2spec: 0 = all passed, non-zero = failures.

set -euo pipefail

IMAGE=ring-h2spec
NO_CACHE=

if [[ "${1:-}" == "--no-cache" ]]; then
NO_CACHE="--no-cache"
fi

echo "==> Building h2spec image..."
docker build $NO_CACHE -f Dockerfile.h2spec -t "$IMAGE" .

echo "==> Running h2spec..."
docker run --rm --security-opt seccomp=unconfined "$IMAGE" /app/entrypoint.sh
Loading
Loading