Removed various assert()'s because, better or worse, we're not asserting things elsewhere.
| 1 | /* |
| 2 | * The contents of this file are subject to the AOLserver Public License |
| 3 | * Version 1.1 (the "License"); you may not use this file except in |
| 4 | * compliance with the License. You may obtain a copy of the License at |
| 5 | * http://aolserver.com/. |
| 6 | * |
| 7 | * Software distributed under the License is distributed on an "AS IS" |
| 8 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See |
| 9 | * the License for the specific language governing rights and limitations |
| 10 | * under the License. |
| 11 | * |
| 12 | * The Original Code is AOLserver Code and related documentation |
| 13 | * distributed by AOL. |
| 14 | * |
| 15 | * The Initial Developer of the Original Code is America Online, |
| 16 | * Inc. Portions created by AOL are Copyright (C) 1999 America Online, |
| 17 | * Inc. All Rights Reserved. |
| 18 | * |
| 19 | * Alternatively, the contents of this file may be used under the terms |
| 20 | * of the GNU General Public License (the "GPL"), in which case the |
| 21 | * provisions of GPL are applicable instead of those above. If you wish |
| 22 | * to allow use of your version of this file only under the terms of the |
| 23 | * GPL and not to allow others to use your version of this file under the |
| 24 | * License, indicate your decision by deleting the provisions above and |
| 25 | * replace them with the notice and other provisions required by the GPL. |
| 26 | * If you do not delete the provisions above, a recipient may use your |
| 27 | * version of this file under either the License or the GPL. |
| 28 | */ |
| 29 | |
| 30 | |
| 31 | /* |
| 32 | * url.c -- |
| 33 | * |
| 34 | * <a href="/cvs/aolserver/aolserver/nsd/adpparse.c#A_Parse">Parse</a> URLs. |
| 35 | */ |
| 36 | |
| 37 | static const char *RCSID = "@(#) $Header: /cvsroot-fuse/aolserver/aolserver/nsd/url.c,v 1.5 2001/03/13 16:46:02 jgdavidson Exp $, compiled: " __DATE__ " " __TIME__; |
| 38 | |
| 39 | #include "nsd.h" |
| 40 | |
| 41 | |
| 42 | /* |
| 43 | *---------------------------------------------------------------------- |
| 44 | * |
| 45 | * <a href="/cvs/aolserver/aolserver/nsd/url.c#A_Ns_RelativeUrl">Ns_RelativeUrl</a> -- |
| 46 | * |
| 47 | * If the url passed in is for this server, then the initial |
| 48 | * part of the URL is stripped off. e.g., on a server whose |
| 49 | * location is http://www.foo.com, <a href="/cvs/aolserver/aolserver/nsd/url.c#A_Ns_RelativeUrl">Ns_RelativeUrl</a> of |
| 50 | * "http://www.foo.com/hello" will return "/hello". |
| 51 | * |
| 52 | * Results: |
| 53 | * A pointer to the beginning of the relative url in the |
| 54 | * passed-in url, or NULL if error. |
| 55 | * |
| 56 | * Side effects: |
| 57 | * Will set errno on error. |
| 58 | * |
| 59 | *---------------------------------------------------------------------- |
| 60 | */ |
| 61 | |
| 62 | char * |
| 63 | <a href="/cvs/aolserver/aolserver/nsd/url.c#A_Ns_RelativeUrl">Ns_RelativeUrl</a>(char *url, char *location) |
| 64 | { |
| 65 | char *v; |
| 66 | |
| 67 | if (url == NULL || location == NULL) { |
| 68 | return NULL; |
| 69 | } |
| 70 | |
| 71 | /* |
| 72 | * <a href="/cvs/aolserver/aolserver/nsd/str.c#A_Ns_Match">Ns_Match</a> will return the point in URL where location stops |
| 73 | * being equal to it because location ends. |
| 74 | * |
| 75 | * e.g., if location = "http://www.foo.com" and |
| 76 | * url="http://www.foo.com/a/b" then after the call, |
| 77 | * v="/a/b", or NULL if there's a mismatch. |
| 78 | */ |
| 79 | |
| 80 | v = <a href="/cvs/aolserver/aolserver/nsd/str.c#A_Ns_Match">Ns_Match</a>(location, url); |
| 81 | if (v != NULL) { |
| 82 | url = v; |
| 83 | } |
| 84 | while (url[0] == '/' && url[1] == '/') { |
| 85 | ++url; |
| 86 | } |
| 87 | return url; |
| 88 | } |
| 89 | |
| 90 | |
| 91 | /* |
| 92 | *---------------------------------------------------------------------- |
| 93 | * |
| 94 | * <a href="/cvs/aolserver/aolserver/nsd/url.c#A_Ns_ParseUrl">Ns_ParseUrl</a> -- |
| 95 | * |
| 96 | * <a href="/cvs/aolserver/aolserver/nsd/adpparse.c#A_Parse">Parse</a> a URL into its component parts |
| 97 | * |
| 98 | * Results: |
| 99 | * NS_OK or NS_ERROR |
| 100 | * |
| 101 | * Side effects: |
| 102 | * Pointers to the protocol, host, port, path, and "tail" (last |
| 103 | * path element) will be set by reference in the passed-in pointers. |
| 104 | * The passed-in url will be modified. |
| 105 | * |
| 106 | *---------------------------------------------------------------------- |
| 107 | */ |
| 108 | |
| 109 | int |
| 110 | <a href="/cvs/aolserver/aolserver/nsd/url.c#A_Ns_ParseUrl">Ns_ParseUrl</a>(char *url, char **pprotocol, char **phost, |
| 111 | char **pport, char **ppath, char **ptail) |
| 112 | { |
| 113 | char *end; |
| 114 | |
| 115 | *pprotocol = NULL; |
| 116 | *phost = NULL; |
| 117 | *pport = NULL; |
| 118 | *ppath = NULL; |
| 119 | *ptail = NULL; |
| 120 | |
| 121 | /* |
| 122 | * Set end to the end of the protocol |
| 123 | * http://www.foo.com:8000/baz/blah/spoo.html |
| 124 | * ^ |
| 125 | * +--end |
| 126 | */ |
| 127 | |
| 128 | end = strchr(url, ':'); |
| 129 | if (end != NULL) { |
| 130 | /* |
| 131 | * There is a protocol specified. Clear out the colon. |
| 132 | * Set pprotocol to the start of the protocol, and url to |
| 133 | * the first character after the colon. |
| 134 | * |
| 135 | * http\0//www.foo.com:8000/baz/blah/spoo.html |
| 136 | * ^ ^ ^ |
| 137 | * | | +-- url |
| 138 | * | +-- end |
| 139 | * +-------- *pprotocol |
| 140 | */ |
| 141 | |
| 142 | *end = '\0'; |
| 143 | *pprotocol = url; |
| 144 | url = end + 1; |
| 145 | if ((*url == '/') && |
| 146 | (*(url + 1) == '/')) { |
| 147 | |
| 148 | /* |
| 149 | * There are two slashes, which means a host is specified. |
| 150 | * Advance url past that and set *phost. |
| 151 | * |
| 152 | * http\0//www.foo.com:8000/baz/blah/spoo.html |
| 153 | * ^ ^ ^ |
| 154 | * | | +-- url, *phost |
| 155 | * | +-- end |
| 156 | * +-------- *pprotocol |
| 157 | */ |
| 158 | |
| 159 | url = url + 2; |
| 160 | |
| 161 | *phost = url; |
| 162 | |
| 163 | /* |
| 164 | * Look for a port number, which is optional. |
| 165 | */ |
| 166 | |
| 167 | end = strchr(url, ':'); |
| 168 | if (end != NULL) { |
| 169 | /* |
| 170 | * A port was specified. Clear the colon and |
| 171 | * set *pport to the first digit. |
| 172 | * |
| 173 | * http\0//www.foo.com\08000/baz/blah/spoo.html |
| 174 | * ^ ^ ^ ^ |
| 175 | * | +-- *phost | +------ url, *pport |
| 176 | * +----- *pprotocol +--- end |
| 177 | */ |
| 178 | |
| 179 | *end = '\0'; |
| 180 | url = end + 1; |
| 181 | *pport = url; |
| 182 | } |
| 183 | |
| 184 | /* |
| 185 | * Move up to the slash which starts the path/tail. |
| 186 | * Clear out the dividing slash. |
| 187 | * |
| 188 | * http\0//www.foo.com\08000\0baz/blah/spoo.html |
| 189 | * ^ ^ ^ ^ ^ |
| 190 | * | | | | +-- url |
| 191 | * | +-- *phost | +-- end |
| 192 | * +----- *pprotocol +-- *pport |
| 193 | */ |
| 194 | |
| 195 | end = strchr(url, '/'); |
| 196 | if (end == NULL) { |
| 197 | /* |
| 198 | * No path or tail specified. Return. |
| 199 | */ |
| 200 | |
| 201 | *ppath = ""; |
| 202 | *ptail = ""; |
| 203 | return NS_OK; |
| 204 | } |
| 205 | *end = '\0'; |
| 206 | url = end + 1; |
| 207 | } else { |
| 208 | /* |
| 209 | * The URL must have been an odd one without a hostname. |
| 210 | * Move the URL up past the dividing slash. |
| 211 | * |
| 212 | * http\0/baz/blah/spoo.html |
| 213 | * ^ ^ ^ |
| 214 | * | | +-- url |
| 215 | * | +-- end |
| 216 | * +-------- *pprotocol |
| 217 | */ |
| 218 | |
| 219 | url++; |
| 220 | } |
| 221 | |
| 222 | /* |
| 223 | * Set the path to URL and advance to the last slash. |
| 224 | * Set ptail to the character after that, or if there is none, |
| 225 | * it becomes path and path becomes an empty string. |
| 226 | * |
| 227 | * http\0//www.foo.com\08000\0baz/blah/spoo.html |
| 228 | * ^ ^ ^ ^ ^ ^^ |
| 229 | * | | | | | |+-- *ptail |
| 230 | * | | | | | +-- end |
| 231 | * | | | | +-- *ppath |
| 232 | * | +-- *phost | +-- end |
| 233 | * +----- *pprotocol +-- *pport |
| 234 | */ |
| 235 | |
| 236 | *ppath = url; |
| 237 | end = strrchr(url, '/'); |
| 238 | if (end == NULL) { |
| 239 | *ptail = *ppath; |
| 240 | *ppath = ""; |
| 241 | } else { |
| 242 | *end = '\0'; |
| 243 | *ptail = end + 1; |
| 244 | } |
| 245 | } else { |
| 246 | /* |
| 247 | * This URL does not have a colon. If it begins with a slash, then |
| 248 | * separate the tail from the path, otherwise it's all tail. |
| 249 | */ |
| 250 | |
| 251 | if (*url == '/') { |
| 252 | url++; |
| 253 | *ppath = url; |
| 254 | |
| 255 | /* |
| 256 | * Find the last slash on the right and everything after that |
| 257 | * becomes tail; if there are no slashes then it's all tail |
| 258 | * and path is an empty string. |
| 259 | */ |
| 260 | |
| 261 | end = strrchr(url, '/'); |
| 262 | if (end == NULL) { |
| 263 | *ptail = *ppath; |
| 264 | *ppath = ""; |
| 265 | } else { |
| 266 | *end = '\0'; |
| 267 | *ptail = end + 1; |
| 268 | } |
| 269 | } else { |
| 270 | |
| 271 | /* |
| 272 | * Just set the tail, there are no slashes. |
| 273 | */ |
| 274 | |
| 275 | *ptail = url; |
| 276 | } |
| 277 | } |
| 278 | return NS_OK; |
| 279 | } |
| 280 | |
| 281 | |
| 282 | /* |
| 283 | *---------------------------------------------------------------------- |
| 284 | * |
| 285 | * <a href="/cvs/aolserver/aolserver/nsd/url.c#A_Ns_AbsoluteUrl">Ns_AbsoluteUrl</a> -- |
| 286 | * |
| 287 | * Construct an URL based on baseurl but with as many parts of |
| 288 | * the incomplete url as possible. |
| 289 | * |
| 290 | * Results: |
| 291 | * NS_OK or NS_ERROR. |
| 292 | * |
| 293 | * Side effects: |
| 294 | * None. |
| 295 | * |
| 296 | *---------------------------------------------------------------------- |
| 297 | */ |
| 298 | |
| 299 | int |
| 300 | <a href="/cvs/aolserver/aolserver/nsd/url.c#A_Ns_AbsoluteUrl">Ns_AbsoluteUrl</a>(Ns_DString *dsPtr, char *url, char *base) |
| 301 | { |
| 302 | char *protocol, *host, *port, *path, *tail, *baseprotocol, |
| 303 | *basehost, *baseport, *basepath, *basetail; |
| 304 | int status = NS_OK; |
| 305 | |
| 306 | /* |
| 307 | * Copy the URL's to allow <a href="/cvs/aolserver/aolserver/nsd/url.c#A_Ns_ParseUrl">Ns_ParseUrl</a> to destory them. |
| 308 | */ |
| 309 | |
| 310 | url = ns_strdup(url); |
| 311 | base = ns_strdup(base); |
| 312 | <a href="/cvs/aolserver/aolserver/nsd/url.c#A_Ns_ParseUrl">Ns_ParseUrl</a>(url, &protocol, &host, &port, &path, &tail); |
| 313 | <a href="/cvs/aolserver/aolserver/nsd/url.c#A_Ns_ParseUrl">Ns_ParseUrl</a>(base, &baseprotocol, &basehost, &baseport, &basepath, &basetail); |
| 314 | if (baseprotocol == NULL || basehost == NULL || basepath == NULL) { |
| 315 | status = NS_ERROR; |
| 316 | goto done; |
| 317 | } |
| 318 | if (protocol == NULL) { |
| 319 | protocol = baseprotocol; |
| 320 | } |
| 321 | if (host == NULL) { |
| 322 | host = basehost; |
| 323 | port = baseport; |
| 324 | } |
| 325 | if (path == NULL) { |
| 326 | path = basepath; |
| 327 | } |
| 328 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringVarAppend">Ns_DStringVarAppend</a>(dsPtr, protocol, "://", host, NULL); |
| 329 | if (port != NULL) { |
| 330 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringVarAppend">Ns_DStringVarAppend</a>(dsPtr, ":", port, NULL); |
| 331 | } |
| 332 | if (*path == '\0') { |
| 333 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringVarAppend">Ns_DStringVarAppend</a>(dsPtr, "/", tail, NULL); |
| 334 | } else { |
| 335 | <a href="/cvs/aolserver/aolserver/nsd/dstring.c#A_Ns_DStringVarAppend">Ns_DStringVarAppend</a>(dsPtr, "/", path, "/", tail, NULL); |
| 336 | } |
| 337 | done: |
| 338 | ns_free(url); |
| 339 | ns_free(base); |
| 340 | return status; |
| 341 | } |
Copyright © 2010 Geeknet, Inc. All rights reserved. Terms of Use