Example #1
0
    def __init__(self, mapping=None):
        self.__d = {}

        # First, handle initializing from other MultiDicts.
        if isinstance(mapping, MultiDict):
            for key, lst in mapping.iterlists():
                self.setlist(key, lst)

        # Otherwise, if we're given another dictionary:
        elif isinstance(mapping, dict):
            for key, value in iteritems(mapping):
                # We convert lists of things to multidict lists.
                if isinstance(value, (list, tuple)):
                    value = list(value)
                else:
                    value = [value]

                self.setlist(key, value)

        # Otherwise, we assume this is some iterable of some sort.
        else:
            tmp = {}
            for key, value in (mapping or ()):
                tmp.setdefault(key, []).append(value)

            for key, lst in iteritems(tmp):
                self.setlist(key, lst)
Example #2
0
    def test_route(self, param):
        if 'skip' in param:
            if hasattr(unittest, 'SkipTest'):
                raise unittest.SkipTest(param['skip'])
            return

        matcher = Matcher(param['path'])
        regex = param['regex'].encode('latin-1')
        self.assertEqual(matcher.match_re.pattern, regex)

        class FakeRequest(object):
            path_info = None

        for succ in param.get('successes', []):
            r = FakeRequest()
            r.path_info = succ['route'].encode('latin-1')
            matched, args, kwargs = matcher.match(r)

            expected_args = [x.encode('latin-1') for x in succ.get('args', [])]
            expected_kwargs_str = succ.get('kwargs', {})
            expected_kwargs = {}
            for k, v in iteritems(expected_kwargs_str):
                if isinstance(v, text_type):
                    v = v.encode('latin-1')
                expected_kwargs[k] = v
            self.assertTrue(matched)
            self.assertEqual(args, expected_args)
            self.assertEqual(kwargs, expected_kwargs)

        for fail in param.get('failures', []):
            r = FakeRequest()
            r.path = fail
            matched, _, _ = matcher.match(r)

            self.assertFalse(matched)
Example #3
0
 def from_dict(self, d):
     """
     Populates this dictionary with values from a given dictionary.  All
     upper-case root keys in the given dictionary are added to this object.
     """
     for key, val in iteritems(d):
         if key.isupper():
             self[key] = val
Example #4
0
    def test_escape_table(self):
        from hoboken.objects.mixins.cookies import _escape_table

        for k, v in iteritems(_escape_table):
            if PY3:
                self.assertTrue(isinstance(k, int))
                self.assertTrue(isinstance(v, bytes))
            else:
                self.assertTrue(isinstance(k, bytes))
                self.assertTrue(isinstance(v, bytes))
Example #5
0
 def extend(self, it):
     if isinstance(it, dict):
         for key, val in iteritems(it):
             if isinstance(val, (tuple, list)):
                 for v in val:
                     self.add(key, v)
             else:
                 self.add(key, val)
     else:
         for key, val in it:
             self.add(key, val)
Example #6
0
    def test_cookie_serialization(self, param):
        if not param:
            return

        name = _e(param['values']['name'])
        value = _e(param['values']['value'])

        m = Morsel(name, value)
        for name, val in iteritems(param['values']['attributes']):
            setattr(m, name, _e(val))

        output = _e(param['output'])
        self.assertEqual(m.serialize(), output)
Example #7
0
    def build(klass, path, **kwargs):
        """
        This function lets us build a request by creating a base, empty WSGI
        environ, and then filling it in with the appropriate values.
        """
        if PY3:         # pragma: no cover
            # We encode bytes as strings.
            if isinstance(path, binary_type):
                path = path.decode('latin-1')
        else:           # pragma: no cover
            # We encode unicode as a string.
            if isinstance(path, text_type):
                path = path.encode('latin-1')

        # Build a temporary environ.
        env = {
            'SERVER_PROTOCOL': 'HTTP/1.0',
            'SCRIPT_NAME': '',
            'PATH_INFO': path,

            # WSGI variables.
            'wsgi.version': (1, 0),
            'wsgi.url_scheme': 'http',
            'wsgi.multithread': False,
            'wsgi.multiprocess': False,
            'wsgi.run_once': False,
        }

        def try_add(arg, key, default=None):
            val = kwargs.get(arg, default)
            if val is not None:
                env[key] = val

        try_add('query_string', 'QUERY_STRING')
        try_add('method', 'REQUEST_METHOD', 'GET')
        try_add('server_name', 'SERVER_NAME', 'localhost')
        try_add('server_port', 'SERVER_PORT', '80')

        # Create our request.
        req = klass(env)

        # Set headers.
        headers = kwargs.get('headers')
        if headers is not None:
            for header, value in iteritems(headers):
                req.headers[header] = value

        # Done!
        return req
Example #8
0
def serialize_auth(val):
    if isinstance(val, (tuple, list)):
        authtype, params = val
        if isinstance(params, dict):
            params = b', '.join(
                [k + b'="' + v + b'"' for k, v in iteritems(params)]
            )
        if not isinstance(params, binary_type):
            msg = "Invalid type for 'params': %s" % (params.__class__.__name__)
            logger.warn(msg)
            raise ValueError(msg)

        return authtype + b' ' + params

    return val
Example #9
0
def iter_multi_items(mapping):
    """
    Iterate over the items in a mapping, properly handling more complex data
    structures.
    """
    if isinstance(mapping, MultiDict):
        # Note: we don't unpack (key, value) from item.
        for item in mapping.iteritems(multi=True):
            yield item

    elif isinstance(mapping, MutableMapping):
        for key, value in iteritems(mapping):
            if isinstance(value, (tuple, list)):
                for value in value:
                    yield key, value
            else:
                yield key, value

    else:
        for item in mapping:
            yield item
