X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fseshigh.c;h=93d8bc3340cccb0c00a8a5d6f0146529b83f6b82;hb=9a32992b1041bf622fdc4825262f5f7110494cce;hp=880cad3a3d3cb83b773a0dcdea9f5ceba8b9c759;hpb=a38648255b03b429e900f150cdf59eec987a7371;p=yaz-moved-to-github.git
diff --git a/src/seshigh.c b/src/seshigh.c
index 880cad3..93d8bc3 100644
--- a/src/seshigh.c
+++ b/src/seshigh.c
@@ -1,11 +1,13 @@
/*
- * Copyright (c) 1995-2003, Index Data
+ * Copyright (c) 1995-2004, Index Data
* See the file LICENSE for details.
*
- * $Id: seshigh.c,v 1.3 2003-11-26 22:47:42 mike Exp $
+ * $Id: seshigh.c,v 1.33 2004-10-15 00:19:00 adam Exp $
*/
-
-/*
+/**
+ * \file seshigh.c
+ * \brief Implements GFS session logic.
+ *
* Frontend server logic.
*
* This code receives incoming APDUs, and handles client requests by means
@@ -271,7 +273,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 =
@@ -353,10 +355,11 @@ void ir_session(IOCHAN h, int event)
return;
}
req->request_mem = odr_extract_mem(assoc->decode);
- if (assoc->print && !z_GDU(assoc->print, &req->gdu_request, 0, 0))
- {
- yaz_log(LOG_WARN, "ODR print error: %s",
- odr_errmsg(odr_geterror(assoc->print)));
+ if (assoc->print)
+ {
+ if (!z_GDU(assoc->print, &req->gdu_request, 0, 0))
+ yaz_log(LOG_WARN, "ODR print error: %s",
+ odr_errmsg(odr_geterror(assoc->print)));
odr_reset(assoc->print);
}
request_enq(&assoc->incoming, req);
@@ -470,6 +473,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.");
@@ -508,9 +512,22 @@ static int srw_bend_fetch(association *assoc, int pos,
rr.comp->u.complex->generic = (Z_Specification *)
odr_malloc(assoc->decode, sizeof(Z_Specification));
+
+ /* schema uri = recordSchema (or NULL if recordSchema is not given) */
rr.comp->u.complex->generic->which = Z_Schema_uri;
rr.comp->u.complex->generic->schema.uri = srw_req->recordSchema;
+
+ /* ESN = recordSchema if recordSchema is present */
rr.comp->u.complex->generic->elementSpec = 0;
+ if (srw_req->recordSchema)
+ {
+ rr.comp->u.complex->generic->elementSpec =
+ (Z_ElementSpec *) odr_malloc(assoc->encode, sizeof(Z_ElementSpec));
+ rr.comp->u.complex->generic->elementSpec->which =
+ Z_ElementSpec_elementSetName;
+ rr.comp->u.complex->generic->elementSpec->u.elementSetName =
+ srw_req->recordSchema;
+ }
rr.stream = assoc->encode;
rr.print = assoc->print;
@@ -531,7 +548,35 @@ static int srw_bend_fetch(association *assoc, int pos,
(*assoc->init->bend_fetch)(assoc->backend, &rr);
- if (rr.len >= 0)
+ if (rr.errcode && rr.surrogate_flag)
+ {
+ int code = yaz_diag_bib1_to_srw(rr.errcode);
+ const char *message = yaz_diag_srw_str(code);
+ int len = 200;
+ if (message)
+ len += strlen(message);
+ if (rr.errstring)
+ len += strlen(rr.errstring);
+
+ record->recordData_buf = odr_malloc(o, len);
+
+ sprintf(record->recordData_buf, "
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[2] = { + 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/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 && - soap_package->u.generic->no == 0) - { - /* SRW package */ - Z_SRW_PDU *sr = soap_package->u.generic->p; - - 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) - { - 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"; - } - srw_bend_search(assoc, req, sr->u.request, - res->u.response); - - 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); - - 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 - { - soap_package->u.generic->p = res; - http_code = 200; - } - } - else - { - z_soap_error(assoc->encode, soap_package, - "SOAP-ENV:Client", "Bad method", 0); - } - } -#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 (!p) /* still no response ? */ - p = z_get_HTTP_Response(o, 500); + {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; + + strcpy(ctype, "text/xml"); + if (charset) + { + strcat(ctype, "; charset="); + strcat(ctype, charset); + } + 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")) { @@ -1193,6 +969,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 { @@ -1304,6 +1081,8 @@ static int process_z_request(association *assoc, request *req, char **msg) return -1; } break; + case Z_APDU_triggerResourceControlRequest: + return 0; default: *msg = "Bad APDU received"; return -1; @@ -1382,10 +1161,11 @@ static int process_gdu_response(association *assoc, request *req, Z_GDU *res) { odr_setbuf(assoc->encode, req->response, req->size_response, 1); - if (assoc->print && !z_GDU(assoc->print, &res, 0, 0)) + if (assoc->print) { - yaz_log(LOG_WARN, "ODR print error: %s", - odr_errmsg(odr_geterror(assoc->print))); + if (!z_GDU(assoc->print, &res, 0, 0)) + yaz_log(LOG_WARN, "ODR print error: %s", + odr_errmsg(odr_geterror(assoc->print))); odr_reset(assoc->print); } if (!z_GDU(assoc->encode, &res, 0, 0)) @@ -1463,10 +1243,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."); @@ -1553,11 +1335,13 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb) ODR_MASK_SET(resp->options, Z_Options_negotiationModel); strcat(options, " negotiation"); } + + ODR_MASK_SET(resp->options, Z_Options_triggerResourceCtrl); 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)) { @@ -1589,7 +1373,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.3 $"); + version = odr_strdup(assoc->encode, "$Revision: 1.33 $"); if (strlen(version) > 10) /* check for unexpanded CVS strings */ version[strlen(version)-2] = '\0'; resp->implementationVersion = odr_prepend(assoc->encode, @@ -1684,6 +1468,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; } @@ -1766,7 +1551,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; @@ -1810,7 +1595,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) @@ -1830,16 +1615,17 @@ 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); - if (this_length + total_length > a->preferredMessageSize) + 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 (a->preferredMessageSize > 0 && + 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; + *pres = Z_PresentStatus_partial_2; break; } /* record can only be fetched by itself */ @@ -1926,6 +1712,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; @@ -1958,7 +1745,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; @@ -2104,7 +1891,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)); @@ -2318,7 +2105,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;