Fix zebrasrv [warn] ir_session (exception) YAZ-838
[yaz-moved-to-github.git] / src / seshigh.c
index d594f43..a9e248e 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2013 Index Data
+ * Copyright (C) Index Data
  * See the file LICENSE for details.
  */
 /**
@@ -74,7 +74,7 @@
 #include <yaz/yaz-util.h>
 #include <yaz/pquery.h>
 #include <yaz/oid_db.h>
-
+#include <yaz/query-charset.h>
 #include <yaz/srw.h>
 #include <yaz/backend.h>
 #include <yaz/yaz-ccl.h>
@@ -469,7 +469,8 @@ void ir_session(IOCHAN h, int event)
     }
     if (event & EVENT_EXCEPT)
     {
-        yaz_log(YLOG_WARN, "ir_session (exception)");
+        if (assoc->state != ASSOC_DEAD)
+            yaz_log(YLOG_WARN, "ir_session (exception)");
         cs_close(conn);
         destroy_association(assoc);
         iochan_destroy(h);
@@ -479,8 +480,10 @@ void ir_session(IOCHAN h, int event)
 static int process_z_request(association *assoc, request *req, char **msg);
 
 
-static void assoc_init_reset(association *assoc)
+static void assoc_init_reset(association *assoc, const char *peer_name1)
 {
+    const char *peer_name2 = cs_addrstr(assoc->client_link);
+
     xfree(assoc->init);
     assoc->init = (bend_initrequest *) xmalloc(sizeof(*assoc->init));
 
@@ -510,13 +513,24 @@ static void assoc_init_reset(association *assoc)
     assoc->init->charneg_response = NULL;
 
     assoc->init->decode = assoc->decode;
-    assoc->init->peer_name =
-        odr_strdup(assoc->encode, cs_addrstr(assoc->client_link));
+
+    assoc->init->peer_name = (char *)
+        odr_malloc(assoc->encode,
+                   (peer_name1 ? strlen(peer_name1) : 0)
+                   + 4 + strlen(peer_name2));
+    strcpy(assoc->init->peer_name, "");
+    if (peer_name1)
+    {
+        strcat(assoc->init->peer_name, peer_name1);
+        strcat(assoc->init->peer_name, ", ");
+    }
+    strcat(assoc->init->peer_name, peer_name2);
 
     yaz_log(log_requestdetail, "peer %s", assoc->init->peer_name);
 }
 
-static int srw_bend_init(association *assoc, Z_SRW_diagnostic **d, int *num, Z_SRW_PDU *sr)
+static int srw_bend_init(association *assoc, Z_HTTP_Header *headers,
+                         Z_SRW_diagnostic **d, int *num, Z_SRW_PDU *sr)
 {
     statserv_options_block *cb = statserv_getcontrol();
     if (!assoc->init)
@@ -526,7 +540,7 @@ static int srw_bend_init(association *assoc, Z_SRW_diagnostic **d, int *num, Z_S
         bend_initresult *binitres;
 
         yaz_log(log_requestdetail, "srw_bend_init config=%s", cb->configname);
-        assoc_init_reset(assoc);
+        assoc_init_reset(assoc, z_HTTP_header_lookup(headers, "X-Forwarded-For"));
 
         if (sr->username)
         {
@@ -688,6 +702,7 @@ static int retrieve_fetch(association *assoc, bend_fetch_rr *rr)
         if (r)
         {
             rr->errcode = YAZ_BIB1_SYSTEM_ERROR_IN_PRESENTING_RECORDS;
+            rr->surrogate_flag = 1;
             if (details)
                 rr->errstring = odr_strdup(rr->stream, details);
         }
@@ -902,6 +917,7 @@ static int ccl2pqf(ODR odr, const Odr_oct *ccl, CCL_bibset bibset,
 }
 
 static void srw_bend_search(association *assoc,
+                            Z_HTTP_Header *headers,
                             Z_SRW_PDU *sr,
                             Z_SRW_PDU *res,
                             int *http_code)
@@ -913,7 +929,8 @@ static void srw_bend_search(association *assoc,
 
     *http_code = 200;
     yaz_log(log_requestdetail, "Got SRW SearchRetrieveRequest");
-    srw_bend_init(assoc, &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
+    srw_bend_init(assoc, headers,
+                  &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
     if (srw_res->num_diagnostics == 0 && assoc->init)
     {
         bend_search_rr rr;
@@ -1254,13 +1271,15 @@ static char *srw_bend_explain_default(bend_explain_rr *rr)
 }
 
 static void srw_bend_explain(association *assoc,
+                             Z_HTTP_Header *headers,
                              Z_SRW_PDU *sr,
                              Z_SRW_explainResponse *srw_res,
                              int *http_code)
 {
     Z_SRW_explainRequest *srw_req = sr->u.explain_request;
     yaz_log(log_requestdetail, "Got SRW ExplainRequest");
-    srw_bend_init(assoc, &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
+    srw_bend_init(assoc, headers,
+                  &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
     if (!assoc->init && srw_res->num_diagnostics == 0)
         *http_code = 404;
     if (assoc->init)
@@ -1303,6 +1322,7 @@ static void srw_bend_explain(association *assoc,
 }
 
 static void srw_bend_scan(association *assoc,
+                          Z_HTTP_Header *headers,
                           Z_SRW_PDU *sr,
                           Z_SRW_PDU *res,
                           int *http_code)
@@ -1312,7 +1332,8 @@ static void srw_bend_scan(association *assoc,
     yaz_log(log_requestdetail, "Got SRW ScanRequest");
 
     *http_code = 200;
-    srw_bend_init(assoc, &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
+    srw_bend_init(assoc, headers,
+                  &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
     if (srw_res->num_diagnostics == 0 && assoc->init)
     {
         int step_size = 0;
@@ -1481,6 +1502,7 @@ static void srw_bend_scan(association *assoc,
 }
 
 static void srw_bend_update(association *assoc,
+                            Z_HTTP_Header *headers,
                            Z_SRW_PDU *sr,
                            Z_SRW_updateResponse *srw_res,
                            int *http_code)
@@ -1488,7 +1510,8 @@ static void srw_bend_update(association *assoc,
     Z_SRW_updateRequest *srw_req = sr->u.update_request;
     yaz_log(log_session, "SRWUpdate action=%s", srw_req->operation);
     yaz_log(YLOG_DEBUG, "num_diag = %d", srw_res->num_diagnostics );
-    srw_bend_init(assoc, &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
+    srw_bend_init(assoc, headers,
+                  &srw_res->diagnostics, &srw_res->num_diagnostics, sr);
     if (!assoc->init && srw_res->num_diagnostics == 0)
         *http_code = 404;
     if (assoc->init)
@@ -1840,8 +1863,8 @@ static void process_http_request(association *assoc, request *req)
         if (sr->which == Z_SRW_searchRetrieve_request)
         {
             Z_SRW_PDU *res =
-                yaz_srw_get_pdu(assoc->encode, Z_SRW_searchRetrieve_response,
-                                sr->srw_version);
+                yaz_srw_get_pdu_e(assoc->encode, Z_SRW_searchRetrieve_response,
+                                  sr);
             stylesheet = sr->u.request->stylesheet;
             if (num_diagnostic)
             {
@@ -1850,36 +1873,35 @@ static void process_http_request(association *assoc, request *req)
             }
             else
             {
-                srw_bend_search(assoc, sr, res, &http_code);
+                srw_bend_search(assoc, hreq->headers, sr, res, &http_code);
             }
             if (http_code == 200)
                 soap_package->u.generic->p = res;
         }
         else if (sr->which == Z_SRW_explain_request)
         {
-            Z_SRW_PDU *res = yaz_srw_get_pdu(o, Z_SRW_explain_response,
-                                             sr->srw_version);
+            Z_SRW_PDU *res = yaz_srw_get_pdu_e(o, Z_SRW_explain_response, sr);
             stylesheet = sr->u.explain_request->stylesheet;
             if (num_diagnostic)
             {
                 res->u.explain_response->diagnostics = diagnostic;
                 res->u.explain_response->num_diagnostics = num_diagnostic;
             }
-            srw_bend_explain(assoc, sr, res->u.explain_response, &http_code);
+            srw_bend_explain(assoc, hreq->headers,
+                             sr, res->u.explain_response, &http_code);
             if (http_code == 200)
                 soap_package->u.generic->p = res;
         }
         else if (sr->which == Z_SRW_scan_request)
         {
-            Z_SRW_PDU *res = yaz_srw_get_pdu(o, Z_SRW_scan_response,
-                                             sr->srw_version);
+            Z_SRW_PDU *res = yaz_srw_get_pdu_e(o, Z_SRW_scan_response, sr);
             stylesheet = sr->u.scan_request->stylesheet;
             if (num_diagnostic)
             {
                 res->u.scan_response->diagnostics = diagnostic;
                 res->u.scan_response->num_diagnostics = num_diagnostic;
             }
-            srw_bend_scan(assoc, sr, res, &http_code);
+            srw_bend_scan(assoc, hreq->headers, sr, res, &http_code);
             if (http_code == 200)
                 soap_package->u.generic->p = res;
         }
@@ -1894,7 +1916,8 @@ static void process_http_request(association *assoc, request *req)
                 res->u.update_response->num_diagnostics = num_diagnostic;
             }
             yaz_log(YLOG_DEBUG, "num_diag = %d", res->u.update_response->num_diagnostics );
-            srw_bend_update(assoc, sr, res->u.update_response, &http_code);
+            srw_bend_update(assoc, hreq->headers,
+                            sr, res->u.update_response, &http_code);
             if (http_code == 200)
                 soap_package->u.generic->p = res;
         }
@@ -2187,8 +2210,9 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
         yaz_log(log_requestdetail, "Version:   %s",
                 req->implementationVersion);
 
-    assoc_init_reset(assoc);
-
+    assoc_init_reset(assoc, 
+                     yaz_oi_get_string_oid(&req->otherInfo,
+                                           yaz_oid_userinfo_client_ip, 1, 0));
     assoc->init->auth = req->idAuthentication;
     assoc->init->referenceId = req->referenceId;
 
@@ -2475,7 +2499,8 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start,
                                Z_ReferenceId *referenceId,
                                Odr_oid *oid, int *errcode)
 {
-    int recno, total_length = 0, dumped_records = 0;
+    int recno;
+    Odr_int dumped_records = 0;
     int toget = odr_int_to_int(*num);
     Z_Records *records =
         (Z_Records *) odr_malloc(a->encode, sizeof(*records));
@@ -2505,13 +2530,13 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start,
     {
         bend_fetch_rr freq;
         Z_NamePlusRecord *thisrec;
-        int this_length = 0;
+        Odr_int this_length = 0;
         /*
          * we get the number of bytes allocated on the stream before any
          * allocation done by the backend - this should give us a reasonable
          * idea of the total size of the data so far.
          */
