使用netcat的最小Web服务器

我正在尝试使用netcat(nc)设置一个最小的Web服务器。 例如,当浏览器调用localhost:1500时,它应该显示一个函数的结果(在下面的例子中是date ,但最终会是一个产生一些数据的python或c程序)。 我的小型netcat web服务器需要在bash中成为一个真正的循环,可能就像这样简单:

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在shell中执行给定的命令,所以你可以使用echo。 如果您不需要回显,请使用-e 。 有关更多信息,请尝试man nc 。 请注意,使用echo时,您的程序( datereplace)无法获取浏览器请求。 所以你可能最终想要做这样的事情:

 while true ; do nc -l -p 1500 -e /path/to/yourprogram ; done 

在你的程序必须执行协议的东西,如处理GET,发送HTTP 200等

你面对的问题是,NC不知道什么时候Web客户端完成其请求,以便它可以响应请求。
networking会话应该是这样的。

 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”开头的行只是空行,没有空格,只包含新行字符。

我有我的bash httpd由xinetd, xinetd教程启动 。 它还将date,时间,浏览器IP地址和整个浏览器请求logging到日志文件,并计算服务器标题响应的内容长度。

 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" 

要添加更多function,您可以合并。

  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 

快乐扑!

不知道如何或为什么,但我设法find这一点,它适用于我,我有问题,我想返回执行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脚本testing并将结果返回给连接到在端口8080上运行此命令的服务器的浏览器客户端

我的脚本做这个ATM

 $ nano test #!/bin/bash echo "************PRINT SOME TEXT***************\n" echo "Hello World!!!" echo "\n" echo "Resources:" vmstat -SM echo "\n" echo "Addresses:" echo "$(ifconfig)" echo "\n" echo "$(gpio readall)" 

和我的网页浏览器正在显示

 ************PRINT SOME TEXT*************** Hello World!!! Resources: procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu---- rb 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 

我有同样的需求/问题,但这里没有任何工作为我(或我不明白的一切),所以这是我的解决scheme。

我发布我的minimal_http_server.sh(使用/ bin / bash(4.3.11),但不是/ bin / sh,因为redirect):

 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 
 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 

这是一个小bashnetworking服务器的美丽,我发现它在网上,并分支副本,并将其稍微socat一下 – 它使用socatnetcat我已经与socattesting它 – 它是独立的一个脚本,并生成它的自己的configuration文件和favicon。

默认情况下,它将启动为启用Web的文件浏览器,但可以通过configuration文件轻松configuration任何逻辑。 对于文件,它stream图像和音乐(MP3的),video(MP4,AVI等) – 我已经testing串stream各种文件types到Linux,Windows和Android设备,包括智能手表!

我认为它实际上比VLC更好。 我发现将文件传输到无法通过Web浏览器访问的远程客户端(例如Android智能手表),而无需担心物理连接到USB端口。

如果你想尝试一下,把它复制并粘贴到一个名为bashttpd的文件中,然后在主机上用$> bashttpd -s启动它

