summaryrefslogtreecommitdiffstats
path: root/include/iprt/uri.h
blob: 75787cd44c8820f7ff58a17417e656484eb98f37 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
/** @file
 * IPRT - Uniform Resource Identifier handling.
 */

/*
 * Copyright (C) 2011-2022 Oracle and/or its affiliates.
 *
 * This file is part of VirtualBox base platform packages, as
 * available from https://www.virtualbox.org.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, in version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses>.
 *
 * The contents of this file may alternatively be used under the terms
 * of the Common Development and Distribution License Version 1.0
 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
 * in the VirtualBox distribution, in which case the provisions of the
 * CDDL are applicable instead of those of the GPL.
 *
 * You may elect to license modified versions of this file under the
 * terms and conditions of either the GPL or the CDDL or both.
 *
 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
 */

#ifndef IPRT_INCLUDED_uri_h
#define IPRT_INCLUDED_uri_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif

#include <iprt/cdefs.h>
#include <iprt/types.h>

RT_C_DECLS_BEGIN

/** @defgroup grp_rt_uri    RTUri - Uri parsing and creation
 *
 * URI parsing and creation based on RFC-3986.
 *
 * @remarks The whole specification isn't implemented and we only provide scheme
 *          specific special APIs for "file://".
 *
 * @ingroup grp_rt
 * @{
 */


/**
 * Parsed URI.
 *
 * @remarks This structure is subject to change.
 */
typedef struct RTURIPARSED
{
    /** Magic value (for internal use only). */
    uint32_t    u32Magic;
    /** RTURIPARSED_F_XXX. */
    uint32_t    fFlags;

    /** The length of the scheme. */
    size_t      cchScheme;

    /** The offset into the string of the authority. */
    size_t      offAuthority;
    /** The authority length.
     * @remarks The authority component can be zero length, so to check whether
     *          it's there or not consult RTURIPARSED_F_HAVE_AUTHORITY. */
    size_t      cchAuthority;

    /** The offset into the string of the path. */
    size_t      offPath;
    /** The length of the path. */
    size_t      cchPath;

    /** The offset into the string of the query. */
    size_t      offQuery;
    /** The length of the query. */
    size_t      cchQuery;

    /** The offset into the string of the fragment. */
    size_t      offFragment;
    /** The length of the fragment. */
    size_t      cchFragment;

    /** @name Authority subdivisions
     * @{ */
    /** If there is a userinfo part, this is the start of it. Otherwise it's the
     * same as offAuthorityHost. */
    size_t      offAuthorityUsername;
    /** The length of the username (zero if not present). */
    size_t      cchAuthorityUsername;
    /** If there is a userinfo part containing a password, this is the start of it.
     * Otherwise it's the same as offAuthorityHost. */
    size_t      offAuthorityPassword;
    /** The length of the password (zero if not present). */
    size_t      cchAuthorityPassword;
    /** The offset of the host part of the authority. */
    size_t      offAuthorityHost;
    /** The length of the host part of the authority. */
    size_t      cchAuthorityHost;
    /** The authority port number, UINT32_MAX if not present or empty. */
    uint32_t    uAuthorityPort;
    /** @} */
} RTURIPARSED;
/** Pointer to a parsed URI. */
typedef RTURIPARSED *PRTURIPARSED;
/** Pointer to a const parsed URI. */
typedef RTURIPARSED const *PCRTURIPARSED;

/** @name  RTURIPARSED_F_XXX - RTURIPARSED::fFlags
 * @{  */
/** Set if the URI contains escaped characters. */
#define RTURIPARSED_F_CONTAINS_ESCAPED_CHARS        UINT32_C(0x00000001)
/** Set if the URI has an authority component.  Necessary since the authority
 * component can have a zero length. */
#define RTURIPARSED_F_HAS_AUTHORITY                 UINT32_C(0x00000002)
/** Set if there is a port component. */
#define RTURIPARSED_F_HAS_PORT                      UINT32_C(0x00000004)
/** @} */

/**
 * Parses a URI.
 *
 * @returns IPRT status code.
 * @param   pszUri              The URI to parse.
 * @param   pParsed             Where to return the details.  This can be handed
 *                              to the RTUriParsed* APIs for retriving
 *                              information.
 */
RTDECL(int) RTUriParse(const char *pszUri, PRTURIPARSED pParsed);

/**
 * Extract the scheme out of a parsed URI.
 *
 * @returns the scheme if the URI is valid, NULL otherwise.
 * @param   pszUri              The URI passed to RTUriParse when producing the
 *                              info in @a pParsed.
 * @param   pParsed             Pointer to the RTUriParse output.
 */
RTDECL(char *) RTUriParsedScheme(const char *pszUri, PCRTURIPARSED pParsed);

