Mailinglist Archive: zypp-commit (172 mails)

< Previous Next >
[zypp-commit] <libzypp> master : add support for webrick to WebServer.
  • From: Duncan Mac-Vicar P <dmacvicar@xxxxxxx>
  • Date: Thu, 5 Feb 2009 15:00:30 +0100
  • Message-id: <E1LV5g1-0001gX-ER@xxxxxxxxxxxxxxxx>
ref: refs/heads/master
commit e50f1afeeabc80368a7cbaa8363c9978ec57f110
Author: Duncan Mac-Vicar P <dmacvicar@xxxxxxx>
Date: Thu Feb 5 15:00:30 2009 +0100

add support for webrick to WebServer.

Make aria the default
---
tests/lib/CMakeLists.txt | 4 +-
tests/lib/WebServer.cc | 245 +++++++++++++++++++++++++++++++++++---------
tests/lib/WebServer.h | 27 ++---
tests/zypp/Fetcher_test.cc | 11 ++-
vendor/CMakeLists.txt | 5 +-
zypp/media/MediaAccess.cc | 9 +--
zypp/media/MediaAria2c.cc | 6 +-
7 files changed, 227 insertions(+), 80 deletions(-)

diff --git a/tests/lib/CMakeLists.txt b/tests/lib/CMakeLists.txt
index e99de9b..5ff5932 100644
--- a/tests/lib/CMakeLists.txt
+++ b/tests/lib/CMakeLists.txt
@@ -1,5 +1,5 @@

-INCLUDE_DIRECTORIES( ${LIBZYPP_SOURCE_DIR}/vendor/shttpd )
+INCLUDE_DIRECTORIES( ${LIBZYPP_SOURCE_DIR}/vendor/mongoose )

