You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
79 lines
2.8 KiB
79 lines
2.8 KiB
# 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)
|