]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/webserver.hh
rec: ensure correct service user on debian
[thirdparty/pdns.git] / pdns / webserver.hh
index 16d41e1197e0bc4add2b86fc548843ab877ad5fa..d7848847f3aab4dc75ab8a4c8f3d2af247b0bd14 100644 (file)
@@ -34,11 +34,12 @@ class WebServer;
 
 class HttpRequest : public YaHTTP::Request {
 public:
-  HttpRequest() : YaHTTP::Request(), accept_json(false), accept_html(false), complete(false) { };
+  HttpRequest(const string& logprefix="") : YaHTTP::Request(), accept_json(false), accept_html(false), complete(false), logprefix(logprefix) { };
 
   bool accept_json;
   bool accept_html;
   bool complete;
+  string logprefix;
   json11::Json json();
 
   // checks password _only_.
@@ -65,6 +66,11 @@ public:
     d_response.status = status;
   };
 
+  HttpException(int status, const string& msg) : d_response()
+  {
+    d_response.setErrorResult(msg, status);
+  };
+
   HttpResponse response()
   {
     return d_response;
@@ -77,6 +83,7 @@ protected:
 class HttpBadRequestException : public HttpException {
 public:
   HttpBadRequestException() : HttpException(400) { };
+  HttpBadRequestException(const string& msg) : HttpException(400, msg) { };
 };
 
 class HttpUnauthorizedException : public HttpException {
@@ -90,26 +97,31 @@ public:
 class HttpForbiddenException : public HttpException {
 public:
   HttpForbiddenException() : HttpException(403) { };
+  HttpForbiddenException(const string& msg) : HttpException(403, msg) { };
 };
 
 class HttpNotFoundException : public HttpException {
 public:
   HttpNotFoundException() : HttpException(404) { };
+  HttpNotFoundException(const string& msg) : HttpException(404, msg) { };
 };
 
 class HttpMethodNotAllowedException : public HttpException {
 public:
   HttpMethodNotAllowedException() : HttpException(405) { };
+  HttpMethodNotAllowedException(const string& msg) : HttpException(405, msg) { };
 };
 
 class HttpConflictException : public HttpException {
 public:
   HttpConflictException() : HttpException(409) { };
+  HttpConflictException(const string& msg) : HttpException(409, msg) { };
 };
 
 class HttpInternalServerErrorException : public HttpException {
 public:
   HttpInternalServerErrorException() : HttpException(500) { };
+  HttpInternalServerErrorException(const string& msg) : HttpException(500, msg) { };
 };
 
 class ApiException : public runtime_error
@@ -144,6 +156,19 @@ class WebServer : public boost::noncopyable
 public:
   WebServer(const string &listenaddress, int port);
   virtual ~WebServer() { };
+
+  void setApiKey(const string &apikey) {
+    d_apikey = apikey;
+  }
+
+  void setPassword(const string &password) {
+    d_webserverPassword = password;
+  }
+
+  void setACL(const NetmaskGroup &nmg) {
+    d_acl = nmg;
+  }
+
   void bind();
   void go();
 
@@ -151,11 +176,46 @@ public:
   void handleRequest(HttpRequest& request, HttpResponse& resp) const;
 
   typedef boost::function<void(HttpRequest* req, HttpResponse* resp)> HandlerFunction;
-  void registerApiHandler(const string& url, HandlerFunction handler);
+  void registerApiHandler(const string& url, HandlerFunction handler, bool allowPassword=false);
   void registerWebHandler(const string& url, HandlerFunction handler);
 
+  enum class LogLevel : uint8_t {
+    None = 0,                // No logs from requests at all
+    Normal = 10,             // A "common log format"-like line e.g. '127.0.0.1 "GET /apache_pb.gif HTTP/1.0" 200 2326'
+    Detailed = 20,           // The full request headers and body, and the full response headers and body
+  };
+
+  void setLogLevel(const string& level) {
+    if (level == "none") {
+      d_loglevel = LogLevel::None;
+      return;
+    }
+
+    if (level == "normal") {
+      d_loglevel = LogLevel::Normal;
+      return;
+    }
+
+    if (level == "detailed") {
+      d_loglevel = LogLevel::Detailed;
+      return;
+    }
+
+    throw PDNSException("Unknown webserver log level: " + level);
+  }
+
+  void setLogLevel(const LogLevel level) {
+    d_loglevel = level;
+  };
+
+  LogLevel getLogLevel() {
+    return d_loglevel;
+  };
+
 protected:
   void registerBareHandler(const string& url, HandlerFunction handler);
+  void logRequest(const HttpRequest& req, const ComboAddress& remote) const;
+  void logResponse(const HttpResponse& resp, const ComboAddress& remote, const string& logprefix) const;
 
   virtual std::shared_ptr<Server> createServer() {
     return std::make_shared<Server>(d_listenaddress, d_port);
@@ -165,6 +225,18 @@ protected:
   int d_port;
   string d_password;
   std::shared_ptr<Server> d_server;
+
+  std::string d_apikey;
+  void apiWrapper(WebServer::HandlerFunction handler, HttpRequest* req, HttpResponse* resp, bool allowPassword);
+  std::string d_webserverPassword;
+  void webWrapper(WebServer::HandlerFunction handler, HttpRequest* req, HttpResponse* resp);
+
+  NetmaskGroup d_acl;
+
+  const string d_logprefix = "[webserver] ";
+
+  // Describes the amount of logging the webserver does
+  WebServer::LogLevel d_loglevel{WebServer::LogLevel::Detailed};
 };
 
 #endif /* WEBSERVER_HH */