summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--icespider/core/core.cpp62
-rw-r--r--icespider/core/core.h9
-rw-r--r--icespider/core/ihttpRequest.cpp19
-rw-r--r--icespider/core/ihttpRequest.h5
-rw-r--r--icespider/fcgi/cgiCore.cpp51
-rw-r--r--icespider/fcgi/cgiCore.h21
-rw-r--r--icespider/fcgi/cgiRequestBase.cpp13
-rw-r--r--icespider/fcgi/cgiRequestBase.h3
-rw-r--r--icespider/fcgi/main.cpp3
-rw-r--r--icespider/unittests/Jamfile.jam3
-rw-r--r--icespider/unittests/testApp.cpp26
-rw-r--r--icespider/unittests/testFcgi.cpp4
12 files changed, 138 insertions, 81 deletions
diff --git a/icespider/core/core.cpp b/icespider/core/core.cpp
index ab80b90..117c869 100644
--- a/icespider/core/core.cpp
+++ b/icespider/core/core.cpp
@@ -10,17 +10,6 @@ INSTANTIATEFACTORY(IceSpider::Plugin, Ice::CommunicatorPtr, Ice::PropertiesPtr);
namespace IceSpider {
const boost::filesystem::path Core::defaultConfig("config/ice.properties");
- static
- bool
- operator/=(const PathElements & pathparts, const IRouteHandler * r)
- {
- auto rpi = r->parts.begin();
- for (auto ppi = pathparts.begin(); ppi != pathparts.end(); ++ppi, ++rpi) {
- if (!(*rpi)->matches(*ppi)) return false;
- }
- return true;
- }
-
Core::Core(const Ice::StringSeq & args)
{
Ice::InitializationData id;
@@ -34,18 +23,11 @@ namespace IceSpider {
// Initialize routes
for (const auto & rp : AdHoc::PluginManager::getDefault()->getAll<RouteHandlerFactory>()) {
- auto r = rp->implementation()->create(this);
- if (routes.size() <= r->pathElementCount()) {
- routes.resize(r->pathElementCount() + 1);
- }
- auto & lroutes = routes[r->pathElementCount()];
- lroutes.push_back(r);
- }
- for (auto & l : routes) {
- std::sort(l.begin(), l.end(), [](const auto & a, const auto & b) {
- return a->path < b->path;
- });
+ allRoutes.push_back(rp->implementation()->create(this));
}
+ std::sort(allRoutes.begin(), allRoutes.end(), [](const auto & a, const auto & b) {
+ return a->path < b->path;
+ });
// Load plugins
auto plugins = AdHoc::PluginManager::getDefault()->getAll<PluginFactory>();
if (!plugins.empty()) {
@@ -69,21 +51,19 @@ namespace IceSpider {
pluginAdapter->deactivate();
pluginAdapter->destroy();
}
- // Initialize routes
- for (auto l : routes) {
- for (auto r : l) {
- delete r;
- }
+ // Terminate routes
+ for (auto r : allRoutes) {
+ delete r;
}
if (communicator) communicator->destroy();
}
void
- Core::process(IHttpRequest * request) const
+ Core::process(IHttpRequest * request, const IRouteHandler * route) const
{
try {
- findRoute(request)->execute(request);
+ (route ? route : findRoute(request))->execute(request);
}
catch (const HttpException & he) {
request->response(he.code, he.message);
@@ -96,28 +76,10 @@ namespace IceSpider {
}
}
- const IRouteHandler *
- Core::findRoute(const IHttpRequest * request) const
+ const IceSpider::IRouteHandler *
+ Core::findRoute(const IceSpider::IHttpRequest *) const
{
- const auto & pathparts = request->getRequestPath();
- const auto method = request->getRequestMethod();
- if (pathparts.size() >= routes.size()) {
- throw Http404_NotFound();
- }
- const auto & routeSet = routes[pathparts.size()];
- bool match = false;
- for (const auto & r : routeSet) {
- if (pathparts /= r) {
- if (r->method == method) {
- return r;
- }
- match = true;
- }
- }
- if (!match) {
- throw Http404_NotFound();
- }
- throw Http405_MethodNotAllowed();
+ throw Http404_NotFound();
}
Ice::ObjectPrx
diff --git a/icespider/core/core.h b/icespider/core/core.h
index 0627e74..d6aa173 100644
--- a/icespider/core/core.h
+++ b/icespider/core/core.h
@@ -11,14 +11,13 @@
namespace IceSpider {
class DLL_PUBLIC Core {
public:
- typedef std::vector<const IRouteHandler *> LengthRoutes;
- typedef std::vector<LengthRoutes> Routes;
+ typedef std::vector<const IRouteHandler *> AllRoutes;
Core(const Ice::StringSeq & = {});
~Core();
- void process(IHttpRequest *) const;
- const IRouteHandler * findRoute(const IHttpRequest *) const;
+ virtual const IRouteHandler * findRoute(const IHttpRequest *) const;
+ void process(IHttpRequest *, const IRouteHandler * = nullptr) const;
Ice::ObjectPrx getProxy(const char * type) const;
@@ -28,7 +27,7 @@ namespace IceSpider {
return Interface::ProxyType::uncheckedCast(getProxy(typeid(Interface).name()));
}
- Routes routes;
+ AllRoutes allRoutes;
Ice::CommunicatorPtr communicator;
Ice::ObjectAdapterPtr pluginAdapter;
diff --git a/icespider/core/ihttpRequest.cpp b/icespider/core/ihttpRequest.cpp
index 1ca4c38..dea84e0 100644
--- a/icespider/core/ihttpRequest.cpp
+++ b/icespider/core/ihttpRequest.cpp
@@ -101,8 +101,8 @@ namespace IceSpider {
const IceUtil::Optional<std::string> & d, const IceUtil::Optional<std::string> & p, bool s,
IceUtil::Optional<time_t> e)
{
- auto & o = getOutputStream();
- o << "Set-Cookie: " << XWwwFormUrlEncoded::urlencode(name) <<
+ std::stringstream o;
+ o << XWwwFormUrlEncoded::urlencode(name) <<
'=' << XWwwFormUrlEncoded::urlencode(value);
if (e) {
char buf[45];
@@ -115,7 +115,7 @@ namespace IceSpider {
if (d) o << "; domain=" << *d;
if (p) o << "; path=" << *p;
if (s) o << "; secure";
- o << "\r\n";
+ setHeader("Set-Cookie", o.str());
}
template <typename T>
@@ -127,17 +127,8 @@ namespace IceSpider {
void IHttpRequest::responseRedirect(const std::string & url, const IceUtil::Optional<std::string> & statusMsg) const
{
- getOutputStream()
- << "Status: 303 " << (statusMsg ? *statusMsg : "Moved") << "\r\n"
- << "Location: " << url << "\r\n"
- << "\r\n";
- }
-
- void IHttpRequest::response(short statusCode, const std::string & statusMsg) const
- {
- getOutputStream()
- << "Status: " << statusCode << " " << statusMsg << "\r\n"
- << "\r\n";
+ setHeader("Location", url);
+ response(303, (statusMsg ? *statusMsg : "Moved"));
}
diff --git a/icespider/core/ihttpRequest.h b/icespider/core/ihttpRequest.h
index 0cd0f8b..d92d549 100644
--- a/icespider/core/ihttpRequest.h
+++ b/icespider/core/ihttpRequest.h
@@ -35,6 +35,7 @@ namespace IceSpider {
virtual ContentTypeSerializer getSerializer(const IRouteHandler *) const;
virtual std::istream & getInputStream() const = 0;
virtual std::ostream & getOutputStream() const = 0;
+ virtual void setHeader(const std::string &, const std::string &) const = 0;
template<typename T>
T getURLParam(unsigned int) const;
@@ -70,12 +71,12 @@ namespace IceSpider {
IceUtil::Optional<T> getHeaderParam(const std::string & key) const;
template<typename T>
IceUtil::Optional<T> getCookieParam(const std::string & key) const;
- void response(short, const std::string &) const;
+ virtual void response(short, const std::string &) const = 0;
template<typename T>
void response(const IRouteHandler * route, const T & t) const
{
auto s = getSerializer(route);
- getOutputStream() << "Content-Type: " << s.first.group << "/" << s.first.type << "\r\n";
+ setHeader("Content-Type", s.first.group + "/" + s.first.type);
response(200, "OK");
Slicer::SerializeAnyWith<T>(t, s.second);
}
diff --git a/icespider/fcgi/cgiCore.cpp b/icespider/fcgi/cgiCore.cpp
new file mode 100644
index 0000000..0adefab
--- /dev/null
+++ b/icespider/fcgi/cgiCore.cpp
@@ -0,0 +1,51 @@
+#include "cgiCore.h"
+
+namespace IceSpider {
+ static
+ bool
+ operator/=(const PathElements & pathparts, const IRouteHandler * r)
+ {
+ auto rpi = r->parts.begin();
+ for (auto ppi = pathparts.begin(); ppi != pathparts.end(); ++ppi, ++rpi) {
+ if (!(*rpi)->matches(*ppi)) return false;
+ }
+ return true;
+ }
+
+ CgiCore::CgiCore(const Ice::StringSeq & opts) :
+ Core(opts)
+ {
+ for (const auto & r : allRoutes) {
+ if (routes.size() <= r->pathElementCount()) {
+ routes.resize(r->pathElementCount() + 1);
+ }
+ auto & lroutes = routes[r->pathElementCount()];
+ lroutes.push_back(r);
+ }
+ }
+
+ const IRouteHandler *
+ CgiCore::findRoute(const IHttpRequest * request) const
+ {
+ const auto & pathparts = request->getRequestPath();
+ const auto method = request->getRequestMethod();
+ if (pathparts.size() >= routes.size()) {
+ throw Http404_NotFound();
+ }
+ const auto & routeSet = routes[pathparts.size()];
+ bool match = false;
+ for (const auto & r : routeSet) {
+ if (pathparts /= r) {
+ if (r->method == method) {
+ return r;
+ }
+ match = true;
+ }
+ }
+ if (!match) {
+ throw Http404_NotFound();
+ }
+ throw Http405_MethodNotAllowed();
+ }
+}
+
diff --git a/icespider/fcgi/cgiCore.h b/icespider/fcgi/cgiCore.h
new file mode 100644
index 0000000..1915a4d
--- /dev/null
+++ b/icespider/fcgi/cgiCore.h
@@ -0,0 +1,21 @@
+#ifndef ICESPIDER_CGI_CGICORE_H
+#define ICESPIDER_CGI_CGICORE_H
+
+#include <core.h>
+
+namespace IceSpider {
+ class CgiCore : public Core {
+ public:
+ typedef std::vector<const IRouteHandler *> LengthRoutes;
+ typedef std::vector<LengthRoutes> Routes;
+
+ CgiCore(const Ice::StringSeq & = {});
+
+ const IRouteHandler * findRoute(const IHttpRequest *) const override;
+
+ Routes routes;
+ };
+}
+
+#endif
+
diff --git a/icespider/fcgi/cgiRequestBase.cpp b/icespider/fcgi/cgiRequestBase.cpp
index a773b07..e820e05 100644
--- a/icespider/fcgi/cgiRequestBase.cpp
+++ b/icespider/fcgi/cgiRequestBase.cpp
@@ -121,6 +121,19 @@ namespace IceSpider {
return optionalLookup(("HTTP_" + boost::algorithm::to_upper_copy(key)).c_str(), envmap);
}
+ void CgiRequestBase::response(short statusCode, const std::string & statusMsg) const
+ {
+ getOutputStream()
+ << "Status: " << statusCode << " " << statusMsg << "\r\n"
+ << "\r\n";
+ }
+
+ void
+ CgiRequestBase::setHeader(const std::string & header, const std::string & value) const
+ {
+ getOutputStream() << header << ": " << value << "\r\n";
+ }
+
bool
CgiRequestBase::cmp_str::operator()(char const * a, char const * b) const
{
diff --git a/icespider/fcgi/cgiRequestBase.h b/icespider/fcgi/cgiRequestBase.h
index e613866..ec3d4dd 100644
--- a/icespider/fcgi/cgiRequestBase.h
+++ b/icespider/fcgi/cgiRequestBase.h
@@ -28,6 +28,9 @@ namespace IceSpider {
OptionalString getCookieParam(const std::string & key) const override;
OptionalString getEnv(const std::string & key) const override;
+ void response(short, const std::string &) const override;
+ void setHeader(const std::string &, const std::string &) const override;
+
private:
static OptionalString optionalLookup(const std::string & key, const VarMap &);
static OptionalString optionalLookup(const std::string & key, const StringMap &);
diff --git a/icespider/fcgi/main.cpp b/icespider/fcgi/main.cpp
index 2c543e1..4149cb2 100644
--- a/icespider/fcgi/main.cpp
+++ b/icespider/fcgi/main.cpp
@@ -1,6 +1,7 @@
#include <visibility.h>
#include "fcgiRequest.h"
#include "cgiRequest.h"
+#include "cgiCore.h"
using namespace IceSpider;
@@ -8,7 +9,7 @@ DLL_PUBLIC
int
main(int argc, char ** argv, char ** env)
{
- Core core;
+ CgiCore core;
if (!FCGX_IsCGI()) {
FCGX_Request request;
diff --git a/icespider/unittests/Jamfile.jam b/icespider/unittests/Jamfile.jam
index 8a0edff..ddc1e4a 100644
--- a/icespider/unittests/Jamfile.jam
+++ b/icespider/unittests/Jamfile.jam
@@ -64,6 +64,7 @@ run
testApp.cpp
base2.cpp
testRoutes.json
+ ../fcgi/cgiCore.cpp
: :
config/ice.properties
xslt/transform.xslt
@@ -83,12 +84,14 @@ run
<implicit-dependency>test-api
<dependency>../compile
<include>.
+ <include>../fcgi
: testApp ;
run
testFcgi.cpp
test-fcgi.ice
../fcgi/cgiRequestBase.cpp
+ ../fcgi/cgiCore.cpp
: : :
<slicer>yes
<define>BOOST_TEST_DYN_LINK
diff --git a/icespider/unittests/testApp.cpp b/icespider/unittests/testApp.cpp
index de5e921..e42a5aa 100644
--- a/icespider/unittests/testApp.cpp
+++ b/icespider/unittests/testApp.cpp
@@ -3,7 +3,7 @@
#include <safeMapFind.h>
#include <irouteHandler.h>
-#include <core.h>
+#include <cgiCore.h>
#include <exceptions.h>
#include <test-api.h>
#include <Ice/ObjectAdapter.h>
@@ -84,6 +84,18 @@ class TestRequest : public IHttpRequest {
return output;
}
+ void response(short statusCode, const std::string & statusMsg) const override
+ {
+ getOutputStream()
+ << "Status: " << statusCode << " " << statusMsg << "\r\n"
+ << "\r\n";
+ }
+
+ void setHeader(const std::string & header, const std::string & value) const override
+ {
+ getOutputStream() << header << ": " << value << "\r\n";
+ }
+
typedef std::map<std::string, std::string> MapVars;
typedef std::vector<std::string> UrlVars;
UrlVars url;
@@ -97,10 +109,10 @@ class TestRequest : public IHttpRequest {
const HttpMethod method;
};
-class CoreWithProps : public Core {
+class CoreWithProps : public CgiCore {
public:
CoreWithProps() :
- Core({
+ CgiCore({
"--Custom.Prop=value"
})
{
@@ -119,10 +131,10 @@ BOOST_AUTO_TEST_CASE( properties )
BOOST_AUTO_TEST_SUITE_END();
-class CoreWithFileProps : public Core {
+class CoreWithFileProps : public CgiCore {
public:
CoreWithFileProps() :
- Core({
+ CgiCore({
"--IceSpider.Config=config/custom.properties",
"--Custom.Prop=value"
})
@@ -144,7 +156,7 @@ BOOST_AUTO_TEST_CASE( properties )
BOOST_AUTO_TEST_SUITE_END();
-BOOST_FIXTURE_TEST_SUITE(defaultProps, Core);
+BOOST_FIXTURE_TEST_SUITE(defaultProps, CgiCore);
BOOST_AUTO_TEST_CASE( testCoreSettings )
{
@@ -228,7 +240,7 @@ class TestSerice : public TestIceSpider::TestApi {
}
};
-class TestApp : public Core {
+class TestApp : public CgiCore {
public:
TestApp() :
adp(communicator->createObjectAdapterWithEndpoints("test", "default"))
diff --git a/icespider/unittests/testFcgi.cpp b/icespider/unittests/testFcgi.cpp
index bf8e442..2db9bcf 100644
--- a/icespider/unittests/testFcgi.cpp
+++ b/icespider/unittests/testFcgi.cpp
@@ -1,7 +1,7 @@
#define BOOST_TEST_MODULE TestApp
#include <boost/test/unit_test.hpp>
-#include <core.h>
+#include <cgiCore.h>
#include <definedDirs.h>
#include <cgiRequestBase.h>
#include <test-fcgi.h>
@@ -87,7 +87,7 @@ namespace std {
// LCOV_EXCL_STOP
}
-BOOST_FIXTURE_TEST_SUITE( CgiRequestBase, IceSpider::Core );
+BOOST_FIXTURE_TEST_SUITE( CgiRequestBase, IceSpider::CgiCore );
BOOST_AUTO_TEST_CASE( NoEnvironment )
{