webview_thread.cpp

00001
00002 /***************************************************************************
00003  *  webview_thread.cpp - Thread that handles web interface requests
00004  *
00005  *  Created: Mon Oct 13 17:51:31 2008 (I5 Developer's Day)
00006  *  Copyright  2006-2008  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version.
00014  *
00015  *  This program is distributed in the hope that it will be useful,
00016  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018  *  GNU Library General Public License for more details.
00019  *
00020  *  Read the full text in the LICENSE.GPL file in the doc directory.
00021  */
00022
00023 #include "webview_thread.h"
00024 #include "request_dispatcher.h"
00025 #include "static_processor.h"
00026 #include "blackboard_processor.h"
00027 #include "startpage_processor.h"
00028 #include "plugins_processor.h"
00029 #include "page_reply.h"
00030 #include "service_browse_handler.h"
00031
00032 #include <microhttpd.h>
00033
00034 using namespace fawkes;
00035
00036 
00037 /** Prefix for the WebStaticRequestProcessor. */
00038 const char *WebviewThread::STATIC_URL_PREFIX = "/static";
00039 /** Prefix for the WebBlackBoardRequestProcessor. */
00040 const char *WebviewThread::BLACKBOARD_URL_PREFIX = "/blackboard";
00041 /** Prefix for the WebPluginsRequestProcessor. */
00042 const char *WebviewThread::PLUGINS_URL_PREFIX = "/plugins";
00043 
00044 /** @class WebviewThread "webview_thread.h"
00045  * Webview Thread.
00046  * This thread runs the HTTP server and handles requests via the
00047  * WebRequestDispatcher.
00048  * @author Tim Niemueller
00049  */
00050
00051 
00052 /** Constructor. */
00053 WebviewThread::WebviewThread()
00054   : Thread("WebviewThread", Thread::OPMODE_CONTINUOUS),
00055     LoggerAspect(&__cache_logger)
00056 {
00057   set_prepfin_conc_loop(true);
00058
00059 }
00060
00061
00062 WebviewThread::~WebviewThread()
00063 {
00064 }
00065
00066 void
00067 WebviewThread::init()
00068 {
00069   __cfg_port = config->get_uint("/webview/port");
00070
00071   __cache_logger.clear();
00072
00073   __dispatcher = new WebRequestDispatcher();
00074   __daemon = MHD_start_daemon(MHD_NO_FLAG,
00075                               __cfg_port,
00076                               NULL,
00077                               NULL,
00078                               WebRequestDispatcher::process_request_cb,
00079                               (void *)__dispatcher,
00080                               MHD_OPTION_END);
00081
00082   if ( __daemon == NULL ) {
00083     throw Exception("Could not start microhttpd");
00084   }
00085
00086   __startpage_processor  = new WebStartPageRequestProcessor(&__cache_logger);
00087   __static_processor     = new WebStaticRequestProcessor(STATIC_URL_PREFIX, RESDIR"/webview", logger);
00088   __blackboard_processor = new WebBlackBoardRequestProcessor(BLACKBOARD_URL_PREFIX, blackboard);
00089   __plugins_processor    = new WebPluginsRequestProcessor(PLUGINS_URL_PREFIX, plugin_manager);
00090   __dispatcher->add_processor("/", __startpage_processor);
00091   __dispatcher->add_processor(STATIC_URL_PREFIX, __static_processor);
00092   __dispatcher->add_processor(BLACKBOARD_URL_PREFIX, __blackboard_processor);
00093   __dispatcher->add_processor(PLUGINS_URL_PREFIX, __plugins_processor);
00094
00095   WebPageReply::add_nav_entry(BLACKBOARD_URL_PREFIX, "BlackBoard");
00096   WebPageReply::add_nav_entry(PLUGINS_URL_PREFIX, "Plugins");
00097
00098   logger->log_info("WebviewThread", "Listening for HTTP connections on port %u", __cfg_port);
00099
00100   __webview_service = new NetworkService(nnresolver, "Fawkes Webview on %h",
00101                                          "_http._tcp", __cfg_port);
00102   __webview_service->add_txt("fawkesver=0.1");
00103   service_publisher->publish_service(__webview_service);
00104
00105   __service_browse_handler = new WebviewServiceBrowseHandler(logger, __webview_service);
00106   service_browser->watch_service("_http._tcp", __service_browse_handler);
00107
00108   WebPageReply::set_service_browse_handler(__service_browse_handler);
00109 }
00110
00111 void
00112 WebviewThread::finalize()
00113 {
00114   service_publisher->unpublish_service(__webview_service);
00115   service_browser->unwatch_service("_http._tcp", __service_browse_handler);
00116   delete __webview_service;
00117   delete __service_browse_handler;
00118
00119   WebPageReply::remove_nav_entry(BLACKBOARD_URL_PREFIX);
00120   MHD_stop_daemon(__daemon);
00121   delete __dispatcher;
00122   delete __static_processor;
00123   delete __blackboard_processor;
00124   delete __startpage_processor;
00125   delete __plugins_processor;
00126   __daemon = NULL;
00127   __dispatcher = NULL;
00128 }
00129
00130
00131 void
00132 WebviewThread::loop()
00133 {
00134   fd_set read_fd, write_fd, except_fd;
00135   int max_fd = 0;
00136   FD_ZERO(&read_fd); FD_ZERO(&write_fd); FD_ZERO(&except_fd);
00137   if ( MHD_get_fdset(__daemon, &read_fd, &write_fd, &except_fd, &max_fd) != MHD_YES ) {
00138     logger->log_warn("WebviewThread", "Could not get microhttpd fdsets");
00139     return;
00140   }
00141   select(max_fd + 1, &read_fd, &write_fd, &except_fd, NULL);
00142   MHD_run(__daemon);
00143 }