Contact: fumanchu@aminus.org

Log in as guest/misc to create tickets

root/asp_gateway.py

Revision 72 (checked in by fumanchu, 7 years ago)

Fix for #2 (ASP gateway doesn't forward HTTP status code to ASP).

  • Property svn:eol-style set to native
Line 
1 """
2 WSGI wrapper for ASP.
3
4
5 Example Global.asa for a CherryPy app called "mcontrol":
6
7 <script language=Python runat=Server>
8 def Application_OnStart():
9     Application.Contents("multiprocess") = False
10     Application.Contents("multithread") = True
11     from mcontrol import chpy
12 </script>
13
14
15 Example handler.asp:
16
17 <%@Language=Python%>
18 <%
19 from wsgiref.asp_gateway import handler
20 from cherrypy.wsgiapp import wsgiApp
21
22 h = handler(Application, Request, Response)
23 h.run(wsgiApp)
24 Response.status = handler.status
25 %>
26
27 """
28
29 import sys
30 from wsgiref.handlers import BaseCGIHandler
31
32
33 class ASPInputWrapper(object):
34    
35     def __init__(self, Request):
36         self.stream = Request.BinaryRead
37         size = Request.ServerVariables('CONTENT_LENGTH')
38         self.remainder = self.size = int(size)
39    
40     def read(self, size=-1):
41         if size < 0:
42             size = self.remainder
43         content, size = self.stream(size)
44         self.remainder -= size
45         return str(content)
46    
47     def readline(self):
48         output = []
49         while True:
50             # Use an internal buffer instead? Still have to check for \n
51             char = self.read(1)
52             if not char:
53                 break
54             output.append(char)
55             if char in ('\n', '\r'):
56                 break
57         return ''.join(output)
58    
59     def readlines(self, hint=-1):
60         lines = []
61         while True:
62             line = self.readline()
63             if not line:
64                 break
65             lines.append(line)
66         return lines
67    
68     def __iter__(self):
69         line = self.readline()
70         while line:
71             yield line
72             # Notice this won't prefetch the next line; it only
73             # gets called if the generator is resumed.
74             line = self.readline()
75
76
77 class handler(BaseCGIHandler):
78    
79     def __init__(self, Application, Request, Response, buffering=True):
80         # If you set buffering to False, you must not "Enable Buffering" in
81         # the current Virtual Directory, NOR in any of its parent containers
82         # (directory, site, or server). IIS 5 and 6 buffer by default.
83         # See http://support.microsoft.com/default.aspx?scid=kb;en-us;Q306805
84         # and http://www.aspfaq.com/show.asp?id=2262
85         Response.Buffer = buffering
86        
87         env = {}
88         for name in Request.ServerVariables:
89             try:
90                 # names and values are both probably unicode. coerce them.
91                 env[str(name)] = str(Request.ServerVariables(name))
92             except UnicodeEncodeError, x:
93                 # There's a potential problem lurking here, since some ASP
94                 # server var's which are required by WSGI may be high ASCII.
95                 x.args += ((u"Server Variable '%s'" % name),)
96                 raise x
97        
98         multiprocess = str(Application.Contents("multiprocess"))
99         multithread = str(Application.Contents("multithread"))
100        
101         # You will probably need *some* form of rewriter to use ASP
102         # with WSGI, since ASP requires one physical .asp file
103         # per requestable-URL; so far, we support one:
104        
105         # Handle URL rewriting done by ISAPI_Rewrite Lite.
106         # http://www.isapirewrite.com/
107         # Note that PATH_TRANSLATED is also rewritten, but we
108         # don't make any provision for unmunging that.
109         old_path = env.get("HTTP_X_REWRITE_URL", None)
110         if old_path:
111             # Tear off any params.
112             env["PATH_INFO"] = old_path.split("?")[0]
113        
114         # ASP puts the same values in SCRIPT_NAME and PATH_INFO,
115         # for some odd reason. Empty one of them.
116         env["SCRIPT_NAME"] = ""
117        
118         BaseCGIHandler.__init__(self,
119                                 stdin=ASPInputWrapper(Request),
120                                 stdout=None,
121                                 stderr=sys.stderr,
122                                 environ=env,
123                                 multiprocess=multiprocess,
124                                 multithread=multithread
125                                 )
126        
127         self.Response = Response
128         self._write = Response.Write
129    
130     def _flush(self):
131         self.Response.Flush()
132    
133     def send_headers(self):
134         self.cleanup_headers()
135         self.headers_sent = True
136         for key, val in self.headers.items():
137             self.Response.AddHeader(key, val)
138    
139     def start_response(self, *args, **kwargs):
140         BaseCGIHandler.start_response(self, *args, **kwargs)
141         self.Response.Status = self.status
142
Note: See TracBrowser for help on using the browser.