def __init__(self, environ):
        self.environ = environ
        # This isn't "state" really, since the object is derivative:
        self.headers = EnvironHeaders(environ)

        defaults = self.defaults._current_obj()
        self.charset = defaults.get('charset')
        if self.charset:
            # There's a charset: params will be coerced to unicode. In that
            # case, attempt to use the charset specified by the browser
            browser_charset = self.determine_browser_charset()
            if browser_charset:
                self.charset = browser_charset
        self.errors = defaults.get('errors', 'strict')
        self.decode_param_names = defaults.get('decode_param_names', False)
        self._languages = None
 def __init__(self, environ):
     self.environ = environ
     # This isn't "state" really, since the object is derivative:
     self.headers = EnvironHeaders(environ)
     
     defaults = self.defaults._current_obj()
     self.charset = defaults.get('charset')
     if self.charset:
         # There's a charset: params will be coerced to unicode. In that
         # case, attempt to use the charset specified by the browser
         browser_charset = self.determine_browser_charset()
         if browser_charset:
             self.charset = browser_charset
     self.errors = defaults.get('errors', 'strict')
     self.decode_param_names = defaults.get('decode_param_names', False)
     self._languages = None
class WSGIRequest(object):
    """WSGI Request API Object

    This object represents a WSGI request with a more friendly interface.
    This does not expose every detail of the WSGI environment, and attempts
    to express nothing beyond what is available in the environment
    dictionary.

    The only state maintained in this object is the desired ``charset``,
    its associated ``errors`` handler, and the ``decode_param_names``
    option.

    The incoming parameter values will be automatically coerced to unicode
    objects of the ``charset`` encoding when ``charset`` is set. The
    incoming parameter names are not decoded to unicode unless the
    ``decode_param_names`` option is enabled.

    When unicode is expected, ``charset`` will overridden by the the
    value of the ``Content-Type`` header's charset parameter if one was
    specified by the client.

    The class variable ``defaults`` specifies default values for
    ``charset``, ``errors``, and ``langauge``. These can be overridden for the
    current request via the registry.

    The ``language`` default value is considered the fallback during i18n
    translations to ensure in odd cases that mixed languages don't occur should
    the ``language`` file contain the string but not another language in the
    accepted languages list. The ``language`` value only applies when getting
    a list of accepted languages from the HTTP Accept header.

    This behavior is duplicated from Aquarium, and may seem strange but is
    very useful. Normally, everything in the code is in "en-us".  However,
    the "en-us" translation catalog is usually empty.  If the user requests
    ``["en-us", "zh-cn"]`` and a translation isn't found for a string in
    "en-us", you don't want gettext to fallback to "zh-cn".  You want it to
    just use the string itself.  Hence, if a string isn't found in the
    ``language`` catalog, the string in the source code will be used.

    *All* other state is kept in the environment dictionary; this is
    essential for interoperability.

    You are free to subclass this object.

    """
    defaults = StackedObjectProxy(default=dict(charset=None,
                                               errors='replace',
                                               decode_param_names=False,
                                               language='en-us'))

    def __init__(self, environ):
        self.environ = environ
        # This isn't "state" really, since the object is derivative:
        self.headers = EnvironHeaders(environ)

        defaults = self.defaults._current_obj()
        self.charset = defaults.get('charset')
        if self.charset:
            # There's a charset: params will be coerced to unicode. In that
            # case, attempt to use the charset specified by the browser
            browser_charset = self.determine_browser_charset()
            if browser_charset:
                self.charset = browser_charset
        self.errors = defaults.get('errors', 'strict')
        self.decode_param_names = defaults.get('decode_param_names', False)
        self._languages = None

    body = environ_getter('wsgi.input')
    scheme = environ_getter('wsgi.url_scheme')
    method = environ_getter('REQUEST_METHOD')
    script_name = environ_getter('SCRIPT_NAME')
    path_info = environ_getter('PATH_INFO')

    def urlvars(self):
        """
        Return any variables matched in the URL (e.g.,
        ``wsgiorg.routing_args``).
        """
        if 'paste.urlvars' in self.environ:
            return self.environ['paste.urlvars']
        elif 'wsgiorg.routing_args' in self.environ:
            return self.environ['wsgiorg.routing_args'][1]
        else:
            return {}

    urlvars = property(urlvars, doc=urlvars.__doc__)

    def is_xhr(self):
        """Returns a boolean if X-Requested-With is present and a XMLHttpRequest"""
        return self.environ.get('HTTP_X_REQUESTED_WITH',
                                '') == 'XMLHttpRequest'

    is_xhr = property(is_xhr, doc=is_xhr.__doc__)

    def host(self):
        """Host name provided in HTTP_HOST, with fall-back to SERVER_NAME"""
        return self.environ.get('HTTP_HOST', self.environ.get('SERVER_NAME'))

    host = property(host, doc=host.__doc__)

    def languages(self):
        """Return a list of preferred languages, most preferred first.

        The list may be empty.
        """
        if self._languages is not None:
            return self._languages
        acceptLanguage = self.environ.get('HTTP_ACCEPT_LANGUAGE')
        langs = ACCEPT_LANGUAGE.parse(self.environ)
        fallback = self.defaults.get('language', 'en-us')
        if not fallback:
            return langs
        if fallback not in langs:
            langs.append(fallback)
        index = langs.index(fallback)
        langs[index + 1:] = []
        self._languages = langs
        return self._languages

    languages = property(languages, doc=languages.__doc__)

    def _GET(self):
        return parse_dict_querystring(self.environ)

    def GET(self):
        """
        Dictionary-like object representing the QUERY_STRING
        parameters. Always present, if possibly empty.

        If the same key is present in the query string multiple times, a
        list of its values can be retrieved from the ``MultiDict`` via
        the ``getall`` method.

        Returns a ``MultiDict`` container or a ``UnicodeMultiDict`` when
        ``charset`` is set.
        """
        params = self._GET()
        if self.charset:
            params = UnicodeMultiDict(params,
                                      encoding=self.charset,
                                      errors=self.errors,
                                      decode_keys=self.decode_param_names)
        return params

    GET = property(GET, doc=GET.__doc__)

    def _POST(self):
        return parse_formvars(self.environ, include_get_vars=False)

    def POST(self):
        """Dictionary-like object representing the POST body.

        Most values are encoded strings, or unicode strings when
        ``charset`` is set. There may also be FieldStorage objects
        representing file uploads. If this is not a POST request, or the
        body is not encoded fields (e.g., an XMLRPC request) then this
        will be empty.

        This will consume wsgi.input when first accessed if applicable,
        but the raw version will be put in
        environ['paste.parsed_formvars'].

        Returns a ``MultiDict`` container or a ``UnicodeMultiDict`` when
        ``charset`` is set.
        """
        params = self._POST()
        if self.charset:
            params = UnicodeMultiDict(params,
                                      encoding=self.charset,
                                      errors=self.errors,
                                      decode_keys=self.decode_param_names)
        return params

    POST = property(POST, doc=POST.__doc__)

    def params(self):
        """Dictionary-like object of keys from POST, GET, URL dicts

        Return a key value from the parameters, they are checked in the
        following order: POST, GET, URL

        Additional methods supported:

        ``getlist(key)``
            Returns a list of all the values by that key, collected from
            POST, GET, URL dicts

        Returns a ``MultiDict`` container or a ``UnicodeMultiDict`` when
        ``charset`` is set.
        """
        params = MultiDict()
        params.update(self._POST())
        params.update(self._GET())
        if self.charset:
            params = UnicodeMultiDict(params,
                                      encoding=self.charset,
                                      errors=self.errors,
                                      decode_keys=self.decode_param_names)
        return params

    params = property(params, doc=params.__doc__)

    def cookies(self):
        """Dictionary of cookies keyed by cookie name.

        Just a plain dictionary, may be empty but not None.

        """
        return get_cookie_dict(self.environ)

    cookies = property(cookies, doc=cookies.__doc__)

    def determine_browser_charset(self):
        """
        Determine the encoding as specified by the browser via the
        Content-Type's charset parameter, if one is set
        """
        charset_match = _CHARSET_RE.search(self.headers.get(
            'Content-Type', ''))
        if charset_match:
            return charset_match.group(1)

    def match_accept(self, mimetypes):
        """Return a list of specified mime-types that the browser's HTTP Accept
        header allows in the order provided."""
        return desired_matches(mimetypes,
                               self.environ.get('HTTP_ACCEPT', '*/*'))

    def __repr__(self):
        """Show important attributes of the WSGIRequest"""
        pf = pformat
        msg = '<%s.%s object at 0x%x method=%s,' % \
            (self.__class__.__module__, self.__class__.__name__,
             id(self), pf(self.method))
        msg += '\nscheme=%s, host=%s, script_name=%s, path_info=%s,' % \
            (pf(self.scheme), pf(self.host), pf(self.script_name),
             pf(self.path_info))
        msg += '\nlanguages=%s,' % pf(self.languages)
        if self.charset:
            msg += ' charset=%s, errors=%s,' % (pf(
                self.charset), pf(self.errors))
        msg += '\nGET=%s,' % pf(self.GET)
        msg += '\nPOST=%s,' % pf(self.POST)
        msg += '\ncookies=%s>' % pf(self.cookies)
        return msg
