-/* $Id: yaz-proxy.cpp,v 1.12 2004-11-30 21:10:45 adam Exp $
- Copyright (c) 1998-2004, Index Data.
+/* $Id: yaz-proxy.cpp,v 1.19 2005-02-07 13:29:38 adam Exp $
+ Copyright (c) 1998-2005, Index Data.
This file is part of the yaz-proxy.
*/
#ifdef WIN32
-#else
-#include <unistd.h>
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TYPES_H 1
#endif
-#if HAVE_GETTIMEOFDAY
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
#include <assert.h>
#include <time.h>
-#include <sys/types.h>
#include <fcntl.h>
#include <yaz/srw.h>
#include <yaz/marcdisp.h>
#include <yaz/yaz-iconv.h>
-#include <yaz/ylog.h>
+#include <yaz/log.h>
#include <yaz/diagbib1.h>
-#include <yazproxy/proxy.h>
+#include "proxyp.h"
#include <yaz/pquery.h>
#include <yaz/otherinfo.h>
-#if HAVE_XSLT
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxslt/xsltutils.h>
-#include <libxslt/transform.h>
-#endif
-
static const char *apdu_name(Z_APDU *apdu)
{
switch (apdu->which)
#else
m_time_tv = 0;
#endif
+ m_usemarcon_ini_stage1 = 0;
+ m_usemarcon_ini_stage2 = 0;
+ m_usemarcon = new Yaz_usemarcon();
if (!m_parent)
low_socket_open();
}
xfree (m_schema);
xfree (m_backend_type);
xfree (m_backend_charset);
+ xfree (m_usemarcon_ini_stage1);
+ xfree (m_usemarcon_ini_stage2);
+ delete m_usemarcon;
if (m_s2z_odr_init)
odr_destroy(m_s2z_odr_init);
if (m_s2z_odr_search)
void Yaz_Proxy::convert_xsl_delay()
{
- Z_NamePlusRecord *npr = m_stylesheet_nprl->records[m_stylesheet_offset];
#if HAVE_XSLT
+ Z_NamePlusRecord *npr = m_stylesheet_nprl->records[m_stylesheet_offset];
if (npr->which == Z_NamePlusRecord_databaseRecord)
{
Z_External *r = npr->u.databaseRecord;
Z_External *r = npr->u.databaseRecord;
if (r->which == Z_External_octet)
{
+#if HAVE_USEMARCON
+ if (m_usemarcon_ini_stage1 && *m_usemarcon_ini_stage1)
+ {
+ if (!m_usemarcon->m_stage1)
+ {
+ m_usemarcon->m_stage1 = new CDetails();
+ }
+ m_usemarcon->m_stage1->SetIniFileName(m_usemarcon_ini_stage1);
+ m_usemarcon->m_stage1->SetMarcRecord((char*) r->u.octet_aligned->buf, r->u.octet_aligned->len);
+ int res = m_usemarcon->m_stage1->Start();
+ if (res == 0)
+ {
+ char *converted;
+ int convlen;
+ m_usemarcon->m_stage1->GetMarcRecord(converted, convlen);
+ if (m_usemarcon_ini_stage2 && *m_usemarcon_ini_stage2)
+ {
+ if (!m_usemarcon->m_stage2)
+ {
+ m_usemarcon->m_stage2 = new CDetails();
+ }
+ m_usemarcon->m_stage2->SetIniFileName(m_usemarcon_ini_stage2);
+ m_usemarcon->m_stage2->SetMarcRecord(converted, convlen);
+ res = m_usemarcon->m_stage2->Start();
+ if (res == 0)
+ {
+ free(converted);
+ m_usemarcon->m_stage2->GetMarcRecord(converted, convlen);
+ }
+ else
+ {
+ yaz_log(YLOG_LOG, "%sUSEMARCON stage 2 error %d", m_session_str, res);
+ }
+ }
+ npr->u.databaseRecord =
+ z_ext_record(odr_encode(),
+ m_frontend_type,
+ converted,
+ strlen(converted));
+ free(converted);
+ }
+ else
+ {
+ yaz_log(YLOG_LOG, "%sUSEMARCON stage 1 error %d", m_session_str, res);
+ }
+ continue;
+ }
+#endif
npr->u.databaseRecord =
z_ext_record(odr_encode(),
m_frontend_type,
{
if (p && p->which == Z_Records_DBOSD)
{
- if (m_backend_type)
+ if (m_backend_type
+#if HAVE_USEMARCON
+ || m_usemarcon_ini_stage1 || m_usemarcon_ini_stage2
+#endif
+ )
convert_to_frontend_type(p->u.databaseOrSurDiagnostics);
if (m_marcxml_flag)
convert_to_marcxml(p->u.databaseOrSurDiagnostics,
}
if (p && p->which == Z_Records_DBOSD)
{
- if (m_backend_type)
+ if (m_backend_type
+#if HAVE_USEMARCON
+ || m_usemarcon_ini_stage1 || m_usemarcon_ini_stage2
+#endif
+ )
convert_to_frontend_type(p->u.databaseOrSurDiagnostics);
if (m_marcxml_flag)
convert_to_marcxml(p->u.databaseOrSurDiagnostics,
reduce = (reduce > nreduce) ? reduce : nreduce;
}
}
+ m_http_version = 0;
if (reduce)
{
yaz_log(YLOG_LOG, "%sdelay=%d bw=%d pdu=%d limit-bw=%d limit-pdu=%d",
m_default_target,
sr->preferredRecordSyntax, rc,
&addinfo, &stylesheet_name, &m_schema,
- &m_backend_type, &m_backend_charset);
+ &m_backend_type, &m_backend_charset,
+ &m_usemarcon_ini_stage1,
+ &m_usemarcon_ini_stage2);
if (stylesheet_name)
{
m_parent->low_socket_close();
pr->preferredRecordSyntax,
pr->recordComposition,
&addinfo, &stylesheet_name, &m_schema,
- &m_backend_type, &m_backend_charset);
+ &m_backend_type, &m_backend_charset,
+ &m_usemarcon_ini_stage1,
+ &m_usemarcon_ini_stage2
+ );
if (stylesheet_name)
{
m_parent->low_socket_close();
m_default_target = xstrdup(t);
}
}
+
+int Yaz_Proxy::file_access(Z_HTTP_Request *hreq)
+{
+ struct stat sbuf;
+ yaz_log(YLOG_LOG, "file_access");
+ if (strcmp(hreq->method, "GET"))
+ return 0;
+ if (hreq->path[0] != '/')
+ {
+ yaz_log(YLOG_WARN, "Bad path: %s", hreq->path);
+ return 0;
+ }
+ const char *cp = hreq->path;
+ while (*cp)
+ {
+ if (*cp == '/' && strchr("/.", cp[1]))
+ {
+ yaz_log(YLOG_WARN, "Bad path: %s", hreq->path);
+ return 0;
+ }
+ cp++;
+ }
+ const char *fname = hreq->path+1;
+ if (stat(fname, &sbuf))
+ {
+ yaz_log(YLOG_WARN|YLOG_ERRNO, "%s: stat failed", fname);
+ return 0;
+ }
+ if ((sbuf.st_mode & S_IFMT) != S_IFREG)
+ {
+ yaz_log(YLOG_WARN, "%s: not a regular file", fname);
+ return 0;
+ }
+ if (sbuf.st_size > (off_t) 1000000)
+ {
+ yaz_log(YLOG_WARN, "%s: too large for transfer", fname);
+ return 0;
+ }
+
+ ODR o = odr_encode();
+ Yaz_ProxyConfig *cfg = check_reconfigure();
+ const char *ctype = cfg->check_mime_type(fname);
+ Z_GDU *gdu = z_get_HTTP_Response(o, 200);
+ Z_HTTP_Response *hres = gdu->u.HTTP_Response;
+ if (m_http_version)
+ hres->version = odr_strdup(o, m_http_version);
+ z_HTTP_header_add(o, &hres->headers, "Content-Type", ctype);
+ if (m_http_keepalive)
+ z_HTTP_header_add(o, &hres->headers, "Connection", "Keep-Alive");
+ else
+ timeout(0);
+
+ hres->content_len = sbuf.st_size;
+ hres->content_buf = (char*) odr_malloc(o, hres->content_len);
+ FILE *f = fopen(fname, "rb");
+ if (f)
+ {
+ fread(hres->content_buf, 1, hres->content_len, f);
+ fclose(f);
+ }
+ else
+ {
+ return 0;
+ }
+ if (m_log_mask & PROXY_LOG_REQ_CLIENT)
+ {
+ yaz_log (YLOG_LOG, "%sSending file %s to client", m_session_str,
+ fname);
+ }
+ int len;
+ send_GDU(gdu, &len);
+ return 1;
+}
void Yaz_Proxy::handle_incoming_HTTP(Z_HTTP_Request *hreq)
{
char *charset = 0;
Z_SRW_diagnostic *diagnostic = 0;
int num_diagnostic = 0;
- if (yaz_srw_decode(hreq, &srw_pdu, &soap_package, odr_decode(),
- &charset) == 0
- || yaz_sru_decode(hreq, &srw_pdu, &soap_package, odr_decode(),
- &charset, &diagnostic, &num_diagnostic) == 0)
+
+ if (file_access(hreq))
+ {
+ return;
+ }
+ else if (yaz_srw_decode(hreq, &srw_pdu, &soap_package, odr_decode(),
+ &charset) == 0
+ || yaz_sru_decode(hreq, &srw_pdu, &soap_package, odr_decode(),
+ &charset, &diagnostic, &num_diagnostic) == 0)
{
m_s2z_odr_init = odr_createmem(ODR_ENCODE);
m_s2z_odr_search = odr_createmem(ODR_ENCODE);
send_to_srw_client_error(4, 0);
}
}
- int len = 0;
- Z_GDU *p = z_get_HTTP_Response(odr_encode(), 400);
- timeout(0);
- send_GDU(p, &len);
+ send_http_response(400);
}
void Yaz_Proxy::handle_incoming_Z_PDU(Z_APDU *apdu)
m_client = get_client(apdu, get_cookie(oi), get_proxy(oi));
if (!m_client)
{
- delete this;
- return;
+ if (m_http_version)
+ {
+ send_http_response(404);
+ return;
+ }
+ else
+ {
+ delete this;
+ return;
+ }
}
m_client->m_server = this;
// delete other info construct completely if 0 elements
get_otherInfoAPDU(apdu, &oi);
- if (*oi && (*oi)->num_elements == 0)
+ if (oi && *oi && (*oi)->num_elements == 0)
*oi = 0;
if (apdu->which == Z_APDU_presentRequest &&