1 # This is an ISAPI extension purely for testing purposes. It is NOT 2 # a 'demo' (even though it may be useful!) 3 # 4 # Install this extension, then point your browser to: 5 # "http://localhost/pyisapi_test/test1" 6 # This will execute the method 'test1' below. See below for the list of 7 # test methods that are acceptable. 8 9 # If we have no console (eg, am running from inside IIS), redirect output 10 # somewhere useful - in this case, the standard win32 trace collector. 11 import win32api 12 import winerror 13 14 from isapi import ExtensionError, threaded_extension 15 16 try: 17 win32api.GetConsoleTitle() 18 except win32api.error: 19 # No console - redirect 20 import win32traceutil 21 22 23 # The ISAPI extension - handles requests in our virtual dir, and sends the 24 # response to the client. 25 class Extension(threaded_extension.ThreadPoolExtension): 26 "Python ISAPI Tester" 27 28 def Dispatch(self, ecb): 29 print('Tester dispatching "{}"'.format(ecb.GetServerVariable("URL"))) 30 url = ecb.GetServerVariable("URL") 31 test_name = url.split("/")[-1] 32 meth = getattr(self, test_name, None) 33 if meth is None: 34 raise AttributeError(f"No test named '{test_name}'") 35 result = meth(ecb) 36 if result is None: 37 # This means the test finalized everything 38 return 39 ecb.SendResponseHeaders("200 OK", "Content-type: text/html\r\n\r\n", False) 40 print("<HTML><BODY>Finished running test <i>", test_name, "</i>", file=ecb) 41 print("<pre>", file=ecb) 42 print(result, file=ecb) 43 print("</pre>", file=ecb) 44 print("</BODY></HTML>", file=ecb) 45 ecb.DoneWithSession() 46 47 def test1(self, ecb): 48 try: 49 ecb.GetServerVariable("foo bar") 50 raise AssertionError("should have failed!") 51 except ExtensionError as err: 52 assert err.errno == winerror.ERROR_INVALID_INDEX, err 53 return "worked!" 54 55 def test_long_vars(self, ecb): 56 qs = ecb.GetServerVariable("QUERY_STRING") 57 # Our implementation has a default buffer size of 8k - so we test 58 # the code that handles an overflow by ensuring there are more 59 # than 8k worth of chars in the URL. 60 expected_query = "x" * 8500 61 if len(qs) == 0: 62 # Just the URL with no query part - redirect to myself, but with 63 # a huge query portion. 64 me = ecb.GetServerVariable("URL") 65 headers = "Location: " + me + "?" + expected_query + "\r\n\r\n" 66 ecb.SendResponseHeaders("301 Moved", headers) 67 ecb.DoneWithSession() 68 return None 69 if qs == expected_query: 70 return "Total length of variable is %d - test worked!" % (len(qs),) 71 else: 72 return "Unexpected query portion! Got %d chars, expected %d" % ( 73 len(qs), 74 len(expected_query), 75 ) 76 77 def test_unicode_vars(self, ecb): 78 # We need to check that we are running IIS6! This seems the only 79 # effective way from an extension. 80 ver = float(ecb.GetServerVariable("SERVER_SOFTWARE").split("/")[1]) 81 if ver < 6.0: 82 return "This is IIS version %g - unicode only works in IIS6 and later" % ver 83 84 us = ecb.GetServerVariable("UNICODE_SERVER_NAME") 85 assert isinstance(us, str), "unexpected type!" 86 assert us == str( 87 ecb.GetServerVariable("SERVER_NAME") 88 ), "Unicode and non-unicode values were not the same" 89 return "worked!" 90 91 92 # The entry points for the ISAPI extension. 93 def __ExtensionFactory__(): 94 return Extension() 95 96 97 if __name__ == "__main__": 98 # If run from the command-line, install ourselves. 99 from isapi.install import * 100 101 params = ISAPIParameters() 102 # Setup the virtual directories - this is a list of directories our 103 # extension uses - in this case only 1. 104 # Each extension has a "script map" - this is the mapping of ISAPI 105 # extensions. 106 sm = [ScriptMapParams(Extension="*", Flags=0)] 107 vd = VirtualDirParameters( 108 Name="pyisapi_test", 109 Description=Extension.__doc__, 110 ScriptMaps=sm, 111 ScriptMapUpdate="replace", 112 ) 113 params.VirtualDirs = [vd] 114 HandleCommandLine(params) 115