More work on session_shared
[metaproxy-moved-to-github.git] / src / util.cpp
index 26f1edb..8bb34f9 100644 (file)
@@ -1,5 +1,5 @@
-/* $Id: util.cpp,v 1.7 2006-01-17 16:43:22 adam Exp $
-   Copyright (c) 2005, Index Data.
+/* $Id: util.cpp,v 1.14 2006-03-16 10:40:59 adam Exp $
+   Copyright (c) 2005-2006, Index Data.
 
 %LICENSE%
  */
@@ -9,10 +9,42 @@
 #include <yaz/odr.h>
 #include <yaz/pquery.h>
 #include <yaz/otherinfo.h>
+#include <yaz/querytowrbuf.h> // for yaz_query_to_wrbuf()
 #include "util.hpp"
 
+//#include <iostream>
 
-bool yp2::util::pqf(ODR odr, Z_APDU *apdu, const std::string &q) {
+namespace mp = metaproxy_1;
+
+void mp::util::piggyback(int smallSetUpperBound,
+                          int largeSetLowerBound,
+                          int mediumSetPresentNumber,
+                          int result_set_size,
+                          int &number_to_present)
+{
+    // deal with piggyback
+
+    if (result_set_size < smallSetUpperBound)
+    {
+        // small set . Return all records in set
+        number_to_present = result_set_size;
+    }
+    else if (result_set_size > largeSetLowerBound)
+    {
+        // large set . Return no records
+        number_to_present = 0;
+    }
+    else
+    {
+        // medium set . Return mediumSetPresentNumber records
+        number_to_present = mediumSetPresentNumber;
+        if (number_to_present > result_set_size)
+            number_to_present = result_set_size;
+    }
+}
+
+
+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());
@@ -30,7 +62,50 @@ bool yp2::util::pqf(ODR odr, Z_APDU *apdu, const std::string &q) {
     return true;
 }
 
-void yp2::util::get_default_diag(Z_DefaultDiagFormat *r,
+
+std::string mp::util::zQueryToString(Z_Query *query)
+{
+    std::string query_str = "";
+
+    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();
+            
+            // 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_free(w, 1);
+        }
+    }
+
+#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;
+}
+
+void mp::util::get_default_diag(Z_DefaultDiagFormat *r,
                                  int &error_code, std::string &addinfo)
 {
     error_code = *r->condition;
@@ -45,7 +120,7 @@ void yp2::util::get_default_diag(Z_DefaultDiagFormat *r,
     }
 }
 
