I am trying to set up a web server using only windows batch scripting.
I have already come up with the following script:
@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
)
)
However, the response is always one request behind, I mean, if I type something like this into the browser:
REQUEST: localhost/mystring
I will get the following response:
RESPONSE: not-found
Only in the next request I will receive the correct answer for the request presented above.
This is happening because as soon as netcat receives a request it responds with the current content of the tempfile.txt which has not been updated yet based on the request.
Is there any way to block the response until the tempfile.txt is updated or any other method which accomplish the expected result?
The Netcat ( nc ) command is a command-line utility for reading and writing data between two computer networks. The communication happens using either TCP or UDP. The command differs depending on the system ( netcat , nc , ncat , and others).
The command nc –l will put Netcat into server or listening mode, and nc by itself will run Netcat in client mode.
The –v switch is the parameter for using Netcat in verbose mode. Verbosity is simply the amount of feedback that the utility provides back to the screen during operation. Netcat also supports –vv (double v) for additional verbosity that will give you the number of bytes transferred during a file transfer.
To listen on port 80, use the nc command with the —v (verbose) —l (listen) —p (port) switches. (The —v switch is not required and simply provides more verbose output, as shown below in Figure 9.18.)
Checkout the -e
option, you could write a script that does the processing and then execute
nc -L -w1 -p 80 -eexec.bat
which would pipe stdin and stdout back and forth from nc to the script like you want.
exec.bat could be something like (somewhat pseudo code):
findstr mystring
if not errorlevel 1 (echo found) else (echo not-found)
or maybe a loop (also somewhat pseudo code):
: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)
The problem is, as far as I can tell, nc
can't perform a callback to tailor its output based on client input. Once you have...
stdout generation | nc -l
... blocking and waiting for a connection, its output is already determined. That output is static at that point.
The only workaround which occurs to me is rather inefficient. It basically involves the following logic:
Example code:
@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
)
As a side note, delayed expansion can mutilate variable values set with exclamation marks if it's enabled at the time of setting. Best to wait to enable delayed expansion until retrieval.
Also, when performing a boolean check on %ERRORLEVEL%
it's more graceful to employ conditional execution. But that has nothing to do with my solution. :)
And finally, instead of doing type filename.html | nc -l
, consider using <filename.html nc -l
(or nc -l <filename.html
) to avoid the useless use of type
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With