Send diagnostic 7 for missing query
[yazpp-moved-to-github.git] / src / yaz-proxy.cpp
index 7da3e15..bd8dee5 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (c) 1998-2004, Index Data.
  * See the file LICENSE for details.
  * 
- * $Id: yaz-proxy.cpp,v 1.76 2004-01-05 11:31:04 adam Exp $
+ * $Id: yaz-proxy.cpp,v 1.83 2004-01-07 22:19:05 adam Exp $
  */
 
 #include <assert.h>
@@ -106,7 +106,9 @@ Yaz_Proxy::Yaz_Proxy(IYaz_PDU_Observable *the_PDU_Observable,
     m_invalid_session = 0;
     m_config = 0;
     m_marcxml_flag = 0;
-    m_stylesheet = 0;
+    m_stylesheet_schema = 0;
+    m_s2z_stylesheet = 0;
+    m_schema = 0;
     m_initRequest_apdu = 0;
     m_initRequest_mem = 0;
     m_apdu_invalid_session = 0;
@@ -134,7 +136,8 @@ Yaz_Proxy::~Yaz_Proxy()
     xfree (m_default_target);
     xfree (m_proxy_authentication);
     xfree (m_optimize);
-    xfree (m_stylesheet);
+    xfree (m_stylesheet_schema);
+    xfree (m_schema);
     if (m_s2z_odr_init)
        odr_destroy(m_s2z_odr_init);
     if (m_s2z_odr_search)
@@ -290,7 +293,6 @@ Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu, const char *cookie,
 {
     assert (m_parent);
     Yaz_Proxy *parent = m_parent;
-    Z_OtherInformation **oi;
     Yaz_ProxyClient *c = m_client;
     
     if (!m_proxyTarget)
@@ -581,9 +583,9 @@ void Yaz_Proxy::display_diagrecs(Z_DiagRec **pp, int num)
 
 void Yaz_Proxy::convert_xsl(Z_NamePlusRecordList *p)
 {
-    if (!m_stylesheet)
+    if (!m_stylesheet_schema)
        return;
-    xmlDocPtr xslt_doc = xmlParseFile(m_stylesheet);
+    xmlDocPtr xslt_doc = xmlParseFile(m_stylesheet_schema);
     xsltStylesheetPtr xsp;
 
     xsp = xsltParseStylesheetDoc(xslt_doc);
@@ -697,7 +699,6 @@ void Yaz_Proxy::logtime()
 int Yaz_Proxy::send_http_response(int code)
 {
     ODR o = odr_encode();
-    const char *ctype = "text/xml";
     Z_GDU *gdu = z_get_HTTP_Response(o, code);
     Z_HTTP_Response *hres = gdu->u.HTTP_Response;
     if (m_http_version)
@@ -742,9 +743,9 @@ int Yaz_Proxy::send_srw_response(Z_SRW_PDU *srw_pdu)
     soap_package->u.generic->ns = soap_handlers[0].ns;
     soap_package->u.generic->p = (void *) srw_pdu;
     soap_package->ns = m_soap_ns;
-    int ret = z_soap_codec_enc(o, &soap_package,
-                              &hres->content_buf, &hres->content_len,
-                              soap_handlers, 0);
+    z_soap_codec_enc_xsl(o, &soap_package,
+                        &hres->content_buf, &hres->content_len,
+                        soap_handlers, 0, m_s2z_stylesheet);
     if (m_log_mask & PROXY_LOG_REQ_CLIENT)
     {
        yaz_log (LOG_LOG, "%sSending %s to client", m_session_str,
@@ -815,7 +816,7 @@ int Yaz_Proxy::send_to_srw_client_ok(int hits, Z_Records *records, int start)
            oident *ent = oid_getentbyoid(r->direct_reference);
            if (r->which == Z_External_octet && ent->value == VAL_TEXT_XML)
            {
-               srw_res->records[i].recordSchema = "http://www.loc.gov/marcxml/";
+               srw_res->records[i].recordSchema = m_schema;
                srw_res->records[i].recordPacking = m_s2z_packing;
                srw_res->records[i].recordData_buf = (char*) 
                    r->u.octet_aligned->buf;
@@ -1017,11 +1018,12 @@ int Yaz_Proxy::send_to_client(Z_APDU *apdu)
 int Yaz_ProxyClient::send_to_target(Z_APDU *apdu)
 {
     int len = 0;
+    const char *apdu_name_tmp = apdu_name(apdu);
     int r = send_Z_PDU(apdu, &len);
     if (m_root->get_log_mask() & PROXY_LOG_REQ_SERVER)
        yaz_log (LOG_LOG, "%sSending %s to %s %d bytes",
                 get_session_str(),
-                apdu_name(apdu), get_hostname(), len);
+                apdu_name_tmp, get_hostname(), len);
     m_bytes_sent += len;
     return r;
 }
@@ -1360,16 +1362,32 @@ Z_APDU *Yaz_Proxy::handle_query_transformation(Z_APDU *apdu)
     {
        Z_RPNQuery *rpnquery = 0;
        Z_SearchRequest *sr = apdu->u.searchRequest;
+       char *addinfo = 0;
        
        yaz_log(LOG_LOG, "%sCQL: %s", m_session_str,
                sr->query->u.type_104->u.cql);
 
        int r = m_cql2rpn.query_transform(sr->query->u.type_104->u.cql,
-                                         &rpnquery, odr_encode());
+                                         &rpnquery, odr_encode(),
+                                         &addinfo);
        if (r == -3)
            yaz_log(LOG_LOG, "%sNo CQL to RPN table", m_session_str);
        else if (r)
+       {
            yaz_log(LOG_LOG, "%sCQL Conversion error %d", m_session_str, r);
+           Z_APDU *new_apdu = create_Z_PDU(Z_APDU_searchResponse);
+
+           new_apdu->u.searchResponse->referenceId = sr->referenceId;
+           new_apdu->u.searchResponse->records =
+               create_nonSurrogateDiagnostics(odr_encode(),
+                                              yaz_diag_srw_to_bib1(r),
+                                              addinfo);
+           *new_apdu->u.searchResponse->searchStatus = 0;
+
+           send_to_client(new_apdu);
+
+           return 0;
+       }
        else
        {
            sr->query->which = Z_Query_type_1;
@@ -1431,7 +1449,7 @@ Z_APDU *Yaz_Proxy::handle_syntax_validation(Z_APDU *apdu)
            err = cfg->check_syntax(odr_encode(),
                                    m_default_target,
                                    sr->preferredRecordSyntax, rc,
-                                   &addinfo, &m_stylesheet);
+                                   &addinfo, &m_stylesheet_schema, &m_schema);
        if (err == -1)
        {
            sr->preferredRecordSyntax =
@@ -1463,7 +1481,7 @@ Z_APDU *Yaz_Proxy::handle_syntax_validation(Z_APDU *apdu)
            err = cfg->check_syntax(odr_encode(), m_default_target,
                                    pr->preferredRecordSyntax,
                                    pr->recordComposition,
-                                   &addinfo, &m_stylesheet);
+                                   &addinfo, &m_stylesheet_schema, &m_schema);
        if (err == -1)
        {
            pr->preferredRecordSyntax =
@@ -1548,10 +1566,18 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq)
        m_s2z_init_apdu = 0;
        m_s2z_search_apdu = 0;
        m_s2z_present_apdu = 0;
+
+       m_s2z_stylesheet = 0;
+       
        if (srw_pdu->which == Z_SRW_searchRetrieve_request)
        {
            Z_SRW_searchRetrieveRequest *srw_req = srw_pdu->u.request;
 
+           // save stylesheet
+           if (srw_req->stylesheet)
+               m_s2z_stylesheet =
+                   odr_strdup(m_s2z_odr_init, srw_req->stylesheet);
+                                             
            // set packing for response records ..
            if (srw_req->recordPacking &&
                !strcmp(srw_req->recordPacking, "xml"))
@@ -1578,6 +1604,11 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq)
            
            if (srw_req->query_type == Z_SRW_query_type_cql)
            {
+                if (!srw_req->query.cql)
+                {
+                   send_to_srw_client_error(7);
+                   return;
+                }
                Z_External *ext = (Z_External *) 
                    odr_malloc(m_s2z_odr_search, sizeof(*ext));
                ext->direct_reference = 
@@ -1617,7 +1648,7 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq)
            }
            else
            {
-               send_to_srw_client_error(11);
+               send_to_srw_client_error(7);
                return;
            }
 
@@ -1631,7 +1662,9 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq)
                start = *srw_req->startRecord;
            if (max > 0)
            {
-               if (start <= 1)  // Z39.50 piggyback
+                // Some backend, such as Voyager doesn't honor piggyback
+               // So we use present always (0 &&).
+               if (0 && start <= 1)  // Z39.50 piggyback
                {
                    *z_searchRequest->smallSetUpperBound = max;
                    *z_searchRequest->mediumSetPresentNumber = max;
@@ -1693,7 +1726,12 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq)
        else if (srw_pdu->which == Z_SRW_explain_request)
        {
            Z_SRW_explainRequest *srw_req = srw_pdu->u.explain_request;
-           
+
+           // save stylesheet
+           if (srw_req->stylesheet)
+               m_s2z_stylesheet =
+                   odr_strdup(m_s2z_odr_init, srw_req->stylesheet);
+
            if (srw_req->recordPacking &&
                !strcmp(srw_req->recordPacking, "xml"))
                m_s2z_packing = Z_SRW_recordPacking_XML;
@@ -1702,7 +1740,6 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq)
 
            if (!m_client)
            {
-               yaz_log(LOG_LOG, "handle_incoming: initRequest");
                m_s2z_init_apdu = zget_APDU(m_s2z_odr_init,
                                            Z_APDU_initRequest);
                
@@ -1715,6 +1752,10 @@ void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq)
                send_srw_explain();
            return;
        }
+       else
+        {
+           send_to_srw_client_error(4);
+        }
     }
     int len = 0;
     Z_GDU *p = z_get_HTTP_Response(odr_encode(), 400);
@@ -1971,7 +2012,6 @@ void Yaz_Proxy::pre_init()
     int keepalive_limit_bw, keepalive_limit_pdu;
     int pre_init;
     const char *cql2rpn = 0;
-    const char *zeerex = 0;
 
     Yaz_ProxyConfig *cfg = check_reconfigure();
 
@@ -2248,7 +2288,7 @@ int Yaz_Proxy::server(const char *addr)
     int r = Yaz_Z_Assoc::server(addr);
     if (!r)
     {
-       yaz_log(LOG_LOG, "%sStarted listener on %s", m_session_str, addr);
+       yaz_log(LOG_LOG, "%sStarted proxy " VERSION " on %s", m_session_str, addr);
        timeout(1);
     }
     return r;