Hot fix for version 2.28

This commit is contained in:
Russel Yasol
2025-08-24 18:13:37 +08:00
parent 752fce41b4
commit 8e99618f2a
157 changed files with 1609 additions and 478 deletions

View File

@@ -0,0 +1,301 @@
#!/bin/sh
# Memory Settings Configuration Script
# Manages memory service (enable/disable) and daemon settings with dynamic service management
# Handle OPTIONS request first
if [ "${REQUEST_METHOD:-GET}" = "OPTIONS" ]; then
echo "Content-Type: text/plain"
echo "Access-Control-Allow-Origin: *"
echo "Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS"
echo "Access-Control-Allow-Headers: Content-Type"
echo "Access-Control-Max-Age: 86400"
echo ""
exit 0
fi
# Set content type and CORS headers
echo "Content-Type: application/json"
echo "Access-Control-Allow-Origin: *"
echo "Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS"
echo "Access-Control-Allow-Headers: Content-Type"
echo ""
# Configuration paths
CONFIG_DIR="/etc/quecmanager/settings"
CONFIG_FILE="$CONFIG_DIR/memory_settings.conf"
FALLBACK_CONFIG_DIR="/tmp/quecmanager/settings"
FALLBACK_CONFIG_FILE="$FALLBACK_CONFIG_DIR/memory_settings.conf"
LOG_FILE="/tmp/memory_settings.log"
SERVICES_INIT="/etc/init.d/quecmanager_services"
# Logging function
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
# Error response function
send_error() {
local error_code="$1"
local error_message="$2"
log_message "ERROR: $error_message"
echo "{\"status\":\"error\",\"code\":\"$error_code\",\"message\":\"$error_message\"}"
exit 1
}
# Success response function
send_success() {
local message="$1"
local data="$2"
log_message "SUCCESS: $message"
if [ -n "$data" ]; then
echo "{\"status\":\"success\",\"message\":\"$message\",\"data\":$data}"
else
echo "{\"status\":\"success\",\"message\":\"$message\"}"
fi
}
# Get current configuration
get_config() {
# Defaults
ENABLED="false"
INTERVAL="1"
# Try primary config first, then fallback
local config_to_read=""
if [ -f "$CONFIG_FILE" ]; then
config_to_read="$CONFIG_FILE"
elif [ -f "$FALLBACK_CONFIG_FILE" ]; then
config_to_read="$FALLBACK_CONFIG_FILE"
fi
if [ -n "$config_to_read" ]; then
local enabled_val=$(grep "^MEMORY_ENABLED=" "$config_to_read" 2>/dev/null | tail -n1 | cut -d'=' -f2)
local interval_val=$(grep "^MEMORY_INTERVAL=" "$config_to_read" 2>/dev/null | tail -n1 | cut -d'=' -f2)
case "$enabled_val" in
true|1|on|yes|enabled) ENABLED="true" ;;
*) ENABLED="false" ;;
esac
if echo "$interval_val" | grep -qE '^[0-9]+$' && [ "$interval_val" -ge 1 ] && [ "$interval_val" -le 10 ]; then
INTERVAL="$interval_val"
fi
fi
}
# Save configuration
save_config() {
local enabled="$1"
local interval="$2"
# Try primary location first
if mkdir -p "$CONFIG_DIR" 2>/dev/null && [ -w "$CONFIG_DIR" ]; then
{
echo "MEMORY_ENABLED=$enabled"
echo "MEMORY_INTERVAL=$interval"
} > "$CONFIG_FILE" && chmod 644 "$CONFIG_FILE" 2>/dev/null
log_message "Saved config to primary location: enabled=$enabled, interval=$interval"
return 0
fi
# Fallback to tmp
mkdir -p "$FALLBACK_CONFIG_DIR" 2>/dev/null
{
echo "MEMORY_ENABLED=$enabled"
echo "MEMORY_INTERVAL=$interval"
} > "$FALLBACK_CONFIG_FILE" && chmod 644 "$FALLBACK_CONFIG_FILE" 2>/dev/null
log_message "Saved config to fallback location: enabled=$enabled, interval=$interval"
}
# Add memory daemon to services init script
add_memory_daemon_to_services() {
if [ ! -f "$SERVICES_INIT" ]; then
log_message "Services init file not found: $SERVICES_INIT"
return 1
fi
# Check if memory daemon is already present
if grep -q "memory_daemon.sh" "$SERVICES_INIT" 2>/dev/null; then
log_message "Memory daemon already present in services"
return 0
fi
# Create a temporary file with the memory daemon block
local temp_file="/tmp/services_temp_$$"
# Find the line before "echo \"All QuecManager services Started\"" and insert memory daemon
awk '
/echo "All QuecManager services Started"/ {
print " # Start memory daemon"
print " echo \"Starting Memory Daemon...\""
print " procd_open_instance"
print " procd_set_param command /www/cgi-bin/services/memory_daemon.sh"
print " procd_set_param respawn"
print " procd_set_param stdout 1"
print " procd_set_param stderr 1"
print " procd_close_instance"
print " echo \"Memory Daemon started\""
print ""
}
{ print }
' "$SERVICES_INIT" > "$temp_file"
if [ -s "$temp_file" ]; then
mv "$temp_file" "$SERVICES_INIT"
chmod +x "$SERVICES_INIT"
log_message "Added memory daemon to services init script"
return 0
else
rm -f "$temp_file"
log_message "Failed to add memory daemon to services"
return 1
fi
}
# Remove memory daemon from services init script
remove_memory_daemon_from_services() {
if [ ! -f "$SERVICES_INIT" ]; then
log_message "Services init file not found: $SERVICES_INIT"
return 1
fi
# Check if memory daemon is present
if ! grep -q "memory_daemon.sh" "$SERVICES_INIT" 2>/dev/null; then
log_message "Memory daemon not present in services"
return 0
fi
# Remove the memory daemon block (from "# Start memory daemon" to the empty line after)
local temp_file="/tmp/services_temp_$$"
awk '
/# Start memory daemon/ { skip=1; next }
skip && /^$/ { skip=0; next }
!skip { print }
' "$SERVICES_INIT" > "$temp_file"
if [ -s "$temp_file" ]; then
mv "$temp_file" "$SERVICES_INIT"
chmod +x "$SERVICES_INIT"
log_message "Removed memory daemon from services init script"
return 0
else
rm -f "$temp_file"
log_message "Failed to remove memory daemon from services"
return 1
fi
}
# Restart QuecManager services
restart_services() {
log_message "Restarting QuecManager services..."
# Stop services
if [ -x "$SERVICES_INIT" ]; then
"$SERVICES_INIT" stop >/dev/null 2>&1
sleep 2
"$SERVICES_INIT" start >/dev/null 2>&1
log_message "Services restarted successfully"
return 0
else
log_message "Cannot restart services - init script not found or not executable"
return 1
fi
}
# Check if memory daemon is running
is_memory_daemon_running() {
pgrep -f "memory_daemon.sh" >/dev/null 2>&1
}
# Handle POST request - Update memory setting
handle_post() {
log_message "POST request received"
local content_length=${CONTENT_LENGTH:-0}
if [ "$content_length" -eq 0 ]; then
send_error "NO_DATA" "No data provided"
fi
# Read POST data
local post_data=$(dd bs=$content_length count=1 2>/dev/null)
log_message "Received POST data: $post_data"
# Parse enabled and interval from JSON
local enabled=$(echo "$post_data" | sed -n 's/.*"enabled"[[:space:]]*:[[:space:]]*\([^,}]*\).*/\1/p' | tr -d ' "')
local interval=$(echo "$post_data" | sed -n 's/.*"interval"[[:space:]]*:[[:space:]]*\([0-9][0-9]*\).*/\1/p')
# Set defaults if not provided
[ -z "$enabled" ] && enabled="false"
[ -z "$interval" ] && interval="1"
# Validate input
case "$enabled" in
true|false) ;;
*) send_error "INVALID_SETTING" "Invalid enabled value. Must be true or false." ;;
esac
if ! echo "$interval" | grep -qE '^[0-9]+$' || [ "$interval" -lt 1 ] || [ "$interval" -gt 10 ]; then
send_error "INVALID_INTERVAL" "Interval must be a number between 1 and 10 seconds."
fi
# Get current config to compare
get_config
local prev_enabled="$ENABLED"
local prev_interval="$INTERVAL"
# Save new configuration
save_config "$enabled" "$interval"
# Handle service changes
if [ "$enabled" = "true" ]; then
# Enable memory daemon
add_memory_daemon_to_services
if [ "$prev_enabled" != "true" ] || [ "$prev_interval" != "$interval" ]; then
restart_services
fi
else
# Disable memory daemon
remove_memory_daemon_from_services
restart_services
fi
# Return current status
sleep 1 # Give services time to start/stop
local running="false"
if is_memory_daemon_running; then
running="true"
fi
send_success "Memory setting updated successfully" "{\"enabled\":$enabled,\"interval\":$interval,\"running\":$running}"
}
# Handle DELETE request - Reset to default
handle_delete() {
log_message "DELETE request received"
# Remove memory daemon from services and restart
remove_memory_daemon_from_services
restart_services
# Remove config files
rm -f "$CONFIG_FILE" "$FALLBACK_CONFIG_FILE" 2>/dev/null
send_success "Memory setting reset to default (disabled)" "{\"enabled\":false,\"interval\":1,\"running\":false,\"isDefault\":true}"
}
# Main execution
log_message "Memory settings script called with method: ${REQUEST_METHOD:-GET}"
case "${REQUEST_METHOD:-GET}" in
POST)
handle_post
;;
DELETE)
handle_delete
;;
*)
send_error "METHOD_NOT_ALLOWED" "HTTP method ${REQUEST_METHOD} not supported."
;;
esac

View File

@@ -1,11 +1,22 @@
#!/bin/sh
# Ping Settings Configuration Script
# Manages ping enable/disable preferences
# Manages ping service (enable/disable) and daemon settings
# Author: dr-dolomite
# Date: 2025-08-04
# Set content type and CORS headers
# Handle OPTIONS request first (before any headers)
if [ "${REQUEST_METHOD:-GET}" = "OPTIONS" ]; then
echo "Content-Type: text/plain"
echo "Access-Control-Allow-Origin: *"
echo "Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS"
echo "Access-Control-Allow-Headers: Content-Type"
echo "Access-Control-Max-Age: 86400"
echo ""
exit 0
fi
# Set content type and CORS headers for other requests
echo "Content-Type: application/json"
echo "Access-Control-Allow-Origin: *"
echo "Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS"
@@ -15,7 +26,12 @@ echo ""
# Configuration
CONFIG_DIR="/etc/quecmanager/settings"
CONFIG_FILE="$CONFIG_DIR/ping_settings.conf"
FALLBACK_CONFIG_DIR="/tmp/quecmanager/settings"
FALLBACK_CONFIG_FILE="$FALLBACK_CONFIG_DIR/ping_settings.conf"
LOG_FILE="/tmp/ping_settings.log"
PID_FILE="/tmp/quecmanager/ping_daemon.pid"
# Prefer the new services location, fall back to the legacy path for compatibility
DAEMON_RELATIVE_PATHS="/cgi-bin/services/ping_daemon.sh"
# Logging function
log_message() {
@@ -43,99 +59,176 @@ send_success() {
fi
}
# Ensure configuration directory exists
ensure_config_directory() {
if [ ! -d "$CONFIG_DIR" ]; then
log_message "Creating directory: $CONFIG_DIR"
mkdir -p "$CONFIG_DIR"
if [ $? -ne 0 ]; then
# Try to use a fallback location in /tmp
CONFIG_DIR="/tmp/quecmanager/settings"
CONFIG_FILE="$CONFIG_DIR/ping_settings.conf"
log_message "Fallback to alternative location: $CONFIG_DIR"
mkdir -p "$CONFIG_DIR"
if [ $? -ne 0 ]; then
send_error "DIRECTORY_ERROR" "Failed to create configuration directory"
fi
fi
chmod 755 "$CONFIG_DIR"
log_message "Created configuration directory: $CONFIG_DIR"
# Resolve config file for reading: prefer primary, then fallback
resolve_config_for_read() {
if [ -f "$CONFIG_FILE" ]; then
return 0
elif [ -f "$FALLBACK_CONFIG_FILE" ]; then
CONFIG_FILE="$FALLBACK_CONFIG_FILE"
CONFIG_DIR="$FALLBACK_CONFIG_DIR"
return 0
fi
# Default to primary path if none exist
return 0
}
# Determine daemon path (absolute) based on typical web root layouts
resolve_daemon_path() {
# Common locations where CGI/WWW is mounted
for rel in $DAEMON_RELATIVE_PATHS; do
for base in \
/www \
/; do
if [ -x "$base$rel" ]; then
echo "$base$rel"
return 0
fi
done
# Also try as-is if busybox httpd cwd matches web root
if [ -x "$rel" ]; then
echo "$rel"
return 0
fi
done
# Nothing found; return first candidate as a best-effort path
set -- $DAEMON_RELATIVE_PATHS
echo "$1"
}
daemon_running() {
if [ -f "$PID_FILE" ]; then
pid="$(cat "$PID_FILE" 2>/dev/null || true)"
if [ -n "${pid:-}" ] && kill -0 "$pid" 2>/dev/null; then
return 0
fi
fi
return 1
}
start_daemon() {
# Ensure /tmp/quecmanager exists for PID
[ -d "/tmp/quecmanager" ] || mkdir -p "/tmp/quecmanager"
if daemon_running; then
log_message "Daemon already running"
return 0
fi
local daemon_path
daemon_path="$(resolve_daemon_path)"
if [ ! -x "$daemon_path" ]; then
# Try to make it executable if present
if [ -f "$daemon_path" ]; then
chmod +x "$daemon_path" 2>/dev/null || true
fi
fi
if [ -x "$daemon_path" ]; then
nohup "$daemon_path" >/dev/null 2>&1 &
log_message "Started ping daemon: $daemon_path (pid $!)"
return 0
else
log_message "Daemon script not found or not executable: $daemon_path"
return 1
fi
}
stop_daemon() {
if daemon_running; then
pid="$(cat "$PID_FILE" 2>/dev/null || true)"
if [ -n "${pid:-}" ]; then
kill "$pid" 2>/dev/null || true
sleep 0.2
kill -9 "$pid" 2>/dev/null || true
fi
fi
rm -f "$PID_FILE" 2>/dev/null || true
}
# Get current ping setting
get_ping_setting() {
# If config file exists, read from it
get_config_values() {
# defaults
ENABLED="true"
HOST="8.8.8.8"
INTERVAL="5"
resolve_config_for_read
if [ -f "$CONFIG_FILE" ]; then
ping_enabled=$(grep "^PING_ENABLED=" "$CONFIG_FILE" | cut -d'=' -f2)
if [ -n "$ping_enabled" ]; then
if [ "$ping_enabled" = "true" ] || [ "$ping_enabled" = "1" ] || [ "$ping_enabled" = "on" ]; then
echo "true"
else
echo "false"
fi
return
val=$(grep -E "^PING_ENABLED=" "$CONFIG_FILE" | tail -n1 | cut -d'=' -f2)
if [ -n "${val:-}" ]; then
case "$val" in
true|1|on|yes|enabled) ENABLED="true" ;;
*) ENABLED="false" ;;
esac
fi
val=$(grep -E "^PING_HOST=" "$CONFIG_FILE" | tail -n1 | cut -d'=' -f2)
[ -n "${val:-}" ] && HOST="$val"
val=$(grep -E "^PING_INTERVAL=" "$CONFIG_FILE" | tail -n1 | cut -d'=' -f2)
if echo "${val:-}" | grep -qE '^[0-9]+$'; then
INTERVAL="$val"
fi
fi
# Default to enabled if no config exists
echo "true"
}
# Save ping setting to config file
save_ping_setting() {
save_config() {
local enabled="$1"
ensure_config_directory
# Create or update config file
if [ -f "$CONFIG_FILE" ]; then
# Update existing file
sed -i "s/^PING_ENABLED=.*$/PING_ENABLED=$enabled/" "$CONFIG_FILE"
if [ $? -ne 0 ]; then
# If sed fails (e.g., no match), append the setting
echo "PING_ENABLED=$enabled" >> "$CONFIG_FILE"
local host="$2"
local interval="$3"
# Try primary directory first
if mkdir -p "$CONFIG_DIR" 2>/dev/null; then
local tmp="$CONFIG_FILE.tmp.$$"
echo "PING_ENABLED=$enabled" > "$tmp" || rm -f "$tmp" || return 1
echo "PING_HOST=$host" >> "$tmp" || rm -f "$tmp" || return 1
echo "PING_INTERVAL=$interval" >> "$tmp" || rm -f "$tmp" || return 1
if mv -f "$tmp" "$CONFIG_FILE" 2>/dev/null; then
chmod 644 "$CONFIG_FILE" 2>/dev/null || true
log_message "Saved ping config (primary): enabled=$enabled host=$host interval=$interval"
return 0
fi
else
# Create new file
echo "PING_ENABLED=$enabled" > "$CONFIG_FILE"
fi
chmod 644 "$CONFIG_FILE"
log_message "Saved ping setting: $enabled"
# Fallback to /tmp
mkdir -p "$FALLBACK_CONFIG_DIR" 2>/dev/null || true
local tmp2="$FALLBACK_CONFIG_FILE.tmp.$$"
echo "PING_ENABLED=$enabled" > "$tmp2" || rm -f "$tmp2" || return 1
echo "PING_HOST=$host" >> "$tmp2" || rm -f "$tmp2" || return 1
echo "PING_INTERVAL=$interval" >> "$tmp2" || rm -f "$tmp2" || return 1
mv -f "$tmp2" "$FALLBACK_CONFIG_FILE" 2>/dev/null || return 1
chmod 644 "$FALLBACK_CONFIG_FILE" 2>/dev/null || true
# Point CONFIG_FILE to fallback for subsequent reads in this request
CONFIG_FILE="$FALLBACK_CONFIG_FILE"; CONFIG_DIR="$FALLBACK_CONFIG_DIR"
log_message "Saved ping config (fallback): enabled=$enabled host=$host interval=$interval"
}
# Delete ping configuration (reset to default)
delete_ping_setting() {
if [ -f "$CONFIG_FILE" ]; then
# Remove the PING_ENABLED line
sed -i '/^PING_ENABLED=/d' "$CONFIG_FILE"
log_message "Deleted ping configuration"
# If file is empty after deletion, remove it
if [ ! -s "$CONFIG_FILE" ]; then
rm -f "$CONFIG_FILE"
log_message "Removed empty config file"
local removed=1
for f in "$CONFIG_FILE" "$FALLBACK_CONFIG_FILE"; do
if [ -f "$f" ]; then
sed -i '/^PING_ENABLED=/d' "$f" 2>/dev/null || true
sed -i '/^PING_HOST=/d' "$f" 2>/dev/null || true
sed -i '/^PING_INTERVAL=/d' "$f" 2>/dev/null || true
log_message "Deleted ping configuration entries in $f"
[ -s "$f" ] || { rm -f "$f" 2>/dev/null || true; log_message "Removed empty config file $f"; }
removed=0
fi
return 0
else
return 1
fi
done
return $removed
}
# Handle GET request - Retrieve ping setting
handle_get() {
log_message "GET request received"
# Get current setting (from config or default)
local enabled=$(get_ping_setting)
# Check if it's from config or default
get_config_values
local running=false
if daemon_running; then running=true; fi
local is_default=true
if [ -f "$CONFIG_FILE" ] && grep -q "^PING_ENABLED=" "$CONFIG_FILE"; then
is_default=false
fi
send_success "Ping setting retrieved" "{\"enabled\":$enabled,\"isDefault\":$is_default}"
send_success "Ping configuration retrieved" "{\"enabled\":$ENABLED,\"host\":\"$HOST\",\"interval\":$INTERVAL,\"running\":$running,\"isDefault\":$is_default}"
}
# Handle POST request - Update ping setting
@@ -148,38 +241,58 @@ handle_post() {
local post_data=$(dd bs=$content_length count=1 2>/dev/null)
log_message "Received POST data: $post_data"
# Parse JSON to extract enabled value
local enabled=""
# Approach 1: Simple regex extraction for boolean
enabled=$(echo "$post_data" | sed -n 's/.*"enabled"[[:space:]]*:[[:space:]]*\([^,}]*\).*/\1/p' | tr -d ' ')
# Approach 2: grep + cut extraction
if [ -z "$enabled" ]; then
enabled=$(echo "$post_data" | grep -o '"enabled":[^,}]*' | cut -d':' -f2 | tr -d ' ')
# Parse fields
local enabled host interval
enabled=$(echo "$post_data" | sed -n 's/.*"enabled"[[:space:]]*:[[:space:]]*\([^,}]*\).*/\1/p' | tr -d ' ' | sed 's/"//g')
host=$(echo "$post_data" | sed -n 's/.*"host"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p')
interval=$(echo "$post_data" | sed -n 's/.*"interval"[[:space:]]*:[[:space:]]*\([0-9][0-9]*\).*/\1/p')
# Defaults when missing
[ -z "$enabled" ] && enabled="true"
[ -z "$host" ] && host="8.8.8.8"
[ -z "$interval" ] && interval="5"
# Validate
case "$enabled" in
true|false) : ;;
*) send_error "INVALID_SETTING" "Invalid enabled value. Must be true or false." ;;
esac
if ! echo "$interval" | grep -qE '^[0-9]+$'; then
send_error "INVALID_INTERVAL" "Interval must be a number (seconds)."
fi
# Approach 3: Look for true/false in the payload
if [ -z "$enabled" ]; then
if echo "$post_data" | grep -q '"enabled"[[:space:]]*:[[:space:]]*true'; then
enabled="true"
elif echo "$post_data" | grep -q '"enabled"[[:space:]]*:[[:space:]]*false'; then
enabled="false"
if [ "$interval" -lt 1 ] || [ "$interval" -gt 3600 ]; then
send_error "INVALID_INTERVAL" "Interval must be between 1 and 3600 seconds."
fi
# Capture previous values to decide on restart
get_config_values
local prev_enabled="$ENABLED"
local prev_host="$HOST"
local prev_interval="$INTERVAL"
save_config "$enabled" "$host" "$interval" || send_error "WRITE_FAILED" "Failed to save configuration"
if [ "$enabled" = "true" ]; then
if daemon_running; then
# Restart only if effective parameters changed
if [ "$prev_host" != "$host" ] || [ "$prev_interval" != "$interval" ] || [ "$prev_enabled" != "$enabled" ]; then
log_message "Config change detected (host/interval/enabled). Restarting daemon."
stop_daemon
start_daemon || log_message "Failed to restart daemon"
else
log_message "No change requiring restart; daemon remains running"
fi
else
start_daemon || log_message "Failed to start daemon"
fi
fi
# Clean up the value (remove quotes if present)
enabled=$(echo "$enabled" | sed 's/"//g')
log_message "Received enabled: $enabled"
# Validate setting
if [ "$enabled" = "true" ] || [ "$enabled" = "false" ]; then
save_ping_setting "$enabled"
send_success "Ping setting updated successfully" "{\"enabled\":$enabled}"
else
send_error "INVALID_SETTING" "Invalid setting provided. Must be 'true' or 'false'."
stop_daemon
fi
get_config_values
local running=false
if daemon_running; then running=true; fi
send_success "Ping setting updated successfully" "{\"enabled\":$ENABLED,\"host\":\"$HOST\",\"interval\":$INTERVAL,\"running\":$running}"
else
send_error "NO_DATA" "No data provided"
fi
@@ -188,24 +301,15 @@ handle_post() {
# Handle DELETE request - Reset to default (delete configuration)
handle_delete() {
log_message "DELETE request received"
stop_daemon
if delete_ping_setting; then
# Default is enabled
send_success "Ping setting reset to default" "{\"enabled\":true,\"isDefault\":true}"
send_success "Ping setting reset to default" "{\"enabled\":true,\"isDefault\":true,\"running\":false}"
else
send_error "NOT_FOUND" "Ping setting configuration not found"
fi
}
# Handle OPTIONS request for CORS preflight
handle_options() {
log_message "OPTIONS request received"
echo "Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONS"
echo "Access-Control-Allow-Headers: Content-Type"
echo "Access-Control-Max-Age: 86400"
exit 0
}
# Main execution
log_message "Ping settings script called with method: ${REQUEST_METHOD:-GET}"
@@ -220,10 +324,7 @@ case "${REQUEST_METHOD:-GET}" in
DELETE)
handle_delete
;;
OPTIONS)
handle_options
;;
*)
send_error "METHOD_NOT_ALLOWED" "HTTP method ${REQUEST_METHOD} not supported"
;;
esac
esac