In this article, I will go through how to spin up a stub/mock server and proxy server using netcat.
Stub Server
If you are working on any client application and if the service you want to consume is not yet ready, then you can spin up a mock/stub server using netcat.
For example, if you want to mock a service /api/companies
store response like below in companies.txt
.
HTTP/1.0 200 OK
Content-Type: application/json
[{"id": 1, "name": "Company One"}, {"id": 2, "name": "Company Two"}]
Protip: You can separate response headers and response body into two files.
For example, inside success_head.txt (a new line at the end is required, it separates headers from the body)
HTTP/1.1 200 OK
Content-type: application/json
Now you can start netcat like below
cat /tmp/companies.txt | nc -l 5000
# OR if you seperated headers and json
cat success_head.txt companies.json | nc -l 5000
If you send a request like the one below.
curl localhost:5000/api/companies
output -
[{"id": 1, "name": "Company One"}, {"id": 2, "name": "Company Two"}]
After serving the response, nc exits, you can use a loop to keep it permanently running - while true; do cat companies.txt | nc -l 5000; done
To come out of this, Ctrl+c won’t work; you need to use Ctrl+z and kill %1
to kill the job.
The nice thing about this approach is that you can send any path URL and request method and get your response. For example, if you send a curl request as
curl -H 'content-type:application/json' \
localhost:5000/api/companies -d '{"x", "y"}'
In the nc logs, you will see
POST /api/companies HTTP/1.1
Host: localhost:5000
User-Agent: curl/7.64.1
Accept: */*
content-type:application/json
Content-Length: 10
{"x", "y"}
Of course, you can mock any response code with any content you want. For example, if you want to mock 404 not found, you can have something like the one below.
HTTP/1.0 404 Not found
Content-Type: application/json
{"message": "company does not exist"}
If you send a request like the one below, you should get the 404 response code.
curl -v -X PUT localhost:5000/api/companies/3 -d '{"x": "y"}'
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 5000 (#0)
> PUT /api/companies/3 HTTP/1.1
> Host: localhost:5000
> User-Agent: curl/7.64.1
> Accept: */*
> Content-Length: 10
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 10 out of 10 bytes
* HTTP 1.0, assume close after body
< HTTP/1.0 404 Not found
< Content-Type: application/json
<
{"message": "company does not exist"}
Let’s say you want to test your socket timeouts; you can do nc -l 5000
(you can use any port),
now you can send a request, and it waits for the response until you send some response in nc -l 5000
prompt.
Proxy Server
You can also spin up a proxy using nc.
First, create tcpproxy.sh
file with the below content
#!/bin/sh -e
if [ $# != 3 ]
then
echo "usage: $0 <src-port> <dst-host> <dst-port>"
exit 0
fi
while true
do
echo "Press [CTRL+C] to stop.."
TMP=`mktemp -d`
BACK=$TMP/pipe.back
SENT=$TMP/pipe.sent
RCVD=$TMP/pipe.rcvd
trap 'rm -rf "$TMP"' EXIT
mkfifo -m 0600 "$BACK" "$SENT" "$RCVD"
sed 's/^/ => /' <"$SENT" &
sed 's/^/<= /' <"$RCVD" &
nc -l "$1" <"$BACK" | tee "$SENT" | nc "$2" "$3" | tee "$RCVD" >"$BACK"
done
Give permissions chmod 755 tcpproxy.sh
Now start the proxy
tcpproxy.sh 8812 localhost 5000
Now in the other terminal, start the stub server like below
cat companies.txt | nc -l 5000
Now at the client, make a call using http_proxy
http_proxy=localhost:8812 curl -v localhost:5000/api/companies
You should see this in tcpproxy.sh
prompt when you send a request.
=> GET http://localhost:5000/api/companies HTTP/1.1
=> Host: localhost:5000
=> User-Agent: curl/7.64.1
=> Accept: */*
=> Proxy-Connection: Keep-Alive
=>
<= HTTP/1.0 200 OK
<= Content-Type: application/json
<=
<= [{"id": 1, "name": "Company One"}, {"id": 2, "name": "Company Two"}]
Note that you can only capture HTTP traffic with the above approach.
Netcat is a fantastic tool, and above are a few ways to use it to debug HTTP requests. I hope this helps.
– RC
Comments