/* 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
#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>
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;
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,
Z_OtherInformation **oi;
int i;
- yaz_oi_APDU(a, &oi);
- if (facet_list)
+ if (facet_list && a->which == Z_APDU_searchRequest)
+ {
+ oi = &a->u.searchRequest->additionalSearchInfo;
yaz_oi_set_facetlist(oi, out, facet_list);
+ }
+ yaz_oi_APDU(a, &oi);
for (i = 0; i < maxOtherInfosSupported; ++i)
{
if (oid_oidlen(extraOtherInfos[i].oid) > 0)
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);
printf("\n");
}
+static void print_mab_record(const char *buf, size_t len)
+{
+ size_t i;
+ size_t last_linebreak = 0;
+ size_t last_subfield = 0;
+ for (i = 0; i < len; i++)
+ {
+ // line break after header
+ if ( i == 24 )
+ {
+ printf("\n");
+ last_linebreak = i - 1;
+ }
+
+ // space between field and content
+ if ( i > 24 && i - last_linebreak == 5 )
+ printf(" ");
+
+ // space after subfield
+ if ( last_subfield != 0 && i - last_subfield == 2 )
+ printf(" ");
+
+ if ((buf[i] <= 126 && buf[i] >= 32) || strchr("\n\r\t\f", buf[i]))
+ printf("%c", buf[i]);
+ else if ( buf[i] == 29 ) // record separator
+ printf("\n");
+ else if ( buf[i] == 30 ) // field separator
+ {
+ printf("\n");
+ last_linebreak = i;
+ }
+ else if ( buf[i] == 31 ) // subfield
+ {
+ // space before subfields; except first one
+ if ( i > 24 && i - last_linebreak > 5 )
+ printf(" ");
+ printf("$");
+ last_subfield = i;
+ }
+ else
+ printf("\\X%02X", ((const unsigned char *)buf)[i]);
+ }
+}
+
static void print_xml_record(const char *buf, size_t len)
{
int has_printed = 0;
}
else if (!oid_oidcmp(oid, yaz_oid_recsyn_mab))
{
- print_record(octet_buf, octet_len);
+ print_mab_record(octet_buf, octet_len);
}
else
{
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)
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);
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";
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;
}
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);
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);
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");
}
handle_srw_record(res->records + i);
}
+ setno += res->num_records;
}
static void handle_srw_scan_term(Z_SRW_scanTerm *term)
{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,
}
#endif
-#define max_HTTP_redirects 2
+#define max_HTTP_redirects 3
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");
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)