Do not URI encode SRU database
[yaz-moved-to-github.git] / src / srwutil.c
index 99e417c..36d88b6 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2009 Index Data
+ * Copyright (C) 1995-2010 Index Data
  * See the file LICENSE for details.
  */
 /**
  */
 
 #include <stdlib.h>
+#include <assert.h>
 #include <yaz/srw.h>
 #include <yaz/matchstr.h>
 #include <yaz/yaz-iconv.h>
 
-static int hex_digit (int ch)
+static char *yaz_decode_sru_dbpath_odr(ODR n, const char *uri, size_t len)
 {
-    if (ch >= '0' && ch <= '9')
-        return ch - '0';
-    else if (ch >= 'a' && ch <= 'f')
-        return ch - 'a'+10;
-    else if (ch >= 'A' && ch <= 'F')
-        return ch - 'A'+10;
-    return 0;
+    return odr_strdupn(n, uri, len);
 }
 
-void encode_uri_char(char *dst, char ch)
+void yaz_encode_sru_dbpath_buf(char *dst, const char *db)
 {
-    if (ch == ' ')
-        strcpy(dst, "+");
-    /*  mark        = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" */
-    else if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') ||
-             (ch >= '0' && ch <= '9') || strchr("-_.!~*'(|)", ch))
-    {
-        dst[0] = ch;
-        dst[1] = '\0';
-    }
-    else
-    {
-        dst[0] = '%';
-        sprintf(dst+1, "%02X", (unsigned char ) ch);
-    }
+    assert(db);
+    *dst = '/';
+    strcpy(dst+1, db);
 }
 
-static void yaz_array_to_uri(char **path, ODR o, char **name, char **value)
+char *yaz_encode_sru_dbpath_odr(ODR out, const char *db)
 {
-    size_t i, szp = 0, sz = 1;
-    for(i = 0; name[i]; i++)
-        sz += strlen(name[i]) + 3 + strlen(value[i]) * 3;
-    *path = (char *) odr_malloc(o, sz);
-    
-    for(i = 0; name[i]; i++)
-    {
-        size_t j, ilen;
-        if (i)
-            (*path)[szp++] = '&';
-        ilen = strlen(name[i]);
-        memcpy(*path+szp, name[i], ilen);
-        szp += ilen;
-        (*path)[szp++] = '=';
-        for (j = 0; value[i][j]; j++)
-        {
-            size_t vlen;
-            char vstr[5];
-            encode_uri_char(vstr, value[i][j]);
-            vlen = strlen(vstr);
-            memcpy(*path+szp, vstr, vlen);
-            szp += vlen;
-        }
-    }
-    (*path)[szp] = '\0';
-}
-
-int yaz_uri_to_array(const char *path, ODR o, char ***name, char ***val)
-{
-    int no = 2;
-    const char *cp;
-    *name = 0;
-    if (*path == '?')
-        path++;
-    if (!*path)
-        return 0;
-    cp = path;
-    while ((cp = strchr(cp, '&')))
-    {
-        cp++;
-        no++;
-    }
-    *name = (char **) odr_malloc(o, no * sizeof(char*));
-    *val = (char **) odr_malloc(o, no * sizeof(char*));
-
-    for (no = 0; *path; no++)
-    {
-        const char *p1 = strchr(path, '=');
-        size_t i = 0;
-        char *ret;
-        if (!p1)
-            break;
-
-        (*name)[no] = (char *) odr_malloc(o, (p1-path)+1);
-        memcpy((*name)[no], path, p1-path);
-        (*name)[no][p1-path] = '\0';
-
-        path = p1 + 1;
-        p1 = strchr(path, '&');
-        if (!p1)
-            p1 = strlen(path) + path;
-        (*val)[no] = ret = (char *) odr_malloc(o, p1 - path + 1);
-        while (*path && *path != '&')
-        {
-            if (*path == '+')
-            {
-                ret[i++] = ' ';
-                path++;
-            }
-            else if (*path == '%' && path[1] && path[2])
-            {
-                ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
-                path = path + 3;
-            }
-            else
-                ret[i++] = *path++;
-        }
-        ret[i] = '\0';
-
-        if (*path)
-            path++;
-    }
-    (*name)[no] = 0;
-    (*val)[no] = 0;
-    return no;
-}
-
-char *yaz_uri_val(const char *path, const char *name, ODR o)
-{
-    size_t nlen = strlen(name);
-    if (*path != '?')
-        return 0;
-    path++;
-    while (path && *path)
-    {
-        const char *p1 = strchr(path, '=');
-        if (!p1)
-            break;
-        if ((size_t)(p1 - path) == nlen && !memcmp(path, name, nlen))
-        {
-            size_t i = 0;
-            char *ret;
-            
-            path = p1 + 1;
-            p1 = strchr(path, '&');
-            if (!p1)
-                p1 = strlen(path) + path;
-            ret = (char *) odr_malloc(o, p1 - path + 1);
-            while (*path && *path != '&')
-            {
-                if (*path == '+')
-                {
-                    ret[i++] = ' ';
-                    path++;
-                }
-                else if (*path == '%' && path[1] && path[2])
-                {
-                    ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]);
-                    path = path + 3;
-                }
-                else
-                    ret[i++] = *path++;
-            }
-            ret[i] = '\0';
-            return ret;
-        }
-        path = strchr(p1, '&');
-        if (path)
-            path++;
-    }
-    return 0;
+    char *dst = odr_malloc(out, 3 * strlen(db) + 2);
+    yaz_encode_sru_dbpath_buf(dst, db);
+    return dst;
 }
 
 #if YAZ_HAVE_XML2
