Coverage Report

Created: 2026-04-12 06:45

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
static inline int
86
0
coap_uri_scheme_is_secure(const coap_uri_t *uri) {
87
0
  return uri && ((uri->scheme & COAP_URI_SCHEME_SECURE_MASK) != 0);
88
0
}
Unexecuted instantiation: observe_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
89
90
/**
91
 * Determines from the @p host whether this is a Unix Domain socket
92
 * request.
93
 *
94
 * @param host    The host object.
95
 *
96
 * @return        @c 0 on failure, or @c 1 on success.
97
 *
98
 */
99
int coap_host_is_unix_domain(const coap_str_const_t *host);
100
101
/**
102
 * Creates a new coap_uri_t object from the specified URI. Returns the new
103
 * object or NULL on error. The memory allocated by the new coap_uri_t
104
 * should be released using coap_delete_uri().
105
 *
106
 * @param uri The URI path to copy.
107
 * @param length The length of uri.
108
 *
109
 * @return New URI object or NULL on error.
110
 */
111
coap_uri_t *coap_new_uri(const uint8_t *uri, unsigned int length);
112
113
/**
114
 * Clones the specified coap_uri_t object. This function allocates sufficient
115
 * memory to hold the coap_uri_t structure and its contents. The object should
116
 * be released with delete_uri().
117
 *
118
 * @param uri The coap_uri_t structure to copy.
119
 *
120
 * @return New URI object or NULL on error.
121
 */
122
coap_uri_t *coap_clone_uri(const coap_uri_t *uri);
123
124
/**
125
 * Removes the specified coap_uri_t object.
126
 *
127
 * @param uri The coap_uri_t structure to remove.
128
 */
129
void coap_delete_uri(coap_uri_t *uri);
130
131
/**
132
 * @ingroup application_api
133
 * @defgroup uri_parse URI Parsing Functions
134
 * API for parsing URIs.
135
 * CoAP PDUs contain normalized URIs with their path and query split into
136
 * multiple segments. The functions in this module help splitting strings.
137
 * @{
138
 */
139
140
/**
141
 * Parses a given string into URI components. The identified syntactic
142
 * components are stored in the result parameter @p uri. Optional URI
143
 * components that are not specified will be set to { 0, 0 }, except for the
144
 * port which is set to the default port for the protocol. This function
145
 * returns @p 0 if parsing succeeded, a value less than zero otherwise.
146
 *
147
 * @param str_var The string to split up.
148
 * @param len     The actual length of @p str_var
149
 * @param uri     The coap_uri_t object to store the result.
150
 *
151
 * @return        @c 0 on success, or < 0 on error.
152
 *
153
 */
154
int coap_split_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri);
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 default port for the protocol. This function returns
161
 * @p 0 if parsing succeeded, a value less than zero otherwise.
162
 * Note: This function enforces that the given string is in Proxy-Uri format
163
 *       as well as supports different schema such as http and https.
164
 *
165
 * @param str_var The string to split up.
166
 * @param len     The actual length of @p str_var
167
 * @param uri     The coap_uri_t object to store the result.
168
 *
169
 * @return        @c 0 on success, or < 0 on error.
170
 *
171
 */
172
int coap_split_proxy_uri(const uint8_t *str_var, size_t len, coap_uri_t *uri);
173
174
/**
175
 * Takes a coap_uri_t and then adds CoAP options into the @p optlist_chain.
176
 * If the port is not the default port and create_port_host_opt is not 0, then
177
 * the Uri-Port option is added to the @p optlist_chain.
178
 * If the dst defines an address that does not match the host in uri->host and
179
 * is not 0, then the Uri-Host option is added to the @p optlist_chain.
180
 * Any path or query are broken down into the individual segment Uri-Path or
181
 * Uri-Query options and added to the @p optlist_chain.
182
 *
183
 * Note: coap_uri_into_optlist(3) is an alternative function (but has a
184
 * different return value).
185
 *
186
 * @param uri     The coap_uri_t object.
187
 * @param dst     The destination, or NULL if URI_HOST not to be added.
188
 * @param optlist_chain Where to store the chain of options.
189
 * @param create_port_host_opt @c 1 if port/host option to be added
190
 *                             (if non-default) else @c 0
191
 * @param buf     Parameter ignored. Can be NULL.
192
 * @param buflen  Parameter ignored.
193
 *
194
 * @return        @c 0 on success, or < 0 on error.
195
 *
196
 */
197
int coap_uri_into_options(const coap_uri_t *uri, const coap_address_t *dst,
198
                          coap_optlist_t **optlist_chain,
199
                          int create_port_host_opt,
200
                          uint8_t *buf, size_t buflen);
