Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
20
venv/Lib/site-packages/isapi/samples/README.txt
Normal file
20
venv/Lib/site-packages/isapi/samples/README.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
In this directory you will find examples of ISAPI filters and extensions.
|
||||
|
||||
The filter loading mechanism works like this:
|
||||
* IIS loads the special Python "loader" DLL. This DLL will generally have a
|
||||
leading underscore as part of its name.
|
||||
* This loader DLL looks for a Python module, by removing the first letter of
|
||||
the DLL base name.
|
||||
|
||||
This means that an ISAPI extension module consists of 2 key files - the loader
|
||||
DLL (eg, "_MyIISModule.dll", and a Python module (which for this example
|
||||
would be "MyIISModule.py")
|
||||
|
||||
When you install an ISAPI extension, the installation code checks to see if
|
||||
there is a loader DLL for your implementation file - if one does not exist,
|
||||
or the standard loader is different, it is copied and renamed accordingly.
|
||||
|
||||
We use this mechanism to provide the maximum separation between different
|
||||
Python extensions installed on the same server - otherwise filter order and
|
||||
other tricky IIS semantics would need to be replicated. Also, each filter
|
||||
gets its own thread-pool, etc.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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)
|
109
venv/Lib/site-packages/isapi/samples/redirector.py
Normal file
109
venv/Lib/site-packages/isapi/samples/redirector.py
Normal file
|
@ -0,0 +1,109 @@
|
|||
# This is a sample ISAPI extension written in Python.
|
||||
#
|
||||
# Please see README.txt in this directory, and specifically the
|
||||
# information about the "loader" DLL - installing this sample will create
|
||||
# "_redirector.dll" in the current directory. The readme explains this.
|
||||
|
||||
# Executing this script (or any server config script) will install the extension
|
||||
# into your web server. As the server executes, the PyISAPI framework will load
|
||||
# this module and create your Extension and Filter objects.
|
||||
|
||||
# This is the simplest possible redirector (or proxy) we can write. The
|
||||
# extension installs with a mask of '*' in the root of the site.
|
||||
# As an added bonus though, we optionally show how, on IIS6 and later, we
|
||||
# can use HSE_ERQ_EXEC_URL to ignore certain requests - in IIS5 and earlier
|
||||
# we can only do this with an ISAPI filter - see redirector_with_filter for
|
||||
# an example. If this sample is run on IIS5 or earlier it simply ignores
|
||||
# any excludes.
|
||||
|
||||
from isapi import isapicon, threaded_extension
|
||||
import sys
|
||||
import traceback
|
||||
try:
|
||||
from urllib.request import urlopen
|
||||
except ImportError:
|
||||
# py3k spelling...
|
||||
from urllib.request import urlopen
|
||||
import win32api
|
||||
|
||||
# sys.isapidllhandle will exist when we are loaded by the IIS framework.
|
||||
# In this case we redirect our output to the win32traceutil collector.
|
||||
if hasattr(sys, "isapidllhandle"):
|
||||
import win32traceutil
|
||||
|
||||
# The site we are proxying.
|
||||
proxy = "http://www.python.org"
|
||||
|
||||
# Urls we exclude (ie, allow IIS to handle itself) - all are lowered,
|
||||
# and these entries exist by default on Vista...
|
||||
excludes = ["/iisstart.htm", "/welcome.png"]
|
||||
|
||||
# An "io completion" function, called when ecb.ExecURL completes...
|
||||
def io_callback(ecb, url, cbIO, errcode):
|
||||
# Get the status of our ExecURL
|
||||
httpstatus, substatus, win32 = ecb.GetExecURLStatus()
|
||||
print("ExecURL of %r finished with http status %d.%d, win32 status %d (%s)" % (
|
||||
url, httpstatus, substatus, win32, win32api.FormatMessage(win32).strip()))
|
||||
# nothing more to do!
|
||||
ecb.DoneWithSession()
|
||||
|
||||
# The ISAPI extension - handles all requests in the site.
|
||||
class Extension(threaded_extension.ThreadPoolExtension):
|
||||
"Python sample Extension"
|
||||
def Dispatch(self, ecb):
|
||||
# Note that our ThreadPoolExtension base class will catch exceptions
|
||||
# in our Dispatch method, and write the traceback to the client.
|
||||
# That is perfect for this sample, so we don't catch our own.
|
||||
#print 'IIS dispatching "%s"' % (ecb.GetServerVariable("URL"),)
|
||||
url = ecb.GetServerVariable("URL").decode("ascii")
|
||||
for exclude in excludes:
|
||||
if url.lower().startswith(exclude):
|
||||
print("excluding %s" % url)
|
||||
if ecb.Version < 0x60000:
|
||||
print("(but this is IIS5 or earlier - can't do 'excludes')")
|
||||
else:
|
||||
ecb.IOCompletion(io_callback, url)
|
||||
ecb.ExecURL(None, None, None, None, None, isapicon.HSE_EXEC_URL_IGNORE_CURRENT_INTERCEPTOR)
|
||||
return isapicon.HSE_STATUS_PENDING
|
||||
|
||||
new_url = proxy + url
|
||||
print("Opening %s" % new_url)
|
||||
fp = urlopen(new_url)
|
||||
headers = fp.info()
|
||||
# subtle py3k breakage: in py3k, str(headers) has normalized \r\n
|
||||
# back to \n and also stuck an extra \n term. py2k leaves the
|
||||
# \r\n from the server in tact and finishes with a single term.
|
||||
if sys.version_info < (3,0):
|
||||
header_text = str(headers) + "\r\n"
|
||||
else:
|
||||
# take *all* trailing \n off, replace remaining with
|
||||
# \r\n, then add the 2 trailing \r\n.
|
||||
header_text = str(headers).rstrip('\n').replace('\n', '\r\n') + '\r\n\r\n'
|
||||
ecb.SendResponseHeaders("200 OK", header_text, False)
|
||||
ecb.WriteClient(fp.read())
|
||||
ecb.DoneWithSession()
|
||||
print("Returned data from '%s'" % (new_url,))
|
||||
return isapicon.HSE_STATUS_SUCCESS
|
||||
|
||||
# The entry points for the ISAPI extension.
|
||||
def __ExtensionFactory__():
|
||||
return Extension()
|
||||
|
||||
if __name__=='__main__':
|
||||
# If run from the command-line, install ourselves.
|
||||
from isapi.install import *
|
||||
params = ISAPIParameters()
|
||||
# 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="/",
|
||||
Description = Extension.__doc__,
|
||||
ScriptMaps = sm,
|
||||
ScriptMapUpdate = "replace"
|
||||
)
|
||||
params.VirtualDirs = [vd]
|
||||
HandleCommandLine(params)
|
78
venv/Lib/site-packages/isapi/samples/redirector_asynch.py
Normal file
78
venv/Lib/site-packages/isapi/samples/redirector_asynch.py
Normal file
|
@ -0,0 +1,78 @@
|
|||
# This is a sample ISAPI extension written in Python.
|
||||
|
||||
# This is like the other 'redirector' samples, but uses asnch IO when writing
|
||||
# back to the client (it does *not* use asynch io talking to the remote
|
||||
# server!)
|
||||
|
||||
from isapi import isapicon, threaded_extension
|
||||
import sys
|
||||
import traceback
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
|
||||
# sys.isapidllhandle will exist when we are loaded by the IIS framework.
|
||||
# In this case we redirect our output to the win32traceutil collector.
|
||||
if hasattr(sys, "isapidllhandle"):
|
||||
import win32traceutil
|
||||
|
||||
# The site we are proxying.
|
||||
proxy = "http://www.python.org"
|
||||
|
||||
# We synchronously read chunks of this size then asynchronously write them.
|
||||
CHUNK_SIZE=8192
|
||||
|
||||
# The callback made when IIS completes the asynch write.
|
||||
def io_callback(ecb, fp, cbIO, errcode):
|
||||
print("IO callback", ecb, fp, cbIO, errcode)
|
||||
chunk = fp.read(CHUNK_SIZE)
|
||||
if chunk:
|
||||
ecb.WriteClient(chunk, isapicon.HSE_IO_ASYNC)
|
||||
# and wait for the next callback to say this chunk is done.
|
||||
else:
|
||||
# eof - say we are complete.
|
||||
fp.close()
|
||||
ecb.DoneWithSession()
|
||||
|
||||
# The ISAPI extension - handles all requests in the site.
|
||||
class Extension(threaded_extension.ThreadPoolExtension):
|
||||
"Python sample proxy server - asynch version."
|
||||
def Dispatch(self, ecb):
|
||||
print('IIS dispatching "%s"' % (ecb.GetServerVariable("URL"),))
|
||||
url = ecb.GetServerVariable("URL")
|
||||
|
||||
new_url = proxy + url
|
||||
print("Opening %s" % new_url)
|
||||
fp = urllib.request.urlopen(new_url)
|
||||
headers = fp.info()
|
||||
ecb.SendResponseHeaders("200 OK", str(headers) + "\r\n", False)
|
||||
# now send the first chunk asynchronously
|
||||
ecb.ReqIOCompletion(io_callback, fp)
|
||||
chunk = fp.read(CHUNK_SIZE)
|
||||
if chunk:
|
||||
ecb.WriteClient(chunk, isapicon.HSE_IO_ASYNC)
|
||||
return isapicon.HSE_STATUS_PENDING
|
||||
# no data - just close things now.
|
||||
ecb.DoneWithSession()
|
||||
return isapicon.HSE_STATUS_SUCCESS
|
||||
|
||||
# The entry points for the ISAPI extension.
|
||||
def __ExtensionFactory__():
|
||||
return Extension()
|
||||
|
||||
if __name__=='__main__':
|
||||
# If run from the command-line, install ourselves.
|
||||
from isapi.install import *
|
||||
params = ISAPIParameters()
|
||||
# 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="/",
|
||||
Description = Extension.__doc__,
|
||||
ScriptMaps = sm,
|
||||
ScriptMapUpdate = "replace"
|
||||
)
|
||||
params.VirtualDirs = [vd]
|
||||
HandleCommandLine(params)
|
155
venv/Lib/site-packages/isapi/samples/redirector_with_filter.py
Normal file
155
venv/Lib/site-packages/isapi/samples/redirector_with_filter.py
Normal file
|
@ -0,0 +1,155 @@
|
|||
# This is a sample configuration file for an ISAPI filter and extension
|
||||
# written in Python.
|
||||
#
|
||||
# Please see README.txt in this directory, and specifically the
|
||||
# information about the "loader" DLL - installing this sample will create
|
||||
# "_redirector_with_filter.dll" in the current directory. The readme explains
|
||||
# this.
|
||||
|
||||
# Executing this script (or any server config script) will install the extension
|
||||
# into your web server. As the server executes, the PyISAPI framework will load
|
||||
# this module and create your Extension and Filter objects.
|
||||
|
||||
# This sample provides sample redirector:
|
||||
# It is implemented by a filter and an extension, so that some requests can
|
||||
# be ignored. Compare with 'redirector_simple' which avoids the filter, but
|
||||
# is unable to selectively ignore certain requests.
|
||||
# The process is sample uses is:
|
||||
# * The filter is installed globally, as all filters are.
|
||||
# * A Virtual Directory named "python" is setup. This dir has our ISAPI
|
||||
# extension as the only application, mapped to file-extension '*'. Thus, our
|
||||
# extension handles *all* requests in this directory.
|
||||
# The basic process is that the filter does URL rewriting, redirecting every
|
||||
# URL to our Virtual Directory. Our extension then handles this request,
|
||||
# forwarding the data from the proxied site.
|
||||
# For example:
|
||||
# * URL of "index.html" comes in.
|
||||
# * Filter rewrites this to "/python/index.html"
|
||||
# * Our extension sees the full "/python/index.html", removes the leading
|
||||
# portion, and opens and forwards the remote URL.
|
||||
|
||||
|
||||
# This sample is very small - it avoid most error handling, etc. It is for
|
||||
# demonstration purposes only.
|
||||
|
||||
from isapi import isapicon, threaded_extension
|
||||
from isapi.simple import SimpleFilter
|
||||
import sys
|
||||
import traceback
|
||||
import urllib.request, urllib.parse, urllib.error
|
||||
|
||||
# sys.isapidllhandle will exist when we are loaded by the IIS framework.
|
||||
# In this case we redirect our output to the win32traceutil collector.
|
||||
if hasattr(sys, "isapidllhandle"):
|
||||
import win32traceutil
|
||||
|
||||
# The site we are proxying.
|
||||
proxy = "http://www.python.org"
|
||||
# The name of the virtual directory we install in, and redirect from.
|
||||
virtualdir = "/python"
|
||||
|
||||
# The key feature of this redirector over the simple redirector is that it
|
||||
# can choose to ignore certain responses by having the filter not rewrite them
|
||||
# to our virtual dir. For this sample, we just exclude the IIS help directory.
|
||||
|
||||
# The ISAPI extension - handles requests in our virtual dir, and sends the
|
||||
# response to the client.
|
||||
class Extension(threaded_extension.ThreadPoolExtension):
|
||||
"Python sample Extension"
|
||||
def Dispatch(self, ecb):
|
||||
# Note that our ThreadPoolExtension base class will catch exceptions
|
||||
# in our Dispatch method, and write the traceback to the client.
|
||||
# That is perfect for this sample, so we don't catch our own.
|
||||
#print 'IIS dispatching "%s"' % (ecb.GetServerVariable("URL"),)
|
||||
url = ecb.GetServerVariable("URL")
|
||||
if url.startswith(virtualdir):
|
||||
new_url = proxy + url[len(virtualdir):]
|
||||
print("Opening", new_url)
|
||||
fp = urllib.request.urlopen(new_url)
|
||||
headers = fp.info()
|
||||
ecb.SendResponseHeaders("200 OK", str(headers) + "\r\n", False)
|
||||
ecb.WriteClient(fp.read())
|
||||
ecb.DoneWithSession()
|
||||
print("Returned data from '%s'!" % (new_url,))
|
||||
else:
|
||||
# this should never happen - we should only see requests that
|
||||
# start with our virtual directory name.
|
||||
print("Not proxying '%s'" % (url,))
|
||||
|
||||
|
||||
# The ISAPI filter.
|
||||
class Filter(SimpleFilter):
|
||||
"Sample Python Redirector"
|
||||
filter_flags = isapicon.SF_NOTIFY_PREPROC_HEADERS | \
|
||||
isapicon.SF_NOTIFY_ORDER_DEFAULT
|
||||
|
||||
def HttpFilterProc(self, fc):
|
||||
#print "Filter Dispatch"
|
||||
nt = fc.NotificationType
|
||||
if nt != isapicon.SF_NOTIFY_PREPROC_HEADERS:
|
||||
return isapicon.SF_STATUS_REQ_NEXT_NOTIFICATION
|
||||
|
||||
pp = fc.GetData()
|
||||
url = pp.GetHeader("url")
|
||||
#print "URL is '%s'" % (url,)
|
||||
prefix = virtualdir
|
||||
if not url.startswith(prefix):
|
||||
new_url = prefix + url
|
||||
print("New proxied URL is '%s'" % (new_url,))
|
||||
pp.SetHeader("url", new_url)
|
||||
# For the sake of demonstration, show how the FilterContext
|
||||
# attribute is used. It always starts out life as None, and
|
||||
# any assignments made are automatically decref'd by the
|
||||
# framework during a SF_NOTIFY_END_OF_NET_SESSION notification.
|
||||
if fc.FilterContext is None:
|
||||
fc.FilterContext = 0
|
||||
fc.FilterContext += 1
|
||||
print("This is request number %d on this connection" % fc.FilterContext)
|
||||
return isapicon.SF_STATUS_REQ_HANDLED_NOTIFICATION
|
||||
else:
|
||||
print("Filter ignoring URL '%s'" % (url,))
|
||||
|
||||
# Some older code that handled SF_NOTIFY_URL_MAP.
|
||||
#~ print "Have URL_MAP notify"
|
||||
#~ urlmap = fc.GetData()
|
||||
#~ print "URI is", urlmap.URL
|
||||
#~ print "Path is", urlmap.PhysicalPath
|
||||
#~ if urlmap.URL.startswith("/UC/"):
|
||||
#~ # Find the /UC/ in the physical path, and nuke it (except
|
||||
#~ # as the path is physical, it is \)
|
||||
#~ p = urlmap.PhysicalPath
|
||||
#~ pos = p.index("\\UC\\")
|
||||
#~ p = p[:pos] + p[pos+3:]
|
||||
#~ p = r"E:\src\pyisapi\webroot\PyTest\formTest.htm"
|
||||
#~ print "New path is", p
|
||||
#~ urlmap.PhysicalPath = p
|
||||
|
||||
# The entry points for the ISAPI extension.
|
||||
def __FilterFactory__():
|
||||
return Filter()
|
||||
def __ExtensionFactory__():
|
||||
return Extension()
|
||||
|
||||
if __name__=='__main__':
|
||||
# If run from the command-line, install ourselves.
|
||||
from isapi.install import *
|
||||
params = ISAPIParameters()
|
||||
# Setup all filters - these are global to the site.
|
||||
params.Filters = [
|
||||
FilterParameters(Name="PythonRedirector",
|
||||
Description=Filter.__doc__),
|
||||
]
|
||||
# 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=virtualdir[1:],
|
||||
Description = Extension.__doc__,
|
||||
ScriptMaps = sm,
|
||||
ScriptMapUpdate = "replace"
|
||||
)
|
||||
params.VirtualDirs = [vd]
|
||||
HandleCommandLine(params)
|
154
venv/Lib/site-packages/isapi/samples/test.py
Normal file
154
venv/Lib/site-packages/isapi/samples/test.py
Normal file
|
@ -0,0 +1,154 @@
|
|||
# This extension is used mainly for testing purposes - it is not
|
||||
# designed to be a simple sample, but instead is a hotch-potch of things
|
||||
# that attempts to exercise the framework.
|
||||
|
||||
from isapi import isapicon
|
||||
from isapi.simple import SimpleExtension
|
||||
import sys, os, stat
|
||||
|
||||
if hasattr(sys, "isapidllhandle"):
|
||||
import win32traceutil
|
||||
|
||||
# We use the same reload support as 'advanced.py' demonstrates.
|
||||
from isapi import InternalReloadException
|
||||
import win32event, win32file, winerror, win32con, threading
|
||||
|
||||
# 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)
|
||||
|
||||
def TransmitFileCallback(ecb, hFile, cbIO, errCode):
|
||||
print("Transmit complete!")
|
||||
ecb.close()
|
||||
|
||||
# The ISAPI extension - handles requests in our virtual dir, and sends the
|
||||
# response to the client.
|
||||
class Extension(SimpleExtension):
|
||||
"Python test 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
|
||||
|
||||
if ecb.GetServerVariable("UNICODE_URL").endswith("test.py"):
|
||||
file_flags = win32con.FILE_FLAG_SEQUENTIAL_SCAN | win32con.FILE_FLAG_OVERLAPPED
|
||||
hfile = win32file.CreateFile(__file__, win32con.GENERIC_READ,
|
||||
0, None, win32con.OPEN_EXISTING,
|
||||
file_flags, None)
|
||||
flags = isapicon.HSE_IO_ASYNC | isapicon.HSE_IO_DISCONNECT_AFTER_SEND | \
|
||||
isapicon.HSE_IO_SEND_HEADERS
|
||||
# We pass hFile to the callback simply as a way of keeping it alive
|
||||
# for the duration of the transmission
|
||||
try:
|
||||
ecb.TransmitFile(TransmitFileCallback, hfile,
|
||||
int(hfile),
|
||||
"200 OK",
|
||||
0, 0, None, None, flags)
|
||||
except:
|
||||
# Errors keep this source file open!
|
||||
hfile.Close()
|
||||
raise
|
||||
else:
|
||||
# default response
|
||||
ecb.SendResponseHeaders("200 OK", "Content-Type: text/html\r\n\r\n", 0)
|
||||
print("<HTML><BODY>", file=ecb)
|
||||
print("The root of this site is at", ecb.MapURLToPath("/"), 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 /PyISAPITest")
|
||||
|
||||
# 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="PyISAPITest",
|
||||
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