When developing IoT firmware, testing REST API client libraries, or validating webhooks in a local staging environment, backend engineers often need a lightweight HTTP server capable of receiving POST payloads and returning immediate, custom HTTP responses without deploying full web frameworks like Express or Flask.
Netcat (nc) paired with Unix Named Pipes (FIFOs) provides an elegant solution. It allows you to simulate a full HTTP/1.1 server on any specified port number, inspect incoming POST headers and body payloads, and respond with customized status codes, JSON objects, or XML data. In this article, we demonstrate how to set up a bi-directional Netcat HTTP server and send test requests using curl and Python.
Client/Server Setup Quick Cheatsheet
Run the Netcat server on port 9090 and transmit an HTTP POST request from a client terminal:
# 1. Create a temporary named pipe (FIFO)
rm -f /tmp/netcat_pipe && mkfifo /tmp/netcat_pipe
# 2. Start Netcat HTTP server returning an HTTP 200 JSON payload
while true; do
{ printf "HTTP/1.1 200 OK
Content-Type: application/json
Connection: close
{"status":"SUCCESS","code":200}
"; } | nc -l 9090 > /tmp/netcat_pipe
cat /tmp/netcat_pipe
done# Send an HTTP POST request containing JSON data to port 9090
curl -i -X POST http://localhost:9090/v1/telemetry \
-H "Content-Type: application/json" \
-d '{"device_id": "sensor-09", "temperature": 24.8}'
# Expected Response Received by Client:
# HTTP/1.1 200 OK
# Content-Type: application/json
# Connection: close
#
# {"status":"SUCCESS","code":200}Step-by-Step Implementation: Bi-Directional HTTP Server
1. Why Named Pipes (FIFOs) Are Required
A standard Netcat command (nc -l 9090) opens a one-way socket. To receive client request data on stdout while simultaneously piping back an HTTP response on stdin, Unix named pipes (mkfifo) connect the input and output streams of Netcat asynchronously without blocking.
2. Writing a Robust Netcat HTTP Server Script
Create a standalone executable bash script (http_server_netcat.sh) that logs incoming requests and returns custom headers:
#!/usr/bin/env bash
# Production-ready Netcat Mock HTTP Server
PORT=9090
PIPE="/tmp/http_fifo"
# Cleanup existing pipe on exit
trap 'rm -f "${PIPE}"' EXIT
rm -f "${PIPE}"
mkfifo "${PIPE}"
echo "=================================================="
echo " Netcat Mock HTTP Server active on port ${PORT}"
echo "=================================================="
while true; do
# Write custom HTTP 200 OK response header and JSON body to FIFO pipe
cat << 'EOF' > "${PIPE}" &
HTTP/1.1 200 OK
Server: Netcat-Mock-Server/1.0
Content-Type: application/json
Access-Control-Allow-Origin: *
Connection: close
{
"message": "HTTP POST payload processed successfully",
"timestamp": "$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
}
EOF
echo -e "
[$(date '+%Y-%m-%d %H:%M:%S')] Incoming Request:"
nc -l "${PORT}" < "${PIPE}"
doneClient Testing: Python and Shell POST Workflows
Testing with Python requests
Verify your Netcat mock server against a Python HTTP client script:
import requests
import json
url = "http://localhost:9090/api/event"
payload = {
"app": "Lynxbee-Client",
"status": "active",
"metrics": {"cpu": 12.5, "mem_mb": 512}
}
headers = {"Content-Type": "application/json"}
try:
print(f"Sending POST request to {url}...")
response = requests.post(url, data=json.dumps(payload), headers=headers, timeout=5)
print("
--- Server Response ---")
print(f"Status Code: {response.status_code}")
print(f"Headers: {dict(response.headers)}")
print(f"Body: {response.text}")
except Exception as e:
print(f"Request failed: {e}")Troubleshooting & Advanced Netcat Flags
`Address already in use` (`EADDRINUSE`): Occurs if another service is using port 9090. Find and terminate the process using
sudo lsof -i :9090orfuser -k 9090/tcp.OpenBSD vs Nmap `ncat` Variant: On Fedora/RedHat or systems with Nmap installed,
ncatsupports multi-client handling natively:ncat -l 9090 --keep-open --exec "/bin/cat response.http".Port Binding Permissions: Remember that binding to ports below 1024 (e.g. port 80 or 443) requires
sudoprivileges on Linux.
Comments and corrections