201
202
/**
203
 * Takes a coap_uri_t and then adds CoAP options into the @p optlist_chain.
204
 * If the port is not the default port and create_port_host_opt is not 0, then
205
 * the Uri-Port option is added to the @p optlist_chain.
206
 * If the dst defines an address that does not match the host in uri->host and
207
 * is not 0, then the Uri-Host option is added to the @p optlist_chain.
208
 * Any path or query are broken down into the individual segment Uri-Path or
209
 * Uri-Query options and added to the @p optlist_chain.
210
 *
211
 * @param uri     The coap_uri_t object.
212
 * @param dst     The destination, or NULL if URI_HOST not to be added.
213
 * @param optlist_chain Where to store the chain of options.
214
 * @param create_port_host_opt @c 1 if port/host option to be added
215
 *                             (if non-default) else @c 0.
216
 *
217
 * @return        @c 1 on success, @c 0 if error.
218
 *
219
 */
220
int coap_uri_into_optlist(const coap_uri_t *uri, const coap_address_t *dst,
221
                          coap_optlist_t **optlist_chain,
222
                          int create_port_host_opt);
223
224
/**
225
 * Splits the given URI path into segments. Each segment is preceded
226
 * by an option pseudo-header with delta-value 0 and the actual length
227
 * of the respective segment after percent-decoding.
228
 *
229
 * @param path   The path string to split.
230
 * @param length The actual length of @p path.
231
 * @param buf    Result buffer for parsed segments.
232
 * @param buflen Maximum length of @p buf. Will be set to the actual number
233
 *               of bytes written into buf on success. This needs to be
234
 *               at least @p length, but 2 bytes should be added for each
235
 *               segment to handle large segments.
236
 *
237
 * @return       The number of segments created or @c -1 on error.
238
 */
239
int coap_split_path(const uint8_t *path,
240
                    size_t length,
241
                    unsigned char *buf,
242
                    size_t *buflen);
243
244
/**
245
 * Splits the given URI path into '/' separate segments, and then adds
246
 * the Uri-Path / Location-Path option for each segment to the @p optlist_chain.
247
 *
248
 * Note: any segments that are just '.' or '..' are stripped out.
249
 *
250
 * @param path   The path string to split.
251
 * @param length The actual length of @p path.
252
 * @param optnum The CoAP option (COAP_OPTION_URI_PATH or
253
 *               COAP_OPTION_LOCATION_PATH)
254
 * @param optlist_chain The chain of optlists to add to. optlist_chain
255
 *                      parent is to be NULL or a previous set of optlists.
256
 *
257
 * @return       @c 1 on success else @c 0 if error.
258
 */
259
int coap_path_into_optlist(const uint8_t *path, size_t length,
260
                           coap_option_num_t optnum,
261
                           coap_optlist_t **optlist_chain);
262
263
/**
264
 * Splits the given URI query into segments. Each segment is preceded
265
 * by an option pseudo-header with delta-value 0 and the actual length
266
 * of the respective query segment.
267
 *
268
 * @param query  The query string to split.
269
 * @param length The actual length of @p query
270
 * @param buf    Result buffer for parsed segments.
271
 * @param buflen Maximum length of @p buf. Will be set to the actual number
272
 *               of bytes written into buf on success. This needs to be
273
 *               at least @p length, but 2 bytes should be added for each
274
 *               segment to handle large segments.
275
 *
276
 * @return       The number of segments created or @c -1 on error.
277
 */
278
int coap_split_query(const uint8_t *query,
279
                     size_t length,
280
                     unsigned char *buf,
281
                     size_t *buflen);
282
283
/**
284
 * Splits the given URI query into '&' separate segments, and then adds
285
 * the Uri-Query / Location-Query option for each segment to the @p optlist_chain.
286
 *
287
 * @param query  The query string to split.
288
 * @param length The actual length of @p query.
289
 * @param optnum The CoAP option (COAP_OPTION_URI_QUERY or
290
 *               COAP_OPTION_LOCATION_QUERY)
291
 * @param optlist_chain The chain of optlists to add to. optlist_chain
292
 *                      parent is to be NULL or a previous set of optlists.
293
 *
294
 * @return       @c 1 on success else @c 0 if error.
295
 */
296
int coap_query_into_optlist(const uint8_t *query, size_t length,
297
                            coap_option_num_t optnum,
298
                            coap_optlist_t **optlist_chain);
299
300
/**
301
 * Extract query string from request PDU according to escape rules in 6.5.8.
302
 * @param request Request PDU.
303
 * @return        Reconstructed and escaped query string part or @c NULL if
304
 *                no query was contained in @p request. The coap_string_t
305
 *                object returned by this function must be released with
306
 *                coap_delete_string.
307
 */
308
coap_string_t *coap_get_query(const coap_pdu_t *request);
309
310
/**
311
 * Extract uri_path string from request PDU
312
 * @param request Request PDU.
313
 * @return        Reconstructed and escaped uri path string part or @c NULL
314
 *                if no Uri-Path was contained in @p request. The
315
 *                coap_string_t object returned by this function must be
316
 *                released with coap_delete_string.
317
 */
318
coap_string_t *coap_get_uri_path(const coap_pdu_t *request);
319
320
/** @} */
321
322
#ifdef __cplusplus
323
}
324
#endif
325
326
#endif /* COAP_URI_H_ */