Merge pull request #7699 from nmeum/gcoap-method-not-allowed

gcoap: return Method Not Allowed if appropriate
This commit is contained in:
Martine Lenders 2018-04-06 15:35:05 +02:00 committed by GitHub
commit 3c93ebc86e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -30,6 +30,11 @@
#define ENABLE_DEBUG (0) #define ENABLE_DEBUG (0)
#include "debug.h" #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 */ /* Internal functions */
static void *_event_loop(void *arg); static void *_event_loop(void *arg);
static void _listen(sock_udp_t *sock); static void _listen(sock_udp_t *sock);
@ -42,7 +47,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 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, static void _find_req_memo(gcoap_request_memo_t **memo_ptr, coap_pkt_t *pdu,
const sock_udp_ep_t *remote); 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); gcoap_listener_t **listener_ptr);
static int _find_observer(sock_udp_ep_t **observer, sock_udp_ep_t *remote); 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, static int _find_obs_memo(gcoap_observe_memo_t **memo, sock_udp_ep_t *remote,
@ -260,19 +265,21 @@ static void _listen(sock_udp_t *sock)
static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len, static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
sock_udp_ep_t *remote) sock_udp_ep_t *remote)
{ {
coap_resource_t *resource; coap_resource_t *resource = NULL;
gcoap_listener_t *listener; gcoap_listener_t *listener = NULL;
sock_udp_ep_t *observer = NULL; sock_udp_ep_t *observer = NULL;
gcoap_observe_memo_t *memo = NULL; gcoap_observe_memo_t *memo = NULL;
gcoap_observe_memo_t *resource_memo = NULL; gcoap_observe_memo_t *resource_memo = NULL;
_find_resource(pdu, &resource, &listener); switch (_find_resource(pdu, &resource, &listener)) {
if (resource == NULL) { case GCOAP_RESOURCE_WRONG_METHOD:
return gcoap_response(pdu, buf, len, COAP_CODE_PATH_NOT_FOUND); return gcoap_response(pdu, buf, len, COAP_CODE_METHOD_NOT_ALLOWED);
} case GCOAP_RESOURCE_NO_PATH:
else { return gcoap_response(pdu, buf, len, COAP_CODE_PATH_NOT_FOUND);
/* used below to ensure a memo not already recorded for the resource */ case GCOAP_RESOURCE_FOUND:
_find_obs_memo_resource(&resource_memo, resource); /* 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) { if (coap_get_observe(pdu) == COAP_OBS_REGISTER) {
@ -349,10 +356,15 @@ static size_t _handle_req(coap_pkt_t *pdu, uint8_t *buf, size_t len,
* *
* param[out] resource_ptr -- found resource * param[out] resource_ptr -- found resource
* param[out] listener_ptr -- listener for 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) gcoap_listener_t **listener_ptr)
{ {
int ret = GCOAP_RESOURCE_NO_PATH;
unsigned method_flag = coap_method2flag(coap_get_code_detail(pdu)); unsigned method_flag = coap_method2flag(coap_get_code_detail(pdu));
/* Find path for CoAP msg among listener resources and execute callback. */ /* Find path for CoAP msg among listener resources and execute callback. */
@ -363,9 +375,6 @@ static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
if (i) { if (i) {
resource++; resource++;
} }
if (! (resource->methods & method_flag)) {
continue;
}
int res = strcmp((char *)&pdu->url[0], resource->path); int res = strcmp((char *)&pdu->url[0], resource->path);
if (res > 0) { if (res > 0) {
@ -376,16 +385,20 @@ static void _find_resource(coap_pkt_t *pdu, coap_resource_t **resource_ptr,
break; break;
} }
else { else {
if (! (resource->methods & method_flag)) {
ret = GCOAP_RESOURCE_WRONG_METHOD;
continue;
}
*resource_ptr = resource; *resource_ptr = resource;
*listener_ptr = listener; *listener_ptr = listener;
return; return GCOAP_RESOURCE_FOUND;
} }
} }
listener = listener->next; listener = listener->next;
} }
/* resource not found */
*resource_ptr = NULL; return ret;
*listener_ptr = NULL;
} }
/* /*