From e8e33f0424ad5e255bdb4dc6c8444c0799c00fd0 Mon Sep 17 00:00:00 2001 From: Jon Shallow Date: Thu, 11 Nov 2021 14:57:50 +0000 Subject: [PATCH] coap-server: Add in POST support for unknown request handler --- examples/coap-server.c | 52 +++++++++++++++++++++++++++++++--------- man/coap_resource.txt.in | 4 ++-- 2 files changed, 43 insertions(+), 13 deletions(-) diff --git a/examples/coap-server.c b/examples/coap-server.c index 24ee18ea66..bd58e1e351 100644 --- a/examples/coap-server.c +++ b/examples/coap-server.c @@ -1329,12 +1329,12 @@ hnd_get(coap_resource_t *resource, } /* - * Regular PUT handler - used by resources created by the - * Unknown Resource PUT handler + * Regular PUT or POST handler - used by resources created by the + * Unknown Resource PUT/POST handler */ static void -hnd_put(coap_resource_t *resource, +hnd_put_post(coap_resource_t *resource, coap_session_t *session, const coap_pdu_t *request, const coap_string_t *query COAP_UNUSED, @@ -1370,7 +1370,7 @@ hnd_put(coap_resource_t *resource, } if (i == dynamic_count) { if (dynamic_count >= support_dynamic) { - /* Should have been caught in hnd_unknown_put() */ + /* Should have been caught hnd_put_post_unknown() */ coap_pdu_set_code(response, COAP_RESPONSE_CODE_NOT_ACCEPTABLE); coap_delete_string(uri_path); return; @@ -1383,7 +1383,6 @@ hnd_put(coap_resource_t *resource, dynamic_entry[i].value = NULL; dynamic_entry[i].resource = resource; dynamic_entry[i].created = 1; - coap_pdu_set_code(response, COAP_RESPONSE_CODE_CREATED); if ((option = coap_check_option(request, COAP_OPTION_CONTENT_FORMAT, &opt_iter)) != NULL) { dynamic_entry[i].media_type = @@ -1413,7 +1412,6 @@ hnd_put(coap_resource_t *resource, } else { /* Need to do this as coap_get_uri_path() created it */ coap_delete_string(uri_path); - coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED); } resource_entry = &dynamic_entry[i]; @@ -1512,8 +1510,32 @@ hnd_put(coap_resource_t *resource, resource_entry->value = transient_value; if (resource_entry->created) { + coap_pdu_code_t code = coap_pdu_get_code(request); + resource_entry->created = 0; coap_pdu_set_code(response, COAP_RESPONSE_CODE_CREATED); + if (code == COAP_REQUEST_CODE_POST) { + /* Add in Location-Path / Location-Query Options */ + coap_option_iterator_init(request, &opt_iter, COAP_OPT_ALL); + while ((option = coap_option_next(&opt_iter))) { + switch (opt_iter.number) { + case COAP_OPTION_URI_PATH: + if (!coap_add_option(response, COAP_OPTION_LOCATION_PATH, + coap_opt_length(option), + coap_opt_value(option))) + goto fail; + break; + case COAP_OPTION_URI_QUERY: + if (!coap_add_option(response, COAP_OPTION_LOCATION_QUERY, + coap_opt_length(option), + coap_opt_value(option))) + goto fail; + break; + default: + break; + } + } + } } else { coap_pdu_set_code(response, COAP_RESPONSE_CODE_CHANGED); @@ -1530,6 +1552,11 @@ hnd_put(coap_resource_t *resource, body.s, release_resource_data, resource_entry->value); } + return; + +fail: + coap_pdu_set_code(response, COAP_RESPONSE_CODE_INTERNAL_ERROR); + return; } /* @@ -1537,7 +1564,7 @@ hnd_put(coap_resource_t *resource, */ static void -hnd_unknown_put(coap_resource_t *resource COAP_UNUSED, +hnd_put_post_unknown(coap_resource_t *resource COAP_UNUSED, coap_session_t *session, const coap_pdu_t *request, const coap_string_t *query, @@ -1566,15 +1593,16 @@ hnd_unknown_put(coap_resource_t *resource COAP_UNUSED, r = coap_resource_init((coap_str_const_t*)uri_path, COAP_RESOURCE_FLAGS_RELEASE_URI | resource_flags); coap_add_attr(r, coap_make_str_const("title"), coap_make_str_const("\"Dynamic\""), 0); - coap_register_request_handler(r, COAP_REQUEST_PUT, hnd_put); + coap_register_request_handler(r, COAP_REQUEST_PUT, hnd_put_post); + coap_register_request_handler(r, COAP_REQUEST_POST, hnd_put_post); coap_register_request_handler(r, COAP_REQUEST_DELETE, hnd_delete); /* We possibly want to Observe the GETs */ coap_resource_set_get_observable(r, 1); coap_register_request_handler(r, COAP_REQUEST_GET, hnd_get); coap_add_resource(coap_session_get_context(session), r); - /* Do the PUT for this first call */ - hnd_put(r, session, request, query, response); + /* Do the PUT/POST for this first call */ + hnd_put_post(r, session, request, query, response); } #if SERVER_CAN_PROXY @@ -1779,7 +1807,9 @@ init_resources(coap_context_t *ctx) { if (support_dynamic > 0) { /* Create a resource to handle PUTs to unknown URIs */ - r = coap_resource_unknown_init(hnd_unknown_put); + r = coap_resource_unknown_init(hnd_put_post_unknown); + /* Add in handling POST as well */ + coap_register_handler(r, COAP_REQUEST_POST, hnd_put_post_unknown); coap_add_resource(ctx, r); } diff --git a/man/coap_resource.txt.in b/man/coap_resource.txt.in index abe66e1c79..6d67423919 100644 --- a/man/coap_resource.txt.in +++ b/man/coap_resource.txt.in @@ -410,7 +410,7 @@ check_url_fn(coap_string_t *uri_path, uint8_t code) { /* Unknown Resource PUT handler */ static void -hnd_unknown_put(coap_resource_t *resource, coap_session_t *session, +hnd_put_unknown(coap_resource_t *resource, coap_session_t *session, const coap_pdu_t *request, const coap_string_t *query, coap_pdu_t *response) { /* Remove (void) definition if variable is used */ (void)resource; @@ -461,7 +461,7 @@ init_resources(coap_context_t *ctx) { coap_resource_t *r; /* Create a resource to handle PUTs to unknown URIs */ - r = coap_resource_unknown_init(hnd_unknown_put); + r = coap_resource_unknown_init(hnd_put_unknown); /* * Additional handlers can be added - for example * coap_register_request_handler(r, COAP_REQUEST_POST, hnd_post_unknown);