Merge branch 'master' of ssh://git.indexdata.com/home/git/pub/yaz
authorAdam Dickmeiss <adam@indexdata.dk>
Fri, 22 Jul 2011 10:53:35 +0000 (12:53 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Fri, 22 Jul 2011 10:53:35 +0000 (12:53 +0200)
15 files changed:
NEWS
configure.ac
debian/changelog
debian/rules
include/yaz/comstack.h
include/yaz/zgdu.h
src/comstack.c
src/cql2ccl.c
src/http.c
src/marc_read_line.c
src/srw.c
src/zoom-c.c
src/zoom-p.h
src/zoom-sru.c
yaz.spec

diff --git a/NEWS b/NEWS
index 310b970..8fec542 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,26 @@
+--- 4.2.5 2011/07/21
+
+ZOOM HTTP: use absoluteURI's in proxy mode as required by RFC 2616 (HTTP).
+Fix a bug in handling of cookies. Fix a bug that would occur if proxy +
+redirect was used at the same time.
+
+MARC line mode decoding: be less picky about length given - first
+5 digits of header that is.
+
+CQL to CCL conversion: deal with CQL proximity (cql_to_ccl function).
+
+Changes to decoding of SRU records: a record with recordPacking=xml is
+modified with a new root element <yaz_record> if the recordData contains
+multiple children elements. This is to make the record XML parseable
+afterwards.
+
+RPN to SOLR conversion: encode special characters.
+
+Generic Frontend Server: fix uinitialized member, stepSize.
+
 --- 4.2.4 2011/06/21
 
-Fix a bug in SRU decoding of records.. The datbase records stored
+Fix a bug in SRU decoding of records.. The database records stored
 had un-initialized memory, but it would only be seen with yaz_record_render
 and type_spec="ext" .
 
index c935363..7cfba5c 100644 (file)
@@ -1,7 +1,7 @@
 dnl This file is part of the YAZ toolkit.
 dnl Copyright (C) 1995-2011 Index Data
 AC_PREREQ([2.60])
-AC_INIT([yaz],[4.2.4],[yaz-help@indexdata.dk])
+AC_INIT([yaz],[4.2.5],[yaz-help@indexdata.dk])
 AC_CONFIG_HEADERS(include/config.h)
 AC_CONFIG_SRCDIR([configure.ac])
 AC_CONFIG_AUX_DIR([config])
index b5fa95f..9a731ed 100644 (file)
@@ -1,3 +1,9 @@
+yaz (4.2.5-1indexdata) unstable; urgency=low
+
+   * Upstream.
+
+ -- Adam Dickmeiss <adam@indexdata.dk>  Thu, 21 Jul 2011 10:13:25 +0200
+
 yaz (4.2.4-1indexdata) unstable; urgency=low
 
   * Upstream.
index de84f0e..a108b09 100755 (executable)
@@ -98,7 +98,7 @@ binary-arch: build install
        dh_fixperms
 #      dh_perl
 #      dh_python
-       dh_makeshlibs -V 'libyaz4 (>= 4.2.3)'
+       dh_makeshlibs -V 'libyaz4 (>= 4.2.5)'
        dh_installdeb
        dh_shlibdeps  -l debian/libyaz4/usr/lib
        dh_gencontrol
index ed5065b..6aef53e 100644 (file)
@@ -122,6 +122,10 @@ YAZ_EXPORT const char *cs_strerror(COMSTACK h);
 YAZ_EXPORT const char *cs_errmsg(int n);
 YAZ_EXPORT COMSTACK cs_create_host(const char *type_and_host, 
                                    int blocking, void **vp);
+
+YAZ_EXPORT COMSTACK cs_create_host_proxy(const char *vhost,
+                                         int blocking, void **vp,
+                                         const char *proxy_host);
 YAZ_EXPORT void cs_get_host_args(const char *type_and_host, const char **args);
 YAZ_EXPORT int cs_complete_auto_head(const char *buf, int len);
 YAZ_EXPORT int cs_complete_auto(const char *buf, int len);
index d0f8f03..ff8cb64 100644 (file)
@@ -92,7 +92,9 @@ YAZ_EXPORT Z_GDU *z_get_HTTP_Request(ODR o);
 YAZ_EXPORT Z_GDU *z_get_HTTP_Request_host_path(ODR odr,
                                                const char *host,
                                                const char *path);
-
+YAZ_EXPORT Z_GDU *z_get_HTTP_Request_uri(ODR odr, const char *uri,
+                                         const char *args,
+                                         int use_full_uri);
 YAZ_EXPORT int yaz_decode_http_request(ODR o, Z_HTTP_Request **hr_p);
 YAZ_EXPORT int yaz_decode_http_response(ODR o, Z_HTTP_Response **hr_p);
 YAZ_EXPORT int yaz_encode_http_response(ODR o, Z_HTTP_Response *hr);
index 669117d..b81e89c 100644 (file)
@@ -157,6 +157,12 @@ static int cs_parse_host(const char *uri, const char **host,
 
 COMSTACK cs_create_host(const char *vhost, int blocking, void **vp)
 {
+    return cs_create_host_proxy(vhost, blocking, vp, 0);
+}
+
+COMSTACK cs_create_host_proxy(const char *vhost, int blocking, void **vp,
+                              const char *proxy_host)
+{
     enum oid_proto proto = PROTO_Z3950;
     const char *host = 0;
     COMSTACK cs;
@@ -175,6 +181,8 @@ COMSTACK cs_create_host(const char *vhost, int blocking, void **vp)
     }
     if (cs)
     {
+        if (proxy_host)
+            host = proxy_host;
         if (!(*vp = cs_straddr(cs, connect_host ? connect_host : host)))
         {
             cs_close (cs);
index 4a3932e..0705ed5 100644 (file)
@@ -136,16 +136,60 @@ static int bool(struct cql_node *cn,
     char *value = cn->u.boolean.value;
     int r;
 
-    /* Rather lame initial attempt at interpreting proximity */
-    if (!strcmp(value, "prox")) value = "!";
-
     pr("(", client_data);
     r = cql_to_ccl_r(cn->u.boolean.left, pr, client_data);
     if (r)
         return r;
     
     pr(" ", client_data);
-    pr(value, client_data);
+
+    if (strcmp(value, "prox"))
+    {   /* not proximity. assuming boolean */
+        pr(value, client_data);
+    }
+    else
+    {
+        struct cql_node *n = cn->u.boolean.modifiers;
+        int ordered = 0;
+        int distance = 1;
+        for (; n ; n = n->u.st.modifiers)
+            if (n->which == CQL_NODE_ST)
+            {
+                if (!strcmp(n->u.st.index, "unit"))
+                {
+                    if (!strcmp(n->u.st.term, "word"))
+                        ;
+                    else
+                        return -1;
+                }
+                else if (!strcmp(n->u.st.index, "distance"))
+                {
+                    if (!strcmp(n->u.st.relation, "<="))
+                        distance = atoi(n->u.st.term);
+                    else if (!strcmp(n->u.st.relation, "<"))
+                        distance = atoi(n->u.st.term) - 1;
+                    else
+                        return -1;
+                }
+                else if (!strcmp(n->u.st.index, "unordered"))
+                {
+                    ordered = 0;
+                }
+                else if (!strcmp(n->u.st.index, "ordered"))
+                {
+                    ordered = 1;
+                }
+                else
+                    return -1;
+            }
+        pr(ordered ? "!" : "%", client_data);
+        if (distance != 1)
+        {
+            char x[40];
+            sprintf(x, "%d", distance);
+            pr(x, client_data);
+        }
+    }
     pr(" ", client_data);
 
     r = cql_to_ccl_r(cn->u.boolean.right, pr, client_data);
index 3f8fb53..c05dc02 100644 (file)
@@ -317,6 +317,48 @@ Z_GDU *z_get_HTTP_Request_host_path(ODR odr,
     return p;
 }
 
+Z_GDU *z_get_HTTP_Request_uri(ODR odr, const char *uri, const char *args,
+                              int use_full_uri)
+{
+    Z_GDU *p = z_get_HTTP_Request(odr);
+    const char *cp0 = strstr(uri, "://");
+    const char *cp1 = 0;
+    if (cp0)
+        cp0 = cp0+3;
+    else
+        cp0 = uri;
+    
+    cp1 = strchr(cp0, '/');
+    if (!cp1)
+        cp1 = cp0+strlen(cp0);
+    
+    if (cp0 && cp1)
+    {
+        char *h = (char*) odr_malloc(odr, cp1 - cp0 + 1);
+        memcpy (h, cp0, cp1 - cp0);
+        h[cp1-cp0] = '\0';
+        z_HTTP_header_add(odr, &p->u.HTTP_Request->headers,
+                          "Host", h);
+    }
+
+    if (!args)
+    {
+        if (*cp1)
+            args = cp1 + 1;
+        else
+            args = "";
+    }
+    p->u.HTTP_Request->path = odr_malloc(odr, cp1 - uri + strlen(args) + 2);
+    if (use_full_uri)
+    {
+        memcpy(p->u.HTTP_Request->path, uri, cp1 - uri);
+        strcpy(p->u.HTTP_Request->path + (cp1 - uri), "/");
+    }
+    else
+        strcpy(p->u.HTTP_Request->path, "/");
+    strcat(p->u.HTTP_Request->path, args);
+    return p;
+}
 
 Z_GDU *z_get_HTTP_Response(ODR o, int code)
 {
index 2137197..85356c9 100644 (file)
@@ -127,7 +127,7 @@ int yaz_marc_read_line(yaz_marc_t mt,
         }
         else if (line[0] == '(') /* annotation, skip it */
             ;
-        else if (line_len == 24 && atoi_n_check(line, 5, &val) && val >= 24)
+        else if (line_len == 24 && atoi_n_check(line, 5, &val))
         {
             /* deal with header lines:  00366nam  22001698a 4500
             */
index 3bf499c..e23eee0 100644 (file)
--- a/src/srw.c
+++ b/src/srw.c
@@ -133,10 +133,11 @@ static int match_xsd_string(xmlNodePtr ptr, const char *elem, ODR o,
     return match_xsd_string_n(ptr, elem, o, val, 0);
 }
 
-static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o,
-                           char **val, int *len)
+static int match_xsd_XML_n2(xmlNodePtr ptr, const char *elem, ODR o,
+                            char **val, int *len, int fixup_root)
 {
     xmlBufferPtr buf;
+    int no_root_nodes = 0;
 
     if (!match_element(ptr, elem))
         return 0;
@@ -158,11 +159,17 @@ static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o,
             xmlNodeDump(buf, tmp->doc, tmp, 0, 0);
             
             xmlFreeNode(tmp);
+            no_root_nodes++;
         }
     }
-    
-    *val = (char *) odr_malloc(o, buf->use+1);
-    memcpy (*val, buf->content, buf->use);
+    if (no_root_nodes != 1 && fixup_root)
+    {
+        /* does not appear to be an XML document. Make it so */
+        xmlBufferAddHead(buf, (const xmlChar *) "<yaz_record>", -1);
+        xmlBufferAdd(buf, (const xmlChar *) "</yaz_record>", -1);
+    }
+    *val = (char *) odr_malloc(o, buf->use + 1);
+    memcpy(*val, buf->content, buf->use);
     (*val)[buf->use] = '\0';
 
     if (len)
@@ -172,7 +179,13 @@ static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o,
 
     return 1;
 }
-                     
+
+static int match_xsd_XML_n(xmlNodePtr ptr, const char *elem, ODR o,
+                           char **val, int *len)
+{
+    return match_xsd_XML_n2(ptr, elem, o, val, len, 0);
+}
+
 static int match_xsd_integer(xmlNodePtr ptr, const char *elem, ODR o,
                              Odr_int **val)
 {
@@ -211,7 +224,7 @@ char *yaz_negotiate_sru_version(char *input_ver)
 
     if (!strcmp(input_ver, "1.1"))
         return "1.1";
-    return  "1.2"; /* our latest supported version */
+    return "1.2"; /* our latest supported version */
 }
 
 static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec,
@@ -268,11 +281,11 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec,
         }
         if (data_ptr)
         {
-            switch(pack)
+            switch (pack)
             {
             case Z_SRW_recordPacking_XML:
-                match_xsd_XML_n(data_ptr, "recordData", o, 
-                                &rec->recordData_buf, &rec->recordData_len);
+                match_xsd_XML_n2(data_ptr, "recordData", o, 
+                                &rec->recordData_buf, &rec->recordData_len, 1);
                 break;
             case Z_SRW_recordPacking_URL:
                 /* just store it as a string.
@@ -303,7 +316,7 @@ static int yaz_srw_record(ODR o, xmlNodePtr pptr, Z_SRW_record *rec,
         add_xsd_string(ptr, "recordSchema", rec->recordSchema);
         if (spack)
             add_xsd_string(ptr, "recordPacking", spack);
-        switch(pack)
+        switch (pack)
         {
         case Z_SRW_recordPacking_string:
             add_xsd_string_n(ptr, "recordData", rec->recordData_buf,
@@ -520,8 +533,11 @@ static int yaz_sru_proxy_decode_facets(ODR o, xmlNodePtr root,
             num_facets = 0;
             for (node = ptr->children; node; node= node->next)
             {
-                if (match_element(node, "facet")) {
-                    facet_list_field_set(o, facet_list, yaz_sru_proxy_decode_facet_field(o, node), num_facets);
+                if (match_element(node, "facet"))
+                {
+                    facet_list_field_set(
+                        o, facet_list,
+                        yaz_sru_proxy_decode_facet_field(o, node), num_facets);
                     num_facets++;
                 }
             }
@@ -1024,7 +1040,7 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
 
             if ((*p)->srw_version)
                 add_xsd_string(ptr, "version", (*p)->srw_version);
-            switch(req->query_type)
+            switch (req->query_type)
             {
             case Z_SRW_query_type_cql:
                 add_xsd_string(ptr, "query", req->query.cql);
@@ -1042,7 +1058,7 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
             add_xsd_string(ptr, "recordSchema", req->recordSchema);
             add_xsd_string(ptr, "recordXPath", req->recordXPath);
             add_xsd_integer(ptr, "resultSetTTL", req->resultSetTTL);
-            switch(req->sort_type)
+            switch (req->sort_type)
             {
             case Z_SRW_sort_type_none:
                 break;
@@ -1127,7 +1143,7 @@ int yaz_srw_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
             xmlSetNs(ptr, ns_srw);
 
             add_xsd_string(ptr, "version", (*p)->srw_version);
-            switch(req->query_type)
+            switch (req->query_type)
             {
             case Z_SRW_query_type_cql:
                 add_xsd_string(ptr, "scanClause", req->scanClause.cql);
@@ -1223,12 +1239,13 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
                     ;
                 else if (match_xsd_string(ptr, "action", o, 
                                           &oper)){
-                    if ( oper ){
-                        if ( !strcmp(oper, "info:srw/action/1/delete"))
+                    if (oper)
+                    {
+                        if (!strcmp(oper, "info:srw/action/1/delete"))
                             req->operation = "delete";
                         else if (!strcmp(oper,"info:srw/action/1/replace" ))
                             req->operation = "replace";
-                        else if ( !strcmp( oper, "info:srw/action/1/create"))
+                        else if (!strcmp(oper, "info:srw/action/1/create"))
                             req->operation = "insert";
                     }
                 }
@@ -1316,7 +1333,6 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
         Z_SRW_PDU **p = handler_data;
         xmlNsPtr ns_ucp, ns_srw;
 
-
         if ((*p)->which == Z_SRW_update_request)
         {
             Z_SRW_updateRequest *req = (*p)->u.update_request;
@@ -1389,7 +1405,6 @@ int yaz_ucp_codec(ODR o, void * vptr, Z_SRW_PDU **handler_data,
         }
         else
             return -1;
-
     }
     return 0;
 }
index c9a8676..742b956 100644 (file)
@@ -265,7 +265,6 @@ ZOOM_API(ZOOM_connection)
     c->options = ZOOM_options_create_with_parent(options);
 
     c->host_port = 0;
-    c->path = 0;
     c->proxy = 0;
     
     c->charset = c->lang = 0;
@@ -351,7 +350,6 @@ ZOOM_API(void)
                             const char *host, int portnum)
 {
     const char *val;
-    ZOOM_task task;
 
     initlog();
 
@@ -510,7 +508,7 @@ ZOOM_API(void)
     c->async = ZOOM_options_get_bool(c->options, "async", 0);
     yaz_log(c->log_details, "%p ZOOM_connection_connect async=%d", c, c->async);
  
-    task = ZOOM_connection_add_task(c, ZOOM_TASK_CONNECT);
+    ZOOM_connection_add_task(c, ZOOM_TASK_CONNECT);
 
     if (!c->async)
     {
@@ -584,7 +582,6 @@ ZOOM_API(void)
     ZOOM_connection_remove_tasks(c);
     ZOOM_connection_remove_events(c);
     xfree(c->host_port);
-    xfree(c->path);
     xfree(c->proxy);
     xfree(c->charset);
     xfree(c->lang);
@@ -1027,45 +1024,25 @@ static void get_cert(ZOOM_connection c)
 }
 
 static zoom_ret do_connect_host(ZOOM_connection c,
-                                const char *effective_host,
                                 const char *logical_url);
 
 static zoom_ret do_connect(ZOOM_connection c)
 {
-    const char *effective_host;
-
-    if (c->proxy)
-        effective_host = c->proxy;
-    else
-        effective_host = c->host_port;
-    return do_connect_host(c, effective_host, c->host_port);
+    return do_connect_host(c, c->host_port);
 }
 
-static zoom_ret do_connect_host(ZOOM_connection c, const char *effective_host,
-    const char *logical_url)
+static zoom_ret do_connect_host(ZOOM_connection c, const char *logical_url)
 {
     void *add;
 
-    yaz_log(c->log_details, "%p do_connect effective_host=%s", c, effective_host);
-
     if (c->cs)
         cs_close(c->cs);
-    c->cs = cs_create_host(effective_host, 0, &add);
-
+    c->cs = cs_create_host_proxy(logical_url, 0, &add, c->proxy);
+    
     if (c->cs && c->cs->protocol == PROTO_HTTP)
     {
 #if YAZ_HAVE_XML2
-        if (logical_url)
-        {
-            const char *db = 0;
-            
-            c->proto = PROTO_HTTP;
-            cs_get_host_args(logical_url, &db);
-            xfree(c->path);
-            
-            c->path = xmalloc(strlen(db) * 3 + 2);
-            yaz_encode_sru_dbpath_buf(c->path, db);
-        }
+        c->proto = PROTO_HTTP;
 #else
         ZOOM_set_error(c, ZOOM_ERROR_UNSUPPORTED_PROTOCOL, "SRW");
         ZOOM_connection_close(c);
@@ -1483,39 +1460,14 @@ ZOOM_API(int)
 }
 
 #if YAZ_HAVE_XML2
-static Z_GDU *get_HTTP_Request_url(ODR odr, const char *url)
-{
-    Z_GDU *p = z_get_HTTP_Request(odr);
-    const char *host = url;
-    const char *cp0 = strstr(host, "://");
-    const char *cp1 = 0;
-    if (cp0)
-        cp0 = cp0+3;
-    else
-        cp0 = host;
-    
-    cp1 = strchr(cp0, '/');
-    if (!cp1)
-        cp1 = cp0 + strlen(cp0);
-    
-    if (cp0 && cp1)
-    {
-        char *h = (char*) odr_malloc(odr, cp1 - cp0 + 1);
-        memcpy (h, cp0, cp1 - cp0);
-        h[cp1-cp0] = '\0';
-        z_HTTP_header_add(odr, &p->u.HTTP_Request->headers, "Host", h);
-    }
-    p->u.HTTP_Request->path = odr_strdup(odr, *cp1 ? cp1 : "/");
-    return p;
-}
 
 static zoom_ret send_HTTP_redirect(ZOOM_connection c, const char *uri,
                                   Z_HTTP_Response *cookie_hres)
 {
     struct Z_HTTP_Header *h;
-    Z_GDU *gdu = get_HTTP_Request_url(c->odr_out, uri);
-    char *combined_cookies;
+    char *combined_cookies = 0;
     int combined_cookies_len = 0;
+    Z_GDU *gdu = z_get_HTTP_Request_uri(c->odr_out, uri, 0, c->proxy ? 1 : 0);
 
     gdu->u.HTTP_Request->method = odr_strdup(c->odr_out, "GET");
     z_HTTP_header_add(c->odr_out, &gdu->u.HTTP_Request->headers, "Accept",
@@ -1581,7 +1533,7 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres)
 
     ZOOM_connection_set_mask(c, 0);
     yaz_log(c->log_details, "%p handle_http", c);
-    
+
     if ((hres->code == 301 || hres->code == 302) && c->sru_mode == zoom_sru_get
         && (location = z_HTTP_header_lookup(hres->headers, "Location")))
     {
@@ -1596,11 +1548,10 @@ static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres)
         {
             /* since redirect may change host we just reconnect. A smarter
                implementation might check whether it's the same server */
-            do_connect_host(c, location, 0);
+            do_connect_host(c, location);
             send_HTTP_redirect(c, location, hres);
             /* we're OK for now. Operation is not really complete */
-            ret = 0;
-            cret = zoom_pending;
+            return;
         }
     }
     else 
index 3041928..3c7b7ea 100644 (file)
@@ -64,7 +64,6 @@ struct ZOOM_connection_p {
     enum oid_proto proto;
     COMSTACK cs;
     char *host_port;
-    char *path;
     int error;
     char *addinfo;
     char *diagset;
index d6ce28d..105970f 100644 (file)
@@ -36,12 +36,10 @@ static zoom_ret send_srw(ZOOM_connection c, Z_SRW_PDU *sr)
     Z_GDU *gdu;
     ZOOM_Event event;
     const char *database =  ZOOM_options_get(c->options, "databaseName");
-    char *fdatabase = 0;
-    
-    if (database)
-        fdatabase = yaz_encode_sru_dbpath_odr(c->odr_out, database);
-    gdu = z_get_HTTP_Request_host_path(c->odr_out, c->host_port,
-                                       fdatabase ? fdatabase : c->path);
+
+    gdu = z_get_HTTP_Request_uri(c->odr_out, c->host_port,
+                                 database,
+                                 c->proxy ? 1 : 0);
 
     if (c->sru_mode == zoom_sru_get)
     {
index e65b6bd..3512f16 100644 (file)
--- a/yaz.spec
+++ b/yaz.spec
@@ -5,7 +5,7 @@
 
 Name: yaz
 Summary: Z39.50 Programs
-Version: 4.2.4
+Version: 4.2.5
 Release: 1indexdata
 
 # determine system