This file is indexed.

/usr/share/pyshared/cherrypy/filters/encodingfilter.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
import cherrypy
from basefilter import BaseFilter


class EncodingFilter(BaseFilter):
    """Filter that automatically encodes the response."""
    
    def before_finalize(self):
        conf = cherrypy.config.get
        if not conf('encoding_filter.on', False):
            return
        
        ct = cherrypy.response.headers.elements("Content-Type")
        if ct:
            ct = ct[0]
            if ct.value.lower().startswith("text/"):
                # Set "charset=..." param on response Content-Type header
                ct.params['charset'] = find_acceptable_charset()
                cherrypy.response.headers["Content-Type"] = str(ct)


def encode_stream(encoding, errors='strict'):
    """Encode a streaming response body.
    
    Use a generator wrapper, and just pray it works as the stream is
    being written out.
    """
    def encoder(body):
        for chunk in body:
            if isinstance(chunk, unicode):
                chunk = chunk.encode(encoding, errors)
            yield chunk
    cherrypy.response.body = encoder(cherrypy.response.body)
    return True

def encode_string(encoding, errors='strict'):
    """Encode a buffered response body."""
    try:
        body = []
        for chunk in cherrypy.response.body:
            if isinstance(chunk, unicode):
                chunk = chunk.encode(encoding, errors)
            body.append(chunk)
        cherrypy.response.body = body
        # Delete Content-Length header so finalize() recalcs it.
        cherrypy.response.headers.pop("Content-Length", None)
    except (LookupError, UnicodeError):
        return False
    else:
        return True

def find_acceptable_charset():
    conf = cherrypy.config.get
    response = cherrypy.response
    
    attempted_charsets = []
    
    stream = conf("stream_response", False)
    if stream:
        encode = encode_stream
    else:
        response.collapse_body()
        encode = encode_string
    
    failmsg = "The response could not be encoded with %s"
    
    errors = conf('encoding_filter.errors', 'strict')
    enc = conf('encoding_filter.encoding', None)
    if enc is not None:
        # If specified, force this encoding to be used, or fail.
        if encode(enc, errors):
            return enc
        else:
            raise cherrypy.HTTPError(500, failmsg % enc)
    
    # Parse the Accept_Charset request header, and try to provide one
    # of the requested charsets (in order of user preference).
    default_enc = conf('encoding_filter.default_encoding', 'utf-8')
    
    encs = cherrypy.request.headerMap.elements('Accept-Charset')
    if not encs:
        # Any character-set is acceptable.
        charsets = []
        if encode(default_enc, errors):
            return default_enc
        else:
            raise cherrypy.HTTPError(500, failmsg % default_enc)
    else:
        charsets = [enc.value.lower() for enc in encs]
        if "*" not in charsets:
            # If no "*" is present in an Accept-Charset field, then all
            # character sets not explicitly mentioned get a quality
            # value of 0, except for ISO-8859-1, which gets a quality
            # value of 1 if not explicitly mentioned.
            iso = 'iso-8859-1'
            if iso not in charsets:
                attempted_charsets.append(iso)
                if encode(iso, errors):
                    return iso
        
        for element in encs:
            if element.qvalue > 0:
                if element.value == "*":
                    # Matches any charset. Try our default.
                    if default_enc not in attempted_charsets:
                        attempted_charsets.append(default_enc)
                        if encode(default_enc, errors):
                            return default_enc
                else:
                    encoding = element.value
                    if encoding not in attempted_charsets:
                        attempted_charsets.append(encoding)
                        if encode(encoding, errors):
                            return encoding
    
    # No suitable encoding found.
    ac = cherrypy.request.headers.get('Accept-Charset')
    if ac is None:
        msg = "Your client did not send an Accept-Charset header."
    else:
        msg = "Your client sent this Accept-Charset header: %s." % ac
    msg += " We tried these charsets: %s." % ", ".join(attempted_charsets)
    raise cherrypy.HTTPError(406, msg)