1 /* $Id: filter_sru_to_z3950.cpp,v 1.4 2006-09-14 11:51:08 marc Exp $
2 Copyright (c) 2005-2006, Index Data.
4 See the LICENSE file for details
11 #include "filter_sru_to_z3950.hpp"
16 #include <boost/thread/mutex.hpp>
23 namespace mp = metaproxy_1;
24 namespace yf = mp::filter;
30 std::string to_string(const T& t)
39 std::string http_header_value(const Z_HTTP_Header* header,
40 const std::string name)
42 while (header && header->name
43 && std::string(header->name) != name)
44 header = header->next;
46 if (header && header->name && std::string(header->name) == name
48 return std::string(header->value);
57 namespace metaproxy_1 {
59 class SRUtoZ3950::Rep {
60 //friend class SRUtoZ3950;
62 void configure(const xmlNode *xmlnode);
63 void process(metaproxy_1::Package &package) const;
65 std::string sru_protocol(const Z_HTTP_Request &http_req) const;
66 std::string debug_http(const Z_HTTP_Request &http_req) const;
67 void http_response(metaproxy_1::Package &package,
68 const std::string &content,
69 int http_code = 200) const;
74 yf::SRUtoZ3950::SRUtoZ3950() : m_p(new Rep)
78 yf::SRUtoZ3950::~SRUtoZ3950()
79 { // must have a destructor because of boost::scoped_ptr
82 void yf::SRUtoZ3950::configure(const xmlNode *xmlnode)
84 m_p->configure(xmlnode);
87 void yf::SRUtoZ3950::process(mp::Package &package) const
89 m_p->process(package);
92 void yf::SRUtoZ3950::Rep::configure(const xmlNode *xmlnode)
96 void yf::SRUtoZ3950::Rep::process(mp::Package &package) const
98 Z_GDU *zgdu_req = package.request().get();
100 // ignoring all non HTTP_Request packages
101 if (!zgdu_req || !(zgdu_req->which == Z_GDU_HTTP_Request)){
106 // only working on HTTP_Request packages now
107 Z_HTTP_Request* http_req = zgdu_req->u.HTTP_Request;
109 // SRU request package checking
111 // std::cout << "Detected " << sru_protocol(*http_req) << "\n";
113 Z_SRW_PDU *sru_pdu_req = 0;
114 Z_SOAP *soap_req = 0;
116 Z_SRW_diagnostic *diag = 0;
118 mp::odr odr(ODR_DECODE);
120 if (0 == yaz_sru_decode(http_req, &sru_pdu_req, &soap_req,
121 odr, &charset, &diag, &num_diags))
123 std::cout << "SRU GET/POST \n";
125 else if (0 == yaz_srw_decode(http_req, &sru_pdu_req, &soap_req,
128 std::cout << "SRU SOAP \n";
132 std::cout << "SRU DECODING ERROR - SHOULD NEVER HAPPEN\n";
133 package.session().close();
139 std::cout << "SRU DIAGNOSTICS " << num_diags << "\n";
140 // TODO: make nice diagnostic return package
141 //Z_SRW_PDU *srw_pdu_res =
142 // yaz_srw_get(odr(ODR_ENCODE),
143 // Z_SRW_searchRetrieve_response);
144 // Z_SRW_searchRetrieveResponse *srw_res = srw_pdu_res->u.response;
146 // srw_res->diagnostics = diagnostic;
147 // srw_res->num_diagnostics = num_diagnostic;
148 // send_srw_response(srw_pdu_res);
151 // package.session().close();
156 // SRU request package translation to Z3950 package
159 if (sru_pdu_req && sru_pdu_req->which == Z_SRW_searchRetrieve_request)
161 Z_SRW_searchRetrieveRequest *srw_req = sru_pdu_req->u.request;
163 // recordXPath unsupported.
164 //if (srw_req->recordXPath)
165 // yaz_add_srw_diagnostic(odr_decode(),
166 // &diag, &num_diags, 72, 0);
168 // if (srw_req->sort_type != Z_SRW_sort_type_none)
169 // yaz_add_srw_diagnostic(odr_decode(),
170 // &diag, &num_diags, 80, 0);
174 std::cout << "SRU OPERATION NOT SUPPORTED \n";
175 // TODO: make nice diagnostic return package
176 // package.session().close();
182 // sending Z3950 package through pipeline
186 // TODO: Z3950 response parsing and translation to SRU package
187 //Z_HTTP_Response* http_res = 0;
189 std::string content = debug_http(*http_req);
192 http_response(package, content, http_code);
194 //package.response() = zgdu_res;
198 yf::SRUtoZ3950::Rep::sru_protocol(const Z_HTTP_Request &http_req) const
200 const std::string mime_urlencoded("application/x-www-form-urlencoded");
201 const std::string mime_text_xml("text/xml");
202 const std::string mime_soap_xml("application/soap+xml");
204 const std::string http_method(http_req.method);
205 const std::string http_type
206 = http_header_value(http_req.headers, "Content-Type");
208 if (http_method == "GET")
211 if (http_method == "POST"
212 && http_type == mime_urlencoded)
215 if ( http_method == "POST"
216 && (http_type == mime_text_xml
217 || http_type == mime_soap_xml))
224 yf::SRUtoZ3950::Rep::debug_http(const Z_HTTP_Request &http_req) const
226 std::string message("<html>\n<body>\n<h1>"
227 "Metaproxy SRUtoZ3950 filter"
230 message += "<h3>HTTP Info</h3><br/>\n";
232 message += "<b>Method: </b> " + std::string(http_req.method) + "<br/>\n";
233 message += "<b>Version:</b> " + std::string(http_req.version) + "<br/>\n";
234 message += "<b>Path: </b> " + std::string(http_req.path) + "<br/>\n";
236 message += "<b>Content-Type:</b>"
237 + http_header_value(http_req.headers, "Content-Type")
239 message += "<b>Content-Length:</b>"
240 + http_header_value(http_req.headers, "Content-Length")
244 message += "<h3>Headers</h3><br/>\n";
246 Z_HTTP_Header* header = http_req.headers;
248 message += "<b>Header: </b> <i>"
249 + std::string(header->name) + ":</i> "
250 + std::string(header->value) + "<br/>\n";
251 header = header->next;
254 message += "</body>\n</html>\n";
258 void yf::SRUtoZ3950::Rep::http_response(metaproxy_1::Package &package,
259 const std::string &content,
263 Z_GDU *zgdu_req = package.request().get();
267 = odr.create_HTTP_Response(package.session(),
268 zgdu_req->u.HTTP_Request,
271 zgdu_res->u.HTTP_Response->content_len = content.size();
272 zgdu_res->u.HTTP_Response->content_buf
273 = (char*) odr_malloc(odr, zgdu_res->u.HTTP_Response->content_len);
275 strncpy(zgdu_res->u.HTTP_Response->content_buf,
276 content.c_str(), zgdu_res->u.HTTP_Response->content_len);
278 //z_HTTP_header_add(odr, &hres->headers,
279 // "Content-Type", content_type.c_str());
280 package.response() = zgdu_res;
286 static mp::filter::Base* filter_creator()
288 return new mp::filter::SRUtoZ3950;
292 struct metaproxy_1_filter_struct metaproxy_1_filter_sru_to_z3950 = {
303 * indent-tabs-mode: nil
304 * c-file-style: "stroustrup"
306 * vim: shiftwidth=4 tabstop=8 expandtab