Coverage Report

Created: 2026-01-09 06:55

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 <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_ */