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

时间:2016-10-17 08:34:29

标签: windows batch-file webserver named-pipes 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或完成预期结果的任何其他方法之前,有没有办法阻止响应?

2 个答案:

答案 0 :(得分:5)

签出-e选项,您可以编写执行处理的脚本,然后执行

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

可以将stdin和stdout从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)

答案 1 :(得分:3)

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

stdout generation | nc -l

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

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

  1. 侦听准备让客户端执行重新加载的连接
  2. 从上一个请求的标题中删除GET地址。
  3. 在客户的第二次连接上提供相关内容
  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