]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/url.c
ucw docs: Documented mempools
[libucw.git] / ucw / url.c
index 74d8c1d5facf68f976360052d31891019b298f7d..7145af5f764e80b9b9ed60cd223743a76093b008 100644 (file)
--- a/ucw/url.c
+++ b/ucw/url.c
@@ -7,11 +7,6 @@
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
  *
- *     The URL syntax corresponds to RFC 2396 with several exceptions:
- *
- *        o  Escaping of special characters still follows RFC 1738.
- *        o  Interpretation of path parameters follows RFC 1808.
- *
  *     XXX: The buffer handling in this module is really horrible, but it works.
  */
 
@@ -19,6 +14,7 @@
 #include "ucw/url.h"
 #include "ucw/chartype.h"
 #include "ucw/conf.h"
+#include "ucw/prime.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -60,10 +56,10 @@ enhex(uns x)
 }
 
 int
-url_deescape(const byte *s, byte *d)
+url_deescape(const char *s, char *d)
 {
-  byte *dstart = d;
-  byte *end = d + MAX_URL_SIZE - 10;
+  char *dstart = d;
+  char *end = d + MAX_URL_SIZE - 10;
   while (*s)
     {
       if (d >= end)
@@ -94,15 +90,21 @@ url_deescape(const byte *s, byte *d)
              val = NCC_AND; break;
            case '#':
              val = NCC_HASH; break;
+           case '$':
+             val = NCC_DOLLAR; break;
+           case '+':
+             val = NCC_PLUS; break;
+           case ',':
+             val = NCC_COMMA; break;
            }
          *d++ = val;
          s += 3;
        }
-      else if (*s > 0x20)
+      else if ((byte) *s > 0x20)
        *d++ = *s++;
       else if (Cspace(*s))
        {
-         const byte *s0 = s;
+         const char *s0 = s;
          while (Cspace(*s))
            s++;
          if (!url_ignore_spaces || !(!*s || d == dstart))
@@ -123,25 +125,25 @@ url_deescape(const byte *s, byte *d)
 }
 
 int
