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
21 changes: 8 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ httpjail --request-log requests.log --js "true" -- npm install
# Log format: "<timestamp> <+/-> <METHOD> <URL>" (+ = allowed, - = blocked)

# Use custom script for request evaluation
httpjail --script /path/to/check.sh -- ./my-app
httpjail --sh /path/to/check.sh -- ./my-app
# Script receives: HTTPJAIL_URL, HTTPJAIL_METHOD, HTTPJAIL_HOST, HTTPJAIL_SCHEME, HTTPJAIL_PATH
# Exit 0 to allow, non-zero to block. stdout becomes additional context in 403 response.

Expand Down Expand Up @@ -170,26 +170,21 @@ Instead of writing JavaScript, you can use a custom script to evaluate each requ

```bash
# Simple script example
cat > check_request.sh << 'EOF'
#!/bin/bash
# Allow only GitHub and reject everything else
if [[ "$HTTPJAIL_HOST" == "github.com" ]]; then
exit 0
if [ "$HTTPJAIL_HOST" = "github.com" ] && [ "$HTTPJAIL_METHOD" = "GET" ]; then
exit 0 # Allow the request
else
echo "Access denied: $HTTPJAIL_HOST is not on the allowlist"
exit 1
exit 1 # Block the request
fi
EOF
chmod +x check_request.sh

# Use the script
httpjail --script ./check_request.sh -- curl https://github.com
httpjail --sh ./check_request.sh -- curl https://github.com

# Inline script (with spaces, executed via shell)
httpjail --script '[ "$HTTPJAIL_HOST" = "github.com" ] && exit 0 || exit 1' -- git pull
httpjail --sh '[ "$HTTPJAIL_HOST" = "github.com" ] && exit 0 || exit 1' -- git pull
```

If `--script` has spaces, it's run through `$SHELL` (default `/bin/sh`); otherwise it's executed directly.
If `--sh` has spaces, it's run through `sh`; otherwise it's executed directly.

**Environment variables provided to the script:**

Expand Down Expand Up @@ -259,7 +254,7 @@ All request information is available via the `r` object:
- JavaScript evaluation is generally faster than external script execution

> [!NOTE]
> The `--js` flag conflicts with `--script` and `--js-file`. Only one evaluation method can be used at a time.
> The `--js` flag conflicts with `--sh` and `--js-file`. Only one evaluation method can be used at a time.

### Advanced Options

Expand Down
10 changes: 5 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ struct Args {
/// HTTPJAIL_URL, HTTPJAIL_METHOD, HTTPJAIL_HOST, HTTPJAIL_SCHEME, HTTPJAIL_PATH
/// Exit code 0 allows the request, non-zero blocks it
/// stdout becomes additional context in the 403 response
#[arg(short = 's', long = "script", value_name = "PROG")]
script: Option<String>,
#[arg(long = "sh", value_name = "PROG")]
sh: Option<String>,

/// Use JavaScript (V8) for evaluating requests
/// The JavaScript code receives global variables:
Expand All @@ -33,7 +33,7 @@ struct Args {
#[arg(
long = "js",
value_name = "CODE",
conflicts_with = "script",
conflicts_with = "sh",
conflicts_with = "js_file"
)]
js: Option<String>,
Expand All @@ -43,7 +43,7 @@ struct Args {
#[arg(
long = "js-file",
value_name = "FILE",
conflicts_with = "script",
conflicts_with = "sh",
conflicts_with = "js"
)]
js_file: Option<String>,
Expand Down Expand Up @@ -298,7 +298,7 @@ async fn main() -> Result<()> {
None
};

let rule_engine = if let Some(script) = &args.script {
let rule_engine = if let Some(script) = &args.sh {
info!("Using script-based rule evaluation: {}", script);
let script_engine = Box::new(ScriptRuleEngine::new(script.clone()));
RuleEngine::from_trait(script_engine, request_log)
Expand Down
3 changes: 1 addition & 2 deletions src/rules/script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ impl ScriptRuleEngine {

// Build the command
let mut cmd = if self.script.contains(' ') {
let shell = std::env::var("SHELL").unwrap_or_else(|_| "/bin/sh".to_string());
let mut cmd = tokio::process::Command::new(&shell);
let mut cmd = tokio::process::Command::new("sh");
cmd.arg("-c").arg(&self.script);
cmd
} else {
Expand Down
Loading