cookie: introduce yaz_cookies_reset
[yaz-moved-to-github.git] / client / client.c
index 97773d0..6fea730 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2013 Index Data
+ * Copyright (C) Index Data
  * See the file LICENSE for details.
  */
 /** \file client.c
@@ -64,6 +64,7 @@
 #include <yaz/cql.h>
 #include <yaz/log.h>
 #include <yaz/facet.h>
+#include <yaz/cookie.h>
 
 #if HAVE_READLINE_READLINE_H
 #include <readline/readline.h>
@@ -103,9 +104,9 @@ char *databaseNames[128];
 int num_databaseNames = 0;
 static Z_External *record_last = 0;
 static int setnumber = -1;              /* current result set number */
-static int smallSetUpperBound = 0;
-static int largeSetLowerBound = 1;
-static int mediumSetPresentNumber = 0;
+static Odr_int smallSetUpperBound = 0;
+static Odr_int largeSetLowerBound = 1;
+static Odr_int mediumSetPresentNumber = 0;
 static Z_ElementSetNames *elementSetNames = 0;
 static Z_FacetList *facet_list = 0;
 static ODR facet_odr = 0;
@@ -149,6 +150,7 @@ static char cur_host[200];
 static Odr_int last_hit_count = 0;
 static int pretty_xml = 0;
 static Odr_int sru_maximumRecords = 0;
+static yaz_cookies_t yaz_cookies = 0;
 
 typedef enum {
     QueryType_Prefix,
@@ -742,6 +744,9 @@ static int session_connect(const char *arg)
     int r;
     const char *basep = 0;
 
+    yaz_cookies_destroy(yaz_cookies);
+    yaz_cookies = yaz_cookies_create();
+
     r = session_connect_base(arg, &basep);
     if (basep && *basep)
         set_base(basep);
@@ -1361,43 +1366,17 @@ static int send_srw(Z_SRW_PDU *sr)
     return send_srw_host_path(sr, cur_host, path);
 }
 
-static int send_SRW_redirect(const char *uri, Z_HTTP_Response *cookie_hres)
+static int send_SRW_redirect(const char *uri)
 {
     const char *username = 0;
     const char *password = 0;
-    struct Z_HTTP_Header *h;
-    char *combined_cookies = 0;
-    int combined_cookies_len = 0;
     Z_GDU *gdu = get_HTTP_Request_url(out, uri);
 
     gdu->u.HTTP_Request->method = odr_strdup(out, "GET");
     z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers, "Accept",
                       "text/xml");
 
-    for (h = cookie_hres->headers; h; h = h->next)
-    {
-        if (!strcmp(h->name, "Set-Cookie"))
-        {
-            char *cp;
-
-            if (!(cp = strchr(h->value, ';')))
-                cp = h->value + strlen(h->value);
-            if (cp - h->value >= 1)
-            {
-                combined_cookies = xrealloc(combined_cookies, combined_cookies_len + cp - h->value + 3);
-                memcpy(combined_cookies+combined_cookies_len, h->value, cp - h->value);
-                combined_cookies[combined_cookies_len + cp - h->value] = '\0';
-                strcat(combined_cookies,"; ");
-                combined_cookies_len = strlen(combined_cookies);
-            }
-        }
-    }
-    if (combined_cookies_len)
-    {
-        z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers, "Cookie", combined_cookies);
-        xfree(combined_cookies);
-    }
-
+    yaz_cookies_request(yaz_cookies, out, gdu->u.HTTP_Request);
     if (auth)
     {
         if (auth->which == Z_IdAuthentication_open)
@@ -1524,8 +1503,7 @@ static int send_SRW_searchRequest(const char *arg)
     sru_maximumRecords = 0;
     sr->u.request->maximumRecords = odr_intdup(out, 0);
     sr->u.request->facetList = facet_list;
-    if (record_schema)
-        sr->u.request->recordSchema = record_schema;
+    sr->u.request->recordSchema = record_schema;
     if (recordsyntax_size == 1 && !yaz_matchstr(recordsyntax_list[0], "xml"))
         sr->u.request->recordPacking = "xml";
     return send_srw(sr);
@@ -2679,7 +2657,7 @@ static int cmd_explain(const char *arg)
         setno = 1;
 
         /* save this for later .. when fetching individual records */
-        sr = yaz_srw_get(out, Z_SRW_explain_request);
+        sr = yaz_srw_get_pdu(out, Z_SRW_explain_request, sru_version);
         if (recordsyntax_size == 1
             && !yaz_matchstr(recordsyntax_list[0], "xml"))
             sr->u.explain_request->recordPacking = "xml";
@@ -2950,30 +2928,30 @@ static int cmd_delete(const char *arg)
 
 static int cmd_ssub(const char *arg)
 {
-    if (!(smallSetUpperBound = atoi(arg)))
-        return 0;
+    smallSetUpperBound = odr_strtol(arg, 0, 10);
     return 1;
 }
 
 static int cmd_lslb(const char *arg)
 {
-    if (!(largeSetLowerBound = atoi(arg)))
-        return 0;
+    largeSetLowerBound = odr_strtol(arg, 0, 10);
     return 1;
 }
 
 static int cmd_mspn(const char *arg)
 {
-    if (!(mediumSetPresentNumber = atoi(arg)))
-        return 0;
+    mediumSetPresentNumber = odr_strtol(arg, 0, 10);
     return 1;
 }
 
 static int cmd_status(const char *arg)
 {
-    printf("smallSetUpperBound: %d\n", smallSetUpperBound);
-    printf("largeSetLowerBound: %d\n", largeSetLowerBound);
-    printf("mediumSetPresentNumber: %d\n", mediumSetPresentNumber);
+    printf("smallSetUpperBound: " ODR_INT_PRINTF "\n",
+           smallSetUpperBound);
+    printf("largeSetLowerBound: " ODR_INT_PRINTF "\n",
+           largeSetLowerBound);
+    printf("mediumSetPresentNumber: " ODR_INT_PRINTF "\n",
+           mediumSetPresentNumber);
     return 1;
 }
 
@@ -3185,8 +3163,7 @@ static int send_SRW_presentRequest(const char *arg)
     sr->u.request->startRecord = odr_intdup(out, setno);
     sru_maximumRecords = nos;
     sr->u.request->maximumRecords = odr_intdup(out, nos);
-    if (record_schema)
-        sr->u.request->recordSchema = record_schema;
+    sr->u.request->recordSchema = record_schema;
     if (recordsyntax_size == 1 && !yaz_matchstr(recordsyntax_list[0], "xml"))
         sr->u.request->recordPacking = "xml";
     return send_srw(sr);
@@ -3267,6 +3244,7 @@ static int cmd_show(const char *arg)
 
 static void exit_client(int code)
 {
+    yaz_cookies_destroy(yaz_cookies);
     file_history_save(file_history);
     file_history_destroy(&file_history);
     nmem_destroy(nmem_auth);
@@ -4330,10 +4308,7 @@ struct timeval tv_start;
 static void handle_srw_record(Z_SRW_record *rec)
 {
     if (rec->recordPosition)
-    {
         printf("pos=" ODR_INT_PRINTF, *rec->recordPosition);
-        setno = *rec->recordPosition + 1;
-    }
     if (rec->recordSchema)
         printf(" schema=%s", rec->recordSchema);
     printf("\n");
@@ -4387,6 +4362,7 @@ static void handle_srw_response(Z_SRW_searchRetrieveResponse *res)
         }
         handle_srw_record(res->records + i);
     }
+    setno += res->num_records;
 }
 
 static void handle_srw_scan_term(Z_SRW_scanTerm *term)
