3 #include "boost/version.hpp"
5 #if BOOST_VERSION >= 106800
6 #define BOOST_ERROR_CODE_HEADER_ONLY
9 #include "boost/bind.hpp"
10 #include "boost/thread.hpp"
12 #include "zypp/base/Logger.h"
13 #include "zypp/base/String.h"
14 #include "zypp/base/Exception.h"
15 #include "zypp/ExternalProgram.h"
16 #include "WebServer.h"
23 #if ( BOOST_VERSION >= 105000 ) && ( BOOST_VERSION < 106800)
24 // https://svn.boost.org/trac/boost/ticket/7085
29 class fake_error_category : public error_category
31 virtual const char * name() const noexcept(true)
32 { return "falke_name"; }
33 virtual std::string message( int ev ) const
34 { return "falke_message"; }
36 const error_category & generic_category()
38 static fake_error_category _e;
40 throw std::exception(/*"boost/ticket/7085 workaound sucks :("*/);
42 const error_category & system_category()
44 static fake_error_category _e;
46 throw std::exception(/*"boost/ticket/7085 workaound sucks :("*/);
52 static inline string hostname()
56 if (!::gethostname(buf, 255))
57 result += string(buf);
74 virtual string log() const
83 virtual void worker_thread()
86 virtual int port() const
94 friend Impl * rwcowClone<Impl>( const Impl * rhs );
95 /** clone for RWCOW_pointer */
97 { return new Impl( *this ); }
100 class WebServerWebrickImpl : public WebServer::Impl
103 WebServerWebrickImpl(const Pathname &root, unsigned int port)
104 : _docroot(root), _port(port), _stop(false), _stopped(true)
108 ~WebServerWebrickImpl()
114 virtual int port() const
120 virtual void worker_thread()
124 stringstream strlog(_log);
126 string webrick_code = str::form("require \"webrick\"; s = WEBrick::HTTPServer.new(:Port => %d, :DocumentRoot => \"%s\"); trap(\"INT\"){ s.shutdown }; trap(\"SIGKILL\") { s.shutdown }; s.start;", _port, _docroot.c_str());
132 webrick_code.c_str(),
136 ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
143 MIL << "Thread end requested" << endl;
145 if ( prog.running() )
147 MIL << "Thread about to finish" << endl;
150 virtual string log() const
157 MIL << "Waiting for Webrick thread to finish" << endl;
160 MIL << "Webrick thread finished" << endl;
167 //_thrd.reset( new boost::thread( boost::bind(&WebServerWebrickImpl::worker_thread, this) ) );
170 zypp::Pathname _docroot;
172 zypp::shared_ptr<boost::thread> _thrd;
178 class WebServerMongooseImpl : public WebServer::Impl
181 WebServerMongooseImpl(const Pathname &root, unsigned int port)
182 : _ctx(0L), _docroot(root)
188 ~WebServerMongooseImpl()
190 MIL << "Destroying web server" << endl;
200 MIL << "mongoose server already running, stopping." << endl;
204 MIL << "Starting shttpd (mongoose)" << endl;
209 ret = mg_set_option(_ctx, "ports", str::form("%d", _port).c_str());
211 ZYPP_THROW(Exception(str::form("Failed to set port: %d", ret)));
213 MIL << "Setting root directory to : '" << _docroot << "'" << endl;
214 ret = mg_set_option(_ctx, "root", _docroot.c_str());
216 ZYPP_THROW(Exception(str::form("Failed to set docroot: %d", ret)));
221 virtual int port() const
227 virtual string log() const
234 MIL << "Stopping shttpd" << endl;
236 MIL << "shttpd finished" << endl;
242 zypp::Pathname _docroot;
249 WebServer::WebServer(const Pathname &root, unsigned int port)
251 : _pimpl(new WebServerWebrickImpl(root, port))
253 : _pimpl(new WebServerMongooseImpl(root, port))
258 void WebServer::start()
264 std::string WebServer::log() const
266 return _pimpl->log();
269 int WebServer::port() const
271 return _pimpl->port();
275 Url WebServer::url() const
278 url.setHost("localhost");
279 url.setPort(str::numstring(port()));
280 url.setScheme("http");
284 void WebServer::stop()
289 WebServer::~WebServer()