Socat - 穷人的 http 服务器

问题描述

在过去的几个小时里,我一直在绞尽脑汁,试图使用 socat 构建一个穷人的 http 服务器。不要问为什么或建议替代方案。我需要在纯 bash 中执行此操作。所以我像这样运行 socat:

socat -v TCP-LISTEN:1234,reuseaddr,fork SYstem:./httpd.sh

httpd.sh 应该读取 http 请求,解析它然后发送响应。

例如GET /index.html输出 Index!GET /random输出一个随机数。

我遇到的问题是读取整个 http 请求。考虑以下用于读取 http 请求的每一行的代码

while read -r LINE
do
    echo "$LINE" 
done

通常它应该将请求输出回浏览器。问题是在我打开 127.0.0.1:1234 后它只是挂起等待某些东西。如果我 CTRL + C socat,连接将关闭并且响应显示在浏览器中。我认为 while 循环会一直持续下去,从而阻止了响应的传输。

如果我使用下面的代码

while read -r LINE
do
    echo "$LINE" 
    [ -z "$LINE" ] && break
done

while 循环中断,浏览器不再挂起。似乎是一个很好的解决方案。但是...在 POST 请求的情况下,不会记录 POST 数据,因为中断发生在标题(空行)之后...

POST /index.html HTTP/1.0
User-Agent: Firefox
Content-Type: application/x-www-form-urlencoded

parameter1=test

如何通过 shell 脚本读取整个 http 请求,处理它并发送响应而不挂起?

编辑:

我认为这可能是答案。如果我运行这个命令:

socat TCP4-LISTEN:1234,fork,crlf SYstem:"echo hello world"

一切正常,每次都输出hello world。

socat 如何知道 HTTP 请求何时结束?

解决方法

如何通过 shell 脚本读取整个 http 请求,处理它并发送响应而不挂起?

在您撰写本文时,您已经有了 GET 的解决方案;在 POST 请求的情况下,您只需要再读一行(多个数据值 & 分隔在一行上)。发送响应后,您必须退出 httpd.sh 或至少关闭其输出。

socat 如何知道 HTTP 请求何时结束?

socat 知道 响应 在来自 echo 的数据管道在该进程终止时关闭时结束。

,

您无法逐行读取请求。 HTTP 请求可能包含换行符。您需要阅读整个请求并对其进行解析。

对于 GET 请求或 Head 请求,您只需要标题,因此您只能读取一行。

对于帖子,您需要读取内容长度标头中规定的字节数,或者直到您收到 EOF。

可以说,您的脚本变得更加复杂了。