-url_enescape(const byte *s, byte *d)
+url_enescape(const char *s, char *d)
 {
-  byte *end = d + MAX_URL_SIZE - 10;
+  char *end = d + MAX_URL_SIZE - 10;
   unsigned int c;
 
   while (c = *s)
     {
       if (d >= end)
        return URL_ERR_TOO_LONG;
-      if (Calnum(c) ||                                                 /* RFC 1738(2.2): Only alphanumerics ... */
-         c == '$' || c == '-' || c == '_' || c == '.' || c == '+' ||   /* ... and several other exceptions ... */
+      if (Calnum(c) ||                                                 /* RFC 2396 (2.1-2.3): Only alphanumerics ... */
+         c == '-' || c == '_' || c == '.' || c == '+' || c == '~' ||   /* ... and several other exceptions ... */
          c == '!' || c == '*' || c == '\'' || c == '(' || c == ')' ||
-         c == ',' ||
          c == '/' || c == '?' || c == ':' || c == '@' ||               /* ... and reserved chars used for reserved purpose */
-         c == '=' || c == '&' || c == '#' || c == ';')
+         c == '=' || c == '&' || c == '#' || c == ';' ||
+         c == '$' || c == '+' || c == ',')
        *d++ = *s++;
       else
        {
-         uns val = (*s < NCC_MAX) ? NCC_CHARS[*s] : *s;
+         uns val = ((byte)*s < NCC_MAX) ? NCC_CHARS[(byte)*s] : *s;
          *d++ = '%';
          *d++ = enhex(val >> 4);
          *d++ = enhex(val & 0x0f);
@@ -153,22 +155,23 @@ url_enescape(const byte *s, byte *d)
 }
 
 int
-url_enescape_friendly(const byte *src, byte *dest)
+url_enescape_friendly(const char *src, char *dest)
 {
-  byte *end = dest + MAX_URL_SIZE - 10;
-  while (*src)
+  char *end = dest + MAX_URL_SIZE - 10;
+  const byte *srcb = src;
+  while (*srcb)
     {
       if (dest >= end)
        return URL_ERR_TOO_LONG;
-      if (*src < NCC_MAX)
-       *dest++ = NCC_CHARS[*src++];
-      else if (*src >= 0x20 && *src < 0x7f)
-       *dest++ = *src++;
+      if (*srcb < NCC_MAX)
+       *dest++ = NCC_CHARS[*srcb++];
+      else if (*srcb >= 0x20 && *srcb < 0x7f)
+       *dest++ = *srcb++;
       else
        {
          *dest++ = '%';
-         *dest++ = enhex(*src >> 4);
-         *dest++ = enhex(*src++ & 0x0f);
+         *dest++ = enhex(*srcb >> 4);
+         *dest++ = enhex(*srcb++ & 0x0f);
        }
     }
   *dest = 0;
@@ -177,11 +180,11 @@ url_enescape_friendly(const byte *src, byte *dest)
 
 /* Split an URL (several parts may be copied to the destination buffer) */
 
-byte *url_proto_names[URL_PROTO_MAX] = URL_PNAMES;
+char *url_proto_names[URL_PROTO_MAX] = URL_PNAMES;
 static int url_proto_path_flags[URL_PROTO_MAX] = URL_PATH_FLAGS;
 
 uns
-identify_protocol(const byte *p)
+identify_protocol(const char *p)
 {
   uns i;
 
@@ -192,7 +195,7 @@ identify_protocol(const byte *p)
 }
 
 int
-url_split(byte *s, struct url *u, byte *d)
+url_split(char *s, struct url *u, char *d)
 {
   bzero(u, sizeof(struct url));
   u->port = ~0;
@@ -200,7 +203,7 @@ url_split(byte *s, struct url *u, byte *d)
 
   if (s[0] != '/')                     /* Seek for "protocol:" */
     {
-      byte *p = s;
+      char *p = s;
       while (*p && Calnum(*p))
        p++;
       if (p != s && *p == ':')
@@ -227,8 +230,8 @@ url_split(byte *s, struct url *u, byte *d)
     {
       if (s[1] == '/')                 /* Host spec */
        {
-         byte *q, *e;
-         byte *at = NULL;
+         char *q, *e;
+         char *at = NULL;
          char *ep;
 
          s += 2;
@@ -285,11 +288,11 @@ static uns std_ports[] = URL_DEFPORTS;    /* Default port numbers */
 static int
 relpath_merge(struct url *u, struct url *b)
 {
-  byte *a = u->rest;
-  byte *o = b->rest;
-  byte *d = u->buf;
-  byte *e = u->bufend;
-  byte *p;
+  char *a = u->rest;
+  char *o = b->rest;
+  char *d = u->buf;
+  char *e = u->bufend;
+  char *p;
 
   if (a[0] == '/')                     /* Absolute path => OK */
     return 0;
@@ -316,15 +319,9 @@ relpath_merge(struct url *u, struct url *b)
        ;
       goto copy;
     }
-  if (a[0] == ';')                     /* Change parameters */
-    {
-      for(p=o; *p && *p != ';' && *p != '?' && *p != '#'; p++)
-       ;
-      goto copy;
-    }
 
   p = NULL;                            /* Copy original path and find the last slash */
-  while (*o && *o != ';' && *o != '?' && *o != '#')
+  while (*o && *o != '?' && *o != '#')
     {
       if (d >= e)
        return URL_ERR_TOO_LONG;
@@ -452,7 +449,7 @@ url_normalize(struct url *u, struct url *b)
 /* Name canonicalization */
 
 static void
-lowercase(byte *b)
+lowercase(char *b)
 {
   if (b)
     while (*b)
@@ -464,9 +461,9 @@ lowercase(byte *b)
 }
 
 static void
-kill_end_dot(byte *b)
+kill_end_dot(char *b)
 {
-  byte *k;
+  char *k;
 
   if (b)
     {
@@ -493,8 +490,8 @@ url_canonicalize(struct url *u)
 
 /* Pack a broken-down URL */
 
-static byte *
-append(byte *d, const byte *s, byte *e)
+static char *
+append(char *d, const char *s, char *e)
 {
   if (d)
     while (*s)
@@ -507,9 +504,9 @@ append(byte *d, const byte *s, byte *e)
 }
 
 int
-url_pack(struct url *u, byte *d)
+url_pack(struct url *u, char *d)
 {
-  byte *e = d + MAX_URL_SIZE - 10;
+  char *e = d + MAX_URL_SIZE - 10;
 
   if (u->protocol)
     {
@@ -573,7 +570,7 @@ url_error(uns err)
 /* Standard cookbook recipes */
 
 int
-url_canon_split_rel(const byte *u, byte *buf1, byte *buf2, struct url *url, struct url *base)
+url_canon_split_rel(const char *u, char *buf1, char *buf2, struct url *url, struct url *base)
 {
   int err;
 
@@ -587,9 +584,9 @@ url_canon_split_rel(const byte *u, byte *buf1, byte *buf2, struct url *url, stru
 }
 
 int
-url_auto_canonicalize_rel(const byte *src, byte *dst, struct url *base)
+url_auto_canonicalize_rel(const char *src, char *dst, struct url *base)
 {
-  byte buf1[MAX_URL_SIZE], buf2[MAX_URL_SIZE], buf3[MAX_URL_SIZE];
+  char buf1[MAX_URL_SIZE], buf2[MAX_URL_SIZE], buf3[MAX_URL_SIZE];
   int err;
   struct url ur;
 
@@ -608,7 +605,7 @@ int main(int argc, char **argv)
   char buf1[MAX_URL_SIZE], buf2[MAX_URL_SIZE], buf3[MAX_URL_SIZE], buf4[MAX_URL_SIZE];
   int err;
   struct url url, url0;
-  char *base = "http://mj@www.hell.org/123/sub_dir/index.html;param?query&zzz/subquery#fragment";
+  char *base = "http://mj@www.hell.org/123/sub_dir;param/index.html;param?query&zzz/sub;query+#fragment?";
 
   if (argc != 2 && argc != 3)
     return 1;
@@ -667,14 +664,14 @@ int main(int argc, char **argv)
 #endif
 
 struct component {
-       const byte *start;
+       const char *start;
        int length;
        uns count;
        u32 hash;
 };
 
 static inline u32
-hashf(const byte *start, int length)
+hashf(const char *start, int length)
 {
        u32 hf = length;
        while (length-- > 0)
@@ -704,11 +701,11 @@ repeat_count(struct component *comp, uns count, uns len)
 }
 
 int
-url_has_repeated_component(const byte *url)
+url_has_repeated_component(const char *url)
 {
        struct component *comp;
        uns comps, comp_len, rep_prefix, hash_size, *hash, *next;
-       const byte *c;
+       const char *c;
        uns i, j, k;
 
        for (comps=0, c=url; c; comps++)