libcoap 4.3.3
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-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
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_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;
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;
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
268int
269coap_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
273int
274coap_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
278int
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,
315 uri->host.length,
316 uri->host.s));
317 }
318 }
319 /* Add in UriPort if not default */
320 switch ((int)uri->scheme) {
323 if (uri->port != 80)
324 add_option = 1;
325 break;
328 if (uri->port != 443)
329 add_option = 1;
330 break;
331 default:
334 add_option = 1;
335 break;
336 }
337 if (add_option)
338 coap_insert_optlist(optlist_chain,
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,
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,
376 coap_opt_length(buf),
377 coap_opt_value(buf)));
378
379 buf += coap_opt_size(buf);
380 }
381 }
382 return 0;
383}
384
385int
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
418static void
419decode_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
442static int
443check_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
485static int
486make_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
529typedef void (*segment_handler_t)(const uint8_t *, size_t, void *);
530
535dots(const uint8_t *s, size_t len) {
536 return len && *s == '.' && (len == 1 || (len == 2 && *(s+1) == '.'));
537}
538
550static size_t
551coap_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
579struct cnt_str {
581 int n;
582};
583
584static void
585write_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
599int
600coap_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
611int
612coap_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
638coap_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) {
651 return NULL;
652 }
653 return (coap_uri_t *)result;
654}
655
658 coap_uri_t *result;
659 uint8_t *p;
660
661 if (!uri)
662 return NULL;
663
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
698void
702
704is_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
713is_unescaped_in_query(const uint8_t c) {
714 return is_unescaped_in_path(c) || c=='/' || c=='?';
715}
716
718coap_get_query(const coap_pdu_t *request) {
719 coap_opt_iterator_t opt_iter;
721 coap_opt_t *q;
722 coap_string_t *query = NULL;
723 size_t length = 0;
724 static const uint8_t hex[] = "0123456789ABCDEF";
725
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
770 coap_opt_iterator_t opt_iter;
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
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
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}
#define INET6_ADDRSTRLEN
Definition coap_debug.c:211
Pulls together all the internal only header files.
@ 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:37
COAP_STATIC_INLINE int is_unescaped_in_path(const uint8_t c)
Definition coap_uri.c:704
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
COAP_STATIC_INLINE int is_unescaped_in_query(const uint8_t c)
Definition coap_uri.c:713
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
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
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:443
static void write_option(const uint8_t *s, size_t len, void *data)
Definition coap_uri.c:585
void coap_delete_uri(coap_uri_t *uri)
Removes the specified coap_uri_t object.
Definition coap_uri.c:699
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:404
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
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:657
#define URI_DATA(uriobj)
Definition coap_uri.c:635
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
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
void(* segment_handler_t)(const uint8_t *, size_t, void *)
Definition coap_uri.c:529
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_dtls_is_supported(void)
Check whether DTLS is available.
Definition coap_notls.c:23
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:364
#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:116
#define COAP_DEFAULT_PORT
Definition coap_pdu.h:37
#define COAP_OPTION_URI_QUERY
Definition coap_pdu.h:128
#define COAP_OPTION_URI_PATH
Definition coap_pdu.h:123
#define COAPS_DEFAULT_PORT
Definition coap_pdu.h:38
#define COAP_OPTION_URI_PORT
Definition coap_pdu.h:120
#define COAP_OPTION_PROXY_URI
Definition coap_pdu.h:137
#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:769
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
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
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
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
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_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_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:935
int coap_wss_is_supported(void)
Check whether Secure WebSockets is available.
Definition coap_ws.c:940
#define COAP_STATIC_INLINE
Definition libcoap.h:53
int n
Definition coap_uri.c:581
coap_string_t buf
Definition coap_uri.c:580
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