X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fseshigh.c;h=6349c4e0881c366a8dc4c90d8a9f48beebd9d716;hp=533ab9a5373469d8b26c931028d53f788a68565d;hb=725fc033b729b22a1e0cfba614192b6fbfaeda4f;hpb=da52cf68299952193806f8093c04e46d1bbf8375 diff --git a/src/seshigh.c b/src/seshigh.c index 533ab9a..6349c4e 100644 --- a/src/seshigh.c +++ b/src/seshigh.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 1995-2003, Index Data + * Copyright (c) 1995-2004, Index Data * See the file LICENSE for details. * - * $Id: seshigh.c,v 1.12 2003-12-31 00:14:01 adam Exp $ + * $Id: seshigh.c,v 1.24 2004-05-10 07:48:56 adam Exp $ */ /* @@ -271,7 +271,7 @@ void ir_session(IOCHAN h, int event) destroy_association(assoc); iochan_destroy(h); } - iochan_clearflag (h, EVENT_OUTPUT|EVENT_OUTPUT); + iochan_clearflag (h, EVENT_OUTPUT); if (conn->io_pending) { /* cs_accept didn't complete */ assoc->cs_accept_mask = @@ -471,6 +471,7 @@ static int srw_bend_init(association *assoc) ce = yaz_set_proposal_charneg(assoc->decode, &encoding, 1, 0, 0, 1); assoc->init->charneg_request = ce->u.charNeg3; #endif + assoc->backend = 0; if (!(binitres = (*cb->bend_init)(assoc->init))) { yaz_log(LOG_WARN, "Bad response from backend."); @@ -564,12 +565,8 @@ static void srw_bend_search(association *assoc, request *req, { srw_error = 3; /* assume Authentication error */ - srw_res->num_diagnostics = 1; - srw_res->diagnostics = (Z_SRW_diagnostic *) - odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics)); - srw_res->diagnostics[0].code = - odr_intdup(assoc->encode, srw_error); - srw_res->diagnostics[0].details = 0; + yaz_add_srw_diagnostic(assoc->encode, &srw_res->diagnostics, + &srw_res->num_diagnostics, 1, 0); return; } } @@ -635,9 +632,8 @@ static void srw_bend_search(association *assoc, request *req, srw_res->num_diagnostics = 1; srw_res->diagnostics = (Z_SRW_diagnostic *) odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics)); - srw_res->diagnostics[0].code = - odr_intdup(assoc->encode, srw_error); - srw_res->diagnostics[0].details = 0; + yaz_mk_std_diagnostic(assoc->encode, + srw_res->diagnostics, srw_error, 0); return; } @@ -665,13 +661,11 @@ static void srw_bend_search(association *assoc, request *req, srw_res->num_diagnostics = 1; srw_res->diagnostics = (Z_SRW_diagnostic *) odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics)); - srw_res->diagnostics[0].code = - odr_intdup(assoc->encode, - yaz_diag_bib1_to_srw (rr.errcode)); - srw_res->diagnostics[0].details = rr.errstring; - yaz_log(LOG_DEBUG, "srw_bend_search returned SRW error %d", - *srw_res->diagnostics[0].code); - + yaz_mk_std_diagnostic(assoc->encode, srw_res->diagnostics, + yaz_diag_bib1_to_srw (rr.errcode), + rr.errstring); + yaz_log(LOG_DEBUG, "srw_bend_search returned SRW error %s", + srw_res->diagnostics[0].uri); } else { @@ -717,10 +711,11 @@ static void srw_bend_search(association *assoc, request *req, srw_res->diagnostics = (Z_SRW_diagnostic *) odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics)); - srw_res->diagnostics[0].code = - odr_intdup(assoc->encode, - yaz_diag_bib1_to_srw (errcode)); - srw_res->diagnostics[0].details = rr.errstring; + + yaz_mk_std_diagnostic(assoc->encode, + srw_res->diagnostics, + yaz_diag_bib1_to_srw (errcode), + rr.errstring); break; } if (srw_res->records[j].recordData_buf) @@ -758,6 +753,7 @@ static void srw_bend_explain(association *assoc, request *req, rr.print = assoc->print; rr.explain_buf = 0; rr.database = srw_req->database; + rr.schema = "http://explain.z3950.org/dtd/2.0/"; (*assoc->init->bend_explain)(assoc->backend, &rr); if (rr.explain_buf) { @@ -779,370 +775,129 @@ static void process_http_request(association *assoc, request *req) { Z_HTTP_Request *hreq = req->gdu_request->u.HTTP_Request; ODR o = assoc->encode; + int r = 2; /* 2=NOT TAKEN, 1=TAKEN, 0=SOAP TAKEN */ + Z_SRW_PDU *sr = 0; + Z_SOAP *soap_package = 0; Z_GDU *p = 0; + char *charset = 0; Z_HTTP_Response *hres = 0; int keepalive = 1; + char *stylesheet = 0; + Z_SRW_diagnostic *diagnostic = 0; + int num_diagnostic = 0; - if (!strcmp(hreq->method, "GET")) + if (!strcmp(hreq->path, "/test")) + { + p = z_get_HTTP_Response(o, 200); + hres = p->u.HTTP_Response; + hres->content_buf = "1234567890\n"; + hres->content_len = strlen(hres->content_buf); + r = 1; + } + if (r == 2) { - char *db = "Default"; - const char *p0 = hreq->path, *p1; - const char *operation = 0; -#if HAVE_XML2 - int ret = -1; - char *charset = 0; - Z_SOAP *soap_package = 0; - static Z_SOAP_Handler soap_handlers[2] = { - {"http://www.loc.gov/zing/srw/", 0, - (Z_SOAP_fun) yaz_srw_codec}, - {0, 0, 0} - }; -#endif - if (*p0 == '/') - p0++; - p1 = strchr(p0, '?'); - if (!p1) - p1 = p0 + strlen(p0); - if (p1 != p0) - { - db = odr_malloc(assoc->decode, p1 - p0 + 1); - memcpy (db, p0, p1 - p0); - db[p1 - p0] = '\0'; - } - if (p1) - operation = yaz_uri_val(p1, "operation", o); - if (!operation) - operation = "explain"; -#if HAVE_XML2 - if (p1 && !strcmp(operation, "searchRetrieve")) - { - Z_SRW_PDU *res = yaz_srw_get(o, Z_SRW_searchRetrieve_response); - Z_SRW_PDU *sr = yaz_srw_get(o, Z_SRW_searchRetrieve_request); - char *query = yaz_uri_val(p1, "query", o); - char *pQuery = yaz_uri_val(p1, "pQuery", o); - char *sortKeys = yaz_uri_val(p1, "sortKeys", o); - int http_code = 200; - - if (query) - { - sr->u.request->query_type = Z_SRW_query_type_cql; - sr->u.request->query.cql = query; - } - if (pQuery) - { - sr->u.request->query_type = Z_SRW_query_type_pqf; - sr->u.request->query.pqf = pQuery; - } - if (sortKeys) - { - sr->u.request->sort_type = Z_SRW_sort_type_sort; - sr->u.request->sort.sortKeys = sortKeys; - } - sr->u.request->recordSchema = yaz_uri_val(p1, "recordSchema", o); - sr->u.request->recordPacking = yaz_uri_val(p1, "recordPacking", o); - if (!sr->u.request->recordPacking) - sr->u.request->recordPacking = "xml"; - yaz_uri_val_int(p1, "maximumRecords", o, - &sr->u.request->maximumRecords); - yaz_uri_val_int(p1, "startRecord", o, - &sr->u.request->startRecord); - sr->u.request->database = db; - srw_bend_search(assoc, req, sr->u.request, res->u.response, - &http_code); - - soap_package = odr_malloc(o, sizeof(*soap_package)); - soap_package->which = Z_SOAP_generic; - - soap_package->u.generic = - odr_malloc(o, sizeof(*soap_package->u.generic)); - - soap_package->u.generic->p = res; - soap_package->u.generic->ns = soap_handlers[0].ns; - soap_package->u.generic->no = 0; - - soap_package->ns = "SRU"; + r = yaz_srw_decode(hreq, &sr, &soap_package, assoc->decode, &charset); + yaz_log(LOG_DEBUG, "yaz_srw_decode returned %d", r); + } + if (r == 2) /* not taken */ + { + r = yaz_sru_decode(hreq, &sr, &soap_package, assoc->decode, &charset, + &diagnostic, &num_diagnostic); + yaz_log(LOG_DEBUG, "yaz_sru_decode returned %d", r); + } + if (r == 0) /* decode SRW/SRU OK .. */ + { + int http_code = 200; + if (sr->which == Z_SRW_searchRetrieve_request) + { + Z_SRW_PDU *res = + yaz_srw_get(assoc->encode, Z_SRW_searchRetrieve_response); - p = z_get_HTTP_Response(o, http_code); - if (http_code == 200) + stylesheet = sr->u.request->stylesheet; + if (num_diagnostic) { - hres = p->u.HTTP_Response; - - ret = z_soap_codec_enc(assoc->encode, &soap_package, - &hres->content_buf, &hres->content_len, - soap_handlers, charset); - if (!charset) - z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/xml"); - else - { - char ctype[60]; - strcpy(ctype, "text/xml; charset="); - strcat(ctype, charset); - z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype); - } + res->u.response->diagnostics = diagnostic; + res->u.response->num_diagnostics = num_diagnostic; } - } - else if (p1 && !strcmp(operation, "explain")) - { + else + { + srw_bend_search(assoc, req, sr->u.request, res->u.response, + &http_code); + } + if (http_code == 200) + soap_package->u.generic->p = res; + } + else if (sr->which == Z_SRW_explain_request) + { Z_SRW_PDU *res = yaz_srw_get(o, Z_SRW_explain_response); - Z_SRW_PDU *sr = yaz_srw_get(o, Z_SRW_explain_request); - int http_code = 200; - - sr->u.explain_request->database = db; - sr->u.explain_request->recordPacking = - yaz_uri_val(p1, "recordPacking", o); - if (!sr->u.explain_request->recordPacking) - sr->u.explain_request->recordPacking = "xml"; - - srw_bend_explain(assoc, req, sr->u.explain_request, - res->u.explain_response, &http_code); - - if (res->u.explain_response->record.recordData_buf) - { - soap_package = odr_malloc(o, sizeof(*soap_package)); - soap_package->which = Z_SOAP_generic; - - soap_package->u.generic = - odr_malloc(o, sizeof(*soap_package->u.generic)); - - soap_package->u.generic->p = res; - soap_package->u.generic->ns = soap_handlers[0].ns; - soap_package->u.generic->no = 0; - - soap_package->ns = "SRU"; - - p = z_get_HTTP_Response(o, 200); - hres = p->u.HTTP_Response; - - ret = z_soap_codec_enc(assoc->encode, &soap_package, - &hres->content_buf, &hres->content_len, - soap_handlers, charset); - if (!charset) - z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/xml"); - else - { - char ctype[60]; - strcpy(ctype, "text/xml; charset="); - strcat(ctype, charset); - z_HTTP_header_add(o, &hres->headers, "Content-Type", - ctype); - } - } - } -#endif -#ifdef DOCDIR - if (strlen(hreq->path) >= 5 && strlen(hreq->path) < 80 && - !memcmp(hreq->path, "/doc/", 5)) - { - FILE *f; - char fpath[120]; - - strcpy(fpath, DOCDIR); - strcat(fpath, hreq->path+4); - f = fopen(fpath, "rb"); - if (f) { - struct stat sbuf; - if (fstat(fileno(f), &sbuf) || !S_ISREG(sbuf.st_mode)) - { - fclose(f); - f = 0; - } - } - if (f) - { - long sz; - fseek(f, 0L, SEEK_END); - sz = ftell(f); - if (sz >= 0 && sz < 500000) - { - const char *ctype = "application/octet-stream"; - const char *cp; - - p = z_get_HTTP_Response(o, 200); - hres = p->u.HTTP_Response; - hres->content_buf = (char *) odr_malloc(o, sz + 1); - hres->content_len = sz; - fseek(f, 0L, SEEK_SET); - fread(hres->content_buf, 1, sz, f); - if ((cp = strrchr(fpath, '.'))) { - cp++; - if (!strcmp(cp, "png")) - ctype = "image/png"; - else if (!strcmp(cp, "gif")) - ctype = "image/gif"; - else if (!strcmp(cp, "xml")) - ctype = "text/xml"; - else if (!strcmp(cp, "html")) - ctype = "text/html"; - } - z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype); - } - fclose(f); + stylesheet = sr->u.explain_request->stylesheet; + if (num_diagnostic) + { + res->u.explain_response->diagnostics = diagnostic; + res->u.explain_response->num_diagnostics = num_diagnostic; } + srw_bend_explain(assoc, req, sr->u.explain_request, + res->u.explain_response, &http_code); + if (http_code == 200) + soap_package->u.generic->p = res; } -#endif - -#if 0 - if (!strcmp(hreq->path, "/")) - { -#ifdef DOCDIR - struct stat sbuf; -#endif - const char *doclink = ""; - p = z_get_HTTP_Response(o, 200); - hres = p->u.HTTP_Response; - hres->content_buf = (char *) odr_malloc(o, 400); -#ifdef DOCDIR - if (stat(DOCDIR "/yaz.html", &sbuf) == 0 && S_ISREG(sbuf.st_mode)) - doclink = "

Documentation

"; -#endif - sprintf (hres->content_buf, - "\n" - "\n" - " \n" - " YAZ " YAZ_VERSION "\n" - " \n" - " \n" - "

YAZ " - YAZ_VERSION "

\n" - "%s" - " \n" - "\n", doclink); - hres->content_len = strlen(hres->content_buf); - z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/html"); - } -#endif - - if (!p) - { - p = z_get_HTTP_Response(o, 404); - } - } - else if (!strcmp(hreq->method, "POST")) - { - const char *content_type = z_HTTP_header_lookup(hreq->headers, - "Content-Type"); - if (content_type && !yaz_strcmp_del("text/xml", content_type, "; ")) - { - Z_SOAP *soap_package = 0; - int ret = -1; - int http_code = 500; - const char *charset_p = 0; - char *charset = 0; - - static Z_SOAP_Handler soap_handlers[3] = { + else if (sr->which == Z_SRW_scan_request) + { + Z_SRW_PDU *res = yaz_srw_get(o, Z_SRW_scan_response); + stylesheet = sr->u.scan_request->stylesheet; + if (num_diagnostic) + { + res->u.scan_response->diagnostics = diagnostic; + res->u.scan_response->num_diagnostics = num_diagnostic; + } + yaz_add_srw_diagnostic(o, + &res->u.scan_response->diagnostics, + &res->u.scan_response->num_diagnostics, + 4, "scan"); + if (http_code == 200) + soap_package->u.generic->p = res; + } + else + { + yaz_log(LOG_LOG, "generate soap error"); + http_code = 500; + z_soap_error(assoc->encode, soap_package, + "SOAP-ENV:Client", "Bad method", 0); + } + if (http_code == 200 || http_code == 500) + { + static Z_SOAP_Handler soap_handlers[3] = { #if HAVE_XML2 - {"http://www.loc.gov/zing/srw/", 0, - (Z_SOAP_fun) yaz_srw_codec}, + {"http://www.loc.gov/zing/srw/", 0, + (Z_SOAP_fun) yaz_srw_codec}, {"http://www.loc.gov/zing/srw/v1.0/", 0, (Z_SOAP_fun) yaz_srw_codec}, #endif - {0, 0, 0} - }; - if ((charset_p = strstr(content_type, "; charset="))) - { - int i = 0; - charset_p += 10; - while (i < 20 && charset_p[i] && - !strchr("; \n\r", charset_p[i])) - i++; - charset = odr_malloc(assoc->encode, i+1); - memcpy(charset, charset_p, i); - charset[i] = '\0'; - yaz_log(LOG_LOG, "SOAP encoding %s", charset); - } - ret = z_soap_codec(assoc->decode, &soap_package, - &hreq->content_buf, &hreq->content_len, - soap_handlers); -#if HAVE_XML2 - if (!ret && soap_package->which == Z_SOAP_generic) - { - /* SRW package */ - char *db = "Default"; - const char *p0 = hreq->path, *p1; - Z_SRW_PDU *sr = soap_package->u.generic->p; - - if (*p0 == '/') - p0++; - p1 = strchr(p0, '?'); - if (!p1) - p1 = p0 + strlen(p0); - if (p1 != p0) - { - db = (char*) odr_malloc(assoc->decode, p1 - p0 + 1); - memcpy (db, p0, p1 - p0); - db[p1 - p0] = '\0'; - } - - if (sr->which == Z_SRW_searchRetrieve_request) - { - Z_SRW_PDU *res = - yaz_srw_get(assoc->encode, - Z_SRW_searchRetrieve_response); - - if (!sr->u.request->database) - sr->u.request->database = db; - - if (soap_package->u.generic->no == 1) /* SRW 1.0 */ - res->srw_version = 0; - - srw_bend_search(assoc, req, sr->u.request, - res->u.response, &http_code); - - soap_package->u.generic->p = res; - } - else if (sr->which == Z_SRW_explain_request) - { - Z_SRW_PDU *res = - yaz_srw_get(assoc->encode, Z_SRW_explain_response); - sr->u.explain_request->database = db; - - if (soap_package->u.generic->no == 1) /* SRW 1.0 */ - res->srw_version = 0; - - srw_bend_explain(assoc, req, sr->u.explain_request, - res->u.explain_response, &http_code); - if (http_code == 200) - soap_package->u.generic->p = res; - } - else - { - z_soap_error(assoc->encode, soap_package, - "SOAP-ENV:Client", "Bad method", 0); - } + {0, 0, 0} + }; + char ctype[60]; + int ret; + p = z_get_HTTP_Response(o, 200); + hres = p->u.HTTP_Response; + ret = z_soap_codec_enc_xsl(assoc->encode, &soap_package, + &hres->content_buf, &hres->content_len, + soap_handlers, charset, stylesheet); + hres->code = http_code; - } -#endif - if (http_code == 200 || http_code == 500) + strcpy(ctype, "text/xml"); + if (charset) { - p = z_get_HTTP_Response(o, 200); - hres = p->u.HTTP_Response; - ret = z_soap_codec_enc(assoc->encode, &soap_package, - &hres->content_buf, &hres->content_len, - soap_handlers, charset); - hres->code = http_code; - if (!charset) - z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/xml"); - else - { - char ctype[60]; - strcpy(ctype, "text/xml; charset="); - strcat(ctype, charset); - z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype); - } + strcat(ctype, "; charset="); + strcat(ctype, charset); } - else - p = z_get_HTTP_Response(o, http_code); - } - if (!p) /* still no response ? */ - p = z_get_HTTP_Response(o, 500); + z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype); + } + else + p = z_get_HTTP_Response(o, http_code); } - else - { - p = z_get_HTTP_Response(o, 405); - hres = p->u.HTTP_Response; - z_HTTP_header_add(o, &hres->headers, "Allow", "GET, POST"); - } + if (p == 0) + p = z_get_HTTP_Response(o, 500); hres = p->u.HTTP_Response; if (!strcmp(hreq->version, "1.0")) { @@ -1166,6 +921,7 @@ static void process_http_request(association *assoc, request *req) { z_HTTP_header_add(o, &hres->headers, "Connection", "close"); assoc->state = ASSOC_DEAD; + assoc->cs_get_mask = 0; } else { @@ -1437,10 +1193,12 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) { Z_CharSetandLanguageNegotiation *negotiation = yaz_get_charneg_record (req->otherInfo); - if (negotiation->which == Z_CharSetandLanguageNegotiation_proposal) + if (negotiation && + negotiation->which == Z_CharSetandLanguageNegotiation_proposal) assoc->init->charneg_request = negotiation; } + assoc->backend = 0; if (!(binitres = (*cb->bend_init)(assoc->init))) { yaz_log(LOG_WARN, "Bad response from backend."); @@ -1531,7 +1289,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_1)) { ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_1); - assoc->version = 2; /* 1 & 2 are equivalent */ + assoc->version = 1; /* 1 & 2 are equivalent */ } if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_2)) { @@ -1563,7 +1321,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) assoc->init->implementation_name, odr_prepend(assoc->encode, "GFS", resp->implementationName)); - version = odr_strdup(assoc->encode, "$Revision: 1.12 $"); + version = odr_strdup(assoc->encode, "$Revision: 1.24 $"); if (strlen(version) > 10) /* check for unexpanded CVS strings */ version[strlen(version)-2] = '\0'; resp->implementationVersion = odr_prepend(assoc->encode, @@ -1658,6 +1416,7 @@ static Z_External *init_diagnostics(ODR odr, int error, char *addinfo) e->which = Z_DiagnosticFormat_s_defaultDiagRec; e->u.defaultDiagRec = justdiag(odr, error, addinfo); + e->message = 0; return x; } @@ -1740,7 +1499,7 @@ static Z_Records *pack_records(association *a, char *setname, int start, records->u.databaseOrSurDiagnostics = reclist; reclist->num_records = 0; reclist->records = list; - *pres = Z_PRES_SUCCESS; + *pres = Z_PresentStatus_success; *num = 0; *next = 0; @@ -1784,7 +1543,7 @@ static Z_Records *pack_records(association *a, char *setname, int start, if (!freq.surrogate_flag) { char s[20]; - *pres = Z_PRES_FAILURE; + *pres = Z_PresentStatus_failure; /* for 'present request out of range', set addinfo to record position if not set */ if (freq.errcode == 13 && freq.errstring == 0) @@ -1807,13 +1566,14 @@ static Z_Records *pack_records(association *a, char *setname, int start, this_length = odr_total(a->encode) - total_length - dumped_records; yaz_log(LOG_DEBUG, " fetched record, len=%d, total=%d dumped=%d", this_length, total_length, dumped_records); - if (this_length + total_length > a->preferredMessageSize) + if (a->preferredMessageSize > 0 && + this_length + total_length > a->preferredMessageSize) { /* record is small enough, really */ if (this_length <= a->preferredMessageSize && recno > start) { yaz_log(LOG_DEBUG, " Dropped last normal-sized record"); - *pres = Z_PRES_PARTIAL_2; + *pres = Z_PresentStatus_partial_2; break; } /* record can only be fetched by itself */ @@ -1933,7 +1693,7 @@ static Z_APDU *response_searchRequest(association *assoc, request *reqb, int *nulint = odr_intdup (assoc->encode, 0); bool_t *sr = odr_intdup(assoc->encode, 1); int *next = odr_intdup(assoc->encode, 0); - int *none = odr_intdup(assoc->encode, Z_RES_NONE); + int *none = odr_intdup(assoc->encode, Z_SearchResponse_none); apdu->which = Z_APDU_searchResponse; apdu->u.searchResponse = resp; @@ -2079,7 +1839,7 @@ static Z_APDU *process_presentRequest(association *assoc, request *reqb, if (bprr->errcode) { resp->records = diagrec(assoc, bprr->errcode, bprr->errstring); - *resp->presentStatus = Z_PRES_FAILURE; + *resp->presentStatus = Z_PresentStatus_failure; } } apdu = (Z_APDU *)odr_malloc (assoc->encode, sizeof(*apdu)); @@ -2293,7 +2053,7 @@ static Z_APDU *process_sortRequest(association *assoc, request *reqb, bsrr->stream = assoc->encode; bsrr->print = assoc->print; - bsrr->sort_status = Z_SortStatus_failure; + bsrr->sort_status = Z_SortResponse_failure; bsrr->errcode = 0; bsrr->errstring = 0;