使用netcat时如何根据请求有条件响应

How to respond conditionally based on the request when using netcat

我正在尝试仅使用 windows 批处理脚本来设置 Web 服务器。

我已经想出了以下脚本:

@echo off
@setlocal  enabledelayedexpansion

for /l %%a in (1,0,2) do (
  type tempfile.txt | nc -w 1 -l -p 80  | findstr mystring
  if !ERRORLEVEL! == 0 (
    echo found > tempfile.txt
  ) else (
    echo not-found > tempfile.txt
  )
)

但是,响应总是落后一个请求,我的意思是,如果我在浏览器中输入如下内容:

REQUEST: localhost/mystring

我会得到以下回复:

RESPONSE: not-found

只有在下一次请求中,我才会收到上述请求的正确答案。

发生这种情况是因为一旦 netcat 收到请求,它就会使用尚未根据请求更新的 tempfile.txt 的当前内容进行响应。

在 tempfile.txt 更新之前是否有任何方法可以阻止响应或任何其他方法可以达到预期的结果?

问题是,据我所知,nc 无法执行回调以根据客户端输入调整其输出。一旦你有...

stdout generation | nc -l

...阻塞并等待连接,它的输出已经确定。该输出在那时是静态的。

我想到的唯一解决方法是效率很低。基本上涉及以下逻辑:

  1. 侦听准备让客户端执行重新加载的连接
  2. 从上一个请求的 headers.
  3. 中抓取 GET 地址
  4. 在客户端的第二个连接上提供相关内容

示例代码:

@echo off & setlocal

rem // macro for netcat command line and args
set "nc=\cygwin64\bin\nc.exe -w 1 -l 80"

rem // macro for sending refresh header
set "refresh=^(echo HTTP/1.1 200 OK^&echo Refresh:0;^)^| %nc%"

for /L %%# in (1,0,2) do (
    rem // run refresh macro and capture client's requested URL
    for /f "tokens=2" %%I in ('%refresh% ^| findstr "^GET"') do set "URL=%%I"

    rem // serve content to the client
    setlocal enabledelayedexpansion
    echo URL: !URL! | %nc%
    endlocal
)

附带说明一下,如果延迟扩展在设置时启用,它可能会破坏用感叹号设置的变量值。最好等到检索时启用延迟扩展。

此外,在对 %ERRORLEVEL% 执行布尔检查时,使用 conditional execution 更为优雅。但这与我的解决方案无关。 :)

最后,不要使用 type filename.html | nc -l,而是考虑使用 <filename.html nc -l(或 nc -l <filename.html)以避免无用地使用 type

检查-e选项,你可以写一个脚本来处理然后执行

nc -L -w1 -p 80 -eexec.bat

它将标准输入和标准输出从 nc 来回传送到您想要的脚本。

exec.bat 可能类似于(有点伪代码):

findstr mystring
if not errorlevel 1 (echo found) else (echo not-found)

或者可能是一个循环(也有点伪代码):

:top
set /p input=
if input wasn't "" echo %input% >> output.dat && goto top
findstr /C:"mystring" output.dat
if not errorlevel 1 (echo found) else (echo not-found)