X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fsrwutil.c;h=47af17829cea89fa4fb0e7612b42f159e0dcfda0;hp=581c00d53a4008ef5588eb898ec7ee8c7e377daf;hb=8dc67a9430644549801c18ec7e3a725e5a4ef782;hpb=b462b5047a365a76a5be26341e62b69076a33d3a diff --git a/src/srwutil.c b/src/srwutil.c index 581c00d..47af178 100644 --- a/src/srwutil.c +++ b/src/srwutil.c @@ -2,7 +2,7 @@ * Copyright (c) 2002-2004, Index Data. * See the file LICENSE for details. * - * $Id: srwutil.c,v 1.6 2004-01-07 20:36:44 adam Exp $ + * $Id: srwutil.c,v 1.15 2004-03-24 10:14:24 adam Exp $ */ #include @@ -19,6 +19,65 @@ static int hex_digit (int ch) return 0; } +int yaz_uri_array(const char *path, ODR o, char ***name, char ***val) +{ + int no = 2; + const char *cp; + *name = 0; + if (*path != '?') + return no; + path++; + cp = path; + while ((cp = strchr(cp, '&'))) + { + cp++; + no++; + } + *name = odr_malloc(o, no * sizeof(char**)); + *val = odr_malloc(o, no * sizeof(char**)); + + for (no = 0; *path; no++) + { + const char *p1 = strchr(path, '='); + size_t i = 0; + char *ret; + if (!p1) + break; + + (*name)[no] = odr_malloc(o, (p1-path)+1); + memcpy((*name)[no], path, p1-path); + (*name)[no][p1-path] = '\0'; + + path = p1 + 1; + p1 = strchr(path, '&'); + if (!p1) + p1 = strlen(path) + path; + (*val)[no] = 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'; + + if (*path) + path++; + } + (*name)[no] = 0; + (*val)[no] = 0; + return no; +} + char *yaz_uri_val(const char *path, const char *name, ODR o) { size_t nlen = strlen(name); @@ -72,6 +131,31 @@ void yaz_uri_val_int(const char *path, const char *name, ODR o, int **intp) *intp = odr_intdup(o, atoi(v)); } +void yaz_mk_std_diagnostic(ODR o, Z_SRW_diagnostic *d, + int code, const char *details) +{ + d->uri = (char *) odr_malloc(o, 50); + sprintf(d->uri, "info:srw/diagnostic/1/%d", code); + d->message = 0; + if (details) + d->details = odr_strdup(o, details); + else + d->details = 0; +} + +void yaz_add_srw_diagnostic(ODR o, Z_SRW_diagnostic **d, + int *num, int code, const char *addinfo) +{ + Z_SRW_diagnostic *d_new; + d_new = (Z_SRW_diagnostic *) odr_malloc (o, (*num + 1)* sizeof(**d)); + if (*num) + memcpy (d_new, *d, *num *sizeof(**d)); + *d = d_new; + + yaz_mk_std_diagnostic(o, *d + *num, code, addinfo); + (*num)++; +} + int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, Z_SOAP **soap_package, ODR decode, char **charset) { @@ -147,7 +231,8 @@ int yaz_srw_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, } int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, - Z_SOAP **soap_package, ODR decode, char **charset) + Z_SOAP **soap_package, ODR decode, char **charset, + Z_SRW_diagnostic **diag, int *num_diag) { #if HAVE_XML2 static Z_SOAP_Handler soap_handlers[2] = { @@ -161,10 +246,20 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, char *db = "Default"; const char *p0 = hreq->path, *p1; const char *operation = 0; + char *version = 0; char *query = 0; char *pQuery = 0; + char *sortKeys = 0; char *stylesheet = 0; - + char *scanClause = 0; + char *recordXPath = 0; + char *recordSchema = 0; + char *recordPacking = "xml"; /* xml packing is default for SRU */ + char *maximumRecords = 0; + char *startRecord = 0; + char **uri_name; + char **uri_val; + if (charset) *charset = 0; if (*p0 == '/') @@ -178,45 +273,87 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, memcpy (db, p0, p1 - p0); db[p1 - p0] = '\0'; } + yaz_uri_array(p1, decode, &uri_name, &uri_val); #if HAVE_XML2 - query = yaz_uri_val(p1, "query", decode); - pQuery = yaz_uri_val(p1, "pQuery", decode); - operation = yaz_uri_val(p1, "operation", decode); - stylesheet = yaz_uri_val(p1, "stylesheet", decode); + if (uri_name) + { + int i; + for (i = 0; uri_name[i]; i++) + { + char *n = uri_name[i]; + char *v = uri_val[i]; + if (!strcmp(n, "query")) + query = v; + else if (!strcmp(n, "x-pquery")) + pQuery = v; + else if (!strcmp(n, "operation")) + operation = v; + else if (!strcmp(n, "stylesheet")) + stylesheet = v; + else if (!strcmp(n, "sortKeys")) + sortKeys = v; + else if (!strcmp(n, "recordXPath")) + recordXPath = v; + else if (!strcmp(n, "recordSchema")) + recordSchema = v; + else if (!strcmp(n, "recordPacking")) + recordPacking = v; + else if (!strcmp(n, "version")) + version = v; + else if (!strcmp(n, "scanClause")) + scanClause = v; + else if (!strcmp(n, "maximumRecords")) + maximumRecords = v; + else if (!strcmp(n, "startRecord")) + startRecord = v; + else + yaz_add_srw_diagnostic(decode, diag, num_diag, 8, n); + } + } + if (!version) + yaz_add_srw_diagnostic(decode, diag, num_diag, 7, "version"); + else if (version && strcmp(version, "1.1")) + yaz_add_srw_diagnostic(decode, diag, num_diag, 5, "1.1"); if (!operation) + { + yaz_add_srw_diagnostic(decode, diag, num_diag, 7, "operation"); operation = "explain"; - if ((operation && !strcmp(operation, "searchRetrieve")) - || pQuery || query) + } + if (!strcmp(operation, "searchRetrieve")) { Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_searchRetrieve_request); - char *sortKeys = yaz_uri_val(p1, "sortKeys", decode); - + + sr->srw_version = version; *srw_pdu = sr; if (query) { sr->u.request->query_type = Z_SRW_query_type_cql; sr->u.request->query.cql = query; } - if (pQuery) + else if (pQuery) { sr->u.request->query_type = Z_SRW_query_type_pqf; sr->u.request->query.pqf = pQuery; } + else + yaz_add_srw_diagnostic(decode, diag, num_diag, 7, "query"); + 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", decode); - sr->u.request->recordPacking = yaz_uri_val(p1, "recordPacking", decode); + sr->u.request->recordXPath = recordXPath; + sr->u.request->recordSchema = recordSchema; + sr->u.request->recordPacking = recordPacking; sr->u.request->stylesheet = stylesheet; - if (!sr->u.request->recordPacking) - sr->u.request->recordPacking = "xml"; - yaz_uri_val_int(p1, "maximumRecords", decode, - &sr->u.request->maximumRecords); - yaz_uri_val_int(p1, "startRecord", decode, - &sr->u.request->startRecord); + if (maximumRecords) + sr->u.request->maximumRecords = + odr_intdup(decode, atoi(maximumRecords)); + if (startRecord) + sr->u.request->startRecord = + odr_intdup(decode, atoi(startRecord)); sr->u.request->database = db; @@ -234,15 +371,13 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, return 0; } - else if (p1 && !strcmp(operation, "explain")) + else if (!strcmp(operation, "explain")) { Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request); + sr->srw_version = version; *srw_pdu = sr; - sr->u.explain_request->recordPacking = - yaz_uri_val(p1, "recordPacking", decode); - if (!sr->u.explain_request->recordPacking) - sr->u.explain_request->recordPacking = "xml"; + sr->u.explain_request->recordPacking = recordPacking; sr->u.explain_request->database = db; sr->u.explain_request->stylesheet = stylesheet; @@ -261,6 +396,62 @@ int yaz_sru_decode(Z_HTTP_Request *hreq, Z_SRW_PDU **srw_pdu, return 0; } + else if (!strcmp(operation, "scan")) + { + Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_scan_request); + + if (!scanClause) + yaz_add_srw_diagnostic(decode, diag, num_diag, 7, + "scanClause"); + sr->srw_version = version; + *srw_pdu = sr; + sr->u.scan_request->scanClause = scanClause; + sr->u.scan_request->database = db; + sr->u.scan_request->stylesheet = stylesheet; + + (*soap_package) = odr_malloc(decode, sizeof(**soap_package)); + (*soap_package)->which = Z_SOAP_generic; + + (*soap_package)->u.generic = + odr_malloc(decode, sizeof(*(*soap_package)->u.generic)); + + (*soap_package)->u.generic->p = sr; + (*soap_package)->u.generic->ns = soap_handlers[0].ns; + (*soap_package)->u.generic->no = 0; + + (*soap_package)->ns = "SRU"; + + return 0; + } + else + { + /* unsupported operation ... */ + /* Act as if we received a explain request and throw diagnostic. */ + + Z_SRW_PDU *sr = yaz_srw_get(decode, Z_SRW_explain_request); + + sr->srw_version = version; + *srw_pdu = sr; + sr->u.explain_request->recordPacking = recordPacking; + sr->u.explain_request->database = db; + + sr->u.explain_request->stylesheet = stylesheet; + + (*soap_package) = odr_malloc(decode, sizeof(**soap_package)); + (*soap_package)->which = Z_SOAP_generic; + + (*soap_package)->u.generic = + odr_malloc(decode, sizeof(*(*soap_package)->u.generic)); + + (*soap_package)->u.generic->p = sr; + (*soap_package)->u.generic->ns = soap_handlers[0].ns; + (*soap_package)->u.generic->no = 0; + + (*soap_package)->ns = "SRU"; + + yaz_add_srw_diagnostic(decode, diag, num_diag, 4, operation); + return 0; + } #endif return 1; } @@ -321,6 +512,23 @@ Z_SRW_PDU *yaz_srw_get(ODR o, int which) Z_SRW_recordPacking_string; sr->u.explain_response->diagnostics = 0; sr->u.explain_response->num_diagnostics = 0; + break; + case Z_SRW_scan_request: + sr->u.scan_request = (Z_SRW_scanRequest *) + odr_malloc(o, sizeof(*sr->u.scan_request)); + sr->u.scan_request->database = 0; + sr->u.scan_request->stylesheet = 0; + sr->u.scan_request->maximumTerms = 0; + sr->u.scan_request->responsePosition = 0; + sr->u.scan_request->scanClause = 0; + break; + case Z_SRW_scan_response: + sr->u.scan_response = (Z_SRW_scanResponse *) + odr_malloc(o, sizeof(*sr->u.scan_response)); + sr->u.scan_response->terms = 0; + sr->u.scan_response->num_terms = 0; + sr->u.scan_response->diagnostics = 0; + sr->u.scan_response->num_diagnostics = 0; } return sr; } @@ -333,22 +541,27 @@ static struct { {1, "Permanent system error"}, {2, "System temporarily unavailable"}, {3, "Authentication error"}, +{4, "Unsupported operation"}, +{5, "Unsupported version"}, +{6, "Unsupported parameter value"}, +{7, "Mandatory parameter not supplied"}, +{8, "Unsupported parameter"}, /* Diagnostics Relating to CQL */ {10, "Query syntax error"}, {11, "Unsupported query type"}, {12, "Too many characters in query"}, -{13, "Unbalanced or illegal use of parentheses"}, -{14, "Unbalanced or illegal use of quotes"}, -{15, "Illegal or unsupported context set"}, -{16, "Illegal or unsupported index"}, -{17, "Illegal or unsupported combination of index and context set"}, -{18, "Illegal or unsupported combination of indexes"}, -{19, "Illegal or unsupported relation"}, -{20, "Illegal or unsupported relation modifier"}, -{21, "Illegal or unsupported combination of relation modifers"}, -{22, "Illegal or unsupported combination of relation and index"}, +{13, "Invalid or unsupported use of parentheses"}, +{14, "Invalid or unsupported use of quotes"}, +{15, "Unsupported context set"}, +{16, "Unsupported index"}, +{17, "Unsupported combination of index and context set"}, +{18, "Unsupported combination of indexes"}, +{19, "Unsupported relation"}, +{20, "Unsupported relation modifier"}, +{21, "Unsupported combination of relation modifers"}, +{22, "Unsupported combination of relation and index"}, {23, "Too many characters in term"}, -{24, "Illegal combination of relation and term"}, +{24, "Unsupported combination of relation and term"}, {25, "Special characters not quoted in term"}, {26, "Non special character escaped in term"}, {27, "Empty term unsupported"}, @@ -356,19 +569,19 @@ static struct { {29, "Masked words too short"}, {30, "Too many masking characters in term"}, {31, "Anchoring character not supported"}, -{32, "Anchoring character in illegal or unsupported position"}, +{32, "Anchoring character in unsupported position"}, {33, "Combination of proximity/adjacency and masking characters not supported"}, {34, "Combination of proximity/adjacency and anchoring characters not supported"}, -{35, "Terms only exclusion (stop) words"}, +{35, "Terms only exclusion stopwords"}, {36, "Term in invalid format for index or relation"}, -{37, "Illegal or unsupported boolean operator"}, +{37, "Unsupported boolean operator"}, {38, "Too many boolean operators in query"}, {39, "Proximity not supported"}, -{40, "Illegal or unsupported proximity relation"}, -{41, "Illegal or unsupported proximity distance"}, -{42, "Illegal or unsupported proximity unit"}, -{43, "Illegal or unsupported proximity ordering"}, -{44, "Illegal or unsupported combination of proximity modifiers"}, +{40, "Unsupported proximity relation"}, +{41, "Unsupported proximity distance"}, +{42, "Unsupported proximity unit"}, +{43, "Unsupported proximity ordering"}, +{44, "Unsupported combination of proximity modifiers"}, {45, "context set name (prefix) assigned to multiple identifiers"}, /* Diagnostics Relating to Result Sets */ {50, "Result sets not supported"}, @@ -382,7 +595,7 @@ static struct { {58, "Result set created with unpredictable partial results available"}, {59, "Result set created with valid partial results available"}, /* Diagnostics Relating to Records */ -{60, "Too many records retrieved"}, +{60, "Result set no created: too many records retrieved"}, {61, "First record position out of range"}, {62, "Negative number of records requested"}, {63, "System error in retrieving records"}, @@ -393,24 +606,33 @@ static struct { {68, "Not authorised to send record"}, {69, "Not authorised to send record in this schema"}, {70, "Record too large to send"}, +{71, "Unsupported record packing"}, +{72, "XPath retrieval unsupported"}, +{73, "XPath expression contains unsupported feature"}, +{74, "Unable to evaluate XPath expression"}, /* Diagnostics Relating to Sorting */ {80, "Sort not supported"}, -{81, "Unsupported sort type (sortKeys vs xSortKeys)"}, -{82, "Illegal or unsupported sort sequence"}, -{83, "Too many records"}, -{84, "Too many sort keys"}, +{81, "Unsupported sort type"}, +{82, "Unsupported sort sequence"}, +{83, "Too many records to sort"}, +{84, "Too many sort keys to sort"}, {85, "Duplicate sort keys"}, -{86, "Incompatible record formats"}, +{86, "Cannot sort: incompatible record formats"}, {87, "Unsupported schema for sort"}, -{88, "Unsupported tag path for sort"}, -{89, "Tag path illegal or unsupported for schema"}, -{90, "Illegal or unsupported direction value"}, -{91, "Illegal or unsupported case value"}, -{92, "Illegal or unsupported missing value action"}, +{88, "Unsupported path for sort"}, +{89, "Path unsupported for schema"}, +{90, "Unsupported direction value"}, +{91, "Unsupported case value"}, +{92, "Unsupported missing value action"}, /* Diagnostics Relating to Explain */ {100, "Explain not supported"}, {101, "Explain request type not supported (SOAP vs GET)"}, {102, "Explain record temporarily unavailable"}, +/* Diagnostics Relating to Stylesheets */ +{110, "Stylesheets not supported"}, +{111, "Unsupported stylesheet"}, +/* Diagnostics relating to Scan */ +{120, "Response position out of range"}, {0, 0} }; @@ -473,7 +695,6 @@ static int srw_bib1_map[] = { 105, 3, 106, 66, 107, 11, - 108, 10, 108, 13, 108, 14, 108, 25, @@ -481,7 +702,7 @@ static int srw_bib1_map[] = { 108, 27, 108, 45, - 109, 1, + 109, 2, 110, 37, 111, 1, 112, 58, @@ -490,6 +711,7 @@ static int srw_bib1_map[] = { 115, 16, 116, 16, 117, 19, + 117, 20, 118, 22, 119, 32, 119, 31,