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
37using 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
80WebviewRESTRequestProcessor::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}
~WebviewRESTRequestProcessor()
Destructor.
WebviewRESTRequestProcessor(fawkes::WebUrlManager *url_manager, fawkes::WebviewRestApiManager *api_mgr, fawkes::Logger *logger)
Constructor.
Base class for exceptions in Fawkes.
Definition: exception.h:36
virtual const char * what_no_backtrace() const noexcept
Get primary string (does not implicitly print the back trace).
Definition: exception.cpp:663
Interface for logging.
Definition: logger.h:42
virtual void log_error(const char *component, const char *format,...)=0
Log error message.
Static web reply.
Definition: reply.h:136
Basic web reply.
Definition: reply.h:34
Web request meta data carrier.
Definition: request.h:42
std::string path_arg(const std::string &what) const
Get a path argument.
Definition: request.h:300
Manage URL mappings.
Definition: url_manager.h:40
void remove_handler(WebRequest::Method method, const std::string &path)
Remove a request processor.
Definition: url_manager.cpp:84
void add_handler(WebRequest::Method method, const std::string &path, Handler handler)
Add a request processor.
Definition: url_manager.cpp:54
WebviewRestApi * get_api(std::string &name)
Find API by name.
Webview REST API component.
Definition: rest_api.h:221
WebReply * process_request(const WebRequest *request, const std::string &rest_url)
Process REST API request.
Definition: rest_api.cpp:64
Fawkes library namespace.
WebReply * no_caching(WebReply *reply)
Disable caching on a reply.
Definition: reply.cpp:47