Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
196
venv/Lib/site-packages/isapi/samples/advanced.py
Normal file
196
venv/Lib/site-packages/isapi/samples/advanced.py
Normal file
|
@ -0,0 +1,196 @@
|
|||
# This extension demonstrates some advanced features of the Python ISAPI
|
||||
# framework.
|
||||
# We demonstrate:
|
||||
# * Reloading your Python module without shutting down IIS (eg, when your
|
||||
# .py implementation file changes.)
|
||||
# * Custom command-line handling - both additional options and commands.
|
||||
# * Using a query string - any part of the URL after a '?' is assumed to
|
||||
# be "variable names" separated by '&' - we will print the values of
|
||||
# these server variables.
|
||||
# * If the tail portion of the URL is "ReportUnhealthy", IIS will be
|
||||
# notified we are unhealthy via a HSE_REQ_REPORT_UNHEALTHY request.
|
||||
# Whether this is acted upon depends on if the IIS health-checking
|
||||
# tools are installed, but you should always see the reason written
|
||||
# to the Windows event log - see the IIS documentation for more.
|
||||
|
||||
from isapi import isapicon
|
||||
from isapi.simple import SimpleExtension
|
||||
import sys, os, stat
|
||||
|
||||
if hasattr(sys, "isapidllhandle"):
|
||||
import win32traceutil
|
||||
|
||||
# Notes on reloading
|
||||
# If your HttpFilterProc or HttpExtensionProc functions raises
|
||||
# 'isapi.InternalReloadException', the framework will not treat it
|
||||
# as an error but instead will terminate your extension, reload your
|
||||
# extension module, re-initialize the instance, and re-issue the request.
|
||||
# The Initialize functions are called with None as their param. The
|
||||
# return code from the terminate function is ignored.
|
||||
#
|
||||
# This is all the framework does to help you. It is up to your code
|
||||
# when you raise this exception. This sample uses a Win32 "find
|
||||
# notification". Whenever windows tells us one of the files in the
|
||||
# directory has changed, we check if the time of our source-file has
|
||||
# changed, and set a flag. Next imcoming request, we check the flag and
|
||||
# raise the special exception if set.
|
||||
#
|
||||
# The end result is that the module is automatically reloaded whenever
|
||||
# the source-file changes - you need take no further action to see your
|
||||
# changes reflected in the running server.
|
||||
|
||||
# The framework only reloads your module - if you have libraries you
|
||||
# depend on and also want reloaded, you must arrange for this yourself.
|
||||
# One way of doing this would be to special case the import of these
|
||||
# modules. Eg:
|
||||
# --
|
||||
# try:
|
||||
# my_module = reload(my_module) # module already imported - reload it
|
||||
# except NameError:
|
||||
# import my_module # first time around - import it.
|
||||
# --
|
||||
# When your module is imported for the first time, the NameError will
|
||||
# be raised, and the module imported. When the ISAPI framework reloads
|
||||
# your module, the existing module will avoid the NameError, and allow
|
||||
# you to reload that module.
|
||||
|
||||
from isapi import InternalReloadException
|
||||
import win32event, win32file, winerror, win32con, threading
|
||||
|
||||
try:
|
||||
reload_counter += 1
|
||||
except NameError:
|
||||
reload_counter = 0
|
||||
|
||||
# A watcher thread that checks for __file__ changing.
|
||||
# When it detects it, it simply sets "change_detected" to true.
|
||||
class ReloadWatcherThread(threading.Thread):
|
||||
def __init__(self):
|
||||
self.change_detected = False
|
||||
self.filename = __file__
|
||||
if self.filename.endswith("c") or self.filename.endswith("o"):
|
||||
self.filename = self.filename[:-1]
|
||||
self.handle = win32file.FindFirstChangeNotification(
|
||||
os.path.dirname(self.filename),
|
||||
False, # watch tree?
|
||||
win32con.FILE_NOTIFY_CHANGE_LAST_WRITE)
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
def run(self):
|
||||
last_time = os.stat(self.filename)[stat.ST_MTIME]
|
||||
while 1:
|
||||
try:
|
||||
rc = win32event.WaitForSingleObject(self.handle,
|
||||
win32event.INFINITE)
|
||||
win32file.FindNextChangeNotification(self.handle)
|
||||
except win32event.error as details:
|
||||
# handle closed - thread should terminate.
|
||||
if details.winerror != winerror.ERROR_INVALID_HANDLE:
|
||||
raise
|
||||
break
|
||||
this_time = os.stat(self.filename)[stat.ST_MTIME]
|
||||
if this_time != last_time:
|
||||
print("Detected file change - flagging for reload.")
|
||||
self.change_detected = True
|
||||
last_time = this_time
|
||||
|
||||
def stop(self):
|
||||
win32file.FindCloseChangeNotification(self.handle)
|
||||
|
||||
# The ISAPI extension - handles requests in our virtual dir, and sends the
|
||||
# response to the client.
|
||||
class Extension(SimpleExtension):
|
||||
"Python advanced sample Extension"
|
||||
def __init__(self):
|
||||
self.reload_watcher = ReloadWatcherThread()
|
||||
self.reload_watcher.start()
|
||||
|
||||
def HttpExtensionProc(self, ecb):
|
||||
# NOTE: If you use a ThreadPoolExtension, you must still perform
|
||||
# this check in HttpExtensionProc - raising the exception from
|
||||
# The "Dispatch" method will just cause the exception to be
|
||||
# rendered to the browser.
|
||||
if self.reload_watcher.change_detected:
|
||||
print("Doing reload")
|
||||
raise InternalReloadException
|
||||
|
||||
url = ecb.GetServerVariable("UNICODE_URL")
|
||||
if url.endswith("ReportUnhealthy"):
|
||||
ecb.ReportUnhealthy("I'm a little sick")
|
||||
|
||||
ecb.SendResponseHeaders("200 OK", "Content-Type: text/html\r\n\r\n", 0)
|
||||
print("<HTML><BODY>", file=ecb)
|
||||
|
||||
qs = ecb.GetServerVariable("QUERY_STRING")
|
||||
if qs:
|
||||
queries = qs.split("&")
|
||||
print("<PRE>", file=ecb)
|
||||
for q in queries:
|
||||
val = ecb.GetServerVariable(q, '<no such variable>')
|
||||
print("%s=%r" % (q, val), file=ecb)
|
||||
print("</PRE><P/>", file=ecb)
|
||||
|
||||
print("This module has been imported", file=ecb)
|
||||
print("%d times" % (reload_counter,), file=ecb)
|
||||
print("</BODY></HTML>", file=ecb)
|
||||
ecb.close()
|
||||
return isapicon.HSE_STATUS_SUCCESS
|
||||
|
||||
def TerminateExtension(self, status):
|
||||
self.reload_watcher.stop()
|
||||
|
||||
# The entry points for the ISAPI extension.
|
||||
def __ExtensionFactory__():
|
||||
return Extension()
|
||||
|
||||
# Our special command line customization.
|
||||
# Pre-install hook for our virtual directory.
|
||||
def PreInstallDirectory(params, options):
|
||||
# If the user used our special '--description' option,
|
||||
# then we override our default.
|
||||
if options.description:
|
||||
params.Description = options.description
|
||||
|
||||
# Post install hook for our entire script
|
||||
def PostInstall(params, options):
|
||||
print()
|
||||
print("The sample has been installed.")
|
||||
print("Point your browser to /AdvancedPythonSample")
|
||||
print("If you modify the source file and reload the page,")
|
||||
print("you should see the reload counter increment")
|
||||
|
||||
# Handler for our custom 'status' argument.
|
||||
def status_handler(options, log, arg):
|
||||
"Query the status of something"
|
||||
print("Everything seems to be fine!")
|
||||
|
||||
custom_arg_handlers = {"status": status_handler}
|
||||
|
||||
if __name__=='__main__':
|
||||
# If run from the command-line, install ourselves.
|
||||
from isapi.install import *
|
||||
params = ISAPIParameters(PostInstall = PostInstall)
|
||||
# Setup the virtual directories - this is a list of directories our
|
||||
# extension uses - in this case only 1.
|
||||
# Each extension has a "script map" - this is the mapping of ISAPI
|
||||
# extensions.
|
||||
sm = [
|
||||
ScriptMapParams(Extension="*", Flags=0)
|
||||
]
|
||||
vd = VirtualDirParameters(Name="AdvancedPythonSample",
|
||||
Description = Extension.__doc__,
|
||||
ScriptMaps = sm,
|
||||
ScriptMapUpdate = "replace",
|
||||
# specify the pre-install hook.
|
||||
PreInstall = PreInstallDirectory
|
||||
)
|
||||
params.VirtualDirs = [vd]
|
||||
# Setup our custom option parser.
|
||||
from optparse import OptionParser
|
||||
parser = OptionParser('') # blank usage, so isapi sets it.
|
||||
parser.add_option("", "--description",
|
||||
action="store",
|
||||
help="custom description to use for the virtual directory")
|
||||
|
||||
HandleCommandLine(params, opt_parser=parser,
|
||||
custom_arg_handlers = custom_arg_handlers)
|
Loading…
Add table
Add a link
Reference in a new issue