Fawkes API  Fawkes Development Version
rest_processor.cpp
1 
2 /***************************************************************************
3  * rest_processor.cpp - Web request processor for an extensible REST API
4  *
5  * Created: Fri Mar 16 12:02:53 2018
6  * Copyright 2006-2018 Tim Niemueller [www.niemueller.de]
7  ****************************************************************************/
8 
9 /* This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU Library General Public License for more details.
18  *
19  * Read the full text in the LICENSE.GPL file in the doc directory.
20  */
21 
22 #include "rest_processor.h"
23 
24 #include <core/exception.h>
25 #include <logging/logger.h>
26 #include <utils/misc/string_split.h>
27 #include <webview/error_reply.h>
28 #include <webview/rest_api.h>
29 #include <webview/rest_api_manager.h>
30 #include <webview/url_manager.h>
31 
32 #include <cstdlib>
33 #include <cstring>
34 #include <string>
35 #include <vector>
36 
37 using namespace fawkes;
38 
39 /** @class WebviewRESTRequestProcessor "rest_processor.h"
40  * REST API web processor.
41  * This processor provides an extensible REST API.
42  * @author Tim Niemueller
43  */
44 
45 /** Constructor.
46  * @param url_manager URL manager to register with
47  * @param api_mgr REST API manager to check for available APIs
48  * @param logger logger
49  */
52  fawkes::Logger * logger)
53 : url_mgr_(url_manager),
54  api_mgr_(api_mgr),
55  logger_(logger),
56  methods_{WebRequest::METHOD_GET,
57  WebRequest::METHOD_POST,
58  WebRequest::METHOD_PUT,
59  WebRequest::METHOD_DELETE,
60  WebRequest::METHOD_PATCH}
61 {
62  for (const auto &method : methods_) {
63  url_mgr_->add_handler(method,
64  "/api/{rest_url*}",
65  std::bind(&WebviewRESTRequestProcessor::process_request,
66  this,
67  std::placeholders::_1));
68  }
69 }
70 
71 /** Destructor. */
73 {
74  for (const auto &method : methods_) {
75  url_mgr_->remove_handler(method, "/api/{rest_url*}");
76  }
77 }
78 
79 WebReply *
80 WebviewRESTRequestProcessor::process_request(const fawkes::WebRequest *request)
81 {
82  std::string rest_url = "/" + request->path_arg("rest_url");
83  std::vector<std::string> rest_url_parts{str_split(rest_url, '/')};
84 
85  if (rest_url_parts.empty()) {
86  return new StaticWebReply(WebReply::HTTP_NOT_FOUND, "REST API overview not yet implemented\n");
87  }
88 
89  std::string rest_path = rest_url.substr(rest_url_parts[0].length() + 1);
90  std::string rest_api = rest_url_parts[0];
91  WebviewRestApi *api = api_mgr_->get_api(rest_api);
92  if (!api) {
93  logger_->log_error("WebRESTProc", "REST API '%s' unknown", rest_api.c_str());
94  return new StaticWebReply(WebReply::HTTP_NOT_FOUND, "REST API '" + rest_api + "' unknown\n");
95  }
96 
97  try {
98  WebReply *reply = api->process_request(request, rest_path);
99  if (!reply) {
100  return new StaticWebReply(WebReply::HTTP_NOT_FOUND,
101  "REST API '" + rest_api + "' has no endpoint '" + rest_path
102  + "'\n");
103  }
104  return no_caching(reply);
105  } catch (Exception &e) {
106  logger_->log_error("WebRESTProc", "REST API '%s' failed, exception follows", rest_api.c_str());
107  logger_->log_error("WebRESTProc", e);
108  return no_caching(
109  new StaticWebReply(WebReply::HTTP_INTERNAL_SERVER_ERROR,
110  "REST API '" + rest_api + "': " + e.what_no_backtrace() + "\n"));
111  }
112 }
fawkes::WebviewRestApiManager::get_api
WebviewRestApi * get_api(std::string &name)
Find API by name.
Definition: rest_api_manager.cpp:87
WebviewRESTRequestProcessor::WebviewRESTRequestProcessor
WebviewRESTRequestProcessor(fawkes::WebUrlManager *url_manager, fawkes::WebviewRestApiManager *api_mgr, fawkes::Logger *logger)
Constructor.
Definition: rest_processor.cpp:50
fawkes::WebRequest
Definition: request.h:41
fawkes::WebviewRestApiManager
Definition: rest_api_manager.h:42
fawkes::WebUrlManager::remove_handler
void remove_handler(WebRequest::Method method, const std::string &path)
Remove a request processor.
Definition: url_manager.cpp:90
fawkes::WebviewRestApi::process_request
WebReply * process_request(const WebRequest *request, const std::string &rest_url)
Process REST API request.
Definition: rest_api.cpp:69
fawkes::WebUrlManager
Definition: url_manager.h:45
WebviewRESTRequestProcessor::~WebviewRESTRequestProcessor
~WebviewRESTRequestProcessor()
Destructor.
Definition: rest_processor.cpp:72
fawkes::Logger::log_error
virtual void log_error(const char *component, const char *format,...)=0
fawkes::WebRequest::path_arg
std::string path_arg(const std::string &what) const
Get a path argument.
Definition: request.h:300
fawkes::Logger
Definition: logger.h:41
fawkes
fawkes::Exception::what_no_backtrace
virtual const char * what_no_backtrace() const
Get primary string (does not implicitly print the back trace).
Definition: exception.cpp:663
fawkes::WebviewRestApi
Definition: rest_api.h:225
fawkes::StaticWebReply
Definition: reply.h:141
fawkes::no_caching
WebReply * no_caching(WebReply *reply)
Disable caching on a reply.
Definition: reply.cpp:53
fawkes::WebReply
Definition: reply.h:39
fawkes::Exception
Definition: exception.h:41