X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fsru_util.cpp;h=d9e873096c00367a483ca0d364a1000462ebb7b4;hb=586d78659d671683f33ec55f4a7d32b28e345ccd;hp=e1165922ce289591416fa33114fad348b5e544ed;hpb=30c0a93ac5646f497d4f1eabd3ddb5132ea1c37a;p=metaproxy-moved-to-github.git diff --git a/src/sru_util.cpp b/src/sru_util.cpp index e116592..d9e8730 100644 --- a/src/sru_util.cpp +++ b/src/sru_util.cpp @@ -1,14 +1,23 @@ -/* $Id: sru_util.cpp,v 1.5 2007-01-07 00:41:18 marc Exp $ - Copyright (c) 2005-2006, Index Data. - - See the LICENSE file for details +/* This file is part of Metaproxy. + 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 +Software Foundation; either version 2, or (at your option) any later +version. + +Metaproxy is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "sru_util.hpp" -#include "util.hpp" - -//#include -//#include +#include #include #include @@ -23,11 +32,11 @@ const std::string xmlns_explain("http://explain.z3950.org/dtd/2.0/"); bool mp_util::build_sru_debug_package(mp::Package &package) { Z_GDU *zgdu_req = package.request().get(); - if (zgdu_req && zgdu_req->which == Z_GDU_HTTP_Request) - { + if (zgdu_req && zgdu_req->which == Z_GDU_HTTP_Request) + { Z_HTTP_Request* http_req = zgdu_req->u.HTTP_Request; std::string content = mp_util::http_headers_debug(*http_req); - int http_code = 400; + int http_code = 400; mp_util::http_response(package, content, http_code); return true; } @@ -36,45 +45,44 @@ bool mp_util::build_sru_debug_package(mp::Package &package) } mp_util::SRUServerInfo mp_util::get_sru_server_info(mp::Package &package) - //Z_SRW_explainRequest const *er_req) { mp_util::SRUServerInfo sruinfo; - // getting database info - //if (er_req && er_req->database) - // sruinfo.database = er_req->database; - // getting host and port info - sruinfo.host = package.origin().listen_host(); - sruinfo.port = mp_util::to_string(package.origin().listen_port()); + sruinfo.host = "localhost"; + sruinfo.port = "80"; // overwriting host and port info if set from HTTP Host header Z_GDU *zgdu_req = package.request().get(); - if (zgdu_req && zgdu_req->which == Z_GDU_HTTP_Request) + if (zgdu_req && zgdu_req->which == Z_GDU_HTTP_Request) { Z_HTTP_Request* http_req = zgdu_req->u.HTTP_Request; if (http_req) { - - //std::string http_method = http_req->method; - //std::string http_version = http_req->version; std::string http_path = http_req->path; + + // taking out GET parameters + std::string::size_type ipath = http_path.rfind("?"); + if (ipath != std::string::npos) + http_path.assign(http_path, 0, ipath); + + // assign to database name if (http_path.size() > 1) sruinfo.database.assign(http_path, 1, std::string::npos); std::string http_host_address = mp_util::http_header_value(http_req->headers, "Host"); - std::string::size_type i = http_host_address.rfind(":"); - if (i != std::string::npos) + std::string::size_type iaddress = http_host_address.rfind(":"); + if (iaddress != std::string::npos) { - sruinfo.host.assign(http_host_address, 0, i); - sruinfo.port.assign(http_host_address, i + 1, + sruinfo.host.assign(http_host_address, 0, iaddress); + sruinfo.port.assign(http_host_address, iaddress + 1, std::string::npos); } } } - + //std::cout << "sruinfo.database " << sruinfo.database << "\n"; //std::cout << "sruinfo.host " << sruinfo.host << "\n"; //std::cout << "sruinfo.port " << sruinfo.port << "\n"; @@ -83,53 +91,7 @@ mp_util::SRUServerInfo mp_util::get_sru_server_info(mp::Package &package) } -// bool mp_util::build_simple_explain(mp::Package &package, -// mp::odr &odr_en, -// Z_SRW_PDU *sru_pdu_res, -// SRUServerInfo sruinfo, -// Z_SRW_explainRequest const *er_req) -// { -// // z3950'fy recordPacking -// int record_packing = Z_SRW_recordPacking_XML; -// if (er_req && er_req->recordPacking && 's' == *(er_req->recordPacking)) -// record_packing = Z_SRW_recordPacking_string; - -// // building SRU explain record -// std::string explain_xml -// = mp_util::to_string( -// "\n" -// " \n" -// " ") -// + sruinfo.host -// + mp_util::to_string("\n" -// " ") -// + sruinfo.port -// + mp_util::to_string("\n" -// " ") -// + sruinfo.database -// + mp_util::to_string("\n" -// " \n" -// "\n"); - - -// // preparing explain record insert -// Z_SRW_explainResponse *sru_res = sru_pdu_res->u.explain_response; - -// // inserting one and only explain record - -// sru_res->record.recordPosition = odr_intdup(odr_en, 1); -// sru_res->record.recordPacking = record_packing; -// sru_res->record.recordSchema = (char *)xmlns_explain.c_str(); -// sru_res->record.recordData_len = 1 + explain_xml.size(); -// sru_res->record.recordData_buf -// = odr_strdupn(odr_en, (const char *)explain_xml.c_str(), -// 1 + explain_xml.size()); - -// return true; -// }; - - -bool mp_util::build_sru_explain(metaproxy_1::Package &package, +bool mp_util::build_sru_explain(metaproxy_1::Package &package, metaproxy_1::odr &odr_en, Z_SRW_PDU *sru_pdu_res, SRUServerInfo sruinfo, @@ -138,10 +100,11 @@ bool mp_util::build_sru_explain(metaproxy_1::Package &package, { // building SRU explain record - std::string explain_xml; + std::string explain_xml; - if (explain == 0){ - explain_xml + if (explain == 0) + { + explain_xml = mp_util::to_string( "\n" " \n" @@ -157,39 +120,49 @@ bool mp_util::build_sru_explain(metaproxy_1::Package &package, " \n" "\n"); } - else { - explain_xml = ""; + else + { + // make new XML DOC with given explain node + xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0"); + xmlDocSetRootElement(doc, (xmlNode*)explain); + + xmlChar *xmlbuff; + int xmlbuffsz; + xmlDocDumpFormatMemory(doc, &xmlbuff, &xmlbuffsz, 1); + + explain_xml.assign((const char*)xmlbuff, 0, xmlbuffsz); + xmlFree(xmlbuff); } // z3950'fy recordPacking int record_packing = Z_SRW_recordPacking_XML; if (er_req && er_req->recordPacking && 's' == *(er_req->recordPacking)) - record_packing = Z_SRW_recordPacking_string; - + record_packing = Z_SRW_recordPacking_string; + // preparing explain record insert Z_SRW_explainResponse *sru_res = sru_pdu_res->u.explain_response; - + // inserting one and only explain record - + sru_res->record.recordPosition = odr_intdup(odr_en, 1); sru_res->record.recordPacking = record_packing; sru_res->record.recordSchema = (char *)xmlns_explain.c_str(); sru_res->record.recordData_len = 1 + explain_xml.size(); sru_res->record.recordData_buf - = odr_strdupn(odr_en, (const char *)explain_xml.c_str(), + = odr_strdupn(odr_en, (const char *)explain_xml.c_str(), 1 + explain_xml.size()); return true; -}; +} -bool mp_util::build_sru_response(mp::Package &package, - mp::odr &odr_en, - Z_SOAP *soap, - const Z_SRW_PDU *sru_pdu_res, - char *charset, - const char *stylesheet) +bool mp_util::build_sru_response(mp::Package &package, + mp::odr &odr_en, + Z_SOAP *soap, + const Z_SRW_PDU *sru_pdu_res, + char *charset, + const char *stylesheet) { // SRU request package translation to Z3950 package @@ -198,55 +171,53 @@ bool mp_util::build_sru_response(mp::Package &package, //else // std::cout << "SRU empty\n"; - + Z_GDU *zgdu_req = package.request().get(); if (zgdu_req && zgdu_req->which == Z_GDU_HTTP_Request) - { + { Z_GDU *zgdu_res //= z_get_HTTP_Response(odr_en, 200); - = odr_en.create_HTTP_Response(package.session(), - zgdu_req->u.HTTP_Request, + = odr_en.create_HTTP_Response(package.session(), + zgdu_req->u.HTTP_Request, 200); // adding HTTP response code and headers Z_HTTP_Response * http_res = zgdu_res->u.HTTP_Response; //http_res->code = http_code; - + std::string ctype("text/xml"); - if (charset){ + if (charset) + { ctype += "; charset="; ctype += charset; } - z_HTTP_header_add(odr_en, + z_HTTP_header_add(odr_en, &http_res->headers, "Content-Type", ctype.c_str()); - // packaging Z_SOAP into HTML response - static Z_SOAP_Handler soap_handlers[4] = { - {"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}, - {"http://www.loc.gov/zing/srw/update/", 0, - (Z_SOAP_fun) yaz_ucp_codec}, - {0, 0, 0} - }; - - - // empty stylesheet means NO stylesheet - if (stylesheet && *stylesheet == '\0') - stylesheet = 0; - - // encoding SRU package - - soap->u.generic->p = (void*) sru_pdu_res; - //int ret = - z_soap_codec_enc_xsl(odr_en, &soap, - &http_res->content_buf, &http_res->content_len, - soap_handlers, charset, stylesheet); - - - package.response() = zgdu_res; - return true; + // packaging Z_SOAP into HTML response + static Z_SOAP_Handler soap_handlers[4] = { + {(char *)YAZ_XMLNS_SRU_v1_1, 0, (Z_SOAP_fun) yaz_srw_codec}, + {(char *)YAZ_XMLNS_SRU_v1_0, 0, (Z_SOAP_fun) yaz_srw_codec}, + {(char *)YAZ_XMLNS_UPDATE_v0_9, 0, (Z_SOAP_fun) yaz_ucp_codec}, + {0, 0, 0} + }; + + + // empty stylesheet means NO stylesheet + if (stylesheet && *stylesheet == '\0') + stylesheet = 0; + + // encoding SRU package + + soap->u.generic->p = (void*) sru_pdu_res; + //int ret = + z_soap_codec_enc_xsl(odr_en, &soap, + &http_res->content_buf, &http_res->content_len, + soap_handlers, charset, stylesheet); + + + package.response() = zgdu_res; + return true; } package.session().close(); return false; @@ -254,47 +225,41 @@ bool mp_util::build_sru_response(mp::Package &package, - Z_SRW_PDU * mp_util::decode_sru_request(mp::Package &package, - mp::odr &odr_de, - mp::odr &odr_en, - Z_SRW_PDU *sru_pdu_res, - Z_SOAP *&soap, - char *charset, - char *stylesheet) +Z_SRW_PDU * mp_util::decode_sru_request(mp::Package &package, + mp::odr &odr_de, + mp::odr &odr_en, + Z_SRW_diagnostic **diagnostic, + int *num_diagnostic, + Z_SOAP **soap, + char *charset) { Z_GDU *zgdu_req = package.request().get(); Z_SRW_PDU *sru_pdu_req = 0; //assert((zgdu_req->which == Z_GDU_HTTP_Request)); - + //ignoring all non HTTP_Request packages - if (!zgdu_req || !(zgdu_req->which == Z_GDU_HTTP_Request)){ + if (!zgdu_req || !(zgdu_req->which == Z_GDU_HTTP_Request)) + { return 0; } - + Z_HTTP_Request* http_req = zgdu_req->u.HTTP_Request; if (! http_req) return 0; // checking if we got a SRU GET/POST/SOAP HTTP package // closing connection if we did not ... - if (0 == yaz_sru_decode(http_req, &sru_pdu_req, &soap, - odr_de, &charset, - &(sru_pdu_res->u.response->diagnostics), - &(sru_pdu_res->u.response->num_diagnostics))) + if (0 == yaz_sru_decode(http_req, &sru_pdu_req, soap, + odr_de, &charset, + diagnostic, num_diagnostic)) { - if (sru_pdu_res->u.response->num_diagnostics) - { - //sru_pdu_res = sru_pdu_res_exp; - package.session().close(); - return 0; - } return sru_pdu_req; } - else if (0 == yaz_srw_decode(http_req, &sru_pdu_req, &soap, + else if (0 == yaz_srw_decode(http_req, &sru_pdu_req, soap, odr_de, &charset)) return sru_pdu_req; - else + else { //sru_pdu_res = sru_pdu_res_exp; package.session().close(); @@ -304,66 +269,85 @@ bool mp_util::build_sru_response(mp::Package &package, } -bool -mp_util::check_sru_query_exists(mp::Package &package, +bool +mp_util::check_sru_query_exists(mp::Package &package, mp::odr &odr_en, - Z_SRW_PDU *sru_pdu_res, + Z_SRW_PDU *sru_pdu_res, Z_SRW_searchRetrieveRequest const *sr_req) { - if( (sr_req->query_type == Z_SRW_query_type_cql && !sr_req->query.cql) ) +#ifdef Z_SRW_query_type_cql + if ((sr_req->query_type == Z_SRW_query_type_cql && !sr_req->query.cql)) { yaz_add_srw_diagnostic(odr_en, - &(sru_pdu_res->u.response->diagnostics), - &(sru_pdu_res->u.response->num_diagnostics), - 7, "query"); + &(sru_pdu_res->u.response->diagnostics), + &(sru_pdu_res->u.response->num_diagnostics), + YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, + "query"); yaz_add_srw_diagnostic(odr_en, - &(sru_pdu_res->u.response->diagnostics), - &(sru_pdu_res->u.response->num_diagnostics), - 10, "CQL query is empty"); + &(sru_pdu_res->u.response->diagnostics), + &(sru_pdu_res->u.response->num_diagnostics), + YAZ_SRW_QUERY_SYNTAX_ERROR, + "CQL query is empty"); return false; } - if( (sr_req->query_type == Z_SRW_query_type_xcql && !sr_req->query.xcql) ) + if ((sr_req->query_type == Z_SRW_query_type_xcql && !sr_req->query.xcql)) { - yaz_add_srw_diagnostic(odr_en, - &(sru_pdu_res->u.response->diagnostics), - &(sru_pdu_res->u.response->num_diagnostics), - 10, "XCQL query is empty"); - return false; - } - if( (sr_req->query_type == Z_SRW_query_type_pqf && !sr_req->query.pqf) ) + yaz_add_srw_diagnostic(odr_en, + &(sru_pdu_res->u.response->diagnostics), + &(sru_pdu_res->u.response->num_diagnostics), + YAZ_SRW_QUERY_SYNTAX_ERROR, + "XCQL query is empty"); + return false; + } + if ((sr_req->query_type == Z_SRW_query_type_pqf && !sr_req->query.pqf)) { yaz_add_srw_diagnostic(odr_en, - &(sru_pdu_res->u.response->diagnostics), - &(sru_pdu_res->u.response->num_diagnostics), - 10, "PQF query is empty"); + &(sru_pdu_res->u.response->diagnostics), + &(sru_pdu_res->u.response->num_diagnostics), + YAZ_SRW_QUERY_SYNTAX_ERROR, + "PQF query is empty"); return false; } +#else + if (!sr_req->query) + { + yaz_add_srw_diagnostic(odr_en, + &(sru_pdu_res->u.response->diagnostics), + &(sru_pdu_res->u.response->num_diagnostics), + YAZ_SRW_MANDATORY_PARAMETER_NOT_SUPPLIED, + "query"); + yaz_add_srw_diagnostic(odr_en, + &(sru_pdu_res->u.response->diagnostics), + &(sru_pdu_res->u.response->num_diagnostics), + YAZ_SRW_QUERY_SYNTAX_ERROR, + "CQL query is empty"); + return false; + } +#endif return true; -}; - - +} -Z_ElementSetNames * -mp_util::build_esn_from_schema(mp::odr &odr_en, - const char *schema) +Z_ElementSetNames * +mp_util::build_esn_from_schema(mp::odr &odr_en, const char *schema) { - if (!schema) + if (!schema) return 0; - - Z_ElementSetNames *esn + + Z_ElementSetNames *esn = (Z_ElementSetNames *) odr_malloc(odr_en, sizeof(Z_ElementSetNames)); esn->which = Z_ElementSetNames_generic; esn->u.generic = odr_strdup(odr_en, schema); - return esn; + return esn; } -std::ostream& std::operator<<(std::ostream& os, Z_SRW_PDU& srw_pdu) +std::ostream& std::operator<<(std::ostream& os, Z_SRW_PDU& srw_pdu) { os << "SRU"; - - switch(srw_pdu.which) { + + switch (srw_pdu.which) + { case Z_SRW_searchRetrieve_request: os << " " << "searchRetrieveRequest"; { @@ -391,7 +375,8 @@ std::ostream& std::operator<<(std::ostream& os, Z_SRW_PDU& srw_pdu) os << " " << (sr->recordSchema); else os << " -"; - + +#ifdef Z_SRW_query_type_cql switch (sr->query_type){ case Z_SRW_query_type_cql: os << " CQL"; @@ -407,6 +392,10 @@ std::ostream& std::operator<<(std::ostream& os, Z_SRW_PDU& srw_pdu) os << " " << sr->query.pqf; break; } +#else + os << " " << (sr->queryType ? sr->queryType : "cql") + << " " << sr->query; +#endif } } break; @@ -431,7 +420,7 @@ std::ostream& std::operator<<(std::ostream& os, Z_SRW_PDU& srw_pdu) os << " " << *(sr->nextRecordPosition); else os << " -"; - } + } else { os << " DIAG"; @@ -448,8 +437,8 @@ std::ostream& std::operator<<(std::ostream& os, Z_SRW_PDU& srw_pdu) else os << " -"; } - - + + } } break; @@ -471,133 +460,19 @@ std::ostream& std::operator<<(std::ostream& os, Z_SRW_PDU& srw_pdu) case Z_SRW_update_response: os << " " << "updateResponse"; break; - default: - os << " " << "UNKNOWN"; + default: + os << " " << "UNKNOWN"; } - return os; + return os; } - - - -// mp_util::SRU::SRU_protocol_type -// mp_util::SRU::protocol(const Z_HTTP_Request &http_req) const -// { -// const std::string mime_urlencoded("application/x-www-form-urlencoded"); -// const std::string mime_text_xml("text/xml"); -// const std::string mime_soap_xml("application/soap+xml"); - -// const std::string http_method(http_req.method); -// const std::string http_type -// = mp_util::http_header_value(http_req.headers, "Content-Type"); - -// if (http_method == "GET") -// return SRU_GET; - -// if (http_method == "POST" -// && http_type == mime_urlencoded) -// return SRU_POST; - -// if ( http_method == "POST" -// && (http_type == mime_text_xml -// || http_type == mime_soap_xml)) -// return SRU_SOAP; - -// return SRU_NONE; -// } - -// std::string -// mp_util::sru_protocol(const Z_HTTP_Request &http_req) const -// { -// const std::string mime_urlencoded("application/x-www-form-urlencoded"); -// const std::string mime_text_xml("text/xml"); -// const std::string mime_soap_xml("application/soap+xml"); - -// const std::string http_method(http_req.method); -// const std::string http_type -// = mp_util::http_header_value(http_req.headers, "Content-Type"); - -// if (http_method == "GET") -// return "SRU GET"; - -// if (http_method == "POST" -// && http_type == mime_urlencoded) -// return "SRU POST"; - -// if ( http_method == "POST" -// && (http_type == mime_text_xml -// || http_type == mime_soap_xml)) -// return "SRU SOAP"; - -// return "HTTP"; -// } - -// std::string -// mp_util::debug_http(const Z_HTTP_Request &http_req) const -// { -// std::string message("\n\n

" -// "Metaproxy SRUtoZ3950 filter" -// "

\n"); - -// message += "

HTTP Info


\n"; -// message += "

\n"; -// message += "Method: " + std::string(http_req.method) + "
\n"; -// message += "Version: " + std::string(http_req.version) + "
\n"; -// message += "Path: " + std::string(http_req.path) + "
\n"; - -// message += "Content-Type:" -// + mp_util::http_header_value(http_req.headers, "Content-Type") -// + "
\n"; -// message += "Content-Length:" -// + mp_util::http_header_value(http_req.headers, "Content-Length") -// + "
\n"; -// message += "

\n"; - -// message += "

Headers


\n"; -// message += "

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

\n"; -// message += "\n\n"; -// return message; -// } - -// void mp_util::http_response(metaproxy_1::Package &package, -// const std::string &content, -// int http_code) const -// { - -// 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, -// http_code); - -// zgdu_res->u.HTTP_Response->content_len = content.size(); -// 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, -// 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; -// } - /* * Local variables: * c-basic-offset: 4 + * c-file-style: "Stroustrup" * indent-tabs-mode: nil - * c-file-style: "stroustrup" * End: * vim: shiftwidth=4 tabstop=8 expandtab */ +