#!/bin/sh set -eu SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) APP_DIR=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd) CONFIG_PATH=${1:-"$APP_DIR/router_local.conf"} if [ ! -r "$CONFIG_PATH" ]; then echo "[router-http] config not found: $CONFIG_PATH" >&2 exit 1 fi # shellcheck disable=SC1090 . "$CONFIG_PATH" RUNTIME_DIR=${RUNTIME_DIR:-"$APP_DIR/cfip_runtime"} VALUE_TEXT_FILE=${VALUE_TEXT_FILE:-"current_ip.txt"} VALUE_JSON_FILE=${VALUE_JSON_FILE:-"current_ip.json"} STATE_FILE=${STATE_FILE:-"state.json"} EXPORT_VARS_FILE=${EXPORT_VARS_FILE:-"substore_vars.json"} HTTP_PORT=${HTTP_PORT:-8080} TEXT_PATH="$RUNTIME_DIR/$VALUE_TEXT_FILE" JSON_PATH="$RUNTIME_DIR/$VALUE_JSON_FILE" STATE_PATH="$RUNTIME_DIR/$STATE_FILE" EXPORT_PATH="$RUNTIME_DIR/$EXPORT_VARS_FILE" TMP_BASE=${TMPDIR:-/tmp} nc_listen() { if nc -h 2>&1 | grep -qi 'busybox'; then nc -l -p "$HTTP_PORT" else nc -l "$HTTP_PORT" fi } serve_once() { req_fifo="$TMP_BASE/router_http_req.$$" resp_fifo="$TMP_BASE/router_http_resp.$$" rm -f "$req_fifo" "$resp_fifo" mkfifo "$req_fifo" "$resp_fifo" cat "$resp_fifo" | nc_listen > "$req_fifo" 2>/dev/null & nc_pid=$! sleep 1 if ! kill -0 "$nc_pid" 2>/dev/null; then rm -f "$req_fifo" "$resp_fifo" echo "[router-http] nc listen failed on port $HTTP_PORT" >&2 return 1 fi exec 3<"$req_fifo" exec 4>"$resp_fifo" if ! IFS= read -r request_line <&3; then exec 3<&- exec 4>&- wait "$nc_pid" 2>/dev/null || true rm -f "$req_fifo" "$resp_fifo" return 0 fi while IFS= read -r header_line <&3; do [ "$header_line" = "$(printf '\r')" ] && break [ -z "$header_line" ] && break done request_path=$(printf '%s' "$request_line" | awk '{print $2}') status_line="HTTP/1.1 200 OK\r" content_type="text/plain; charset=utf-8" file_path="$TEXT_PATH" case "$request_path" in /|/current_ip.txt|"/$VALUE_TEXT_FILE") content_type="text/plain; charset=utf-8" file_path="$TEXT_PATH" ;; /current_ip.json|"/$VALUE_JSON_FILE") content_type="application/json; charset=utf-8" file_path="$JSON_PATH" ;; /state.json|"/$STATE_FILE") content_type="application/json; charset=utf-8" file_path="$STATE_PATH" ;; /substore_vars.json|"/$EXPORT_VARS_FILE") content_type="application/json; charset=utf-8" file_path="$EXPORT_PATH" ;; *) status_line="HTTP/1.1 404 Not Found\r" file_path="" ;; esac if [ -n "$file_path" ] && [ -f "$file_path" ]; then content_length=$(wc -c < "$file_path" | tr -d ' ') printf '%b\n' "$status_line" >&4 printf 'Content-Type: %s\r\n' "$content_type" >&4 printf 'Content-Length: %s\r\n' "$content_length" >&4 printf 'Connection: close\r\n' >&4 printf '\r\n' >&4 cat "$file_path" >&4 else body='not found' printf '%b\n' "$status_line" >&4 printf 'Content-Type: text/plain; charset=utf-8\r\n' >&4 printf 'Content-Length: %s\r\n' "$(printf '%s' "$body" | wc -c | tr -d ' ')" >&4 printf 'Connection: close\r\n' >&4 printf '\r\n' >&4 printf '%s' "$body" >&4 fi exec 3<&- exec 4>&- wait "$nc_pid" 2>/dev/null || true rm -f "$req_fifo" "$resp_fifo" } echo "[router-http] listening on 0.0.0.0:$HTTP_PORT" while true; do if ! serve_once; then exit 1 fi done