+ // only working on HTTP_Request packages now
+
+ // see if HTTP request is already being executed..
+ // we consider only the SRU - GET case..
+ if (zgdu_req->u.HTTP_Request->content_len == 0)
+ {
+ const char *path = zgdu_req->u.HTTP_Request->path;
+ boost::mutex::scoped_lock lock(m_mutex);
+ while (1)
+ {
+ ActiveUrlMap::iterator it = m_active_urls.find(path);
+ if (it == m_active_urls.end())
+ {
+ m_active_urls[path] = 1;
+ break;
+ }
+ yaz_log(YLOG_LOG, "Waiting for %s to complete", path);
+ m_cond_url_ready.wait(lock);
+ }
+ }
+ sru(package, zgdu_req);
+ if (zgdu_req->u.HTTP_Request->content_len == 0)
+ {
+ const char *path = zgdu_req->u.HTTP_Request->path;
+ boost::mutex::scoped_lock lock(m_mutex);
+
+ ActiveUrlMap::iterator it = m_active_urls.find(path);
+
+ m_active_urls.erase(it);
+ m_cond_url_ready.notify_all();
+ }
+}
+
+
+bool
+yf::SRUtoZ3950::Impl::z3950_init_request(mp::Package &package,
+ mp::odr &odr_en,
+ std::string zurl,
+ Z_SRW_PDU *sru_pdu_res,
+ const Z_SRW_PDU *sru_pdu_req) const
+{
+ // prepare Z3950 package
+ Package z3950_package(package.session(), package.origin());
+ z3950_package.copy_filter(package);
+
+ // set initRequest APDU
+ Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_initRequest);
+ Z_InitRequest *init_req = apdu->u.initRequest;
+
+ Z_IdAuthentication *auth = NULL;
+ if (sru_pdu_req->username && !sru_pdu_req->password)
+ {
+ auth = (Z_IdAuthentication *) odr_malloc(odr_en, sizeof(Z_IdAuthentication));
+ auth->which = Z_IdAuthentication_open;
+ auth->u.open = odr_strdup(odr_en, sru_pdu_req->username);
+ }
+ else if (sru_pdu_req->username && sru_pdu_req->password)
+ {
+ auth = (Z_IdAuthentication *) odr_malloc(odr_en, sizeof(Z_IdAuthentication));
+ auth->which = Z_IdAuthentication_idPass;
+ auth->u.idPass = (Z_IdPass *) odr_malloc(odr_en, sizeof(Z_IdPass));
+ auth->u.idPass->groupId = NULL;
+ auth->u.idPass->password = odr_strdup(odr_en, sru_pdu_req->password);
+ auth->u.idPass->userId = odr_strdup(odr_en, sru_pdu_req->username);
+ }
+
+ init_req->idAuthentication = auth;
+
+ *init_req->preferredMessageSize = 10*1024*1024;
+ *init_req->maximumRecordSize = 10*1024*1024;
+
+ ODR_MASK_SET(init_req->options, Z_Options_search);
+ ODR_MASK_SET(init_req->options, Z_Options_present);
+ ODR_MASK_SET(init_req->options, Z_Options_namedResultSets);
+ ODR_MASK_SET(init_req->options, Z_Options_scan);
+
+ ODR_MASK_SET(init_req->protocolVersion, Z_ProtocolVersion_1);
+ ODR_MASK_SET(init_req->protocolVersion, Z_ProtocolVersion_2);
+ ODR_MASK_SET(init_req->protocolVersion, Z_ProtocolVersion_3);
+
+ if (zurl.length())
+ {
+ std::string host;
+ std::list<std::string> dblist;
+ mp_util::split_zurl(zurl, host, dblist);
+ mp_util::set_vhost_otherinfo(&init_req->otherInfo, odr_en, host, 1);
+ }
+
+ z3950_package.request() = apdu;
+
+ // send Z3950 package
+ z3950_package.move();
+
+ // dead Z3950 backend detection
+ if (z3950_package.session().is_closed())
+ {
+ yaz_add_srw_diagnostic(odr_en,
+ &(sru_pdu_res->u.response->diagnostics),
+ &(sru_pdu_res->u.response->num_diagnostics),
+ YAZ_SRW_SYSTEM_TEMPORARILY_UNAVAILABLE, 0);
+ return false;
+ }
+
+ // check successful initResponse
+ Z_GDU *z3950_gdu = z3950_package.response().get();
+
+ if (z3950_gdu && z3950_gdu->which == Z_GDU_Z3950
+ && z3950_gdu->u.z3950->which == Z_APDU_initResponse
+ && *z3950_gdu->u.z3950->u.initResponse->result)
+ return true;
+
+ yaz_add_srw_diagnostic(odr_en,
+ &(sru_pdu_res->u.response->diagnostics),
+ &(sru_pdu_res->u.response->num_diagnostics),
+ YAZ_SRW_SYSTEM_TEMPORARILY_UNAVAILABLE, 0);
+ return false;
+}
+
+bool
+yf::SRUtoZ3950::Impl::z3950_close_request(mp::Package &package) const
+{
+ // prepare and close Z3950 package
+ Package z3950_package(package.session(), package.origin());
+ z3950_package.copy_filter(package);
+ z3950_package.session().close();
+
+ // set close APDU
+ //mp::odr odr_en(ODR_ENCODE);
+ //Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_close);
+ //z3950_package.request() = apdu;
+
+ z3950_package.move();
+
+ // check successful close response
+ //Z_GDU *z3950_gdu = z3950_package.response().get();
+ //if (z3950_gdu && z3950_gdu->which == Z_GDU_Z3950
+ // && z3950_gdu->u.z3950->which == Z_APDU_close)
+ // return true;
+
+ if (z3950_package.session().is_closed())
+ {
+ return true;
+ }
+ return false;
+}
+
+bool yf::SRUtoZ3950::Impl::z3950_search_request(mp::Package &package,
+ mp::odr &odr_en,
+ Z_SRW_PDU *sru_pdu_res,
+ Z_SRW_searchRetrieveRequest
+ const *sr_req,
+ std::string zurl) const
+{
+
+ assert(sru_pdu_res->u.response);
+
+ Package z3950_package(package.session(), package.origin());
+ z3950_package.copy_filter(package);
+
+ //add stuff in z3950 apdu
+ Z_APDU *apdu = zget_APDU(odr_en, Z_APDU_searchRequest);
+ Z_SearchRequest *z_searchRequest = apdu->u.searchRequest;
+
+ // RecordSyntax will always be XML
+ z_searchRequest->preferredRecordSyntax
+ = odr_oiddup(odr_en, yaz_oid_recsyn_xml);
+
+ if (!mp_util::set_databases_from_zurl(odr_en, zurl,
+ &z_searchRequest->num_databaseNames,
+ &z_searchRequest->databaseNames))
+ {
+ z_searchRequest->num_databaseNames = 1;
+ z_searchRequest->databaseNames = (char**)
+ odr_malloc(odr_en, sizeof(char *));
+
+ if (sr_req->database)
+ z_searchRequest->databaseNames[0]
+ = odr_strdup(odr_en, const_cast<char *>(sr_req->database));
+ else
+ z_searchRequest->databaseNames[0]
+ = odr_strdup(odr_en, "Default");
+ }
+
+ // z3950'fy query
+ Z_Query *z_query = (Z_Query *) odr_malloc(odr_en, sizeof(Z_Query));
+ z_searchRequest->query = z_query;
+
+ int sru_diagnostic = z3950_build_query(odr_en, z_query, sr_req);
+ if (sru_diagnostic)
+ {
+ yaz_add_srw_diagnostic(odr_en,
+ &(sru_pdu_res->u.response->diagnostics),
+ &(sru_pdu_res->u.response->num_diagnostics),
+ sru_diagnostic,
+ "query");
+ return false;
+ }
+
+ z3950_package.request() = apdu;
+
+ // send Z39.50 package off to backend
+ z3950_package.move();
+
+
+ Z_GDU *z3950_gdu = z3950_package.response().get();
+
+ //TODO: check success condition
+ //int yaz_diag_bib1_to_srw (int bib1_code);
+ //int yaz_diag_srw_to_bib1(int srw_code);
+ //Se kode i src/seshigh.c (srw_bend_search, srw_bend_init).
+
+ if (!z3950_gdu || z3950_gdu->which != Z_GDU_Z3950
+ || z3950_gdu->u.z3950->which != Z_APDU_searchResponse
+ || !z3950_gdu->u.z3950->u.searchResponse
+ || !z3950_gdu->u.z3950->u.searchResponse->searchStatus)
+ {
+ yaz_add_srw_diagnostic(odr_en,
+ &(sru_pdu_res->u.response->diagnostics),
+ &(sru_pdu_res->u.response->num_diagnostics),
+ YAZ_SRW_SYSTEM_TEMPORARILY_UNAVAILABLE, 0);
+ return false;
+ }
+
+ // everything fine, continuing
+ Z_SearchResponse *sr = z3950_gdu->u.z3950->u.searchResponse;