Example #1
0
File: rd.py Project: ltn22/aiocoap
def link_format_from_message(message):
    try:
        if message.opt.content_format == media_types_rev['application/link-format']:
            return parse(message.payload.decode('utf8'))
        elif message.opt.content_format == media_types_rev['application/link-format+json']:
            return LinkFormat.from_json_string(message.payload.decode('utf8'))
        elif message.opt.content_format == media_types_rev['application/link-format+cbor']:
            return LinkFormat.from_cbor_bytes(message.payload)
        else:
            raise error.UnsupportedMediaType()
    except (UnicodeDecodeError, link_header.ParseException):
        raise error.BadRequest()
Example #2
0
 def get_links():
     links = site.get_resources_as_linkheader()
     for l in links.links:
         if l.href == "/sensors/light":
             l.attr_pairs.append(
                 ("anchor", "coap://spurious.example.com:5683"))
     return LinkFormat(links.links)
Example #3
0
File: rd.py Project: ltn22/aiocoap
    async def render_get(self, request):
        query = query_split(request)

        candidates = self.common_rd.get_endpoints()

        for search_key, search_value in query.items():
            if search_key in ('page', 'count'):
                continue # filtered last

            if search_value.endswith('*'):
                matches = lambda x, start=search_value[:-1]: x.startswith(start)
            else:
                matches = lambda x: x == search_value

            if search_key in ('if', 'rt'):
                candidates = (c for c in candidates if any(any(matches(x) for x in getattr(r, search_key, '').split()) for r in c.get_based_links().links))
                continue

            if search_key == 'href':
                candidates = (c for c in candidates if
                        matches(c.href) or
                        any(matches(r.href) for r in c.get_based_links().links)
                        )
                continue

            candidates = (c for c in candidates if
                    (search_key in c.registration_parameters and matches(c.registration_parameters[search_key])) or
                    any(_link_matches(r, search_key, matches) for r in c.get_based_links().links)
                    )

        candidates = _paginate(candidates, query)

        result = [c.get_host_link() for c in candidates]

        return link_format_to_message(request, LinkFormat(result))
Example #4
0
 def get_links():
     links = site.get_resources_as_linkheader()
     links.links.append(Link("/t", anchor="sensors/temp", rel="alternate"))
     links.links.append(
         Link("http://www.example.com/sensors/t123",
              anchor="sensors/temp",
              rel="describedby"))
     return LinkFormat(links.links)
Example #5
0
File: rd.py Project: ltn22/aiocoap
        def __init__(self, path, network_remote, delete_cb, update_cb, registration_parameters):
            # note that this can not modify d and ep any more, since they were
            # already used in keying to a path
            self.path = path
            self.links = LinkFormat([])

            self._delete_cb = delete_cb
            self._update_cb = update_cb
            self.update_params(network_remote, registration_parameters, is_initial=True)
Example #6
0
def link_format_from_message(message):
    """Convert a response message into a LinkFormat object

    This expects an explicit media type set on the response (or was explicitly requested)
    """
    certain_format = message.opt.content_format
    if certain_format is None:
        certain_format = message.request.opt.accept
    try:
        if certain_format == media_types_rev['application/link-format']:
            return parse(message.payload.decode('utf8'))
        elif certain_format == media_types_rev['application/link-format+json']:
            return LinkFormat.from_json_string(message.payload.decode('utf8'))
        elif certain_format == media_types_rev['application/link-format+cbor']:
            return LinkFormat.from_cbor_bytes(message.payload)
        else:
            raise error.UnsupportedMediaType()
    except (UnicodeDecodeError, link_header.ParseException):
        raise error.BadRequest()
Example #7
0
    async def render_get(self, request):
        query = query_split(request)

        eps = self.common_rd.get_endpoints()
        candidates = ((e, c) for e in eps for c in e.get_based_links().links)

        for search_key, search_values in query.items():
            if search_key in ('page', 'count'):
                continue  # filtered last

            for search_value in search_values:
                if search_value is not None and search_value.endswith('*'):

                    def matches(x, start=search_value[:-1]):
                        return x.startswith(start)
                else:

                    def matches(x, search_value=search_value):
                        return x == search_value

                if search_key in ('if', 'rt'):

                    def matches(x, original_matches=matches):
                        return any(original_matches(v) for v in x.split())

                if search_key == 'href':
                    candidates = (
                        (e, c)
                        for (e, c) in candidates if matches(c.href) or matches(
                            e.href
                        )  # FIXME: They SHOULD give this as relative as we do, but don't have to
                    )
                    continue

                candidates = (
                    (e, c) for (e, c) in candidates
                    if _link_matches(c, search_key, matches) or (
                        search_key in e.registration_parameters and any(
                            matches(x)
                            for x in e.registration_parameters[search_key])))

        # strip endpoint
        candidates = (c for (e, c) in candidates)

        candidates = _paginate(candidates, query)

        # strip needless anchors
        candidates = [
            Link(l.href, [(k, v) for (k, v) in l.attr_pairs if k != 'anchor'])
            if dict(l.attr_pairs)['anchor'] == urljoin(l.href, '/') else l
            for l in candidates
        ]

        return link_format_to_message(request, LinkFormat(candidates))
