mercurial/hgweb/wsgicgi.py
author Konstantin Zemlyak <zart@zartsoft.ru>
Mon, 22 Mar 2010 15:16:27 +0100
branchstable
changeset 10753 a1cb8ca051c0
parent 10339 23e608f42f2c
child 13570 617a87cb7eb2
permissions -rw-r--r--
wsgicgi: call close() on iterable to avoid resource leaks Quoting PEP 333 (WSGI): "If the iterable returned by the application has a close() method, the server or gateway must call that method upon completion of the current request, whether the request was completed normally, or terminated early due to an error. (This is to support resource release by the application. This protocol is intended to complement PEP 325's generator support, and other common iterables with close() methods."
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
     1
# hgweb/wsgicgi.py - CGI->WSGI translator
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
     2
#
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
     3
# Copyright 2006 Eric Hopper <hopper@omnifarious.org>
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
     4
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 7622
diff changeset
     5
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 10201
diff changeset
     6
# GNU General Public License version 2 or any later version.
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
     7
#
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
     8
# This was originally copied from the public domain code at
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
     9
# http://www.python.org/dev/peps/pep-0333/#the-server-gateway-side
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    10
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    11
import os, sys
4076
5a89c61c189c Switch CGI stdout to binary on windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
    12
from mercurial import util
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    13
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    14
def launch(application):
4484
7605da1c3b5c wsgicgi: change stdin to binary mode
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 4076
diff changeset
    15
    util.set_binary(sys.stdin)
4076
5a89c61c189c Switch CGI stdout to binary on windows
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 3673
diff changeset
    16
    util.set_binary(sys.stdout)
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    17
7622
4dd7b28003d2 use dict.iteritems() rather than dict.items()
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7406
diff changeset
    18
    environ = dict(os.environ.iteritems())
5580
f429e0e067a8 Fix style nit and add some comments to tests.
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5579
diff changeset
    19
    environ.setdefault('PATH_INFO', '')
10201
d2847c4523e8 hgweb: improve IIS PATH_INFO fix ee8af8a4d905 (issue1580)
Patrick Mezard <pmezard@gmail.com>
parents: 8225
diff changeset
    20
    if environ.get('SERVER_SOFTWARE', '').startswith('Microsoft-IIS'):
d2847c4523e8 hgweb: improve IIS PATH_INFO fix ee8af8a4d905 (issue1580)
Patrick Mezard <pmezard@gmail.com>
parents: 8225
diff changeset
    21
        # IIS includes script_name in path_info
d2847c4523e8 hgweb: improve IIS PATH_INFO fix ee8af8a4d905 (issue1580)
Patrick Mezard <pmezard@gmail.com>
parents: 8225
diff changeset
    22
        scriptname = environ['SCRIPT_NAME']
d2847c4523e8 hgweb: improve IIS PATH_INFO fix ee8af8a4d905 (issue1580)
Patrick Mezard <pmezard@gmail.com>
parents: 8225
diff changeset
    23
        if environ['PATH_INFO'].startswith(scriptname):
d2847c4523e8 hgweb: improve IIS PATH_INFO fix ee8af8a4d905 (issue1580)
Patrick Mezard <pmezard@gmail.com>
parents: 8225
diff changeset
    24
            environ['PATH_INFO'] = environ['PATH_INFO'][len(scriptname):]
7406
ee8af8a4d905 hgweb: support broken IIS 5 behavior with .cgi in PATH_INFO
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7008
diff changeset
    25
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    26
    environ['wsgi.input'] = sys.stdin
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    27
    environ['wsgi.errors'] = sys.stderr
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    28
    environ['wsgi.version'] = (1, 0)
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    29
    environ['wsgi.multithread'] = False
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    30
    environ['wsgi.multiprocess'] = True
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    31
    environ['wsgi.run_once'] = True
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    32
10339
23e608f42f2c fix spaces/identation issues
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 10263
diff changeset
    33
    if environ.get('HTTPS', 'off').lower() in ('on', '1', 'yes'):
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    34
        environ['wsgi.url_scheme'] = 'https'
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    35
    else:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    36
        environ['wsgi.url_scheme'] = 'http'
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    37
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    38
    headers_set = []
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    39
    headers_sent = []
2558
1120302009d7 hgweb: fix unbundle.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2506
diff changeset
    40
    out = sys.stdout
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    41
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    42
    def write(data):
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    43
        if not headers_set:
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    44
            raise AssertionError("write() before start_response()")
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    45
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    46
        elif not headers_sent:
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    47
            # Before the first output, send the stored headers
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    48
            status, response_headers = headers_sent[:] = headers_set
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    49
            out.write('Status: %s\r\n' % status)
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    50
            for header in response_headers:
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    51
                out.write('%s: %s\r\n' % header)
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    52
            out.write('\r\n')
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    53
2558
1120302009d7 hgweb: fix unbundle.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2506
diff changeset
    54
        out.write(data)
1120302009d7 hgweb: fix unbundle.
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 2506
diff changeset
    55
        out.flush()
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    56
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    57
    def start_response(status, response_headers, exc_info=None):
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    58
        if exc_info:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    59
            try:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    60
                if headers_sent:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    61
                    # Re-raise original exception if headers sent
7008
8fee8ff13d37 use Exception(args)-style raising consistently (py3k compatibility)
Peter Ruibal <peter.ruibal@intel.com>
parents: 6922
diff changeset
    62
                    raise exc_info[0](exc_info[1], exc_info[2])
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    63
            finally:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    64
                exc_info = None     # avoid dangling circular ref
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    65
        elif headers_set:
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    66
            raise AssertionError("Headers already set!")
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    67
3673
eb0b4a2d70a9 white space and line break cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 2558
diff changeset
    68
        headers_set[:] = [status, response_headers]
2506
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    69
        return write
d0db3462d568 This patch make several WSGI related alterations.
Eric Hopper <hopper@omnifarious.org>
parents:
diff changeset
    70
6922
1ec2d227a521 hgweb: fix WSGI iterators handling in CGI adapter (issue1254)
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 5580
diff changeset
    71
    content = application(environ, start_response)
10753
a1cb8ca051c0 wsgicgi: call close() on iterable to avoid resource leaks
Konstantin Zemlyak <zart@zartsoft.ru>
parents: 10339
diff changeset
    72
    try:
a1cb8ca051c0 wsgicgi: call close() on iterable to avoid resource leaks
Konstantin Zemlyak <zart@zartsoft.ru>
parents: 10339
diff changeset
    73
        for chunk in content:
a1cb8ca051c0 wsgicgi: call close() on iterable to avoid resource leaks
Konstantin Zemlyak <zart@zartsoft.ru>
parents: 10339
diff changeset
    74
            write(chunk)
a1cb8ca051c0 wsgicgi: call close() on iterable to avoid resource leaks
Konstantin Zemlyak <zart@zartsoft.ru>
parents: 10339
diff changeset
    75
    finally:
a1cb8ca051c0 wsgicgi: call close() on iterable to avoid resource leaks
Konstantin Zemlyak <zart@zartsoft.ru>
parents: 10339
diff changeset
    76
        if hasattr(content, 'close'):
a1cb8ca051c0 wsgicgi: call close() on iterable to avoid resource leaks
Konstantin Zemlyak <zart@zartsoft.ru>
parents: 10339
diff changeset
    77
            content.close()