netcat (nc)을 사용하여 최소 웹 서버를 설정하려고합니다. 예를 들어 브라우저가 localhost : 1500을 호출 할 때 함수의 결과를 표시해야합니다 ( 아래 예에서는 날짜 이지만 결국 일부 데이터를 생성하는 파이썬 또는 c 프로그램이됩니다). 내 작은 netcat 웹 서버는 bash에서 while true 루프 여야합니다. 아마도 다음과 같이 간단합니다.
while true ; do echo -e "HTTP/1.1 200 OK\n\n $(date)" | nc -l -p 1500 ; done
이것을 시도하면 브라우저는 nc가 시작되는 순간 현재 사용 가능한 데이터를 보여줍니다. 그래도 브라우저가 요청하는 동안 브라우저가 데이터를 표시하고 싶습니다. 이것을 어떻게 할 수 있습니까?
답변
이 시도:
while true ; do nc -l -p 1500 -c 'echo -e "HTTP/1.1 200 OK\n\n $(date)"'; done
-c
당신이 에코 사용할 수 있도록 만든다은 쉘에 주어진 명령을 실행 netcat을. 에코가 필요하지 않으면 -e
. 이에 대한 자세한 내용을 보려면를 시도하십시오 man nc
. 를 사용할 때 echo
프로그램 ( date
대체)이 브라우저 요청을받을 수있는 방법이 없습니다 . 따라서 마침내 다음과 같이하고 싶을 것입니다.
while true ; do nc -l -p 1500 -e /path/to/yourprogram ; done
yourprogram
GET 처리, HTTP 200 전송 등과 같은 프로토콜 작업은 어디에서 해야합니까?
답변
방법 또는 이유가 없지만 주변에서 이것을 찾을 수 있고 나를 위해 작동합니다. bash 실행 결과를 반환하고 싶었던 문제가있었습니다.
$ while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; sh test; } | nc -l 8080; done
참고 : 이 명령은 http://www.razvantudorica.com/08/web-server-in-one-line-of-bash 에서 가져 왔습니다.
이것은 bash 스크립트 테스트를 실행하고 포트 8080에서이 명령을 실행하는 서버에 연결하는 브라우저 클라이언트에 결과를 반환합니다.
내 스크립트는이 ATM을 수행합니다.
$ nano test
#!/bin/bash
echo "************PRINT SOME TEXT***************\n"
echo "Hello World!!!"
echo "\n"
echo "Resources:"
vmstat -S M
echo "\n"
echo "Addresses:"
echo "$(ifconfig)"
echo "\n"
echo "$(gpio readall)"
내 웹 브라우저에
************PRINT SOME TEXT***************
Hello World!!!
Resources:
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
0 0 0 314 18 78 0 0 2 1 306 31 0 0 100 0
Addresses:
eth0 Link encap:Ethernet HWaddr b8:27:eb:86:e8:c5
inet addr:192.168.1.83 Bcast:192.168.1.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:27734 errors:0 dropped:0 overruns:0 frame:0
TX packets:26393 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1924720 (1.8 MiB) TX bytes:3841998 (3.6 MiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
GPIOs:
+----------+-Rev2-+------+--------+------+-------+
| wiringPi | GPIO | Phys | Name | Mode | Value |
+----------+------+------+--------+------+-------+
| 0 | 17 | 11 | GPIO 0 | IN | Low |
| 1 | 18 | 12 | GPIO 1 | IN | Low |
| 2 | 27 | 13 | GPIO 2 | IN | Low |
| 3 | 22 | 15 | GPIO 3 | IN | Low |
| 4 | 23 | 16 | GPIO 4 | IN | Low |
| 5 | 24 | 18 | GPIO 5 | IN | Low |
| 6 | 25 | 22 | GPIO 6 | IN | Low |
| 7 | 4 | 7 | GPIO 7 | IN | Low |
| 8 | 2 | 3 | SDA | IN | High |
| 9 | 3 | 5 | SCL | IN | High |
| 10 | 8 | 24 | CE0 | IN | Low |
| 11 | 7 | 26 | CE1 | IN | Low |
| 12 | 10 | 19 | MOSI | IN | Low |
| 13 | 9 | 21 | MISO | IN | Low |
| 14 | 11 | 23 | SCLK | IN | Low |
| 15 | 14 | 8 | TxD | ALT0 | High |
| 16 | 15 | 10 | RxD | ALT0 | High |
| 17 | 28 | 3 | GPIO 8 | ALT2 | Low |
| 18 | 29 | 4 | GPIO 9 | ALT2 | Low |
| 19 | 30 | 5 | GPIO10 | ALT2 | Low |
| 20 | 31 | 6 | GPIO11 | ALT2 | Low |
+----------+------+------+--------+------+-------+
단순히 놀랍습니다!
답변
추가 -q 1
받는 netcat
명령 행 :
while true; do
echo -e "HTTP/1.1 200 OK\n\n $(date)" | nc -l -p 1500 -q 1
done
답변
당신이 직면 한 문제는 nc가 웹 클라이언트가 요청에 응답 할 수 있도록 웹 클라이언트가 언제 완료되었는지 알지 못한다는 것입니다.
웹 세션은 다음과 같이 진행되어야합니다.
TCP session is established.
Browser Request Header: GET / HTTP/1.1
Browser Request Header: Host: www.google.com
Browser Request Header: \n #Note: Browser is telling Webserver that the request header is complete.
Server Response Header: HTTP/1.1 200 OK
Server Response Header: Content-Type: text/html
Server Response Header: Content-Length: 24
Server Response Header: \n #Note: Webserver is telling browser that response header is complete
Server Message Body: <html>sample html</html>
Server Message Body: \n #Note: Webserver is telling the browser that the requested resource is finished.
The server closes the TCP session.
“\ n”으로 시작하는 줄은 공백없이 단순히 빈 줄이며 줄 바꿈 문자 만 포함합니다.
xinetd, xinetd tutorial에 의해 시작된 bash httpd가 있습니다 . 또한 날짜, 시간, 브라우저 IP 주소 및 전체 브라우저 요청을 로그 파일에 기록하고 서버 헤더 응답에 대한 콘텐츠 길이를 계산합니다.
user@machine:/usr/local/bin# cat ./bash_httpd
#!/bin/bash
x=0;
Log=$( echo -n "["$(date "+%F %T %Z")"] $REMOTE_HOST ")$(
while read I[$x] && [ ${#I[$x]} -gt 1 ];do
echo -n '"'${I[$x]} | sed -e's,.$,",'; let "x = $x + 1";
done ;
); echo $Log >> /var/log/bash_httpd
Message_Body=$(echo -en '<html>Sample html</html>')
echo -en "HTTP/1.0 200 OK\nContent-Type: text/html\nContent-Length: ${#Message_Body}\n\n$Message_Body"
더 많은 기능을 추가하려면 통합 할 수 있습니다.
METHOD=$(echo ${I[0]} |cut -d" " -f1)
REQUEST=$(echo ${I[0]} |cut -d" " -f2)
HTTP_VERSION=$(echo ${I[0]} |cut -d" " -f3)
If METHOD = "GET" ]; then
case "$REQUEST" in
"/") Message_Body="HTML formatted home page stuff"
;;
/who) Message_Body="HTML formatted results of who"
;;
/ps) Message_Body="HTML formatted results of ps"
;;
*) Message_Body= "Error Page not found header and content"
;;
esac
fi
해피 배싱!
답변
나는 똑같은 필요 / 문제가 있었지만 여기서는 나를 위해 일하지 않았거나 (또는 모든 것을 이해하지 못했습니다) 이것이 내 해결책입니다.
내 minimal_http_server.sh를 게시합니다 (내 / bin / bash (4.3.11)와 함께 작동하지만 리디렉션으로 인해 / bin / 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 -r 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 [ -z "$line" ] # empty line / end of request
then
# call a script here
# Note: REQUEST is exported, so the script can parse it (to answer 200/403/404 status code + content)
./a_script.sh > out
fi
done
)
done
그리고 내 a_script.sh (필요에 따라) :
#!/bin/bash
echo -e "HTTP/1.1 200 OK\r"
echo "Content-type: text/html"
echo
date
답변
이를 수행하는 또 다른 방법
while true; do (echo -e 'HTTP/1.1 200 OK\r\n'; echo -e "\n\tMy website has date function" ; echo -e "\t$(date)\n") | nc -lp 8080; done
curl을 사용하여 2 개의 HTTP 요청으로 테스트 해 보겠습니다.
이 예에서 172.16.2.6은 서버 IP 주소입니다.
서버 측
admin@server:~$ while true; do (echo -e 'HTTP/1.1 200 OK\r\n'; echo -e "\n\tMy website has date function" ; echo -e "\t$(date)\n") | nc -lp 8080; done
GET / HTTP/1.1 Host: 172.16.2.6:8080 User-Agent: curl/7.48.0 Accept:
*/*
GET / HTTP/1.1 Host: 172.16.2.6:8080 User-Agent: curl/7.48.0 Accept:
*/*
고객 입장에서
user@client:~$ curl 172.16.2.6:8080
My website has date function
Tue Jun 13 18:00:19 UTC 2017
user@client:~$ curl 172.16.2.6:8080
My website has date function
Tue Jun 13 18:00:24 UTC 2017
user@client:~$
다른 명령을 실행하려면 $ (date)를 자유롭게 바꾸십시오.
답변
mkfifo pipe;
while true ;
do
#use read line from pipe to make it blocks before request comes in,
#this is the key.
{ read line<pipe;echo -e "HTTP/1.1 200 OK\r\n";echo $(date);
} | nc -l -q 0 -p 8080 > pipe;
done