]>
Commit | Line | Data |
---|---|---|
12c86877 | 1 | /* |
12471842 PL |
2 | * This file is part of PowerDNS or dnsdist. |
3 | * Copyright -- PowerDNS.COM B.V. and its contributors | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify | |
6 | * it under the terms of version 2 of the GNU General Public License as | |
7 | * published by the Free Software Foundation. | |
8 | * | |
9 | * In addition, for the avoidance of any doubt, permission is granted to | |
10 | * link this program with OpenSSL and to (re)distribute the binaries | |
11 | * produced as the result of such linking. | |
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 | |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
21 | */ | |
12c86877 BH |
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> | |
5938c49f | 29 | #include "json11.hpp" |
10f4eea8 | 30 | #include "namespaces.hh" |
825fa717 | 31 | #include "sstuff.hh" |
12c86877 | 32 | |
bbef8f04 CH |
33 | class WebServer; |
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 | 38 | |
80d59cd1 CH |
39 | bool accept_json; |
40 | bool accept_html; | |
825fa717 | 41 | bool complete; |
5938c49f | 42 | json11::Json json(); |
bbef8f04 CH |
43 | |
44 | // checks password _only_. | |
45 | bool compareAuthorization(const string &expected_password); | |
46 | bool compareHeader(const string &header_name, const string &expected_value); | |
80d59cd1 CH |
47 | }; |
48 | ||
49 | class HttpResponse: public YaHTTP::Response { | |
50 | public: | |
51 | HttpResponse() : YaHTTP::Response() { }; | |
80d59cd1 | 52 | HttpResponse(const YaHTTP::Response &resp) : YaHTTP::Response(resp) { }; |
669822d0 | 53 | |
5938c49f | 54 | void setBody(const json11::Json& document); |
692829aa CH |
55 | void setErrorResult(const std::string& message, const int status); |
56 | void setSuccessResult(const std::string& message, const int status = 200); | |
80d59cd1 CH |
57 | }; |
58 | ||
59 | ||
33196945 CH |
60 | class HttpException |
61 | { | |
62 | public: | |
80d59cd1 | 63 | HttpException(int status) : d_response() |
33196945 | 64 | { |
80d59cd1 | 65 | d_response.status = status; |
33196945 CH |
66 | }; |
67 | ||
80d59cd1 CH |
68 | HttpResponse response() |
69 | { | |
70 | return d_response; | |
33196945 CH |
71 | } |
72 | ||
80d59cd1 CH |
73 | protected: |
74 | HttpResponse d_response; | |
33196945 CH |
75 | }; |
76 | ||
77 | class HttpBadRequestException : public HttpException { | |
78 | public: | |
80d59cd1 | 79 | HttpBadRequestException() : HttpException(400) { }; |
33196945 CH |
80 | }; |
81 | ||
82 | class HttpUnauthorizedException : public HttpException { | |
83 | public: | |
53255086 | 84 | HttpUnauthorizedException(string const &scheme) : HttpException(401) |
80d59cd1 | 85 | { |
53255086 | 86 | d_response.headers["WWW-Authenticate"] = scheme + " realm=\"PowerDNS\""; |
33196945 CH |
87 | } |
88 | }; | |
89 | ||
53255086 PL |
90 | class HttpForbiddenException : public HttpException { |
91 | public: | |
92 | HttpForbiddenException() : HttpException(403) { }; | |
93 | }; | |
94 | ||
33196945 CH |
95 | class HttpNotFoundException : public HttpException { |
96 | public: | |
80d59cd1 | 97 | HttpNotFoundException() : HttpException(404) { }; |
33196945 CH |
98 | }; |
99 | ||
100 | class HttpMethodNotAllowedException : public HttpException { | |
101 | public: | |
80d59cd1 | 102 | HttpMethodNotAllowedException() : HttpException(405) { }; |
33196945 CH |
103 | }; |
104 | ||
0f67eeda CH |
105 | class HttpInternalServerErrorException : public HttpException { |
106 | public: | |
107 | HttpInternalServerErrorException() : HttpException(500) { }; | |
108 | }; | |
109 | ||
3ae143b0 CH |
110 | class ApiException : public runtime_error |
111 | { | |
112 | public: | |
113 | ApiException(const string& what) : runtime_error(what) { | |
114 | } | |
115 | }; | |
02c04144 | 116 | |
a7650f23 CH |
117 | class Server |
118 | { | |
119 | public: | |
93f4e5ce | 120 | 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 |
121 | d_server_socket.setReuseAddr(); |
122 | d_server_socket.bind(d_local); | |
123 | d_server_socket.listen(); | |
124 | } | |
690984d4 | 125 | virtual ~Server() { }; |
a7650f23 CH |
126 | |
127 | ComboAddress d_local; | |
128 | ||
d4c53d8c RG |
129 | std::shared_ptr<Socket> accept() { |
130 | return std::shared_ptr<Socket>(d_server_socket.accept()); | |
a7650f23 CH |
131 | } |
132 | ||
133 | protected: | |
134 | Socket d_server_socket; | |
135 | }; | |
136 | ||
3ae143b0 | 137 | class WebServer : public boost::noncopyable |
12c86877 BH |
138 | { |
139 | public: | |
bbef8f04 | 140 | WebServer(const string &listenaddress, int port); |
690984d4 | 141 | virtual ~WebServer() { }; |
825fa717 | 142 | void bind(); |
12c86877 | 143 | void go(); |
232f0877 | 144 | |
b184a9dc RG |
145 | void serveConnection(std::shared_ptr<Socket> client) const; |
146 | void handleRequest(HttpRequest& request, HttpResponse& resp) const; | |
232f0877 | 147 | |
80d59cd1 | 148 | typedef boost::function<void(HttpRequest* req, HttpResponse* resp)> HandlerFunction; |
3ae143b0 | 149 | void registerApiHandler(const string& url, HandlerFunction handler); |
bbef8f04 | 150 | void registerWebHandler(const string& url, HandlerFunction handler); |
232f0877 | 151 | |
3ae143b0 | 152 | protected: |
bbef8f04 | 153 | void registerBareHandler(const string& url, HandlerFunction handler); |
232f0877 | 154 | |
690984d4 RG |
155 | virtual std::shared_ptr<Server> createServer() { |
156 | return std::make_shared<Server>(d_listenaddress, d_port); | |
825fa717 CH |
157 | } |
158 | ||
12c86877 BH |
159 | string d_listenaddress; |
160 | int d_port; | |
232f0877 | 161 | string d_password; |
690984d4 | 162 | std::shared_ptr<Server> d_server; |
12c86877 | 163 | }; |
3ae143b0 | 164 | |
12c86877 | 165 | #endif /* WEBSERVER_HH */ |