X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=lib%2Furl.c;h=d5cbcea21a34d718b7e9b70f6ee09131574deaa4;hb=d1a5b69d490ce61a0f41db08263580487720bf2f;hp=8475a85f378498835509117b51c5b35362f208eb;hpb=90c97fa2d0d6937544205ea9ee72779753a969e6;p=libucw.git diff --git a/lib/url.c b/lib/url.c index 8475a85f..d5cbcea2 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1,8 +1,8 @@ /* - * Sherlock Library -- URL Functions + * UCW Library -- URL Functions * * (c) 1997--2004 Martin Mares - * (c) 2001 Robert Spalek + * (c) 2001--2005 Robert Spalek * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -149,6 +149,29 @@ url_enescape(byte *s, byte *d) return 0; } +int +url_enescape_friendly(byte *src, byte *dest) +{ + byte *end = dest + MAX_URL_SIZE - 10; + while (*src) + { + if (dest >= end) + return URL_ERR_TOO_LONG; + if (*src < NCC_MAX) + *dest++ = NCC_CHARS[*src++]; + else if (*src >= 0x20 && *src < 0x7f) + *dest++ = *src++; + else + { + *dest++ = '%'; + *dest++ = enhex(*src >> 4); + *dest++ = enhex(*src++ & 0x0f); + } + } + *dest = 0; + return 0; +} + /* Split an URL (several parts may be copied to the destination buffer) */ byte *url_proto_names[URL_PROTO_MAX] = URL_PNAMES; @@ -201,18 +224,28 @@ url_split(byte *s, struct url *u, byte *d) { if (s[1] == '/') /* Host spec */ { - byte *q, *w, *e; + byte *q, *e; + byte *at = NULL; char *ep; s += 2; q = d; while (*s && *s != '/' && *s != '?') /* Copy user:passwd@host:port */ - *d++ = *s++; + { + if (*s != '@') + *d++ = *s; + else if (!at) + { + *d++ = 0; + at = d; + } + else /* This shouldn't happen with sane URL's, but we need to be sure */ + *d++ = NCC_AT; + s++; + } *d++ = 0; - w = strchr(q, '@'); - if (w) /* user:passwd present */ + if (at) /* user:passwd present */ { - *w++ = 0; u->user = q; if (e = strchr(q, ':')) { @@ -221,8 +254,8 @@ url_split(byte *s, struct url *u, byte *d) } } else - w = q; - e = strchr(w, ':'); + at = q; + e = strchr(at, ':'); if (e) /* host:port present */ { uns p; @@ -233,7 +266,7 @@ url_split(byte *s, struct url *u, byte *d) else if (p) /* Port 0 (e.g. in :/) is treated as default port */ u->port = p; } - u->host = w; + u->host = at; } } @@ -537,7 +570,7 @@ url_error(uns err) /* Standard cookbook recipes */ int -url_canon_split(byte *u, byte *buf1, byte *buf2, struct url *url) +url_canon_split_rel(byte *u, byte *buf1, byte *buf2, struct url *url, struct url *base) { int err; @@ -545,19 +578,19 @@ url_canon_split(byte *u, byte *buf1, byte *buf2, struct url *url) return err; if (err = url_split(buf1, url, buf2)) return err; - if (err = url_normalize(url, NULL)) + if (err = url_normalize(url, base)) return err; return url_canonicalize(url); } int -url_auto_canonicalize(byte *src, byte *dst) +url_auto_canonicalize_rel(byte *src, byte *dst, struct url *base) { byte buf1[MAX_URL_SIZE], buf2[MAX_URL_SIZE], buf3[MAX_URL_SIZE]; int err; struct url ur; - (void)((err = url_canon_split(src, buf1, buf2, &ur)) || + (void)((err = url_canon_split_rel(src, buf1, buf2, &ur, base)) || (err = url_pack(&ur, buf3)) || (err = url_enescape(buf3, dst))); return err;