-void yp2::util::get_init_diagnostics(Z_InitResponse *initrs,
+void mp::util::get_init_diagnostics(Z_InitResponse *initrs,
                                      int &error_code, std::string &addinfo)
 {
     Z_External *uif = initrs->userInformationField;
@@ -69,7 +144,7 @@ void yp2::util::get_init_diagnostics(Z_InitResponse *initrs,
                 {
                     Z_DiagnosticFormat_s *ds = diag->elements[0];
                     if (ds->which == Z_DiagnosticFormat_s_defaultDiagRec)
-                        yp2::util::get_default_diag(ds->u.defaultDiagRec,
+                        mp::util::get_default_diag(ds->u.defaultDiagRec,
                                                     error_code, addinfo);
                 }
             } 
@@ -77,7 +152,7 @@ void yp2::util::get_init_diagnostics(Z_InitResponse *initrs,
     }
 }
 
-int yp2::util::get_vhost_otherinfo(Z_OtherInformation **otherInformation,
+int mp::util::get_vhost_otherinfo(Z_OtherInformation **otherInformation,
                                    bool remove_flag,
                                    std::list<std::string> &vhosts)
 {
@@ -98,7 +173,20 @@ int yp2::util::get_vhost_otherinfo(Z_OtherInformation **otherInformation,
     return cat;
 }
 
-void yp2::util::split_zurl(std::string zurl, std::string &host,
+void mp::util::set_vhost_otherinfo(Z_OtherInformation **otherInformation,
+                                    ODR odr,
+                                    const std::list<std::string> &vhosts)
+{
+    int cat;
+    std::list<std::string>::const_iterator it = vhosts.begin();
+    for (cat = 1; it != vhosts.end() ; cat++, it++)
+    {
+        yaz_oi_set_string_oidval(otherInformation, odr,
+                                 VAL_PROXY, cat, it->c_str());
+    }
+}
+
+void mp::util::split_zurl(std::string zurl, std::string &host,
                            std::list<std::string> &db)
 {
     const char *zurl_cstr = zurl.c_str();
@@ -128,7 +216,7 @@ void yp2::util::split_zurl(std::string zurl, std::string &host,
     }
 }
 
-bool yp2::util::set_databases_from_zurl(ODR odr, std::string zurl,
+bool mp::util::set_databases_from_zurl(ODR odr, std::string zurl,
                                         int *db_num, char ***db_strings)
 {
     std::string host;
@@ -147,27 +235,27 @@ bool yp2::util::set_databases_from_zurl(ODR odr, std::string zurl,
     return true;
 }
 
-yp2::odr::odr(int type)
+mp::odr::odr(int type)
 {
     m_odr = odr_createmem(type);
 }
 
-yp2::odr::odr()
+mp::odr::odr()
 {
     m_odr = odr_createmem(ODR_ENCODE);
 }
 
-yp2::odr::~odr()
+mp::odr::~odr()
 {
     odr_destroy(m_odr);
 }
 
-yp2::odr::operator ODR() const
+mp::odr::operator ODR() const
 {
     return m_odr;
 }
 
-Z_APDU *yp2::odr::create_close(Z_APDU *in_apdu,
+Z_APDU *mp::odr::create_close(Z_APDU *in_apdu,
                                int reason, const char *addinfo)
 {
     Z_APDU *apdu = create_APDU(Z_APDU_close, in_apdu);
@@ -178,20 +266,20 @@ Z_APDU *yp2::odr::create_close(Z_APDU *in_apdu,
     return apdu;
 }
 
-Z_APDU *yp2::odr::create_APDU(int type, Z_APDU *in_apdu)
+Z_APDU *mp::odr::create_APDU(int type, Z_APDU *in_apdu)
 {
-    return yp2::util::create_APDU(m_odr, type, in_apdu);
+    return mp::util::create_APDU(m_odr, type, in_apdu);
 }
 
-Z_APDU *yp2::util::create_APDU(ODR odr, int type, Z_APDU *in_apdu)
+Z_APDU *mp::util::create_APDU(ODR odr, int type, Z_APDU *in_apdu)
 {
     Z_APDU *out_apdu = zget_APDU(odr, type);
 
-    Z_ReferenceId **id_to = yp2::util::get_referenceId(out_apdu);
+    Z_ReferenceId **id_to = mp::util::get_referenceId(out_apdu);
     *id_to = 0;
     if (in_apdu)
     {
-        Z_ReferenceId **id_from = yp2::util::get_referenceId(in_apdu);
+        Z_ReferenceId **id_from = mp::util::get_referenceId(in_apdu);
         if (id_from && *id_from && id_to)
         {
             *id_to = (Z_ReferenceId*) odr_malloc (odr, sizeof(**id_to));
@@ -205,7 +293,7 @@ Z_APDU *yp2::util::create_APDU(ODR odr, int type, Z_APDU *in_apdu)
     return out_apdu;
 }
 
-Z_APDU *yp2::odr::create_initResponse(Z_APDU *in_apdu,
+Z_APDU *mp::odr::create_initResponse(Z_APDU *in_apdu,
                                       int error, const char *addinfo)
 {
     Z_APDU *apdu = create_APDU(Z_APDU_initResponse, in_apdu);
@@ -218,7 +306,7 @@ Z_APDU *yp2::odr::create_initResponse(Z_APDU *in_apdu,
     return apdu;
 }
 
-Z_APDU *yp2::odr::create_searchResponse(Z_APDU *in_apdu,
+Z_APDU *mp::odr::create_searchResponse(Z_APDU *in_apdu,
                                         int error, const char *addinfo)
 {
     Z_APDU *apdu = create_APDU(Z_APDU_searchResponse, in_apdu);
@@ -235,7 +323,7 @@ Z_APDU *yp2::odr::create_searchResponse(Z_APDU *in_apdu,
     return apdu;
 }
 
-Z_APDU *yp2::odr::create_presentResponse(Z_APDU *in_apdu,
+Z_APDU *mp::odr::create_presentResponse(Z_APDU *in_apdu,
                                          int error, const char *addinfo)
 {
     Z_APDU *apdu = create_APDU(Z_APDU_presentResponse, in_apdu);
@@ -243,35 +331,76 @@ Z_APDU *yp2::odr::create_presentResponse(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);
+        *apdu->u.presentResponse->presentStatus = Z_PresentStatus_failure;
     }
     return apdu;
 }
 
-Z_APDU *yp2::odr::create_scanResponse(Z_APDU *in_apdu,
+Z_APDU *mp::odr::create_scanResponse(Z_APDU *in_apdu,
                                       int error, const char *addinfo)
 {
     Z_APDU *apdu = create_APDU(Z_APDU_scanResponse, in_apdu);
+    Z_ScanResponse *res = apdu->u.scanResponse;
+    res->entries = (Z_ListEntries *) odr_malloc(m_odr, sizeof(*res->entries));
+    res->entries->num_entries = 0;
+    res->entries->entries = 0;
+
     if (error)
     {
-        Z_ScanResponse *res = apdu->u.scanResponse;
-        res->entries = (Z_ListEntries *) odr_malloc(m_odr, sizeof(*res->entries));
         *res->scanStatus = Z_Scan_failure;
 
-        res->entries->num_entries = 0;
-        res->entries->entries = 0;
         res->entries->num_nonsurrogateDiagnostics = 1;
         res->entries->nonsurrogateDiagnostics = (Z_DiagRec **)
             odr_malloc(m_odr, sizeof(Z_DiagRec *));
         res->entries->nonsurrogateDiagnostics[0] = 
             zget_DiagRec(m_odr, error, addinfo);
     }
+    else
+    {
+        res->entries->num_nonsurrogateDiagnostics = 0;
+        res->entries->nonsurrogateDiagnostics = 0;
+    }
     return apdu;
 }
 
-Z_ReferenceId **yp2::util::get_referenceId(Z_APDU *apdu)
+Z_GDU *mp::odr::create_HTTP_Response(mp::Session &session,
+                                      Z_HTTP_Request *hreq, int code)
+{
+    const char *response_version = "1.0";
+    bool keepalive = false;
+    if (!strcmp(hreq->version, "1.0")) 
+    {
+        const char *v = z_HTTP_header_lookup(hreq->headers, "Connection");
+        if (v && !strcmp(v, "Keep-Alive"))
+            keepalive = true;
+        else
+            session.close();
+        response_version = "1.0";
+    }
+    else
+    {
+        const char *v = z_HTTP_header_lookup(hreq->headers, "Connection");
+        if (v && !strcmp(v, "close"))
+            session.close();
+        else
+            keepalive = true;
+        response_version = "1.1";
+    }
+
+    Z_GDU *gdu = z_get_HTTP_Response(m_odr, code);
+    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_ReferenceId **mp::util::get_referenceId(Z_APDU *apdu)
 {
     switch (apdu->which)
     {