使用netcat的最小化Web服务器

179

我正在尝试使用netcat(nc)来设置一个最小的web服务器。例如,当浏览器访问localhost:1500时,它应该显示一个函数的结果(在下面的示例中是日期,但最终将是一个生成一些数据的Python或C程序)。

我的小netcat web服务器需要作为bash中的while true循环,可能像这样简单:

while true ; do  echo -e "HTTP/1.1 200 OK\n\n $(date)" | nc -l -p 1500  ; done

当我尝试这样做时,浏览器会在nc启动时显示当前可用的数据。然而,我希望浏览器在请求数据时显示它,该怎么办?


2
谢谢大家的建议,它们引导我进行了更多的搜索。恰巧我在链接上找到了一个完全不同的解决方案。我无法使用python或C,但我已经在所有目标平台上测试过了。 netcat的问题是有很多不同的版本。其中一些不允许使用-e、-c或-q选项。 - andwagon
请注意,nc会在连接建立后立即发送响应,这并不总是在客户端发送HTTP GET请求之前发生。对于像Chrome和Firefox这样的许多客户端来说,这似乎不是一个问题,但对于至少Safari来说,这被视为错误,不会发出任何请求。 - undefined
17个回答

4
实际上,优雅地关闭连接的最佳方法是发送以下内容的 Content-Length 头信息。客户端(例如 curl)在接收到数据后将关闭连接。
DATA="Date: $(date)"; 
LENGTH=$(echo $DATA | wc -c);
echo -e "HTTP/1.1 200 OK\nContent-Length: ${LENGTH}\n\n${DATA}" | nc -l -p 8000;

3
echo $DATA | wc -c的长度并不一定与"$DATA"相同:当你在echo中不使用引号时,通配符会被展开,连续的空格会被改成单个空格等。建议使用length=${#data}代替(遵循POSIX规范约定,使用小写字母的变量名;请阅读该文档时牢记环境变量和常规shell变量共享一个命名空间)。 - Charles Duffy

4
while true; do (echo -e 'HTTP/1.1 200 OK\r\nConnection: close\r\n';) | timeout 1  nc -lp 8080 ; done

在1秒后关闭连接,这样curl就不会挂在上面。


1
我的Bash shell在我尝试这个之后挂起了。Ctrl+Z无法杀死进程。我不得不生成另一个shell实例并删除以前的实例。 - Gerardo Cauich

2
我认为列出的所有解决方案都无法解决问题,这是由于http服务的本质原因。每个请求都与不同的客户端建立连接,响应需要在不同的上下文中处理,每个请求都必须分叉一个新的响应实例...

目前我认为的解决方案是使用netcat-e选项,但我不知道为什么不起作用...也许是我在openwrt上测试的nc版本的问题...

使用socat可以解决这个问题....

我尝试了https://github.com/avleen/bashttpd,它可以工作,但我必须使用这个命令运行shell脚本。

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

在 GitHub 上的 socatnetcat 示例对我来说无法工作,但我使用的 socat 可以工作。

有了 reuseaddr 标志,你让我的一天过得很愉快!谢谢你。 - WBAR

2

输入nc -h,查看是否有可用的-e选项。如果有,您可以创建一个脚本,例如:

script.sh

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

并像这样运行它:

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

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

0

在OSX上,您可以使用:

while true; do echo -e "HTTP/1.1 200 OK\n\n $(date)" | nc -l  localhost 1500 ; done

0
我很晚才参加派对,但我通常喜欢避免在bash中使用while true循环,而ncat有两个方便的标志:
  • -k(或--keep-open
  • -c(或--sh-exec
所以我会用这个一行命令来实现:
ncat -l localhost 1500 -k -c "printf 'HTTP/1.1 200 OK\n\n%s\n' '$(date)'"

请注意您的ncat版本,因为OSX上的nc略有不同。我使用的是:
Ncat: Version 7.94 ( https://nmap.org/ncat )

0
通常在响应头中需要的不仅仅是HTTP/1.1 200 OK,否则HTTP客户端会等待更多的响应数据。下面的命令似乎可以完成这个任务:
while true ; do echo -e "HTTP/1.1 200 OK\n"\
                        "Date: $(date)\n"\
                        "Server: Echo\n"\
                        "Content-Length: 0\n"\
                        "Connection: Closed\n"\
                | nc -l localhost 1500; done

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接