This file is indexed.

/usr/share/pyshared/cherrypy/filters/wsgiappfilter.py is in python-cherrypy 2.3.0-3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
"""a WSGI application filter for CherryPy

also see cherrypy.lib.cptools.WSGIApp"""

# by Christian Wyglendowski

import sys

import cherrypy
from cherrypy.filters.basefilter import BaseFilter
from cherrypy._cputil import get_object_trail


# is this sufficient for start_response?
def start_response(status, response_headers, exc_info=None):
    cherrypy.response.status = status
    headers_dict = dict(response_headers)
    cherrypy.response.headers.update(headers_dict)

def get_path_components(path):
    """returns (script_name, path_info)

    determines what part of the path belongs to cp (script_name)
    and what part belongs to the wsgi application (path_info)
    """
    no_parts = ['']
    object_trail = get_object_trail(path)
    root = object_trail.pop(0)
    if not path.endswith('/index'):
        object_trail.pop()
    script_name_parts = [""]
    path_info_parts = [""]
    for (pc,obj) in object_trail:
        if obj:
            script_name_parts.append(pc)
        else:
            path_info_parts.append(pc)
    script_name = "/".join(script_name_parts)
    path_info = "/".join(path_info_parts)
    if len(script_name) > 1 and path.endswith('/'):
        path_info = path_info + '/'
    
    if script_name and not script_name.startswith('/'):
        script_name = '/' + script_name
    if path_info and not path_info.startswith('/'):
        path_info = '/' + path_info
    
    return script_name, path_info

def make_environ():
    """grabbed some of below from _cpwsgiserver.py
    
    for hosting WSGI apps in non-WSGI environments (yikes!)
    """

    script_name, path_info = get_path_components(cherrypy.request.path)
    
    # create and populate the wsgi environment
    environ = dict()
    environ["wsgi.version"] = (1,0)
    environ["wsgi.url_scheme"] = cherrypy.request.scheme
    environ["wsgi.input"] = cherrypy.request.rfile
    environ["wsgi.errors"] = sys.stderr
    environ["wsgi.multithread"] = True
    environ["wsgi.multiprocess"] = False
    environ["wsgi.run_once"] = False
    environ["REQUEST_METHOD"] = cherrypy.request.method
    environ["SCRIPT_NAME"] = script_name
    environ["PATH_INFO"] = path_info
    environ["QUERY_STRING"] = cherrypy.request.queryString
    environ["SERVER_PROTOCOL"] = cherrypy.request.version
    server_name = getattr(cherrypy.server.httpserver, 'server_name', "None")
    environ["SERVER_NAME"] = server_name 
    environ["SERVER_PORT"] = cherrypy.config.get('server.socketPort')
    environ["REMOTE_HOST"] = cherrypy.request.remoteHost
    environ["REMOTE_ADDR"] = cherrypy.request.remoteAddr
    environ["REMOTE_PORT"] = cherrypy.request.remotePort
    # then all the http headers
    headers = cherrypy.request.headers
    environ["CONTENT_TYPE"] = headers.get("Content-type", "")
    environ["CONTENT_LENGTH"] = headers.get("Content-length", "")
    for (k, v) in headers.iteritems():
        envname = "HTTP_" + k.upper().replace("-","_")
        environ[envname] = v
    return environ


class WSGIAppFilter(BaseFilter):
    """A filter for running any WSGI middleware/application within CP.

    Here are the parameters:

    wsgi_app - any wsgi application callable
    env_update - a dictionary with arbitrary keys and values to be 
                 merged with the WSGI environment dictionary.

    Example:
    
    class Whatever:
        _cp_filters = [WSGIAppFilter(some_app)]
    """

    def __init__(self, wsgi_app, env_update=None):
        self.app = wsgi_app
        self.env_update = env_update or {}
   
    def before_request_body(self):
        
        # keep the request body intact so the wsgi app
        # can have its way with it
        cherrypy.request.processRequestBody = False

    def before_main(self):
        """run the wsgi_app and set response.body to its output
        """
        
        request = cherrypy.request
        # if the static filter is on for this path and
        # request.execute_main is False, assume that the
        # static filter has already taken care of this request
        staticfilter_on = cherrypy.config.get('static_filter.on', False)
        if staticfilter_on and not request.execute_main:
            return

        try:
            environ = request.wsgi_environ
            sn, pi = get_path_components(request.path)
            environ['SCRIPT_NAME'] = sn
            environ['PATH_INFO'] = pi
        except AttributeError:
            environ = make_environ()

        # update the environ with the dict passed to the filter's
        # constructor
        environ.update(self.env_update)

        # run the wsgi app and have it set response.body
        response = self.app(environ, start_response)
        try:
            cherrypy.response.body = response
        finally:
            if hasattr(response, "close"):
                response.close()
        
        # tell CP not to handle the request further
        request.execute_main = False


if __name__ == '__main__':

    def my_app(environ, start_response):
        status = '200 OK'
        response_headers = [('Content-type', 'text/plain')]
        start_response(status, response_headers)
        yield 'Hello, world!\n'
        yield 'This is a wsgi app running within CherryPy!\n\n'
        keys = environ.keys()
        keys.sort()
        for k in keys:
            yield '%s: %s\n' % (k,environ[k])

    class Root(object):
        def index(self):
            yield "<h1>Hi, from CherryPy!</h1>"
            yield "<a href='app'>A non-CP WSGI app</a><br>"
            yield "<br>"
            yield "SCRIPT_NAME and PATH_INFO get set "
            yield "<a href='app/this/n/that'>properly</a>"
        index.exposed = True

    class HostedWSGI(object):
        _cp_filters = [WSGIAppFilter(my_app, {'cherrypy.wsgi':True,}),]

    # mount standard CherryPy app
    cherrypy.tree.mount(Root(), '/')
    # mount the WSGI app
    cherrypy.tree.mount(HostedWSGI(), '/app')

    cherrypy.server.start()