@@ -279,7 +135,7 @@ static void yaz_srw_decodeauth(Z_SRW_PDU *sr, Z_HTTP_Request *hreq,
 }
 #endif
 
-void yaz_uri_val_int(const char *path, const char *name, ODR o, odr_int_t **intp)
+void yaz_uri_val_int(const char *path, const char *name, ODR o, Odr_int **intp)
 {
     const char *v = yaz_uri_val(path, name, o);
     if (v)
@@ -422,12 +278,7 @@ int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
             if (!p1)
                 p1 = p0 + strlen(p0);
             if (p1 != p0)
-            {
-                db = (char*) odr_malloc(decode, p1 - p0 + 1);
-                memcpy (db, p0, p1 - p0);
-                db[p1 - p0] = '\0';
-            }
-
+                db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
             grab_charset(decode, content_type, charset);
 
             ret = z_soap_codec(decode, soap_package, 
@@ -463,7 +314,7 @@ int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
 
 #if YAZ_HAVE_XML2
 static int yaz_sru_decode_integer(ODR odr, const char *pname, 
-                                  const char *valstr, odr_int_t **valp,
+                                  const char *valstr, Odr_int **valp,
                                   Z_SRW_diagnostic **diag, int *num_diag,
                                   int min_value)
 {
@@ -550,11 +401,7 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu,
         if (!p1)
             p1 = p0 + strlen(p0);
         if (p1 != p0)
-        {
-            db = (char*) odr_malloc(decode, p1 - p0 + 1);
-            memcpy (db, p0, p1 - p0);
-            db[p1 - p0] = '\0';
-        }
+            db = yaz_decode_sru_dbpath_odr(decode, p0, p1 - p0);
         if (!strcmp(hreq->method, "POST"))
             p1 = hreq->content_buf;
         yaz_uri_to_array(p1, decode, &uri_name, &uri_val);
@@ -862,6 +709,8 @@ static Z_SRW_PDU *yaz_srw_get_core_ver(ODR o, const char *version)
     p->username = 0;
     p->password = 0;
     p->extra_args = 0;
+    p->extraResponseData_buf = 0;
+    p->extraResponseData_len = 0;
     return p;
 }
 
@@ -1197,7 +1046,7 @@ int yaz_diag_srw_to_bib1(int code)
 }
 
 static void add_val_int(ODR o, char **name, char **value,  int *i,
-                        char *a_name, odr_int_t *val)
+                        char *a_name, Odr_int *val)
 {
     if (val)
     {
@@ -1467,7 +1316,6 @@ void yaz_encode_sru_extra(Z_SRW_PDU *sr, ODR odr, const char *extra_args)
 }
 
 
-
 /*
  * Local variables:
  * c-basic-offset: 4