X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fseshigh.c;h=cc5f47d5f95eb91f3a6ff8e5474c1fe4c9f6ff95;hb=037037e14faa1f992ed3574817086eabc469c9c4;hp=40d40494952a01fca37b40b1381091c758cef504;hpb=7330ea6fe4f984d5bd0498aa7e962ad4d7462916;p=yaz-moved-to-github.git diff --git a/src/seshigh.c b/src/seshigh.c index 40d4049..cc5f47d 100644 --- a/src/seshigh.c +++ b/src/seshigh.c @@ -2,7 +2,7 @@ * Copyright (c) 1995-2003, Index Data * See the file LICENSE for details. * - * $Id: seshigh.c,v 1.2 2003-11-17 21:32:58 mike Exp $ + * $Id: seshigh.c,v 1.9 2003-12-29 14:54:33 adam Exp $ */ /* @@ -546,12 +546,14 @@ static int srw_bend_fetch(association *assoc, int pos, static void srw_bend_search(association *assoc, request *req, Z_SRW_searchRetrieveRequest *srw_req, - Z_SRW_searchRetrieveResponse *srw_res) + Z_SRW_searchRetrieveResponse *srw_res, + int *http_code) { int srw_error = 0; bend_search_rr rr; Z_External *ext; + *http_code = 200; yaz_log(LOG_LOG, "Got SRW SearchRetrieveRequest"); yaz_log(LOG_DEBUG, "srw_bend_search"); if (!assoc->init) @@ -654,6 +656,11 @@ static void srw_bend_search(association *assoc, request *req, if (rr.errcode) { yaz_log(LOG_DEBUG, "bend_search returned Bib-1 code %d", rr.errcode); + if (rr.errcode == 109) /* database unavailable */ + { + *http_code = 404; + return; + } srw_res->num_diagnostics = 1; srw_res->diagnostics = (Z_SRW_diagnostic *) odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics)); @@ -726,17 +733,20 @@ static void srw_bend_search(association *assoc, request *req, } } - static void srw_bend_explain(association *assoc, request *req, Z_SRW_explainRequest *srw_req, - Z_SRW_explainResponse *srw_res) + Z_SRW_explainResponse *srw_res, + int *http_code) { yaz_log(LOG_LOG, "Got SRW ExplainRequest"); + *http_code = 404; if (!assoc->init) { yaz_log(LOG_DEBUG, "srw_bend_init"); if (!srw_bend_init(assoc)) + { return; + } } if (assoc->init && assoc->init->bend_explain) { @@ -746,77 +756,22 @@ static void srw_bend_explain(association *assoc, request *req, rr.decode = assoc->decode; rr.print = assoc->print; rr.explain_buf = 0; + rr.database = srw_req->database; (*assoc->init->bend_explain)(assoc->backend, &rr); if (rr.explain_buf) { - srw_res->explainData_buf = rr.explain_buf; - srw_res->explainData_len = strlen(rr.explain_buf); - } - } -} - -static int hex_digit (int ch) -{ - if (ch >= '0' && ch <= '9') - return ch - '0'; - else if (ch >= 'a' && ch <= 'f') - return ch - 'a'+10; - else if (ch >= 'A' && ch <= 'F') - return ch - 'A'+10; - return 0; -} - -static char *uri_val(const char *path, const char *name, ODR o) -{ - size_t nlen = strlen(name); - if (*path != '?') - return 0; - path++; - while (path && *path) - { - const char *p1 = strchr(path, '='); - if (!p1) - break; - if ((size_t)(p1 - path) == nlen && !memcmp(path, name, nlen)) - { - size_t i = 0; - char *ret; - - path = p1 + 1; - p1 = strchr(path, '&'); - if (!p1) - p1 = strlen(path) + path; - ret = odr_malloc(o, p1 - path + 1); - while (*path && *path != '&') - { - if (*path == '+') - { - ret[i++] = ' '; - path++; - } - else if (*path == '%' && path[1] && path[2]) - { - ret[i++] = hex_digit (path[1])*16 + hex_digit (path[2]); - path = path + 3; - } - else - ret[i++] = *path++; - } - ret[i] = '\0'; - return ret; + int packing = Z_SRW_recordPacking_string; + if (srw_req->recordPacking && + !strcmp(srw_req->recordPacking, "xml")) + packing = Z_SRW_recordPacking_XML; + srw_res->record.recordSchema = 0; + srw_res->record.recordPacking = packing; + srw_res->record.recordData_buf = rr.explain_buf; + srw_res->record.recordData_len = strlen(rr.explain_buf); + srw_res->record.recordPosition = 0; + *http_code = 200; } - path = strchr(p1, '&'); - if (path) - path++; } - return 0; -} - -void uri_val_int(const char *path, const char *name, ODR o, int **intp) -{ - const char *v = uri_val(path, name, o); - if (v) - *intp = odr_intdup(o, atoi(v)); } static void process_http_request(association *assoc, request *req) @@ -831,17 +786,17 @@ static void process_http_request(association *assoc, request *req) { 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/v1.0/", 0, + {"http://www.loc.gov/zing/srw/", 0, (Z_SOAP_fun) yaz_srw_codec}, {0, 0, 0} }; #endif - if (*p0 == '/') p0++; p1 = strchr(p0, '?'); @@ -853,14 +808,19 @@ static void process_http_request(association *assoc, request *req) 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 && *p1 == '?' && p1[1]) + 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 = uri_val(p1, "query", o); - char *pQuery = uri_val(p1, "pQuery", o); - char *sortKeys = uri_val(p1, "sortKeys", o); + 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) { @@ -877,18 +837,17 @@ static void process_http_request(association *assoc, request *req) sr->u.request->sort_type = Z_SRW_sort_type_sort; sr->u.request->sort.sortKeys = sortKeys; } - sr->u.request->recordSchema = uri_val(p1, "recordSchema", o); - sr->u.request->recordPacking = uri_val(p1, "recordPacking", o); + 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"; - uri_val_int(p1, "maximumRecords", o, + yaz_uri_val_int(p1, "maximumRecords", o, &sr->u.request->maximumRecords); - uri_val_int(p1, "startRecord", o, + yaz_uri_val_int(p1, "startRecord", o, &sr->u.request->startRecord); - if (sr->u.request->startRecord) - yaz_log(LOG_LOG, "startRecord=%d", *sr->u.request->startRecord); sr->u.request->database = db; - srw_bend_search(assoc, req, sr->u.request, res->u.response); + 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; @@ -902,32 +861,41 @@ static void process_http_request(association *assoc, request *req) 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); - } - + p = z_get_HTTP_Response(o, http_code); + if (http_code == 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); + } + } } - else + else if (p1 && !strcmp(operation, "explain")) { 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); + res->u.explain_response, &http_code); - if (res->u.explain_response->explainData_buf) + if (res->u.explain_response->record.recordData_buf) { soap_package = odr_malloc(o, sizeof(*soap_package)); soap_package->which = Z_SOAP_generic; @@ -1062,7 +1030,7 @@ static void process_http_request(association *assoc, request *req) static Z_SOAP_Handler soap_handlers[2] = { #if HAVE_XML2 - {"http://www.loc.gov/zing/srw/v1.0/", 0, + {"http://www.loc.gov/zing/srw/", 0, (Z_SOAP_fun) yaz_srw_codec}, #endif {0, 0, 0} @@ -1087,8 +1055,22 @@ static void process_http_request(association *assoc, request *req) soap_package->u.generic->no == 0) { /* 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 = @@ -1096,46 +1078,23 @@ static void process_http_request(association *assoc, request *req) Z_SRW_searchRetrieve_response); if (!sr->u.request->database) - { - const char *p0 = hreq->path, *p1; - if (*p0 == '/') - p0++; - p1 = strchr(p0, '?'); - if (!p1) - p1 = p0 + strlen(p0); - if (p1 != p0) - { - sr->u.request->database = - odr_malloc(assoc->decode, p1 - p0 + 1); - memcpy (sr->u.request->database, p0, p1 - p0); - sr->u.request->database[p1 - p0] = '\0'; - } - else - sr->u.request->database = "Default"; - } + sr->u.request->database = db; + srw_bend_search(assoc, req, sr->u.request, - res->u.response); + res->u.response, &http_code); soap_package->u.generic->p = res; - http_code = 200; } 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; srw_bend_explain(assoc, req, sr->u.explain_request, - res->u.explain_response); - if (!res->u.explain_response->explainData_buf) - { - z_soap_error(assoc->encode, soap_package, - "SOAP-ENV:Client", "Explain Not Supported", 0); - } - else - { + res->u.explain_response, &http_code); + if (http_code == 200) soap_package->u.generic->p = res; - http_code = 200; - } } else { @@ -1144,21 +1103,26 @@ static void process_http_request(association *assoc, request *req) } } #endif - 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); - } + if (http_code == 200 || http_code == 500) + { + 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); + } + } + else + p = z_get_HTTP_Response(o, http_code); } if (!p) /* still no response ? */ p = z_get_HTTP_Response(o, 500); @@ -1443,7 +1407,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) Z_APDU *apdu = zget_APDU(assoc->encode, Z_APDU_initResponse); Z_InitResponse *resp = apdu->u.initResponse; bend_initresult *binitres; - + char *version; char options[140]; yaz_log(LOG_LOG, "Got initRequest"); @@ -1581,41 +1545,21 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) resp->preferredMessageSize = &assoc->preferredMessageSize; resp->maximumRecordSize = &assoc->maximumRecordSize; - resp->implementationName = "GFS/YAZ"; + resp->implementationId = odr_prepend(assoc->encode, + assoc->init->implementation_id, + resp->implementationId); - if (assoc->init->implementation_id) - { - char *nv = (char *) - odr_malloc (assoc->encode, - strlen(assoc->init->implementation_id) + 10 + - strlen(resp->implementationId)); - sprintf (nv, "%s/%s", - assoc->init->implementation_id, - resp->implementationId); - resp->implementationId = nv; - } - if (assoc->init->implementation_name) - { - char *nv = (char *) - odr_malloc (assoc->encode, - strlen(assoc->init->implementation_name) + 10 + - strlen(resp->implementationName)); - sprintf (nv, "%s/%s", - assoc->init->implementation_name, - resp->implementationName); - resp->implementationName = nv; - } - if (assoc->init->implementation_version) - { - char *nv = (char *) - odr_malloc (assoc->encode, - strlen(assoc->init->implementation_version) + 10 + - strlen(resp->implementationVersion)); - sprintf (nv, "%s/YAZ %s", - assoc->init->implementation_version, - resp->implementationVersion); - resp->implementationVersion = nv; - } + resp->implementationName = odr_prepend(assoc->encode, + assoc->init->implementation_name, + odr_prepend(assoc->encode, "GFS", resp->implementationName)); + + version = odr_strdup(assoc->encode, "$Revision: 1.9 $"); + if (strlen(version) > 10) /* check for unexpanded CVS strings */ + version[strlen(version)-2] = '\0'; + resp->implementationVersion = odr_prepend(assoc->encode, + assoc->init->implementation_version, + odr_prepend(assoc->encode, &version[11], + resp->implementationVersion)); if (binitres->errcode) { @@ -1850,13 +1794,13 @@ static Z_Records *pack_records(association *a, char *setname, int start, if (freq.len >= 0) this_length = freq.len; else - this_length = odr_total(a->encode) - total_length; - yaz_log(LOG_DEBUG, " fetched record, len=%d, total=%d", - this_length, total_length); + 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) { /* record is small enough, really */ - if (this_length <= a->preferredMessageSize) + if (this_length <= a->preferredMessageSize && recno > start) { yaz_log(LOG_DEBUG, " Dropped last normal-sized record"); *pres = Z_PRES_PARTIAL_2; @@ -1946,6 +1890,7 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb, bsrr->basenames = req->databaseNames; bsrr->query = req->query; bsrr->stream = assoc->encode; + nmem_transfer(bsrr->stream->mem, reqb->request_mem); bsrr->decode = assoc->decode; bsrr->print = assoc->print; bsrr->errcode = 0;