]> mj.ucw.cz Git - libucw.git/blobdiff - lib/url.c
Adjust comments in UCW Library modules.
[libucw.git] / lib / url.c
index 105c7dd019e9f9d3c2de55a711b5cbd6eba390f8..f805e32ff23f0f994dda2f7710a0e4b27807e824 100644 (file)
--- a/lib/url.c
+++ b/lib/url.c
@@ -1,5 +1,5 @@
 /*
- *     Sherlock Library -- URL Functions
+ *     UCW Library -- URL Functions
  *
  *     (c) 1997--2004 Martin Mares <mj@ucw.cz>
  *     (c) 2001 Robert Spalek <robert@ucw.cz>
@@ -11,9 +11,8 @@
  *
  *        o  Escaping of special characters still follows RFC 1738.
  *        o  Interpretation of path parameters follows RFC 1808.
- *        o  Parsing a relative URL "x" wrt. base "http://hell.org?y"
- *           gives an error, which might be wrong. However, I failed
- *           to find any rule applying to this case in the RFC.
+ *
+ *     XXX: The buffer handling in this module is really horrible, but it works.
  */
 
 #include "lib/lib.h"
@@ -369,8 +368,7 @@ url_normalize(struct url *u, struct url *b)
   int err;
 
   /* Basic checks */
-  if (url_proto_path_flags[u->protoid] && !u->host ||
-      u->host && !*u->host ||
+  if (url_proto_path_flags[u->protoid] && (!u->host || !*u->host) ||
       !u->host && u->user ||
       !u->user && u->pass ||
       !u->rest)
@@ -396,6 +394,18 @@ url_normalize(struct url *u, struct url *b)
        }
     }
 
+  /* Change path "?" to "/?" because it's the true meaning */
+  if (u->rest[0] == '?')
+    {
+      int l = strlen(u->rest);
+      if (u->bufend - u->buf < l+1)
+       return URL_ERR_TOO_LONG;
+      u->buf[0] = '/';
+      memcpy(u->buf+1, u->rest, l+1);
+      u->rest = u->buf;
+      u->buf += l+2;
+    }
+
   /* Fill in missing info */
   if (u->port == ~0U)
     u->port = std_ports[u->protoid];
@@ -527,7 +537,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;
 
@@ -535,19 +545,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;