/**
 * Extract the authority out of a parsed URI.
 *
 * @returns the authority if the URI contains one, NULL otherwise.
 * @param   pszUri              The URI passed to RTUriParse when producing the
 *                              info in @a pParsed.
 * @param   pParsed             Pointer to the RTUriParse output.
 * @remarks The authority can have a zero length.
 */
RTDECL(char *) RTUriParsedAuthority(const char *pszUri, PCRTURIPARSED pParsed);

/**
 * Extract the username out of the authority component in a parsed URI.
 *
 * @returns The username if the URI contains one, otherwise NULL.
 * @param   pszUri              The URI passed to RTUriParse when producing the
 *                              info in @a pParsed.
 * @param   pParsed             Pointer to the RTUriParse output.
 *
 * @todo    This may currently be returning NULL when it maybe would be more
 *          appropriate to return an empty string...
 */
RTDECL(char *) RTUriParsedAuthorityUsername(const char *pszUri, PCRTURIPARSED pParsed);

/**
 * Extract the password out of the authority component in a parsed URI.
 *
 * @returns The password if the URI contains one, otherwise NULL.
 * @param   pszUri              The URI passed to RTUriParse when producing the
 *                              info in @a pParsed.
 * @param   pParsed             Pointer to the RTUriParse output.
 *
 * @todo    This may currently be returning NULL when it maybe would be more
 *          appropriate to return an empty string...
 */
RTDECL(char *) RTUriParsedAuthorityPassword(const char *pszUri, PCRTURIPARSED pParsed);

/**
 * Extract the host out of the authority component in a parsed URI.
 *
 * @returns The host if the URI contains one, otherwise NULL.
 * @param   pszUri              The URI passed to RTUriParse when producing the
 *                              info in @a pParsed.
 * @param   pParsed             Pointer to the RTUriParse output.
 *
 * @todo    This may currently be returning NULL when it maybe would be more
 *          appropriate to return an empty string...
 */
RTDECL(char *) RTUriParsedAuthorityHost(const char *pszUri, PCRTURIPARSED pParsed);

/**
 * Extract the port number out of the authority component in a parsed URI.
 *
 * @returns The port number if the URI contains one, otherwise UINT32_MAX.
 * @param   pszUri              The URI passed to RTUriParse when producing the
 *                              info in @a pParsed.
 * @param   pParsed             Pointer to the RTUriParse output.
 */
RTDECL(uint32_t) RTUriParsedAuthorityPort(const char *pszUri, PCRTURIPARSED pParsed);

/**
 * Extract the path out of a parsed URI.
 *
 * @returns the path if the URI contains one, NULL otherwise.
 * @param   pszUri              The URI passed to RTUriParse when producing the
 *                              info in @a pParsed.
 * @param   pParsed             Pointer to the RTUriParse output.
 */
RTDECL(char *) RTUriParsedPath(const char *pszUri, PCRTURIPARSED pParsed);

/**
 * Extract the query out of a parsed URI.
 *
 * @returns the query if the URI contains one, NULL otherwise.
 * @param   pszUri              The URI passed to RTUriParse when producing the
 *                              info in @a pParsed.
 * @param   pParsed             Pointer to the RTUriParse output.
 */
RTDECL(char *) RTUriParsedQuery(const char *pszUri, PCRTURIPARSED pParsed);

/**
 * Extract the fragment out of a parsed URI.
 *
 * @returns the fragment if the URI contains one, NULL otherwise.
 * @param   pszUri              The URI passed to RTUriParse when producing the
 *                              info in @a pParsed.
 * @param   pParsed             Pointer to the RTUriParse output.
 */
RTDECL(char *) RTUriParsedFragment(const char *pszUri, PCRTURIPARSED pParsed);



/**
 * Creates a generic URI.
 *
 * The returned pointer must be freed using RTStrFree().
 *
 * @returns the new URI on success, NULL otherwise.
 * @param   pszScheme           The URI scheme.
 * @param   pszAuthority        The authority part of the URI (optional).
 * @param   pszPath             The path part of the URI (optional).
 * @param   pszQuery            The query part of the URI (optional).
 * @param   pszFragment         The fragment part of the URI (optional).
 */
RTDECL(char *) RTUriCreate(const char *pszScheme, const char *pszAuthority, const char *pszPath, const char *pszQuery,
                           const char *pszFragment);

/**
 * Check whether the given scheme matches that of the URI.
 *
 * This does not validate the URI, it just compares the scheme, no more, no
 * less.  Thus it's much faster than using RTUriParsedScheme.
 *
 * @returns true if the scheme match, false if not.
 * @param   pszUri              The URI to check.
 * @param   pszScheme           The scheme to compare with.
 */
RTDECL(bool)   RTUriIsSchemeMatch(const char *pszUri, const char *pszScheme);

