Coverage Report

Created: 2026-05-16 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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_ */