/src/libcoap/include/coap3/coap_uri.h
Line | Count | Source |
1 | | /* |
2 | | * coap_uri.h -- helper functions for URI treatment |
3 | | * |
4 | | * Copyright (C) 2010-2026 Olaf Bergmann <bergmann@tzi.org> |
5 | | * |
6 | | * SPDX-License-Identifier: BSD-2-Clause |
7 | | * |
8 | | * This file is part of the CoAP library libcoap. Please see README for terms |
9 | | * of use. |
10 | | */ |
11 | | |
12 | | /** |
13 | | * @file coap_uri.h |
14 | | * @brief Helper functions for URI treatment |
15 | | */ |
16 | | |
17 | | #ifndef COAP_URI_H_ |
18 | | #define COAP_URI_H_ |
19 | | |
20 | | #include <stdint.h> |
21 | | |
22 | | #include "coap_str.h" |
23 | | |
24 | | #ifdef __cplusplus |
25 | | extern "C" { |
26 | | #endif |
27 | | |
28 | | /** |
29 | | * The scheme specifiers. Secure schemes have an odd numeric value, |
30 | | * others are even. |
31 | | */ |
32 | | typedef enum coap_uri_scheme_t { |
33 | | COAP_URI_SCHEME_COAP = 0, |
34 | | COAP_URI_SCHEME_COAPS, /* 1 */ |
35 | | COAP_URI_SCHEME_COAP_TCP, /* 2 */ |
36 | | COAP_URI_SCHEME_COAPS_TCP, /* 3 */ |
37 | | COAP_URI_SCHEME_HTTP, /* 4 Proxy-Uri only */ |
38 | | COAP_URI_SCHEME_HTTPS, /* 5 Proxy-Uri only */ |
39 | | COAP_URI_SCHEME_COAP_WS, /* 6 */ |
40 | | COAP_URI_SCHEME_COAPS_WS, /* 7 */ |
41 | | COAP_URI_SCHEME_LAST /* 8 Size of scheme */ |
42 | | } coap_uri_scheme_t; |
43 | | |
44 | | /** This mask can be used to check if a parsed URI scheme is secure. */ |
45 | 0 | #define COAP_URI_SCHEME_SECURE_MASK 0x01 |
46 | | |
47 | | #define COAP_URI_SCHEME_COAP_BIT (1 << COAP_URI_SCHEME_COAP) |
48 | | #define COAP_URI_SCHEME_COAPS_BIT (1 << COAP_URI_SCHEME_COAPS) |
49 | | #define COAP_URI_SCHEME_COAP_TCP_BIT (1 << COAP_URI_SCHEME_COAP_TCP) |
50 | | #define COAP_URI_SCHEME_COAPS_TCP_BIT (1 << COAP_URI_SCHEME_COAPS_TCP) |
51 | | #define COAP_URI_SCHEME_HTTP_BIT (1 << COAP_URI_SCHEME_HTTP) |
52 | | #define COAP_URI_SCHEME_HTTPS_BIT (1 << COAP_URI_SCHEME_HTTPS) |
53 | | #define COAP_URI_SCHEME_COAP_WS_BIT (1 << COAP_URI_SCHEME_COAP_WS) |
54 | | #define COAP_URI_SCHEME_COAPS_WS_BIT (1 << COAP_URI_SCHEME_COAPS_WS) |
55 | | |
56 | | #define COAP_URI_SCHEME_ALL_COAP_BITS (COAP_URI_SCHEME_COAP_BIT | \ |
57 | | COAP_URI_SCHEME_COAPS_BIT | \ |
58 | | COAP_URI_SCHEME_COAP_TCP_BIT | \ |
59 | | COAP_URI_SCHEME_COAPS_TCP_BIT | \ |
60 | | COAP_URI_SCHEME_COAP_WS_BIT | \ |
61 | | COAP_URI_SCHEME_COAPS_WS_BIT) |
62 | | |
63 | | /** |
64 | | * Representation of parsed URI. Components may be filled from a string with |
65 | | * coap_split_uri() or coap_split_proxy_uri() and can be used as input for |
66 | | * option-creation functions. Alternatively, coap_uri_into_optlist() can |
67 | | * be used to convert coap_uri_t into CoAP options. |
68 | | * |
69 | | * Note: host, path and query point to data which must remain there for the |
70 | | * lifetime of the coap_uri_t. |
71 | | */ |
72 | | typedef struct { |
73 | | coap_str_const_t host; /**< The host part of the URI */ |
74 | | uint16_t port; /**< The port in host byte order */ |
75 | | coap_str_const_t path; /**< The complete path if present or {0, NULL}. |
76 | | Needs to be split into options using |
77 | | coap_path_into_optlist() or |
78 | | coap_uri_into_optlist(). */ |
79 | | coap_str_const_t query; /**< The complete query if present or {0, NULL}. |
80 | | Needs to be split into options using |
81 | | coap_query_into_options() or |
82 | | coap_uri_into_optlist(). */ |
83 | | /** The parsed scheme specifier. */ |
84 | | enum coap_uri_scheme_t scheme; |
85 | | } coap_uri_t; |
86 | | |
87 | | static inline int |
88 | 0 | coap_uri_scheme_is_secure(const coap_uri_t *uri) { |
89 | 0 | return uri && ((uri->scheme & COAP_URI_SCHEME_SECURE_MASK) != 0); |
90 | 0 | } Unexecuted instantiation: coap_debug.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_encode.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_net.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_netif.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_notls.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_option.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_oscore.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_pdu.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_proxy.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_prng.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_resource.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_session.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_sha1.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_str.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_strm_posix.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_subscribe.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_threadsafe.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_time.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_uri.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_ws.c:coap_uri_scheme_is_secure Unexecuted instantiation: oscore.c:coap_uri_scheme_is_secure Unexecuted instantiation: oscore_cbor.c:coap_uri_scheme_is_secure Unexecuted instantiation: oscore_context.c:coap_uri_scheme_is_secure Unexecuted instantiation: oscore_cose.c:coap_uri_scheme_is_secure Unexecuted instantiation: oscore_crypto.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_address.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_async.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_block.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_cache.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_dgrm_posix.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_dtls.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_hashkey.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_io.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_io_posix.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_layers.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_mem.c:coap_uri_scheme_is_secure |
91 | | |
92 | | /** |
93 | | * Determines from the @p host whether this is a Unix Domain socket |
94 | | * request. |
95 | | * |
96 | | * @param host The host object. |
97 | | * |
98 | | * @return @c 0 on failure, or @c 1 on success. |
99 | | * |
100 | | */ |
101 | | int coap_host_is_unix_domain(const coap_str_const_t *host); |
102 | | |
103 | | /** |
104 | | * Creates a new coap_uri_t object from the specified URI. Returns the new |
105 | | * object or NULL on error. The memory allocated by the new coap_uri_t |
106 | | * should be released using coap_delete_uri(). |
107 | | * |
108 | | * @param uri The URI path to copy. |
109 | | * @param length The length of uri. |
110 | | * |
111 | | * @return New URI object or NULL on error. |
112 | | */ |
113 | | coap_uri_t *coap_new_uri(const uint8_t *uri, unsigned int length); |
114 | | |
115 | | /** |
116 | | * Clones the specified coap_uri_t object. This function allocates sufficient |
117 | | * memory to hold the coap_uri_t structure and its contents. The object should |
118 | | * be released with delete_uri(). |
119 | | * |
120 | | * @param uri The coap_uri_t structure to copy. |
121 | | * |
122 | | * @return New URI object or NULL on error. |
123 | | */ |
124 | | coap_uri_t *coap_clone_uri(const coap_uri_t *uri); |
125 | | |
126 | | /** |
127 | | * Removes the specified coap_uri_t object. |
128 | | * |
129 | | * @param uri The coap_uri_t structure to remove. |
130 | | */ |
131 | | void coap_delete_uri(coap_uri_t *uri); |
132 | | |
133 | | /** |
134 | | * @ingroup application_api |
135 | | * @defgroup uri_parse URI Parsing Functions |
136 | | * API for parsing URIs. |
137 | | * CoAP PDUs contain normalized URIs with their path and query split into |
138 | | * multiple segments. The functions in this module help splitting strings. |
139 | | * @{ |
140 | | */ |
141 | | |
142 | | /** |
143 | | * Parses a given string into URI components. The identified syntactic |
144 | | * components are stored in the result parameter @p uri. Optional URI |
145 | | * components that are not specified will be set to { 0, 0 }, except for the |
146 | | * port which is set to the default port for the protocol. This function |
147 | | * returns @p 0 if parsing succeeded, a value less than zero otherwise. |
148 | | * |
149 | | * @param str_var The string to split up. |
150 | | * @param len The actual length of @p str_var |
151 | | * @param uri The coap_uri_t object to store the result. |
152 | | * |
153 | | * @return @c 0 on success, or < 0 on error. |
154 | | * |
155 | | */ |
156 | | int coap_split_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri); |
157 | | |
158 | | /** |
159 | | * Parses a given string into URI components. The identified syntactic |
160 | | * components are stored in the result parameter @p uri. Optional URI |
161 | | * components that are not specified will be set to { 0, 0 }, except for the |
162 | | * port which is set to default port for the protocol. This function returns |
163 | | * @p 0 if parsing succeeded, a value less than zero otherwise. |
164 | | * Note: This function enforces that the given string is in Proxy-Uri format |
165 | | * as well as supports different schema such as http and https. |
166 | | * |
167 | | * @param str_var The string to split up. |
168 | | * @param len The actual length of @p str_var |
169 | | * @param uri The coap_uri_t object to store the result. |
170 | | * |
171 | | * @return @c 0 on success, or < 0 on error. |
172 | | * |
173 | | */ |
174 | | int coap_split_proxy_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri); |
175 | | |
176 | | /** |
177 | | * Takes a coap_uri_t and then adds CoAP options into the @p optlist_chain. |
178 | | * If the port is not the default port and create_port_host_opt is not 0, then |
179 | | * the Uri-Port option is added to the @p optlist_chain. |
180 | | * If the dst defines an address that does not match the host in uri->host and |
181 | | * is not 0, then the Uri-Host option is added to the @p optlist_chain. |
182 | | * Any path or query are broken down into the individual segment Uri-Path or |
183 | | * Uri-Query options and added to the @p optlist_chain. |
184 | | * |
185 | | * Note: coap_uri_into_optlist(3) is an alternative function (but has a |
186 | | * different return value). |
187 | | * |
188 | | * @param uri The coap_uri_t object. |
189 | | * @param dst The destination, or NULL if URI_HOST not to be added. |
190 | | * @param optlist_chain Where to store the chain of options. |
191 | | * @param create_port_host_opt @c 1 if port/host option to be added |
192 | | * (if non-default) else @c 0 |
193 | | * @param buf Parameter ignored. Can be NULL. |
194 | | * @param buflen Parameter ignored. |
195 | | * |
196 | | * @return @c 0 on success, or < 0 on error. |
197 | | * |
198 | | */ |
199 | | int coap_uri_into_options(const coap_uri_t *uri, const coap_address_t *dst, |
200 | | coap_optlist_t **optlist_chain, |
201 | | int create_port_host_opt, |
202 | | uint8_t *buf, size_t buflen); |
203 | | |
204 | | /** |
205 | | * Takes a coap_uri_t and then adds CoAP options into the @p optlist_chain. |
206 | | * If the port is not the default port and create_port_host_opt is not 0, then |
207 | | * the Uri-Port option is added to the @p optlist_chain. |
208 | | * If the dst defines an address that does not match the host in uri->host and |
209 | | * is not 0, then the Uri-Host option is added to the @p optlist_chain. |
210 | | * Any path or query are broken down into the individual segment Uri-Path or |
211 | | * Uri-Query options and added to the @p optlist_chain. |
212 | | * |
213 | | * @param uri The coap_uri_t object. |
214 | | * @param dst The destination, or NULL if URI_HOST not to be added. |
215 | | * @param optlist_chain Where to store the chain of options. |
216 | | * @param create_port_host_opt @c 1 if port/host option to be added |
217 | | * (if non-default) else @c 0. |
218 | | * |
219 | | * @return @c 1 on success, @c 0 if error. |
220 | | * |
221 | | */ |
222 | | int coap_uri_into_optlist(const coap_uri_t *uri, const coap_address_t *dst, |
223 | | coap_optlist_t **optlist_chain, |
224 | | int create_port_host_opt); |
225 | | |
226 | | /** |
227 | | * Splits the given URI path into segments. Each segment is preceded |
228 | | * by an option pseudo-header with delta-value 0 and the actual length |
229 | | * of the respective segment after percent-decoding. |
230 | | * |
231 | | * @param path The path string to split. |
232 | | * @param length The actual length of @p path. |
233 | | * @param buf Result buffer for parsed segments. |
234 | | * @param buflen Maximum length of @p buf. Will be set to the actual number |
235 | | * of bytes written into buf on success. This needs to be |
236 | | * at least @p length, but 2 bytes should be added for each |
237 | | * segment to handle large segments. |
238 | | * |
239 | | * @return The number of segments created or @c -1 on error. |
240 | | */ |
241 | | int coap_split_path(const uint8_t *path, |
242 | | size_t length, |
243 | | unsigned char *buf, |
244 | | size_t *buflen); |
245 | | |
246 | | /** |
247 | | * Splits the given URI path into '/' separate segments, and then adds |
248 | | * the Uri-Path / Location-Path option for each segment to the @p optlist_chain. |
249 | | * |
250 | | * Note: any segments that are just '.' or '..' are stripped out. |
251 | | * |
252 | | * @param path The path string to split. |
253 | | * @param length The actual length of @p path. |
254 | | * @param optnum The CoAP option (COAP_OPTION_URI_PATH or |
255 | | * COAP_OPTION_LOCATION_PATH) |
256 | | * @param optlist_chain The chain of optlists to add to. optlist_chain |
257 | | * parent is to be NULL or a previous set of optlists. |
258 | | * |
259 | | * @return @c 1 on success else @c 0 if error. |
260 | | */ |
261 | | int coap_path_into_optlist(const uint8_t *path, size_t length, |
262 | | coap_option_num_t optnum, |
263 | | coap_optlist_t **optlist_chain); |
264 | | |
265 | | /** |
266 | | * Splits the given URI query into segments. Each segment is preceded |
267 | | * by an option pseudo-header with delta-value 0 and the actual length |
268 | | * of the respective query segment. |
269 | | * |
270 | | * @param query The query string to split. |
271 | | * @param length The actual length of @p query |
272 | | * @param buf Result buffer for parsed segments. |
273 | | * @param buflen Maximum length of @p buf. Will be set to the actual number |
274 | | * of bytes written into buf on success. This needs to be |
275 | | * at least @p length, but 2 bytes should be added for each |
276 | | * segment to handle large segments. |
277 | | * |
278 | | * @return The number of segments created or @c -1 on error. |
279 | | */ |
280 | | int coap_split_query(const uint8_t *query, |
281 | | size_t length, |
282 | | unsigned char *buf, |
283 | | size_t *buflen); |
284 | | |
285 | | /** |
286 | | * Splits the given URI query into '&' separate segments, and then adds |
287 | | * the Uri-Query / Location-Query option for each segment to the @p optlist_chain. |
288 | | * |
289 | | * @param query The query string to split. |
290 | | * @param length The actual length of @p query. |
291 | | * @param optnum The CoAP option (COAP_OPTION_URI_QUERY or |
292 | | * COAP_OPTION_LOCATION_QUERY) |
293 | | * @param optlist_chain The chain of optlists to add to. optlist_chain |
294 | | * parent is to be NULL or a previous set of optlists. |
295 | | * |
296 | | * @return @c 1 on success else @c 0 if error. |
297 | | */ |
298 | | int coap_query_into_optlist(const uint8_t *query, size_t length, |
299 | | coap_option_num_t optnum, |
300 | | coap_optlist_t **optlist_chain); |
301 | | |
302 | | /** |
303 | | * Extract query string from request PDU according to escape rules in 6.5.8. |
304 | | * @param request Request PDU. |
305 | | * @return Reconstructed and escaped query string part or @c NULL if |
306 | | * no query was contained in @p request. The coap_string_t |
307 | | * object returned by this function must be released with |
308 | | * coap_delete_string. |
309 | | */ |
310 | | coap_string_t *coap_get_query(const coap_pdu_t *request); |
311 | | |
312 | | /** |
313 | | * Extract uri_path string from request PDU |
314 | | * @param request Request PDU. |
315 | | * @return Reconstructed and escaped uri path string part or @c NULL |
316 | | * if no Uri-Path was contained in @p request. The |
317 | | * coap_string_t object returned by this function must be |
318 | | * released with coap_delete_string. |
319 | | */ |
320 | | coap_string_t *coap_get_uri_path(const coap_pdu_t *request); |
321 | | |
322 | | /** @} */ |
323 | | |
324 | | #ifdef __cplusplus |
325 | | } |
326 | | #endif |
327 | | |
328 | | #endif /* COAP_URI_H_ */ |