class WSGIRequest(object):
    """WSGI Request API Object

    This object represents a WSGI request with a more friendly interface.
    This does not expose every detail of the WSGI environment, and attempts
    to express nothing beyond what is available in the environment
    dictionary.

    The only state maintained in this object is the desired ``charset``,
    its associated ``errors`` handler, and the ``decode_param_names``
    option.

    The incoming parameter values will be automatically coerced to unicode
    objects of the ``charset`` encoding when ``charset`` is set. The
    incoming parameter names are not decoded to unicode unless the
    ``decode_param_names`` option is enabled.

    When unicode is expected, ``charset`` will overridden by the the
    value of the ``Content-Type`` header's charset parameter if one was
    specified by the client.

    The class variable ``defaults`` specifies default values for
    ``charset``, ``errors``, and ``langauge``. These can be overridden for the
    current request via the registry.
        
    The ``language`` default value is considered the fallback during i18n
    translations to ensure in odd cases that mixed languages don't occur should
    the ``language`` file contain the string but not another language in the
    accepted languages list. The ``language`` value only applies when getting
    a list of accepted languages from the HTTP Accept header.
    
    This behavior is duplicated from Aquarium, and may seem strange but is
    very useful. Normally, everything in the code is in "en-us".  However, 
    the "en-us" translation catalog is usually empty.  If the user requests
    ``["en-us", "zh-cn"]`` and a translation isn't found for a string in
    "en-us", you don't want gettext to fallback to "zh-cn".  You want it to 
    just use the string itself.  Hence, if a string isn't found in the
    ``language`` catalog, the string in the source code will be used.

    *All* other state is kept in the environment dictionary; this is
    essential for interoperability.

    You are free to subclass this object.

    """
    defaults = StackedObjectProxy(default=dict(charset=None, errors='replace',
                                               decode_param_names=False,
                                               language='en-us'))
    def __init__(self, environ):
        self.environ = environ
        # This isn't "state" really, since the object is derivative:
        self.headers = EnvironHeaders(environ)
        
        defaults = self.defaults._current_obj()
        self.charset = defaults.get('charset')
        if self.charset:
            # There's a charset: params will be coerced to unicode. In that
            # case, attempt to use the charset specified by the browser
            browser_charset = self.determine_browser_charset()
            if browser_charset:
                self.charset = browser_charset
        self.errors = defaults.get('errors', 'strict')
        self.decode_param_names = defaults.get('decode_param_names', False)
        self._languages = None
    
    body = environ_getter('wsgi.input')
    scheme = environ_getter('wsgi.url_scheme')
    method = environ_getter('REQUEST_METHOD')
    script_name = environ_getter('SCRIPT_NAME')
    path_info = environ_getter('PATH_INFO')

    def urlvars(self):
        """
        Return any variables matched in the URL (e.g.,
        ``wsgiorg.routing_args``).
        """
        if 'paste.urlvars' in self.environ:
            return self.environ['paste.urlvars']
        elif 'wsgiorg.routing_args' in self.environ:
            return self.environ['wsgiorg.routing_args'][1]
        else:
            return {}
    urlvars = property(urlvars, doc=urlvars.__doc__)
    
    def is_xhr(self):
        """Returns a boolean if X-Requested-With is present and a XMLHttpRequest"""
        return self.environ.get('HTTP_X_REQUESTED_WITH', '') == 'XMLHttpRequest'
    is_xhr = property(is_xhr, doc=is_xhr.__doc__)
    
    def host(self):
        """Host name provided in HTTP_HOST, with fall-back to SERVER_NAME"""
        return self.environ.get('HTTP_HOST', self.environ.get('SERVER_NAME'))
    host = property(host, doc=host.__doc__)

    def languages(self):
        """Return a list of preferred languages, most preferred first.
        
        The list may be empty.
        """
        if self._languages is not None:
            return self._languages
        acceptLanguage = self.environ.get('HTTP_ACCEPT_LANGUAGE')
        langs = ACCEPT_LANGUAGE.parse(self.environ)
        fallback = self.defaults.get('language', 'en-us')
        if not fallback:
            return langs
        if fallback not in langs:
            langs.append(fallback)
        index = langs.index(fallback)
        langs[index+1:] = []
        self._languages = langs
        return self._languages
    languages = property(languages, doc=languages.__doc__)
    
    def _GET(self):
        return parse_dict_querystring(self.environ)

    def GET(self):
        """
        Dictionary-like object representing the QUERY_STRING
        parameters. Always present, if possibly empty.

        If the same key is present in the query string multiple times, a
        list of its values can be retrieved from the ``MultiDict`` via
        the ``getall`` method.

        Returns a ``MultiDict`` container or a ``UnicodeMultiDict`` when
        ``charset`` is set.
        """
        params = self._GET()
        if self.charset:
            params = UnicodeMultiDict(params, encoding=self.charset,
                                      errors=self.errors,
                                      decode_keys=self.decode_param_names)
        return params
    GET = property(GET, doc=GET.__doc__)

    def _POST(self):
        return parse_formvars(self.environ, include_get_vars=False)

    def POST(self):
        """Dictionary-like object representing the POST body.

        Most values are encoded strings, or unicode strings when
        ``charset`` is set. There may also be FieldStorage objects
        representing file uploads. If this is not a POST request, or the
        body is not encoded fields (e.g., an XMLRPC request) then this
        will be empty.

        This will consume wsgi.input when first accessed if applicable,
        but the raw version will be put in
        environ['paste.parsed_formvars'].

        Returns a ``MultiDict`` container or a ``UnicodeMultiDict`` when
        ``charset`` is set.
        """
        params = self._POST()
        if self.charset:
            params = UnicodeMultiDict(params, encoding=self.charset,
                                      errors=self.errors,
                                      decode_keys=self.decode_param_names)
        return params
    POST = property(POST, doc=POST.__doc__)

    def params(self):
        """Dictionary-like object of keys from POST, GET, URL dicts

        Return a key value from the parameters, they are checked in the
        following order: POST, GET, URL

        Additional methods supported:

        ``getlist(key)``
            Returns a list of all the values by that key, collected from
            POST, GET, URL dicts

        Returns a ``MultiDict`` container or a ``UnicodeMultiDict`` when
        ``charset`` is set.
        """
        params = MultiDict()
        params.update(self._POST())
        params.update(self._GET())
        if self.charset:
            params = UnicodeMultiDict(params, encoding=self.charset,
                                      errors=self.errors,
                                      decode_keys=self.decode_param_names)
        return params
    params = property(params, doc=params.__doc__)

    def cookies(self):
        """Dictionary of cookies keyed by cookie name.

        Just a plain dictionary, may be empty but not None.
        
        """
        return get_cookie_dict(self.environ)
    cookies = property(cookies, doc=cookies.__doc__)

    def determine_browser_charset(self):
        """
        Determine the encoding as specified by the browser via the
        Content-Type's charset parameter, if one is set
        """
        charset_match = _CHARSET_RE.search(self.headers.get('Content-Type', ''))
        if charset_match:
            return charset_match.group(1)

    def match_accept(self, mimetypes):
        """Return a list of specified mime-types that the browser's HTTP Accept
        header allows in the order provided."""
        return desired_matches(mimetypes, 
                               self.environ.get('HTTP_ACCEPT', '*/*'))

    def __repr__(self):
        """Show important attributes of the WSGIRequest"""
        pf = pformat
        msg = '<%s.%s object at 0x%x method=%s,' % \
            (self.__class__.__module__, self.__class__.__name__,
             id(self), pf(self.method))
        msg += '\nscheme=%s, host=%s, script_name=%s, path_info=%s,' % \
            (pf(self.scheme), pf(self.host), pf(self.script_name),
             pf(self.path_info))
        msg += '\nlanguges=%s,' % pf(self.languages)
        if self.charset:
            msg += ' charset=%s, errors=%s,' % (pf(self.charset),
                                                pf(self.errors))
        msg += '\nGET=%s,' % pf(self.GET)
        msg += '\nPOST=%s,' % pf(self.POST)
        msg += '\ncookies=%s>' % pf(self.cookies)
        return msg