@@ -4470,6 +4446,7 @@ static void http_response(Z_HTTP_Response *hres)
                 {YAZ_XMLNS_SRU_v2_mask, 0, (Z_SOAP_fun) yaz_srw_codec},
                 {YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec},
                 {YAZ_XMLNS_SRU_v1_response, 0, (Z_SOAP_fun) yaz_srw_codec},
+                {"searchRetrieveResponse", 0, (Z_SOAP_fun) yaz_srw_codec},
                 {0, 0, 0}
             };
             ret = z_soap_codec(o, &soap_package,
@@ -4532,7 +4509,7 @@ static void http_response(Z_HTTP_Response *hres)
 }
 #endif
 
-#define max_HTTP_redirects 2
+#define max_HTTP_redirects 3
 
 static void wait_and_handle_response(int one_response_only)
 {
@@ -4669,17 +4646,37 @@ static void wait_and_handle_response(int one_response_only)
             Z_HTTP_Response *hres = gdu->u.HTTP_Response;
             int code = hres->code;
             const char *location = 0;
+
+            yaz_cookies_response(yaz_cookies, hres);
             if ((code == 301 || code == 302)
                 && no_redirects < max_HTTP_redirects
                 && !yaz_matchstr(sru_method, "get")
                 && (location = z_HTTP_header_lookup(hres->headers, "Location")))
             {
                 const char *base_tmp;
-                session_connect_base(location, &base_tmp);
+
+                if (*location == '/')
+                {
+                    char *args = 0;
+                    char *nlocation = odr_malloc(in, strlen(location)
+                                                 + strlen(cur_host) + 3);
+                    strcpy(nlocation, cur_host);
+                    cs_get_host_args(nlocation, (const char **) &args);
+                    if (!args || !*args)
+                        args = nlocation + strlen(nlocation);
+                    else
+                        args--;
+                    strcpy(args, location);
+                    location = nlocation;
+                }
+                else
+                {
+                    session_connect_base(location, &base_tmp);
+                }
                 no_redirects++;
                 if (conn)
                 {
-                    if (send_SRW_redirect(location, hres) == 2)
+                    if (send_SRW_redirect(location) == 2)
                         continue;
                 }
                 printf("Redirect failed\n");
@@ -4899,7 +4896,9 @@ static int cmd_list_all(const char* args)
     printf("Named Result Sets    : %s\n",setnumber==-1?"off":"on");
 
     /* piggy back options */
-    printf("ssub/lslb/mspn       : %d/%d/%d\n",smallSetUpperBound,largeSetLowerBound,mediumSetPresentNumber);
+    printf("ssub/lslb/mspn       : " ODR_INT_PRINTF "/" ODR_INT_PRINTF "/"
+           ODR_INT_PRINTF "\n",
+           smallSetUpperBound, largeSetLowerBound, mediumSetPresentNumber);
 
     /* print present related options */
     if (recordsyntax_size > 0)