libcoap 4.3.2rc2

coap_uri.c
Go to the documentation of this file.
1/* coap_uri.c -- helper functions for URI treatment
2 *
3 * Copyright (C) 2010--2012,2015-2016,2022-2023 Olaf Bergmann <bergmann@tzi.org>
4 *
5 * SPDX-License-Identifier: BSD-2-Clause
6 *
7 * This file is part of the CoAP library libcoap. Please see
8 * README for terms of use.
9 */
10
16#include "coap3/coap_internal.h"
17
18#if defined(HAVE_LIMITS_H)
19#include <limits.h>
20#endif
21
22#include <stdint.h>
23#include <stdio.h>
24#include <string.h>
25#include <ctype.h>
26
38 COAP_STATIC_INLINE const uint8_t *
39 strnchr(const uint8_t *s, size_t len, unsigned char c) {
40 while (len && *s++ != c)
41 --len;
42
43 return len ? s : NULL;
44}
45
46 typedef enum coap_uri_check_t {
47 COAP_URI_CHECK_URI,
48 COAP_URI_CHECK_PROXY
49} coap_uri_check_t;
50
51 coap_uri_info_t coap_uri_scheme[COAP_URI_SCHEME_LAST] = {
52 { "coap", COAP_DEFAULT_PORT, 0, COAP_URI_SCHEME_COAP },
53 { "coaps", COAPS_DEFAULT_PORT, 0, COAP_URI_SCHEME_COAPS },
54 { "coap+tcp", COAP_DEFAULT_PORT, 0, COAP_URI_SCHEME_COAP_TCP },
55 { "coaps+tcp", COAPS_DEFAULT_PORT, 0, COAP_URI_SCHEME_COAPS_TCP },
56 { "http", 80, 1, COAP_URI_SCHEME_HTTP },
57 { "https", 443, 1, COAP_URI_SCHEME_HTTPS },
58 { "coap+ws", 80, 0, COAP_URI_SCHEME_COAP_WS },
59 { "coaps+ws", 443, 0, COAP_URI_SCHEME_COAPS_WS }
60};
61
62 static int
63 coap_split_uri_sub(const uint8_t *str_var,
64 size_t len,
65 coap_uri_t *uri,
66 coap_uri_check_t check_proxy) {
67 const uint8_t *p, *q;
68 int res = 0;
69 size_t i;
70 int is_unix_domain = 0;
71
72 if (!str_var || !uri || len == 0)
73 return -1;
74
75 memset(uri, 0, sizeof(coap_uri_t));
76 uri->port = COAP_DEFAULT_PORT;
77
78 /* search for scheme */
79 p = str_var;
80 if (*p == '/') {
81 /* no scheme, host or port */
82 if (check_proxy == COAP_URI_CHECK_PROXY) {
83 /* Must have ongoing host if proxy definition */
84 return -1;
85 }
86 q = p;
87 goto path;
88 }
89
90 /* find scheme terminating :// */
91 while (len >= 3 && !(p[0] == ':' && p[1] == '/' && p[2] == '/')) {
92 ++p;
93 --len;
94 }
95 if (len < 3) {
96 /* scheme not defined with a :// terminator */
97 res = -2;
98 goto error;
99 }
100 for (i = 0; i < COAP_URI_SCHEME_LAST; i++) {
101 if ((p - str_var) == (int)strlen(coap_uri_scheme[i].name) &&
102 memcmp(str_var, coap_uri_scheme[i].name, p - str_var) == 0) {
103 if (check_proxy != COAP_URI_CHECK_PROXY && coap_uri_scheme[i].proxy_only) {
104 coap_log_err("%.*s URI scheme not enabled (not a proxy)\n",
105 (int)(p - str_var), str_var);
106 return -1;
107 }
108 uri->scheme = coap_uri_scheme[i].scheme;
109 uri->port = coap_uri_scheme[i].port;
110 break;
111 }
112 }
113 if (i == COAP_URI_SCHEME_LAST) {
114 /* scheme unknown */
115 coap_log_err("%.*s URI scheme unknown\n", (int)(p - str_var), str_var);
116 res = -1;
117 goto error;
118 }
119 switch (uri->scheme) {
120 case COAP_URI_SCHEME_COAP:
121 break;
122 case COAP_URI_SCHEME_COAPS:
123 if (!coap_dtls_is_supported()) {
124 coap_log_err("coaps URI scheme not supported in this version of libcoap\n");
125 return -1;
126 }
127 break;
128 case COAP_URI_SCHEME_COAP_TCP:
129 if (!coap_tcp_is_supported()) {
130 coap_log_err("coap+tcp URI scheme not supported in this version of libcoap\n");
131 return -1;
132 }
133 break;
134 case COAP_URI_SCHEME_COAPS_TCP:
135 if (!coap_tcp_is_supported()) {
136 coap_log_err("coaps+tcp URI scheme not supported in this version of libcoap\n");
137 return -1;
138 }
139 break;
140 case COAP_URI_SCHEME_COAP_WS:
141 if (!coap_ws_is_supported()) {
142 coap_log_err("coap+ws URI scheme not supported in this version of libcoap\n");
143 return -1;
144 }
145 break;
146 case COAP_URI_SCHEME_COAPS_WS:
147 if (!coap_wss_is_supported()) {
148 coap_log_err("coaps+ws URI scheme not supported in this version of libcoap\n");
149 return -1;
150 }
151 break;
152 case COAP_URI_SCHEME_HTTP:
153 case COAP_URI_SCHEME_HTTPS:
154 case COAP_URI_SCHEME_LAST:
155 default:
156 coap_log_warn("Unsupported URI type %d\n", uri->scheme);
157 return -1;
158 }
159 /* skip :// */
160 p += 3;
161 len -= 3;
162
163 /* p points to beginning of Uri-Host */
164 q = p;
165 if (len && *p == '[') {
166 /* IPv6 address reference */
167 ++p;
168
169 while (len && *q != ']') {
170 ++q;
171 --len;
172 }
173
174 if (!len || *q != ']' || p == q) {
175 res = -3;
176 goto error;
177 }
178
179 COAP_SET_STR(&uri->host, q - p, p);
180 ++q;
181 --len;
182 } else {
183 /* IPv4 address, FQDN or Unix domain socket */
184 if (len >= 3 && p[0] == '%' && p[1] == '2' &&
185 (p[2] == 'F' || p[2] == 'f')) {
186 /* Unix domain definition */
187 uri->port = 0;
188 is_unix_domain = 1;
189 }
190 while (len && *q != ':' && *q != '/' && *q != '?') {
191 ++q;
192 --len;
193 }
194
195 if (p == q) {
196 res = -3;
197 goto error;
198 }
199
200 COAP_SET_STR(&uri->host, q - p, p);
201 }
202
203 /* check for Uri-Port (invalid for Unix) */
204 if (len && *q == ':') {
205 if (is_unix_domain) {
206 res = -5;
207 goto error;
208 }
209 p = ++q;
210 --len;
211
212 while (len && isdigit(*q)) {
213 ++q;
214 --len;
215 }
216
217 if (p < q) { /* explicit port number given */
218 int uri_port = 0;
219
220 while ((p < q) && (uri_port <= UINT16_MAX))
221 uri_port = uri_port * 10 + (*p++ - '0');
222
223 /* check if port number is in allowed range */
224 if (uri_port > UINT16_MAX) {
225 res = -4;
226 goto error;
227 }
228
229 uri->port = (uint16_t)uri_port;
230 }
231 }
232
233path: /* at this point, p must point to an absolute path */
234
235 if (!len)
236 goto end;
237
238 if (*q == '/') {
239 p = ++q;
240 --len;
241
242 while (len && *q != '?') {
243 ++q;
244 --len;
245 }
246
247 if (p < q) {
248 COAP_SET_STR(&uri->path, q - p, p);
249 p = q;
250 }
251 }
252
253 /* Uri_Query */
254 if (len && *p == '?') {
255 ++p;
256 --len;
257 COAP_SET_STR(&uri->query, len, p);
258 len = 0;
259 }
260
261end:
262 return len ? -1 : 0;
263
264error:
265 return res;
266}
267
268 int
269 coap_split_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri) {
270 return coap_split_uri_sub(str_var, len, uri, COAP_URI_CHECK_URI);
271}
272
273 int
274 coap_split_proxy_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri) {
275 return coap_split_uri_sub(str_var, len, uri, COAP_URI_CHECK_PROXY);
276}
277
278 int
279 coap_uri_into_options(const coap_uri_t *uri, const coap_address_t *dst,
280 coap_optlist_t **optlist_chain, int create_port_host_opt,
281 uint8_t *_buf, size_t _buflen) {
282 int res;
283 unsigned char *buf = _buf;
284 size_t buflen = _buflen;
285
286 if (create_port_host_opt && !coap_host_is_unix_domain(&uri->host)) {
287 int add_option = 0;
288
289 if (dst && uri->host.length) {
290#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
291 char addr[INET6_ADDRSTRLEN];
292#else /* WITH_LWIP || WITH_CONTIKI */
293 char addr[40];
294#endif /* WITH_LWIP || WITH_CONTIKI */
295
296 /* Add in UriHost if not match (need to strip off &iface) */
297 size_t uri_host_len = uri->host.length;
298 const uint8_t *cp = uri->host.s;
299
300 /* Unfortunately not null terminated */
301 for (size_t i = 0; i < uri_host_len; i++) {
302 if (cp[i] == '%') {
303 /* %iface specified in host name */
304 uri_host_len = i;
305 break;
306 }
307 }
308
309 if (coap_print_ip_addr(dst, addr, sizeof(addr)) &&
310 (strlen(addr) != uri_host_len ||
311 memcmp(addr, uri->host.s, uri_host_len) != 0)) {
312 /* add Uri-Host */
313 coap_insert_optlist(optlist_chain,
314 coap_new_optlist(COAP_OPTION_URI_HOST,
315 uri->host.length,
316 uri->host.s));
317 }
318 }
319 /* Add in UriPort if not default */
320 switch ((int)uri->scheme) {
321 case COAP_URI_SCHEME_HTTP:
322 case COAP_URI_SCHEME_COAP_WS:
323 if (uri->port != 80)
324 add_option = 1;
325 break;
326 case COAP_URI_SCHEME_HTTPS:
327 case COAP_URI_SCHEME_COAPS_WS:
328 if (uri->port != 443)
329 add_option = 1;
330 break;
331 default:
332 if (uri->port != (coap_uri_scheme_is_secure(uri) ? COAPS_DEFAULT_PORT :
333 COAP_DEFAULT_PORT))
334 add_option = 1;
335 break;
336 }
337 if (add_option)
338 coap_insert_optlist(optlist_chain,
339 coap_new_optlist(COAP_OPTION_URI_PORT,
340 coap_encode_var_safe(buf, 4,
341 (uri->port & 0xffff)),
342 buf));
343 }
344
345 if (uri->path.length) {
346 if (uri->path.length > buflen)
347 coap_log_warn("URI path will be truncated (max buffer %zu)\n",
348 buflen);
349 res = coap_split_path(uri->path.s, uri->path.length, buf, &buflen);
350 if (res < 0)
351 return -1;
352
353 while (res--) {
354 coap_insert_optlist(optlist_chain,
355 coap_new_optlist(COAP_OPTION_URI_PATH,
356 coap_opt_length(buf),
357 coap_opt_value(buf)));
358
359 buf += coap_opt_size(buf);
360 }
361 }
362
363 if (uri->query.length) {
364 buflen = _buflen;
365 buf = _buf;
366 if (uri->query.length > buflen)
367 coap_log_warn("URI query will be truncated (max buffer %zu)\n",
368 buflen);
369 res = coap_split_query(uri->query.s, uri->query.length, buf, &buflen);
370 if (res < 0)
371 return -1;
372
373 while (res--) {
374 coap_insert_optlist(optlist_chain,
375 coap_new_optlist(COAP_OPTION_URI_QUERY,
376 coap_opt_length(buf),
377 coap_opt_value(buf)));
378
379 buf += coap_opt_size(buf);
380 }
381 }
382 return 0;
383}
384
385 int
386 coap_host_is_unix_domain(const coap_str_const_t *host) {
387 if (host->length >= 3 && host->s[0] == '%' &&
388 host->s[1] == '2' &&
389 (host->s[2] == 'F' || host->s[2] == 'f')) {
390 return 1;
391 }
392 if (host->length >= 1 && host->s[0] == '/')
393 return 1;
394 return 0;
395}
396
404#define hexchar_to_dec(c) ((c) & 0x40 ? ((c) & 0x0F) + 9 : ((c) & 0x0F))
405
418 static void
419 decode_segment(const uint8_t *seg, size_t length, unsigned char *buf) {
420
421 while (length--) {
422
423 if (*seg == '%') {
424 *buf = (hexchar_to_dec(seg[1]) << 4) + hexchar_to_dec(seg[2]);
425
426 seg += 2;
427 length -= 2;
428 } else {
429 *buf = *seg;
430 }
431
432 ++buf;
433 ++seg;
434 }
435}
436
442 static int
443 check_segment(const uint8_t *s, size_t length, size_t *segment_size) {
444 size_t n = 0;
445
446 while (length) {
447 if (*s == '%') {
448 if (length < 2 || !(isxdigit(s[1]) && isxdigit(s[2])))
449 return -1;
450
451 s += 2;
452 length -= 2;
453 }
454
455 ++s;
456 ++n;
457 --length;
458 }
459
460 *segment_size = n;
461
462 return 0;
463}
464
485 static int
486 make_decoded_option(const uint8_t *s, size_t length,
487 unsigned char *buf, size_t buflen, size_t *optionsize) {
488 int res;
489 size_t segmentlen;
490 size_t written;
491
492 if (!buflen) {
493 coap_log_debug("make_decoded_option(): buflen is 0!\n");
494 return -1;
495 }
496
497 res = check_segment(s, length, &segmentlen);
498 if (res < 0)
499 return -1;
500
501 /* write option header using delta 0 and length res */
502 written = coap_opt_setheader(buf, buflen, 0, segmentlen);
503
504 assert(written <= buflen);
505
506 if (!written) /* encoding error */
507 return -1;
508
509 buf += written; /* advance past option type/length */
510 buflen -= written;
511
512 if (buflen < segmentlen) {
513 coap_log_debug("buffer too small for option\n");
514 return -1;
515 }
516
517 decode_segment(s, length, buf);
518
519 *optionsize = written + segmentlen;
520
521 return 0;
522}
523
524
525#ifndef min
526#define min(a,b) ((a) < (b) ? (a) : (b))
527#endif
528
529 typedef void (*segment_handler_t)(const uint8_t *, size_t, void *);
530
534 COAP_STATIC_INLINE int
535 dots(const uint8_t *s, size_t len) {
536 return len && *s == '.' && (len == 1 || (len == 2 && *(s+1) == '.'));
537}
538
550 static size_t
551 coap_split_path_impl(const uint8_t *s, size_t length,
552 segment_handler_t h, void *data) {
553
554 const uint8_t *p, *q;
555
556 p = q = s;
557 while (length > 0 && !strnchr((const uint8_t *)"?#", 2, *q)) {
558 if (*q == '/') { /* start new segment */
559
560 if (!dots(p, q - p)) {
561 h(p, q - p, data);
562 }
563
564 p = q + 1;
565 }
566
567 q++;
568 length--;
569 }
570
571 /* write last segment */
572 if (!dots(p, q - p)) {
573 h(p, q - p, data);
574 }
575
576 return q - s;
577}
578
579 struct cnt_str {
580 coap_string_t buf;
581 int n;
582};
583
584 static void
585 write_option(const uint8_t *s, size_t len, void *data) {
586 struct cnt_str *state = (struct cnt_str *)data;
587 int res;
588 size_t optionsize;
589 assert(state);
590
591 res = make_decoded_option(s, len, state->buf.s, state->buf.length, &optionsize);
592 if (res == 0) {
593 state->buf.s += optionsize;
594 state->buf.length -= optionsize;
595 state->n++;
596 }
597}
598
599 int
600 coap_split_path(const uint8_t *s, size_t length,
601 unsigned char *buf, size_t *buflen) {
602 struct cnt_str tmp = { { *buflen, buf }, 0 };
603
604 coap_split_path_impl(s, length, write_option, &tmp);
605
606 *buflen = *buflen - tmp.buf.length;
607
608 return tmp.n;
609}
610
611 int
612 coap_split_query(const uint8_t *s, size_t length,
613 unsigned char *buf, size_t *buflen) {
614 struct cnt_str tmp = { { *buflen, buf }, 0 };
615 const uint8_t *p;
616
617 p = s;
618 while (length > 0 && *s != '#') {
619 if (*s == '&') { /* start new query element */
620 write_option(p, s - p, &tmp);
621 p = s + 1;
622 }
623
624 s++;
625 length--;
626 }
627
628 /* write last query element */
629 write_option(p, s - p, &tmp);
630
631 *buflen = *buflen - tmp.buf.length;
632 return tmp.n;
633}
634
635#define URI_DATA(uriobj) ((unsigned char *)(uriobj) + sizeof(coap_uri_t))
636
637 coap_uri_t *
638 coap_new_uri(const uint8_t *uri, unsigned int length) {
639 unsigned char *result;
640
641 result = (unsigned char *)coap_malloc_type(COAP_STRING, length + 1 + sizeof(coap_uri_t));
642
643 if (!result)
644 return NULL;
645
646 memcpy(URI_DATA(result), uri, length);
647 URI_DATA(result)[length] = '\0'; /* make it zero-terminated */
648
649 if (coap_split_uri(URI_DATA(result), length, (coap_uri_t *)result) < 0) {
650 coap_free_type(COAP_STRING, result);
651 return NULL;
652 }
653 return (coap_uri_t *)result;
654}
655
656 coap_uri_t *
657 coap_clone_uri(const coap_uri_t *uri) {
658 coap_uri_t *result;
659 uint8_t *p;
660
661 if (!uri)
662 return NULL;
663
664 result = (coap_uri_t *)coap_malloc_type(COAP_STRING, uri->query.length + uri->host.length +
665 uri->path.length + sizeof(coap_uri_t) + 1);
666
667 if (!result)
668 return NULL;
669
670 memset(result, 0, sizeof(coap_uri_t));
671
672 result->port = uri->port;
673
674 if (uri->host.length) {
675 result->host.s = p = URI_DATA(result);
676 result->host.length = uri->host.length;
677
678 memcpy(p, uri->host.s, uri->host.length);
679 }
680
681 if (uri->path.length) {
682 result->path.s = p = URI_DATA(result) + uri->host.length;
683 result->path.length = uri->path.length;
684
685 memcpy(p, uri->path.s, uri->path.length);
686 }
687
688 if (uri->query.length) {
689 result->query.s = p = URI_DATA(result) + uri->host.length + uri->path.length;
690 result->query.length = uri->query.length;
691
692 memcpy(p, uri->query.s, uri->query.length);
693 }
694
695 return result;
696}
697
698 void
699 coap_delete_uri(coap_uri_t *uri) {
700 coap_free_type(COAP_STRING, uri);
701}
702
703 COAP_STATIC_INLINE int
704 is_unescaped_in_path(const uint8_t c) {
705 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
706 (c >= '0' && c <= '9') || c == '-' || c == '.' || c == '_' ||
707 c == '~' || c == '!' || c == '$' || c == '\'' || c == '(' ||
708 c == ')' || c == '*' || c == '+' || c == ',' || c == ';' ||
709 c=='=' || c==':' || c=='@' || c == '&';
710}
711
712 COAP_STATIC_INLINE int
713 is_unescaped_in_query(const uint8_t c) {
714 return is_unescaped_in_path(c) || c=='/' || c=='?';
715}
716
717 coap_string_t *
718 coap_get_query(const coap_pdu_t *request) {
719 coap_opt_iterator_t opt_iter;
720 coap_opt_filter_t f;
721 coap_opt_t *q;
722 coap_string_t *query = NULL;
723 size_t length = 0;
724 static const uint8_t hex[] = "0123456789ABCDEF";
725
726 coap_option_filter_clear(&f);
727 coap_option_filter_set(&f, COAP_OPTION_URI_QUERY);
728 coap_option_iterator_init(request, &opt_iter, &f);
729 while ((q = coap_option_next(&opt_iter))) {
730 uint16_t seg_len = coap_opt_length(q), i;
731 const uint8_t *seg= coap_opt_value(q);
732 for (i = 0; i < seg_len; i++) {
733 if (is_unescaped_in_query(seg[i]))
734 length += 1;
735 else
736 length += 3;
737 }
738 length += 1;
739 }
740 if (length > 0)
741 length -= 1;
742 if (length > 0) {
743 query = coap_new_string(length);
744 if (query) {
745 query->length = length;
746 unsigned char *s = query->s;
747 coap_option_iterator_init(request, &opt_iter, &f);
748 while ((q = coap_option_next(&opt_iter))) {
749 if (s != query->s)
750 *s++ = '&';
751 uint16_t seg_len = coap_opt_length(q), i;
752 const uint8_t *seg= coap_opt_value(q);
753 for (i = 0; i < seg_len; i++) {
754 if (is_unescaped_in_query(seg[i])) {
755 *s++ = seg[i];
756 } else {
757 *s++ = '%';
758 *s++ = hex[seg[i]>>4];
759 *s++ = hex[seg[i]&0x0F];
760 }
761 }
762 }
763 }
764 }
765 return query;
766}
767
768 coap_string_t *
769 coap_get_uri_path(const coap_pdu_t *request) {
770 coap_opt_iterator_t opt_iter;
771 coap_opt_filter_t f;
772 coap_opt_t *q;
773 coap_string_t *uri_path = NULL;
774 size_t length = 0;
775 static const uint8_t hex[] = "0123456789ABCDEF";
776
777 q = coap_check_option(request, COAP_OPTION_PROXY_URI, &opt_iter);
778 if (q) {
779 coap_uri_t uri;
780
781 if (coap_split_proxy_uri(coap_opt_value(q),
782 coap_opt_length(q), &uri) < 0) {
783 return NULL;
784 }
785 uri_path = coap_new_string(uri.path.length);
786 if (uri_path) {
787 memcpy(uri_path->s, uri.path.s, uri.path.length);
788 }
789 return uri_path;
790 }
791
792 coap_option_filter_clear(&f);
793 coap_option_filter_set(&f, COAP_OPTION_URI_PATH);
794 coap_option_iterator_init(request, &opt_iter, &f);
795 while ((q = coap_option_next(&opt_iter))) {
796 uint16_t seg_len = coap_opt_length(q), i;
797 const uint8_t *seg= coap_opt_value(q);
798 for (i = 0; i < seg_len; i++) {
799 if (is_unescaped_in_path(seg[i]))
800 length += 1;
801 else
802 length += 3;
803 }
804 /* bump for the leading "/" */
805 length += 1;
806 }
807 /* The first entry does not have a leading "/" */
808 if (length > 0)
809 length -= 1;
810
811 /* if 0, either no URI_PATH Option, or the first one was empty */
812 uri_path = coap_new_string(length);
813 if (uri_path) {
814 uri_path->length = length;
815 unsigned char *s = uri_path->s;
816 int n = 0;
817 coap_option_iterator_init(request, &opt_iter, &f);
818 while ((q = coap_option_next(&opt_iter))) {
819 if (n++) {
820 *s++ = '/';
821 }
822 uint16_t seg_len = coap_opt_length(q), i;
823 const uint8_t *seg= coap_opt_value(q);
824 for (i = 0; i < seg_len; i++) {
825 if (is_unescaped_in_path(seg[i])) {
826 *s++ = seg[i];
827 } else {
828 *s++ = '%';
829 *s++ = hex[seg[i]>>4];
830 *s++ = hex[seg[i]&0x0F];
831 }
832 }
833 }
834 }
835 return uri_path;
836}
INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN
Definition: coap_debug.c:211
coap_internal.h
Pulls together all the internal only header files.
COAP_STRING
@ COAP_STRING
Definition: coap_mem.h:38
coap_malloc_type
void * coap_malloc_type(coap_memory_tag_t type, size_t size)
Allocates a chunk of size bytes and returns a pointer to the newly allocated memory.
coap_free_type
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
coap_opt_size
size_t coap_opt_size(const coap_opt_t *opt)
Returns the size of the given option, taking into account a possible option jump.
Definition: coap_option.c:284
coap_opt_t
uint8_t coap_opt_t
Use byte-oriented access methods here because sliding a complex struct coap_opt_t over the data buffe...
Definition: coap_option.h:26
coap_tcp_is_supported
int coap_tcp_is_supported(void)
Check whether TCP is available.
Definition: coap_tcp.c:37
is_unescaped_in_path
COAP_STATIC_INLINE int is_unescaped_in_path(const uint8_t c)
Definition: coap_uri.c:704
decode_segment
static void decode_segment(const uint8_t *seg, size_t length, unsigned char *buf)
Decodes percent-encoded characters while copying the string seg of size length to buf.
Definition: coap_uri.c:419
is_unescaped_in_query
COAP_STATIC_INLINE int is_unescaped_in_query(const uint8_t c)
Definition: coap_uri.c:713
dots
COAP_STATIC_INLINE int dots(const uint8_t *s, size_t len)
Checks if path segment s consists of one or two dots.
Definition: coap_uri.c:535
coap_split_path_impl
static size_t coap_split_path_impl(const uint8_t *s, size_t length, segment_handler_t h, void *data)
Splits the given string into segments.
Definition: coap_uri.c:551
strnchr
COAP_STATIC_INLINE const uint8_t * strnchr(const uint8_t *s, size_t len, unsigned char c)
A length-safe version of strchr().
Definition: coap_uri.c:39
check_segment
static int check_segment(const uint8_t *s, size_t length, size_t *segment_size)
Runs through the given path (or query) segment and checks if percent-encodings are correct.
Definition: coap_uri.c:443
write_option
static void write_option(const uint8_t *s, size_t len, void *data)
Definition: coap_uri.c:585
coap_delete_uri
void coap_delete_uri(coap_uri_t *uri)
Removes the specified coap_uri_t object.
Definition: coap_uri.c:699
coap_split_uri_sub
static int coap_split_uri_sub(const uint8_t *str_var, size_t len, coap_uri_t *uri, coap_uri_check_t check_proxy)
Definition: coap_uri.c:63
hexchar_to_dec
#define hexchar_to_dec(c)
Calculates decimal value from hexadecimal ASCII character given in c.
Definition: coap_uri.c:404
make_decoded_option
static int make_decoded_option(const uint8_t *s, size_t length, unsigned char *buf, size_t buflen, size_t *optionsize)
Writes a coap option from given string s to buf.
Definition: coap_uri.c:486
coap_uri_check_t
coap_uri_check_t
Definition: coap_uri.c:46
COAP_URI_CHECK_URI
@ COAP_URI_CHECK_URI
Definition: coap_uri.c:47
COAP_URI_CHECK_PROXY
@ COAP_URI_CHECK_PROXY
Definition: coap_uri.c:48
coap_clone_uri
coap_uri_t * coap_clone_uri(const coap_uri_t *uri)
Clones the specified coap_uri_t object.
Definition: coap_uri.c:657
URI_DATA
#define URI_DATA(uriobj)
Definition: coap_uri.c:635
coap_new_uri
coap_uri_t * coap_new_uri(const uint8_t *uri, unsigned int length)
Creates a new coap_uri_t object from the specified URI.
Definition: coap_uri.c:638
coap_host_is_unix_domain
int coap_host_is_unix_domain(const coap_str_const_t *host)
Determines from the host whether this is a Unix Domain socket request.
Definition: coap_uri.c:386
segment_handler_t
void(* segment_handler_t)(const uint8_t *, size_t, void *)
Definition: coap_uri.c:529
coap_uri_scheme_is_secure
static int coap_uri_scheme_is_secure(const coap_uri_t *uri)
Definition: coap_uri.h:79
COAP_URI_SCHEME_COAPS_WS
@ COAP_URI_SCHEME_COAPS_WS
Definition: coap_uri.h:36
COAP_URI_SCHEME_COAPS_TCP
@ COAP_URI_SCHEME_COAPS_TCP
Definition: coap_uri.h:32
COAP_URI_SCHEME_COAPS
@ COAP_URI_SCHEME_COAPS
Definition: coap_uri.h:30
COAP_URI_SCHEME_COAP_TCP
@ COAP_URI_SCHEME_COAP_TCP
Definition: coap_uri.h:31
COAP_URI_SCHEME_COAP_WS
@ COAP_URI_SCHEME_COAP_WS
Definition: coap_uri.h:35
COAP_URI_SCHEME_HTTPS
@ COAP_URI_SCHEME_HTTPS
Definition: coap_uri.h:34
COAP_URI_SCHEME_COAP
@ COAP_URI_SCHEME_COAP
Definition: coap_uri.h:29
COAP_URI_SCHEME_LAST
@ COAP_URI_SCHEME_LAST
Definition: coap_uri.h:37
COAP_URI_SCHEME_HTTP
@ COAP_URI_SCHEME_HTTP
Definition: coap_uri.h:33
coap_dtls_is_supported
int coap_dtls_is_supported(void)
Check whether DTLS is available.
Definition: coap_notls.c:23
coap_encode_var_safe
unsigned int coap_encode_var_safe(uint8_t *buf, size_t length, unsigned int val)
Encodes multiple-length byte sequences.
Definition: coap_encode.c:47
coap_log_debug
#define coap_log_debug(...)
Definition: coap_debug.h:120
coap_print_ip_addr
const char * coap_print_ip_addr(const coap_address_t *addr, char *buf, size_t len)
Print the IP address into the defined buffer.
Definition: coap_debug.c:364
coap_log_warn
#define coap_log_warn(...)
Definition: coap_debug.h:102
coap_log_err
#define coap_log_err(...)
Definition: coap_debug.h:96
coap_option_next
coap_opt_t * coap_option_next(coap_opt_iterator_t *oi)
Updates the iterator oi to point to the next option.
Definition: coap_option.c:153
coap_new_optlist
coap_optlist_t * coap_new_optlist(uint16_t number, size_t length, const uint8_t *data)
Create a new optlist entry.
Definition: coap_option.c:511
coap_opt_length
uint32_t coap_opt_length(const coap_opt_t *opt)
Returns the length of the given option.
Definition: coap_option.c:212
coap_option_iterator_init
coap_opt_iterator_t * coap_option_iterator_init(const coap_pdu_t *pdu, coap_opt_iterator_t *oi, const coap_opt_filter_t *filter)
Initializes the given option iterator oi to point to the beginning of the pdu's option list.
Definition: coap_option.c:117
coap_option_filter_clear
void coap_option_filter_clear(coap_opt_filter_t *filter)
Clears filter filter.
Definition: coap_option.c:491
coap_check_option
coap_opt_t * coap_check_option(const coap_pdu_t *pdu, coap_option_num_t number, coap_opt_iterator_t *oi)
Retrieves the first option of number number from pdu.
Definition: coap_option.c:199
coap_insert_optlist
int coap_insert_optlist(coap_optlist_t **head, coap_optlist_t *node)
Adds optlist to the given optlist_chain.
Definition: coap_option.c:571
coap_opt_value
const uint8_t * coap_opt_value(const coap_opt_t *opt)
Returns a pointer to the value of the given option.
Definition: coap_option.c:249
coap_option_filter_set
int coap_option_filter_set(coap_opt_filter_t *filter, coap_option_num_t option)
Sets the corresponding entry for number in filter.
Definition: coap_option.c:496
coap_opt_setheader
size_t coap_opt_setheader(coap_opt_t *opt, size_t maxlen, uint16_t delta, size_t length)
Encodes the given delta and length values into opt.
Definition: coap_option.c:292
COAP_OPTION_URI_HOST
#define COAP_OPTION_URI_HOST
Definition: coap_pdu.h:116
COAP_DEFAULT_PORT
#define COAP_DEFAULT_PORT
Definition: coap_pdu.h:37
COAP_OPTION_URI_QUERY
#define COAP_OPTION_URI_QUERY
Definition: coap_pdu.h:128
COAP_OPTION_URI_PATH
#define COAP_OPTION_URI_PATH
Definition: coap_pdu.h:123
COAPS_DEFAULT_PORT
#define COAPS_DEFAULT_PORT
Definition: coap_pdu.h:38
COAP_OPTION_URI_PORT
#define COAP_OPTION_URI_PORT
Definition: coap_pdu.h:120
COAP_OPTION_PROXY_URI
#define COAP_OPTION_PROXY_URI
Definition: coap_pdu.h:137
COAP_SET_STR
#define COAP_SET_STR(st, l, v)
Definition: coap_str.h:51
coap_new_string
coap_string_t * coap_new_string(size_t size)
Returns a new string object with at least size+1 bytes storage allocated.
Definition: coap_str.c:21
coap_get_uri_path
coap_string_t * coap_get_uri_path(const coap_pdu_t *request)
Extract uri_path string from request PDU.
Definition: coap_uri.c:769
coap_split_path
int coap_split_path(const uint8_t *s, size_t length, unsigned char *buf, size_t *buflen)
Splits the given URI path into segments.
Definition: coap_uri.c:600
coap_split_query
int coap_split_query(const uint8_t *s, size_t length, unsigned char *buf, size_t *buflen)
Splits the given URI query into segments.
Definition: coap_uri.c:612
coap_split_uri
int coap_split_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri)
Parses a given string into URI components.
Definition: coap_uri.c:269
coap_split_proxy_uri
int coap_split_proxy_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri)
Parses a given string into URI components.
Definition: coap_uri.c:274
coap_uri_into_options
int coap_uri_into_options(const coap_uri_t *uri, const coap_address_t *dst, coap_optlist_t **optlist_chain, int create_port_host_opt, uint8_t *_buf, size_t _buflen)
Takes a coap_uri_t and then adds CoAP options into the optlist_chain.
Definition: coap_uri.c:279
coap_get_query
coap_string_t * coap_get_query(const coap_pdu_t *request)
Extract query string from request PDU according to escape rules in 6.5.8.
Definition: coap_uri.c:718
coap_uri_scheme
coap_uri_info_t coap_uri_scheme[COAP_URI_SCHEME_LAST]
Definition: coap_uri.c:51
coap_ws_is_supported
int coap_ws_is_supported(void)
Check whether WebSockets is available.
Definition: coap_ws.c:935
coap_wss_is_supported
int coap_wss_is_supported(void)
Check whether Secure WebSockets is available.
Definition: coap_ws.c:940
COAP_STATIC_INLINE
#define COAP_STATIC_INLINE
Definition: libcoap.h:53
cnt_str
Definition: coap_uri.c:579
cnt_str::n
int n
Definition: coap_uri.c:581
cnt_str::buf
coap_string_t buf
Definition: coap_uri.c:580
coap_address_t
Multi-purpose address abstraction.
Definition: coap_address.h:109
coap_opt_filter_t
Definition: coap_option.h:101
coap_opt_iterator_t
Iterator to run through PDU options.
Definition: coap_option.h:168
coap_optlist_t
Representation of chained list of CoAP options to install.
Definition: coap_option.h:325
coap_pdu_t
structure for CoAP PDUs
Definition: coap_pdu_internal.h:119
coap_str_const_t
CoAP string data definition with const data.
Definition: coap_str.h:46
coap_str_const_t::s
const uint8_t * s
read-only string data
Definition: coap_str.h:48
coap_str_const_t::length
size_t length
length of string
Definition: coap_str.h:47
coap_string_t
CoAP string data definition.
Definition: coap_str.h:38
coap_string_t::s
uint8_t * s
string data
Definition: coap_str.h:40
coap_string_t::length
size_t length
length of string
Definition: coap_str.h:39
coap_uri_info_t
Definition: coap_uri_internal.h:29
coap_uri_info_t::scheme
coap_uri_scheme_t scheme
scheme
Definition: coap_uri_internal.h:33
coap_uri_info_t::port
uint16_t port
default scheme port
Definition: coap_uri_internal.h:31
coap_uri_t
Representation of parsed URI.
Definition: coap_uri.h:65
coap_uri_t::scheme
enum coap_uri_scheme_t scheme
The parsed scheme specifier.
Definition: coap_uri.h:75
coap_uri_t::path
coap_str_const_t path
The complete path if present or {0, NULL}.
Definition: coap_uri.h:68
coap_uri_t::port
uint16_t port
The port in host byte order.
Definition: coap_uri.h:67
coap_uri_t::query
coap_str_const_t query
The complete query if present or {0, NULL}.
Definition: coap_uri.h:71
coap_uri_t::host
coap_str_const_t host
The host part of the URI.
Definition: coap_uri.h:66