#!/bin/bash # slow-server - start a web server that responds after a configurable delay # # Usage: # slow-server [port] # slow-server -h # # Options: # port Port to listen on (default: 8080) # -h, --help Show help message # # Starts a socat-based HTTP server where the last path segment of each request # is the delay in milliseconds. Requests without a numeric path return 404 # e.g. `curl http://localhost:8080/2500` responds after ~2.5 seconds _slow_server() ( local SCRIPT_NAME; SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")" case "${BASH_SOURCE[0]}" in /dev/*|/proc/*) SCRIPT_NAME="" ;; esac case "$SCRIPT_NAME" in ""|bash|sh|zsh|dash) SCRIPT_NAME="slow-server" ;; esac _error() { echo "[ERR][$SCRIPT_NAME] $*" >&2; } _show_help() { local s; [ -t 1 ] && s=$'\033[4m' local r; [ -t 1 ] && r=$'\033[24m' cat <&2 # Ignore other paths, return not found if ! _is_number "$last"; then echo " [ignored]" >&2 # append to previous line printf 'HTTP/1.1 404 Not Found\r\n\r\n' return 0 else local delay_ms="$last" printf '\n' >&2 # move to next line fi local seconds="$((delay_ms / 1000)).$((delay_ms % 1000))" sleep "$seconds" printf 'HTTP/1.1 200 OK\r\n\r\n%s\n' "$last" echo "Done: $method $path ($delay_ms)" >&2 unset -f _is_number } case "$1" in -h|--help) _show_help; return 0 ;; esac # Function arguments local port="${1:-8080}" # Check for socat dependency if ! command -v socat >/dev/null 2>&1; then _error "socat is required" return 3 fi export -f _slow_response # exported for socat # Start simple server echo "Starting server at http://localhost:$port" socat "TCP-LISTEN:$port,fork,reuseaddr" "SYSTEM:_slow_response" # _slow_response and any exports die with the wrapper subshell on return ) _slow_server "$@" __slow_server_rc=$? unset -f _slow_server if [ -n "${BASH_SOURCE[0]}" ] && [ "${BASH_SOURCE[0]}" != "$0" ]; then eval "unset __slow_server_rc; return $__slow_server_rc" fi eval "unset __slow_server_rc; exit $__slow_server_rc"