IIS6 kills python cgi script after printing 401 header?
Win2k3 sp2 w/ ii6, python7 configured as a script mapping (detailed later). New to python, using the following code works as expected:
import logging as log
import time
import win32api
LOG_FILENAME="C:\\logs\\iistest.log"
TIME_STEP=.0001
log.basicConfig(filename=LOG_FILENAME,filemode="w",level=log.DEBUG)
try:
win32api.SetConsoleCtrlHandler( \
lambda sig: log.debug("on_exit called with sig [%s]" % str(sig)), True)
log.debug("printing headers...")
# print "Status: 401 Unauthorized"
# print ""
print "Status: 200 OK"
print ""
log.debug("headers printed.")
for i in range(1,11):
time.sleep(TIME_STEP)
log.debug("Tick...(%.4f sec)" % (i*TIME_STEP))
log.debug("Done with main logic.")
except Exception as e:
log.debug("Generic Exception: \n-----\n%s\n-----" % e)
finally:
log.debug("In finally, cleaning up.")
Invoking http://localhost/webtest/authUrl/iistest.py
gets a blank page the following in the logfile (again, as expected)
DEBUG:root:printing headers...
DEBUG:root:headers printed.
DEBUG:root:Tick...(0.0001 sec)
DEBUG:root:Tick...(0.0002 sec)
DEBUG:root:Tick...(0.0003 sec)
DEBUG:root:Tick...(0.0004 sec)
DEBUG:root:Tick...(0.0005 sec)
DEBUG:root:Tick...(0.0006 sec)
DEBUG:root:Tick...(0.0007 sec)
DEBUG:root:Tick...(0.0008 sec)
DEBUG:root:Tick...(0.0009 sec)
DEBUG:root:Tick...(0.0010 sec)
DEBUG:root:Done with main logic.
DEBUG:root:In finally, cleaning up.
If I swap the print statements so it does the 401
instead of the 200
, the client will get the expected stock IIS 401.5 Authorization failed by an ISAPI/CGI application.
, and the log file contains:
DEBUG:root:printing headers...
DEBUG:root:headers printed.
DEBUG:root:Tick...(0.0001 sec)
DEBUG:ro开发者_如何学运维ot:Tick...(0.0002 sec)
DEBUG:root:Tick...(0.0003 sec)
That's it. python.exe
process is gone. Error log on server has nothing, transfer log for IIS properly logs it as a 401.5
, but no other indication anything went wrong.
If I use py2exe to build the script into an executable, put it in a subdirectory and access http://localhost/webtest/authUrl/dist/iistest.exe
, did NOT have the problem, the code runs to completion with a 401, making same log as the 200 one.
Ran the .py scriptmap setup on a WinXP/IIS5 machine, did NOT have the problem; executing the .py
and the 401 let the log fill to completion.
This makes me suspect it's something to do with the application extension mapping .py
to python.exe
, but I don't see anything odd. The relevant bits of MetaBase.xml
:
ScriptMaps=".asa,C:\WINDOWS\system32\inetsrv\asp.dll,5,GET,HEAD,POST,TRACE
....
.py,C:\Python27\python.exe -u "%s" "%s",4
And where the dir's set up:
<IIsWebDirectory Location ="/LM/W3SVC/1/ROOT/webtest/authUrl"
AccessFlags="AccessExecute | AccessRead | AccessScript"
AuthFlags="AuthBasic | AuthAnonymous"
>
<Custom
Name="UNCPassword"
ID="3003"
Value="{insertlonghexhere}"
Type="STRING"
UserType="IIS_MD_UT_FILE"
Attributes="INHERIT | SECURE"
/>
</IIsWebDirectory>
<IIsWebDirectory Location ="/LM/W3SVC/1/ROOT/webtest/authUrl/dist"
>
</IIsWebDirectory>
I know the exit handler didn't fire, but I've verified it does with Ctrl-C on CLI and I wouldn't expect it to with TerminateProcess anyway.
I'm pretty tapped for ideas as to why this is happening, didn't see any google info about IIS killing CGI processes. I know I can work around it by delaying printing the header, but I want to understand. Any hints?
Edit: Also noted that it's not a total timeout. I can connect a remote winpdb to the script and step through, waiting 10s of seconds between statements, and as SOON as it gets past that 2nd print that completes the headers, debugger loses connectivity.
Tried some other status codes:
- 301, 302, and 404 die almost IMMEDIATELY. They all log
headers printed.
, and consistently fail to get to the firstTick
. - 400 has a similar mount of time until death as 401
And still, all of these worked just fine when compiling to an .exe
and running it directly.
Hmmm. I've done some perl CGI work on IIS, but not python, so I won't really be able to help you directly. I yellow-flag, though, about the "Custom" tag in your metabase excerpt. The UNCPassword property should not be registered as a Custom tag. I've had entire virtual directories import as Customs before, and they give unpredictable results. Best of luck (4 months later).
精彩评论