]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/webserver.hh
Merge pull request #5537 from pieterlexis/recursor-doc-fixes
[thirdparty/pdns.git] / pdns / webserver.hh
1 /*
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 */
22 #ifndef WEBSERVER_HH
23 #define WEBSERVER_HH
24 #include <map>
25 #include <string>
26 #include <list>
27 #include <boost/utility.hpp>
28 #include <yahttp/yahttp.hpp>
29 #include "json11.hpp"
30 #include "namespaces.hh"
31 #include "sstuff.hh"
32
33 class WebServer;
34
35 class HttpRequest : public YaHTTP::Request {
36 public:
37 HttpRequest() : YaHTTP::Request(), accept_json(false), accept_html(false), complete(false) { };
38
39 bool accept_json;
40 bool accept_html;
41 bool complete;
42 json11::Json json();
43
44 // checks password _only_.
45 bool compareAuthorization(const string &expected_password);
46 bool compareHeader(const string &header_name, const string &expected_value);
47 };
48
49 class HttpResponse: public YaHTTP::Response {
50 public:
51 HttpResponse() : YaHTTP::Response() { };
52 HttpResponse(const YaHTTP::Response &resp) : YaHTTP::Response(resp) { };
53
54 void setBody(const json11::Json& document);
55 void setErrorResult(const std::string& message, const int status);
56 void setSuccessResult(const std::string& message, const int status = 200);
57 };
58
59
60 class HttpException
61 {
62 public:
63 HttpException(int status) : d_response()
64 {
65 d_response.status = status;
66 };
67
68 HttpResponse response()
69 {
70 return d_response;
71 }
72
73 protected:
74 HttpResponse d_response;
75 };
76
77 class HttpBadRequestException : public HttpException {
78 public:
79 HttpBadRequestException() : HttpException(400) { };
80 };
81
82 class HttpUnauthorizedException : public HttpException {
83 public:
84 HttpUnauthorizedException(string const &scheme) : HttpException(401)
85 {
86 d_response.headers["WWW-Authenticate"] = scheme + " realm=\"PowerDNS\"";
87 }
88 };
89
90 class HttpForbiddenException : public HttpException {
91 public:
92 HttpForbiddenException() : HttpException(403) { };
93 };
94
95 class HttpNotFoundException : public HttpException {
96 public:
97 HttpNotFoundException() : HttpException(404) { };
98 };
99
100 class HttpMethodNotAllowedException : public HttpException {
101 public:
102 HttpMethodNotAllowedException() : HttpException(405) { };
103 };
104
105 class HttpInternalServerErrorException : public HttpException {
106 public:
107 HttpInternalServerErrorException() : HttpException(500) { };
108 };
109
110 class ApiException : public runtime_error
111 {
112 public:
113 ApiException(const string& what) : runtime_error(what) {
114 }
115 };
116
117 class Server
118 {
119 public:
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) {
121 d_server_socket.setReuseAddr();
122 d_server_socket.bind(d_local);
123 d_server_socket.listen();
124 }
125 virtual ~Server() { };
126
127 ComboAddress d_local;
128
129 std::shared_ptr<Socket> accept() {
130 return std::shared_ptr<Socket>(d_server_socket.accept());
131 }
132
133 protected:
134 Socket d_server_socket;
135 };
136
137 class WebServer : public boost::noncopyable
138 {
139 public:
140 WebServer(const string &listenaddress, int port);
141 virtual ~WebServer() { };
142 void bind();
143 void go();
144
145 void serveConnection(std::shared_ptr<Socket> client) const;
146 void handleRequest(HttpRequest& request, HttpResponse& resp) const;
147
148 typedef boost::function<void(HttpRequest* req, HttpResponse* resp)> HandlerFunction;
149 void registerApiHandler(const string& url, HandlerFunction handler);
150 void registerWebHandler(const string& url, HandlerFunction handler);
151
152 protected:
153 void registerBareHandler(const string& url, HandlerFunction handler);
154
155 virtual std::shared_ptr<Server> createServer() {
156 return std::make_shared<Server>(d_listenaddress, d_port);
157 }
158
159 string d_listenaddress;
160 int d_port;
161 string d_password;
162 std::shared_ptr<Server> d_server;
163 };
164
165 #endif /* WEBSERVER_HH */