X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Futil.cpp;h=f23c00c5ad2c0c749b2098b65c39bae45408099e;hb=586d78659d671683f33ec55f4a7d32b28e345ccd;hp=6482063ce92fdb6d483cb389ddf804a25fbde359;hpb=d0123337d70b0fb97b578cc57467bb94980f1014;p=metaproxy-moved-to-github.git diff --git a/src/util.cpp b/src/util.cpp index 6482063..f23c00c 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,5 +1,5 @@ /* This file is part of Metaproxy. - Copyright (C) 2005-2009 Index Data + Copyright (C) Index Data Metaproxy is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -17,13 +17,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "config.hpp" -#include "util.hpp" +#include #include +#include #include #include #include #include +#include #include @@ -32,14 +34,14 @@ namespace mp = metaproxy_1; // Doxygen doesn't like mp::util, so we use this instead namespace mp_util = metaproxy_1::util; -const char * +const char * mp_util::record_composition_to_esn(Z_RecordComposition *comp) { if (comp && comp->which == Z_RecordComp_complex) { - if (comp->u.complex->generic + if (comp->u.complex->generic && comp->u.complex->generic->elementSpec - && (comp->u.complex->generic->elementSpec->which == + && (comp->u.complex->generic->elementSpec->which == Z_ElementSpec_elementSetName)) return comp->u.complex->generic->elementSpec->u.elementSetName; } @@ -51,26 +53,26 @@ mp_util::record_composition_to_esn(Z_RecordComposition *comp) -std::string mp_util::http_header_value(const Z_HTTP_Header* header, +std::string mp_util::http_header_value(const Z_HTTP_Header* header, const std::string name) { while (header && header->name && std::string(header->name) != name) header = header->next; - + if (header && header->name && std::string(header->name) == name && header->value) return std::string(header->value); - + return std::string(); } - + std::string mp_util::http_headers_debug(const Z_HTTP_Request &http_req) { std::string message("\n\n

" "Metaproxy SRUtoZ3950 filter" "

\n"); - + message += "

HTTP Info


\n"; message += "

\n"; message += "Method: " + std::string(http_req.method) + "
\n"; @@ -83,43 +85,43 @@ std::string mp_util::http_headers_debug(const Z_HTTP_Request &http_req) message += "Content-Length:" + mp_util::http_header_value(http_req.headers, "Content-Length") + "
\n"; - message += "

\n"; - + message += "

\n"; + message += "

Headers


\n"; - message += "

\n"; + message += "

\n"; Z_HTTP_Header* header = http_req.headers; while (header){ - message += "Header: " + message += "Header: " + std::string(header->name) + ": " + std::string(header->value) + "
\n"; header = header->next; } - message += "

\n"; + message += "

\n"; message += "\n\n"; return message; } -void mp_util::http_response(metaproxy_1::Package &package, - const std::string &content, +void mp_util::http_response(metaproxy_1::Package &package, + const std::string &content, int http_code) { - Z_GDU *zgdu_req = package.request().get(); - Z_GDU *zgdu_res = 0; + Z_GDU *zgdu_req = package.request().get(); + Z_GDU *zgdu_res = 0; mp::odr odr; - zgdu_res - = odr.create_HTTP_Response(package.session(), - zgdu_req->u.HTTP_Request, + zgdu_res + = odr.create_HTTP_Response(package.session(), + zgdu_req->u.HTTP_Request, http_code); - + zgdu_res->u.HTTP_Response->content_len = content.size(); - zgdu_res->u.HTTP_Response->content_buf + zgdu_res->u.HTTP_Response->content_buf = (char*) odr_malloc(odr, zgdu_res->u.HTTP_Response->content_len); - - strncpy(zgdu_res->u.HTTP_Response->content_buf, + + strncpy(zgdu_res->u.HTTP_Response->content_buf, content.c_str(), zgdu_res->u.HTTP_Response->content_len); - + //z_HTTP_header_add(odr, &hres->headers, // "Content-Type", content_type.c_str()); package.response() = zgdu_res; @@ -137,7 +139,7 @@ int mp_util::memcmp2(const void *buf1, int len1, return 1; else if (c < 0) return -1; - + // compare (remaining bytes) if (d > 0) return 1; @@ -161,11 +163,73 @@ std::string mp_util::database_name_normalize(const std::string &s) } +Z_RecordComposition *mp_util::piggyback_to_RecordComposition( + ODR odr, Odr_int result_set_size, Z_SearchRequest *sreq) +{ + Z_RecordComposition *comp = 0; + Odr_int present_dummy; + const char *element_set_name = 0; + mp::util::piggyback_sr(sreq, result_set_size, + present_dummy, &element_set_name); + if (element_set_name) + { + comp = (Z_RecordComposition *) odr_malloc(odr, sizeof(*comp)); + comp->which = Z_RecordComp_simple; + comp->u.simple = (Z_ElementSetNames *) + odr_malloc(odr, sizeof(Z_ElementSetNames)); + comp->u.simple->which = Z_ElementSetNames_generic; + comp->u.simple->u.generic = odr_strdup(odr, element_set_name); + } + return comp; +} + +void mp_util::piggyback_sr(Z_SearchRequest *sreq, + Odr_int result_set_size, + Odr_int &number_to_present, + const char **element_set_name) +{ + Z_ElementSetNames *esn; + const char *smallSetElementSetNames = 0; + const char *mediumSetElementSetNames = 0; + + esn = sreq->smallSetElementSetNames; + if (esn && esn->which == Z_ElementSetNames_generic) + smallSetElementSetNames = esn->u.generic; + + esn = sreq->mediumSetElementSetNames; + if (esn && esn->which == Z_ElementSetNames_generic) + mediumSetElementSetNames = esn->u.generic; + + piggyback(*sreq->smallSetUpperBound, + *sreq->largeSetLowerBound, + *sreq->mediumSetPresentNumber, + smallSetElementSetNames, + mediumSetElementSetNames, + result_set_size, + number_to_present, + element_set_name); +} + void mp_util::piggyback(int smallSetUpperBound, - int largeSetLowerBound, - int mediumSetPresentNumber, - int result_set_size, - int &number_to_present) + int largeSetLowerBound, + int mediumSetPresentNumber, + int result_set_size, + int &number_to_present) +{ + Odr_int tmp = number_to_present; + piggyback(smallSetUpperBound, largeSetLowerBound, mediumSetPresentNumber, + 0, 0, result_set_size, tmp, 0); + number_to_present = tmp; +} + +void mp_util::piggyback(Odr_int smallSetUpperBound, + Odr_int largeSetLowerBound, + Odr_int mediumSetPresentNumber, + const char *smallSetElementSetNames, + const char *mediumSetElementSetNames, + Odr_int result_set_size, + Odr_int &number_to_present, + const char **element_set_name) { // deal with piggyback @@ -173,11 +237,16 @@ void mp_util::piggyback(int smallSetUpperBound, { // small set . Return all records in set number_to_present = result_set_size; + if (element_set_name && smallSetElementSetNames) + *element_set_name = smallSetElementSetNames; + } else if (result_set_size > largeSetLowerBound) { // large set . Return no records number_to_present = 0; + if (element_set_name) + *element_set_name = 0; } else { @@ -185,14 +254,15 @@ void mp_util::piggyback(int smallSetUpperBound, number_to_present = mediumSetPresentNumber; if (number_to_present > result_set_size) number_to_present = result_set_size; + if (element_set_name && mediumSetElementSetNames) + *element_set_name = mediumSetElementSetNames; } } - bool mp_util::pqf(ODR odr, Z_APDU *apdu, const std::string &q) { YAZ_PQF_Parser pqf_parser = yaz_pqf_create(); - + Z_RPNQuery *rpn = yaz_pqf_parse(pqf_parser, odr, q.c_str()); if (!rpn) { @@ -203,7 +273,7 @@ bool mp_util::pqf(ODR odr, Z_APDU *apdu, const std::string &q) Z_Query *query = (Z_Query *) odr_malloc(odr, sizeof(Z_Query)); query->which = Z_Query_type_1; query->u.type_1 = rpn; - + apdu->u.searchRequest->query = query; return true; } @@ -213,40 +283,37 @@ std::string mp_util::zQueryToString(Z_Query *query) { std::string query_str = ""; - if (query && query->which == Z_Query_type_1){ + if (query && query->which == Z_Query_type_1) + { Z_RPNQuery *rpn = query->u.type_1; - - if (rpn){ - - // allocate wrbuf (strings in YAZ!) - WRBUF w = wrbuf_alloc(); - + + if (rpn) + { + mp::wrbuf w; + // put query in w yaz_rpnquery_to_wrbuf(w, rpn); - + // from w to std::string - query_str = std::string(wrbuf_buf(w), wrbuf_len(w)); - - // destroy wrbuf - wrbuf_destroy(w); + query_str = std::string(w.buf(), w.len()); } } #if 0 if (query && query->which == Z_Query_type_1){ - + // allocate wrbuf (strings in YAZ!) WRBUF w = wrbuf_alloc(); - + // put query in w yaz_query_to_wrbuf(w, query); - + // from w to std::string query_str = std::string(wrbuf_buf(w), wrbuf_len(w)); - + // destroy wrbuf wrbuf_free(w, 1); - } + } #endif return query_str; } @@ -269,33 +336,11 @@ void mp_util::get_default_diag(Z_DefaultDiagFormat *r, void mp_util::get_init_diagnostics( Z_InitResponse *initrs, int &error_code, std::string &addinfo) { - Z_External *uif = initrs->userInformationField; - - if (uif && uif->which == Z_External_userInfo1) - { - Z_OtherInformation *ui = uif->u.userInfo1; - int i; - for (i = 0; i < ui->num_elements; i++) - { - Z_OtherInformationUnit *unit = ui->list[i]; - if (unit->which == Z_OtherInfo_externallyDefinedInfo && - unit->information.externallyDefinedInfo && - unit->information.externallyDefinedInfo->which == - Z_External_diag1) - { - Z_DiagnosticFormat *diag = - unit->information.externallyDefinedInfo->u.diag1; - - if (diag->num > 0) - { - Z_DiagnosticFormat_s *ds = diag->elements[0]; - if (ds->which == Z_DiagnosticFormat_s_defaultDiagRec) - mp::util::get_default_diag(ds->u.defaultDiagRec, - error_code, addinfo); - } - } - } - } + + Z_DefaultDiagFormat *df = yaz_decode_init_diag(0, initrs); + + if (df) + get_default_diag(df, error_code, addinfo); } int mp_util::get_or_remove_vhost_otherinfo( @@ -360,14 +405,15 @@ void mp_util::split_zurl(std::string zurl, std::string &host, std::list &db) { const char *zurl_cstr = zurl.c_str(); - const char *sep = strchr(zurl_cstr, '/'); - - if (sep) + const char *args = 0; + cs_get_host_args(zurl_cstr, &args); + + if (args && *args) { - host = std::string(zurl_cstr, sep - zurl_cstr); + host = std::string(zurl_cstr, args - zurl_cstr); - const char *cp1 = sep+1; - while(1) + const char *cp1 = args; + while (1) { const char *cp2 = strchr(cp1, '+'); if (cp2) @@ -381,9 +427,7 @@ void mp_util::split_zurl(std::string zurl, std::string &host, } } else - { host = zurl; - } } bool mp_util::set_databases_from_zurl( @@ -394,7 +438,7 @@ bool mp_util::set_databases_from_zurl( std::list dblist; split_zurl(zurl, host, dblist); - + if (dblist.size() == 0) return false; *db_num = dblist.size(); @@ -430,7 +474,7 @@ Z_APDU *mp::odr::create_close(const Z_APDU *in_apdu, int reason, const char *addinfo) { Z_APDU *apdu = create_APDU(Z_APDU_close, in_apdu); - + *apdu->u.close->closeReason = reason; if (addinfo) apdu->u.close->diagnosticInformation = odr_strdup(m_odr, addinfo); @@ -456,15 +500,9 @@ void mp_util::transfer_referenceId(ODR odr, const Z_APDU *src, Z_APDU *dst) if (src) { Z_ReferenceId **id_from = mp::util::get_referenceId(src); - if (id_from && *id_from && id_to) - { - *id_to = (Z_ReferenceId*) odr_malloc (odr, sizeof(**id_to)); - (*id_to)->size = (*id_to)->len = (*id_from)->len; - (*id_to)->buf = (unsigned char*) odr_malloc(odr, (*id_to)->len); - memcpy((*id_to)->buf, (*id_from)->buf, (*id_to)->len); - } - else if (id_to) - *id_to = 0; + if (id_from && *id_from) + *id_to = odr_create_Odr_oct(odr, (*id_from)->buf, + (*id_from)->len); } } @@ -478,6 +516,13 @@ Z_APDU *mp::odr::create_initResponse(const Z_APDU *in_apdu, zget_init_diagnostics(m_odr, error, addinfo); *apdu->u.initResponse->result = 0; } + apdu->u.initResponse->implementationName = + odr_prepend(m_odr, "Metaproxy", + apdu->u.initResponse->implementationName); + apdu->u.initResponse->implementationVersion = + odr_prepend(m_odr, + VERSION, apdu->u.initResponse->implementationVersion); + return apdu; } @@ -493,7 +538,7 @@ Z_APDU *mp::odr::create_searchResponse(const Z_APDU *in_apdu, rec->which = Z_Records_NSD; rec->u.nonSurrogateDiagnostic = zget_DefaultDiagFormat(m_odr, error, addinfo); - + } return apdu; } @@ -506,7 +551,7 @@ Z_APDU *mp::odr::create_presentResponse(const Z_APDU *in_apdu, { Z_Records *rec = (Z_Records *) odr_malloc(m_odr, sizeof(Z_Records)); apdu->u.presentResponse->records = rec; - + rec->which = Z_Records_NSD; rec->u.nonSurrogateDiagnostic = zget_DefaultDiagFormat(m_odr, error, addinfo); @@ -531,7 +576,7 @@ Z_APDU *mp::odr::create_scanResponse(const Z_APDU *in_apdu, res->entries->num_nonsurrogateDiagnostics = 1; res->entries->nonsurrogateDiagnostics = (Z_DiagRec **) odr_malloc(m_odr, sizeof(Z_DiagRec *)); - res->entries->nonsurrogateDiagnostics[0] = + res->entries->nonsurrogateDiagnostics[0] = zget_DiagRec(m_odr, error, addinfo); } else @@ -542,12 +587,13 @@ Z_APDU *mp::odr::create_scanResponse(const Z_APDU *in_apdu, return apdu; } -Z_GDU *mp::odr::create_HTTP_Response(mp::Session &session, - Z_HTTP_Request *hreq, int code) +Z_GDU *mp::odr::create_HTTP_Response_details(mp::Session &session, + Z_HTTP_Request *hreq, int code, + const char *details) { const char *response_version = "1.0"; bool keepalive = false; - if (!strcmp(hreq->version, "1.0")) + if (!strcmp(hreq->version, "1.0")) { const char *v = z_HTTP_header_lookup(hreq->headers, "Connection"); if (v && !strcmp(v, "Keep-Alive")) @@ -566,21 +612,29 @@ Z_GDU *mp::odr::create_HTTP_Response(mp::Session &session, response_version = "1.1"; } - Z_GDU *gdu = z_get_HTTP_Response(m_odr, code); + Z_GDU *gdu = z_get_HTTP_Response_server( + m_odr, code, details, "Metaproxy/" VERSION, + "http://www.indexdata.com/metaproxy"); Z_HTTP_Response *hres = gdu->u.HTTP_Response; hres->version = odr_strdup(m_odr, response_version); if (keepalive) z_HTTP_header_add(m_odr, &hres->headers, "Connection", "Keep-Alive"); - return gdu; } +Z_GDU *mp::odr::create_HTTP_Response(mp::Session &session, + Z_HTTP_Request *hreq, int code) +{ + return create_HTTP_Response_details(session, hreq, code, 0); + +} + Z_ReferenceId **mp_util::get_referenceId(const Z_APDU *apdu) { switch (apdu->which) { case Z_APDU_initRequest: - return &apdu->u.initRequest->referenceId; + return &apdu->u.initRequest->referenceId; case Z_APDU_initResponse: return &apdu->u.initResponse->referenceId; case Z_APDU_searchRequest: @@ -629,6 +683,59 @@ Z_ReferenceId **mp_util::get_referenceId(const Z_APDU *apdu) return 0; } +std::string mp_util::uri_encode(std::string s) +{ + char *x = (char *) xmalloc(1 + s.length() * 3); + yaz_encode_uri_component(x, s.c_str()); + std::string result(x); + xfree(x); + return result; +} + + +std::string mp_util::uri_decode(std::string s) +{ + char *x = (char *) xmalloc(1 + s.length()); + yaz_decode_uri_component(x, s.c_str(), s.length()); + std::string result(x); + xfree(x); + return result; +} + +mp::wrbuf::wrbuf() +{ + m_wrbuf = wrbuf_alloc(); +} + +mp::wrbuf::~wrbuf() +{ + wrbuf_destroy(m_wrbuf); +} + +mp::wrbuf::operator WRBUF() const +{ + return m_wrbuf; +} + +size_t mp::wrbuf::len() +{ + return wrbuf_len(m_wrbuf); +} + +const char *mp::wrbuf::buf() +{ + return wrbuf_buf(m_wrbuf); +} + +const char *mp::wrbuf::c_str() +{ + return wrbuf_cstr(m_wrbuf); +} + +const char *mp::wrbuf::c_str_null() +{ + return wrbuf_cstr_null(m_wrbuf); +} /* * Local variables: