1 /******************************************************************************* 2 * 3 * Copyright (c) 2000-2003 Intel Corporation 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * - Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * - Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * - Neither name of Intel Corporation nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR 22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 26 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 ******************************************************************************/ 31 32 #ifndef GENLIB_NET_URI_H 33 #define GENLIB_NET_URI_H 34 35 /*! 36 * \file 37 */ 38 39 #if !defined(_WIN32) 40 #include <sys/param.h> 41 #endif 42 43 #include "UpnpGlobal.h" /* for */ 44 #include "UpnpInet.h" 45 46 #include <ctype.h> 47 #include <errno.h> 48 #include <fcntl.h> 49 #include <stdlib.h> 50 #include <string.h> 51 #include <sys/types.h> 52 #include <time.h> 53 54 #ifdef _WIN32 55 #if !defined(UPNP_USE_MSVCPP) && !defined(UPNP_USE_BCBPP) 56 /* VC Winsocks2 includes these functions */ 57 #include "inet_pton.h" 58 #endif 59 #else 60 #include <netdb.h> /* for struct addrinfo */ 61 #endif 62 63 #ifdef _WIN32 64 #define strncasecmp strnicmp 65 #else 66 /* Other systems have strncasecmp */ 67 #endif 68 69 #ifdef __cplusplus 70 extern "C" { 71 #endif 72 73 #define MARK "-_.!~*'()" 74 75 /*! added {} for compatibility */ 76 #define RESERVED ";/?:@&=+$,{}" 77 78 #define HTTP_SUCCESS 1 79 80 enum hostType { 81 HOSTNAME, 82 IPv4address 83 }; 84 85 enum pathType { 86 ABS_PATH, 87 REL_PATH, 88 OPAQUE_PART 89 }; 90 91 #ifdef _WIN32 92 /* there is a conflict in windows with other symbols. */ 93 enum uriType { 94 absolute, 95 relative 96 }; 97 #else 98 enum uriType { 99 ABSOLUTE, 100 RELATIVE 101 }; 102 #endif 103 104 /*! 105 * \brief Buffer used in parsinghttp messages, urls, etc. generally this simply 106 * holds a pointer into a larger array. 107 */ 108 typedef struct TOKEN { 109 const char *buff; 110 size_t size; 111 } token; 112 113 /*! 114 * \brief Represents a host port: e.g. "127.127.0.1:80" text is a token 115 * pointing to the full string representation. 116 */ 117 typedef struct HOSTPORT { 118 /*! Full host port. */ 119 token text; 120 /* Network Byte Order */ 121 struct sockaddr_storage IPaddress; 122 } hostport_type; 123 124 /*! 125 * \brief Represents a URI used in parse_uri and elsewhere 126 */ 127 typedef struct URI{ 128 enum uriType type; 129 token scheme; 130 enum pathType path_type; 131 token pathquery; 132 token fragment; 133 hostport_type hostport; 134 } uri_type; 135 136 /*! 137 * \brief Represents a list of URLs as in the "callback" header of SUBSCRIBE 138 * message in GENA. "char *" URLs holds dynamic memory. 139 */ 140 typedef struct URL_LIST { 141 /*! */ 142 size_t size; 143 /*! All the urls, delimited by <> */ 144 char *URLs; 145 /*! */ 146 uri_type *parsedURLs; 147 } URL_list; 148 149 /*! 150 * \brief Replaces an escaped sequence with its unescaped version as in 151 * http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs) 152 * 153 * Size of array is NOT checked (MUST be checked by caller) 154 * 155 * \note This function modifies the string. If the sequence is an escaped 156 * sequence it is replaced, the other characters in the string are shifted 157 * over, and NULL characters are placed at the end of the string. 158 * 159 * \return 160 */ 161 int replace_escaped( 162 /*! [in,out] String of characters. */ 163 char *in, 164 /*! [in] Index at which to start checking the characters. */ 165 size_t index, 166 /*! [out] . */ 167 size_t *max); 168 169 /*! 170 * \brief Copies one URL_list into another. 171 * 172 * This includes dynamically allocating the out->URLs field (the full string), 173 * and the structures used to hold the parsedURLs. This memory MUST be freed 174 * by the caller through: free_URL_list(&out). 175 * 176 * \return 177 * \li HTTP_SUCCESS - On Success. 178 * \li UPNP_E_OUTOF_MEMORY - On Failure to allocate memory. 179 */ 180 int copy_URL_list( 181 /*! [in] Source URL list. */ 182 URL_list *in, 183 /*! [out] Destination URL list. */ 184 URL_list *out); 185 186 /*! 187 * \brief Frees the memory associated with a URL_list. 188 * 189 * Frees the dynamically allocated members of of list. Does NOT free the 190 * pointer to the list itself ( i.e. does NOT free(list)). 191 */ 192 void free_URL_list( 193 /*! [in] URL list object. */ 194 URL_list *list); 195 196 /*! 197 * \brief Function useful in debugging for printing a parsed uri. 198 */ 199 #ifdef DEBUG 200 void print_uri( 201 /*! [in] URI object to print. */ 202 uri_type *in); 203 #else 204 #define print_uri(in) do {} while (0) 205 #endif 206 207 /*! 208 * \brief Function useful in debugging for printing a token. 209 */ 210 #ifdef DEBUG 211 void print_token( 212 /*! [in] Token object to print. */ 213 token *in); 214 #else 215 #define print_token(in) do {} while (0) 216 #endif 217 218 /*! 219 * \brief Compares buffer in the token object with the buffer in in2. 220 * 221 * \return 222 * \li < 0, if string1 is less than string2. 223 * \li == 0, if string1 is identical to string2 . 224 * \li > 0, if string1 is greater than string2. 225 */ 226 int token_string_casecmp( 227 /*! [in] Token object whose buffer is to be compared. */ 228 token *in1, 229 /*! [in] String of characters to compare with. */ 230 const char *in2); 231 232 /*! 233 * \brief Compares two tokens. 234 * 235 * \return 236 * \li < 0, if string1 is less than string2. 237 * \li == 0, if string1 is identical to string2 . 238 * \li > 0, if string1 is greater than string2. 239 */ 240 int token_cmp( 241 /*! [in] First token object whose buffer is to be compared. */ 242 token *in1, 243 /*! [in] Second token object used for the comparison. */ 244 token *in2); 245 246 /*! 247 * \brief Removes http escaped characters such as: "%20" and replaces them with 248 * their character representation. i.e. "hello%20foo" -> "hello foo". 249 * 250 * The input IS MODIFIED in place (shortened). Extra characters are replaced 251 * with \b NULL. 252 * 253 * \return UPNP_E_SUCCESS. 254 */ 255 int remove_escaped_chars( 256 /*! [in,out] String of characters to be modified. */ 257 char *in, 258 /*! [in,out] Size limit for the number of characters. */ 259 size_t *size); 260 261 /*! 262 * \brief Removes ".", and ".." from a path. 263 * 264 * If a ".." can not be resolved (i.e. the .. would go past the root of the 265 * path) an error is returned. 266 * 267 * The input IS modified in place.) 268 * 269 * \note Examples 270 * char path[30]="/../hello"; 271 * remove_dots(path, strlen(path)) -> UPNP_E_INVALID_URL 272 * char path[30]="/./hello"; 273 * remove_dots(path, strlen(path)) -> UPNP_E_SUCCESS, 274 * in = "/hello" 275 * char path[30]="/./hello/foo/../goodbye" -> 276 * UPNP_E_SUCCESS, in = "/hello/goodbye" 277 * 278 * \return 279 * \li UPNP_E_SUCCESS - On Success. 280 * \li UPNP_E_OUTOF_MEMORY - On failure to allocate memory. 281 * \li UPNP_E_INVALID_URL - Failure to resolve URL. 282 */ 283 int remove_dots( 284 /*! [in] String of characters from which "dots" have to be removed. */ 285 char *in, 286 /*! [in] Size limit for the number of characters. */ 287 size_t size); 288 289 /*! 290 * \brief resolves a relative url with a base url returning a NEW (dynamically 291 * allocated with malloc) full url. 292 * 293 * If the base_url is \b NULL, then a copy of the rel_url is passed back if 294 * the rel_url is absolute then a copy of the rel_url is passed back if neither 295 * the base nor the rel_url are Absolute then NULL is returned. Otherwise it 296 * tries and resolves the relative url with the base as described in 297 * http://www.ietf.org/rfc/rfc2396.txt (RFCs explaining URIs). 298 * 299 * The resolution of '..' is NOT implemented, but '.' is resolved. 300 * 301 * \return 302 */ 303 char *resolve_rel_url( 304 /*! [in] Base URL. */ 305 char *base_url, 306 /*! [in] Relative URL. */ 307 char *rel_url); 308 309 /*! 310 * \brief Parses a uri as defined in http://www.ietf.org/rfc/rfc2396.txt 311 * (RFC explaining URIs). 312 * 313 * Handles absolute, relative, and opaque uris. Parses into the following 314 * pieces: scheme, hostport, pathquery, fragment (path and query are treated 315 * as one token) 316 * 317 * Caller should check for the pieces they require. 318 * 319 * \return 320 */ 321 int parse_uri( 322 /*! [in] Character string containing uri information to be parsed. */ 323 const char *in, 324 /*! [in] Maximum limit on the number of characters. */ 325 size_t max, 326 /*! [out] Output parameter which will have the parsed uri information. */ 327 uri_type *out); 328 329 /*! 330 * \brief 331 * 332 * \return 333 */ 334 int parse_token( 335 /*! [in] . */ 336 char *in, 337 /*! [out] . */ 338 token *out, 339 /*! [in] . */ 340 int max_size); 341 342 #ifdef __cplusplus 343 } 344 #endif 345 346 347 #endif /* GENLIB_NET_URI_H */ 348 349