【问题标题】:How to respond conditionally based on the request when using netcat使用netcat时如何根据请求有条件地响应
【发布时间】:2016-10-17 08:34:28
【问题描述】:

我正在尝试仅使用 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 更新或任何其他实现预期结果的方法?

【问题讨论】:

  • 你正在用字符串“found”或“not-found”覆盖tempfile.txt的内容;你的代码根本不应该工作。
  • @SomethingDark 我相信这是故意的。这些不打算成为日志。它们旨在包含 HTTP 内容。 OP 要求的是如何根据浏览器的请求标头内容使nc TCP 输出有条件。
  • @rojo - 他正在覆盖他正在通过管道传输到 netcat 的文件。 Netcat 应该会左右吐错误。
  • @SomethingDark Netcat 执行在 findstr 执行时已完成。在下一次循环迭代之前,Netcat 不太关心 tempfile.txt 会发生什么。
  • 在第一次迭代之后,tempfile.txt 将只包含字符串“found”或“not found”。我不明白脚本是如何多次成功运行的。

标签: windows batch-file webserver named-pipes netcat


【解决方案1】:

签出-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)

【讨论】:

  • 你能提供任何工作代码作为概念证明吗?如果是这样,您使用了哪个版本的 netcat 来与您的代码一起使用?我已经尝试了所有我能想到的使用netcat 1.12 for Win32/64 的排列,并且无论是x86 还是x64 构建,我都无法获得-e 开关来运行批处理脚本并将其输出发送到客户端。 Firebug 始终将 GET 请求状态显示为“已中止”。
  • 是的,我在 linux 上,但会在大约 4 个半小时内回复您。
  • 哈哈 6 个半。现在就做。
  • 嗯,这是一个记录在案的功能,但对于我来说,我似乎无法让它工作。它与可执行文件一起工作得很好,我想知道批处理脚本没有在交互式会话中运行是否有问题?真的很抱歉,这是一个记录在案的功能......我仍在研究它。
【解决方案2】:

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

stdout generation | nc -l

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

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

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

示例代码:

@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的无用使用。

【讨论】:

    猜你喜欢
    • 2017-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-15
    • 1970-01-01
    • 2017-09-30
    • 1970-01-01
    • 2016-06-19
    相关资源
    最近更新 更多