Permalink
Browse files

git-svn-id: svn://cherokee-project.com/cherokee-pyscgi@504 5dc97367-9…

…7f1-0310-9951-d761b3857238
  • Loading branch information...
0 parents commit 2d940788929b2c20c2d4dd8821382e612f0cdb73 @alobbs alobbs committed Dec 10, 2006
Showing with 288 additions and 0 deletions.
  1. +1 −0 AUTHORS
  2. +5 −0 ChangeLog
  3. +29 −0 LICENSE
  4. +6 −0 MANIFEST.in
  5. +58 −0 README
  6. 0 pyscgi/__init__.py
  7. +106 −0 pyscgi/pyscgi.py
  8. +13 −0 setup.py
  9. +27 −0 tests/test1_env.py
  10. +43 −0 tests/test2_post.py
@@ -0,0 +1 @@
+Alvaro Lopez Ortega <alvaro@alobbs.com>
@@ -0,0 +1,5 @@
+2006-12-10 Alvaro Lopez Ortega <alvaro@alobbs.com>
+
+ * pyscgi/pyscgi.py, tests/test1_env.py, tests/test2_post.py: First
+ version.
+
@@ -0,0 +1,29 @@
+Copyright (c) 2006, Alvaro Lopez Ortega <alvaro@alobbs.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+* The name "Alvaro Lopez Ortega" may not be used to endorse or
+ promote products derived from this software without specific prior
+ written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,6 @@
+include README
+include LICENSE
+include ChangeLog
+include pyscgi/pyscgi.py
+include tests/test1_env.py
+include tests/test2_post.py
@@ -0,0 +1,58 @@
+Cherokee's SCGI Python implementation
+=====================================
+
+I have written this package because the original SCGI python module
+(written by Neil Schemenauer) didn't fit for my needs. The problem is
+that it depends on a C source file that needs to be compiled in order
+to make the module work, and even if Python provides tools for the
+task, it still makes the distribution a bit more difficult under some
+circumstances.
+
+This implementation of the SCGI protocol has been completely written
+in Python to easy as much as possible the deploy for SCGI based apps.
+
+This module is BSD licensed. Read the LICENSE file or the notice at
+the beginning of the source code files for more information.
+
+
+Tests
+=====
+There are a few tests programs for checking the module. Each one of
+them test an specific feature of the module.
+
+
+Configuration
+=============
+This module is suitable for all the web servers that support SCGI:
+Cherokee, Apache or any one else.
+
+However, here is an configuration example for Cherokee 0.6 (actually,
+this is what I've used to test it out):
+
+vserver!default!directory!/!handler = scgi
+vserver!default!directory!/!handler!balancer = round_robin
+vserver!default!directory!/!handler!balancer!type = interpreter
+vserver!default!directory!/!handler!balancer!local1!host = localhost:4000
+vserver!default!directory!/!priority = 99999
+
+Just write that on a file, lets suppose /var/tmp/test_scgi.conf, and
+execute Cherokee with the -C parameter to point to the configuration
+file:
+
+ # cherokee -C /var/tmp/test_scgi.conf
+
+Then, launch one of the test programs provided with this package. It
+will start a new SCGI server instance that will be used to execute the
+web server requests. Finally, go to your browser and try to browser
+and type http://localhost.
+
+
+References
+==========
+SCGI: http://www.mems-exchange.org/software/scgi/
+Cherokee: http://www.cherokee-project.com/
+
+
+--
+Alvaro Lopez Ortega
+<alvaro@alobbs.com>
No changes.
@@ -0,0 +1,106 @@
+"""
+pyscgi.py - Portable SCGI implementation
+
+This module has been written as part of the Cherokee project:
+ http://www.cherokee-project.com/
+"""
+
+# Copyright (c) 2006, Alvaro Lopez Ortega <alvaro@alobbs.com>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * The name "Alvaro Lopez Ortega" may not be used to endorse or
+# promote products derived from this software without specific prior
+# written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+
+import SocketServer
+
+__version__ = '1.0'
+__author__ = 'Alvaro Lopez Ortega'
+
+
+class SCGIHandler (SocketServer.BaseRequestHandler):
+ def __init__ (self, request, client_address, server):
+ self.env = {}
+ self.post = None
+ SocketServer.BaseRequestHandler.__init__ (self, request, client_address, server)
+
+ def __read_netstring_size (self):
+ size = ""
+ while 1:
+ c = self.input.read(1)
+ if c == ':':
+ break
+ elif not c:
+ raise IOError, 'Malformed netstring'
+ size += c
+ return long(size)
+
+ def __read_netstring (self):
+ data = ""
+ size = self.__read_netstring_size()
+ while size > 0:
+ s = self.input.read(size)
+ if not s:
+ raise IOError, 'Malformed netstring'
+ data += s
+ size -= len(s)
+ if self.input.read(1) != ',':
+ raise IOError, 'Missing netstring terminator'
+ return data
+
+ def __read_env (self):
+ headers = self.__read_netstring()
+ items = headers.split('\0')[:-1]
+ itemsn = len(items)
+ if itemsn % 2 != 0:
+ raise Exception, 'Malformed headers'
+ for i in range(0, itemsn, 2):
+ self.env[items[i]] = items[i+1]
+
+ def handle_post (self):
+ if not self.env.has_key('CONTENT_LENGTH'):
+ return
+ length = int(self.env['CONTENT_LENGTH'])
+ self.post = self.input.read(length)
+
+ def handle (self):
+ self.input = self.request.makefile('r')
+ self.output = self.request.makefile('w')
+
+ self.__read_env()
+ self.handle_request()
+ self.output.close()
+ self.input.close()
+
+ def handle_request (self):
+ self.output.write("Content-Type: text/plain\r\n\r\n")
+ self.output.write("handle_request() should be overridden")
+
+
+class SCGIServer(SocketServer.ThreadingTCPServer):
+ def __init__(self, handler_class=SCGIHandler, host="", port=4000):
+ self.allow_reuse_address = True
+ SocketServer.TCPServer.__init__ (self, (host, port), handler_class)
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+
+from distutils.core import setup
+from distutils.extension import Extension
+
+setup (name = "cherokee_pyscgi",
+ version = "1.0",
+ description = "Portable SCGI implementation",
+ author = "Alvaro Lopez Ortega",
+ author_email = "alvaro@alobbs.com",
+ url = "http://www.cherokee-project.com/",
+ license = "BSD. Read LICENSE for details.",
+ packages = ['pyscgi'])
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+
+from pyscgi import SCGIHandler, SCGIServer
+
+DEFAULT_PORT = 4000
+
+class MyHandler(SCGIHandler):
+ def __init__ (self, request, client_address, server):
+ SCGIHandler.__init__ (self, request, client_address, server)
+
+ def print_env (self):
+ self.output.write('<table border="0">')
+ for k, v in self.env.items():
+ self.output.write('<tr><td><b>%s</b></td><td>%r</td></tr>' % (k, v))
+ self.output.write('</table')
+
+ def handle_request (self):
+ self.output.write('Content-Type: text/html\r\n\r\n')
+ self.output.write('<h1>Environment variables</h1>')
+ self.print_env()
+
+def main():
+ srv = SCGIServer(handler_class=MyHandler, port=DEFAULT_PORT)
+ srv.serve_forever()
+
+if __name__ == "__main__":
+ main()
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+
+from pyscgi import SCGIHandler, SCGIServer
+
+DEFAULT_PORT = 4000
+POST_EXAMPLE = """
+<form method="post">
+ <table border="0">
+ <tr><td>Name</td> <td><input name="name"> </td></tr>
+ <tr><td>Surname</td><td><input name="surname"></td></tr>
+ <tr><td>Server</td> <td><select name="server">
+ <option value="cherokee1">Cherokee stable
+ <option value="cherokee2">Cherokee devel
+ </server></td></tr>
+ </table>
+ <input type="submit" value="Submit">
+</form>
+"""
+
+class MyHandler(SCGIHandler):
+ def __init__ (self, request, client_address, server):
+ SCGIHandler.__init__ (self, request, client_address, server)
+
+ def handle_request (self):
+ self.output.write('Content-Type: text/html\r\n\r\n')
+ self.output.write('<h1>Post test</h1>')
+
+ self.handle_post()
+
+ if self.post:
+ length = len(self.post)
+ if length > 0:
+ self.output.write('Post len: %d <br/>' % (length))
+ self.output.write('Post content: %s <br/>' % (self.post))
+ return
+ self.output.write(POST_EXAMPLE)
+
+def main():
+ srv = SCGIServer(handler_class=MyHandler, port=DEFAULT_PORT)
+ srv.serve_forever()
+
+if __name__ == "__main__":
+ main()

0 comments on commit 2d94078

Please sign in to comment.