-        total_length = odr_total(a->encode) - dumped_records;
+        Odr_int total_length = odr_total(a->encode) - dumped_records;
         freq.errcode = 0;
         freq.errstring = 0;
         freq.basename = 0;
@@ -2567,10 +2592,11 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start,
             this_length = freq.len;
         else
             this_length = odr_total(a->encode) - total_length - dumped_records;
-        yaz_log(YLOG_DEBUG, "  fetched record, len=%d, total=%d dumped=%d",
-            this_length, total_length, dumped_records);
+        yaz_log(log_requestdetail, "  fetched record, len=" ODR_INT_PRINTF
+                " total=" ODR_INT_PRINTF " dumped=" ODR_INT_PRINTF,
+                this_length, total_length, dumped_records);
         if (a->preferredMessageSize > 0 &&
-                this_length + total_length > a->preferredMessageSize)
+            this_length + total_length > a->preferredMessageSize)
         {
             /* record is small enough, really */
             if (this_length <= a->preferredMessageSize && recno > start)
@@ -2600,7 +2626,7 @@ static Z_Records *pack_records(association *a, char *setname, Odr_int start,
             else /* too big entirely */
             {
                 yaz_log(log_requestdetail, "Record > maxrcdsz "
-                        "this=%d max=%d",
+                        "this=" ODR_INT_PRINTF " max=%d",
                         this_length, a->maximumRecordSize);
                 reclist->records[reclist->num_records] =
                     surrogatediagrec(
@@ -2683,6 +2709,19 @@ static Z_APDU *process_searchRequest(association *assoc, request *reqb)
             bsrr->search_input = req->otherInfo;
         bsrr->present_number = *req->mediumSetPresentNumber;
 
+        if (assoc->server && assoc->server->client_query_charset &&
+            req->query->which == Z_Query_type_1)
+        {
+            yaz_iconv_t cd =
+                yaz_iconv_open("UTF-8", assoc->server->client_query_charset);
+            if (cd)
+            {
+                yaz_query_charset_convert_rpnquery(req->query->u.type_1,
+                                                   assoc->decode, cd);
+                yaz_iconv_close(cd);
+            }
+        }
+
         if (assoc->server && assoc->server->cql_transform
             && req->query->which == Z_Query_type_104
             && req->query->u.type_104->which == Z_External_CQL)