1 /* 2 * This file is part of the Sofia-SIP package 3 * 4 * Copyright (C) 2005 Nokia Corporation. 5 * 6 * Contact: Pekka Pessi <pekka.pessi@nokia.com> 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public License 10 * as published by the Free Software Foundation; either version 2.1 of 11 * the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 * 02110-1301 USA 22 * 23 */ 24 25 /**@file sofia-sip/url.h 26 * 27 * URL struct and helper functions. 28 * 29 * @author Pekka Pessi <Pekka.Pessi@nokia.com> 30 * 31 * @date Created: Thu Jun 8 19:28:55 2000 ppessi 32 */ 33 34 #ifndef URL_H_TYPES 35 #define URL_H_TYPES 36 37 /** Recognized URL schemes (value of url_t.url_type). 38 * 39 * @sa <<a href="http://www.iana.org/assignments/uri-schemes.html">http://www.iana.org/assignments/uri-schemes.html</a>> 40 */ 41 enum url_type_e { 42 url_invalid = -2, /**< Invalid url. */ 43 url_unknown = -1, /**< Unknown scheme. */ 44 url_any = 0, /**< "*" */ 45 url_sip, /**< "sip:". @sa @RFC3261 */ 46 url_sips, /**< "sips:". @sa @RFC3261 */ 47 url_urn, /**< "urn:". @sa @RFC6061 */ 48 url_tel, /**< "tel:" @sa RFC3966 */ 49 url_fax, /**< "fax:". @note Obsolete. @sa @RFC2806 */ 50 url_modem, /**< "modem:". @note Obsolete. @sa @RFC2806 */ 51 url_http, /**< "http:". @sa @RFC2616, @RFC3986 */ 52 url_https, /**< "https:". @sa @RFC2618, @RFC3986 */ 53 url_ftp, /**< "ftp:". @sa @RFC1738 */ 54 url_file, /**< "file:" @sa @RFC1738 */ 55 url_rtsp, /**< "rtsp:" @sa @RFC2326 */ 56 url_rtspu, /**< "rtspu:" @sa @RFC2326 */ 57 url_mailto, /**< "mailto:" @sa @RFC2368 */ 58 url_im, /**< "im:" (simple instant messaging). @sa @RFC3860 */ 59 url_pres, /**< "pres:" (simple presence). @sa @RFC3859 */ 60 url_cid, /**< "cid:" (Content-ID). @sa @RFC2392 */ 61 url_msrp, /**< "msrp:" (message session relay) */ 62 url_msrps, /**< "msrps:" (new in @VERSION_1_12_2) */ 63 url_wv, /**< "wv:" (Wireless village) */ 64 _url_none 65 }; 66 67 /** URL structure. 68 * 69 * This structure is used to present a parsed URL. 70 */ 71 typedef struct { 72 char url_pad[sizeof(void *) - 2]; 73 /**< Zero pad for URL_STRING_P(). */ 74 signed char url_type; /**< URL type (url_type_e). */ 75 char url_root; /**< Nonzero if root "//" */ 76 char const *url_scheme; /**< URL type as string. */ 77 char const *url_user; /**< User part */ 78 char const *url_password; /**< Password */ 79 char const *url_host; /**< Host part */ 80 char const *url_port; /**< Port */ 81 char const *url_path; /**< Path part, starts with "/" */ 82 char const *url_params; /**< Parameters (separated by ;) */ 83 char const *url_headers; /**< Headers (separated by ? and &) */ 84 char const *url_fragment; /**< Fragment (separated by #) */ 85 } url_t; 86 87 enum { 88 /** Maximum size of a URL. */ 89 URL_MAXLEN = 65536 90 }; 91 92 /** Type to present either a parsed URL or string. 93 * 94 * The union type url_string_t is used to pass a parsed URL or string as a 95 * parameter. The URL_STRING_P() checks if a passed pointer points to a 96 * string or a parsed URL. Testing requires that the first character of the 97 * string is nonzero. Use URL_STRING_MAKE() to properly cast a string 98 * pointer as a pointer to url_string_t. 99 */ 100 typedef union { 101 char us_str[URL_MAXLEN]; /**< URL as a string. */ 102 url_t us_url[1]; /**< Parsed URL. */ 103 } url_string_t; 104 105 #endif 106 107 #ifndef URL_H 108 /** Defined when <sofia-sip/url.h> has been included. */ 109 #define URL_H 110 111 #ifndef SU_ALLOC_H 112 #include <sofia-sip/su_alloc.h> 113 #endif 114 115 SOFIA_BEGIN_DECLS 116 117 /** Convert a string to a url struct. */ 118 SOFIAPUBFUN url_t *url_make(su_home_t *h, char const *str); 119 120 /** Convert a string formatting result to a url struct. */ 121 SOFIAPUBFUN url_t *url_format(su_home_t *h, char const *fmt, ...); 122 123 /** Convert #url_t to a string allocated from @a home */ 124 SOFIAPUBFUN char *url_as_string(su_home_t *home, url_t const *url); 125 126 /** Duplicate the url to memory allocated via home */ 127 SOFIAPUBFUN url_t *url_hdup(su_home_t *h, url_t const *src); 128 129 /** Sanitize a URL. */ 130 SOFIAPUBFUN int url_sanitize(url_t *u); 131 132 /** Get URL scheme by type. */ 133 SOFIAPUBFUN char const *url_scheme(enum url_type_e type); 134 135 /* ---------------------------------------------------------------------- */ 136 /* URL comparison */ 137 138 /** Compare two URLs lazily. */ 139 SOFIAPUBFUN int url_cmp(url_t const *a, url_t const *b); 140 141 /** Compare two URLs conservatively. */ 142 SOFIAPUBFUN int url_cmp_all(url_t const *a, url_t const *b); 143 144 /* ---------------------------------------------------------------------- */ 145 /* Parameter handling */ 146 147 /** Search for a parameter. */ 148 SOFIAPUBFUN isize_t url_param(char const *params, char const *tag, 149 char value[], isize_t vlen); 150 151 /** Check for a parameter. */ 152 SOFIAPUBFUN int url_has_param(url_t const *url, char const *name); 153 154 /** Check for a presence of a parameter in string. */ 155 SOFIAPUBFUN isize_t url_have_param(char const *params, char const *tag); 156 157 /** Add a parameter. */ 158 SOFIAPUBFUN int url_param_add(su_home_t *h, url_t *url, char const *param); 159 160 /** Strip transport-specific stuff away from URI. */ 161 SOFIAPUBFUN int url_strip_transport(url_t *u); 162 163 /** Strip parameter away from URI. */ 164 SOFIAPUBFUN char *url_strip_param_string(char *params, char const *name); 165 166 /** Test if url has any transport-specific stuff. */ 167 SOFIAPUBFUN int url_have_transport(url_t const *u); 168 169 /* ---------------------------------------------------------------------- */ 170 /* Query handling */ 171 172 /** Convert a URL query to a header string. */ 173 SOFIAPUBFUN char *url_query_as_header_string(su_home_t *home, 174 char const *query); 175 176 /* ---------------------------------------------------------------------- */ 177 /* Handling url-escque strings */ 178 179 /** Test if string contains url-reserved characters. */ 180 SOFIAPUBFUN int url_reserved_p(char const *s); 181 182 /** Escape a string. */ 183 SOFIAPUBFUN char *url_escape(char *d, char const *s, char const reserved[]); 184 185 /** Calculate length of string when escaped. */ 186 SOFIAPUBFUN isize_t url_esclen(char const *s, char const reserved[]); 187 188 /** Unescape characters from string */ 189 SOFIAPUBFUN size_t url_unescape_to(char *d, char const *s, size_t n); 190 191 /** Unescape a string */ 192 SOFIAPUBFUN char *url_unescape(char *d, char const *s); 193 194 #define URL_RESERVED_CHARS ";/?:@&=+$," 195 196 /* ---------------------------------------------------------------------- */ 197 /* Initializing */ 198 199 /** Initializer for an #url_t structure. @HI 200 * 201 * The macro URL_INIT_AS() is used to initialize a #url_t structure with a 202 * known url type: 203 * @code 204 * url_t urls[2] = { URL_INIT_AS(sip), URL_INIT_AS(http) }; 205 * @endcode 206 */ 207 #define URL_INIT_AS(type) \ 208 { "\0", url_##type, 0, url_##type != url_any ? #type : "*" } 209 210 /** Init a url structure as given type */ 211 SOFIAPUBFUN void url_init(url_t *url, enum url_type_e type); 212 213 /* ---------------------------------------------------------------------- */ 214 /* Resolving helpers */ 215 216 /** Return default port number corresponding to the url type. */ 217 SOFIAPUBFUN char const *url_port_default(enum url_type_e url_type); 218 219 /** Return default transport name corresponding to the url type */ 220 SOFIAPUBFUN char const *url_tport_default(enum url_type_e url_type); 221 222 /** Return the URL port string, using default port if not present. */ 223 SOFIAPUBFUN char const *url_port(url_t const *u); 224 225 /** Return the URL port string, using default port if none present. */ 226 #define URL_PORT(u) \ 227 ((u) && (u)->url_port ? (u)->url_port : \ 228 url_port_default((u) ? (enum url_type_e)(u)->url_type : url_any)) 229 230 /* ---------------------------------------------------------------------- */ 231 /* url_string_t handling */ 232 233 /** Test if a pointer to #url_string_t is a string 234 * (not a pointer to a #url_t structure). */ 235 #define URL_STRING_P(u) ((u) && *((url_string_t*)(u))->us_str != 0) 236 237 /** Test if a pointer to #url_string_t is a string 238 * (not a pointer to a #url_t structure). */ 239 #define URL_IS_STRING(u) ((u) && *((url_string_t*)(u))->us_str != 0) 240 241 /** Test if a pointer to #url_string_t is a string 242 * (not a pointer to a #url_t structure). */ 243 SOFIAPUBFUN int url_string_p(url_string_t const * url); 244 245 /** Test if a pointer to #url_string_t is a string 246 * (not a pointer to a #url_t structure). */ 247 SOFIAPUBFUN int url_is_string(url_string_t const * url); 248 249 /** Cast a string to a #url_string_t. @HI */ 250 #define URL_STRING_MAKE(s) \ 251 ((url_string_t *)((s) && *((char *)(s)) ? (s) : NULL)) 252 253 /* ---------------------------------------------------------------------- */ 254 /* Printing URL */ 255 256 /** Format string used when printing url with printf(). @HI */ 257 #define URL_PRINT_FORMAT "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s" 258 #define URL_FORMAT_STRING URL_PRINT_FORMAT 259 260 /** Argument list used when printing url with printf(). @HI */ 261 #define URL_PRINT_ARGS(u) \ 262 (u)->url_scheme ? (u)->url_scheme : "", \ 263 (u)->url_type != url_any && (u)->url_scheme && (u)->url_scheme[0] \ 264 ? ":" : "", \ 265 (u)->url_root && ((u)->url_host || (u)->url_user) ? "//" : "", \ 266 (u)->url_user ? (u)->url_user : "", \ 267 (u)->url_user && (u)->url_password ? ":" : "", \ 268 (u)->url_user && (u)->url_password ? (u)->url_password : "", \ 269 (u)->url_user && (u)->url_host ? "@" : "", \ 270 (u)->url_host ? (u)->url_host : "", \ 271 (u)->url_host && (u)->url_port ? ":" : "", \ 272 (u)->url_host && (u)->url_port ? (u)->url_port : "", \ 273 (u)->url_root && (u)->url_path ? "/" : "", \ 274 (u)->url_path ? (u)->url_path : "", \ 275 (u)->url_params ? ";" : "", (u)->url_params ? (u)->url_params : "", \ 276 (u)->url_headers ? "?" : "", (u)->url_headers ? (u)->url_headers : "", \ 277 (u)->url_fragment ? "#" : "", (u)->url_fragment ? (u)->url_fragment : "" 278 279 /* ---------------------------------------------------------------------- */ 280 /* URL digests */ 281 282 struct su_md5_t; 283 284 /** Update MD5 sum with URL contents. */ 285 SOFIAPUBFUN void url_update(struct su_md5_t *md5, url_t const *url); 286 287 /** Calculate a digest from URL contents. */ 288 SOFIAPUBFUN void url_digest(void *hash, int hsize, 289 url_t const *, char const *key); 290 291 /* ---------------------------------------------------------------------- */ 292 /* Parsing and manipulating URLs */ 293 294 /** Decode a URL. */ 295 SOFIAPUBFUN int url_d(url_t *url, char *s); 296 297 /** Calculate the encoding length of URL. */ 298 SOFIAPUBFUN isize_t url_len(url_t const * url); 299 300 /** Encode a URL. */ 301 SOFIAPUBFUN issize_t url_e(char buffer[], isize_t n, url_t const *url); 302 303 /** Encode a URL: use @a buf up to @a end. @HI */ 304 #define URL_E(buf, end, url) \ 305 (buf) += url_e((buf), (buf) < (end) ? (end) - (buf) : 0, (url)) 306 307 /** Calculate the size of srings attached to the url. */ 308 SOFIAPUBFUN isize_t url_xtra(url_t const * url); 309 310 /** Duplicate the url in the provided memory area. */ 311 SOFIAPUBFUN issize_t url_dup(char *, isize_t , url_t *dst, url_t const *src); 312 313 /** Duplicate the url: use @a buf up to @a end. @HI */ 314 #define URL_DUP(buf, end, dst, src) \ 315 (buf) += url_dup((buf), (isize_t)((buf) < (end) ? (end) - (buf) : 0), (dst), (src)) 316 317 SOFIA_END_DECLS 318 #endif 319 320