libcoap 4.3.4
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
62/*
63 * Returns 0 All OK
64 * -1 Insufficient / Invalid parameters
65 * -2 No '://'
66 * -3 Ipv6 definition error or no host defined after scheme://
67 * -4 Invalid port value
68 * -5 Port defined for Unix domain
69 * -6 Hostname > 255 chars
70 */
71static int
72coap_split_uri_sub(const uint8_t *str_var,
73 size_t len,
74 coap_uri_t *uri,
75 coap_uri_check_t check_proxy) {
76 const uint8_t *p, *q;
77 int res = 0;
78 size_t i;
79 int is_unix_domain = 0;
80
81 if (!str_var || !uri || len == 0)
82 return -1;
83
84 memset(uri, 0, sizeof(coap_uri_t));
86
87 /* search for scheme */
88 p = str_var;
89 if (*p == '/') {
90 /* no scheme, host or port */
91 if (check_proxy == COAP_URI_CHECK_PROXY) {
92 /* Must have ongoing host if proxy definition */
93 return -1;
94 }
95 q = p;
96 goto path;
97 }
98
99 /* find scheme terminating :// */
100 while (len >= 3 && !(p[0] == ':' && p[1] == '/' && p[2] == '/')) {
101 ++p;
102 --len;
103 }
104 if (len < 3) {
105 /* scheme not defined with a :// terminator */
106 res = -2;
107 goto error;
108 }
109 for (i = 0; i < COAP_URI_SCHEME_LAST; i++) {
110 if ((p - str_var) == (int)strlen(coap_uri_scheme[i].name) &&
111 memcmp(str_var, coap_uri_scheme[i].name, p - str_var) == 0) {
112 if (check_proxy != COAP_URI_CHECK_PROXY && coap_uri_scheme[i].proxy_only) {
113 coap_log_err("%.*s URI scheme not enabled (not a proxy)\n",
114 (int)(p - str_var), str_var);
115 return -1;
116 }
117 uri->scheme = coap_uri_scheme[i].scheme;
118 uri->port = coap_uri_scheme[i].port;
119 break;
120 }
121 }
122 if (i == COAP_URI_SCHEME_LAST) {
123 /* scheme unknown */
124 coap_log_err("%.*s URI scheme unknown\n", (int)(p - str_var), str_var);
125 res = -1;
126 goto error;
127 }
128 switch (uri->scheme) {
130 break;
132 if (!coap_dtls_is_supported()) {
133 coap_log_err("coaps URI scheme not supported in this version of libcoap\n");
134 return -1;
135 }
136 break;
138 if (!coap_tcp_is_supported()) {
139 coap_log_err("coap+tcp URI scheme not supported in this version of libcoap\n");
140 return -1;
141 }
142 break;
144 if (!coap_tcp_is_supported()) {
145 coap_log_err("coaps+tcp URI scheme not supported in this version of libcoap\n");
146 return -1;
147 }
148 break;
150 if (!coap_ws_is_supported()) {
151 coap_log_err("coap+ws URI scheme not supported in this version of libcoap\n");
152 return -1;
153 }
154 break;
156 if (!coap_wss_is_supported()) {
157 coap_log_err("coaps+ws URI scheme not supported in this version of libcoap\n");
158 return -1;
159 }
160 break;
164 default:
165 coap_log_warn("Unsupported URI type %d\n", uri->scheme);
166 return -1;
167 }
168 /* skip :// */
169 p += 3;
170 len -= 3;
171
172 /* p points to beginning of Uri-Host */
173 q = p;
174 if (len && *p == '[') {
175 /* IPv6 address reference */
176 ++p;
177 ++q;
178 --len;
179
180 while (len && *q != ']' && (isxdigit(*q) || *q == ':')) {
181 ++q;
182 --len;
183 }
184
185 if (!len || *q != ']' || p == q) {
186 res = -3;
187 goto error;
188 }
189
190 COAP_SET_STR(&uri->host, q - p, p);
191 ++q;
192 --len;
193 } else {
194 /* IPv4 address, FQDN or Unix domain socket */
195 if (len >= 3 && p[0] == '%' && p[1] == '2' &&
196 (p[2] == 'F' || p[2] == 'f')) {
197 /* Unix domain definition */
198 uri->port = 0;
199 is_unix_domain = 1;
200 }
201 while (len && *q != ':' && *q != '/' && *q != '?') {
202 ++q;
203 --len;
204 }
205
206 if (p == q) {
207 res = -3;
208 goto error;
209 }
210
211 if ((int)(q - p) > 255) {
212 coap_log_warn("Host name length too long (%d > 255)\n", (int)(q - p));
213 res = -6;
214 goto error;
215 }
216
217 COAP_SET_STR(&uri->host, q - p, p);
218 }
219
220 /* check for Uri-Port (invalid for Unix) */
221 if (len && *q == ':') {
222 if (is_unix_domain) {
223 res = -5;
224 goto error;
225 }
226 p = ++q;
227 --len;
228
229 while (len && isdigit(*q)) {
230 ++q;
231 --len;
232 }
233
234 if (p < q) { /* explicit port number given */
235 int uri_port = 0;
236
237 while ((p < q) && (uri_port <= UINT16_MAX))
238 uri_port = uri_port * 10 + (*p++ - '0');
239
240 /* check if port number is in allowed range */
241 if (uri_port > UINT16_MAX) {
242 coap_log_warn("Port number too big (%ld > 65535)\n", uri_port);
243 res = -4;
244 goto error;
245 }
246
247 uri->port = (uint16_t)uri_port;
248 }
249 }
250
251path: /* at this point, p must point to an absolute path */
252
253 if (!len)
254 goto end;
255
256 if (*q == '/') {
257 p = ++q;
258 --len;
259
260 while (len && *q != '?') {
261 ++q;
262 --len;
263 }
264
265 if (p < q) {
266 COAP_SET_STR(&uri->path, q - p, p);
267 p = q;
268 }
269 }
270
271 /* Uri_Query */
272 if (len && *p == '?') {
273 ++p;
274 --len;
275 COAP_SET_STR(&uri->query, len, p);
276 len = 0;
277 }
278
279end:
280 return len ? -1 : 0;
281
282error:
283 return res;
284}
285
286int
287coap_split_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri) {
288 return coap_split_uri_sub(str_var, len, uri, COAP_URI_CHECK_URI);
289}
290
291int
292coap_split_proxy_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri) {
293 return coap_split_uri_sub(str_var, len, uri, COAP_URI_CHECK_PROXY);
294}
295
296int
298 coap_optlist_t **optlist_chain, int create_port_host_opt,
299 uint8_t *_buf, size_t _buflen) {
300 int res;
301 unsigned char *buf = _buf;
302 size_t buflen = _buflen;
303
304 if (create_port_host_opt && !coap_host_is_unix_domain(&uri->host)) {
305 int add_option = 0;
306
307 if (dst && uri->host.length) {
308#if !defined(WITH_LWIP) && !defined(WITH_CONTIKI)
309 char addr[INET6_ADDRSTRLEN];
310#else /* WITH_LWIP || WITH_CONTIKI */
311 char addr[40];
312#endif /* WITH_LWIP || WITH_CONTIKI */
313
314 /* Add in UriHost if not match (need to strip off &iface) */
315 size_t uri_host_len = uri->host.length;
316 const uint8_t *cp = uri->host.s;
317
318 /* Unfortunately not null terminated */
319 for (size_t i = 0; i < uri_host_len; i++) {
320 if (cp[i] == '%') {
321 /* %iface specified in host name */
322 uri_host_len = i;
323 break;
324 }
325 }
326
327 if (coap_print_ip_addr(dst, addr, sizeof(addr)) &&
328 (strlen(addr) != uri_host_len ||
329 memcmp(addr, uri->host.s, uri_host_len) != 0)) {
330 /* add Uri-Host */
331 coap_insert_optlist(optlist_chain,
333 uri->host.length,
334 uri->host.s));
335 }
336 }
337 /* Add in UriPort if not default */
338 switch ((int)uri->scheme) {
341 if (uri->port != 80)
342 add_option = 1;
343 break;
346 if (uri->port != 443)
347 add_option = 1;
348 break;
349 default:
352 add_option = 1;
353 break;
354 }
355 if (add_option)
356 coap_insert_optlist(optlist_chain,
359 (uri->port & 0xffff)),
360 buf));
361 }
362
363 if (uri->path.length) {
364 if (uri->path.length > buflen)
365 coap_log_warn("URI path will be truncated (max buffer %zu)\n",
366 buflen);
367 res = coap_split_path(uri->path.s, uri->path.length, buf, &buflen);
368 if (res < 0)
369 return -1;
370
371 while (res--) {
372 coap_insert_optlist(optlist_chain,
374 coap_opt_length(buf),
375 coap_opt_value(buf)));
376
377 buf += coap_opt_size(buf);
378 }
379 }
380
381 if (uri->query.length) {
382 buflen = _buflen;
383 buf = _buf;
384 if (uri->query.length > buflen)
385 coap_log_warn("URI query will be truncated (max buffer %zu)\n",
386 buflen);
387 res = coap_split_query(uri->query.s, uri->query.length, buf, &buflen);
388 if (res < 0)
389 return -1;
390
391 while (res--) {
392 coap_insert_optlist(optlist_chain,
394 coap_opt_length(buf),
395 coap_opt_value(buf)));
396
397 buf += coap_opt_size(buf);
398 }
399 }
400 return 0;
401}
402
403int
405 if (host->length >= 3 && host->s[0] == '%' &&
406 host->s[1] == '2' &&
407 (host->s[2] == 'F' || host->s[2] == 'f')) {
408 return 1;
409 }
410 if (host->length >= 1 && host->s[0] == '/')
411 return 1;
412 return 0;
413}
414
422#define hexchar_to_dec(c) ((c) & 0x40 ? ((c) & 0x0F) + 9 : ((c) & 0x0F))
423
436static void
437decode_segment(const uint8_t *seg, size_t length, unsigned char *buf) {
438
439 while (length--) {
440
441 if (*seg == '%') {
442 *buf = (hexchar_to_dec(seg[1]) << 4) + hexchar_to_dec(seg[2]);
443
444 seg += 2;
445 length -= 2;
446 } else {
447 *buf = *seg;
448 }
449
450 ++buf;
451 ++seg;
452 }
453}
454
460static int
461check_segment(const uint8_t *s, size_t length, size_t *segment_size) {
462 size_t n = 0;
463
464 while (length) {
465 if (*s == '%') {
466 if (length < 2 || !(isxdigit(s[1]) && isxdigit(s[2])))
467 return -1;
468
469 s += 2;
470 length -= 2;
471 }
472
473 ++s;
474 ++n;
475 --length;
476 }
477
478 *segment_size = n;
479
480 return 0;
481}
482
503static int
504make_decoded_option(const uint8_t *s, size_t length,
505 unsigned char *buf, size_t buflen, size_t *optionsize) {
506 int res;
507 size_t segmentlen;
508 size_t written;
509
510 if (!buflen) {
511 coap_log_debug("make_decoded_option(): buflen is 0!\n");
512 return -1;
513 }
514
515 res = check_segment(s, length, &segmentlen);
516 if (res < 0)
517 return -1;
518
519 /* write option header using delta 0 and length res */
520 written = coap_opt_setheader(buf, buflen, 0, segmentlen);
521
522 assert(written <= buflen);
523
524 if (!written) /* encoding error */
525 return -1;
526
527 buf += written; /* advance past option type/length */
528 buflen -= written;
529
530 if (buflen < segmentlen) {
531 coap_log_debug("buffer too small for option\n");
532 return -1;
533 }
534
535 decode_segment(s, length, buf);
536
537 *optionsize = written + segmentlen;
538
539 return 0;
540}
541
542
543#ifndef min
544#define min(a,b) ((a) < (b) ? (a) : (b))
545#endif
546
547typedef void (*segment_handler_t)(const uint8_t *, size_t, void *);
548
553dots(const uint8_t *s, size_t len) {
554 return len && *s == '.' && (len == 1 || (len == 2 && *(s+1) == '.'));
555}
556
568static size_t
569coap_split_path_impl(const uint8_t *s, size_t length,
570 segment_handler_t h, void *data) {
571
572 const uint8_t *p, *q;
573
574 p = q = s;
575 while (length > 0 && !strnchr((const uint8_t *)"?#", 2, *q)) {
576 if (*q == '/') { /* start new segment */
577
578 if (!dots(p, q - p)) {
579 h(p, q - p, data);
580 }
581
582 p = q + 1;
583 }
584
585 q++;
586 length--;
587 }
588
589 /* write last segment */
590 if (!dots(p, q - p)) {
591 h(p, q - p, data);
592 }
593
594 return q - s;
595}
596
597struct cnt_str {
599 int n;
600};
601
602static void
603write_option(const uint8_t *s, size_t len, void *data) {
604 struct cnt_str *state = (struct cnt_str *)data;
605 int res;
606 size_t optionsize;
607 assert(state);
608
609 res = make_decoded_option(s, len, state->buf.s, state->buf.length, &optionsize);
610 if (res == 0) {
611 state->buf.s += optionsize;
612 state->buf.length -= optionsize;
613 state->n++;
614 }
615}
616
617int
618coap_split_path(const uint8_t *s, size_t length,
619 unsigned char *buf, size_t *buflen) {
620 struct cnt_str tmp = { { *buflen, buf }, 0 };
621
622 coap_split_path_impl(s, length, write_option, &tmp);
623
624 *buflen = *buflen - tmp.buf.length;
625
626 return tmp.n;
627}
628
629int
630coap_split_query(const uint8_t *s, size_t length,
631 unsigned char *buf, size_t *buflen) {
632 struct cnt_str tmp = { { *buflen, buf }, 0 };
633 const uint8_t *p;
634
635 p = s;
636 while (length > 0 && *s != '#') {
637 if (*s == '&') { /* start new query element */
638 write_option(p, s - p, &tmp);
639 p = s + 1;
640 }
641
642 s++;
643 length--;
644 }
645
646 /* write last query element */
647 write_option(p, s - p, &tmp);
648
649 *buflen = *buflen - tmp.buf.length;
650 return tmp.n;
651}
652
653#define URI_DATA(uriobj) ((unsigned char *)(uriobj) + sizeof(coap_uri_t))
654
656coap_new_uri(const uint8_t *uri, unsigned int length) {
657 unsigned char *result;
658
659 result = (unsigned char *)coap_malloc_type(COAP_STRING, length + 1 + sizeof(coap_uri_t));
660
661 if (!result)
662 return NULL;
663
664 memcpy(URI_DATA(result), uri, length);
665 URI_DATA(result)[length] = '\0'; /* make it zero-terminated */
666
667 if (coap_split_uri(URI_DATA(result), length, (coap_uri_t *)result) < 0) {
669 return NULL;
670 }
671 return (coap_uri_t *)result;
672}
673
676 coap_uri_t *result;
677 uint8_t *p;
678
679 if (!uri)
680 return NULL;
681
683 uri->path.length + sizeof(coap_uri_t) + 1);
684
685 if (!result)
686 return NULL;
687
688 memset(result, 0, sizeof(coap_uri_t));
689
690 result->port = uri->port;
691
692 if (uri->host.length) {
693 result->host.s = p = URI_DATA(result);
694 result->host.length = uri->host.length;
695
696 memcpy(p, uri->host.s, uri->host.length);
697 }
698
699 if (uri->path.length) {
700 result->path.s = p = URI_DATA(result) + uri->host.length;
701 result->path.length = uri->path.length;
702
703 memcpy(p, uri->path.s, uri->path.length);
704 }
705
706 if (uri->query.length) {
707 result->query.s = p = URI_DATA(result) + uri->host.length + uri->path.length;
708 result->query.length = uri->query.length;
709
710 memcpy(p, uri->query.s, uri->query.length);
711 }
712
713 return result;
714}
715
716void
720
722is_unescaped_in_path(const uint8_t c) {
723 return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
724 (c >= '0' && c <= '9') || c == '-' || c == '.' || c == '_' ||
725 c == '~' || c == '!' || c == '$' || c == '\'' || c == '(' ||
726 c == ')' || c == '*' || c == '+' || c == ',' || c == ';' ||
727 c=='=' || c==':' || c=='@' || c == '&';
728}
729
731is_unescaped_in_query(const uint8_t c) {
732 return is_unescaped_in_path(c) || c=='/' || c=='?';
733}
734
736coap_get_query(const coap_pdu_t *request) {
737 coap_opt_iterator_t opt_iter;
739 coap_opt_t *q;
740 coap_string_t *query = NULL;
741 size_t length = 0;
742 static const uint8_t hex[] = "0123456789ABCDEF";
743
746 coap_option_iterator_init(request, &opt_iter, &f);
747 while ((q = coap_option_next(&opt_iter))) {
748 uint16_t seg_len = coap_opt_length(q), i;
749 const uint8_t *seg= coap_opt_value(q);
750 for (i = 0; i < seg_len; i++) {
751 if (is_unescaped_in_query(seg[i]))
752 length += 1;
753 else
754 length += 3;
755 }
756 length += 1;
757 }
758 if (length > 0)
759 length -= 1;
760 if (length > 0) {
761 query = coap_new_string(length);
762 if (query) {
763 query->length = length;
764 unsigned char *s = query->s;
765 coap_option_iterator_init(request, &opt_iter, &f);
766 while ((q = coap_option_next(&opt_iter))) {
767 if (s != query->s)
768 *s++ = '&';
769 uint16_t seg_len = coap_opt_length(q), i;
770 const uint8_t *seg= coap_opt_value(q);
771 for (i = 0; i < seg_len; i++) {
772 if (is_unescaped_in_query(seg[i])) {
773 *s++ = seg[i];
774 } else {
775 *s++ = '%';
776 *s++ = hex[seg[i]>>4];
777 *s++ = hex[seg[i]&0x0F];
778 }
779 }
780 }
781 }
782 }
783 return query;
784}
785
788 coap_opt_iterator_t opt_iter;
790 coap_opt_t *q;
791 coap_string_t *uri_path = NULL;
792 size_t length = 0;
793 static const uint8_t hex[] = "0123456789ABCDEF";
794
795 q = coap_check_option(request, COAP_OPTION_PROXY_URI, &opt_iter);
796 if (q) {
797 coap_uri_t uri;
798
800 coap_opt_length(q), &uri) < 0) {
801 return NULL;
802 }
803 uri_path = coap_new_string(uri.path.length);
804 if (uri_path) {
805 memcpy(uri_path->s, uri.path.s, uri.path.length);
806 }
807 return uri_path;
808 }
809
812 coap_option_iterator_init(request, &opt_iter, &f);
813 while ((q = coap_option_next(&opt_iter))) {
814 uint16_t seg_len = coap_opt_length(q), i;
815 const uint8_t *seg= coap_opt_value(q);
816 for (i = 0; i < seg_len; i++) {
817 if (is_unescaped_in_path(seg[i]))
818 length += 1;
819 else
820 length += 3;
821 }
822 /* bump for the leading "/" */
823 length += 1;
824 }
825 /* The first entry does not have a leading "/" */
826 if (length > 0)
827 length -= 1;
828
829 /* if 0, either no URI_PATH Option, or the first one was empty */
830 uri_path = coap_new_string(length);
831 if (uri_path) {
832 uri_path->length = length;
833 unsigned char *s = uri_path->s;
834 int n = 0;
835 coap_option_iterator_init(request, &opt_iter, &f);
836 while ((q = coap_option_next(&opt_iter))) {
837 if (n++) {
838 *s++ = '/';
839 }
840 uint16_t seg_len = coap_opt_length(q), i;
841 const uint8_t *seg= coap_opt_value(q);
842 for (i = 0; i < seg_len; i++) {
843 if (is_unescaped_in_path(seg[i])) {
844 *s++ = seg[i];
845 } else {
846 *s++ = '%';
847 *s++ = hex[seg[i]>>4];
848 *s++ = hex[seg[i]&0x0F];
849 }
850 }
851 }
852 }
853 return uri_path;
854}
#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:722
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:437
COAP_STATIC_INLINE int is_unescaped_in_query(const uint8_t c)
Definition coap_uri.c:731
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:553
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:569
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:461
static void write_option(const uint8_t *s, size_t len, void *data)
Definition coap_uri.c:603
void coap_delete_uri(coap_uri_t *uri)
Removes the specified coap_uri_t object.
Definition coap_uri.c:717
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:72
#define hexchar_to_dec(c)
Calculates decimal value from hexadecimal ASCII character given in c.
Definition coap_uri.c:422
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:504
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:675
#define URI_DATA(uriobj)
Definition coap_uri.c:653
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:656
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:404
void(* segment_handler_t)(const uint8_t *, size_t, void *)
Definition coap_uri.c:547
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:787
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:618
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:630
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:287
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:292
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:297
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:736
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:599
coap_string_t buf
Definition coap_uri.c:598
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