]>
Commit | Line | Data |
---|---|---|
12c86877 BH |
1 | /* |
2 | PowerDNS Versatile Database Driven Nameserver | |
a2ce158c | 3 | Copyright (C) 2002-2012 PowerDNS.COM BV |
12c86877 BH |
4 | |
5 | This program is free software; you can redistribute it and/or modify | |
22dc646a BH |
6 | it under the terms of the GNU General Public License version 2 |
7 | as published by the Free Software Foundation | |
f782fe38 MH |
8 | |
9 | Additionally, the license of this program contains a special | |
10 | exception which allows to distribute the program in binary form when | |
11 | it is linked against OpenSSL. | |
12c86877 BH |
12 | |
13 | This program is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with this program; if not, write to the Free Software | |
06bd9ccf | 20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
12c86877 BH |
21 | */ |
22 | #ifndef WEBSERVER_HH | |
23 | #define WEBSERVER_HH | |
24 | #include <map> | |
25 | #include <string> | |
232f0877 | 26 | #include <list> |
3ae143b0 CH |
27 | #include <boost/utility.hpp> |
28 | #include <yahttp/yahttp.hpp> | |
6ec5e728 CH |
29 | #include "rapidjson/document.h" |
30 | #include "rapidjson/stringbuffer.h" | |
31 | #include "rapidjson/writer.h" | |
10f4eea8 | 32 | #include "namespaces.hh" |
825fa717 | 33 | #include "sstuff.hh" |
12c86877 | 34 | |
80d59cd1 CH |
35 | class HttpRequest : public YaHTTP::Request { |
36 | public: | |
825fa717 | 37 | HttpRequest() : YaHTTP::Request(), accept_json(false), accept_html(false), complete(false) { }; |
80d59cd1 CH |
38 | |
39 | map<string,string> path_parameters; | |
40 | bool accept_json; | |
41 | bool accept_html; | |
825fa717 | 42 | bool complete; |
6ec5e728 | 43 | void json(rapidjson::Document& document); |
80d59cd1 CH |
44 | }; |
45 | ||
46 | class HttpResponse: public YaHTTP::Response { | |
47 | public: | |
48 | HttpResponse() : YaHTTP::Response() { }; | |
49 | HttpResponse(const YaHTTP::Request &req) : YaHTTP::Response(req) { }; | |
50 | HttpResponse(const YaHTTP::Response &resp) : YaHTTP::Response(resp) { }; | |
669822d0 CH |
51 | |
52 | void setBody(rapidjson::Document& document); | |
80d59cd1 CH |
53 | }; |
54 | ||
55 | ||
33196945 CH |
56 | class HttpException |
57 | { | |
58 | public: | |
80d59cd1 | 59 | HttpException(int status) : d_response() |
33196945 | 60 | { |
80d59cd1 | 61 | d_response.status = status; |
33196945 CH |
62 | }; |
63 | ||
80d59cd1 CH |
64 | HttpResponse response() |
65 | { | |
66 | return d_response; | |
33196945 CH |
67 | } |
68 | ||
80d59cd1 CH |
69 | protected: |
70 | HttpResponse d_response; | |
33196945 CH |
71 | }; |
72 | ||
73 | class HttpBadRequestException : public HttpException { | |
74 | public: | |
80d59cd1 | 75 | HttpBadRequestException() : HttpException(400) { }; |
33196945 CH |
76 | }; |
77 | ||
78 | class HttpUnauthorizedException : public HttpException { | |
79 | public: | |
80d59cd1 CH |
80 | HttpUnauthorizedException() : HttpException(401) |
81 | { | |
82 | d_response.headers["WWW-Authenticate"] = "Basic realm=\"PowerDNS\""; | |
33196945 CH |
83 | } |
84 | }; | |
85 | ||
86 | class HttpNotFoundException : public HttpException { | |
87 | public: | |
80d59cd1 | 88 | HttpNotFoundException() : HttpException(404) { }; |
33196945 CH |
89 | }; |
90 | ||
91 | class HttpMethodNotAllowedException : public HttpException { | |
92 | public: | |
80d59cd1 | 93 | HttpMethodNotAllowedException() : HttpException(405) { }; |
33196945 CH |
94 | }; |
95 | ||
0f67eeda CH |
96 | class HttpInternalServerErrorException : public HttpException { |
97 | public: | |
98 | HttpInternalServerErrorException() : HttpException(500) { }; | |
99 | }; | |
100 | ||
3ae143b0 CH |
101 | class ApiException : public runtime_error |
102 | { | |
103 | public: | |
104 | ApiException(const string& what) : runtime_error(what) { | |
105 | } | |
106 | }; | |
02c04144 | 107 | |
a7650f23 CH |
108 | class Server |
109 | { | |
110 | public: | |
93f4e5ce | 111 | Server(const string &localaddress, int port) : d_local(localaddress.empty() ? "0.0.0.0" : localaddress, port), d_server_socket(d_local.sin4.sin_family, SOCK_STREAM, 0) { |
a7650f23 CH |
112 | d_server_socket.setReuseAddr(); |
113 | d_server_socket.bind(d_local); | |
114 | d_server_socket.listen(); | |
115 | } | |
116 | ||
117 | ComboAddress d_local; | |
118 | ||
119 | Socket *accept() { | |
120 | return d_server_socket.accept(); | |
121 | } | |
122 | ||
123 | protected: | |
124 | Socket d_server_socket; | |
125 | }; | |
126 | ||
3ae143b0 | 127 | class WebServer : public boost::noncopyable |
12c86877 BH |
128 | { |
129 | public: | |
130 | WebServer(const string &listenaddress, int port, const string &password=""); | |
825fa717 | 131 | void bind(); |
12c86877 | 132 | void go(); |
232f0877 | 133 | |
825fa717 | 134 | void serveConnection(Socket *client); |
80d59cd1 | 135 | HttpResponse handleRequest(HttpRequest request); |
232f0877 | 136 | |
80d59cd1 | 137 | typedef boost::function<void(HttpRequest* req, HttpResponse* resp)> HandlerFunction; |
232f0877 CH |
138 | struct HandlerRegistration { |
139 | std::list<string> urlParts; | |
140 | std::list<string> paramNames; | |
f6154a3b | 141 | HandlerFunction handler; |
232f0877 CH |
142 | }; |
143 | ||
f6154a3b | 144 | void registerHandler(const string& url, HandlerFunction handler); |
3ae143b0 | 145 | void registerApiHandler(const string& url, HandlerFunction handler); |
232f0877 | 146 | |
3ae143b0 | 147 | protected: |
12c86877 BH |
148 | static char B64Decode1(char cInChar); |
149 | static int B64Decode(const std::string& strInput, std::string& strOutput); | |
232f0877 CH |
150 | bool route(const std::string& url, std::map<std::string, std::string>& urlArgs, HandlerFunction** handler); |
151 | ||
825fa717 CH |
152 | virtual Server* createServer() { |
153 | return new Server(d_listenaddress, d_port); | |
154 | } | |
155 | ||
12c86877 BH |
156 | string d_listenaddress; |
157 | int d_port; | |
232f0877 | 158 | std::list<HandlerRegistration> d_handlers; |
232f0877 | 159 | string d_password; |
96d299db | 160 | Server* d_server; |
12c86877 | 161 | }; |
3ae143b0 | 162 | |
12c86877 | 163 | #endif /* WEBSERVER_HH */ |