我一直在寻找使用nc作为Docker容器的单行的最小REST Web服务器。例如:
* http://localhost/echo/marcello: prints marcello
* http://localhost/date: prints the server's date
* http://localhost/...: others
我正在查看问题" Minimal web server using netcat",但它代理了对shell脚本的调用...我只需要一个像这样的衬里
while true ; do nc -l -p 1500 -c 'echo -e "HTTP/1.1 200 OK\n\n $(date)"'; done
发布的其他解决方案很长并且从文件加载......
答案 0 :(得分:11)
我攻击了@syme在" https://stackoverflow.com/a/24342101/433814"并创建了单行REST服务器。缺少某些标头,但它正确处理HTTP GET和404未实现的资源。
rm -f out ; mkfifo out ; trap "rm -f out" EXIT ; while true ; do cat out | nc -l 1500 > >(export REQUEST= ; while read line ; do line=$(echo "$line" | tr -d '[\r\n]') ; if echo "$line" | grep -qE '^GET /' ; then REQUEST=$(echo "$line" | cut -d ' ' -f2) ; elif [ "x$line" = x ] ; then HTTP_200="HTTP/1.1 200 OK" ; HTTP_LOCATION="Location:" ; HTTP_404="HTTP/1.1 404 Not Found" ; if echo $REQUEST | grep -qE '^/echo/' ; then printf "%s\n%s %s\n\n%s\n" "$HTTP_200" "$HTTP_LOCATION" $REQUEST ${REQUEST#"/echo/"} > out ; elif echo $REQUEST | grep -qE '^/date' ; then date > out ; elif echo $REQUEST | grep -qE '^/stats' ; then vmstat -S M > out ; elif echo $REQUEST | grep -qE '^/net' ; then ifconfig > out ; else printf "%s\n%s %s\n\n%s\n" "$HTTP_404" "$HTTP_LOCATION" $REQUEST "Resource $REQUEST NOT FOUND!" > out ; fi ; fi ; done) ; done
格式化版本位于https://gist.github.com/marcellodesales/9e4288f35ac2cc3e1b83#file-formatted
上面的API实现了以下内容:
返回给定的{name}
$ curl -i http://localhost:1500/echo/marcello
HTTP/1.1 200 OK
Location: /echo/marcello
marcello
返回服务器的日期
$ curl -i http://localhost:1500/date
Sun Oct 19 14:12:27 PDT 2014
返回服务器的统计信息
$ curl -i http://localhost:1500/stats
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
0 0 11 374 383 2198 0 0 6 22 33 8 2 2 97 0 0
打印服务器的网络
$ curl -i http://localhost:1500/net
docker0 Link encap:Ethernet HWaddr 56:84:7a:fe:97:99
inet addr:172.17.42.1 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::5484:7aff:fefe:9799/64 Scope:Link
UP BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:120694 errors:0 dropped:0 overruns:0 frame:0
TX packets:141757 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:272911625 (272.9 MB) TX bytes:289945068 (289.9 MB)
eth0 Link encap:Ethernet HWaddr 00:0c:29:1f:d3:b5
inet addr:192.168.248.206 Bcast:192.168.248.255 Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe1f:d3b5/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:2322493 errors:0 dropped:0 overruns:0 frame:0
TX packets:1098965 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:2367412677 (2.3 GB) TX bytes:700548644 (700.5 MB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:151566 errors:0 dropped:0 overruns:0 frame:0
TX packets:151566 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:305833574 (305.8 MB) TX bytes:305833574 (305.8 MB)
对于服务器未实现的任何内容,它会打印404消息。
$ curl -i http://localhost:1500/wrong
HTTP/1.1 404 Not Found
Location: /wrong
Resource /wrong NOT FOUND!
这是来自上述GIST的格式化解决方案。您可以将其另存为" web.sh"并运行:)
rm -f out
mkfifo out
trap "rm -f out" EXIT
while true
do
cat out | nc -l 1500 > >( # parse the netcat output, to build the answer redirected to the pipe "out".
export REQUEST=
while read line
do
line=$(echo "$line" | tr -d '[\r\n]')
if echo "$line" | grep -qE '^GET /' # if line starts with "GET /"
then
REQUEST=$(echo "$line" | cut -d ' ' -f2) # extract the request
elif [ "x$line" = x ] # empty line / end of request
then
HTTP_200="HTTP/1.1 200 OK"
HTTP_LOCATION="Location:"
HTTP_404="HTTP/1.1 404 Not Found"
# call a script here
# Note: REQUEST is exported, so the script can parse it (to answer 200/403/404 status code + content)
if echo $REQUEST | grep -qE '^/echo/'
then
printf "%s\n%s %s\n\n%s\n" "$HTTP_200" "$HTTP_LOCATION" $REQUEST ${REQUEST#"/echo/"} > out
elif echo $REQUEST | grep -qE '^/date'
then
date > out
elif echo $REQUEST | grep -qE '^/stats'
then
vmstat -S M > out
elif echo $REQUEST | grep -qE '^/net'
then
ifconfig > out
else
printf "%s\n%s %s\n\n%s\n" "$HTTP_404" "$HTTP_LOCATION" $REQUEST "Resource $REQUEST NOT FOUND!" > out
fi
fi
done
)
done
答案 1 :(得分:0)
Bash with NetCat的另一个完整而简单的解决方案如下。它支持内容类型,文件大小等等。最新版本可在https://github.com/jdoleczek/Bash-NetCat-HTTPD/blob/master/httpd.sh
找到#!/bin/bash
# LICENSE MIT
PORT=${1:-8080}
FILES=${2:-"./"}
NS=$(netstat -taupen 2>/dev/null | grep ":$PORT ")
test -n "$NS" && echo "Port $PORT is already taken" && exit 1
echo -e "\n\tHTTPD started for files in $FILES:"
for IP in $(ifconfig | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1) ; do
echo -e "\tlistening at $IP:$PORT"
done
echo -e "\n"
FIFO="/tmp/httpd$PORT"
rm -f $FIFO
mkfifo $FIFO
trap ctrl_c INT
function ctrl_c() {
rm -f $FIFO && echo -e "\n\tServer shut down.\n" && exit
}
while true; do (
read req < $FIFO;
req=$(echo $req | cut -d" " -f2 | cut -d"#" -f1 | cut -d"?" -f1 | cut -c2-);
>&2 echo -e -n "\tRequest: \"$req\"\t";
test -z "$req" && req="index.html"
if [ -f "$FILES$req" ] ; then
ext="${req##*.}"
ext=$(echo "$ext" | tr '[:upper:]' '[:lower:]')
case "$ext" in
"html" | "htm") CONTENTTYPE="text/html; charset=UTF-8" ;;
"json") CONTENTTYPE="application/json; charset=UTF-8" ;;
"css" | "less" | "sass") CONTENTTYPE="text/css" ;;
"txt") CONTENTTYPE="text/plain" ;;
"xml") CONTENTTYPE="text/xml" ;;
"js") CONTENTTYPE="application/javascript" ;;
"jpg" | "jpeg") CONTENTTYPE="image/jpeg" ;;
"png") CONTENTTYPE="image/png" ;;
"gif") CONTENTTYPE="image/gif" ;;
"ico") CONTENTTYPE="image/x-icon" ;;
"wav") CONTENTTYPE="audio/wav" ;;
"mp3") CONTENTTYPE="audio/mpeg3" ;;
"avi") CONTENTTYPE="video/avi" ;;
"mp4" | "mpg" | "mpeg" | "mpe") CONTENTTYPE="video/mpeg" ;;
*) CONTENTTYPE="application/octet-stream"
esac
echo "HTTP/1.x 200 OK"
echo "Date: $(LC_TIME=en_US date -u)"
echo "Server: promyk.doleczek.pl"
echo "Connection: close"
echo "Pragma: public"
echo "Content-Type: $CONTENTTYPE"
FILESIZE=$(wc -c < "$FILES$req")
echo -e "Content-Length: $FILESIZE\n"
cat "$FILES$req"
>&2 echo "[ ok ]"
else
echo -e "HTTP/1.x 404 Not found\n\n<h1>File not found.</h1>"
>&2 echo "[ no file ]"
fi
) | nc -l -k -w 1 -p $PORT > $FIFO; done;