* Copyright (c) 1998-2003, Index Data.
* See the file LICENSE for details.
*
- * $Id: yaz-proxy.cpp,v 1.49 2003-10-03 13:01:42 adam Exp $
+ * $Id: yaz-proxy.cpp,v 1.52 2003-10-08 09:32:49 adam Exp $
*/
#include <assert.h>
return 0;
}
+const char *Yaz_Proxy::load_balance(const char **url)
+{
+ int zurl_in_use[MAX_ZURL_PLEX];
+ Yaz_ProxyClient *c;
+ int i;
+
+ for (i = 0; i<MAX_ZURL_PLEX; i++)
+ zurl_in_use[i] = 0;
+ for (c = m_parent->m_clientPool; c; c = c->m_next)
+ {
+ for (i = 0; url[i]; i++)
+ if (!strcmp(url[i], c->get_hostname()))
+ zurl_in_use[i]++;
+ }
+ int min = 100000;
+ const char *ret = 0;
+ for (i = 0; url[i]; i++)
+ {
+ yaz_log(LOG_LOG, "%s zurl=%s use=%d",
+ m_session_str, url[i], zurl_in_use[i]);
+ if (min > zurl_in_use[i])
+ {
+ ret = url[i];
+ min = zurl_in_use[i];
+ }
+ }
+ return ret;
+}
+
Yaz_ProxyClient *Yaz_Proxy::get_client(Z_APDU *apdu)
{
assert (m_parent);
if (!m_proxyTarget)
{
+ const char *url[MAX_ZURL_PLEX];
const char *proxy_host = get_proxy(oi);
- if (!proxy_host)
+ if (proxy_host)
{
xfree(m_default_target);
m_default_target = xstrdup(proxy_host);
proxy_host = m_default_target;
}
- const char *url = 0;
int client_idletime = -1;
- m_config.get_target_info(proxy_host, &url, &m_keepalive, &m_bw_max,
+ m_config.get_target_info(proxy_host, url, &m_keepalive, &m_bw_max,
&m_pdu_max, &m_max_record_retrieve,
&m_target_idletime, &client_idletime,
&parent->m_max_clients);
m_client_idletime = client_idletime;
timeout(m_client_idletime);
}
- if (!url)
+ if (!url[0])
{
yaz_log(LOG_LOG, "%s No default target", m_session_str);
return 0;
}
- m_proxyTarget = (char*) xstrdup(url);
+ m_proxyTarget = (char*) xstrdup(load_balance(url));
}
if (cookie && *cookie)
{
}
}
}
- else
+ else // query doesn't match
{
delete m_client->m_last_query;
m_client->m_last_query = this_query;
if (err)
{
Z_APDU *new_apdu = create_Z_PDU(Z_APDU_searchResponse);
- int *nulint = odr_intdup (odr_encode(), 0);
new_apdu->u.searchResponse->referenceId = sr->referenceId;
new_apdu->u.searchResponse->records =
create_nonSurrogateDiagnostics(odr_encode(), err, addinfo);
- new_apdu->u.searchResponse->searchStatus = nulint;
- new_apdu->u.searchResponse->resultCount = nulint;
+ *new_apdu->u.searchResponse->searchStatus = 0;
send_to_client(new_apdu);
return apdu;
}
+Z_APDU *Yaz_Proxy::handle_syntax_validation(Z_APDU *apdu)
+{
+ if (apdu->which == Z_APDU_searchRequest)
+ {
+ Z_SearchRequest *sr = apdu->u.searchRequest;
+ if (*sr->smallSetUpperBound > 0 || *sr->largeSetLowerBound > 1)
+ {
+ int err;
+ char *addinfo = 0;
+ err = m_config.check_syntax(odr_encode(), m_default_target,
+ sr->preferredRecordSyntax,
+ &addinfo);
+ if (err)
+ {
+ 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(), err, addinfo);
+ *new_apdu->u.searchResponse->searchStatus = 0;
+
+ send_to_client(new_apdu);
+
+ return 0;
+ }
+ }
+ }
+ else if (apdu->which == Z_APDU_presentRequest)
+ {
+ Z_PresentRequest *pr = apdu->u.presentRequest;
+ int err;
+ char *addinfo = 0;
+ err = m_config.check_syntax(odr_encode(), m_default_target,
+ pr->preferredRecordSyntax,
+ &addinfo);
+ if (err)
+ {
+ Z_APDU *new_apdu = create_Z_PDU(Z_APDU_presentResponse);
+
+ new_apdu->u.presentResponse->referenceId = pr->referenceId;
+ new_apdu->u.presentResponse->records =
+ create_nonSurrogateDiagnostics(odr_encode(), err, addinfo);
+ *new_apdu->u.presentResponse->presentStatus =
+ Z_PresentStatus_failure;
+
+ send_to_client(new_apdu);
+
+ return 0;
+ }
+ }
+ return apdu;
+}
+
void Yaz_Proxy::recv_Z_PDU_0(Z_APDU *apdu)
{
// Determine our client.
if (apdu->which == Z_APDU_initRequest)
{
+ if (apdu->u.initRequest->implementationId)
+ yaz_log(LOG_LOG, "%s implementationId: %s",
+ m_session_str, apdu->u.initRequest->implementationId);
+ if (apdu->u.initRequest->implementationName)
+ yaz_log(LOG_LOG, "%s implementationName: %s",
+ m_session_str, apdu->u.initRequest->implementationName);
+ if (apdu->u.initRequest->implementationVersion)
+ yaz_log(LOG_LOG, "%s implementationVersion: %s",
+ m_session_str, apdu->u.initRequest->implementationVersion);
if (m_client->m_init_flag)
{
Z_APDU *apdu = m_client->m_initResponse;
handle_max_record_retrieve(apdu);
if (apdu)
+ apdu = handle_syntax_validation(apdu);
+
+ if (apdu)
apdu = handle_query_validation(apdu);
if (apdu)