1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

sys/net/application_layer/nanocoap: Add path prefix opt

This adds a prefix option for the methods field of a coap resource and
modifies the way the path is matched on a request to accept prefix
matching.
This commit is contained in:
Leandro Lanzieri 2019-03-11 13:21:52 +01:00
parent 9e9a51a3ea
commit 6bb4158c31
3 changed files with 55 additions and 2 deletions

View File

@ -26,6 +26,25 @@
* capital precede lower case). nanocoap provides the
* COAP_WELL_KNOWN_CORE_DEFAULT_HANDLER entry for `/.well-known/core`.
*
* ### Path matching ###
* By default the URI-path of an incoming request should match exactly one of
* the registered resources. But also, a resource can be configured to
* match just a prefix of the URI-path of the request by adding the
* @ref COAP_MATCH_SUBTREE option to coap_resource_t::methods.
*
* For example, if a resource is configured with a
* @ref coap_resource_t::path "path" `/resource01` and the
* @ref COAP_MATCH_SUBTREE option is used it would match any of `/resource01/`,
* `/resource01/sub/path`, `/resource01alt`.
*
* If the behavior of matching `/resource01alt` is not wanted and only subtrees
* are wanted to match, the path should be `/resource01/`.
*
* If in addition just `/resource01` is wanted to match, together with any
* subtrees of `/resource01/`, then a first resource with the path `/resource01`
* and exact matching should be register, and then a second one with the path
* `/resource01/` and subtree matching.
*
* ### Handler functions ###
*
* For each resource, you must implement a ::coap_handler_t handler function.
@ -170,6 +189,8 @@ extern "C" {
#define COAP_POST (0x2)
#define COAP_PUT (0x4)
#define COAP_DELETE (0x8)
#define COAP_MATCH_SUBTREE (0x8000) /**< Path is considered as a prefix
when matching */
/** @} */
/**
@ -1065,6 +1086,23 @@ static inline unsigned coap_method2flag(unsigned code)
return (1 << (code - 1));
}
/**
* @brief Checks if a CoAP resource path matches a given URI
*
* Builds on strcmp() with rules specific to URI path matching
*
* @note This function is not intended for application use.
* @internal
*
* @param[in] resource CoAP resource to check
* @param[in] uri Null-terminated string URI to compare
*
* @return 0 if the resource path matches the URI
* @return <0 if the resource path sorts before the URI
* @return >0 if the resource path sorts after the URI
*/
int coap_match_path(const coap_resource_t *resource, uint8_t *uri);
#if defined(MODULE_GCOAP) || defined(DOXYGEN)
/**
* @brief Identifies a packet containing an observe option

View File

@ -399,7 +399,7 @@ static int _find_resource(coap_pkt_t *pdu, const coap_resource_t **resource_ptr,
resource++;
}
int res = strcmp((char *)&uri[0], resource->path);
int res = coap_match_path(resource, uri);
if (res > 0) {
continue;
}

View File

@ -146,6 +146,21 @@ int coap_parse(coap_pkt_t *pkt, uint8_t *buf, size_t len)
return 0;
}
int coap_match_path(const coap_resource_t *resource, uint8_t *uri)
{
assert(resource && uri);
int res;
if (resource->methods & COAP_MATCH_SUBTREE) {
int len = strlen(resource->path);
res = strncmp((char *)uri, resource->path, len);
}
else {
res = strcmp((char *)uri, resource->path);
}
return res;
}
uint8_t *coap_find_option(const coap_pkt_t *pkt, unsigned opt_num)
{
const coap_optpos_t *optpos = pkt->options;
@ -323,7 +338,7 @@ ssize_t coap_handle_req(coap_pkt_t *pkt, uint8_t *resp_buf, unsigned resp_buf_le
continue;
}
int res = strcmp((char *)uri, resource->path);
int res = coap_match_path(resource, uri);
if (res > 0) {
continue;
}