+--- 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" .
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])
+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.
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
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);
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);
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;
}
if (cs)
{
+ if (proxy_host)
+ host = proxy_host;
if (!(*vp = cs_straddr(cs, connect_host ? connect_host : host)))
{
cs_close (cs);
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);
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)
{
}
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
*/
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;
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)
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)
{
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,
}
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.
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,
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++;
}
}
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);
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;
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);
;
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";
}
}
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;
}
else
return -1;
-
}
return 0;
}
c->options = ZOOM_options_create_with_parent(options);
c->host_port = 0;
- c->path = 0;
c->proxy = 0;
c->charset = c->lang = 0;
const char *host, int portnum)
{
const char *val;
- ZOOM_task task;
initlog();
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)
{
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);
}
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);
}
#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",
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")))
{
{
/* 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
enum oid_proto proto;
COMSTACK cs;
char *host_port;
- char *path;
int error;
char *addinfo;
char *diagset;
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)
{
Name: yaz
Summary: Z39.50 Programs
-Version: 4.2.4
+Version: 4.2.5
Release: 1indexdata
# determine system