/* This file is part of Metaproxy.
- Copyright (C) 2005-2011 Index Data
+ Copyright (C) Index Data
Metaproxy is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
#include <string.h>
#include <yaz/wrbuf.h>
-#include <yaz/zgdu.h>
-#include <yaz/srw.h>
-#include <yaz/comstack.h>
-
+#include <yaz/log.h>
+#include <yaz/url.h>
+#include <metaproxy/util.hpp>
#include "torus.hpp"
namespace mp = metaproxy_1;
-
-static Z_GDU *get_HTTP_Request_url(ODR odr, const char *url)
+xmlDoc *mp::get_searchable(mp::Package &package,
+ std::string url_template, const std::string &db,
+ const std::string &query,
+ const std::string &realm,
+ const std::string &proxy,
+ std::string &addinfo)
{
- Z_GDU *p = z_get_HTTP_Request(odr);
- const char *host = url;
- const char *cp0 = strstr(host, "://");
- const char *cp1 = 0;
- if (cp0)
- cp0 = cp0+3;
- else
- cp0 = host;
-
- cp1 = strchr(cp0, '/');
- if (!cp1)
- cp1 = cp0 + strlen(cp0);
-
- if (cp0 && cp1)
- {
- char *h = (char*) odr_malloc(odr, cp1 - cp0 + 1);
- memcpy (h, cp0, cp1 - cp0);
- h[cp1-cp0] = '\0';
- z_HTTP_header_add(odr, &p->u.HTTP_Request->headers, "Host", h);
- }
- p->u.HTTP_Request->path = odr_strdup(odr, *cp1 ? cp1 : "/");
- return p;
-}
-
-static WRBUF get_url(const char *uri, WRBUF username, WRBUF password,
- int *code)
-{
- int number_of_redirects = 0;
- WRBUF result = 0;
- ODR out = odr_createmem(ODR_ENCODE);
- ODR in = odr_createmem(ODR_DECODE);
-
- while (1)
+ // http://mk2.indexdata.com/torus2/searchable/records/?query=udb%3d%db
+ // or
+ // http://mk2.indexdata.com/torus2/searchable/records/?query=%query
+ xmlDoc *doc = 0;
+ size_t found;
+
+ found = url_template.find("%query");
+ if (found != std::string::npos)
+ url_template.replace(found, 6, mp::util::uri_encode(query));
+
+ found = url_template.find("%db");
+ if (found != std::string::npos)
+ url_template.replace(found, 3, mp::util::uri_encode(db));
+
+ found = url_template.find("%realm");
+ if (found != std::string::npos)
+ url_template.replace(found, 6, mp::util::uri_encode(realm));
+
+ Z_HTTP_Header *http_headers = 0;
+ mp::odr odr;
+
+ z_HTTP_header_add(odr, &http_headers, "Accept","application/xml");
+
+ yaz_url_t url_p = yaz_url_create();
+ if (proxy.length())
+ yaz_url_set_proxy(url_p, proxy.c_str());
+
+ Z_HTTP_Response *http_response = yaz_url_exec(url_p,
+ url_template.c_str(),
+ "GET",
+ http_headers,
+ 0, /* content buf */
+ 0 /* content_len */
+ );
+ if (http_response && http_response->code == 200 &&
+ http_response->content_buf)
{
- Z_HTTP_Response *res = 0;
- const char *location = 0;
- Z_GDU *gdu = get_HTTP_Request_url(out, uri);
- yaz_log(YLOG_LOG, "GET %s", uri);
- gdu->u.HTTP_Request->method = odr_strdup(out, "GET");
- if (username && password)
- {
- z_HTTP_header_add_basic_auth(out, &gdu->u.HTTP_Request->headers,
- wrbuf_cstr(username),
- wrbuf_cstr(password));
- }
- z_HTTP_header_add(out, &gdu->u.HTTP_Request->headers, "Accept",
- "application/xml");
- if (!z_GDU(out, &gdu, 0, 0))
- {
- yaz_log(YLOG_WARN, "Can not encode HTTP request URL:%s", uri);
- break;
- }
- void *add;
- COMSTACK conn = cs_create_host(uri, 1, &add);
- if (!conn)
- yaz_log(YLOG_WARN, "Bad address for URL:%s", uri);
- else if (cs_connect(conn, add) < 0)
- yaz_log(YLOG_WARN, "Can not connect to URL:%s", uri);
+ doc = xmlParseMemory(http_response->content_buf,
+ http_response->content_len);
+ if (doc)
+ package.log("zoom", YLOG_LOG, "Torus: %s OK",
+ url_template.c_str());
else
{
- int len;
- char *buf = odr_getbuf(out, &len, 0);
-
- if (cs_put(conn, buf, len) < 0)
- yaz_log(YLOG_WARN, "cs_put failed URL:%s", uri);
- else
- {
- char *netbuffer = 0;
- int netlen = 0;
- int cs_res = cs_get(conn, &netbuffer, &netlen);
- if (cs_res <= 0)
- {
- yaz_log(YLOG_WARN, "cs_get failed URL:%s", uri);
- }
- else
- {
- Z_GDU *gdu;
- odr_setbuf(in, netbuffer, cs_res, 0);
- if (!z_GDU(in, &gdu, 0, 0)
- || gdu->which != Z_GDU_HTTP_Response)
- {
- yaz_log(YLOG_WARN, "HTTP decoding failed "
- "URL:%s", uri);
- }
- else
- {
- res = gdu->u.HTTP_Response;
- }
- }
- xfree(netbuffer);
- }
- cs_close(conn);
+ package.log("zoom", YLOG_WARN, "Torus: %s FAIL. XML parse failed",
+ url_template.c_str());
+ addinfo = "Torus: XML parse failed";
}
- if (!res)
- break; // ERROR
- *code = res->code;
- location = z_HTTP_header_lookup(res->headers, "Location");
- if (++number_of_redirects < 10 &&
- location && (*code == 301 || *code == 302 || *code == 307))
+ }
+ else
+ {
+ addinfo = "Torus: ";
+ if (http_response)
{
- odr_reset(out);
- uri = odr_strdup(out, location);
- odr_reset(in);
+ package.log("zoom", YLOG_WARN, "Torus: %s FAIL. HTTP code %d",
+ url_template.c_str(), http_response->code);
+ addinfo += std::string(http_response->content_buf,
+ http_response->content_len);
}
else
{
- result = wrbuf_alloc();
- wrbuf_write(result, res->content_buf, res->content_len);
- break;
+ addinfo += "unknown error";
+ package.log("zoom", YLOG_WARN, "Torus: %s FAIL. No HTTP response",
+ url_template.c_str());
}
}
- odr_destroy(out);
- odr_destroy(in);
- return result;
-}
-
-
-mp::Torus::Torus()
-{
- doc = 0;
-}
-
-mp::Torus::~Torus()
-{
- if (doc)
- xmlFreeDoc(doc);
-}
-void mp::Torus::read_searchables(std::string url)
-{
- if (doc)
- {
- xmlFreeDoc(doc);
- doc = 0;
- }
- if (url.length() == 0)
- return;
-
- int code;
- WRBUF w = get_url(url.c_str(), 0, 0, &code);
- if (code == 200)
+ if (http_response && http_response->content_buf)
{
- doc = xmlParseMemory(wrbuf_buf(w), wrbuf_len(w));
- if (doc)
- yaz_log(YLOG_LOG, "xmlParseMemory OK");
+ package.log("zoom", YLOG_LOG, "HTTP content");
+ package.log_write(http_response->content_buf,
+ http_response->content_len);
}
- wrbuf_destroy(w);
-}
-
-xmlDoc *mp::Torus::get_doc()
-{
+ yaz_url_destroy(url_p);
return doc;
}