使用netcat搭建HTTP服务器时bash存储png/jpeg损坏、read -s GET异常致加载失败
问题根源
你遇到的所有异常对应四个明确的脚本错误,没有模糊的未知问题:
- 变量不匹配导致路径提取完全失效
你写的read -s GET是把HTTP请求第一行存入名为GET的变量,但后续提取路径时用的$input从来没有被赋值过,永远是空值。因此echo "$input" | grep ...的结果永远为空,resource只会默认取index.html或Error.html,根本不会读取你请求的图片文件。
你提到「移除read语句后纯文本可正常响应、图片加载失败」的原因:移除read后$input依然是空,resource还是默认指向index.html,访问根路径时刚好能返回纯文本首页;但请求图片时脚本依旧只会输出HTML内容,浏览器把HTML当图片解析,自然显示损坏占位图标。 - Bash变量无法存储二进制内容(图片损坏的核心原因)
Bash变量仅支持处理纯文本,遇到png、jpeg这类二进制文件时,会自动转义、截断二进制中的特殊字符(比如空字节),哪怕用output=$(cat "$resource")读入图片内容,存进output变量的瞬间文件就已经损坏。 - HTTP响应头格式不规范
HTTP协议要求响应头每一行结尾必须是\r\n,你写的响应头用\n换行,且末尾多输出了一个\n,会导致浏览器解析响应头时匹配不上Content-Length和实际内容长度,资源加载失败。 - Netcat参数冗余
你用的-q 1参数会让连接在收到EOF后等待1秒就断开,容易导致未传输完的资源被截断。
修复后的脚本
核心修改逻辑:绝对不要把二进制文件内容存入Bash变量,直接输出文件内容到stdout
#!/bin/bash index_page=index.html error_page=Error.html # 正确读取请求行,存入独立变量 read -r GET_REQUEST # 用正确的请求行变量提取路径 resource=$(echo "$GET_REQUEST" | grep -P -o '(?<=GET \/).*(?=\ )') # 处理路径不存在的情况 if [ -z "$resource" ]; then resource=$index_page elif [ ! -f "$resource" ]; then resource=$error_page fi content_type=$(file -b --mime-type "$resource") content_length=$(stat -c '%s' "$resource") # 输出符合HTTP规范的响应头,每一行用\r\n结尾 echo -ne "HTTP/1.1 200 OK\r\n" echo -ne "Content-Length: $content_length\r\n" echo -ne "Content-Type: $content_type\r\n" # 响应头和内容之间用空行分隔 echo -ne "\r\n" # 直接输出文件内容,二进制文件也不会损坏 cat "$resource"
启动命令调整
先给脚本加执行权限,再启动服务:
chmod +x serverhttp.sh nc -l -k -p 80 -e ./serverhttp.sh
内容的提问来源于stack exchange,提问作者joan
相关产品推荐
相关产品推荐

