Added cs_get_SSL. yaz-client-ssl prints peer info
[yaz-moved-to-github.git] / src / seshigh.c
index 7e5f65b..1bdede6 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (c) 1995-2003, Index Data
+ * Copyright (c) 1995-2004, Index Data
  * See the file LICENSE for details.
  *
- * $Id: seshigh.c,v 1.8 2003-12-29 13:39:41 adam Exp $
+ * $Id: seshigh.c,v 1.23 2004-03-29 15:09:14 adam Exp $
  */
 
 /*
@@ -271,7 +271,7 @@ void ir_session(IOCHAN h, int event)
            destroy_association(assoc);
            iochan_destroy(h);
        }
-       iochan_clearflag (h, EVENT_OUTPUT|EVENT_OUTPUT);
+       iochan_clearflag (h, EVENT_OUTPUT);
        if (conn->io_pending) 
        {   /* cs_accept didn't complete */
            assoc->cs_accept_mask = 
@@ -353,10 +353,11 @@ void ir_session(IOCHAN h, int event)
                return;
            }
            req->request_mem = odr_extract_mem(assoc->decode);
-           if (assoc->print && !z_GDU(assoc->print, &req->gdu_request, 0, 0))
-           {
-               yaz_log(LOG_WARN, "ODR print error: %s", 
-                   odr_errmsg(odr_geterror(assoc->print)));
+           if (assoc->print) 
+            {
+               if (!z_GDU(assoc->print, &req->gdu_request, 0, 0))
+                   yaz_log(LOG_WARN, "ODR print error: %s", 
+                      odr_errmsg(odr_geterror(assoc->print)));
                odr_reset(assoc->print);
            }
            request_enq(&assoc->incoming, req);
@@ -470,6 +471,7 @@ static int srw_bend_init(association *assoc)
     ce = yaz_set_proposal_charneg(assoc->decode, &encoding, 1, 0, 0, 1);
     assoc->init->charneg_request = ce->u.charNeg3;
 #endif
+    assoc->backend = 0;
     if (!(binitres = (*cb->bend_init)(assoc->init)))
     {
        yaz_log(LOG_WARN, "Bad response from backend.");
@@ -546,12 +548,14 @@ static int srw_bend_fetch(association *assoc, int pos,
 
 static void srw_bend_search(association *assoc, request *req,
                             Z_SRW_searchRetrieveRequest *srw_req,
-                            Z_SRW_searchRetrieveResponse *srw_res)
+                            Z_SRW_searchRetrieveResponse *srw_res,
+                           int *http_code)
 {
     int srw_error = 0;
     bend_search_rr rr;
     Z_External *ext;
     
+    *http_code = 200;
     yaz_log(LOG_LOG, "Got SRW SearchRetrieveRequest");
     yaz_log(LOG_DEBUG, "srw_bend_search");
     if (!assoc->init)
@@ -561,12 +565,8 @@ static void srw_bend_search(association *assoc, request *req,
         {
             srw_error = 3;  /* assume Authentication error */
 
-            srw_res->num_diagnostics = 1;
-            srw_res->diagnostics = (Z_SRW_diagnostic *)
-                odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics));
-            srw_res->diagnostics[0].code = 
-                odr_intdup(assoc->encode, srw_error);
-            srw_res->diagnostics[0].details = 0;
+           yaz_add_srw_diagnostic(assoc->encode, &srw_res->diagnostics,
+                                  &srw_res->num_diagnostics, 1, 0);
             return;
         }
     }
@@ -632,9 +632,8 @@ static void srw_bend_search(association *assoc, request *req,
         srw_res->num_diagnostics = 1;
         srw_res->diagnostics = (Z_SRW_diagnostic *)
            odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics));
-        srw_res->diagnostics[0].code = 
-            odr_intdup(assoc->encode, srw_error);
-        srw_res->diagnostics[0].details = 0;
+       yaz_mk_std_diagnostic(assoc->encode,
+                             srw_res->diagnostics, srw_error, 0);
         return;
     }
     