然后,你可以去任何其他的计算机(假设防火墙不阻止端口8080的入站TCP连接 – 默认端口,您可以使用脚本顶部的全局variables将端口更改为任何你想要的)。 http://bashttpd_server_ip:8080

 #!/usr/bin/env bash ############################################################################# ########################################################################### ### bashttpd v 1.12 ### ### Original author: Avleen Vig, 2012 ### Reworked by: Josh Cartwright, 2012 ### Modified by: AMDanischewski, 2015 ### Issues: If you find any issues leave me a comment at ### http://scriptsandoneliners.blogspot.com/2015/04/bashttpd-self-contained-bash-webserver.html ### ### This is a simple Bash based webserver. By default it will browse files and allows for ### retrieving binary files. ### ### It has been tested successfully to view and stream files including images, mp3s, ### mp4s and downloading files of any type including binary and compressed files via ### any web browser. ### ### Successfully tested on various browsers on Windows, Linux and Android devices (including the ### Android Smartwatch ZGPAX S8). ### ### It handles favicon requests by hardcoded favicon image -- by default a marathon ### runner; change it to whatever you want! By base64 encoding your favorit favicon ### and changing the global variable below this header. ### ### Make sure if you have a firewall it allows connections to the port you plan to ### listen on (8080 by default). ### ### By default this program will allow for the browsing of files from the ### computer where it is run. ### ### Make sure you are allowed connections to the port you plan to listen on ### (8080 by default). Then just drop it on a host machine (that has bash) ### and start it up like this: ### ### $192.168.1.101> bashttpd -s ### ### On the remote machine you should be able to browse and download files from the host ### server via any web browser by visiting: ### ### http://192.168.1.101:8080 ### #### This program requires (to work to full capacity) by default: ### socat or netcat (w/ '-e' option - on Ubuntu netcat-traditional) ### tree - useful for pretty directory listings ### If you are using socat, you can type: bashttpd -s ### ### to start listening on the LISTEN_PORT (default is 8080), you can change ### the port below. ### Eg nc -lp 8080 -e ./bashttpd ## <-- If your nc has the -e option. ### Eg nc.traditional -lp 8080 -e ./bashttpd ### Eg bashttpd -s -or- socat TCP4-LISTEN:8080,fork EXEC:bashttpd ### ### Copyright (C) 2012, Avleen Vig <avleen@gmail.com> ### ### Permission is hereby granted, free of charge, to any person obtaining a copy of ### this software and associated documentation files (the "Software"), to deal in ### the Software without restriction, including without limitation the rights to ### use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of ### the Software, and to permit persons to whom the Software is furnished to do so, ### subject to the following conditions: ### ### The above copyright notice and this permission notice shall be included in all ### copies or substantial portions of the Software. ### ### THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ### IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS ### FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR ### COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER ### IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ### CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ### ########################################################################### ############################################################################# ### CHANGE THIS TO WHERE YOU WANT THE CONFIGURATION FILE TO RESIDE declare -r BASHTTPD_CONF="/tmp/bashttpd.conf" ### CHANGE THIS IF YOU WOULD LIKE TO LISTEN ON A DIFFERENT PORT declare -i LISTEN_PORT=8080 ## If you are on AIX, IRIX, Solaris, or a hardened system redirecting ## to /dev/random will probably break, you can change it to /dev/null. declare -a DUMP_DEV="/dev/random" ## Just base64 encode your favorite favicon and change this to whatever you want. declare -r FAVICON="AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAADg4+3/srjc/5KV2P+ortn/xMrj/6Ch1P+Vl9f/jIzc/3572f+CgNr/fnzP/3l01f+Ih9r/h4TZ/8fN4//P1Oj/3uPr/7O+1v+xu9X/u8XY/9bi6v+UmdD/XV26/3F1x/+GitT/VVXC/3x/x/+HjNT/lp3Z/6633f/E0eD/2ePr/+bt8v/U4+v/0uLp/9Xj6//Z5e3/oKbX/0pJt/9maML/cHLF/3p8x//T3+n/3Ofu/9vo7//W5Oz/0uHq/9zn7f/j6vD/1OLs/8/f6P/R4Oj/1OPr/7jA4f9KSbf/Skm3/3p/yf/U4ez/1ePq/9rn7//Z5e3/0uHp/87e5//a5Ov/5Ovw/9Hf6v/T4uv/1OLp/9bj6/+kq9r/Skq3/0pJt/+cotb/zdnp/9jl7f/a5u//1+Ts/9Pi6v/O3ub/2uXr/+bt8P/Q3un/0eDq/9bj7P/Z5u7/r7jd/0tKt/9NTLf/S0u2/8zW6v/c5+//2+fv/9bj6//S4un/zt3m/9zm7P/k7PD/1OPr/9Li7P/V5Oz/2OXt/9jl7v+HjM3/lZvT/0tKt/+6w+L/2ebu/9fk7P/V4+v/0uHq/83d5v/a5ev/5ezw/9Pi6v/U4+z/1eXs/9bj6//b5+//vsjj/1hYvP9JSLb/horM/9nk7P/X5e3/1eTs/9Pi6v/P3uf/2eXr/+Tr7//O3+n/0uLr/9Xk7P/Y5e3/w8/k/7XA3/9JR7f/SEe3/2lrw//G0OX/1uLr/9Xi7P/T4ev/0N/o/9zn7f/k7PD/zN3p/8rd5v/T4ur/1ePt/5We0/+0w9//SEe3/0pKt/9OTrf/p7HZ/7fD3//T4uv/0N/o/9Hg6f/d5+3/5ezw/9Li6//T4uv/2ubu/8PQ5f9+hsr/ucff/4eOzv+Ei8z/rLja/8zc6P/I1+b/0OLq/8/f6P/Q4Oj/3eft/+bs8f/R4On/0+Lq/9Tj6v/T4Ov/wM7h/9Df6f/M2uf/z97q/9Dg6f/Q4On/1OPr/9Tj6//S4ur/0ODp/93o7f/n7vH/0N/o/8/f5//P3+b/2OXt/9zo8P/c6fH/zdjn/7fB3/+3weD/1eLs/9nn7//V5Oz/0+Lr/9Pi6//e6O7/5u3x/9Pi6v/S4en/0uLp/9Tj6//W4+v/3Ojw/9rm7v9vccT/wcvm/9rn7//X5Oz/0uHq/9Hg6f/S4er/3uju/+bt8f/R4On/0uHp/9Xk6//Y5u7/1OTs/9bk7P/W5Ov/XFy9/2lrwf/a5+//1uPr/9Pi6v/U4er/0eHq/93o7v/v8vT/5ezw/+bt8f/o7vL/6e/z/+jv8v/p7/L/6e/y/9XZ6//IzOX/6e7y/+nv8v/o7vL/5+7x/+ft8f/r8PP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==" declare -i DEBUG=1 declare -i VERBOSE=0 declare -a REQUEST_HEADERS declare REQUEST_URI="" declare -a HTTP_RESPONSE=( [200]="OK" [400]="Bad Request" [403]="Forbidden" [404]="Not Found" [405]="Method Not Allowed" [500]="Internal Server Error") declare DATE=$(date +"%a, %d %b %Y %H:%M:%S %Z") declare -a RESPONSE_HEADERS=( "Date: $DATE" "Expires: $DATE" "Server: Slash Bin Slash Bash" ) function warn() { ((${VERBOSE})) && echo "WARNING: $@" >&2; } function chk_conf_file() { [ -r "${BASHTTPD_CONF}" ] || { cat >"${BASHTTPD_CONF}" <<'EOF' # # bashttpd.conf - configuration for bashttpd # # The behavior of bashttpd is dictated by the evaluation # of rules specified in this configuration file. Each rule # is evaluated until one is matched. If no rule is matched, # bashttpd will serve a 500 Internal Server Error. # # The format of the rules are: # on_uri_match REGEX command [args] # unconditionally command [args] # # on_uri_match: # On an incoming request, the URI is checked against the specified # (bash-supported extended) regular expression, and if encounters a match the # specified command is executed with the specified arguments. # # For additional flexibility, on_uri_match will also pass the results of the # regular expression match, ${BASH_REMATCH[@]} as additional arguments to the # command. # # unconditionally: # Always serve via the specified command. Useful for catchall rules. # # The following commands are available for use: # # serve_file FILE # Statically serves a single file. # # serve_dir_with_tree DIRECTORY # Statically serves the specified directory using 'tree'. It must be # installed and in the PATH. # # serve_dir_with_ls DIRECTORY # Statically serves the specified directory using 'ls -al'. # # serve_dir DIRECTORY # Statically serves a single directory listing. Will use 'tree' if it is # installed and in the PATH, otherwise, 'ls -al' # # serve_dir_or_file_from DIRECTORY # Serves either a directory listing (using serve_dir) or a file (using # serve_file). Constructs local path by appending the specified root # directory, and the URI portion of the client request. # # serve_static_string STRING # Serves the specified static string with Content-Type text/plain. # # Examples of rules: # # on_uri_match '^/issue$' serve_file "/etc/issue" # # When a client's requested URI matches the string '/issue', serve them the # contents of /etc/issue # # on_uri_match 'root' serve_dir / # # When a client's requested URI has the word 'root' in it, serve up # a directory listing of / # # DOCROOT=/var/www/html # on_uri_match '/(.*)' serve_dir_or_file_from "$DOCROOT" # When any URI request is made, attempt to serve a directory listing # or file content based on the request URI, by mapping URI's to local # paths relative to the specified "$DOCROOT" # #unconditionally serve_static_string 'Hello, world! You can configure bashttpd by modifying bashttpd.conf.' DOCROOT=/ on_uri_match '/(.*)' serve_dir_or_file_from # More about commands: # # It is possible to somewhat easily write your own commands. An example # may help. The following example will serve "Hello, $x!" whenever # a client sends a request with the URI /say_hello_to/$x: # # serve_hello() { # add_response_header "Content-Type" "text/plain" # send_response_ok_exit <<< "Hello, $2!" # } # on_uri_match '^/say_hello_to/(.*)$' serve_hello # # Like mentioned before, the contents of ${BASH_REMATCH[@]} are passed # to your command, so its possible to use regular expression groups # to pull out info. # # With this example, when the requested URI is /say_hello_to/Josh, serve_hello # is invoked with the arguments '/say_hello_to/Josh' 'Josh', # (${BASH_REMATCH[0]} is always the full match) EOF warn "Created bashttpd.conf using defaults. Please review and configure bashttpd.conf before running bashttpd again." # exit 1 } } function recv() { ((${VERBOSE})) && echo "< $@" >&2; } function send() { ((${VERBOSE})) && echo "> $@" >&2; echo "$*"; } function add_response_header() { RESPONSE_HEADERS+=("$1: $2"); } function send_response_binary() { local code="$1" local file="${2}" local transfer_stats="" local tmp_stat_file="/tmp/_send_response_$$_" send "HTTP/1.0 $1 ${HTTP_RESPONSE[$1]}" for i in "${RESPONSE_HEADERS[@]}"; do send "$i" done send if ((${VERBOSE})); then ## Use dd since it handles null bytes dd 2>"${tmp_stat_file}" < "${file}" transfer_stats=$(<"${tmp_stat_file}") echo -en ">> Transferred: ${file}\n>> $(awk '/copied/{print}' <<< "${transfer_stats}")\n" >&2 rm "${tmp_stat_file}" else ## Use dd since it handles null bytes dd 2>"${DUMP_DEV}" < "${file}" fi } function send_response() { local code="$1" send "HTTP/1.0 $1 ${HTTP_RESPONSE[$1]}" for i in "${RESPONSE_HEADERS[@]}"; do send "$i" done send while IFS= read -r line; do send "${line}" done } function send_response_ok_exit() { send_response 200; exit 0; } function send_response_ok_exit_binary() { send_response_binary 200 "${1}"; exit 0; } function fail_with() { send_response "$1" <<< "$1 ${HTTP_RESPONSE[$1]}"; exit 1; } function serve_file() { local file="$1" local CONTENT_TYPE="" case "${file}" in *\.css) CONTENT_TYPE="text/css" ;; *\.js) CONTENT_TYPE="text/javascript" ;; *) CONTENT_TYPE=$(file -b --mime-type "${file}") ;; esac add_response_header "Content-Type" "${CONTENT_TYPE}" CONTENT_LENGTH=$(stat -c'%s' "${file}") add_response_header "Content-Length" "${CONTENT_LENGTH}" ## Use binary safe transfer method since text doesn't break. send_response_ok_exit_binary "${file}" } function serve_dir_with_tree() { local dir="$1" tree_vers tree_opts basehref x ## HTML 5 compatible way to avoid tree html from generating favicon ## requests in certain browsers, such as browsers in android smartwatches. =) local no_favicon=" <link href=\"data:image/x-icon;base64,${FAVICON}\" rel=\"icon\" type=\"image/x-icon\" />" local tree_page="" local base_server_path="/${2%/}" [ "$base_server_path" = "/" ] && base_server_path=".." local tree_opts="--du -h -a --dirsfirst" add_response_header "Content-Type" "text/html" # The --du option was added in 1.6.0. "/${2%/*}" read _ tree_vers x < <(tree --version) tree_page=$(tree -H "$base_server_path" -L 1 "${tree_opts}" -D "${dir}") tree_page=$(sed "5 i ${no_favicon}" <<< "${tree_page}") [[ "${tree_vers}" == v1.6* ]] send_response_ok_exit <<< "${tree_page}" } function serve_dir_with_ls() { local dir="$1" add_response_header "Content-Type" "text/plain" send_response_ok_exit < \ <(ls -la "${dir}") } function serve_dir() { local dir="$1" # If `tree` is installed, use that for pretty output. which tree &>"${DUMP_DEV}" && \ serve_dir_with_tree "$@" serve_dir_with_ls "$@" fail_with 500 } function urldecode() { [ "${1%/}" = "" ] && echo "/" || echo -e "$(sed 's/%\([[:xdigit:]]\{2\}\)/\\\x\1/g' <<< "${1%/}")"; } function serve_dir_or_file_from() { local URL_PATH="${1}/${3}" shift URL_PATH=$(urldecode "${URL_PATH}") [[ $URL_PATH == *..* ]] && fail_with 400 # Serve index file if exists in requested directory [[ -d "${URL_PATH}" && -f "${URL_PATH}/index.html" && -r "${URL_PATH}/index.html" ]] && \ URL_PATH="${URL_PATH}/index.html" if [[ -f "${URL_PATH}" ]]; then [[ -r "${URL_PATH}" ]] && \ serve_file "${URL_PATH}" "$@" || fail_with 403 elif [[ -d "${URL_PATH}" ]]; then [[ -x "${URL_PATH}" ]] && \ serve_dir "${URL_PATH}" "$@" || fail_with 403 fi fail_with 404 } function serve_static_string() { add_response_header "Content-Type" "text/plain" send_response_ok_exit <<< "$1" } function on_uri_match() { local regex="$1" shift [[ "${REQUEST_URI}" =~ $regex ]] && \ "$@" "${BASH_REMATCH[@]}" } function unconditionally() { "$@" "$REQUEST_URI"; } function main() { local recv="" local line="" local REQUEST_METHOD="" local REQUEST_HTTP_VERSION="" chk_conf_file [[ ${UID} = 0 ]] && warn "It is not recommended to run bashttpd as root." # Request-Line HTTP RFC 2616 $5.1 read -r line || fail_with 400 line=${line%%$'\r'} recv "${line}" read -r REQUEST_METHOD REQUEST_URI REQUEST_HTTP_VERSION <<< "${line}" [ -n "${REQUEST_METHOD}" ] && [ -n "${REQUEST_URI}" ] && \ [ -n "${REQUEST_HTTP_VERSION}" ] || fail_with 400 # Only GET is supported at this time [ "${REQUEST_METHOD}" = "GET" ] || fail_with 405 while IFS= read -r line; do line=${line%%$'\r'} recv "${line}" # If we've reached the end of the headers, break. [ -z "${line}" ] && break REQUEST_HEADERS+=("${line}") done } if [[ ! -z "{$1}" ]] && [ "${1}" = "-s" ]; then socat TCP4-LISTEN:${LISTEN_PORT},fork EXEC:"${0}" else main source "${BASHTTPD_CONF}" fail_with 500 fi 

