extension_simple.py 4.4 KB

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