/** @defgroup grp_rt_uri_file   RTUriFile - Uri file parsing and creation
 *
 * Implements basic "file:" scheme support to the generic RTUri interface.  This
 * is partly documented in RFC-1738.
 *
 * @{
 */

/**
 * Creates a file URI.
 *
 * The returned pointer must be freed using RTStrFree().
 *
 * @returns The new URI on success, NULL otherwise.  Free With RTStrFree.
 * @param   pszPath         The path to create an 'file://' URI for.  This is
 *                          assumed to be using the default path style of the
 *                          system.
 *
 * @sa      RTUriFileCreateEx, RTUriCreate
 */
RTDECL(char *) RTUriFileCreate(const char *pszPath);

/**
 * Creates an file URL for the given path.
 *
 * This API works like RTStrToUtf16Ex with regard to result allocation or
 * buffering (i.e. it's a bit complicated but very flexible).
 *
 * @returns iprt status code.
 * @param   pszPath         The path to convert to a file:// URL.
 * @param   fPathStyle      The input path style, exactly one of
 *                          RTPATH_STR_F_STYLE_HOST, RTPATH_STR_F_STYLE_DOS and
 *                          RTPATH_STR_F_STYLE_UNIX.  Must include iprt/path.h.
 * @param   ppszUri         If cbUri is non-zero, this must either be pointing
 *                          to pointer to a buffer of the specified size, or
 *                          pointer to a NULL pointer.  If *ppszUri is NULL or
 *                          cbUri is zero a buffer of at least cbUri chars will
 *                          be allocated to hold the URI.  If a buffer was
 *                          requested it must be freed using RTStrFree().
 * @param   cbUri           The buffer size in bytes (includes terminator).
 * @param   pcchUri         Where to store the length of the URI string,
 *                          excluding the terminator. (Optional)
 *
 *                          This may be set under some error conditions,
 *                          however, only for VERR_BUFFER_OVERFLOW and
 *                          VERR_NO_STR_MEMORY will it contain a valid string
 *                          length that can be used to resize the buffer.
 * @sa      RTUriCreate, RTUriFileCreate
 */
RTDECL(int) RTUriFileCreateEx(const char *pszPath, uint32_t fPathStyle, char **ppszUri, size_t cbUri, size_t *pcchUri);

/**
 * Returns the file path encoded in the file URI.
 *
 * This differs a quite a bit from RTUriParsedPath in that it tries to be
 * compatible with URL produced by older windows version.  This API is basically
 * producing the same results as the PathCreateFromUrl API on Windows.
 *
 * @returns The path if the URI contains one, system default path style,
 *          otherwise NULL.
 * @param   pszUri          The alleged 'file://' URI to extract the path from.
 *
 * @sa      RTUriParsedPath, RTUriFilePathEx
 */
RTDECL(char *) RTUriFilePath(const char *pszUri);

/**
 * Queries the file path for the given file URI.
 *
 * This API works like RTStrToUtf16Ex with regard to result allocation or
 * buffering (i.e. it's a bit complicated but very flexible).
 *
 * This differs a quite a bit from RTUriParsedPath in that it tries to be
 * compatible with URL produced by older windows version.  This API is basically
 * producing the same results as the PathCreateFromUrl API on Windows.
 *
 * @returns IPRT status code.
 * @retval  VERR_URI_NOT_FILE_SCHEME if not file scheme.
 *
 * @param   pszUri          The alleged file:// URI to extract the path from.
 * @param   fPathStyle      The output path style, exactly one of
 *                          RTPATH_STR_F_STYLE_HOST, RTPATH_STR_F_STYLE_DOS and
 *                          RTPATH_STR_F_STYLE_UNIX.  Must include iprt/path.h.
 * @param   ppszPath        If cbPath is non-zero, this must either be pointing
 *                          to pointer to a buffer of the specified size, or
 *                          pointer to a NULL pointer.  If *ppszPath is NULL or
 *                          cbPath is zero a buffer of at least cbPath chars
 *                          will be allocated to hold the path.  If a buffer was
 *                          requested it must be freed using RTStrFree().
 * @param   cbPath          The buffer size in bytes (includes terminator).
 * @param   pcchPath        Where to store the length of the path string,
 *                          excluding the terminator. (Optional)
 *
 *                          This may be set under some error conditions,
 *                          however, only for VERR_BUFFER_OVERFLOW and
 *                          VERR_NO_STR_MEMORY will it contain a valid string
 *                          length that can be used to resize the buffer.
 * @sa      RTUriParsedPath, RTUriFilePath
 */
RTDECL(int) RTUriFilePathEx(const char *pszUri, uint32_t fPathStyle, char **ppszPath, size_t cbPath, size_t *pcchPath);

/** @} */

/** @} */

RT_C_DECLS_END

#endif /* !IPRT_INCLUDED_uri_h */