@@ -654,16 +653,19 @@ static void srw_bend_search(association *assoc, request *req,
     if (rr.errcode)
     {
         yaz_log(LOG_DEBUG, "bend_search returned Bib-1 code %d", rr.errcode);
+       if (rr.errcode == 109) /* database unavailable */
+       {
+           *http_code = 404;
+           return;
+       }
         srw_res->num_diagnostics = 1;
         srw_res->diagnostics = (Z_SRW_diagnostic *)
            odr_malloc(assoc->encode, sizeof(*srw_res->diagnostics));
-        srw_res->diagnostics[0].code = 
-            odr_intdup(assoc->encode, 
-                       yaz_diag_bib1_to_srw (rr.errcode));
-        srw_res->diagnostics[0].details = rr.errstring;
-        yaz_log(LOG_DEBUG, "srw_bend_search returned SRW error %d",
-                *srw_res->diagnostics[0].code);
-                
+       yaz_mk_std_diagnostic(assoc->encode, srw_res->diagnostics,
+                             yaz_diag_bib1_to_srw (rr.errcode),
+                             rr.errstring);
+        yaz_log(LOG_DEBUG, "srw_bend_search returned SRW error %s",
+                srw_res->diagnostics[0].uri);
     }
     else
     {
@@ -709,10 +711,11 @@ static void srw_bend_search(association *assoc, request *req,
                         srw_res->diagnostics = (Z_SRW_diagnostic *)
                             odr_malloc(assoc->encode, 
                                        sizeof(*srw_res->diagnostics));
-                        srw_res->diagnostics[0].code = 
-                            odr_intdup(assoc->encode, 
-                                       yaz_diag_bib1_to_srw (errcode));
-                        srw_res->diagnostics[0].details = rr.errstring;
+
+                       yaz_mk_std_diagnostic(assoc->encode, 
+                                             srw_res->diagnostics,
+                                             yaz_diag_bib1_to_srw (errcode),
+                                             rr.errstring);
                         break;
                     }
                     if (srw_res->records[j].recordData_buf)
@@ -728,14 +731,18 @@ static void srw_bend_search(association *assoc, request *req,
 
 static void srw_bend_explain(association *assoc, request *req,
                              Z_SRW_explainRequest *srw_req,
-                             Z_SRW_explainResponse *srw_res)
+                             Z_SRW_explainResponse *srw_res,
+                            int *http_code)
 {
     yaz_log(LOG_LOG, "Got SRW ExplainRequest");
+    *http_code = 404;
     if (!assoc->init)
     {
         yaz_log(LOG_DEBUG, "srw_bend_init");
         if (!srw_bend_init(assoc))
+       {
             return;
+       }
     }
     if (assoc->init && assoc->init->bend_explain)
     {
@@ -745,6 +752,8 @@ static void srw_bend_explain(association *assoc, request *req,
         rr.decode = assoc->decode;
         rr.print = assoc->print;
         rr.explain_buf = 0;
+       rr.database = srw_req->database;
+       rr.schema = "http://explain.z3950.org/dtd/2.0/";
         (*assoc->init->bend_explain)(assoc->backend, &rr);
         if (rr.explain_buf)
         {
@@ -757,6 +766,7 @@ static void srw_bend_explain(association *assoc, request *req,
             srw_res->record.recordData_buf = rr.explain_buf;
             srw_res->record.recordData_len = strlen(rr.explain_buf);
            srw_res->record.recordPosition = 0;
+           *http_code = 200;
         }
     }
 }
@@ -765,361 +775,129 @@ static void process_http_request(association *assoc, request *req)
 {
     Z_HTTP_Request *hreq = req->gdu_request->u.HTTP_Request;
     ODR o = assoc->encode;
+    int r = 2;  /* 2=NOT TAKEN, 1=TAKEN, 0=SOAP TAKEN */
+    Z_SRW_PDU *sr = 0;
+    Z_SOAP *soap_package = 0;
     Z_GDU *p = 0;
+    char *charset = 0;
     Z_HTTP_Response *hres = 0;
     int keepalive = 1;
+    char *stylesheet = 0;
+    Z_SRW_diagnostic *diagnostic = 0;
+    int num_diagnostic = 0;
 
-    if (!strcmp(hreq->method, "GET"))
+    if (!strcmp(hreq->path, "/test")) 
+    {  
+       p = z_get_HTTP_Response(o, 200);
+       hres = p->u.HTTP_Response;
+       hres->content_buf = "1234567890\n";
+       hres->content_len = strlen(hres->content_buf);
+       r = 1;
+    }
+    if (r == 2)
     {
-        char *db = "Default";
-        const char *p0 = hreq->path, *p1;
-       const char *operation = 0;
-#if HAVE_XML2
-        int ret = -1;
-        char *charset = 0;
-        Z_SOAP *soap_package = 0;
-        static Z_SOAP_Handler soap_handlers[2] = {
-            {"http://www.loc.gov/zing/srw/", 0,
-             (Z_SOAP_fun) yaz_srw_codec},
-            {0, 0, 0}
-        };
-#endif
-        if (*p0 == '/')
-            p0++;
-        p1 = strchr(p0, '?');
-        if (!p1)
-            p1 = p0 + strlen(p0);
-        if (p1 != p0)
-        {
-            db = odr_malloc(assoc->decode, p1 - p0 + 1);
-            memcpy (db, p0, p1 - p0);
-            db[p1 - p0] = '\0';
-        }
-       if (p1)
-           operation = yaz_uri_val(p1, "operation", o);
-       if (!operation)
-           operation = "explain";
-#if HAVE_XML2
-        if (p1 && !strcmp(operation, "searchRetrieve"))
-        {
-            Z_SRW_PDU *res = yaz_srw_get(o, Z_SRW_searchRetrieve_response);
-            Z_SRW_PDU *sr = yaz_srw_get(o, Z_SRW_searchRetrieve_request);
-            char *query = yaz_uri_val(p1, "query", o);
-            char *pQuery = yaz_uri_val(p1, "pQuery", o);
-            char *sortKeys = yaz_uri_val(p1, "sortKeys", o);
-            
-            if (query)
-            {
-                sr->u.request->query_type = Z_SRW_query_type_cql;
-                sr->u.request->query.cql = query;
-            }
-            if (pQuery)
-            {
-                sr->u.request->query_type = Z_SRW_query_type_pqf;
-                sr->u.request->query.pqf = pQuery;
-            }
-            if (sortKeys)
-            {
-                sr->u.request->sort_type = Z_SRW_sort_type_sort;
-                sr->u.request->sort.sortKeys = sortKeys;
-            }
-            sr->u.request->recordSchema = yaz_uri_val(p1, "recordSchema", o);
-            sr->u.request->recordPacking = yaz_uri_val(p1, "recordPacking", o);
-            if (!sr->u.request->recordPacking)
-                sr->u.request->recordPacking = "xml";
-            yaz_uri_val_int(p1, "maximumRecords", o, 
-                        &sr->u.request->maximumRecords);
-            yaz_uri_val_int(p1, "startRecord", o,
-                        &sr->u.request->startRecord);
-            sr->u.request->database = db;
-            srw_bend_search(assoc, req, sr->u.request, res->u.response);
-            
-            soap_package = odr_malloc(o, sizeof(*soap_package));
-            soap_package->which = Z_SOAP_generic;
-
-            soap_package->u.generic =
-                odr_malloc(o, sizeof(*soap_package->u.generic));
-
-            soap_package->u.generic->p = res;
-            soap_package->u.generic->ns = soap_handlers[0].ns;
-            soap_package->u.generic->no = 0;
-            
-            soap_package->ns = "SRU";
-
-            p = z_get_HTTP_Response(o, 200);
-            hres = p->u.HTTP_Response;
+       r = yaz_srw_decode(hreq, &sr, &soap_package, assoc->decode, &charset);
+       yaz_log(LOG_DEBUG, "yaz_srw_decode returned %d", r);
+    }
+    if (r == 2)  /* not taken */
+    {
+       r = yaz_sru_decode(hreq, &sr, &soap_package, assoc->decode, &charset,
+                          &diagnostic, &num_diagnostic);
+       yaz_log(LOG_DEBUG, "yaz_sru_decode returned %d", r);
+    }
+    if (r == 0)  /* decode SRW/SRU OK .. */
+    {
+       int http_code = 200;
+       if (sr->which == Z_SRW_searchRetrieve_request)
+       {
+           Z_SRW_PDU *res =
+               yaz_srw_get(assoc->encode, Z_SRW_searchRetrieve_response);
 
-            ret = z_soap_codec_enc(assoc->encode, &soap_package,
-                                   &hres->content_buf, &hres->content_len,
-                                   soap_handlers, charset);
-            if (!charset)
-                z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/xml");
-            else
-            {
-                char ctype[60];
-                strcpy(ctype, "text/xml; charset=");
-                strcat(ctype, charset);
-                z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype);
-            }
-        }
-        else if (p1 && !strcmp(operation, "explain"))
-        {
+           stylesheet = sr->u.request->stylesheet;
+           if (num_diagnostic)
+           {
+               res->u.response->diagnostics = diagnostic;
+               res->u.response->num_diagnostics = num_diagnostic;
+           }
+           else
+           {
+               srw_bend_search(assoc, req, sr->u.request, res->u.response, 
+                               &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(o, Z_SRW_explain_response);
-            Z_SRW_PDU *sr = yaz_srw_get(o, Z_SRW_explain_request);
-
-            sr->u.explain_request->recordPacking =
-               yaz_uri_val(p1, "recordPacking", o);
-            if (!sr->u.explain_request->recordPacking)
-                sr->u.explain_request->recordPacking = "xml";
-
-            srw_bend_explain(assoc, req, sr->u.explain_request,
-                            res->u.explain_response);
-
-            if (res->u.explain_response->record.recordData_buf)
-            {
-                soap_package = odr_malloc(o, sizeof(*soap_package));
-                soap_package->which = Z_SOAP_generic;
-                
-                soap_package->u.generic =
-                    odr_malloc(o, sizeof(*soap_package->u.generic));
-                
-                soap_package->u.generic->p = res;
-                soap_package->u.generic->ns = soap_handlers[0].ns;
-                soap_package->u.generic->no = 0;
-                
-                soap_package->ns = "SRU";
-                
-                p = z_get_HTTP_Response(o, 200);
-                hres = p->u.HTTP_Response;
-                
-                ret = z_soap_codec_enc(assoc->encode, &soap_package,
-                                       &hres->content_buf, &hres->content_len,
-                                       soap_handlers, charset);
-                if (!charset)
-                    z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/xml");
-                else
-                {
-                    char ctype[60];
-                    strcpy(ctype, "text/xml; charset=");
-                    strcat(ctype, charset);
-                    z_HTTP_header_add(o, &hres->headers, "Content-Type",
-                                      ctype);
-                }
-            }
-        }
-#endif
-#ifdef DOCDIR
-       if (strlen(hreq->path) >= 5 && strlen(hreq->path) < 80 &&
-                        !memcmp(hreq->path, "/doc/", 5))
-        {
-           FILE *f;
-            char fpath[120];
-
-           strcpy(fpath, DOCDIR);
-           strcat(fpath, hreq->path+4);
-           f = fopen(fpath, "rb");
-           if (f) {
-                struct stat sbuf;
-                if (fstat(fileno(f), &sbuf) || !S_ISREG(sbuf.st_mode))
-                {
-                    fclose(f);
-                    f = 0;
-                }
-            }
-            if (f)
-            {
-               long sz;
-               fseek(f, 0L, SEEK_END);
-               sz = ftell(f);
-               if (sz >= 0 && sz < 500000)
-               {
-                   const char *ctype = "application/octet-stream";
-                   const char *cp;
-
-                    p = z_get_HTTP_Response(o, 200);
-                    hres = p->u.HTTP_Response;
-                   hres->content_buf = (char *) odr_malloc(o, sz + 1);
-                   hres->content_len = sz;
-                   fseek(f, 0L, SEEK_SET);
-                   fread(hres->content_buf, 1, sz, f);
-                   if ((cp = strrchr(fpath, '.'))) {
-                       cp++;
-                       if (!strcmp(cp, "png"))
-                           ctype = "image/png";
-                       else if (!strcmp(cp, "gif"))
-                           ctype = "image/gif";
-                       else if (!strcmp(cp, "xml"))
-                           ctype = "text/xml";
-                       else if (!strcmp(cp, "html"))
-                           ctype = "text/html";
-                   }
-                    z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype);
-               }
-               fclose(f);
+           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, req, sr->u.explain_request,
+                            res->u.explain_response, &http_code);
+           if (http_code == 200)
+               soap_package->u.generic->p = res;
        }
-#endif
-
-#if 0
-       if (!strcmp(hreq->path, "/")) 
-        {
-#ifdef DOCDIR
-            struct stat sbuf;
-#endif
-            const char *doclink = "";
-            p = z_get_HTTP_Response(o, 200);
-            hres = p->u.HTTP_Response;
-            hres->content_buf = (char *) odr_malloc(o, 400);
-#ifdef DOCDIR
-            if (stat(DOCDIR "/yaz.html", &sbuf) == 0 && S_ISREG(sbuf.st_mode))
-                doclink = "<P><A HREF=\"/doc/yaz.html\">Documentation</A></P>";
-#endif
-            sprintf (hres->content_buf, 
-                     "<!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"
-                     "<HTML>\n"
-                     " <HEAD>\n"
-                     "  <TITLE>YAZ " YAZ_VERSION "</TITLE>\n"
-                     " </HEAD>\n"
-                     " <BODY>\n"
-                     "  <P><A HREF=\"http://www.indexdata.dk/yaz/\">YAZ</A> " 
-                     YAZ_VERSION "</P>\n"
-                     "%s"
-                     " </BODY>\n"
-                     "</HTML>\n", doclink);
-            hres->content_len = strlen(hres->content_buf);
-            z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/html");
-        }
-#endif
-
-        if (!p)
-        {
-            p = z_get_HTTP_Response(o, 404);
-        }
-    }
-    else if (!strcmp(hreq->method, "POST"))
-    {
-        const char *content_type = z_HTTP_header_lookup(hreq->headers,
-                                                        "Content-Type");
-        if (content_type && !yaz_strcmp_del("text/xml", content_type, "; "))
-        {
-            Z_SOAP *soap_package = 0;
-            int ret = -1;
-            int http_code = 500;
-            const char *charset_p = 0;
-            char *charset = 0;
-
-            static Z_SOAP_Handler soap_handlers[2] = {
+       else if (sr->which == Z_SRW_scan_request)
+       {
+            Z_SRW_PDU *res = yaz_srw_get(o, Z_SRW_scan_response);
+           stylesheet = sr->u.scan_request->stylesheet;
+           if (num_diagnostic)
+           {   
+               res->u.scan_response->diagnostics = diagnostic;
+               res->u.scan_response->num_diagnostics = num_diagnostic;
+           }
+           yaz_add_srw_diagnostic(o, 
+                                  &res->u.scan_response->diagnostics,
+                                  &res->u.scan_response->num_diagnostics,
+                                  4, "scan");
+           if (http_code == 200)
+               soap_package->u.generic->p = res;
+       }
+       else
+       {
+                yaz_log(LOG_LOG, "generate soap error");
+           http_code = 500;
+           z_soap_error(assoc->encode, soap_package,
+                        "SOAP-ENV:Client", "Bad method", 0); 
+       }
+       if (http_code == 200 || http_code == 500)
+       {
+           static Z_SOAP_Handler soap_handlers[3] = {
 #if HAVE_XML2
-                {"http://www.loc.gov/zing/srw/", 0,
+               {"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},
 #endif
-                {0, 0, 0}
-            };
-            if ((charset_p = strstr(content_type, "; charset=")))
-            {
-                int i = 0;
-                charset_p += 10;
-                while (i < 20 && charset_p[i] &&
-                       !strchr("; \n\r", charset_p[i]))
-                    i++;
-                charset = odr_malloc(assoc->encode, i+1);
-                memcpy(charset, charset_p, i);
-                charset[i] = '\0';
-                yaz_log(LOG_LOG, "SOAP encoding %s", charset);
-            }
-            ret = z_soap_codec(assoc->decode, &soap_package, 
-                               &hreq->content_buf, &hreq->content_len,
-                               soap_handlers);
-#if HAVE_XML2
-            if (!ret && soap_package->which == Z_SOAP_generic &&
-                soap_package->u.generic->no == 0)
-            {
-                /* SRW package */
-               char *db = "Default";
-               const char *p0 = hreq->path, *p1;
-                Z_SRW_PDU *sr = soap_package->u.generic->p;
-               
-               if (*p0 == '/')
-                   p0++;
-               p1 = strchr(p0, '?');
-               if (!p1)
-                   p1 = p0 + strlen(p0);
-               if (p1 != p0)
-               {
-                   db = (char*) odr_malloc(assoc->decode, p1 - p0 + 1);
-                   memcpy (db, p0, p1 - p0);
-                   db[p1 - p0] = '\0';
-               }
-
-                if (sr->which == Z_SRW_searchRetrieve_request)
-                {
-                    Z_SRW_PDU *res =
-                        yaz_srw_get(assoc->encode,
-                                    Z_SRW_searchRetrieve_response);
-
-                    if (!sr->u.request->database)
-                       sr->u.request->database = db;
-
-                    srw_bend_search(assoc, req, sr->u.request,
-                                    res->u.response);
-                    
-                    soap_package->u.generic->p = res;
-                    http_code = 200;
-                }
-                else if (sr->which == Z_SRW_explain_request)
-                {
-                    Z_SRW_PDU *res =
-                        yaz_srw_get(assoc->encode, Z_SRW_explain_response);
-
-                    if (!sr->u.explain_request->database)
-                       sr->u.explain_request->database = db;
-
-                    srw_bend_explain(assoc, req, sr->u.explain_request,
-                                     res->u.explain_response);
-                    if (!res->u.explain_response->record.recordData_buf)
-                    {
-                        z_soap_error(assoc->encode, soap_package,
-                                     "SOAP-ENV:Client", "Explain Not Supported", 0);
-                    }
-                    else
-                    {
-                        soap_package->u.generic->p = res;
-                        http_code = 200;
-                    }
-                }
-                else
-                {
-                    z_soap_error(assoc->encode, soap_package,
-                                 "SOAP-ENV:Client", "Bad method", 0); 
-                }
-            }
-#endif
-            p = z_get_HTTP_Response(o, 200);
-            hres = p->u.HTTP_Response;
-            ret = z_soap_codec_enc(assoc->encode, &soap_package,
-                                   &hres->content_buf, &hres->content_len,
-                                   soap_handlers, charset);
-            hres->code = http_code;
-            if (!charset)
-                z_HTTP_header_add(o, &hres->headers, "Content-Type", "text/xml");
-            else
-            {
-                char ctype[60];
-                strcpy(ctype, "text/xml; charset=");
-                strcat(ctype, charset);
-                z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype);
-            }
-        }
-        if (!p) /* still no response ? */
-            p = z_get_HTTP_Response(o, 500);
+               {0, 0, 0}
+           };
+           char ctype[60];
+           int ret;
+           p = z_get_HTTP_Response(o, 200);
+           hres = p->u.HTTP_Response;
+           ret = z_soap_codec_enc_xsl(assoc->encode, &soap_package,
+                                      &hres->content_buf, &hres->content_len,
+                                      soap_handlers, charset, stylesheet);
+           hres->code = http_code;
+
+           strcpy(ctype, "text/xml");
+           if (charset)
+           {
+               strcat(ctype, "; charset=");
+               strcat(ctype, charset);
+           }
+           z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype);
+       }
+       else
+           p = z_get_HTTP_Response(o, http_code);
     }
-    else
-    {
-        p = z_get_HTTP_Response(o, 405);
-        hres = p->u.HTTP_Response;
 
-        z_HTTP_header_add(o, &hres->headers, "Allow", "GET, POST");
-    }
+    if (p == 0)
+       p = z_get_HTTP_Response(o, 500);
     hres = p->u.HTTP_Response;
     if (!strcmp(hreq->version, "1.0")) 
     {
@@ -1143,6 +921,7 @@ static void process_http_request(association *assoc, request *req)
     {
         z_HTTP_header_add(o, &hres->headers, "Connection", "close");
         assoc->state = ASSOC_DEAD;
+       assoc->cs_get_mask = 0;
     }
     else
     {
@@ -1332,10 +1111,11 @@ static int process_gdu_response(association *assoc, request *req, Z_GDU *res)
 {
     odr_setbuf(assoc->encode, req->response, req->size_response, 1);
 
-    if (assoc->print && !z_GDU(assoc->print, &res, 0, 0))
+    if (assoc->print)
     {
-       yaz_log(LOG_WARN, "ODR print error: %s", 
-           odr_errmsg(odr_geterror(assoc->print)));
+       if (!z_GDU(assoc->print, &res, 0, 0))
+           yaz_log(LOG_WARN, "ODR print error: %s", 
+               odr_errmsg(odr_geterror(assoc->print)));
        odr_reset(assoc->print);
     }
     if (!z_GDU(assoc->encode, &res, 0, 0))
@@ -1413,10 +1193,12 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
     {
         Z_CharSetandLanguageNegotiation *negotiation =
             yaz_get_charneg_record (req->otherInfo);
-        if (negotiation->which == Z_CharSetandLanguageNegotiation_proposal)
+        if (negotiation &&
+           negotiation->which == Z_CharSetandLanguageNegotiation_proposal)
             assoc->init->charneg_request = negotiation;
     }
     
+    assoc->backend = 0;
     if (!(binitres = (*cb->bend_init)(assoc->init)))
     {
        yaz_log(LOG_WARN, "Bad response from backend.");
@@ -1507,7 +1289,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
     if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_1))
     {
        ODR_MASK_SET(resp->protocolVersion, Z_ProtocolVersion_1);
-       assoc->version = 2; /* 1 & 2 are equivalent */
+       assoc->version = 1; /* 1 & 2 are equivalent */
     }
     if (ODR_MASK_GET(req->protocolVersion, Z_ProtocolVersion_2))
     {
@@ -1539,7 +1321,7 @@ static Z_APDU *process_initRequest(association *assoc, request *reqb)
                assoc->init->implementation_name,
                odr_prepend(assoc->encode, "GFS", resp->implementationName));
 
-    version = odr_strdup(assoc->encode, "$Revision: 1.8 $");
+    version = odr_strdup(assoc->encode, "$Revision: 1.23 $");
     if (strlen(version) > 10)  /* check for unexpanded CVS strings */
        version[strlen(version)-2] = '\0';
     resp->implementationVersion = odr_prepend(assoc->encode,
@@ -1634,6 +1416,7 @@ static Z_External *init_diagnostics(ODR odr, int error, char *addinfo)
 
     e->which = Z_DiagnosticFormat_s_defaultDiagRec;
     e->u.defaultDiagRec = justdiag(odr, error, addinfo);
+    e->message = 0;
     return x;
 }
 
@@ -1783,7 +1566,8 @@ static Z_Records *pack_records(association *a, char *setname, int start,
            this_length = odr_total(a->encode) - total_length - dumped_records;
        yaz_log(LOG_DEBUG, "  fetched record, len=%d, total=%d dumped=%d",
            this_length, total_length, dumped_records);
-       if (this_length + total_length > a->preferredMessageSize)
+       if (a->preferredMessageSize > 0 &&
+               this_length + total_length > a->preferredMessageSize)
        {
            /* record is small enough, really */
            if (this_length <= a->preferredMessageSize && recno > start)