FilterFrontendNet allows listening on multiple ports.
[metaproxy-moved-to-github.git] / src / ex_filter_frontend_net.cpp
1
2 #include <cstdlib>
3 #include <iostream>
4 #include <stdexcept>
5
6 #include <boost/program_options.hpp>
7 namespace po = boost::program_options;
8
9 #include "config.hpp"
10
11 #include "filter_frontend_net.hpp"
12
13 #include "router.hpp"
14 #include "session.hpp"
15 #include "package.hpp"
16
17 class FilterInit: public yp2::Filter {
18 public:
19     void process(yp2::Package & package) const {
20
21         if (package.session().is_closed())
22         {
23             // std::cout << "Got Close.\n";
24         }
25        
26         Z_GDU *gdu = package.request().get();
27         if (gdu)
28         {
29             ODR odr = odr_createmem(ODR_ENCODE);
30             switch(gdu->which)
31             {
32             case Z_GDU_Z3950:
33                 // std::cout << "Got PDU. Sending init response\n";
34                 Z_APDU *apdu = zget_APDU(odr, Z_APDU_initResponse);
35                 
36                 apdu->u.initResponse->implementationName = "YP2/YAZ";
37                 
38                 package.response() = apdu;
39                 break;
40             case Z_GDU_HTTP_Request:
41                 Z_GDU *gdu = z_get_HTTP_Response(odr, 200);
42                 Z_HTTP_Response *http_res = gdu->u.HTTP_Response;
43         
44                 z_HTTP_header_add(odr, &http_res->headers,
45                                   "Content-Type", "text/plain");
46            
47                 http_res->content_buf = 
48                     odr_strdup(odr, "Welcome to YP2");
49                 http_res->content_len = strlen(http_res->content_buf);
50
51                 package.response() = gdu;
52                 break;
53             default:
54                 break;
55             } 
56             odr_destroy(odr);
57         }
58         return package.move();
59     };
60 };
61
62 int main(int argc, char **argv)
63 {
64     try 
65     {
66         po::options_description desc("Allowed options");
67         desc.add_options()
68             ("help", "produce help message")
69             ("duration", po::value<int>(),
70              "number of seconds for server to exist")
71             ("port", po::value< std::vector<std::string> >(), "listener port")
72             ;
73
74         po::positional_options_description p;
75         p.add("port", -1);
76
77         po::variables_map vm;        
78         po::store(po::command_line_parser(argc, argv).
79                   options(desc).positional(p).run(), vm);
80         po::notify(vm);    
81
82         if (vm.count("help")) {
83             std::cout << desc << "\n";
84             return 1;
85         }
86
87         if (vm.count("port"))
88         {
89             std::vector<std::string> ports = 
90                 vm["port"].as< std::vector<std::string> >();
91
92             for (size_t i = 0; i<ports.size(); i++)
93                 std::cout << "port " << i << " " << ports[i] << "\n";
94
95             yp2::RouterChain router;
96
97             // put in frontend first
98             yp2::FilterFrontendNet filter_front;
99             filter_front.ports() = ports;
100
101             // 0=no time, >0 timeout in seconds
102             if (vm.count("duration")) {
103                 filter_front.listen_duration() = vm["duration"].as<int>();
104             }
105             router.rule(filter_front);
106
107             // put in a backend
108             FilterInit filter_init;
109             router.rule(filter_init);
110
111             yp2::Session session;
112             yp2::Origin origin;
113             yp2::Package pack(session, origin);
114             
115             pack.router(router).move(); 
116         }
117     }
118     catch ( ... ) {
119         std::cerr << "unknown exception\n";
120         std::exit(1);
121     }
122     std::exit(0);
123 }
124
125 /*
126  * Local variables:
127  * c-basic-offset: 4
128  * indent-tabs-mode: nil
129  * End:
130  * vim: shiftwidth=4 tabstop=8 expandtab
131  */