Format: text/x-python
⬇ Download File (4.2 KB)
   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