另一种方法来做到这一点

 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 

让我们用2个使用curl的HTTP请求来testing它

在这个例子中,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)。

大声笑,一个超级蹩脚的黑客,但至lesscurl和Firefox接受它:

 while true ; do (dd if=/dev/zero count=10000;echo -e "HTTP/1.1\n\n $(date)") | nc -l 1500 ; done 

你最好用适当的东西来代替它!

啊,是的,我的nc和你的不一样,它不喜欢-p选项。

inputnc -h ,看看你是否有-e选项。 如果是的话,你可以创build一个脚本,例如:

script.sh

 echo -e "HTTP/1.1 200 OK\n\n $(date)" 

并像这样运行它:

 while true ; do nc -l -p 1500 -e script.sh; done 

请注意, -e选项需要在编译时启用。

我认为列出的所有解决scheme都不起作用的问题在http服务的本质上是固有的,每一个build立的请求都与一个不同的客户端相关,并且响应需要在不同的上下文中处理,每个请求必须分叉回应的实例…

目前的解决scheme,我认为是netcat但我不知道为什么不工作…也许是我的nc版本,我testingopenwrt

socat它的作品….

我试试这个https://github.com/avleen/bashttpd

它的工作原理,但我必须运行这个命令的shell脚本。

 socat tcp-l:80,reuseaddr,fork EXEC:bashttpd & 

github上的socatnetcat样本对我不起作用,但我使用的socat工作。