libcoap 4.3.5rc1
Loading...
Searching...
No Matches
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-2024 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
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
38COAP_STATIC_INLINE const uint8_t *
39strnchr(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
50
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
62static int
63coap_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));
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) {
121 break;
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;
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;
135 if (!coap_tls_is_supported()) {
136 coap_log_err("coaps+tcp URI scheme not supported in this version of libcoap\n");
137 return -1;
138 }
139 break;
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;
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;
154 /* Not proxy, caught above. For proxy, assume app is doing CoAP <> HTTP mapping. */
155 break;
157 default:
158 coap_log_warn("Unsupported URI type %d\n", uri->scheme);
159 return -1;
160 }
161 /* skip :// */
162 p += 3;
163 len -= 3;
164
165 /* p points to beginning of Uri-Host */
166 q = p;
167 if (len && *p == '[') {
168 /* IPv6 address reference */
169 ++p;
170
171 while (len && *q != ']') {
172 ++q;
173 --len;
174 }
175
176 if (!len || *q != ']' || p == q) {
177 res = -3;
178 goto error;
179 }
180
181 COAP_SET_STR(&uri->host, q - p, p);
182 ++q;
183 --len;
184 } else {
185 /* IPv4 address, FQDN or Unix domain socket */
186 if (len >= 3 && p[0] == '%' && p[1] == '2' &&
187 (p[2] == 'F' || p[2] == 'f')) {
188 /* Unix domain definition */
189 uri->port = 0;
190 is_unix_domain = 1;
191 }
192 while (len && *q != ':' && *q != '/' && *q != '?') {
193 ++q;
194 --len;
195 }
196
197 if (p == q) {
198 res = -3;
199 goto error;
200 }
201
202 COAP_SET_STR(&uri->host, q - p, p);
203 }
204
205 /* check for Uri-Port (invalid for Unix) */
206 if (len && *q == ':') {
207 if (is_unix_domain) {
208 res = -5;
209 goto error;
210 }
211 p = ++q;
212 --len;
213
214 while (len && isdigit(*q)) {
215 ++q;
216 --len;
217 }
218
219 if (p < q) { /* explicit port number given */
220 long uri_port = 0;
221
222 while ((p < q) && (uri_port <= UINT16_MAX))
223 uri_port = uri_port * 10 + (*p++ - '0');
224
225 /* check if port number is in allowed range */
226 if (uri_port > UINT16_MAX) {
227 res = -4;
228 goto error;
229 }
230
231 uri->port = (uint16_t)uri_port;
232 }
233 }
234
235path: /* at this point, p must point to an absolute path */
236
237 if (!len)
238 goto end;
239
240 if (*q == '/') {
241 p = ++q;
242 --len;
243
244 while (len && *q != '?') {
245 ++q;
246 --len;
247 }
248
249 if (p < q) {
250 COAP_SET_STR(&uri->path, q - p, p);
251 p = q;
252 }
253 }
254
255 /* Uri_Query */
256 if (len && *p == '?') {
257 ++p;
258 --len;
259 COAP_SET_STR(&uri->query, len, p);
260 len = 0;
261 }
262
263end:
264 return len ? -1 : 0;
265
266error:
267 return res;
268}
269
270int
271coap_split_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri) {
272 return coap_split_uri_sub(str_var, len, uri, COAP_URI_CHECK_URI);
273}
274
275int
276coap_split_proxy_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri) {
277 return coap_split_uri_sub(str_var, len, uri, COAP_URI_CHECK_PROXY);
278}
279
280int
282 coap_optlist_t **optlist_chain, int create_port_host_opt,
283 uint8_t *_buf, size_t _buflen) {
284 int res;
285 unsigned char *buf = _buf;
286 size_t buflen = _buflen;
287
288 if (create_port_host_opt && !coap_host_is_unix_domain(&uri->host)) {
289 int add_option = 0;
290
291 if (dst && uri->host.length) {
292#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
293 char addr[INET6_ADDRSTRLEN];
294#else /* WITH_LWIP || WITH_CONTIKI */
295 char addr[40];
296#endif /* WITH_LWIP || WITH_CONTIKI */
297
298 /* Add in UriHost if not match (need to strip off &iface) */
299 size_t uri_host_len = uri->host.length;
300 const uint8_t *cp = uri->host.s;
301
302 /* Unfortunately not null terminated */
303 for (size_t i = 0; i < uri_host_len; i++) {
304 if (cp[i] == '%') {
305 /* %iface specified in host name */
306 uri_host_len = i;
307 break;
308 }
309 }
310
311 if (coap_print_ip_addr(dst, addr, sizeof(addr)) &&
312 (strlen(addr) != uri_host_len ||
313 memcmp(addr, uri->host.s, uri_host_len) != 0)) {
314 /* add Uri-Host */
315 coap_insert_optlist(optlist_chain,
317 uri->host.length,
318 uri->host.s));
319 }
320 }
321 /* Add in UriPort if not default */
322 switch ((int)uri->scheme) {
325 if (uri->port != 80)
326 add_option = 1;
327 break;
330 if (uri->port != 443)
331 add_option = 1;
332 break;
333 default:
336 add_option = 1;
337 break;
338 }
339 if (add_option)
340 coap_insert_optlist(optlist_chain,
343 (uri->port & 0xffff)),
344 buf));
345 }
346
347 if (uri->path.length) {
348 if (uri->path.length > buflen)
349 coap_log_warn("URI path will be truncated (max buffer %zu)\n",
350 buflen);
351 res = coap_split_path(uri->path.s, uri->path.length, buf, &buflen);
352 if (res < 0)
353 return -1;
354
355 while (res--) {
356 coap_insert_optlist(optlist_chain,
358 coap_opt_length(buf),
359 coap_opt_value(buf)));
360
361 buf += coap_opt_size(buf);
362 }
363 }
364
365 if (uri->query.length) {
366 buflen = _buflen;
367 buf = _buf;
368 if (uri->query.length > buflen)
369 coap_log_warn("URI query will be truncated (max buffer %zu)\n",
370 buflen);
371 res = coap_split_query(uri->query.s, uri->query.length, buf, &buflen);
372 if (res < 0)
373 return -1;
374
375 while (res--) {
376 coap_insert_optlist(optlist_chain,
378 coap_opt_length(buf),
379 coap_opt_value(buf)));
380
381 buf += coap_opt_size(buf);
382 }
383 }
384 return 0;
385}
386
387int
389 if (host->length >= 3 && host->s[0] == '%' &&
390 host->s[1] == '2' &&
391 (host->s[2] == 'F' || host->s[2] == 'f')) {
392 return 1;
393 }
394 if (host->length >= 1 && host->s[0] == '/')
395 return 1;
396 return 0;
397}
398
406#define hexchar_to_dec(c) ((c) & 0x40 ? ((c) & 0x0F) + 9 : ((c) & 0x0F))
407
420static void
421decode_segment(const uint8_t *seg, size_t length, unsigned char *buf) {
422
423 while (length--) {
424
425 if (*seg == '%') {
426 *buf = (hexchar_to_dec(seg[1]) << 4) + hexchar_to_dec(seg[2]);
427
428 seg += 2;
429 length -= 2;
430 } else {
431 *buf = *seg;
432 }
433
434 ++buf;
435 ++seg;
436 }
437}
438
444static int
445check_segment(const uint8_t *s, size_t length, size_t *segment_size) {
446 size_t n = 0;
447
448 while (length) {
449 if (*s == '%') {
450 if (length < 2 || !(isxdigit(s[1]) && isxdigit(s[2])))
451 return -1;
452
453 s += 2;
454 length -= 2;
455 }
456
457 ++s;
458 ++n;
459 --length;
460 }
461
462 *segment_size = n;
463
464 return 0;
465}
466
487static int
488make_decoded_option(const uint8_t *s, size_t length,
489 unsigned char *buf, size_t buflen, size_t *optionsize) {
490 int res;
491 size_t segmentlen;
492 size_t written;
493
494 if (!buflen) {
495 coap_log_debug("make_decoded_option(): buflen is 0!\n");
496 return -1;
497 }
498
499 res = check_segment(s, length, &segmentlen);
500 if (res < 0)
501 return -1;
502
503 /* write option header using delta 0 and length res */
504 written = coap_opt_setheader(buf, buflen, 0, segmentlen);
505
506 assert(written <= buflen);
507
508 if (!written) /* encoding error */
509 return -1;
510
511 buf += written; /* advance past option type/length */
512 buflen -= written;
513
514 if (buflen < segmentlen) {
515 coap_log_debug("buffer too small for option\n");
516 return -1;
517 }
518
519 decode_segment(s, length, buf);
520
521 *optionsize = written + segmentlen;
522
523 return 0;
524}
525
526
527#ifndef min
528#define min(a,b) ((a) < (b) ? (a) : (b))
529#endif
530
531typedef void (*segment_handler_t)(const uint8_t *, size_t, void *);
532
537dots(const uint8_t *s, size_t len) {
538 return len && *s == '.' && (len == 1 || (len == 2 && *(s+1) == '.'));
539}
540
552static size_t
553coap_split_path_impl(const uint8_t *s, size_t length,
554 segment_handler_t h, void *data) {
555
556 const uint8_t *p, *q;
557
558 p = q = s;
559 while (length > 0 && !strnchr((const uint8_t *)"?#", 2, *q)) {
560 if (*q == '/') { /* start new segment */
561
562 if (!dots(p, q - p)) {
563 h(p, q - p, data);
564 }
565
566 p = q + 1;
567 }
568
569 q++;
570 length--;
571 }
572
573 /* write last segment */
574 if (!dots(p, q - p)) {
575 h(p, q - p, data);
576 }
577
578 return q - s;
579}
580
581struct cnt_str {
583 int n;
584};
585
586static void
587write_option(const uint8_t *s, size_t len, void *data) {
588 struct cnt_str *state = (struct cnt_str *)data;
589 int res;
590 size_t optionsize;
591 assert(state);
592
593 res = make_decoded_option(s, len, state->buf.s, state->buf.length, &optionsize);
594 if (res == 0) {
595 state->buf.s += optionsize;
596 state->buf.length -= optionsize;
597 state->n++;
598 }
599}
600
601int
602coap_split_path(const uint8_t *s, size_t length,
603 unsigned char *buf, size_t *buflen) {
604 struct cnt_str tmp = { { *buflen, buf }, 0 };
605
606 coap_split_path_impl(s, length, write_option, &tmp);
607
608 *buflen = *buflen - tmp.buf.length;
609
610 return tmp.n;
611}
612
613int
614coap_split_query(const uint8_t *s, size_t length,
615 unsigned char *buf, size_t *buflen) {
616 struct cnt_str tmp = { { *buflen, buf }, 0 };
617 const uint8_t *p;
618
619 p = s;
620 while (length > 0 && *s != '#') {
621 if (*s == '&') { /* start new query element */
622 write_option(p, s - p, &tmp);
623 p = s + 1;
624 }
625
626 s++;
627 length--;
628 }
629
630 /* write last query element */
631 write_option(p, s - p, &tmp);
632
633 *buflen = *buflen - tmp.buf.length;
634 return tmp.n;
635}
636
637#define URI_DATA(uriobj) ((unsigned char *)(uriobj) + sizeof(coap_uri_t))
638
640coap_new_uri(const uint8_t *uri, unsigned int length) {
641 uint8_t *result;
642 coap_uri_t *out_uri;
643
644 out_uri = (coap_uri_t *)coap_malloc_type(COAP_STRING, length + 1 + sizeof(coap_uri_t));
645
646 if (!out_uri)
647 return NULL;
648
649 result = (uint8_t *)out_uri;
650 memcpy(URI_DATA(result), uri, length);
651 URI_DATA(result)[length] = '\0'; /* make it zero-terminated */
652
653 if (coap_split_uri(URI_DATA(result), length, out_uri) < 0) {
654 coap_free_type(COAP_STRING, out_uri);
655 return NULL;
656 }
657 return out_uri;
658}
659
662 coap_uri_t *result;
663 uint8_t *p;
664
665 if (!uri)
666 return NULL;
667
669 uri->path.length + sizeof(coap_uri_t) + 1);
670
671 if (!result)
672 return NULL;
673
674 memset(result, 0, sizeof(coap_uri_t));
675
676 result->port = uri->port;
677
678 if (uri->host.length) {
679 result->host.s = p = URI_DATA(result);
680 result->host.length = uri->host.length;
681
682 memcpy(p, uri->host.s, uri->host.length);
683 }
684
685 if (uri->path.length) {
686 result->path.s = p = URI_DATA(result) + uri->host.length;
687 result->path.length = uri->path.length;
688
689 memcpy(p, uri->path.s, uri->path.length);
690 }
691
692 if (uri->query.length) {
693 result->query.s = p = URI_DATA(result) + uri->host.length + uri->path.length;
694 result->query.length = uri->query.length;
695
696 memcpy(p, uri->query.s, uri->query.length);
697 }
698
699 return result;
700}
701
702void
706
707static int
708is_unescaped_in_path(const uint8_t c) {
709 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
710 (c >= '0' && c <= '9') || c == '-' || c == '.' || c == '_' ||
711 c == '~' || c == '!' || c == '$' || c == '\'' || c == '(' ||
712 c == ')' || c == '*' || c == '+' || c == ',' || c == ';' ||
713 c=='=' || c==':' || c=='@' || c == '&';
714}
715
716static int
717is_unescaped_in_query(const uint8_t c) {
718 return is_unescaped_in_path(c) || c=='/' || c=='?';
719}
720
722coap_get_query(const coap_pdu_t *request) {
723 coap_opt_iterator_t opt_iter;
725 coap_opt_t *q;
726 coap_string_t *query = NULL;
727 size_t length = 0;
728 static const uint8_t hex[] = "0123456789ABCDEF";
729
732 coap_option_iterator_init(request, &opt_iter, &f);
733 while ((q = coap_option_next(&opt_iter))) {
734 uint16_t seg_len = coap_opt_length(q), i;
735 const uint8_t *seg= coap_opt_value(q);
736 for (i = 0; i < seg_len; i++) {
737 if (is_unescaped_in_query(seg[i]))
738 length += 1;
739 else
740 length += 3;
741 }
742 length += 1;
743 }
744 if (length > 0)
745 length -= 1;
746 if (length > 0) {
747 query = coap_new_string(length);
748 if (query) {
749 query->length = length;
750 unsigned char *s = query->s;
751 coap_option_iterator_init(request, &opt_iter, &f);
752 while ((q = coap_option_next(&opt_iter))) {
753 if (s != query->s)
754 *s++ = '&';
755 uint16_t seg_len = coap_opt_length(q), i;
756 const uint8_t *seg= coap_opt_value(q);
757 for (i = 0; i < seg_len; i++) {
758 if (is_unescaped_in_query(seg[i])) {
759 *s++ = seg[i];
760 } else {
761 *s++ = '%';
762 *s++ = hex[seg[i]>>4];
763 *s++ = hex[seg[i]&0x0F];
764 }
765 }
766 }
767 }
768 }
769 return query;
770}
771
774 coap_opt_iterator_t opt_iter;
776 coap_opt_t *q;
777 coap_string_t *uri_path = NULL;
778 size_t length = 0;
779 static const uint8_t hex[] = "0123456789ABCDEF";
780
781 q = coap_check_option(request, COAP_OPTION_PROXY_URI, &opt_iter);
782 if (q) {
783 coap_uri_t uri;
784
786 coap_opt_length(q), &uri) < 0) {
787 return NULL;
788 }
789 uri_path = coap_new_string(uri.path.length);
790 if (uri_path) {
791 memcpy(uri_path->s, uri.path.s, uri.path.length);
792 }
793 return uri_path;
794 }
795
798 coap_option_iterator_init(request, &opt_iter, &f);
799 while ((q = coap_option_next(&opt_iter))) {
800 uint16_t seg_len = coap_opt_length(q), i;
801 const uint8_t *seg= coap_opt_value(q);
802 for (i = 0; i < seg_len; i++) {
803 if (is_unescaped_in_path(seg[i]))
804 length += 1;
805 else
806 length += 3;
807 }
808 /* bump for the leading "/" */
809 length += 1;
810 }
811 /* The first entry does not have a leading "/" */
812 if (length > 0)
813 length -= 1;
814
815 /* if 0, either no URI_PATH Option, or the first one was empty */
816 uri_path = coap_new_string(length);
817 if (uri_path) {
818 uri_path->length = length;
819 unsigned char *s = uri_path->s;
820 int n = 0;
821 coap_option_iterator_init(request, &opt_iter, &f);
822 while ((q = coap_option_next(&opt_iter))) {
823 if (n++) {
824 *s++ = '/';
825 }
826 uint16_t seg_len = coap_opt_length(q), i;
827 const uint8_t *seg= coap_opt_value(q);
828 for (i = 0; i < seg_len; i++) {
829 if (is_unescaped_in_path(seg[i])) {
830 *s++ = seg[i];
831 } else {
832 *s++ = '%';
833 *s++ = hex[seg[i]>>4];
834 *s++ = hex[seg[i]&0x0F];
835 }
836 }
837 }
838 }
839 return uri_path;
840}
#define INET6_ADDRSTRLEN
Definition coap_debug.c:226
Library specific build wrapper for coap_internal.h.
@ COAP_STRING
Definition coap_mem.h:38
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.
void coap_free_type(coap_memory_tag_t type, void *p)
Releases the memory that was allocated by coap_malloc_type().
size_t coap_opt_size(const coap_opt_t *opt)
Returns the size of the given option, taking into account a possible option jump.
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
int coap_tcp_is_supported(void)
Check whether TCP is available.
Definition coap_tcp.c:20
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:421
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:537
static int is_unescaped_in_query(const uint8_t c)
Definition coap_uri.c:717
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:553
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
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:445
static void write_option(const uint8_t *s, size_t len, void *data)
Definition coap_uri.c:587
void coap_delete_uri(coap_uri_t *uri)
Removes the specified coap_uri_t object.
Definition coap_uri.c:703
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
#define hexchar_to_dec(c)
Calculates decimal value from hexadecimal ASCII character given in c.
Definition coap_uri.c:406
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:488
static int is_unescaped_in_path(const uint8_t c)
Definition coap_uri.c:708
coap_uri_check_t
Definition coap_uri.c:46
@ COAP_URI_CHECK_URI
Definition coap_uri.c:47
@ COAP_URI_CHECK_PROXY
Definition coap_uri.c:48
coap_uri_t * coap_clone_uri(const coap_uri_t *uri)
Clones the specified coap_uri_t object.
Definition coap_uri.c:661
#define URI_DATA(uriobj)
Definition coap_uri.c:637
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:640
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:388
void(* segment_handler_t)(const uint8_t *, size_t, void *)
Definition coap_uri.c:531
static int coap_uri_scheme_is_secure(const coap_uri_t *uri)
Definition coap_uri.h:79
@ COAP_URI_SCHEME_COAPS_WS
Definition coap_uri.h:36
@ COAP_URI_SCHEME_COAPS_TCP
Definition coap_uri.h:32
@ COAP_URI_SCHEME_COAPS
Definition coap_uri.h:30
@ COAP_URI_SCHEME_COAP_TCP
Definition coap_uri.h:31
@ COAP_URI_SCHEME_COAP_WS
Definition coap_uri.h:35
@ COAP_URI_SCHEME_HTTPS
Definition coap_uri.h:34
@ COAP_URI_SCHEME_COAP
Definition coap_uri.h:29
@ COAP_URI_SCHEME_LAST
Definition coap_uri.h:37
@ COAP_URI_SCHEME_HTTP
Definition coap_uri.h:33
int coap_tls_is_supported(void)
Check whether TLS is available.
Definition coap_notls.c:41
int coap_dtls_is_supported(void)
Check whether DTLS is available.
Definition coap_notls.c:36
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
#define coap_log_debug(...)
Definition coap_debug.h:120
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:409
#define coap_log_warn(...)
Definition coap_debug.h:102
#define coap_log_err(...)
Definition coap_debug.h:96
coap_opt_t * coap_option_next(coap_opt_iterator_t *oi)
Updates the iterator oi to point to the next option.
coap_optlist_t * coap_new_optlist(uint16_t number, size_t length, const uint8_t *data)
Create a new optlist entry.
uint32_t coap_opt_length(const coap_opt_t *opt)
Returns the length of the given option.
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.
void coap_option_filter_clear(coap_opt_filter_t *filter)
Clears filter filter.
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.
int coap_insert_optlist(coap_optlist_t **head, coap_optlist_t *node)
Adds optlist to the given optlist_chain.
const uint8_t * coap_opt_value(const coap_opt_t *opt)
Returns a pointer to the value of the given option.
int coap_option_filter_set(coap_opt_filter_t *filter, coap_option_num_t option)
Sets the corresponding entry for number in filter.
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.
#define COAP_OPTION_URI_HOST
Definition coap_pdu.h:120
#define COAP_DEFAULT_PORT
Definition coap_pdu.h:37
#define COAP_OPTION_URI_QUERY
Definition coap_pdu.h:132
#define COAP_OPTION_URI_PATH
Definition coap_pdu.h:127
#define COAPS_DEFAULT_PORT
Definition coap_pdu.h:38
#define COAP_OPTION_URI_PORT
Definition coap_pdu.h:124
#define COAP_OPTION_PROXY_URI
Definition coap_pdu.h:141
#define COAP_SET_STR(st, l, v)
Definition coap_str.h:51
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_string_t * coap_get_uri_path(const coap_pdu_t *request)
Extract uri_path string from request PDU.
Definition coap_uri.c:773
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:602
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:614
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:271
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:276
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:281
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:722
coap_uri_info_t coap_uri_scheme[COAP_URI_SCHEME_LAST]
Definition coap_uri.c:51
int coap_ws_is_supported(void)
Check whether WebSockets is available.
Definition coap_ws.c:932
int coap_wss_is_supported(void)
Check whether Secure WebSockets is available.
Definition coap_ws.c:937
#define COAP_STATIC_INLINE
Definition libcoap.h:53
int n
Definition coap_uri.c:583
coap_string_t buf
Definition coap_uri.c:582
Multi-purpose address abstraction.
Iterator to run through PDU options.
Representation of chained list of CoAP options to install.
structure for CoAP PDUs
CoAP string data definition with const data.
Definition coap_str.h:46
const uint8_t * s
read-only string data
Definition coap_str.h:48
size_t length
length of string
Definition coap_str.h:47
CoAP string data definition.
Definition coap_str.h:38
uint8_t * s
string data
Definition coap_str.h:40
size_t length
length of string
Definition coap_str.h:39
coap_uri_scheme_t scheme
scheme
uint16_t port
default scheme port
Representation of parsed URI.
Definition coap_uri.h:65
enum coap_uri_scheme_t scheme
The parsed scheme specifier.
Definition coap_uri.h:75
coap_str_const_t path
The complete path if present or {0, NULL}.
Definition coap_uri.h:68
uint16_t port
The port in host byte order.
Definition coap_uri.h:67
coap_str_const_t query
The complete query if present or {0, NULL}.
Definition coap_uri.h:71
coap_str_const_t host
The host part of the URI.
Definition coap_uri.h:66