ADD_LIBRARY(zypp_test_utils
TestSetup.h
@@ -7,4 +7,4 @@ ADD_LIBRARY(zypp_test_utils
WebServer.cc
)

-TARGET_LINK_LIBRARIES(zypp_test_utils shttp zypp boost_thread-mt)
+TARGET_LINK_LIBRARIES(zypp_test_utils mongoose zypp boost_thread-mt)
diff --git a/tests/lib/WebServer.cc b/tests/lib/WebServer.cc
index 98a47b3..4d05eb8 100644
--- a/tests/lib/WebServer.cc
+++ b/tests/lib/WebServer.cc
@@ -1,78 +1,227 @@

-#include <sys/types.h>
-#include <sys/select.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-#include <string.h>
+//#include "zypp/ZYpp.h"

-#include "zypp/ZYpp.h"
-
-using namespace zypp;
-
-#include "shttpd.h"
+#include <sstream>
+#include <string>
#include "boost/bind.hpp"
+
+#include "zypp/base/Logger.h"
+#include "zypp/base/String.h"
+#include "zypp/base/Exception.h"
+#include "zypp/ExternalProgram.h"
#include "WebServer.h"

-#define LISTENING_PORT "8080"
+#include "mongoose.h"

-static shttpd_ctx * do_init_ctx()
+using namespace zypp;
+using namespace std;
+
+#define WEBRICK 0
+
+class WebServer::Impl
{
- static const char *argv[] = {"a", "-ports", LISTENING_PORT, NULL};
- static int argc = sizeof(argv) / sizeof(argv[0]) - 1;
- shttpd_ctx *ctx;
+public:
+ Impl()
+ {}

- ctx = shttpd_init(argc, const_cast<char**>(argv));
- return ctx;
-}
-
-WebServer::WebServer(const Pathname root, unsigned int port)
- : _docroot(root), _port(port), _stop(false)
+ virtual ~Impl()
+ {}
+
+ virtual string log() const
+ { return string(); }
+
+ virtual void start()
+ {}
+
+ virtual void stop()
+ {}
+
+ virtual void worker_thread()
+ {}
+
+private:
+ friend Impl * rwcowClone<Impl>( const Impl * rhs );
+ /** clone for RWCOW_pointer */
+ Impl * clone() const
+ { return new Impl( *this ); }
+};
+
+class WebServerWebrickImpl : public WebServer::Impl
{
- // init with a user port
- _ctx = do_init_ctx();
- setStrOption("root", root.asString());
- setNumOption("ports", port);
-}
+public:
+ WebServerWebrickImpl(const Pathname &root, unsigned int port)
+ : _docroot(root), _port(port), _stop(false), _stopped(true)
+ {
+ }
+
+ ~WebServerWebrickImpl()
+ {
+ if ( ! _stopped )
+ stop();
+ }
+
+ virtual void worker_thread()
+ {
+ _log.clear();
+
+ stringstream strlog(_log);

-void WebServer::start()
+ 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());
+
+ const char* argv[] =
+ {
+ "/usr/bin/ruby",
+ "-e",
+ webrick_code.c_str(),
+ NULL
+ };
+
+ ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1,
true);
+ string line;
+
+ _stopped = false;
+
+ while ( _stop );
+
+ /*
+ for(line = prog.receiveLine();
+ !line.empty();
+ line = prog.receiveLine() )
+ {
+ strlog << line;
+ if ( _stop )
+ break;
+ }
+ */
+ MIL << "Thread end requested" << endl;
+ //prog.close();
+ if ( prog.running() )
+ prog.kill();
+ MIL << "Thread about to finish" << endl;
+ }
+
+ virtual string log() const
+ {
+ return _log;
+ }
+
+ virtual void stop()
+ {
+ MIL << "Waiting for Webrick thread to finish" << endl;
+ _stop = true;
+ _thrd->join();
+ MIL << "Webrick thread finished" << endl;
+ _thrd.reset();
+ _stopped = true;
+ }
+
+ virtual void start()
+ {
+ _thrd.reset( new boost::thread(
boost::bind(&WebServerWebrickImpl::worker_thread, this) ) );
+ }
+
+ zypp::Pathname _docroot;
+ unsigned int _port;
+ zypp::shared_ptr<boost::thread> _thrd;
+ bool _stop;
+ bool _stopped;
+ std::string _log;
+};
+
+class WebServerMongooseImpl : public WebServer::Impl
{
-// _thrd.reset( new boost::thread(web_thread(_ctx)) );
- _thrd.reset( new boost::thread( boost::bind(&WebServer::worker_thread,
this) ) );
+public:
+ WebServerMongooseImpl(const Pathname &root, unsigned int port)
+ : _ctx(0L), _docroot(root)
+ , _port(port), _stop(false)
+ , _stopped(true)
+ {
+ }
+
+ ~WebServerMongooseImpl()
+ {
+ if ( ! _stopped )
+ stop();
+ }
+
+ virtual void worker_thread()
+ {
+ _log.clear();
+ _ctx = mg_start();
+ if ( ! mg_set_option(_ctx, "ports", str::form("%d", _port).c_str()) )
+ ZYPP_THROW(Exception("Failed to set port"));
+
+ mg_set_option(_ctx, "root", _docroot.c_str());
+ stringstream strlog(_log);
+
+ while ( !_stop )
+ {
+ // loop
+ }
+ MIL << "Thread end requested, shutting down shttpd" << endl;
+ mg_stop(_ctx);
+ _ctx = 0;
+ }
+
+ virtual string log() const
+ {
+ return _log;
+ }
+
+ virtual void stop()
+ {
+ MIL << "Waiting for shttpd thread to finish" << endl;
+ _stop = true;
+ _thrd->join();
+ MIL << "shttpd thread to finished" << endl;
+ _thrd.reset();
+ _stopped = true;
+ }
+
+ virtual void start()
+ {
+ MIL << "Starting shttpd (mongoose) thread" << endl;
+ _thrd.reset( new boost::thread(
boost::bind(&WebServerMongooseImpl::worker_thread, this) ) );
+ }
+
+ mg_context *_ctx;
+ zypp::Pathname _docroot;
+ unsigned int _port;
+ zypp::shared_ptr<boost::thread> _thrd;
+ bool _stop;
+ bool _stopped;
+ std::string _log;
+};
+
+
+WebServer::WebServer(const Pathname &root, unsigned int port)
+#if WEBRICK
+ : _pimpl(new WebServerWebrickImpl(root, port))
+#else
+ : _pimpl(new WebServerMongooseImpl(root, port))
+#endif
+{
}

