added more code to do protocol detection, experimented with different SRU and SRW...
[metaproxy-moved-to-github.git] / src / filter_sru_to_z3950.cpp
1 /* $Id: filter_sru_to_z3950.cpp,v 1.2 2006-09-13 14:56:07 marc Exp $
2    Copyright (c) 2005-2006, Index Data.
3
4    See the LICENSE file for details
5  */
6
7 #include "config.hpp"
8 #include "filter.hpp"
9 #include "package.hpp"
10 #include "util.hpp"
11 #include "filter_sru_to_z3950.hpp"
12
13 #include <yaz/zgdu.h>
14 #include <yaz/srw.h>
15
16 #include <boost/thread/mutex.hpp>
17
18 #include <iostream>
19 #include <sstream>
20 #include <string>
21
22
23 namespace mp = metaproxy_1;
24 namespace yf = mp::filter;
25
26 namespace metaproxy_1 
27 {
28
29     template<typename T>
30     std::string stringify(const T& x)
31     {
32         std::ostringstream o;
33         o << x;
34         return o.str();
35     }
36 }
37
38
39 namespace metaproxy_1 {
40     namespace filter {
41         class SRUtoZ3950::Rep {
42             friend class SRUtoZ3950;
43             void process(metaproxy_1::Package & package) const;
44             //int dummy;
45         };
46     }
47 }
48
49 yf::SRUtoZ3950::SRUtoZ3950() : m_p(new Rep)
50 {
51     //m_p->dummy = 1;
52 }
53
54 yf::SRUtoZ3950::~SRUtoZ3950()
55 {  // must have a destructor because of boost::scoped_ptr
56 }
57
58 void yf::SRUtoZ3950::process(mp::Package &package) const
59 {
60     //std::cout << m_p->protocol_type(package) << "\n";
61     //m_p->debug_http_headers(package);
62     m_p->process(package);
63 }
64
65 void yf::SRUtoZ3950::Rep::process(mp::Package &package) const
66 {
67     Z_GDU *zgdu_req = package.request().get();
68
69     // ignoring all non HTTP_Request packages
70     if (!zgdu_req || !(zgdu_req->which == Z_GDU_HTTP_Request)){
71         package.move();
72         return;
73     }
74     
75     // only working on  HTTP_Request packages now
76     Z_HTTP_Request* http_req =  zgdu_req->u.HTTP_Request;
77
78     // TODO: SRU package checking and translation to Z3950 package
79  
80
81
82 //     int ret_code = 2;  /* 2=NOT TAKEN, 1=TAKEN, 0=SOAP TAKEN */
83 //     Z_SRW_PDU *sru_res = 0;
84 //     Z_SOAP *soap_package = 0;
85 //     char *charset = 0;
86 //     Z_SRW_diagnostic *diagnostic = 0;
87 //     int num_diagnostic = 0;
88 //     mp::odr odr;
89     
90 //     if (!(ret_code = yaz_sru_decode(http_req, &sru_res, 
91 //                                    &soap_package, odr, &charset,
92 //                                    &diagnostic, &num_diagnostic)))
93 //     {
94 //         protocol = "SRU GET/POST";
95 //     } 
96 //     else if (!(ret_code = yaz_srw_decode(http_req, &sru_res, 
97 //                                         &soap_package, odr, &charset)))
98 //     {
99 //         protocol = "SRU SOAP";
100 //     }
101 //    else
102 //    {
103 //        protocol = "HTTP";
104 //    }
105
106     std::string protocol("HTTP");
107
108     const std::string mime_text_xml("text/xml");
109     const std::string mime_soap_xml("application/soap+xml");
110     const std::string mime_urlencoded("application/x-www-form-urlencoded");
111
112     const std::string http_method(http_req->method);
113     const std::string http_type(z_HTTP_header_lookup(http_req->headers, 
114                                                    "Content-Type"));
115     
116
117     if (http_method == "GET")
118         protocol = "SRU GET";
119     else if ( http_method == "POST"
120               && http_type  == mime_urlencoded)
121         protocol = "SRU POST";
122     else if ( http_method == "POST"
123               && (http_type  == mime_text_xml
124                   || http_type  == mime_soap_xml))
125         protocol = "SRU SOAP";
126     
127     std::cout << "SRUtoZ3950 " << protocol << "\n";
128
129     package.move();
130     return;
131     
132     
133
134     std::string message("<html>\n<body>\n<h1>"
135                         "Metaproxy SRUtoZ3950 filter"
136                         "</h1>\n");
137
138     message += "<h3>HTTP Info</h3><br/>\n";
139     message += "<p>\n";
140     message += "<b>Method: </b> " + std::string(http_req->method) + "<br/>\n";
141     message += "<b>Version:</b> " + std::string(http_req->version) + "<br/>\n";
142     message += "<b>Path:   </b> " + std::string(http_req->path) + "<br/>\n";
143     message += "<b>Content-Type:</b>"
144         + std::string(z_HTTP_header_lookup(http_req->headers, "Content-Type"))
145         + "<br/>\n";
146     message += "<b>Content-Length:</b>"
147         + std::string(z_HTTP_header_lookup(http_req->headers, 
148                                            "Content-Length"))
149         + "<br/>\n";
150     message += "</p>\n";    
151
152     message += "<h3>Headers</h3><br/>\n";
153     message += "<p>\n";    
154     Z_HTTP_Header* header = http_req->headers;
155     while (header){
156           message += "<b>Header: </b> <i>" 
157               + std::string(header->name) + ":</i> "
158               + std::string(header->value) + "<br/>\n";
159           header = header->next;
160     }
161     message += "</p>\n";    
162     message += "</body>\n</html>\n";
163
164     //std::cout << message << "\n";
165     
166
167
168     // sending Z3950 package through pipeline
169     package.move();
170
171
172     // TODO: Z3950 response parsing and translation to SRU package
173     //Z_HTTP_Response* http_res = 0;
174
175
176     Z_GDU *zgdu_res = 0; 
177     mp::odr odr; 
178     zgdu_res 
179        = odr.create_HTTP_Response(package.session(), 
180                                   zgdu_req->u.HTTP_Request, 200);
181
182         
183 //     zgdu_res->u.HTTP_Response->content_len = message.size();
184 //     zgdu_res->u.HTTP_Response->content_buf 
185 //         = (char*) odr_malloc(odr, zgdu_res->u.HTTP_Response->content_len);
186
187 //     strncpy(zgdu_res->u.HTTP_Response->content_buf, 
188 //             message.c_str(),  zgdu_res->u.HTTP_Response->content_len);
189     
190         // z_HTTP_header_add(o, &hres->headers,
191         //            "Content-Type", content_type.c_str());
192
193     package.response() = zgdu_res;
194
195 }
196
197
198 static mp::filter::Base* filter_creator()
199 {
200     return new mp::filter::SRUtoZ3950;
201 }
202
203 extern "C" {
204     struct metaproxy_1_filter_struct metaproxy_1_filter_sru_to_z3950 = {
205         0,
206         "SRUtoZ3950",
207         filter_creator
208     };
209 }
210
211
212 /*
213  * Local variables:
214  * c-basic-offset: 4
215  * indent-tabs-mode: nil
216  * c-file-style: "stroustrup"
217  * End:
218  * vim: shiftwidth=4 tabstop=8 expandtab
219  */