4 #include "boost/bind.hpp"
6 #include "zypp/base/Logger.h"
7 #include "zypp/base/String.h"
8 #include "zypp/base/Exception.h"
9 #include "zypp/ExternalProgram.h"
10 #include "WebServer.h"
17 static inline string hostname()
21 if (!::gethostname(buf, 255))
22 result += string(buf);
39 virtual string log() const
48 virtual void worker_thread()
51 virtual int port() const
59 friend Impl * rwcowClone<Impl>( const Impl * rhs );
60 /** clone for RWCOW_pointer */
62 { return new Impl( *this ); }
65 class WebServerWebrickImpl : public WebServer::Impl
68 WebServerWebrickImpl(const Pathname &root, unsigned int port)
69 : _docroot(root), _port(port), _stop(false), _stopped(true)
73 ~WebServerWebrickImpl()
79 virtual int port() const
85 virtual void worker_thread()
89 stringstream strlog(_log);
91 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());
101 ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
108 MIL << "Thread end requested" << endl;
110 if ( prog.running() )
112 MIL << "Thread about to finish" << endl;
115 virtual string log() const
122 MIL << "Waiting for Webrick thread to finish" << endl;
125 MIL << "Webrick thread finished" << endl;
132 _thrd.reset( new boost::thread( boost::bind(&WebServerWebrickImpl::worker_thread, this) ) );
135 zypp::Pathname _docroot;
137 zypp::shared_ptr<boost::thread> _thrd;
143 class WebServerMongooseImpl : public WebServer::Impl
146 WebServerMongooseImpl(const Pathname &root, unsigned int port)
147 : _ctx(0L), _docroot(root)
153 ~WebServerMongooseImpl()
155 MIL << "Destroying web server" << endl;
165 MIL << "mongoose server already running, stopping." << endl;
169 MIL << "Starting shttpd (mongoose)" << endl;
174 ret = mg_set_option(_ctx, "ports", str::form("%d", _port).c_str());
176 ZYPP_THROW(Exception(str::form("Failed to set port: %d", ret)));
178 MIL << "Setting root directory to : '" << _docroot << "'" << endl;
179 ret = mg_set_option(_ctx, "root", _docroot.c_str());
181 ZYPP_THROW(Exception(str::form("Failed to set docroot: %d", ret)));
186 virtual int port() const
192 virtual string log() const
199 MIL << "Stopping shttpd" << endl;
201 MIL << "shttpd finished" << endl;
207 zypp::Pathname _docroot;
214 WebServer::WebServer(const Pathname &root, unsigned int port)
216 : _pimpl(new WebServerWebrickImpl(root, port))
218 : _pimpl(new WebServerMongooseImpl(root, port))
223 void WebServer::start()
229 std::string WebServer::log() const
231 return _pimpl->log();
234 int WebServer::port() const
236 return _pimpl->port();
240 Url WebServer::url() const
243 url.setHost(hostname());
244 url.setPort(str::numstring(port()));
245 url.setScheme("http");
249 void WebServer::stop()
254 WebServer::~WebServer()