-void WebServer::worker_thread()
+void WebServer::start()
{
- while( ! _stop )
- shttpd_poll(_ctx, 1000);
+ _pimpl->start();
}


-void WebServer::setStrOption( std::string name, std::string value)
+std::string WebServer::log() const
{
- if ( ! shttpd_set_option(_ctx, name.c_str(),
- value.c_str() ) )
- ZYPP_THROW(Exception("bad option"));
+ return _pimpl->log();
}

-void WebServer::setNumOption( std::string name, int value)
-{
- if ( ! shttpd_set_option(_ctx, name.c_str(),
- str::numstring(value).c_str()) )
- ZYPP_THROW(Exception("bad ioption"));
-}

void WebServer::stop()
{
- _stop = true;
- _thrd->join();
- _thrd.reset();
+ _pimpl->stop();
}

WebServer::~WebServer()
{
- shttpd_fini(_ctx);
}


diff --git a/tests/lib/WebServer.h b/tests/lib/WebServer.h
index 02d6625..e7c5420 100644
--- a/tests/lib/WebServer.h
+++ b/tests/lib/WebServer.h
@@ -1,6 +1,6 @@

-#ifndef ZYPP_WEBSERVER_H
-#define ZYPP_WEBSERVER_H
+#ifndef ZYPP_TEST_WEBSERVER_H
+#define ZYPP_TEST_WEBSERVER_H

#include "boost/thread.hpp"
#include "boost/smart_ptr.hpp"
@@ -8,12 +8,11 @@
#include "zypp/Pathname.h"
#include "zypp/base/PtrTypes.h"

-struct shttpd_ctx;
-
/**
*
* Starts a webserver to simulate remote transfers in
* testcases
+ * \author Duncan Mac-Vicar P. <dmacvicar@xxxxxxx>
*
* \code
* #include "WebServer.h"
@@ -39,7 +38,7 @@ class WebServer
/**
* creates a web server on \ref root and \port
*/
- WebServer(const zypp::Pathname root, unsigned int port=9099);
+ WebServer(const zypp::Pathname &root, unsigned int port=10001);
~WebServer();
/**
* Starts the webserver worker thread
@@ -50,17 +49,15 @@ class WebServer
*/
void stop();

- private:
-
- void setStrOption( std::string name, std::string value);
- void setNumOption( std::string name, int value);
+ /**
+ * shows the log of last run
+ */
+ std::string log() const;

- void worker_thread();
- struct shttpd_ctx *_ctx;
- zypp::Pathname _docroot;
- unsigned int _port;
- zypp::shared_ptr<boost::thread> _thrd;
- bool _stop;
+ class Impl;
+private:
+ /** Pointer to implementation */
+ zypp::RWCOW_pointer<Impl> _pimpl;
};

#endif
diff --git a/tests/zypp/Fetcher_test.cc b/tests/zypp/Fetcher_test.cc
index 10c2602..a00ece2 100644
--- a/tests/zypp/Fetcher_test.cc
+++ b/tests/zypp/Fetcher_test.cc
@@ -325,10 +325,10 @@ BOOST_AUTO_TEST_CASE(enqueuedir_http)
// add the key as trusted
//getZYpp()->keyRing()->importKey(PublicKey(DATADIR +
"/complexdir/subdir1/SHA1SUMS.key"), true);

- WebServer web((Pathname(TESTS_SRC_DIR) +
"/zypp/data/Fetcher/remote-site").c_str() );
+ WebServer web((Pathname(TESTS_SRC_DIR) +
"/zypp/data/Fetcher/remote-site").c_str(), 10001);
web.start();

