summaryrefslogtreecommitdiff
path: root/paste/cgiapp.py
diff options
context:
space:
mode:
authorianb <devnull@localhost>2005-08-15 16:49:21 +0000
committerianb <devnull@localhost>2005-08-15 16:49:21 +0000
commit855296d30ad93e655ef75812d9f1a96bc629d4da (patch)
tree46ce6255d1be8678e8aa99c0b187b2a55e62027a /paste/cgiapp.py
parentb146bb5a4942bf2f531975068357de35197d9a17 (diff)
downloadpaste-855296d30ad93e655ef75812d9f1a96bc629d4da.tar.gz
Added CGI proxy application
Diffstat (limited to 'paste/cgiapp.py')
-rw-r--r--paste/cgiapp.py88
1 files changed, 88 insertions, 0 deletions
diff --git a/paste/cgiapp.py b/paste/cgiapp.py
new file mode 100644
index 0000000..edc156a
--- /dev/null
+++ b/paste/cgiapp.py
@@ -0,0 +1,88 @@
+"""
+Application that runs a CGI script.
+"""
+import os
+import subprocess
+
+__all__ = ['CGIError', 'CGIApplication']
+
+class CGIError(Exception):
+ pass
+
+class CGIApplication(object):
+
+ """
+ This object acts as a proxy to a CGI application. You pass in the
+ script path (``script``), an optional path to search for the
+ script (if the name isn't absolute) (``path``). If you don't give
+ a path, then ``$PATH`` will be used.
+ """
+
+ def __init__(self, script, path=None,
+ include_os_environ=True):
+ self.script_filename = script
+ if isinstance(path, (str, unicode)):
+ path = [path]
+ if path is None:
+ path = os.environ.get('PATH', '').split(':')
+ self.path = path
+ if os.path.abspath(script) != script:
+ # relative path
+ for path_dir in self.path:
+ if os.path.exists(os.path.join(path_dir, script)):
+ self.script = os.path.join(path_dir, script)
+ break
+ else:
+ raise CGIError(
+ "Script %r not found in path %r"
+ % (script, self.path))
+ else:
+ self.script = script
+ self.include_os_environ = include_os_environ
+
+ def __call__(self, environ, start_response):
+ if self.include_os_environ:
+ cgi_environ = os.environ.copy()
+ else:
+ cgi_environ = {}
+ for name in environ:
+ # Should unicode values be encoded?
+ if (name.upper() == name
+ and isinstance(environ[name], str)):
+ cgi_environ[name] = environ[name]
+ # Default status in CGI:
+ status = '200 OK'
+ headers = []
+ proc = subprocess.Popen(
+ [self.script],
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ env=cgi_environ,
+ cwd=os.path.dirname(self.script),
+ )
+ proc.stdin.write(environ['wsgi.input'].read())
+ stdout = proc.stdout
+ while 1:
+ line = stdout.readline()
+ line = line.rstrip('\n').rstrip('\r')
+ if not line:
+ break
+ if ':' not in line:
+ raise CGIError(
+ "Bad header line: %r" % line)
+ name, value = line.split(':', 1)
+ value = value.lstrip()
+ name = name.strip()
+ if name.lower() == 'status':
+ status = value
+ else:
+ headers.append((name, value))
+ writer = start_response(status, headers)
+ while 1:
+ data = stdout.read(4096)
+ if not data:
+ break
+ writer(data)
+ environ['wsgi.errors'].write(proc.stderr.read())
+ return []