Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gcoap: return Method Not Allowed if appropriate #7699

Merged
merged 1 commit into from
Apr 6, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 31 additions & 18 deletions sys/net/application_layer/gcoap/gcoap.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
#define ENABLE_DEBUG (0)
#include "debug.h"

/* Return values used by the _find_resource function. */
#define GCOAP_RESOURCE_FOUND 0
#define GCOAP_RESOURCE_WRONG_METHOD -1
#define GCOAP_RESOURCE_NO_PATH -2

/* Internal functions */
static void *_event_loop(void *arg);
static void _listen(sock_udp_t *sock);
Expand All @@ -38,7 +43,7 @@ static void _expire_request(gcoap_request_memo_t *memo);
static bool _endpoints_equal(const sock_udp_ep_t *ep1, const sock_udp_ep_t *ep2);
static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *pdu,
const sock_udp_ep_t *remote);
static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
static int _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
gcoap_listener_t **listener_ptr);
static int _find_observer(sock_udp_ep_t **observer, sock_udp_ep_t *remote);
static int _find_obs_memo(gcoap_observe_memo_t **memo, sock_udp_ep_t *remote,
Expand Down Expand Up @@ -177,19 +182,21 @@ static void _listen(sock_udp_t *sock)
static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
sock_udp_ep_t *remote)
{
coap_resource_t *resource;
gcoap_listener_t *listener;
coap_resource_t *resource = NULL;
gcoap_listener_t *listener = NULL;
sock_udp_ep_t *observer = NULL;
gcoap_observe_memo_t *memo = NULL;
gcoap_observe_memo_t *resource_memo = NULL;

_find_resource(pdu, &resource, &listener);
if (resource == NULL) {
return gcoap_response(pdu, buf, len, COAP_CODE_PATH_NOT_FOUND);
}
else {
/* used below to ensure a memo not already recorded for the resource */
_find_obs_memo_resource(&resource_memo, resource);
switch (_find_resource(pdu, &resource, &listener)) {
case GCOAP_RESOURCE_WRONG_METHOD:
return gcoap_response(pdu, buf, len, COAP_CODE_METHOD_NOT_ALLOWED);
case GCOAP_RESOURCE_NO_PATH:
return gcoap_response(pdu, buf, len, COAP_CODE_PATH_NOT_FOUND);
case GCOAP_RESOURCE_FOUND:
/* used below to ensure a memo not already recorded for the resource */
_find_obs_memo_resource(&resource_memo, resource);
break;
}

if (coap_get_observe(pdu) == COAP_OBS_REGISTER) {
Expand Down Expand Up @@ -266,10 +273,15 @@ static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
*
* param[out] resource_ptr -- found resource
* param[out] listener_ptr -- listener for found resource
* return `GCOAP_RESOURCE_FOUND` if the resource was found,
* `GCOAP_RESOURCE_WRONG_METHOD` if a resource was found but the method
* code didn't match and `GCOAP_RESOURCE_NO_PATH` if no matching
* resource was found.
*/
static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
static int _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
gcoap_listener_t **listener_ptr)
{
int ret = GCOAP_RESOURCE_NO_PATH;
unsigned method_flag = coap_method2flag(coap_get_code_detail(pdu));

/* Find path for CoAP msg among listener resources and execute callback. */
Expand All @@ -280,9 +292,6 @@ static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
if (i) {
resource++;
}
if (! (resource->methods & method_flag)) {
continue;
}

int res = strcmp((char *)&pdu->url[0], resource->path);
if (res > 0) {
Expand All @@ -293,16 +302,20 @@ static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
break;
}
else {
if (! (resource->methods & method_flag)) {
ret = GCOAP_RESOURCE_WRONG_METHOD;
continue;
}

*resource_ptr = resource;
*listener_ptr = listener;
return;
return GCOAP_RESOURCE_FOUND;
}
}
listener = listener->next;
}
/* resource not found */
*resource_ptr = NULL;
*listener_ptr = NULL;

return ret;
}

/*
Expand Down