X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=zutil%2Fzoom-c.c;h=7bad637e3a1ab987554a9454aa1c0c65ca6b70af;hp=cf5b67f9151fb60c3da35a1a79231f5e7c253e09;hb=ac286ae76051058c8e340bf84eb98391340b7d22;hpb=4d531a1a9131d69c3b6c27fbac42837e22cff61c diff --git a/zutil/zoom-c.c b/zutil/zoom-c.c index cf5b67f..7bad637 100644 --- a/zutil/zoom-c.c +++ b/zutil/zoom-c.c @@ -2,7 +2,7 @@ * Copyright (c) 2000-2003, Index Data * See the file LICENSE for details. * - * $Id: zoom-c.c,v 1.13 2003-01-06 08:20:29 adam Exp $ + * $Id: zoom-c.c,v 1.18 2003-02-14 18:49:24 adam Exp $ * * ZOOM layer for C, connections, result sets, queries. */ @@ -18,7 +18,7 @@ #include #include #include - +#include #if HAVE_SYS_POLL_H #include @@ -174,6 +174,8 @@ void ZOOM_connection_remove_task (ZOOM_connection c) } } +static int ZOOM_connection_exec_task (ZOOM_connection c); + void ZOOM_connection_remove_tasks (ZOOM_connection c) { while (c->tasks) @@ -187,7 +189,7 @@ ZOOM_connection_create (ZOOM_options options) { ZOOM_connection c = (ZOOM_connection) xmalloc (sizeof(*c)); - c->soap = 0; + c->proto = PROTO_Z3950; c->cs = 0; c->mask = 0; c->reconnect_ok = 0; @@ -203,6 +205,7 @@ ZOOM_connection_create (ZOOM_options options) c->options = ZOOM_options_create_with_parent(options); c->host_port = 0; + c->path = 0; c->proxy = 0; c->charset = c->lang = 0; @@ -326,6 +329,7 @@ ZOOM_connection_connect(ZOOM_connection c, c->lang = 0; xfree (c->host_port); + xfree (c->path); if (portnum) { char hostn[128]; @@ -401,8 +405,6 @@ ZOOM_API(int) ZOOM_query_cql(ZOOM_query s, const char *str) { Z_External *ext; - char *buf; - int len; ext = (Z_External *) odr_malloc(s->odr, sizeof(*ext)); ext->direct_reference = odr_getoidbystr(s->odr, "1.2.840.10003.16.2"); @@ -434,10 +436,6 @@ ZOOM_connection_destroy(ZOOM_connection c) ZOOM_resultset r; if (!c) return; -#if HAVE_GSOAP - if (c->soap) - soap_end(c->soap); -#endif if (c->cs) cs_close (c->cs); for (r = c->resultsets; r; r = r->next) @@ -652,43 +650,59 @@ static zoom_ret do_connect (ZOOM_connection c) if (memcmp(c->host_port, "http:", 5) == 0) { -#if HAVE_GSOAP - c->soap = soap_new(); - c->soap->namespaces = srw_namespaces; +#if HAVE_XSLT + const char *path; + c->proto = PROTO_SRW; + effective_host = c->host_port + 5; + if (*effective_host == '/') + effective_host++; + if (*effective_host == '/') + effective_host++; + if (!(path = strchr(effective_host, '/'))) + path = "/"; + xfree(c->path); + c->path = xstrdup(path); #else c->state = STATE_IDLE; set_ZOOM_error(c, ZOOM_ERROR_UNSUPPORTED_PROTOCOL, "SRW"); + return zoom_complete; #endif } - else + c->cs = cs_create_host (effective_host, 0, &add); + + if (c->cs) { - c->cs = cs_create_host (effective_host, 0, &add); - - if (c->cs) + int ret = cs_connect (c->cs, add); + if (ret == 0) { - int ret = cs_connect (c->cs, add); - if (ret == 0) - { - ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_CONNECT); - ZOOM_connection_put_event(c, event); + ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_CONNECT); + ZOOM_connection_put_event(c, event); + if (c->proto == PROTO_Z3950) ZOOM_connection_send_init(c); - c->state = STATE_ESTABLISHED; - return zoom_pending; - } - else if (ret > 0) + else { - c->state = STATE_CONNECTING; - c->mask = ZOOM_SELECT_EXCEPT; - if (c->cs->io_pending & CS_WANT_WRITE) - c->mask += ZOOM_SELECT_WRITE; - if (c->cs->io_pending & CS_WANT_READ) - c->mask += ZOOM_SELECT_READ; - return zoom_pending; + /* no init request for SRW .. */ + assert (c->tasks->which == ZOOM_TASK_CONNECT); + ZOOM_connection_remove_task (c); + c->mask = 0; + ZOOM_connection_exec_task (c); } + c->state = STATE_ESTABLISHED; + return zoom_pending; + } + else if (ret > 0) + { + c->state = STATE_CONNECTING; + c->mask = ZOOM_SELECT_EXCEPT; + if (c->cs->io_pending & CS_WANT_WRITE) + c->mask += ZOOM_SELECT_WRITE; + if (c->cs->io_pending & CS_WANT_READ) + c->mask += ZOOM_SELECT_READ; + return zoom_pending; } - c->state = STATE_IDLE; - set_ZOOM_error(c, ZOOM_ERROR_CONNECT, effective_host); } + c->state = STATE_IDLE; + set_ZOOM_error(c, ZOOM_ERROR_CONNECT, effective_host); return zoom_complete; } @@ -899,6 +913,72 @@ static zoom_ret ZOOM_connection_send_init (ZOOM_connection c) return send_APDU (c, apdu); } +static zoom_ret send_srw (ZOOM_connection c, Z_SRW_searchRetrieve *sr) +{ + Z_SOAP_Handler h[2] = { + {"http://www.loc.gov/zing/srw/v1.0/", 0, (Z_SOAP_fun) yaz_srw_codec}, + {0, 0, 0} + }; + ODR o = odr_createmem(ODR_ENCODE); + int ret; + Z_SOAP *p = odr_malloc(o, sizeof(*p)); + Z_GDU *gdu; + ZOOM_Event event; + + gdu = z_get_HTTP_Request(c->odr_out); + gdu->u.HTTP_Request->path = c->path; + z_HTTP_header_add(c->odr_out, &gdu->u.HTTP_Request->headers, + "Content-Type", "text/xml"); + z_HTTP_header_add(c->odr_out, &gdu->u.HTTP_Request->headers, + "SOAPAction", "\"\""); + p->which = Z_SOAP_generic; + p->u.generic = odr_malloc(o, sizeof(*p->u.generic)); + p->u.generic->no = 0; + p->u.generic->ns = 0; + p->u.generic->p = sr; + p->ns = "http://schemas.xmlsoap.org/soap/envelope/"; + + ret = z_soap_codec(o, &p, + &gdu->u.HTTP_Request->content_buf, + &gdu->u.HTTP_Request->content_len, h); + + if (!z_GDU(c->odr_out, &gdu, 0, 0)) + return zoom_complete; + c->buf_out = odr_getbuf(c->odr_out, &c->len_out, 0); + + odr_destroy(o); + + event = ZOOM_Event_create (ZOOM_EVENT_SEND_APDU); + ZOOM_connection_put_event (c, event); + odr_reset(c->odr_out); + return do_write (c); +} + +static zoom_ret ZOOM_connection_srw_send_search(ZOOM_connection c) +{ + ZOOM_resultset resultset; + Z_SRW_searchRetrieve *sr = yaz_srw_get(c->odr_out, + Z_SRW_searchRetrieve_request); + + assert (c->tasks); + assert (c->tasks->which == ZOOM_TASK_SEARCH); + + resultset = c->tasks->u.search.resultset; + assert(resultset); + assert (resultset->z_query); + + if (resultset->z_query->which == Z_Query_type_104 + && resultset->z_query->u.type_104->which == Z_External_CQL) + sr->u.request->query = resultset->z_query->u.type_104->u.cql; + else + sr->u.request->query = "dc.title = computer"; + + sr->u.request->startRecord = odr_intdup (c->odr_out, resultset->start + 1); + sr->u.request->maximumRecords = odr_intdup (c->odr_out, resultset->count); + + return send_srw(c, sr); +} + static zoom_ret ZOOM_connection_send_search (ZOOM_connection c) { ZOOM_resultset r; @@ -958,9 +1038,9 @@ static zoom_ret ZOOM_connection_send_search (ZOOM_connection c) { /* Regular piggyback - do it unless we're going to do sort */ *search_req->largeSetLowerBound = 2000000000; - *search_req->smallSetUpperBound = r->count; + *search_req->smallSetUpperBound = 0; *search_req->mediumSetPresentNumber = r->count; - smallSetElementSetName = 0; /* no need to provide this */ + smallSetElementSetName = 0; } else { @@ -1582,14 +1662,15 @@ static zoom_ret send_present (ZOOM_connection c) compo->u.complex->generic = (Z_Specification *) odr_malloc(c->odr_out, sizeof(*compo->u.complex->generic)); - compo->u.complex->generic->schema = (Odr_oid *) + compo->u.complex->generic->which = Z_Specification_oid; + compo->u.complex->generic->u.oid = (Odr_oid *) yaz_str_to_z3950oid (c->odr_out, CLASS_SCHEMA, schema); - if (!compo->u.complex->generic->schema) + if (!compo->u.complex->generic->u.oid) { /* OID wasn't a schema! Try record syntax instead. */ - compo->u.complex->generic->schema = (Odr_oid *) + compo->u.complex->generic->u.oid = (Odr_oid *) yaz_str_to_z3950oid (c->odr_out, CLASS_RECSYN, schema); } if (elementSetName && *elementSetName) @@ -2097,9 +2178,9 @@ static int ZOOM_connection_exec_task (ZOOM_connection c) } task->running = 1; ret = zoom_complete; - if (c->soap) +#if 0 + if (c->proto == PROTO_SRW) { -#if HAVE_GSOAP ZOOM_resultset resultset; switch (task->which) { @@ -2128,16 +2209,16 @@ static int ZOOM_connection_exec_task (ZOOM_connection c) resultset->z_query->u.type_104->u.cql); break; } -#else - ; #endif - } - else if (c->cs || task->which == ZOOM_TASK_CONNECT) + if (c->cs || task->which == ZOOM_TASK_CONNECT) { switch (task->which) { case ZOOM_TASK_SEARCH: - ret = ZOOM_connection_send_search(c); + if (c->proto == PROTO_SRW) + ret = ZOOM_connection_srw_send_search(c); + else + ret = ZOOM_connection_send_search(c); break; case ZOOM_TASK_RETRIEVE: ret = send_present (c); @@ -2306,10 +2387,16 @@ static void handle_apdu (ZOOM_connection c, Z_APDU *apdu) } } +static void handle_http(ZOOM_connection c, Z_HTTP_Response *hres) +{ + c->mask = 0; + yaz_log (LOG_DEBUG, "handle_http"); + ZOOM_connection_remove_task(c); +} + static int do_read (ZOOM_connection c) { int r; - Z_APDU *apdu; ZOOM_Event event; event = ZOOM_Event_create (ZOOM_EVENT_RECV_DATA); @@ -2338,18 +2425,22 @@ static int do_read (ZOOM_connection c) } else { + Z_GDU *gdu; ZOOM_Event event; odr_reset (c->odr_in); odr_setbuf (c->odr_in, c->buf_in, r, 0); event = ZOOM_Event_create (ZOOM_EVENT_RECV_APDU); ZOOM_connection_put_event (c, event); - if (!z_APDU (c->odr_in, &apdu, 0, 0)) + + if (!z_GDU (c->odr_in, &gdu, 0, 0)) { set_ZOOM_error(c, ZOOM_ERROR_DECODE, 0); do_close (c); } - else - handle_apdu (c, apdu); + else if (gdu->which == Z_GDU_Z3950) + handle_apdu (c, gdu->u.z3950); + else if (gdu->which == Z_GDU_HTTP_Response) + handle_http (c, gdu->u.HTTP_Response); c->reconnect_ok = 0; } return 1; @@ -2555,7 +2646,16 @@ static int ZOOM_connection_do_io(ZOOM_connection c, int mask) else if (ret == 0) { ZOOM_connection_put_event (c, event); - ZOOM_connection_send_init (c); + if (c->proto == PROTO_Z3950) + ZOOM_connection_send_init(c); + else + { + /* no init request for SRW .. */ + assert (c->tasks->which == ZOOM_TASK_CONNECT); + ZOOM_connection_remove_task (c); + c->mask = 0; + ZOOM_connection_exec_task (c); + } c->state = STATE_ESTABLISHED; } else @@ -2745,7 +2845,7 @@ ZOOM_event (int no, ZOOM_connection *cs) { ZOOM_Event event = ZOOM_Event_create(ZOOM_EVENT_TIMEOUT); /* timeout and this connection was waiting */ - set_ZOOM_error(c, ZOOM_ERROR_TIMEOUT); + set_ZOOM_error(c, ZOOM_ERROR_TIMEOUT, 0); do_close (c); yaz_log (LOG_DEBUG, "timeout"); ZOOM_connection_put_event(c, event);