Example #10
0
    def escape_string(self, string):
        base_escapes = {
            b'&': b'\\u0026', b'>': b'\\u003E', b'<': b'\\u003C'
        }
        escapes = base_escapes.copy()
        for k, v in iteritems(base_escapes):
            escapes[k.decode('latin-1')] = v.decode('latin-1')

        # Decode our unicode line/paragraph seperators.
        line_sep = b'\xE2\x80\xA8'.decode('utf-8')
        line_sep_escape = b'\\u2028'.decode('latin-1')
        paragraph_sep = b'\xE2\x80\xA9'.decode('utf-8')
        paragraph_sep_escape = b'\\u2029'.decode('latin-1')

        def encoder(match):
            v = match.group(0)
            return escapes[v]

        if isinstance(string, text_type):
            ret = re.sub(u(r"[&<>]"), encoder, string)
            return ret.replace(line_sep, line_sep_escape).replace(
                paragraph_sep, paragraph_sep_escape)
        else:
            return re.sub(br"[&<>]", encoder, string)
Example #11
0
    def _make_route(self, match, func):
        if isinstance(match, string_types):
            matcher = HobokenRouteMatcher(match)
        elif isinstance(match, RegexType):
            # match is a regex, so we extract any named groups.
            keys = [None] * match.groups
            types = [False] * match.groups
            for name, index in iteritems(match.groupindex):
                types[index - 1] = True
                keys[index - 1] = name

            # Append the route with these keys.
            matcher = RegexMatcher(match, types, keys)

        elif hasattr(match, "match") and callable(getattr(match, "match")):
            # Don't know what type it is, but it has a callable "match"
            # attribute, so we use that.
            matcher = match

        else:
            # Unknown type!
            raise InvalidMatchTypeException("Unknown type: %r" % (match,))

        return Route(matcher, func)
Example #12
0
 def _iter_hashitems(self):
     return iteritems(self)
Example #13
0
 def set_cache_control(self, **kwargs):
     for key, val in iteritems(kwargs):
         setattr(self.response.cache_control, key, val)
Example #14
0
    def test_unquoter_table(self):
        from hoboken.objects.mixins.cookies import _unquoter_table

        for k, v in iteritems(_unquoter_table):
            self.assertTrue(isinstance(k, bytes))
            self.assertTrue(isinstance(v, bytes))
Example #15
0
 def to_list(self):
     return list(iteritems(self))
Example #16
0
    def _handle_request(self):
        # Since these are thread-locals, we grab them as locals.
        request = self.request
        response = self.response
        self.logger.debug("Handling: %s %s", request.method, request.url)

        # Check for valid method.
        # TODO: Should this call our after filters?
        if request.method not in self.SUPPORTED_METHODS:
            self.logger.warn("Called with invalid method: %s", request.method)

            # TODO: hook.

            # Send "invalid method" exception.
            response.status_int = 405
            return

        matched = False
        try:
            # Call before filters.
            for filter in self.before_filters:
                filter(request, response)

            # For each route of the specified type, try to match it.
            matched = self._run_routes(request.method)

            # We special-case the HEAD method to fallback to GET.
            if request.method == 'HEAD' and not matched:
                # Run our routes against the 'GET' method.
                matched = self._run_routes('GET')

        except HaltRoutingException as ex:
            # Set the various parameters.
            if ex.code is not None:
                response.status_int = ex.code

            if ex.body is not None:
                # We pass the body through to on_returned_body.
                self.on_returned_body(request, response, ex.body)

            if ex.headers is not None:
                # Set each header.
                for header, value in iteritems(ex.headers):
                    # Set this header.
                    response.headers[header] = value

            # Must set this, or we get clobbered by the 404 handler.
            matched = True

        except Exception as e:
            # Also, check if the exception has other information attached,
            # like a code/body.
            self.on_exception(e)

            # Must set this, or we get clobbered by the 404 handler.
            matched = True

        finally:
            # Call our after filters
            for route in self.after_filters:
                route(request, response)

        if not matched:
            self.on_route_missing()
Example #17
0
# 1. All safe characters are allowed, so we replace them with themselves.
_escape_table.update((x, x) for x in _safe_chars)

# 2. The characters ':' and ' ' can be used without escaping, too.
_escape_table[':'] = ':'
_escape_table[' '] = ' '

# 3. The escapes for quotes and slashes are special.
_escape_table['"'] = r'\"'
_escape_table['\\'] = r'\\'

# Finally, we might need to convert this table to operate on bytes, if we're
# on Python 3.
if PY3:     # pragma: no cover
    new = {}
    for k, v in iteritems(_escape_table):
        new[ord(k)] = v.encode('ascii')

    _escape_table = new

# This map is used to unquote things.  It contains two types of entries:
#   1. '101' --> 'A'        (octal --> single character)
#   2. 'A'   --> 'A'        (character -> same character)
_unquoter_table = dict(('%03o' % i, chr(i)) for i in range(256))
_unquoter_table.update((v, v) for v in list(_unquoter_table.values()))

# Convert to Python3 format if necessary
if PY3:
    new = {}
    for k, v in iteritems(_unquoter_table):
        new[k.encode('latin-1')] = v.encode('latin-1')