/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 "coap_str.h" |
21 | | |
22 | | #ifdef __cplusplus |
23 | | extern "C" { |
24 | | #endif |
25 | | |
26 | | /** |
27 | | * The scheme specifiers. Secure schemes have an odd numeric value, |
28 | | * others are even. |
29 | | */ |
30 | | typedef enum coap_uri_scheme_t { |
31 | | COAP_URI_SCHEME_COAP = 0, |
32 | | COAP_URI_SCHEME_COAPS, /* 1 */ |
33 | | COAP_URI_SCHEME_COAP_TCP, /* 2 */ |
34 | | COAP_URI_SCHEME_COAPS_TCP, /* 3 */ |
35 | | COAP_URI_SCHEME_HTTP, /* 4 Proxy-Uri only */ |
36 | | COAP_URI_SCHEME_HTTPS, /* 5 Proxy-Uri only */ |
37 | | COAP_URI_SCHEME_COAP_WS, /* 6 */ |
38 | | COAP_URI_SCHEME_COAPS_WS, /* 7 */ |
39 | | COAP_URI_SCHEME_LAST /* 8 Size of scheme */ |
40 | | } coap_uri_scheme_t; |
41 | | |
42 | | /** This mask can be used to check if a parsed URI scheme is secure. */ |
43 | 0 | #define COAP_URI_SCHEME_SECURE_MASK 0x01 |
44 | | |
45 | | #define COAP_URI_SCHEME_COAP_BIT (1 << COAP_URI_SCHEME_COAP) |
46 | | #define COAP_URI_SCHEME_COAPS_BIT (1 << COAP_URI_SCHEME_COAPS) |
47 | | #define COAP_URI_SCHEME_COAP_TCP_BIT (1 << COAP_URI_SCHEME_COAP_TCP) |
48 | | #define COAP_URI_SCHEME_COAPS_TCP_BIT (1 << COAP_URI_SCHEME_COAPS_TCP) |
49 | | #define COAP_URI_SCHEME_HTTP_BIT (1 << COAP_URI_SCHEME_HTTP) |
50 | | #define COAP_URI_SCHEME_HTTPS_BIT (1 << COAP_URI_SCHEME_HTTPS) |
51 | | #define COAP_URI_SCHEME_COAP_WS_BIT (1 << COAP_URI_SCHEME_COAP_WS) |
52 | | #define COAP_URI_SCHEME_COAPS_WS_BIT (1 << COAP_URI_SCHEME_COAPS_WS) |
53 | | |
54 | | #define COAP_URI_SCHEME_ALL_COAP_BITS (COAP_URI_SCHEME_COAP_BIT | \ |
55 | | COAP_URI_SCHEME_COAPS_BIT | \ |
56 | | COAP_URI_SCHEME_COAP_TCP_BIT | \ |
57 | | COAP_URI_SCHEME_COAPS_TCP_BIT | \ |
58 | | COAP_URI_SCHEME_COAP_WS_BIT | \ |
59 | | COAP_URI_SCHEME_COAPS_WS_BIT) |
60 | | |
61 | | /** |
62 | | * Representation of parsed URI. Components may be filled from a string with |
63 | | * coap_split_uri() or coap_split_proxy_uri() and can be used as input for |
64 | | * option-creation functions. Alternatively, coap_uri_into_optlist() can |
65 | | * be used to convert coap_uri_t into CoAP options. |
66 | | * |
67 | | * Note: host, path and query point to data which must remain there for the |
68 | | * lifetime of the coap_uri_t. |
69 | | */ |
70 | | typedef struct { |
71 | | coap_str_const_t host; /**< The host part of the URI */ |
72 | | uint16_t port; /**< The port in host byte order */ |
73 | | coap_str_const_t path; /**< The complete path if present or {0, NULL}. |
74 | | Needs to be split into options using |
75 | | coap_path_into_optlist() or |
76 | | coap_uri_into_optlist(). */ |
77 | | coap_str_const_t query; /**< The complete query if present or {0, NULL}. |
78 | | Needs to be split into options using |
79 | | coap_query_into_options() or |
80 | | coap_uri_into_optlist(). */ |
81 | | /** The parsed scheme specifier. */ |
82 | | enum coap_uri_scheme_t scheme; |
83 | | } coap_uri_t; |
84 | | |
85 | | typedef struct { |
86 | | uint32_t upa_value; /**< The Uri-Path-Abbrev option value */ |
87 | | const char *upa_path; /**< The Uri-Path-Abbrev option path representation |
88 | | (withouot the leading '/') */ |
89 | | } coap_upa_abbrev_t; |
90 | | |
91 | | static inline int |
92 | 0 | coap_uri_scheme_is_secure(const coap_uri_t *uri) { |
93 | 0 | return uri && ((uri->scheme & COAP_URI_SCHEME_SECURE_MASK) != 0); |
94 | 0 | } Unexecuted instantiation: oscore_decrypt_target.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_address.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_debug.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_encode.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_mem.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_openssl.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_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_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_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_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: pdu_parse_udp_target.c:coap_uri_scheme_is_secure Unexecuted instantiation: async_target.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_fuzz_helper.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_event.c:coap_uri_scheme_is_secure Unexecuted instantiation: block_target.c:coap_uri_scheme_is_secure Unexecuted instantiation: split_uri_target.c:coap_uri_scheme_is_secure Unexecuted instantiation: pdu_parse_tcp_target.c:coap_uri_scheme_is_secure Unexecuted instantiation: persist_target.c:coap_uri_scheme_is_secure Unexecuted instantiation: observe_target.c:coap_uri_scheme_is_secure Unexecuted instantiation: pdu_parse_ws_target.c:coap_uri_scheme_is_secure Unexecuted instantiation: network_message_target.c:coap_uri_scheme_is_secure Unexecuted instantiation: oscore_conf_parse_target.c:coap_uri_scheme_is_secure Unexecuted instantiation: get_asn1_tag_target.c:coap_uri_scheme_is_secure Unexecuted instantiation: coap_asn1.c:coap_uri_scheme_is_secure Unexecuted instantiation: block_check_target.c:coap_uri_scheme_is_secure |
95 | | |
96 | | /** |
97 | | * Determines from the @p host whether this is a Unix Domain socket |
98 | | * request. |
99 | | * |
100 | | * @param host The host object. |
101 | | * |
102 | | * @return @c 0 on failure, or @c 1 on success. |
103 | | * |
104 | | */ |
105 | | int coap_host_is_unix_domain(const coap_str_const_t *host); |
106 | | |
107 | | /** |
108 | | * Determines from the @p host whether this is an LLC socket request. |
109 | | * |
110 | | * @param host The host object. |
111 | | * |
112 | | * @return @c 0 on failure, or @c 1 on success. |
113 | | * |
114 | | */ |
115 | | int coap_host_is_llc(const coap_str_const_t *host); |
116 | | |
117 | | /** |
118 | | * Creates a new coap_uri_t object from the specified URI. Returns the new |
119 | | * object or NULL on error. The memory allocated by the new coap_uri_t |
120 | | * should be released using coap_delete_uri(). |
121 | | * |
122 | | * @param uri The URI path to copy. |
123 | | * @param length The length of uri. |
124 | | * |
125 | | * @return New URI object or NULL on error. |
126 | | */ |
127 | | coap_uri_t *coap_new_uri(const uint8_t *uri, unsigned int length); |
128 | | |
129 | | /** |
130 | | * Clones the specified coap_uri_t object. This function allocates sufficient |
131 | | * memory to hold the coap_uri_t structure and its contents. The object should |
132 | | * be released with delete_uri(). |
133 | | * |
134 | | * @param uri The coap_uri_t structure to copy. |
135 | | * |
136 | | * @return New URI object or NULL on error. |
137 | | */ |
138 | | coap_uri_t *coap_clone_uri(const coap_uri_t *uri); |
139 | | |
140 | | /** |
141 | | * Removes the specified coap_uri_t object. |
142 | | * |
143 | | * @param uri The coap_uri_t structure to remove. |
144 | | */ |
145 | | void coap_delete_uri(coap_uri_t *uri); |
146 | | |
147 | | /** |
148 | | * @ingroup application_api |
149 | | * @defgroup uri_parse URI Parsing Functions |
150 | | * API for parsing URIs. |
151 | | * CoAP PDUs contain normalized URIs with their path and query split into |
152 | | * multiple segments. The functions in this module help splitting strings. |
153 | | * @{ |
154 | | */ |
155 | | |
156 | | /** |
157 | | * Parses a given string into URI components. The identified syntactic |
158 | | * components are stored in the result parameter @p uri. Optional URI |
159 | | * components that are not specified will be set to { 0, 0 }, except for the |
160 | | * port which is set to the default port for the protocol. This function |
161 | | * returns @p 0 if parsing succeeded, a value less than zero otherwise. |
162 | | * |
163 | | * @param str_var The string to split up. |
164 | | * @param len The actual length of @p str_var |
165 | | * @param uri The coap_uri_t object to store the result. |
166 | | * |
167 | | * @return @c 0 on success, or < 0 on error. |
168 | | * |
169 | | */ |
170 | | int coap_split_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri); |
171 | | |
172 | | /** |
173 | | * Parses a given string into URI components. The identified syntactic |
174 | | * components are stored in the result parameter @p uri. Optional URI |
175 | | * components that are not specified will be set to { 0, 0 }, except for the |
176 | | * port which is set to default port for the protocol. This function returns |
177 | | * @p 0 if parsing succeeded, a value less than zero otherwise. |
178 | | * Note: This function enforces that the given string is in Proxy-Uri format |
179 | | * as well as supports different schema such as http and https. |
180 | | * |
181 | | * @param str_var The string to split up. |
182 | | * @param len The actual length of @p str_var |
183 | | * @param uri The coap_uri_t object to store the result. |
184 | | * |
185 | | * @return @c 0 on success, or < 0 on error. |
186 | | * |
187 | | */ |
188 | | int coap_split_proxy_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri); |
189 | | |
190 | | /** |
191 | | * Takes a coap_uri_t and then adds CoAP options into the @p optlist_chain. |
192 | | * If the port is not the default port and create_port_host_opt is not 0, then |
193 | | * the Uri-Port option is added to the @p optlist_chain. |
194 | | * If the dst defines an address that does not match the host in uri->host and |
195 | | * is not 0, then the Uri-Host option is added to the @p optlist_chain. |
196 | | * Any path or query are broken down into the individual segment Uri-Path or |
197 | | * Uri-Query options and added to the @p optlist_chain. |
198 | | * |
199 | | * Note: coap_uri_into_optlist(3) is an alternative function (but has a |
200 | | * different return value). |
201 | | * |
202 | | * @param uri The coap_uri_t object. |
203 | | * @param dst The destination, or NULL if URI_HOST not to be added. |
204 | | * @param optlist_chain Where to store the chain of options. |
205 | | * @param create_port_host_opt @c 1 if port/host option to be added |
206 | | * (if non-default) else @c 0 |
207 | | * @param buf Parameter ignored. Can be NULL. |
208 | | * @param buflen Parameter ignored. |
209 | | * |
210 | | * @return @c 0 on success, or < 0 on error. |
211 | | * |
212 | | */ |
213 | | int coap_uri_into_options(const coap_uri_t *uri, const coap_address_t *dst, |
214 | | coap_optlist_t **optlist_chain, |
215 | | int create_port_host_opt, |
216 | | uint8_t *buf, size_t buflen); |
217 | | |
218 | | /** |
219 | | * Takes a coap_uri_t and then adds CoAP options into the @p optlist_chain. |
220 | | * If the port is not the default port and create_port_host_opt is not 0, then |
221 | | * the Uri-Port option is added to the @p optlist_chain. |
222 | | * If the dst defines an address that does not match the host in uri->host and |
223 | | * is not 0, then the Uri-Host option is added to the @p optlist_chain. |
224 | | * Any path or query are broken down into the individual segment Uri-Path or |
225 | | * Uri-Query options and added to the @p optlist_chain. |
226 | | * |
227 | | * @param uri The coap_uri_t object. |
228 | | * @param dst The destination, or NULL if URI_HOST not to be added. |
229 | | * @param optlist_chain Where to store the chain of options. |
230 | | * @param create_port_host_opt @c 1 if port/host option to be added |
231 | | * (if non-default) else @c 0. |
232 | | * |
233 | | * @return @c 1 on success, @c 0 if error. |
234 | | * |
235 | | */ |
236 | | int coap_uri_into_optlist(const coap_uri_t *uri, const coap_address_t *dst, |
237 | | coap_optlist_t **optlist_chain, |
238 | | int create_port_host_opt); |
239 | | /** |
240 | | * Takes a coap_uri_t and then adds CoAP options into the @p optlist_chain. |
241 | | * If the port is not the default port and create_port_host_opt is not 0, then |
242 | | * the Uri-Port option is added to the @p optlist_chain. |
243 | | * If the dst defines an address that does not match the host in uri->host and |
244 | | * is not 0, then the Uri-Host option is added to the @p optlist_chain. |
245 | | * Any path or query are broken down into the individual segment Uri-Path |
246 | | * or Uri-Path-Abbrev (if mapping match) or Uri-Query options and added to |
247 | | * the @p optlist_chain. |
248 | | * |
249 | | * @param uri The coap_uri_t object. |
250 | | * @param dst The destination, or NULL if URI_HOST not to be added. |
251 | | * @param optlist_chain Where to store the chain of options. |
252 | | * @param create_port_host_opt @c 1 if port/host option to be added |
253 | | * (if non-default) else @c 0. |
254 | | * @param mapping A path mapping to value for Uri-Path-Abbrev table or NULL. |
255 | | * (path does not have the leading '/'). |
256 | | * @param count Number of Uri-Path-Abbrev table entries. |
257 | | * |
258 | | * @return @c 1 on success, @c 0 if error. |
259 | | * |
260 | | */ |
261 | | int coap_uri_into_optlist_abbrev(const coap_uri_t *uri, const coap_address_t *dst, |
262 | | coap_optlist_t **optlist_chain, |
263 | | int create_port_host_opt, |
264 | | coap_upa_abbrev_t *mapping, uint32_t count); |
265 | | |
266 | | /** |
267 | | * Splits the given URI path into segments. Each segment is preceded |
268 | | * by an option pseudo-header with delta-value 0 and the actual length |
269 | | * of the respective segment after percent-decoding. |
270 | | * |
271 | | * @param path The path string to split. |
272 | | * @param length The actual length of @p path. |
273 | | * @param buf Result buffer for parsed segments. |
274 | | * @param buflen Maximum length of @p buf. Will be set to the actual number |
275 | | * of bytes written into buf on success. This needs to be |
276 | | * at least @p length, but 2 bytes should be added for each |
277 | | * segment to handle large segments. |
278 | | * |
279 | | * @return The number of segments created or @c -1 on error. |
280 | | */ |
281 | | int coap_split_path(const uint8_t *path, |
282 | | size_t length, |
283 | | unsigned char *buf, |
284 | | size_t *buflen); |
285 | | |
286 | | /** |
287 | | * Splits the given URI path into '/' separate segments, and then adds |
288 | | * the Uri-Path / Location-Path option for each segment to the @p optlist_chain. |
289 | | * |
290 | | * Note: any segments that are just '.' or '..' are stripped out. |
291 | | * |
292 | | * @param path The path string to split. |
293 | | * @param length The actual length of @p path. |
294 | | * @param optnum The CoAP option (COAP_OPTION_URI_PATH or |
295 | | * COAP_OPTION_LOCATION_PATH) |
296 | | * @param optlist_chain The chain of optlists to add to. optlist_chain |
297 | | * parent is to be NULL or a previous set of optlists. |
298 | | * |
299 | | * @return @c 1 on success else @c 0 if error. |
300 | | */ |
301 | | int coap_path_into_optlist(const uint8_t *path, size_t length, |
302 | | coap_option_num_t optnum, |
303 | | coap_optlist_t **optlist_chain); |
304 | | /** |
305 | | * Splits the given URI path into '/' separate segments, and then adds |
306 | | * the Uri-Path / Location-Path option for each segment to the @p optlist_chain. |
307 | | * |
308 | | * Note: any segments that are just '.' or '..' are stripped out. |
309 | | * |
310 | | * @param path The path string to split. |
311 | | * @param length The actual length of @p path. |
312 | | * @param optnum The CoAP option (COAP_OPTION_URI_PATH or |
313 | | * COAP_OPTION_LOCATION_PATH) |
314 | | * @param optlist_chain The chain of optlists to add to. optlist_chain |
315 | | * parent is to be NULL or a previous set of optlists. |
316 | | * @param mapping A path mapping to value for Uri-Path-Abbrev table or NULL. |
317 | | * (path does not have the leading '/'). |
318 | | * @param count Number of Uri-Path-Abbrev table entries. |
319 | | * |
320 | | * @return @c 1 on success else @c 0 if error. |
321 | | */ |
322 | | int coap_path_into_optlist_abbrev(const uint8_t *path, size_t length, |
323 | | coap_option_num_t optnum, |
324 | | coap_optlist_t **optlist_chain, |
325 | | coap_upa_abbrev_t *mapping, uint32_t count); |
326 | | |
327 | | /** |
328 | | * Splits the given URI query into segments. Each segment is preceded |
329 | | * by an option pseudo-header with delta-value 0 and the actual length |
330 | | * of the respective query segment. |
331 | | * |
332 | | * @param query The query string to split. |
333 | | * @param length The actual length of @p query |
334 | | * @param buf Result buffer for parsed segments. |
335 | | * @param buflen Maximum length of @p buf. Will be set to the actual number |
336 | | * of bytes written into buf on success. This needs to be |
337 | | * at least @p length, but 2 bytes should be added for each |
338 | | * segment to handle large segments. |
339 | | * |
340 | | * @return The number of segments created or @c -1 on error. |
341 | | */ |
342 | | int coap_split_query(const uint8_t *query, |
343 | | size_t length, |
344 | | unsigned char *buf, |
345 | | size_t *buflen); |
346 | | |
347 | | /** |
348 | | * Splits the given URI query into '&' separate segments, and then adds |
349 | | * the Uri-Query / Location-Query option for each segment to the @p optlist_chain. |
350 | | * |
351 | | * @param query The query string to split. |
352 | | * @param length The actual length of @p query. |
353 | | * @param optnum The CoAP option (COAP_OPTION_URI_QUERY or |
354 | | * COAP_OPTION_LOCATION_QUERY) |
355 | | * @param optlist_chain The chain of optlists to add to. optlist_chain |
356 | | * parent is to be NULL or a previous set of optlists. |
357 | | * |
358 | | * @return @c 1 on success else @c 0 if error. |
359 | | */ |
360 | | int coap_query_into_optlist(const uint8_t *query, size_t length, |
361 | | coap_option_num_t optnum, |
362 | | coap_optlist_t **optlist_chain); |
363 | | |
364 | | /** |
365 | | * Extract query string from request PDU according to escape rules in 6.5.8. |
366 | | * @param request Request PDU. |
367 | | * @return Reconstructed and escaped query string part or @c NULL if |
368 | | * no query was contained in @p request. The coap_string_t |
369 | | * object returned by this function must be released with |
370 | | * coap_delete_string. |
371 | | */ |
372 | | coap_string_t *coap_get_query(const coap_pdu_t *request); |
373 | | |
374 | | /** |
375 | | * Extract uri_path string from request PDU |
376 | | * @param request Request PDU. |
377 | | * @return Reconstructed and escaped uri path string part or @c NULL |
378 | | * if no Uri-Path was contained in @p request. The |
379 | | * coap_string_t object returned by this function must be |
380 | | * released with coap_delete_string. |
381 | | */ |
382 | | coap_string_t *coap_get_uri_path(const coap_pdu_t *request); |
383 | | |
384 | | /** |
385 | | * Define a Path to use if an Uri-Path-Abbrev option fails and the client |
386 | | * is to retry the request using Uri-Path instread of Uri-Path-Abbrev. |
387 | | * |
388 | | * @param mapping A path mapping to value for Uri-Path-Abbrev table or NULL |
389 | | if the previous mapping is to be cleared. |
390 | | * (path does not have the leading '/'). |
391 | | * @param count Number of Uri-Path-Abbrev table entries. |
392 | | */ |
393 | | void coap_upa_client_fallback(coap_upa_abbrev_t *mapping, uint32_t count); |
394 | | |
395 | | /** |
396 | | * Define a Path to use on receipt of an Uri-Path-Abbrev option value. |
397 | | * |
398 | | * @param mapping A path mapping to value for Uri-Path-Abbrev table or NULL |
399 | | if the previous mapping is to be cleared. |
400 | | * (path does not have the leading '/'). |
401 | | * @param count Number of Uri-Path-Abbrev table entries. |
402 | | */ |
403 | | void coap_upa_server_mapping(coap_upa_abbrev_t *mapping, uint32_t count); |
404 | | |
405 | | /** @} */ |
406 | | |
407 | | #ifdef __cplusplus |
408 | | } |
409 | | #endif |
410 | | |
411 | | #endif /* COAP_URI_H_ */ |