Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Rule Engines

httpjail provides three different rule engines for evaluating HTTP requests. Each has different trade-offs in terms of performance, flexibility, and ease of use.

Engine Comparison

FeatureJavaScript (V8)Shell ScriptLine Processor
Performance
Per-Request Latency550µs-1.3ms700µs-1.6ms70-90µs
Capabilities
Stateful Processing
External Tool Access
Language ChoiceJS onlyAnyAny
Sandboxed ExecutionDepends
Development ComplexityEasyEasyModerate

Performance Note: Latency measurements are from benchmarks on modern hardware. JavaScript (V8) creates a new isolate per request for safety. Line processor maintains a persistent process, providing the best performance for high-throughput scenarios.

Examples

Simple Host Filtering

All three engines can handle basic filtering:

JavaScript:

httpjail --js "r.host === 'github.com'" -- command

Shell Script:

#!/bin/bash
[[ "$HTTPJAIL_HOST" == "github.com" ]] && exit 0 || exit 1

Line Processor:

#!/usr/bin/env python3
import sys, json
for line in sys.stdin:
    req = json.loads(line)
    print("true" if req["host"] == "github.com" else "false")

Complex Logic

For complex scenarios, consider the implementation complexity:

JavaScript - Limited to expression evaluation:

// Complex but still performant
const allowed = ["api.example.com", "cdn.example.com"];
allowed.includes(r.host) && r.method === "GET" && r.path.startsWith("/v1/");

Shell Script - Can use any tool but slower:

#!/bin/bash
# Check against database, but spawns process per request
psql -c "SELECT allowed FROM rules WHERE host='$HTTPJAIL_HOST'" | grep -q true

Line Processor - Best for complex stateful logic:

#!/usr/bin/env python3
# Maintains state, handles thousands of requests efficiently
import sys, json, time
from collections import defaultdict

rate_limits = defaultdict(lambda: {"count": 0, "reset": time.time() + 60})

for line in sys.stdin:
    req = json.loads(line)
    host_limit = rate_limits[req["host"]]

    if time.time() > host_limit["reset"]:
        host_limit["count"] = 0
        host_limit["reset"] = time.time() + 60

    if host_limit["count"] < 100:  # 100 requests per minute
        host_limit["count"] += 1
        print("true")
    else:
        print("false")
    sys.stdout.flush()

Next Steps