- MediaSetAccess media( Url("http://localhost:9099";), "/" );
+ MediaSetAccess media( Url("http://127.0.0.1:10001";), "/" );
Fetcher fetcher;
filesystem::TmpDir dest;

@@ -355,10 +355,10 @@ BOOST_AUTO_TEST_CASE(enqueuedir_http_broken)
// add the key as trusted
//getZYpp()->keyRing()->importKey(PublicKey(DATADIR +
"/complexdir/subdir1/SHA1SUMS.key"), true);

- WebServer web((Pathname(TESTS_SRC_DIR) +
"/zypp/data/Fetcher/remote-site").c_str() );
+ WebServer web((Pathname(TESTS_SRC_DIR) +
"/zypp/data/Fetcher/remote-site").c_str() , 10002 );
web.start();

- MediaSetAccess media( Url("http://localhost:9099";), "/" );
+ MediaSetAccess media( Url("http://127.0.0.1:10002";), "/" );
Fetcher fetcher;
filesystem::TmpDir dest;

@@ -380,6 +380,9 @@ BOOST_AUTO_TEST_CASE(enqueuedir_http_broken)
fetcher.reset();

web.stop();
+
+ MIL << web.log();
+
}
}

diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt
index 46dd22c..a651570 100644
--- a/vendor/CMakeLists.txt
+++ b/vendor/CMakeLists.txt
@@ -1,2 +1,5 @@
-ADD_SUBDIRECTORY(shttpd)
+ADD_SUBDIRECTORY(mongoose)
+
+
+

diff --git a/zypp/media/MediaAccess.cc b/zypp/media/MediaAccess.cc
index 815de4c..85ac5ea 100644
--- a/zypp/media/MediaAccess.cc
+++ b/zypp/media/MediaAccess.cc
@@ -128,14 +128,7 @@ MediaAccess::open (const Url& url, const Pathname &
preferred_attach_point)
else if (scheme == "cifs")
_handler = new MediaCIFS (url,preferred_attach_point);
else if (scheme == "ftp" || scheme == "http" || scheme == "https")
- {
- // Another good idea would be activate MediaAria2c handler via external
var
- if ( getenv( "ZYPP_ARIA2C" ) &&
- MediaAria2c::existsAria2cmd() )
- _handler = new MediaAria2c (url,preferred_attach_point);
- else
- _handler = new MediaCurl (url,preferred_attach_point);
- }
+ _handler = new MediaAria2c (url,preferred_attach_point);
else
{
ZYPP_THROW(MediaUnsupportedUrlSchemeException(url));
diff --git a/zypp/media/MediaAria2c.cc b/zypp/media/MediaAria2c.cc
index 2eacecf..8720c7f 100644
--- a/zypp/media/MediaAria2c.cc
+++ b/zypp/media/MediaAria2c.cc
@@ -421,6 +421,7 @@ void MediaAria2c::getFileCopy( const Pathname & filename ,
const Pathname & targ

ExternalProgram::Arguments args = _args;
args.push_back(str::form("--dir=%s", target.dirname().c_str()));
+
args.push_back(fileurl.asString());

do
@@ -450,8 +451,8 @@ void MediaAria2c::getFileCopy( const Pathname & filename ,
const Pathname & targ
ZYPP_THROW(MediaFileNotFoundException(_url, filename));
}

- if (!ariaResponse.substr(0,9).compare("[#2 SIZE:")) {
-
+ if (!ariaResponse.substr(0,9).compare("[#2 SIZE:"))
+ {
if (!nLine)
{
size_t left_bound = ariaResponse.find('(',0) + 1;
@@ -467,6 +468,7 @@ void MediaAria2c::getFileCopy( const Pathname & filename ,
const Pathname & targ
}
}
}
+
aria.close();

report->finish( _url , zypp::media::DownloadProgressReport::NO_ERROR,
"");
--
To unsubscribe, e-mail: zypp-commit+unsubscribe@xxxxxxxxxxxx
For additional commands, e-mail: zypp-commit+help@xxxxxxxxxxxx

< Previous Next >
This Thread
  • No further messages