Example #8
0
 def get_based_links(self):
     """Produce a LinkFormat object that represents all statements in
     the registration, resolved to the registration's base (and thus
     suitable for comparing anchors)."""
     result = []
     for l in self.links.links:
         href = urljoin(self.base, l.href)
         if 'anchor' in l:
             absanchor = urljoin(self.base, l.anchor)
             data = [(k, v) for (k, v) in l.attr_pairs if k != 'anchor'
                     ] + [['anchor', absanchor]]
         else:
             data = l.attr_pairs + [['anchor', urljoin(href, '/')]]
         result.append(Link(href, data))
     return LinkFormat(result)
Example #9
0
    async def render_get(self, request):
        query = query_split(request)

        eps = self.common_rd.get_endpoints()
        candidates = ((e, c) for e in eps for c in e.get_based_links().links)

        for search_key, search_value in query.items():
            if search_key in ('page', 'count'):
                continue  # filtered last

            # FIXME: maybe we need query_split to turn ?rt=foo&obs into {'rt':
            # 'foo', 'obs': True} to match on obs, and then this needs more
            # type checking
            if search_value.endswith('*'):
                matches = lambda x, start=search_value[:-1]: x.startswith(start
                                                                          )
            else:
                matches = lambda x: x == search_value

            if search_key in ('if', 'rt'):
                candidates = ((e, c) for (e, c) in candidates if any(
                    matches(x)
                    for x in " ".join(getattr(c, search_key, ())).split()))
                continue

            if search_key == 'href':
                candidates = (
                    (e, c) for (e, c) in candidates
                    if matches(urljoin(e.base, c.href)) or matches(
                        e.href
                    )  # FIXME: actually resolved e, but so far we've avoided knowing our own
                )
                continue

            candidates = ((e, c) for (e, c) in candidates
                          if _link_matches(c, search_key, matches) or
                          (search_key in e.registration_parameters
                           and matches(e.registration_parameters[search_key])))

        # strip endpoint
        candidates = (c for (e, c) in candidates)

        candidates = _paginate(candidates, query)

        return link_format_to_message(request, LinkFormat(candidates))
Example #10
0
        def __init__(self, static_registration_parameters, path,
                     network_remote, delete_cb, update_cb,
                     registration_parameters):
            # note that this can not modify d and ep any more, since they are
            # already part of the key and possibly the path
            self.path = path
            self.links = LinkFormat([])

            self._delete_cb = delete_cb
            self._update_cb = update_cb

            self.registration_parameters = static_registration_parameters
            self.lt = 90000
            self.base_is_explicit = False

            self.update_params(network_remote,
                               registration_parameters,
                               is_initial=True)
Example #11
0
        def get_based_links(self):
            """Produce a LinkFormat object that represents all statements in
            the registration, resolved to the registration's base (and thus
            suitable for serving from the lookup interface).

            This implements Limited Link Format as described in Appendix C
            of draft-ietf-core-resource-directory-25."""
            result = []
            for l in self.links.links:
                if 'anchor' in l:
                    absanchor = urljoin(self.base, l.anchor)
                    data = [(k, v) for (k, v) in l.attr_pairs if k != 'anchor'
                            ] + [['anchor', absanchor]]
                else:
                    data = l.attr_pairs + [['anchor', self.base]]
                href = urljoin(self.base, l.href)
                result.append(Link(href, data))
            return LinkFormat(result)
Example #12
0
File: rd.py Project: ltn22/aiocoap
        def get_based_links(self):
            """Produce a LinkFormat object that represents all statements in
            the registration, resolved to the registration's base (and thus
            suitable for serving from the lookup interface).

            If protocol negotiation is implemented and base becomes a list, this
            function will probably grow parameters that hint at which base to
            use.
            """
            result = []
            for l in self.links.links:
                if 'anchor' in l:
                    absanchor = urljoin(self.base, l.anchor)
                    data = [(k, v) for (k, v) in l.attr_pairs if k != 'anchor'] + [['anchor', absanchor]]
                    href = urljoin(absanchor, l.href)
                else:
                    data = l.attr_pairs + [['anchor', self.base]]
                    href = urljoin(self.base, l.href)
                result.append(Link(href, data))
            return LinkFormat(result)