22#include "webview_thread.h"
24#include "rest_processor.h"
25#include "service_browse_handler.h"
26#include "static_processor.h"
27#include "user_verifier.h"
29#include <core/exceptions/system.h>
30#include <core/version.h>
32#include <utils/misc/string_conversions.h>
33#include <utils/system/file.h>
34#include <utils/system/hostinfo.h>
35#include <webview/page_reply.h>
36#include <webview/request_dispatcher.h>
37#include <webview/server.h>
38#include <webview/url_manager.h>
55:
Thread(
"WebviewThread", enable_tp ?
Thread::OPMODE_WAITFORWAKEUP :
Thread::OPMODE_CONTINUOUS)
57 cfg_use_thread_pool_ = enable_tp;
63WebviewThread::~WebviewThread()
72 WebReply::set_caching_default(
config->
get_bool(
"/webview/client_side_caching"));
74 webview_service_ = NULL;
75 service_browse_handler_ = NULL;
88 cfg_tls_create_ =
false;
103 if (cfg_tls_key_[0] !=
'/')
104 cfg_tls_key_ = std::string(CONFDIR
"/") + cfg_tls_key_;
106 if (cfg_tls_cert_[0] !=
'/')
107 cfg_tls_cert_ = std::string(CONFDIR
"/") + cfg_tls_cert_;
110 "Key file: %s Cert file: %s",
111 cfg_tls_key_.c_str(),
112 cfg_tls_cert_.c_str());
114 if (!File::exists(cfg_tls_key_.c_str())) {
115 if (File::exists(cfg_tls_cert_.c_str())) {
116 throw Exception(
"Key file %s does not exist, but certificate file %s "
118 cfg_tls_key_.c_str(),
119 cfg_tls_cert_.c_str());
120 }
else if (cfg_tls_create_) {
121 tls_create(cfg_tls_key_.c_str(), cfg_tls_cert_.c_str());
123 throw Exception(
"Key file %s does not exist", cfg_tls_key_.c_str());
125 }
else if (!File::exists(cfg_tls_cert_.c_str())) {
126 throw Exception(
"Certificate file %s does not exist, but key file %s "
128 cfg_tls_key_.c_str(),
129 cfg_tls_cert_.c_str());
133 if (cfg_use_thread_pool_) {
134 cfg_num_threads_ =
config->
get_uint(
"/webview/thread-pool/num-threads");
137 cfg_use_basic_auth_ =
false;
139 cfg_use_basic_auth_ =
config->
get_bool(
"/webview/use_basic_auth");
142 cfg_basic_auth_realm_ =
"Fawkes Webview";
144 cfg_basic_auth_realm_ =
config->
get_bool(
"/webview/basic_auth_realm");
148 cfg_access_log_ =
"";
154 bool cfg_cors_allow_all =
false;
159 std::vector<std::string> cfg_cors_origins;
164 unsigned int cfg_cors_max_age = 0;
172 webview_service_->
add_txt(
"fawkesver=%u.%u.%u",
173 FAWKES_VERSION_MAJOR,
174 FAWKES_VERSION_MINOR,
175 FAWKES_VERSION_MICRO);
184 .setup_ipv(cfg_use_ipv4_, cfg_use_ipv6_)
185 .setup_cors(cfg_cors_allow_all, std::move(cfg_cors_origins), cfg_cors_max_age);
188 webserver_->
setup_tls(cfg_tls_key_.c_str(),
189 cfg_tls_cert_.c_str(),
190 cfg_tls_cipher_suite_.empty() ? NULL : cfg_tls_cipher_suite_.c_str());
193 if (cfg_use_thread_pool_) {
197 if (cfg_use_basic_auth_) {
199 webserver_->
setup_basic_auth(cfg_basic_auth_realm_.c_str(), user_verifier_);
203 if (cfg_access_log_ !=
"") {
208 delete webview_service_;
209 delete service_browse_handler_;
214 std::vector<std::string> static_dirs =
config->
get_strings(
"/webview/htdocs/dirs");
215 std::string catchall_file;
221 static_dirs = StringConversions::resolve_paths(static_dirs);
222 std::string static_base_url = catchall_file.empty() ?
"/static/" :
"/";
230 for (
const auto &u : cfg_explicit_404_) {
233 std::bind(&WebviewThread::produce_404,
this),
240 if (cfg_use_ipv4_ && cfg_use_ipv6_) {
242 }
else if (cfg_use_ipv4_) {
244 }
else if (cfg_use_ipv6_) {
249 "Listening for HTTP%s connections on port %u (%s)",
250 cfg_use_tls_ ?
"S" :
"",
270 for (
const auto &u : cfg_explicit_404_) {
276 delete webview_service_;
277 delete service_browse_handler_;
280 delete static_processor_;
281 delete rest_processor_;
288 if (!cfg_use_thread_pool_)
293WebviewThread::tls_create(
const char *tls_key_file,
const char *tls_cert_file)
296 "Creating TLS key and certificate. "
297 "This may take a while...");
302 "openssl req -new -x509 -batch -nodes -days 365 "
303 "-subj \"/C=XX/L=World/O=Fawkes/CN=%s.local\" "
304 "-out \"%s\" -keyout \"%s\" >/dev/null 2>&1",
312 int status = system(cmd);
315 if (WEXITSTATUS(status) != 0) {
316 throw Exception(
"Failed to auto-generate key/certificate pair");
321WebviewThread::produce_404()
323 return new StaticWebReply(WebReply::HTTP_NOT_FOUND,
"Not found\n");
Browse handler to detect other Webview instances on the network.
Static file web processor.
virtual void finalize()
Finalize the thread.
virtual void init()
Initialize the thread.
WebviewThread(bool enable_tp)
Constructor.
virtual void loop()
Code to execute in the thread.
Webview user verification.
Configuration * config
This is the Configuration member used to access the configuration.
virtual unsigned int get_uint(const char *path)=0
Get value from configuration which is of type unsigned int.
virtual bool get_bool(const char *path)=0
Get value from configuration which is of type bool.
virtual std::vector< std::string > get_strings(const char *path)=0
Get list of values from configuration which is of type string.
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
Base class for exceptions in Fawkes.
const char * short_name()
Get short hostname (up to first dot).
virtual void log_debug(const char *component, const char *format,...)=0
Log debug message.
virtual void log_info(const char *component, const char *format,...)=0
Log informational message.
Logger * logger
This is the Logger member used to access the logger.
NetworkNameResolver * nnresolver
Network name resolver to lookup IP addresses of hostnames and vice versa.
ServicePublisher * service_publisher
Service publisher to publish services on the network.
ServiceBrowser * service_browser
Service browser to browse services on the network.
Representation of a service announced or found via service discovery (i.e.
void add_txt(const char *format,...)
Add a TXT record.
System ran out of memory and desired operation could not be fulfilled.
virtual void watch_service(const char *service_type, ServiceBrowseHandler *h)=0
Add browse handler for specific service.
virtual void unwatch_service(const char *service_type, ServiceBrowseHandler *h)=0
Remove browse handler for specific service.
virtual void unpublish_service(NetworkService *service)=0
Revoke service publication.
virtual void publish_service(NetworkService *service)=0
Publish service.
Thread class encapsulation of pthreads.
void set_prepfin_conc_loop(bool concurrent=true)
Set concurrent execution of prepare_finalize() and loop().
const char * name() const
Get name of thread.
Encapsulation of the libmicrohttpd webserver.
WebServer & setup_access_log(const char *filename)
Setup access log.
void process()
Process requests.
WebServer & setup_tls(const char *key_pem_filepath, const char *cert_pem_filepath, const char *cipher_suite=WEBVIEW_DEFAULT_CIPHERS)
Setup Transport Layer Security (encryption),.
WebServer & setup_thread_pool(unsigned int num_threads)
Setup thread pool.
WebServer & setup_basic_auth(const char *realm, WebUserVerifier *verifier)
Setup basic authentication.
void start()
Start daemon and enable processing requests.
WebServer & setup_request_manager(WebRequestManager *request_manager)
Setup this server as request manager.
void remove_handler(WebRequest::Method method, const std::string &path)
Remove a request processor.
void add_handler(WebRequest::Method method, const std::string &path, Handler handler)
Add a request processor.
WebRequestManager * webview_request_manager
Webview request manager.
WebviewRestApiManager * webview_rest_api_manager
Webview REST API manager.
WebUrlManager * webview_url_manager
Webview request processor manager.
Fawkes library namespace.