summaryrefslogtreecommitdiffstats
path: root/sca-cpp
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2012-12-11 04:03:29 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2012-12-11 04:03:29 +0000
commit86b1de85536e93c59a25702a5a2d3e384202ffd2 (patch)
treec61d91970980199c597304ddcb01919993fbeb82 /sca-cpp
parent5f29c3b769fcdb2532d4948aa1c649d4330304b9 (diff)
More changes to port to C++11, adjust to use the new JSON support, and cleanup rest of the modules.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1419987 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-cpp')
-rw-r--r--sca-cpp/trunk/modules/http/Makefile.am14
-rw-r--r--sca-cpp/trunk/modules/http/curl-connect.cpp10
-rw-r--r--sca-cpp/trunk/modules/http/curl-get.cpp4
-rw-r--r--sca-cpp/trunk/modules/http/curl-test.cpp19
-rw-r--r--sca-cpp/trunk/modules/http/http.hpp358
-rwxr-xr-xsca-cpp/trunk/modules/http/httpd-callgrind25
-rw-r--r--sca-cpp/trunk/modules/http/httpd.hpp181
-rw-r--r--sca-cpp/trunk/modules/http/mod-openauth.cpp269
-rw-r--r--sca-cpp/trunk/modules/http/mod-ssltunnel.cpp72
-rw-r--r--sca-cpp/trunk/modules/http/openauth.hpp39
-rw-r--r--sca-cpp/trunk/modules/java/Makefile.am5
-rw-r--r--sca-cpp/trunk/modules/java/driver.hpp4
-rw-r--r--sca-cpp/trunk/modules/java/eval.hpp334
-rw-r--r--sca-cpp/trunk/modules/java/java-shell.cpp4
-rw-r--r--sca-cpp/trunk/modules/java/java-test.cpp26
-rw-r--r--sca-cpp/trunk/modules/java/jni-test.cpp8
-rw-r--r--sca-cpp/trunk/modules/java/mod-java.cpp27
-rw-r--r--sca-cpp/trunk/modules/java/mod-java.hpp40
-rw-r--r--sca-cpp/trunk/modules/oauth/Makefile.am4
-rw-r--r--sca-cpp/trunk/modules/oauth/mod-oauth1.cpp187
-rw-r--r--sca-cpp/trunk/modules/oauth/mod-oauth2.cpp167
-rw-r--r--sca-cpp/trunk/modules/opencl/Makefile.am4
-rw-r--r--sca-cpp/trunk/modules/opencl/driver.hpp2
-rw-r--r--sca-cpp/trunk/modules/opencl/eval.hpp49
-rw-r--r--sca-cpp/trunk/modules/opencl/opencl-shell.cpp4
-rw-r--r--sca-cpp/trunk/modules/opencl/opencl-test.cpp72
-rw-r--r--sca-cpp/trunk/modules/python/Makefile.am4
-rw-r--r--sca-cpp/trunk/modules/python/driver.hpp8
-rw-r--r--sca-cpp/trunk/modules/python/eval.hpp204
-rw-r--r--sca-cpp/trunk/modules/python/mod-python.cpp27
-rw-r--r--sca-cpp/trunk/modules/python/mod-python.hpp42
-rw-r--r--sca-cpp/trunk/modules/python/python-shell.cpp4
-rw-r--r--sca-cpp/trunk/modules/python/python-test.cpp165
-rw-r--r--sca-cpp/trunk/modules/server/Makefile.am4
-rw-r--r--sca-cpp/trunk/modules/server/client-test.hpp287
-rw-r--r--sca-cpp/trunk/modules/server/htdocs/test/entry.xml14
-rw-r--r--sca-cpp/trunk/modules/server/htdocs/test/feed.xml44
-rw-r--r--sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt15
-rw-r--r--sca-cpp/trunk/modules/server/htdocs/test/json-result.txt5
-rw-r--r--sca-cpp/trunk/modules/server/impl-test.cpp4
-rw-r--r--sca-cpp/trunk/modules/server/mod-cpp.hpp47
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.cpp8
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.hpp568
-rw-r--r--sca-cpp/trunk/modules/server/mod-scheme.hpp43
-rwxr-xr-xsca-cpp/trunk/modules/server/server-conf12
-rw-r--r--sca-cpp/trunk/modules/wsgi/Makefile.am2
-rw-r--r--sca-cpp/trunk/modules/wsgi/client-test.cpp2
47 files changed, 1667 insertions, 1770 deletions
diff --git a/sca-cpp/trunk/modules/http/Makefile.am b/sca-cpp/trunk/modules/http/Makefile.am
index a504adcda5..42504d57ec 100644
--- a/sca-cpp/trunk/modules/http/Makefile.am
+++ b/sca-cpp/trunk/modules/http/Makefile.am
@@ -20,28 +20,28 @@ INCLUDES = -I${HTTPD_INCLUDE}
incl_HEADERS = *.hpp
incldir = $(prefix)/include/modules/http
-dist_mod_SCRIPTS = httpd-conf httpd-addr httpd-start httpd-stop httpd-restart ssl-ca-conf ssl-cert-conf ssl-cert-find httpd-ssl-conf basic-auth-conf cert-auth-conf form-auth-conf open-auth-conf passwd-auth-conf group-auth-conf cache-conf cache-ssl-conf cache-manifest proxy-conf proxy-base-conf proxy-ssl-conf proxy-balancer-conf proxy-member-conf proxy-ssl-member-conf proxy-ssl-nossl-member-conf alt-host-conf mass-host-conf mass-host-ssl-conf httpd-tunnel-ssl-conf tunnel-ssl-conf httpd-worker-conf httpd-event-conf httpd-loglevel-conf minify-html minify-js minify-css
+dist_mod_SCRIPTS = httpd-conf httpd-addr httpd-start httpd-stop httpd-restart ssl-ca-conf ssl-cert-conf ssl-cert-find httpd-ssl-conf base64-encode basic-auth-conf cert-auth-conf form-auth-conf open-auth-conf passwd-auth-conf group-auth-conf cache-conf cache-ssl-conf cache-manifest proxy-conf proxy-base-conf proxy-ssl-conf proxy-balancer-conf proxy-member-conf proxy-ssl-member-conf proxy-ssl-nossl-member-conf alt-host-conf mass-host-conf mass-host-ssl-conf httpd-tunnel-ssl-conf tunnel-ssl-conf httpd-worker-conf httpd-event-conf httpd-loglevel-conf minify-html minify-js minify-css
moddir = $(prefix)/modules/http
curl_test_SOURCES = curl-test.cpp
-curl_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+curl_test_LDFLAGS = -lxml2 -lcurl -ljansson
curl_get_SOURCES = curl-get.cpp
-curl_get_LDFLAGS = -lxml2 -lcurl -lmozjs
+curl_get_LDFLAGS = -lxml2 -lcurl -ljansson
curl_connect_SOURCES = curl-connect.cpp
-curl_connect_LDFLAGS = -lxml2 -lcurl -lmozjs
+curl_connect_LDFLAGS = -lxml2 -lcurl -ljansson
mod_LTLIBRARIES = libmod_tuscany_ssltunnel.la libmod_tuscany_openauth.la
noinst_DATA = libmod_tuscany_ssltunnel${libsuffix} libmod_tuscany_openauth${libsuffix}
libmod_tuscany_ssltunnel_la_SOURCES = mod-ssltunnel.cpp
-libmod_tuscany_ssltunnel_la_LDFLAGS = -lxml2 -lcurl -lmozjs
+libmod_tuscany_ssltunnel_la_LDFLAGS = -lxml2 -lcurl -ljansson
libmod_tuscany_ssltunnel${libsuffix}:
ln -s .libs/libmod_tuscany_ssltunnel${libsuffix}
libmod_tuscany_openauth_la_SOURCES = mod-openauth.cpp
-libmod_tuscany_openauth_la_LDFLAGS = -lxml2 -lcurl -lmozjs
+libmod_tuscany_openauth_la_LDFLAGS = -lxml2 -lcurl -ljansson
libmod_tuscany_openauth${libsuffix}:
ln -s .libs/libmod_tuscany_openauth${libsuffix}
@@ -82,7 +82,7 @@ modsecuritydir = $(prefix)/modules/http
endif
-dist_noinst_SCRIPTS = httpd-test http-test proxy-test
+dist_noinst_SCRIPTS = httpd-test http-test proxy-test httpd-memgrind httpd-callgrind
noinst_PROGRAMS = curl-test curl-get curl-connect
TESTS = httpd-test http-test proxy-test
diff --git a/sca-cpp/trunk/modules/http/curl-connect.cpp b/sca-cpp/trunk/modules/http/curl-connect.cpp
index 9f5ee17368..6e16da7163 100644
--- a/sca-cpp/trunk/modules/http/curl-connect.cpp
+++ b/sca-cpp/trunk/modules/http/curl-connect.cpp
@@ -34,14 +34,14 @@ namespace tuscany {
namespace http {
const bool testConnect(const string& url, const string& ca = "", const string& cert = "", const string& key = "") {
- gc_scoped_pool p;
+ const gc_scoped_pool p;
- CURLSession cs(ca, cert, key, "", 0);
+ const CURLSession cs(ca, cert, key, "", 0);
const failable<bool> crc = connect(url, cs);
assert(hasContent(crc));
apr_pollset_t* pollset;
- apr_status_t cprc = apr_pollset_create(&pollset, 2, pool(p), 0);
+ const apr_status_t cprc = apr_pollset_create(&pollset, 2, pool(p), 0);
assert(cprc == APR_SUCCESS);
apr_socket_t* csock = sock(0, p);
const apr_pollfd_t* cpollfd = pollfd(csock, APR_POLLIN | APR_POLLERR | APR_POLLNVAL | APR_POLLHUP, p);
@@ -53,7 +53,7 @@ const bool testConnect(const string& url, const string& ca = "", const string& c
const apr_pollfd_t* pollfds;
apr_int32_t pollcount;
for(;;) {
- apr_status_t pollrc = apr_pollset_poll(pollset, -1, &pollcount, &pollfds);
+ const apr_status_t pollrc = apr_pollset_poll(pollset, -1, &pollcount, &pollfds);
assert(pollrc == APR_SUCCESS);
for (; pollcount > 0; pollcount--, pollfds++) {
@@ -88,7 +88,7 @@ const bool testConnect(const string& url, const string& ca = "", const string& c
}
}
-int main(unused const int argc, const char** argv) {
+int main(unused const int argc, const char** const argv) {
if (argc > 2)
tuscany::http::testConnect(tuscany::string(argv[1]), tuscany::string(argv[2]), tuscany::string(argv[3]), tuscany::string(argv[4]));
else
diff --git a/sca-cpp/trunk/modules/http/curl-get.cpp b/sca-cpp/trunk/modules/http/curl-get.cpp
index a16daeeae3..983dd20fc5 100644
--- a/sca-cpp/trunk/modules/http/curl-get.cpp
+++ b/sca-cpp/trunk/modules/http/curl-get.cpp
@@ -33,7 +33,7 @@ namespace tuscany {
namespace http {
const bool testGet(const string& url, const string& ca = "", const string& cert = "", const string& key = "") {
- CURLSession ch(ca, cert, key, "", 0);
+ const CURLSession ch(ca, cert, key, "", 0);
const failable<value> val = get(url, ch);
assert(hasContent(val));
cout << content(val) << endl;
@@ -43,7 +43,7 @@ const bool testGet(const string& url, const string& ca = "", const string& cert
}
}
-int main(unused const int argc, const char** argv) {
+int main(unused const int argc, const char** const argv) {
if (argc > 2)
tuscany::http::testGet(tuscany::string(argv[1]), tuscany::string(argv[2]), tuscany::string(argv[3]), tuscany::string(argv[4]));
else
diff --git a/sca-cpp/trunk/modules/http/curl-test.cpp b/sca-cpp/trunk/modules/http/curl-test.cpp
index f0806ea577..6a1174a404 100644
--- a/sca-cpp/trunk/modules/http/curl-test.cpp
+++ b/sca-cpp/trunk/modules/http/curl-test.cpp
@@ -40,7 +40,7 @@ ostream* curlWriter(const string& s, ostream* os) {
}
const bool testGet() {
- CURLSession ch("", "", "", "", 0);
+ const CURLSession ch("", "", "", "", 0);
{
ostringstream os;
const failable<list<ostream*> > r = get<ostream*>(curlWriter, &os, testURI, ch);
@@ -56,21 +56,14 @@ const bool testGet() {
return true;
}
-struct getLoop {
- CURLSession& ch;
- getLoop(CURLSession& ch) : ch(ch) {
- }
- const bool operator()() const {
+const bool testGetPerf() {
+ const CURLSession ch("", "", "", "", 0);
+ blambda gl = [ch]() -> const bool {
const failable<value> r = getcontent(testURI, ch);
assert(hasContent(r));
assert(contains(car(reverse(list<value>(content(r)))), "It works"));
return true;
- }
-};
-
-const bool testGetPerf() {
- CURLSession ch("", "", "", "", 0);
- lambda<bool()> gl = getLoop(ch);
+ };
cout << "Static GET test " << time(gl, 5, 200) << " ms" << endl;
return true;
}
@@ -79,7 +72,7 @@ const bool testGetPerf() {
}
int main() {
- tuscany::gc_scoped_pool p;
+ const tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
//tuscany::http::testURI = tuscany::string("http://") + tuscany::http::hostName() + ":8090";
diff --git a/sca-cpp/trunk/modules/http/http.hpp b/sca-cpp/trunk/modules/http/http.hpp
index 408b9fdee5..1153f61840 100644
--- a/sca-cpp/trunk/modules/http/http.hpp
+++ b/sca-cpp/trunk/modules/http/http.hpp
@@ -71,86 +71,91 @@ public:
*/
class CURLSession {
public:
- CURLSession() : h(NULL), p(), sock(NULL), wpollset(NULL), wpollfd(NULL), rpollset(NULL), rpollfd(NULL), owner(false), ca(""), cert(""), key(""), cookie(""), timeout(0) {
+ CURLSession() : p(), h(*(new (gc_new<handles>()) handles())), owner(false), ca(emptyString), cert(emptyString), key(emptyString), cookie(emptyString), timeout(0) {
}
- CURLSession(const string& ca, const string& cert, const string& key, const string& cookie, const int timeout) : h(NULL), p(), sock(NULL), wpollset(NULL), wpollfd(NULL), rpollset(NULL), rpollfd(NULL), owner(true), ca(ca), cert(cert), key(key), cookie(cookie), timeout(timeout) {
+ CURLSession(const string& ca, const string& cert, const string& key, const string& cookie, const int timeout) : p(), h(*(new (gc_new<handles>()) handles())), owner(true), ca(ca), cert(cert), key(key), cookie(cookie), timeout(timeout) {
}
- CURLSession(const CURLSession& c) : h(c.h), p(c.p), sock(c.sock), wpollset(c.wpollset), wpollfd(c.wpollfd), rpollset(c.rpollset), rpollfd(c.rpollfd), owner(false), ca(c.ca), cert(c.cert), key(c.key), cookie(c.cookie), timeout(c.timeout) {
+ CURLSession(const CURLSession& c) : p(c.p), h(c.h), owner(false), ca(c.ca), cert(c.cert), key(c.key), cookie(c.cookie), timeout(c.timeout) {
}
- const CURLSession& operator=(const CURLSession& c) {
- if(this == &c)
- return *this;
- h = c.h;
- p = c.p;
- sock = c.sock;
- wpollset = c.wpollset;
- wpollfd = c.wpollfd;
- rpollset = c.rpollset;
- rpollfd = c.rpollfd;
- owner = false;
- ca = c.ca;
- cert = c.cert;
- key = c.key;
- cookie = c.cookie;
- timeout = c.timeout;
- return *this;
- }
+ CURLSession& operator=(const CURLSession& c) = delete;
~CURLSession() {
if (!owner)
return;
- if (h == NULL)
+ if (h.h == NULL)
return;
- curl_easy_cleanup(h);
+ debug(h.h, "http::~CURLSession::cleanup::h");
+ curl_easy_cleanup(h.h);
}
private:
- CURL* h;
- gc_child_pool p;
- apr_socket_t* sock;
- apr_pollset_t* wpollset;
- apr_pollfd_t* wpollfd;
- apr_pollset_t* rpollset;
- apr_pollfd_t* rpollfd;
- bool owner;
-
- friend CURL* handle(const CURLSession& cs);
- friend apr_socket_t* sock(const CURLSession& cs);
- friend const failable<CURL*> setup(const string& url, CURLSession& cs);
- friend const failable<bool> cleanup(CURLSession& cs);
- friend const failable<bool> connect(const string& url, CURLSession& cs);
- friend const failable<bool> send(const char* c, const size_t l, CURLSession& cs);
- friend const failable<size_t> recv(char* c, const size_t l, CURLSession& cs);
+ class handles {
+ public:
+ handles() : h(NULL), sock(NULL), wpollset(NULL), wpollfd(NULL), rpollset(NULL), rpollfd(NULL) {
+ }
+
+ handles(const handles& c) : h(c.h), sock(c.sock), wpollset(c.wpollset), wpollfd(c.wpollfd), rpollset(c.rpollset), rpollfd(c.rpollfd) {
+ }
+
+ private:
+ CURL* h;
+ apr_socket_t* sock;
+ apr_pollset_t* wpollset;
+ apr_pollfd_t* wpollfd;
+ apr_pollset_t* rpollset;
+ apr_pollfd_t* rpollfd;
+
+ friend class CURLSession;
+ friend CURL* const handle(const CURLSession& cs);
+ friend apr_socket_t* const sock(const CURLSession& cs);
+ friend const failable<CURL*> setup(const string& url, const CURLSession& cs);
+ friend const failable<bool> cleanup(const CURLSession& cs);
+ friend const failable<bool> connect(const string& url, const CURLSession& cs);
+ friend const failable<bool> send(const char* const c, const size_t l, const CURLSession& cs);
+ friend const failable<size_t> recv(char* const c, const size_t l, const CURLSession& cs);
+ };
+
+ const gc_child_pool p;
+ handles& h;
+ const bool owner;
+
+ friend CURL* const handle(const CURLSession& cs);
+ friend apr_socket_t* const sock(const CURLSession& cs);
+ friend const failable<CURL*> setup(const string& url, const CURLSession& cs);
+ friend const failable<bool> cleanup(const CURLSession& cs);
+ friend const failable<bool> connect(const string& url, const CURLSession& cs);
+ friend const failable<bool> send(const char* const c, const size_t l, const CURLSession& cs);
+ friend const failable<size_t> recv(char* const c, const size_t l, const CURLSession& cs);
public:
- string ca;
- string cert;
- string key;
- string cookie;
- int timeout;
+ const string ca;
+ const string cert;
+ const string key;
+ const string cookie;
+ const int timeout;
};
/**
* Returns the CURL handle used by a CURL session.
*/
-CURL* handle(const CURLSession& cs) {
- return cs.h;
+CURL* const handle(const CURLSession& cs) {
+ return cs.h.h;
}
/**
* Return an apr_socket_t for the socket used by a CURL session.
*/
-apr_socket_t* sock(const CURLSession& cs) {
- return cs.sock;
+apr_socket_t* const sock(const CURLSession& cs) {
+ return cs.h.sock;
}
/**
* Convert a socket fd to an apr_socket_t.
*/
-apr_socket_t* sock(const int sd, const gc_pool& p) {
+apr_socket_t* const sock(const int sd, const gc_pool& p) {
int fd = sd;
apr_socket_t* s = NULL;
apr_os_sock_put(&s, &fd, pool(p));
@@ -160,14 +165,14 @@ apr_socket_t* sock(const int sd, const gc_pool& p) {
/**
* Convert a CURL return code to an error string.
*/
-const string curlreason(CURLcode rc) {
+const string curlreason(const CURLcode rc) {
return curl_easy_strerror(rc);
}
/**
* Convert an APR status to an error string.
*/
-const string apreason(apr_status_t rc) {
+const string apreason(const apr_status_t rc) {
char buf[256];
return apr_strerror(rc, buf, sizeof(buf));
}
@@ -178,7 +183,7 @@ const string apreason(apr_status_t rc) {
const char escape_c2x[] = "0123456789ABCDEF";
const string escape(const string& unesc, const char* reserv) {
- char* copy = (char*)apr_palloc(gc_current_pool(), 3 * length(unesc) + 3);
+ char* const copy = (char*)apr_palloc(gc_current_pool(), 3 * length(unesc) + 3);
const unsigned char* s = (const unsigned char *)c_str(unesc);
unsigned char* d = (unsigned char*)copy;
unsigned c;
@@ -225,9 +230,9 @@ const string hostName(const string& uri, const gc_pool& p) {
apr_uri_t u;
const apr_status_t rc = apr_uri_parse(pool(p), c_str(uri), &u);
if (rc != APR_SUCCESS)
- return "";
+ return emptyString;
if (u.hostname == NULL)
- return "";
+ return emptyString;
return u.hostname;
}
@@ -238,9 +243,9 @@ const string scheme(const string& uri, const gc_pool& p) {
apr_uri_t u;
const apr_status_t rc = apr_uri_parse(pool(p), c_str(uri), &u);
if (rc != APR_SUCCESS)
- return "";
+ return emptyString;
if (u.scheme == NULL)
- return "";
+ return emptyString;
return u.scheme;
}
@@ -262,13 +267,14 @@ const string topDomain(const string& host) {
/**
* Setup a CURL session
*/
-const failable<CURL*> setup(const string& url, CURLSession& cs) {
+const failable<CURL*> setup(const string& url, const CURLSession& cs) {
// Init CURL session
- if (cs.h != NULL)
+ if (cs.h.h != NULL)
cleanup(cs);
- cs.h = curl_easy_init();
- CURL* ch = cs.h;
+ cs.h.h = curl_easy_init();
+ debug(cs.h.h, "http::setup::init::h");
+ CURL* const ch = cs.h.h;
curl_easy_setopt(ch, CURLOPT_USERAGENT, "libcurl/1.0");
#ifdef WANT_MAINTAINER_CURL_VERBOSE
curl_easy_setopt(ch, CURLOPT_VERBOSE, true);
@@ -279,34 +285,35 @@ const failable<CURL*> setup(const string& url, CURLSession& cs) {
curl_easy_setopt(ch, CURLOPT_FOLLOWLOCATION, true);
curl_easy_setopt(ch, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt(ch, CURLOPT_DNS_USE_GLOBAL_CACHE, 0);
curl_easy_setopt(ch, CURLOPT_TIMEOUT, cs.timeout);
// Setup SSL options
- if (cs.ca != "") {
+ if (cs.ca != emptyString) {
debug(cs.ca, "http::setup::ca");
curl_easy_setopt(ch, CURLOPT_CAINFO, c_str(cs.ca));
curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, true);
curl_easy_setopt(ch, CURLOPT_SSL_VERIFYHOST, 2);
} else
curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, false);
- if (cs.cert != "") {
+ if (cs.cert != emptyString) {
debug(cs.cert, "http::setup::cert");
curl_easy_setopt(ch, CURLOPT_SSLCERT, c_str(cs.cert));
curl_easy_setopt(ch, CURLOPT_SSLCERTTYPE, "PEM");
}
- if (cs.key != "") {
+ if (cs.key != emptyString) {
debug(cs.key, "http::setup::key");
curl_easy_setopt(ch, CURLOPT_SSLKEY, c_str(cs.key));
curl_easy_setopt(ch, CURLOPT_SSLKEYTYPE, "PEM");
}
- if (cs.cookie != "") {
+ if (cs.cookie != emptyString) {
debug(cs.cookie, "http::setup::cookie");
curl_easy_setopt(ch, CURLOPT_COOKIE, c_str(cs.cookie));
}
// Set up HTTP basic auth if requested
apr_uri_t u;
- apr_pool_t* p = gc_current_pool();
+ apr_pool_t* const p = gc_current_pool();
const apr_status_t prc = apr_uri_parse(p, c_str(url), &u);
if (prc == APR_SUCCESS) {
if (u.user != NULL) {
@@ -336,11 +343,12 @@ const failable<CURL*> setup(const string& url, CURLSession& cs) {
/**
* Cleanup a CURL session
*/
-const failable<bool> cleanup(CURLSession& cs) {
- if (cs.h == NULL)
+const failable<bool> cleanup(const CURLSession& cs) {
+ if (cs.h.h == NULL)
return true;
- curl_easy_cleanup(cs.h);
- cs.h = NULL;
+ debug(cs.h.h, "http::cleanup::cleanup::h");
+ curl_easy_cleanup(cs.h.h);
+ cs.h.h = NULL;
return true;
}
@@ -351,15 +359,16 @@ class CURLReadContext {
public:
CURLReadContext(const list<string>& ilist) : ilist(ilist) {
}
- list<string> ilist;
+
+ gc_mutable_ref<list<string> > ilist;
};
/**
* Called by CURL to read data to send.
*/
size_t readCallback(void *ptr, size_t size, size_t nmemb, void *data) {
- CURLReadContext& rcx = *static_cast<CURLReadContext*>(data);
- if (isNil(rcx.ilist))
+ CURLReadContext& rcx = *(CURLReadContext*)data;
+ if (isNil((const list<string>)rcx.ilist))
return 0;
const list<string> f(fragment(rcx.ilist, size * nmemb));
const string s = car(f);
@@ -373,17 +382,18 @@ size_t readCallback(void *ptr, size_t size, size_t nmemb, void *data) {
*/
template<typename R> class CURLWriteContext {
public:
- CURLWriteContext(const lambda<R(const string&, const R)>& reduce, const R& accum) : reduce(reduce), accum(accum) {
+ CURLWriteContext(const lambda<const R(const string&, const R)>& reduce, const R& accum) : reduce(reduce), accum(accum) {
}
- const lambda<R(const string&, const R)> reduce;
- R accum;
+
+ const lambda<const R(const string&, const R)> reduce;
+ gc_mutable_ref<R> accum;
};
/**
* Called by CURL to write received data.
*/
template<typename R> size_t writeCallback(void *ptr, size_t size, size_t nmemb, void *data) {
- CURLWriteContext<R>& wcx = *(static_cast<CURLWriteContext<R>*> (data));
+ CURLWriteContext<R>& wcx = *(CURLWriteContext<R>*)data;
const size_t realsize = size * nmemb;
wcx.accum = wcx.reduce(string((const char*)ptr, realsize), wcx.accum);
return realsize;
@@ -393,13 +403,13 @@ template<typename R> size_t writeCallback(void *ptr, size_t size, size_t nmemb,
* Apply an HTTP verb to a list containing a list of headers and a list of content, and
* a reduce function used to process the response.
*/
-curl_slist* headers(curl_slist* cl, const list<string>& h) {
+curl_slist* headers(curl_slist* const cl, const list<string>& h) {
if (isNil(h))
return cl;
return headers(curl_slist_append(cl, c_str(string(car(h)))), cdr(h));
}
-template<typename R> const failable<list<R> > apply(const list<list<string> >& hdr, const lambda<R(const string&, const R)>& reduce, const R& initial, const string& url, const string& verb, CURLSession& cs) {
+template<typename R> const failable<list<R> > apply(const list<list<string> >& hdr, const lambda<const R(const string&, const R)>& reduce, const R& initial, const string& url, const string& verb, const CURLSession& cs) {
debug(url, "http::apply::url");
debug(verb, "http::apply::verb");
@@ -409,12 +419,12 @@ template<typename R> const failable<list<R> > apply(const list<list<string> >& h
cleanup(cs);
return mkfailure<list<R>>(fch);
}
- CURL* ch = content(fch);
+ CURL* const ch = content(fch);
// Set the request headers
curl_slist* hl = headers(NULL, car(hdr));
- if (hl != NULL)
- curl_easy_setopt(ch, CURLOPT_HTTPHEADER, hl);
+ hl = curl_slist_append(hl, "X-Accept: text/x-scheme; charset=utf-8");
+ curl_easy_setopt(ch, CURLOPT_HTTPHEADER, hl);
// Convert request body to a string
// TODO use HTTP chunking instead
@@ -462,9 +472,7 @@ template<typename R> const failable<list<R> > apply(const list<list<string> >& h
curl_easy_getinfo (ch, CURLINFO_RESPONSE_CODE, &httprc);
if (httprc != 200 && httprc != 201) {
cleanup(cs);
- ostringstream es;
- es << "HTTP code " << httprc;
- return mkfailure<list<R> >(str(es));
+ return mkfailure<list<R> >(string("HTTP code not 200"), (int)httprc, (httprc != 301 && httprc != 302 && httprc != 404));
}
cleanup(cs);
@@ -474,13 +482,12 @@ template<typename R> const failable<list<R> > apply(const list<list<string> >& h
/**
* Evaluate an expression remotely, at the given URL.
*/
-const failable<value> evalExpr(const value& expr, const string& url, CURLSession& cs) {
+const failable<value> evalExpr(const value& expr, const string& url, const CURLSession& cs) {
debug(url, "http::evalExpr::url");
debug(expr, "http::evalExpr::input");
// Convert expression to a JSON-RPC request
- js::JSContext cx;
- const failable<list<string> > jsreq = json::jsonRequest(1, car<value>(expr), cdr<value>(expr), cx);
+ const failable<list<string> > jsreq = json::jsonRequest(1, car<value>(expr), cdr<value>(expr));
if (!hasContent(jsreq))
return mkfailure<value>(jsreq);
@@ -491,7 +498,7 @@ const failable<value> evalExpr(const value& expr, const string& url, CURLSession
return mkfailure<value>(res);
// Parse and return JSON-RPC result
- const failable<value> rval = json::jsonResultValue(cadr<list<string> >(content(res)), cx);
+ const failable<value> rval = json::jsonResultValue(cadr<list<string> >(content(res)));
debug(rval, "http::evalExpr::result");
if (!hasContent(rval))
return mkfailure<value>(rval);
@@ -501,7 +508,7 @@ const failable<value> evalExpr(const value& expr, const string& url, CURLSession
/**
* Find and return a header.
*/
-const maybe<string> header(const char* prefix, const list<string>& h) {
+const maybe<string> header(const char* const prefix, const list<string>& h) {
if (isNil(h))
return maybe<string>();
const string s = car(h);
@@ -516,7 +523,7 @@ const maybe<string> header(const char* prefix, const list<string>& h) {
*/
const string location(const list<string>& h) {
const maybe<string> l = header("Location: ", h);
- return hasContent(l)? content(l) : "";
+ return hasContent(l)? content(l) : emptyString;
}
/**
@@ -524,7 +531,7 @@ const string location(const list<string>& h) {
*/
const value entryId(const failable<string> l) {
if (!hasContent(l))
- return list<value>();
+ return nilListValue;
const string ls(content(l));
return value(mklist<value>(string(substr(ls, find_last(ls, '/') + 1))));
}
@@ -534,13 +541,13 @@ const value entryId(const failable<string> l) {
*/
const string contentType(const list<string>& h) {
const maybe<string> ct = header("Content-Type: ", h);
- return hasContent(ct)? content(ct) : "";
+ return hasContent(ct)? content(ct) : emptyString;
}
/**
* HTTP GET, return the resource at the given URL.
*/
-template<typename R> const failable<list<R> > get(const lambda<R(const string&, const R)>& reduce, const R& initial, const string& url, CURLSession& cs) {
+template<typename R> const failable<list<R> > get(const lambda<const R(const string&, const R)>& reduce, const R& initial, const string& url, const CURLSession& cs) {
debug(url, "http::get::url");
const list<list<string> > req = mklist(list<string>(), list<string>());
return apply(req, reduce, initial, url, "GET", cs);
@@ -549,7 +556,7 @@ template<typename R> const failable<list<R> > get(const lambda<R(const string&,
/**
* HTTP GET, return a list of values representing the resource at the given URL.
*/
-const failable<value> getcontent(const string& url, CURLSession& cs) {
+const failable<value> getcontent(const string& url, const CURLSession& cs) {
debug(url, "http::get::url");
// Get the contents of the resource at the given URL
@@ -576,6 +583,15 @@ const failable<value> responseValue(const list<list<string> > res) {
const list<string> ls(reverse(cadr(res)));
debug(ls, "http::responseValue::content");
+ if (contains(ct, "text/x-scheme")) {
+ // Read a Scheme value
+ ostringstream os;
+ write(ls, os);
+ istringstream is(str(os));
+ const value val(content(scheme::readValue(is)));
+ debug(val, "http::responseValue::result");
+ return val;
+ }
if (atom::isATOMEntry(ls)) {
// Read an ATOM entry
const value val(elementsToValues(content(atom::readATOMEntry(ls))));
@@ -596,8 +612,7 @@ const failable<value> responseValue(const list<list<string> > res) {
}
if (contains(ct, "text/javascript") || contains(ct, "application/json") || json::isJSON(ls)) {
// Read a JSON document
- js::JSContext cx;
- const value val(json::jsonValues(content(json::readJSON(ls, cx))));
+ const value val(content(json::readValue(ls)));
debug(val, "http::responseValue::result");
return val;
}
@@ -612,14 +627,13 @@ const failable<value> responseValue(const list<list<string> > res) {
const list<string> jls = mklist<string>(substr(s, fp + 1, lp - (fp + 1)));
debug(jls, "http::responseValue::javascript::content");
- js::JSContext cx;
- const value val(json::jsonValues(content(json::readJSON(jls, cx))));
+ const value val(content(json::readValue(jls)));
debug(val, "http::responseValue::result");
return val;
}
- if (contains(ct, "text/xml") || contains(ct, "application/xml") || isXML(ls)) {
+ if (contains(ct, "text/xml") || contains(ct, "application/xml") || xml::isXML(ls)) {
// Read an XML document
- const value val(elementsToValues(readXML(ls)));
+ const value val(elementsToValues(content(xml::readElements(ls))));
debug(val, "http::responseValue::result");
return val;
}
@@ -633,7 +647,7 @@ const failable<value> responseValue(const list<list<string> > res) {
/**
* HTTP GET, return a list of values representing the resource at the given URL.
*/
-const failable<value> get(const string& url, CURLSession& cs) {
+const failable<value> get(const string& url, const CURLSession& cs) {
debug(url, "http::get::url");
// Get the contents of the resource at the given URL
@@ -661,58 +675,41 @@ const failable<list<list<string> > > writeRequest(const failable<list<string> >&
*/
const failable<list<list<string> > > contentRequest(const value& c, unused const string& url) {
- // Check if the client requested a specific format
- //TODO derive that from given URL
- const list<value> fmt = assoc<value>("format", list<value>());
-
- // Write as a scheme value if requested by the client
- if (!isNil(fmt) && cadr(fmt) == "scheme")
- return writeRequest(mklist<string>(scheme::writeValue(c)), "text/plain; charset=utf-8");
+ // Write in the format requested by the client, if any
+ const list<value> fmt = assoc<value>("format", nilListValue);
+ if (!isNil(fmt)) {
+ if (cadr(fmt) == "scheme")
+ return writeRequest(scheme::writeValue(c), "text/x-scheme; charset=utf-8");
+ if (cadr(fmt) == "json")
+ return writeRequest(json::writeValue(c), "application/json; charset=utf-8");
+ if (cadr(fmt) == "xml")
+ return writeRequest(xml::writeElements(valuesToElements(c)), "text/xml; charset=utf-8");
+ }
// Write a simple value as a JSON value
if (!isList(c)) {
- js::JSContext cx;
- if (isSymbol(c)) {
- const list<value> lc = mklist<value>(mklist<value>("name", value(string(c))));
- debug(lc, "http::contentRequest::symbol");
- return writeRequest(json::writeJSON(valuesToElements(lc), cx), "application/json; charset=utf-8");
- }
- const list<value> lc = mklist<value>(mklist<value>("value", c));
- debug(lc, "http::contentRequest::value");
- return writeRequest(json::writeJSON(valuesToElements(lc), cx), "application/json; charset=utf-8");
+ debug(c, "http::contentRequest::value");
+ return writeRequest(json::writeValue(c), "application/json; charset=utf-8");
}
- // Write an empty list as a JSON empty value
+ // Write an empty list as a JSON value
if (isNil((list<value>)c)) {
- js::JSContext cx;
- debug(list<value>(), "http::contentRequest::empty");
- return writeRequest(json::writeJSON(list<value>(), cx), "application/json; charset=utf-8");
+ debug(nilListValue, "http::contentRequest::empty");
+ return writeRequest(json::writeValue(c), "application/json; charset=utf-8");
}
// Write content-type / content-list pair
if (isString(car<value>(c)) && !isNil(cdr<value>(c)) && isList(cadr<value>(c)))
return writeRequest(convertValues<string>(cadr<value>(c)), car<value>(c));
- // Write an assoc value as JSON
+ // Write an assoc value as a JSON value
if (isSymbol(car<value>(c)) && !isNil(cdr<value>(c))) {
- js::JSContext cx;
- const list<value> lc = mklist<value>(c);
- debug(lc, "http::contentRequest::assoc");
- debug(valuesToElements(lc), "http::contentRequest::assoc::element");
- return writeRequest(json::writeJSON(valuesToElements(lc), cx), "application/json; charset=utf-8");
- }
-
- // Write value as JSON if requested by the client
- if (!isNil(fmt) && cadr(fmt) == "json") {
- js::JSContext cx;
- return writeRequest(json::writeJSON(valuesToElements(c), cx), "application/json; charset=utf-8");
+ debug(c, "http::contentRequest::assoc");
+ return writeRequest(json::writeValue(c), "application/json; charset=utf-8");
}
- // Convert list of values to element values
- const list<value> e = valuesToElements(c);
- debug(e, "http::contentRequest::elements");
-
// Write an ATOM feed or entry
+ const list<value> e = valuesToElements(c);
if (isList(car<value>(e)) && !isNil(car<value>(e))) {
const list<value> el = car<value>(e);
if (isSymbol(car<value>(el)) && car<value>(el) == element && !isNil(cdr<value>(el)) && isSymbol(cadr<value>(el)) && elementHasChildren(el) && !elementHasValue(el)) {
@@ -724,14 +721,13 @@ const failable<list<list<string> > > contentRequest(const value& c, unused const
}
// Write any other compound value as a JSON value
- js::JSContext cx;
- return writeRequest(json::writeJSON(e, cx), "application/json; charset=utf-8");
+ return writeRequest(json::writeValue(c), "application/json; charset=utf-8");
}
/**
* HTTP POST.
*/
-const failable<value> post(const value& val, const string& url, CURLSession& cs) {
+const failable<value> post(const value& val, const string& url, const CURLSession& cs) {
debug(url, "http::post::url");
// Convert value to a content request
@@ -760,7 +756,7 @@ const failable<value> post(const value& val, const string& url, CURLSession& cs)
/**
* HTTP PUT.
*/
-const failable<value> put(const value& val, const string& url, CURLSession& cs) {
+const failable<value> put(const value& val, const string& url, const CURLSession& cs) {
debug(url, "http::put::url");
// Convert value to a content request
@@ -775,13 +771,13 @@ const failable<value> put(const value& val, const string& url, CURLSession& cs)
return mkfailure<value>(res);
debug(true, "http::put::result");
- return value(true);
+ return trueValue;
}
/**
* HTTP PATCH.
*/
-const failable<value> patch(const value& val, const string& url, CURLSession& cs) {
+const failable<value> patch(const value& val, const string& url, const CURLSession& cs) {
debug(url, "http::put::patch");
// Convert value to a content request
@@ -796,13 +792,13 @@ const failable<value> patch(const value& val, const string& url, CURLSession& cs
return mkfailure<value>(res);
debug(true, "http::patch::result");
- return value(true);
+ return trueValue;
}
/**
* HTTP DELETE.
*/
-const failable<value, string> del(const string& url, CURLSession& cs) {
+const failable<value, string> del(const string& url, const CURLSession& cs) {
debug(url, "http::delete::url");
const list<list<string> > req = mklist(list<string>(), list<string>());
@@ -811,7 +807,7 @@ const failable<value, string> del(const string& url, CURLSession& cs) {
return mkfailure<value>(res);
debug(true, "http::delete::result");
- return value(true);
+ return trueValue;
}
/**
@@ -827,7 +823,7 @@ const string hostName() {
/**
* Create an APR pollfd for a socket.
*/
-apr_pollfd_t* pollfd(apr_socket_t* s, const int e, const gc_pool& p) {
+apr_pollfd_t* const pollfd(apr_socket_t* const s, const int e, const gc_pool& p) {
apr_pollfd_t* pfd = gc_new<apr_pollfd_t>(p);
pfd->p = pool(p);
pfd->desc_type = APR_POLL_SOCKET;
@@ -841,7 +837,7 @@ apr_pollfd_t* pollfd(apr_socket_t* s, const int e, const gc_pool& p) {
/**
* Connect to a URL.
*/
-const failable<bool> connect(const string& url, CURLSession& cs) {
+const failable<bool> connect(const string& url, const CURLSession& cs) {
debug(url, "http::connect::url");
// Setup the CURL session
@@ -850,7 +846,7 @@ const failable<bool> connect(const string& url, CURLSession& cs) {
cleanup(cs);
return mkfailure<bool>(fch);
}
- CURL* ch = content(fch);
+ CURL* const ch = content(fch);
// Connect
curl_easy_setopt(ch, CURLOPT_CONNECT_ONLY, true);
@@ -867,23 +863,23 @@ const failable<bool> connect(const string& url, CURLSession& cs) {
cleanup(cs);
return mkfailure<bool>(string(curl_easy_strerror(grc)));
}
- cs.sock = sock(sd, cs.p);
+ cs.h.sock = sock(sd, cs.p);
// Create pollsets and pollfds which can be used to poll the socket
- apr_status_t rpcrc = apr_pollset_create(&cs.rpollset, 1, pool(cs.p), 0);
+ const apr_status_t rpcrc = apr_pollset_create(&cs.h.rpollset, 1, pool(cs.p), 0);
if (rpcrc != APR_SUCCESS) {
cleanup(cs);
return mkfailure<bool>(apreason(rpcrc));
}
- cs.rpollfd = pollfd(cs.sock, APR_POLLIN, cs.p);
- apr_pollset_add(cs.rpollset, cs.rpollfd);
- apr_status_t wpcrc = apr_pollset_create(&cs.wpollset, 1, pool(cs.p), 0);
+ cs.h.rpollfd = pollfd(cs.h.sock, APR_POLLIN, cs.p);
+ apr_pollset_add(cs.h.rpollset, cs.h.rpollfd);
+ const apr_status_t wpcrc = apr_pollset_create(&cs.h.wpollset, 1, pool(cs.p), 0);
if (wpcrc != APR_SUCCESS) {
cleanup(cs);
return mkfailure<bool>(apreason(wpcrc));
}
- cs.wpollfd = pollfd(cs.sock, APR_POLLOUT, cs.p);
- apr_pollset_add(cs.wpollset, cs.wpollfd);
+ cs.h.wpollfd = pollfd(cs.h.sock, APR_POLLOUT, cs.p);
+ apr_pollset_add(cs.h.wpollset, cs.h.wpollfd);
return true;
}
@@ -891,11 +887,11 @@ const failable<bool> connect(const string& url, CURLSession& cs) {
/**
* Send an array of chars.
*/
-const failable<bool> send(const char* c, const size_t l, CURLSession& cs) {
+const failable<bool> send(const char* const c, const size_t l, const CURLSession& cs) {
// Send the data
size_t wl = 0;
- const CURLcode rc = curl_easy_send(cs.h, c, (size_t)l, &wl);
+ const CURLcode rc = curl_easy_send(cs.h.h, c, (size_t)l, &wl);
if (rc == CURLE_OK && wl == (size_t)l)
return true;
if (rc != CURLE_AGAIN) {
@@ -906,7 +902,7 @@ const failable<bool> send(const char* c, const size_t l, CURLSession& cs) {
// If the socket was not ready, wait for it to become ready
const apr_pollfd_t* pollfds;
apr_int32_t pollcount;
- apr_status_t pollrc = apr_pollset_poll(cs.wpollset, -1, &pollcount, &pollfds);
+ const apr_status_t pollrc = apr_pollset_poll(cs.h.wpollset, -1, &pollcount, &pollfds);
if (pollrc != APR_SUCCESS)
return mkfailure<bool>(apreason(pollrc));
@@ -917,11 +913,11 @@ const failable<bool> send(const char* c, const size_t l, CURLSession& cs) {
/**
* Receive an array of chars.
*/
-const failable<size_t> recv(char* c, const size_t l, CURLSession& cs) {
+const failable<size_t> recv(char* const c, const size_t l, const CURLSession& cs) {
// Receive data
size_t rl;
- const CURLcode rc = curl_easy_recv(cs.h, c, (size_t)l, &rl);
+ const CURLcode rc = curl_easy_recv(cs.h.h, c, (size_t)l, &rl);
if (rc == CURLE_OK)
return (size_t)rl;
if (rc == 1)
@@ -934,7 +930,7 @@ const failable<size_t> recv(char* c, const size_t l, CURLSession& cs) {
// If the socket was not ready, wait for it to become ready
const apr_pollfd_t* pollfds;
apr_int32_t pollcount;
- apr_status_t pollrc = apr_pollset_poll(cs.rpollset, -1, &pollcount, &pollfds);
+ const apr_status_t pollrc = apr_pollset_poll(cs.h.rpollset, -1, &pollcount, &pollfds);
if (pollrc != APR_SUCCESS) {
cleanup(cs);
return mkfailure<size_t>(apreason(pollrc));
@@ -990,8 +986,9 @@ const value escapeQuery(const value& arg) {
/**
* HTTP client proxy function.
*/
-struct proxy {
- proxy(const string& uri, const string& ca, const string& cert, const string& key, const string& cookie, const int timeout, const gc_pool& p) : p(p), uri(uri), ca(ca), cert(cert), key(key), cookie(cookie), cs(*(new (gc_new<CURLSession>(p)) CURLSession(ca, cert, key, cookie, timeout))) {
+class proxy {
+public:
+ proxy(const string& uri, const string& ca, const string& cert, const string& key, const string& cookie, const int timeout) : uri(uri), cs(mksession(ca, cert, key, cookie, timeout)) {
}
const value operator()(const list<value>& args) const {
@@ -1001,39 +998,44 @@ struct proxy {
const list<value> lp = filter<value>(filterPath, cadr(args));
debug(lp, "http::proxy::path");
const list<value> lq = map<value, value>(escapeQuery, filter<value>(filterQuery, cadr(args)));
- debug(lp, "http::proxy::query");
- const value p = path(lp);
+ debug(lq, "http::proxy::query");
const value q = queryString(lq);
- const failable<value> val = get(uri + p + (q != ""? string("?") + q : string("")), cs);
+ const failable<value> val = get(uri + (string)path(lp) + (q != emptyString? string("?") + (string)q : emptyString), *cs);
return content(val);
}
if (fun == "post") {
- const failable<value> val = post(caddr(args), uri + path(cadr(args)), cs);
+ const failable<value> val = post(caddr(args), uri + (string)path(cadr(args)), *cs);
return content(val);
}
if (fun == "put") {
- const failable<value> val = put(caddr(args), uri + path(cadr(args)), cs);
+ const failable<value> val = put(caddr(args), uri + (string)path(cadr(args)), *cs);
return content(val);
}
if (fun == "patch") {
- const failable<value> val = patch(caddr(args), uri + path(cadr(args)), cs);
+ const failable<value> val = patch(caddr(args), uri + (string)path(cadr(args)), *cs);
return content(val);
}
if (fun == "delete") {
- const failable<value> val = del(uri + path(cadr(args)), cs);
+ const failable<value> val = del(uri + (string)path(cadr(args)), *cs);
return content(val);
}
- const failable<value> val = evalExpr(args, uri, cs);
+ const failable<value> val = evalExpr(args, uri, *cs);
return content(val);
}
- const gc_pool p;
+private:
const string uri;
- const string ca;
- const string cert;
- const string key;
- const string cookie;
- CURLSession& cs;
+ const perthread_ptr<http::CURLSession> cs;
+
+
+ const perthread_ptr<http::CURLSession> mksession(const string& ca, const string& cert, const string& key, const string& cookie, const int timeout) {
+ const gc_pool cp = gc_current_pool();
+ const lambda<const gc_ptr<http::CURLSession>()> newsession = [ca, cert, key, cookie, timeout, cp]() -> const gc_ptr<http::CURLSession> {
+ const gc_scoped_pool sp(pool(cp));
+ return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, key, cookie, timeout);
+ };
+ return *(new (gc_new<perthread_ptr<http::CURLSession> >()) perthread_ptr<CURLSession>(newsession));
+ }
};
}
diff --git a/sca-cpp/trunk/modules/http/httpd-callgrind b/sca-cpp/trunk/modules/http/httpd-callgrind
new file mode 100755
index 0000000000..964b046638
--- /dev/null
+++ b/sca-cpp/trunk/modules/http/httpd-callgrind
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Start httpd server
+here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here`
+root=`echo "import os; print os.path.realpath('$1')" | python`
+
+httpd=`cat $here/httpd.prefix`
+$here/../../etc/callgrind $httpd/bin/httpd -X -E $root/logs/error_log -d $root -f $root/conf/httpd.conf
diff --git a/sca-cpp/trunk/modules/http/httpd.hpp b/sca-cpp/trunk/modules/http/httpd.hpp
index 6470d6c587..e090c2fc35 100644
--- a/sca-cpp/trunk/modules/http/httpd.hpp
+++ b/sca-cpp/trunk/modules/http/httpd.hpp
@@ -46,14 +46,14 @@ extern "C" {
#include <http_request.h>
// Ignore conversion warnings in HTTPD 2.3.15 header
#ifdef WANT_MAINTAINER_WARNINGS
-#ifndef IS_DARWIN
+#ifndef __clang__
#pragma GCC diagnostic ignored "-Wconversion"
#endif
#endif
#include <http_protocol.h>
// Re-enable conversion warnings
#ifdef WANT_MAINTAINER_WARNINGS
-#ifndef IS_DARWIN
+#ifndef __clang__
#pragma GCC diagnostic warning "-Wconversion"
#endif
#endif
@@ -94,15 +94,15 @@ template<typename C> void* makeServerConf(apr_pool_t* p, server_rec* s) {
return new (gc_new<C>(p)) C(p, s);
}
-template<typename C> const C& serverConf(const request_rec* r, const module* mod) {
+template<typename C> const C& serverConf(const request_rec* const r, const module* const mod) {
return *(C*)ap_get_module_config(r->server->module_config, mod);
}
-template<typename C> C& serverConf(const server_rec* s, const module* mod) {
+template<typename C> C& serverConf(const server_rec* const s, const module* const mod) {
return *(C*)ap_get_module_config(s->module_config, mod);
}
-template<typename C> C& serverConf(const cmd_parms* cmd, const module* mod) {
+template<typename C> C& serverConf(const cmd_parms* const cmd, const module* const mod) {
return *(C*)ap_get_module_config(cmd->server->module_config, mod);
}
@@ -113,25 +113,25 @@ template<typename C> void* makeDirConf(apr_pool_t *p, char* d) {
return new (gc_new<C>(p)) C(p, d);
}
-template<typename C> const C& dirConf(const request_rec* r, const module* mod) {
+template<typename C> const C& dirConf(const request_rec* const r, const module* const mod) {
return *(C*)ap_get_module_config(r->per_dir_config, mod);
}
-template<typename C> C& dirConf(const void* c) {
+template<typename C> C& dirConf(const void* const c) {
return *(C*)c;
}
/**
* Returns a request-scoped module configuration.
*/
-template<typename C> C& makeRequestConf(const request_rec* r, const module* mod) {
- C* c = new (gc_new<C>(r->pool)) C(r->pool, r);
+template<typename C> C& makeRequestConf(const request_rec* const r, const module* const mod) {
+ C* const c = new (gc_new<C>(r->pool)) C(r->pool, r);
ap_set_module_config(r->request_config, mod, c);
return *c;
}
-template<typename C> C& requestConf(const request_rec* r, const module* mod) {
- C* c = (C*)ap_get_module_config(r->request_config, mod);
+template<typename C> C& requestConf(const request_rec* const r, const module* const mod) {
+ C* const c = (C*)ap_get_module_config(r->request_config, mod);
if (c == NULL)
return makeRequestConf<C>(r, mod);
return *c;
@@ -140,18 +140,18 @@ template<typename C> C& requestConf(const request_rec* r, const module* mod) {
/**
* Return the host name for a server.
*/
-const string hostName(const server_rec* s, const string& def = "localhost") {
+const string hostName(const server_rec* const s, const string& def = "localhost") {
return s->server_hostname != NULL? s->server_hostname : def;
}
/**
* Return the host name from an HTTP request.
*/
-const string hostName(request_rec* r, const string& def = "localhost") {
- const char* fh = apr_table_get(r->headers_in, "X-Forwarded-Server");
+const string hostName(request_rec* const r, const string& def = "localhost") {
+ const char* const fh = apr_table_get(r->headers_in, "X-Forwarded-Server");
if (fh != NULL)
return fh;
- const char* h = ap_get_server_name(r);
+ const char* const h = ap_get_server_name(r);
return h != NULL? h : (r->server->server_hostname != NULL? r->server->server_hostname : def);
}
@@ -166,15 +166,15 @@ const string realm(const string& host) {
/**
* Return the protocol scheme for a server.
*/
-const string scheme(const server_rec* s, const string& def = "http") {
+const string scheme(const server_rec* const s, const string& def = "http") {
return s->server_scheme != NULL? s->server_scheme : def;
}
/**
* Return the protocol scheme from an HTTP request.
*/
-const string scheme(request_rec* r, const string& def = "http") {
- const char* fs = apr_table_get(r->headers_in, "X-Forwarded-HTTPS");
+const string scheme(const request_rec* const r, const string& def = "http") {
+ const char* const fs = apr_table_get(r->headers_in, "X-Forwarded-HTTPS");
if (fs != NULL)
return !strcmp(fs, "on")? "https" : "http";
return r->server->server_scheme != NULL? r->server->server_scheme : def;
@@ -183,15 +183,15 @@ const string scheme(request_rec* r, const string& def = "http") {
/**
* Return the port number for a server.
*/
-const int port(const server_rec* s, const int def = 80) {
+const int port(const server_rec* const s, const int def = 80) {
return s->port != 0? s->port : def;
}
/**
* Return the port number from an HTTP request.
*/
-const int port(request_rec* r, const int def = 80) {
- const char* fp = apr_table_get(r->headers_in, "X-Forwarded-Port");
+const int port(const request_rec* const r, const int def = 80) {
+ const char* const fp = apr_table_get(r->headers_in, "X-Forwarded-Port");
if (fp != NULL)
return atoi(fp);
const int p = ap_get_server_port(r);
@@ -201,7 +201,7 @@ const int port(request_rec* r, const int def = 80) {
/**
* Return the name of a server.
*/
-const string serverName(const server_rec* s, const string& def = "localhost") {
+const string serverName(server_rec* const s, const string& def = "localhost") {
ostringstream n;
const string sc = scheme(s);
const string h = hostName(s, def);
@@ -209,14 +209,14 @@ const string serverName(const server_rec* s, const string& def = "localhost") {
n << sc << "://" << h;
if (!((sc == "http" && p == 80) || (sc == "https" && p == 443)))
n << ":" << p;
- n << (s->path != NULL? string(s->path, s->pathlen) : "");
+ n << (s->path != NULL? string(s->path, s->pathlen) : emptyString);
return str(n);
}
/**
* Determine the name of a server from an HTTP request.
*/
-const string serverName(request_rec* r, const string& def = "localhost") {
+const string serverName(request_rec* const r, const string& def = "localhost") {
ostringstream n;
const string s = scheme(r);
const string h = hostName(r, def);
@@ -224,14 +224,14 @@ const string serverName(request_rec* r, const string& def = "localhost") {
n << s << "://" << h;
if (!((s == "http" && p == 80) || (s == "https" && p == 443)))
n << ":" << p;
- n << (r->server->path != NULL? string(r->server->path, r->server->pathlen) : "");
+ n << (r->server->path != NULL? string(r->server->path, r->server->pathlen) : emptyString);
return str(n);
}
/**
* Return true if a request is targeting a virtual host.
*/
-const bool isVhostRequest(const server_rec* s, const string& d, request_rec* r) {
+const bool isVhostRequest(const server_rec* const s, const string& d, request_rec* const r) {
const string rh = hostName(r);
return rh != hostName(s) && http::topDomain(rh) == d;
}
@@ -239,20 +239,20 @@ const bool isVhostRequest(const server_rec* s, const string& d, request_rec* r)
/**
* Return the content type of a request.
*/
-const string contentType(const request_rec* r) {
+const string contentType(const request_rec* const r) {
const char* ct = apr_table_get(r->headers_in, "Content-Type");
if (ct == NULL)
- return "";
+ return emptyString;
return ct;
}
/**
* Return the cookie header of a request.
*/
-const string cookie(const request_rec* r) {
+const string cookie(const request_rec* const r) {
const char* c = apr_table_get(r->headers_in, "Cookie");
if (c == NULL)
- return "";
+ return emptyString;
return c;
}
@@ -268,7 +268,7 @@ const list<value> pathInfo(const list<value>& uri, const list<value>& path) {
/**
* Convert a URI to an absolute URL.
*/
-const string url(const string& uri, request_rec* r) {
+const string url(const string& uri, request_rec* const r) {
if (contains(uri, "://"))
return uri;
ostringstream n;
@@ -285,8 +285,8 @@ const string url(const string& uri, request_rec* r) {
/**
* Convert a URI and a path to an absolute URL.
*/
-const string url(const string& uri, const list<value>& p, request_rec* r) {
- return url(uri + path(p), r);
+const string url(const string& uri, const list<value>& p, request_rec* const r) {
+ return url(uri + (string)path(p), r);
}
/**
@@ -295,7 +295,7 @@ const string url(const string& uri, const list<value>& p, request_rec* r) {
const char escape_c2x[] = "0123456789ABCDEF";
const string escape(const string& uri) {
debug(uri, "httpd::escape::uri");
- char* copy = (char*)apr_palloc(gc_current_pool(), 3 * length(uri) + 3);
+ char* const copy = (char*)apr_palloc(gc_current_pool(), 3 * length(uri) + 3);
const unsigned char* s = (const unsigned char *)c_str(uri);
unsigned char* d = (unsigned char*)copy;
unsigned c;
@@ -321,7 +321,7 @@ const string escape(const string& uri) {
*/
const string unescape(const string& uri) {
debug(uri, "httpd::unescape::uri");
- char* b = const_cast<char*>(c_str(string(c_str(uri))));
+ char* const b = const_cast<char*>(c_str(string(c_str(uri))));
ap_unescape_url(b);
debug(b, "httpd::unescape::result");
return b;
@@ -348,7 +348,7 @@ const list<value> queryArg(const string& s) {
debug(s, "httpd::queryArg::string");
const list<string> t = tokenize("=", s);
if (isNil(cdr(t)))
- return mklist<value>(c_str(car(t)), "");
+ return mklist<value>(c_str(car(t)), emptyString);
return mklist<value>(c_str(car(t)), cadr(t));
}
@@ -366,7 +366,7 @@ const list<list<value> > queryArgs(const string& a) {
/**
* Returns a list of key value pairs from the args in an HTTP request.
*/
-const list<list<value> > queryArgs(const request_rec* r) {
+const list<list<value> > queryArgs(const request_rec* const r) {
if (r->args == NULL)
return list<list<value> >();
return queryArgs(r->args);
@@ -385,7 +385,7 @@ const list<list<value> > postArgs(const list<value>& a) {
/**
* Setup the HTTP read policy.
*/
-const int setupReadPolicy(request_rec* r) {
+const int setupReadPolicy(request_rec* const r) {
const int rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK);
if(rc != OK)
return rc;
@@ -399,7 +399,7 @@ const int setupReadPolicy(request_rec* r) {
/**
* Read the content of a POST or PUT.
*/
-const list<string> read(request_rec* r) {
+const list<string> read(request_rec* const r) {
char b[1024];
const size_t n = ap_get_client_block(r, b, sizeof(b));
if (n <= 0)
@@ -410,7 +410,7 @@ const list<string> read(request_rec* r) {
/**
* Write an HTTP result.
*/
-const failable<int> writeResult(const failable<list<string> >& ls, const string& ct, request_rec* r) {
+const failable<int> writeResult(const failable<list<string> >& ls, const string& ct, request_rec* const r) {
if (!hasContent(ls))
return mkfailure<int>(ls);
ostringstream os;
@@ -456,16 +456,16 @@ const int reportStatus(const failable<int>& rc) {
}
/**
- * Convert a value to an HTTPD request struc
+ * Convert a value to an HTTPD request struct.
*/
request_rec* request(const value& v) {
return (request_rec*)(long)(double)v;
}
/**
- * Convert an HTTPD request struct to a value
+ * Convert an HTTPD request struct to a value.
*/
-const value requestValue(request_rec* r) {
+const value requestValue(const request_rec* const r) {
return value((double)(long)r);
}
@@ -473,19 +473,37 @@ const value requestValue(request_rec* r) {
* Update request filters in an HTTPD redirect request.
* Similar to httpd/modules/http/http_request.c::update_r_in_filters.
*/
-const bool redirectFilters(ap_filter_t* f, request_rec* from, request_rec* to) {
- if (f == NULL)
- return true;
- if (f->r == from)
- f->r = to;
- return redirectFilters(f->next, from, to);
+const bool internalUpdateFilters(ap_filter_t *f, const request_rec* const from, request_rec* const to) {
+ while(f) {
+ if(f->r == from)
+ f->r = to;
+ f = f->next;
+ }
+ return true;
+}
+
+/**
+ * Rename original env in an HTTPD redirect request.
+ * Similar to httpd/modules/http/http_request.c::rename_original_env.
+ */
+apr_table_t* const internalRenameOriginalEnv(apr_pool_t* const p, apr_table_t* const t) {
+ const apr_array_header_t *env_arr = apr_table_elts(t);
+ const apr_table_entry_t *elts = (const apr_table_entry_t *) (void*)env_arr->elts;
+ apr_table_t *nt = apr_table_make(p, env_arr->nalloc);
+ int i;
+ for(i = 0; i < env_arr->nelts; ++i) {
+ if (!elts[i].key)
+ continue;
+ apr_table_setn(nt, apr_pstrcat(p, "REDIRECT_", elts[i].key, NULL), elts[i].val);
+ }
+ return nt;
}
/**
* Create an HTTPD internal redirect request.
* Similar to httpd/modules/http/http_request.c::internal_internal_redirect.
*/
-const failable<request_rec*> internalRedirectRequest(const string& nr_uri, request_rec* r) {
+const failable<request_rec*> internalRedirectRequest(const string& nr_uri, request_rec* const r) {
if (ap_is_recursion_limit_exceeded(r))
return mkfailure<request_rec*>("Redirect recursion limit exceeded", HTTP_INTERNAL_SERVER_ERROR);
@@ -498,11 +516,15 @@ const failable<request_rec*> internalRedirectRequest(const string& nr_uri, reque
nr->method_number = r->method_number;
nr->allowed_methods = ap_make_method_list(nr->pool, 2);
ap_parse_uri(nr, apr_pstrdup(nr->pool, c_str(nr_uri)));
+ nr->parsed_uri.port_str = r->parsed_uri.port_str;
+ nr->parsed_uri.port = r->parsed_uri.port;
nr->filename = apr_pstrdup(nr->pool, c_str(string("/redirected:") + nr_uri));
nr->request_config = ap_create_request_config(r->pool);
nr->per_dir_config = r->server->lookup_defaults;
nr->prev = r;
r->next = nr;
+ nr->useragent_addr = r->useragent_addr;
+ nr->useragent_ip = r->useragent_ip;
// Run create request hook
ap_run_create_request(nr);
@@ -520,10 +542,15 @@ const failable<request_rec*> internalRedirectRequest(const string& nr_uri, reque
nr->main = r->main;
nr->headers_in = r->headers_in;
nr->headers_out = apr_table_make(r->pool, 12);
+ if (ap_is_HTTP_REDIRECT(nr->status)) {
+ const char *location = apr_table_get(r->headers_out, "Location");
+ if (location)
+ apr_table_setn(nr->headers_out, "Location", location);
+ }
nr->err_headers_out = r->err_headers_out;
nr->subprocess_env = r->subprocess_env;
+ nr->subprocess_env = internalRenameOriginalEnv(r->pool, r->subprocess_env);
nr->notes = apr_table_make(r->pool, 5);
- nr->allowed_methods = ap_make_method_list(nr->pool, 2);
nr->htaccess = r->htaccess;
nr->no_cache = r->no_cache;
nr->expecting_100 = r->expecting_100;
@@ -537,10 +564,28 @@ const failable<request_rec*> internalRedirectRequest(const string& nr_uri, reque
nr->proto_input_filters = r->proto_input_filters;
nr->output_filters = nr->proto_output_filters;
nr->input_filters = nr->proto_input_filters;
- if (nr->main)
- ap_add_output_filter_handle(ap_subreq_core_filter_handle, NULL, nr, nr->connection);
- redirectFilters(nr->input_filters, r, nr);
- redirectFilters(nr->output_filters, r, nr);
+ if (nr->main) {
+ ap_filter_t *f, *nextf;
+ nr->output_filters = r->output_filters;
+ f = nr->output_filters;
+ do {
+ nextf = f->next;
+ if (f->r == r && f->frec != ap_subreq_core_filter_handle) {
+ f->r = nr;
+ ap_remove_output_filter(f);
+ }
+ f = nextf;
+ } while(f && f != nr->proto_output_filters);
+ }
+ else {
+ nr->output_filters = nr->proto_output_filters;
+ }
+ internalUpdateFilters(nr->input_filters, r, nr);
+ internalUpdateFilters(nr->output_filters, r, nr);
+
+ apr_table_setn(nr->subprocess_env, "REDIRECT_STATUS", apr_itoa(r->pool, r->status));
+ nr->used_path_info = AP_REQ_DEFAULT_PATH_INFO;
+
const int rrc = ap_run_post_read_request(nr);
if (rrc != OK && rrc != DECLINED)
return mkfailure<request_rec*>("Error handling internal redirect", rrc);
@@ -552,7 +597,7 @@ const failable<request_rec*> internalRedirectRequest(const string& nr_uri, reque
* Process an HTTPD internal redirect request.
* Similar to httpd/modules/http/http_request.c::ap_internal_redirect.
*/
-const int internalRedirect(request_rec* nr) {
+const int internalRedirect(request_rec* const nr) {
int status = ap_run_quick_handler(nr, 0);
if (status == DECLINED) {
status = ap_process_request_internal(nr);
@@ -570,8 +615,10 @@ const int internalRedirect(request_rec* nr) {
/**
* Create and process an HTTPD internal redirect request.
*/
-const int internalRedirect(const string& uri, request_rec* r) {
+const int internalRedirect(const string& uri, request_rec* const r) {
debug(uri, "httpd::internalRedirect");
+ //ap_internal_redirect(c_str(uri), r);
+ //return OK;
const failable<request_rec*> nr = httpd::internalRedirectRequest(uri, r);
if (!hasContent(nr))
return rcode(nr);
@@ -582,7 +629,7 @@ const int internalRedirect(const string& uri, request_rec* r) {
* Create an HTTPD sub request.
* Similar to httpd/server/request.c::make_sub_request
*/
-const failable<request_rec*> internalSubRequest(const string& nr_uri, request_rec* r) {
+const failable<request_rec*> internalSubRequest(const string& nr_uri, request_rec* const r) {
if (ap_is_recursion_limit_exceeded(r))
return mkfailure<request_rec*>("Redirect recursion limit exceeded", HTTP_INTERNAL_SERVER_ERROR);
@@ -647,7 +694,7 @@ const failable<request_rec*> internalSubRequest(const string& nr_uri, request_re
/**
* Return an HTTP external redirect request.
*/
-const int externalRedirect(const string& uri, request_rec* r) {
+const int externalRedirect(const string& uri, request_rec* const r) {
debug(uri, "httpd::externalRedirect");
r->status = HTTP_MOVED_TEMPORARILY;
apr_table_setn(r->headers_out, "Location", apr_pstrdup(r->pool, c_str(uri)));
@@ -660,7 +707,7 @@ const int externalRedirect(const string& uri, request_rec* r) {
/**
* Put a value in the process user data.
*/
-const bool putUserData(const string& k, const void* v, const server_rec* s) {
+const bool putUserData(const string& k, const void* const v, const server_rec* const s) {
apr_pool_userdata_set((const void *)v, c_str(k), apr_pool_cleanup_null, s->process->pool);
return true;
}
@@ -668,7 +715,7 @@ const bool putUserData(const string& k, const void* v, const server_rec* s) {
/**
* Return a user data value.
*/
-const void* userData(const string& k, const server_rec* s) {
+const void* const userData(const string& k, const server_rec* const s) {
void* v = NULL;
apr_pool_userdata_get(&v, c_str(k), s->process->pool);
return v;
@@ -683,7 +730,7 @@ const void* userData(const string& k, const server_rec* s) {
/**
* Log an optional value.
*/
-const char* debugOptional(const char* s) {
+const char* const debugOptional(const char* const s) {
if (s == NULL)
return "";
return s;
@@ -692,7 +739,7 @@ const char* debugOptional(const char* s) {
/**
* Log a header
*/
-int debugHeader(unused void* r, const char* key, const char* value) {
+int debugHeader(unused void* r, const char* const key, const char* const value) {
cdebug << " header key: " << key << ", value: " << value << endl;
return 1;
}
@@ -700,7 +747,7 @@ int debugHeader(unused void* r, const char* key, const char* value) {
/**
* Log an environment variable
*/
-int debugEnv(unused void* r, const char* key, const char* value) {
+int debugEnv(unused void* r, const char* const key, const char* const value) {
cdebug << " var key: " << key << ", value: " << value << endl;
return 1;
}
@@ -708,7 +755,7 @@ int debugEnv(unused void* r, const char* key, const char* value) {
/**
* Log a note.
*/
-int debugNote(unused void* r, const char* key, const char* value) {
+int debugNote(unused void* r, const char* const key, const char* const value) {
cdebug << " note key: " << key << ", value: " << value << endl;
return 1;
}
@@ -716,8 +763,8 @@ int debugNote(unused void* r, const char* key, const char* value) {
/**
* Log a request.
*/
-const bool debugRequest(request_rec* r, const string& msg) {
- gc_scoped_pool pool;
+const bool debugRequest(request_rec* const r, const string& msg) {
+ const gc_scoped_pool pool;
cdebug << msg << ":" << endl;
cdebug << " unparsed uri: " << debugOptional(r->unparsed_uri) << endl;
cdebug << " uri: " << debugOptional(r->uri) << endl;
diff --git a/sca-cpp/trunk/modules/http/mod-openauth.cpp b/sca-cpp/trunk/modules/http/mod-openauth.cpp
index 2e308ecedb..797e8c10b5 100644
--- a/sca-cpp/trunk/modules/http/mod-openauth.cpp
+++ b/sca-cpp/trunk/modules/http/mod-openauth.cpp
@@ -57,11 +57,11 @@ namespace openauth {
*/
class ServerConf {
public:
- ServerConf(apr_pool_t* p, server_rec* s) : p(p), server(s) {
+ ServerConf(apr_pool_t* const p, server_rec* const s) : p(p), server(s) {
}
const gc_pool p;
- server_rec* server;
+ server_rec* const server;
};
/**
@@ -71,11 +71,11 @@ class AuthnProviderConf {
public:
AuthnProviderConf() : name(), provider(NULL) {
}
- AuthnProviderConf(const string name, const authn_provider* provider) : name(name), provider(provider) {
+ AuthnProviderConf(const string name, const authn_provider* const provider) : name(name), provider(provider) {
}
- string name;
- const authn_provider* provider;
+ const string name;
+ const authn_provider* const provider;
};
/**
@@ -83,14 +83,14 @@ public:
*/
class DirConf {
public:
- DirConf(apr_pool_t* p, char* d) : p(p), dir(d), enabled(false), login("") {
+ DirConf(apr_pool_t* const p, const char* d) : p(p), dir(d), enabled(false), login(emptyString) {
}
const gc_pool p;
- const char* dir;
+ const char* const dir;
bool enabled;
- string login;
- list<AuthnProviderConf> apcs;
+ gc_mutable_ref<string> login;
+ gc_mutable_ref<list<AuthnProviderConf> > apcs;
};
#ifdef WANT_MAINTAINER_LOG
@@ -98,17 +98,17 @@ public:
/**
* Log session entries.
*/
-int debugSessionEntry(unused void* r, const char* key, const char* value) {
+int debugSessionEntry(unused void* r, const char* const key, const char* const value) {
cdebug << " session key: " << key << ", value: " << value << endl;
return 1;
}
-const bool debugSession(request_rec* r, session_rec* z) {
+const bool debugSession(request_rec* const r, const session_rec* const z) {
apr_table_do(debugSessionEntry, r, z->entries, NULL);
return true;
}
-#define debug_authSession(r, z) if (debug_islogging()) openauth::debugSession(r, z)
+#define debug_authSession(r, z) if(debug_islogging()) openauth::debugSession(r, z)
#else
@@ -117,28 +117,35 @@ const bool debugSession(request_rec* r, session_rec* z) {
#endif
/**
+ * Session hook functions.
+ */
+static int (*ap_session_load_fn) (request_rec * r, session_rec ** z) = NULL;
+static apr_status_t (*ap_session_get_fn) (request_rec * r, session_rec * z, const char *key, const char **value) = NULL;
+static apr_status_t (*ap_session_set_fn)(request_rec * r, session_rec * z, const char *key, const char *value) = NULL;
+
+/**
* Run the authnz hooks to authenticate a request.
*/
-const failable<int> checkAuthnzProviders(const string& user, const string& pw, request_rec* r, const list<AuthnProviderConf>& apcs) {
- if (isNil(apcs))
- return mkfailure<int>("Authentication failure for: " + user);
+const failable<int> checkAuthnzProviders(const string& user, const string& pw, request_rec* const r, const list<AuthnProviderConf>& apcs) {
+ if(isNil(apcs))
+ return mkfailure<int>("Authentication failure for: " + user, HTTP_UNAUTHORIZED);
const AuthnProviderConf apc = car<AuthnProviderConf>(apcs);
- if (apc.provider == NULL || !apc.provider->check_password)
+ if(apc.provider == NULL || !apc.provider->check_password)
return checkAuthnzProviders(user, pw, r, cdr(apcs));
apr_table_setn(r->notes, AUTHN_PROVIDER_NAME_NOTE, c_str(apc.name));
const authn_status auth_result = apc.provider->check_password(r, c_str(user), c_str(pw));
apr_table_unset(r->notes, AUTHN_PROVIDER_NAME_NOTE);
- if (auth_result != AUTH_GRANTED)
+ if(auth_result != AUTH_GRANTED)
return checkAuthnzProviders(user, pw, r, cdr(apcs));
return OK;
}
-const failable<int> checkAuthnz(const string& user, const string& pw, request_rec* r, const DirConf& dc) {
- if (substr(user, 0, 1) == "/" && pw == "password")
+const failable<int> checkAuthnz(const string& user, const string& pw, request_rec* const r, const DirConf& dc) {
+ if(substr(user, 0, 1) == "/" && pw == "password")
return mkfailure<int>(string("Encountered FakeBasicAuth spoof: ") + user, HTTP_UNAUTHORIZED);
- if (isNil(dc.apcs)) {
+ if(isNil((const list<AuthnProviderConf>)dc.apcs)) {
const authn_provider* provider = (const authn_provider*)ap_lookup_provider(AUTHN_PROVIDER_GROUP, AUTHN_DEFAULT_PROVIDER, AUTHN_PROVIDER_VERSION);
return checkAuthnzProviders(user, pw, r, mklist<AuthnProviderConf>(AuthnProviderConf(AUTHN_DEFAULT_PROVIDER, provider)));
}
@@ -148,54 +155,47 @@ const failable<int> checkAuthnz(const string& user, const string& pw, request_re
/**
* Return the user info from a form auth encrypted session cookie.
*/
-static int (*ap_session_load_fn) (request_rec * r, session_rec ** z) = NULL;
-static int (*ap_session_get_fn) (request_rec * r, session_rec * z, const char *key, const char **value) = NULL;
-
-const failable<value> userInfoFromSession(const string& realm, request_rec* r) {
+const failable<value> userInfoFromSession(const string& realm, request_rec* const r) {
debug("modopenauth::userInfoFromSession");
- if (ap_session_load_fn == NULL)
- ap_session_load_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_load);
session_rec *z = NULL;
ap_session_load_fn(r, &z);
- if (z == NULL)
- return mkfailure<value>("Couldn't retrieve user session");
+ if(z == NULL)
+ return mkfailure<value>("Couldn't retrieve user session", HTTP_UNAUTHORIZED);
debug_authSession(r, z);
- if (ap_session_get_fn == NULL)
- ap_session_get_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_get);
const char* user = NULL;
ap_session_get_fn(r, z, c_str(realm + "-user"), &user);
- if (user == NULL)
- return mkfailure<value>("Couldn't retrieve user id");
+ if(user == NULL)
+ return mkfailure<value>("Couldn't retrieve user id", HTTP_UNAUTHORIZED);
const char* pw = NULL;
ap_session_get_fn(r, z, c_str(realm + "-pw"), &pw);
- if (pw == NULL)
- return mkfailure<value>("Couldn't retrieve password");
+ if(pw == NULL)
+ return mkfailure<value>("Couldn't retrieve password", HTTP_UNAUTHORIZED);
return value(mklist<value>(mklist<value>("realm", realm), mklist<value>("id", string(user)), mklist<value>("password", string(pw))));
}
/**
* Return the user info from a form auth session cookie.
*/
-const failable<value> userInfoFromCookie(const value& sid, const string& realm, request_rec* r) {
+const failable<value> userInfoFromCookie(const value& sid, const string& realm, request_rec* const r) {
const list<list<value>> info = httpd::queryArgs(sid);
debug(info, "modopenauth::userInfoFromCookie::info");
const list<value> user = assoc<value>(realm + "-user", info);
- if (isNil(user))
+ if(isNil(user))
return userInfoFromSession(realm, r);
const list<value> pw = assoc<value>(realm + "-pw", info);
- if (isNil(pw))
- return mkfailure<value>("Couldn't retrieve password");
+ if(isNil(pw))
+ return mkfailure<value>("Couldn't retrieve password", HTTP_UNAUTHORIZED);
return value(mklist<value>(mklist<value>("realm", realm), mklist<value>("id", cadr(user)), mklist<value>("password", cadr(pw))));
}
/**
* Return the user info from a basic auth header.
*/
-const failable<value> userInfoFromHeader(const char* header, const string& realm, request_rec* r) {
+const failable<value> userInfoFromHeader(const char* header, const string& realm, request_rec* const r) {
debug(header, "modopenauth::userInfoFromHeader::header");
- if (strcasecmp(ap_getword(r->pool, &header, ' '), "Basic"))
- return mkfailure<value>("Wrong authentication scheme");
+ if(strcasecmp(ap_getword(r->pool, &header, ' '), "Basic"))
+ return mkfailure<value>("Wrong authentication scheme", HTTP_UNAUTHORIZED);
while (apr_isspace(*header))
header++;
@@ -212,18 +212,18 @@ const failable<value> userInfoFromHeader(const char* header, const string& realm
/**
* Handle an authenticated request.
*/
-const failable<int> authenticated(const list<list<value> >& info, request_rec* r) {
+const failable<int> authenticated(const list<list<value> >& info, request_rec* const r) {
debug(info, "modopenauth::authenticated::info");
// Store user info in the request
const list<value> realm = assoc<value>("realm", info);
- if (isNil(realm) || isNil(cdr(realm)))
- return mkfailure<int>("Couldn't retrieve realm");
+ if(isNil(realm) || isNil(cdr(realm)))
+ return mkfailure<int>("Couldn't retrieve realm", HTTP_UNAUTHORIZED);
apr_table_set(r->subprocess_env, apr_pstrdup(r->pool, "REALM"), apr_pstrdup(r->pool, c_str(cadr(realm))));
const list<value> id = assoc<value>("id", info);
- if (isNil(id) || isNil(cdr(id)))
- return mkfailure<int>("Couldn't retrieve user id");
+ if(isNil(id) || isNil(cdr(id)))
+ return mkfailure<int>("Couldn't retrieve user id", HTTP_UNAUTHORIZED);
r->user = apr_pstrdup(r->pool, c_str(cadr(id)));
apr_table_set(r->subprocess_env, apr_pstrdup(r->pool, "NICKNAME"), apr_pstrdup(r->pool, c_str(cadr(id))));
@@ -233,127 +233,113 @@ const failable<int> authenticated(const list<list<value> >& info, request_rec* r
/**
* Check user authentication.
*/
-static int checkAuthn(request_rec *r) {
- gc_scoped_pool pool(r->pool);
+static int checkAuthn(request_rec* const r) {
+ const gc_scoped_pool sp(r->pool);
// Decline if we're not enabled or AuthType is not set to Open
const DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_openauth);
- if (!dc.enabled)
+ if(!dc.enabled)
return DECLINED;
const char* atype = ap_auth_type(r);
- if (atype == NULL || strcasecmp(atype, "Open"))
- return DECLINED;
debug_httpdRequest(r, "modopenauth::checkAuthn::input");
debug(atype, "modopenauth::checkAuthn::auth_type");
+ if(atype == NULL || strcasecmp(atype, "Open"))
+ return DECLINED;
+ debug(atype, "modopenauth::checkAuthn::auth_type");
// Get the request args
const list<list<value> > args = httpd::queryArgs(r);
// Get session id from the request
const maybe<string> sid = sessionID(r, "TuscanyOpenAuth");
- if (hasContent(sid)) {
+ if(hasContent(sid)) {
// Decline if the session id was not created by this module
const string stype = substr(content(sid), 0, 7);
- if (stype == "OAuth2_" || stype == "OAuth1_" || stype == "OpenID_")
+ if(stype == "OAuth2_" || stype == "OAuth1_" || stype == "OpenID_")
return DECLINED;
// Retrieve the auth realm
const char* aname = ap_auth_name(r);
- if (aname == NULL)
- return httpd::reportStatus(mkfailure<int>("Missing AuthName"));
+ if(aname == NULL)
+ return reportStatus(mkfailure<int>("Missing AuthName", HTTP_UNAUTHORIZED), dc.login, nilValue, r);
// Extract user info from the session id
const failable<value> userinfo = userInfoFromCookie(content(sid), aname, r);
- if (hasContent(userinfo)) {
+ if(hasContent(userinfo)) {
// Try to authenticate the request
const value uinfo = content(userinfo);
const failable<int> authz = checkAuthnz(cadr(assoc<value>("id", uinfo)), cadr(assoc<value>("password", uinfo)), r, dc);
- if (!hasContent(authz)) {
+ if(!hasContent(authz)) {
// Authentication failed, redirect to login page
r->ap_auth_type = const_cast<char*>(atype);
- return httpd::reportStatus(login(dc.login, value(), 1, r));
+ return reportStatus(authz, dc.login, 1, r);
}
// Successfully authenticated, store the user info in the request
r->ap_auth_type = const_cast<char*>(atype);
- return httpd::reportStatus(authenticated(uinfo, r));
+ return reportStatus(authenticated(uinfo, r), dc.login, nilValue, r);
}
}
// Get basic auth header from the request
- const char* header = apr_table_get(r->headers_in, (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authorization" : "Authorization");
- if (header != NULL) {
+ const char* const header = apr_table_get(r->headers_in, (PROXYREQ_PROXY == r->proxyreq) ? "Proxy-Authorization" : "Authorization");
+ if(header != NULL) {
// Retrieve the auth realm
- const char* aname = ap_auth_name(r);
- if (aname == NULL)
- return httpd::reportStatus(mkfailure<int>("Missing AuthName"));
+ const char* const aname = ap_auth_name(r);
+ if(aname == NULL)
+ return reportStatus(mkfailure<int>("Missing AuthName", HTTP_UNAUTHORIZED), dc.login, nilValue, r);
// Extract user info from the session id
const failable<value> info = userInfoFromHeader(header, aname, r);
- if (hasContent(info)) {
+ if(hasContent(info)) {
// Try to authenticate the request
const value uinfo = content(info);
const failable<int> authz = checkAuthnz(cadr(assoc<value>("id", uinfo)), cadr(assoc<value>("password", uinfo)), r, dc);
- if (!hasContent(authz)) {
+ if(!hasContent(authz)) {
// Authentication failed, redirect to login page
r->ap_auth_type = const_cast<char*>(atype);
- return httpd::reportStatus(login(dc.login, value(), 1, r));
+ return reportStatus(authz, dc.login, 1, r);
}
// Successfully authenticated, store the user info in the request
r->ap_auth_type = const_cast<char*>(atype);
- return httpd::reportStatus(authenticated(uinfo, r));
+ return reportStatus(authenticated(uinfo, r), dc.login, nilValue, r);
}
}
// Decline if the request is for another authentication provider
- if (!isNil(assoc<value>("openid_identifier", args)))
+ if(!isNil(assoc<value>("openid_identifier", args)))
return DECLINED;
// Redirect to the login page, unless we have a session id from another module
- if (hasContent(sessionID(r, "TuscanyOpenIDAuth")) ||
+ if(hasContent(sessionID(r, "TuscanyOpenIDAuth")) ||
hasContent(sessionID(r, "TuscanyOAuth1")) ||
hasContent(sessionID(r, "TuscanyOAuth2")))
return DECLINED;
r->ap_auth_type = const_cast<char*>(atype);
- return httpd::reportStatus(login(dc.login, value(), value(), r));
+ return httpd::reportStatus(login(dc.login, nilValue, nilValue, r));
}
/**
- * Save the auth session cookie in the response.
- */
-static int sessionCookieSave(request_rec* r, session_rec* z) {
- gc_scoped_pool pool(r->pool);
-
- const DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_openauth);
- if (!dc.enabled)
- return DECLINED;
-
- debug(c_str(cookie("TuscanyOpenAuth", z->encoded, httpd::hostName(r))), "modopenauth::setcookie");
- apr_table_set(r->err_headers_out, "Set-Cookie", c_str(cookie("TuscanyOpenAuth", z->encoded, httpd::hostName(r))));
- return OK;
-}
-
-/**
- * Load the auth session cookie from the request. Similar
+ * Load the auth session cookie from the request.
*/
-static int sessionCookieLoad(request_rec* r, session_rec** z) {
- gc_scoped_pool pool(r->pool);
+static int sessionCookieLoad(request_rec* const r, session_rec** const z) {
+ const gc_scoped_pool sp(r->pool);
const DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_openauth);
- if (!dc.enabled)
+ if(!dc.enabled)
return DECLINED;
// First look in the notes
- const char* note = apr_pstrcat(r->pool, "mod_openauth", "TuscanyOpenAuth", NULL);
+ const char* const note = apr_pstrcat(r->pool, "mod_openauth", "TuscanyOpenAuth", NULL);
session_rec* zz = (session_rec*)(void*)apr_table_get(r->notes, note);
- if (zz != NULL) {
+ if(zz != NULL) {
*z = zz;
return OK;
}
@@ -376,22 +362,86 @@ static int sessionCookieLoad(request_rec* r, session_rec** z) {
}
/**
+ * Save the auth session cookie in the response.
+ */
+static int sessionCookieSave(request_rec* const r, session_rec* const z) {
+ const gc_scoped_pool sp(r->pool);
+
+ const DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_openauth);
+ if(!dc.enabled)
+ return DECLINED;
+ if(z->encoded == NULL || *(z->encoded) == '\0') {
+ const maybe<string> sid = sessionID(r, "TuscanyOpenAuth");
+ if(!hasContent(sid))
+ return OK;
+ }
+
+ debug(c_str(cookie("TuscanyOpenAuth", z->encoded, httpd::hostName(r))), "modopenauth::sessioncookiesave::setcookie");
+ apr_table_set(r->err_headers_out, "Set-Cookie", c_str(cookie("TuscanyOpenAuth", z->encoded, httpd::hostName(r))));
+ return OK;
+}
+
+/**
+ * Logout request handler.
+ */
+int logoutHandler(request_rec* const r) {
+ if(r->handler == NULL || strcmp(r->handler, "mod_tuscany_openauth_logout"))
+ return DECLINED;
+
+ const gc_scoped_pool sp(r->pool);
+ debug_httpdRequest(r, "modopenauth::handler::input");
+ const DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_openauth);
+ if(!dc.enabled)
+ return DECLINED;
+
+ // Clear the current session
+ if(hasContent(sessionID(r, "TuscanyOpenAuth"))) {
+ const char* const authname = ap_auth_name(r);
+ session_rec* z = NULL;
+ ap_session_load_fn(r, &z);
+ if(z != NULL && authname != NULL) {
+ ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-user", NULL), NULL);
+ ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-pw", NULL), NULL);
+ ap_session_set_fn(r, z, apr_pstrcat(r->pool, authname, "-site", NULL), NULL);
+ } else
+ apr_table_set(r->err_headers_out, "Set-Cookie", c_str(cookie("TuscanyOpenAuth", emptyString, httpd::hostName(r))));
+ }
+ if(hasContent(sessionID(r, "TuscanyOpenIDAuth")))
+ apr_table_set(r->err_headers_out, "Set-Cookie", c_str(cookie("TuscanyOpenIDAuth", emptyString, httpd::hostName(r))));
+ if(hasContent(sessionID(r, "TuscanyOAuth1")))
+ apr_table_set(r->err_headers_out, "Set-Cookie", c_str(cookie("TuscanyOAuth1", emptyString, httpd::hostName(r))));
+ if(hasContent(sessionID(r, "TuscanyOAuth2")))
+ apr_table_set(r->err_headers_out, "Set-Cookie", c_str(cookie("TuscanyOAuth2", emptyString, httpd::hostName(r))));
+
+ // Redirect to the login page
+ return httpd::reportStatus(login(dc.login, "/", nilValue, r));
+}
+
+/**
* Process the module configuration.
*/
-int postConfigMerge(ServerConf& mainsc, server_rec* s) {
- if (s == NULL)
+int postConfigMerge(const ServerConf& mainsc, server_rec* const s) {
+ if(s == NULL)
return OK;
debug(httpd::serverName(s), "modopenauth::postConfigMerge::serverName");
return postConfigMerge(mainsc, s->next);
}
-int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp, server_rec* s) {
- gc_scoped_pool pool(p);
+int postConfig(apr_pool_t* const p, unused apr_pool_t* const plog, unused apr_pool_t* const ptemp, server_rec* const s) {
+ const gc_scoped_pool sp(p);
- ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_openauth);
+ const ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_openauth);
debug(httpd::serverName(s), "modopenauth::postConfig::serverName");
+ // Retrieve session hook functions
+ if(ap_session_load_fn == NULL)
+ ap_session_load_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_load);
+ if(ap_session_get_fn == NULL)
+ ap_session_get_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_get);
+ if(ap_session_set_fn == NULL)
+ ap_session_set_fn = APR_RETRIEVE_OPTIONAL_FN(ap_session_set);
+
// Merge server configurations
return postConfigMerge(sc, s);
}
@@ -399,15 +449,15 @@ int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp,
/**
* Child process initialization.
*/
-void childInit(apr_pool_t* p, server_rec* s) {
- gc_scoped_pool pool(p);
+void childInit(apr_pool_t* const p, server_rec* const s) {
+ const gc_scoped_pool sp(p);
- ServerConf* psc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_openauth);
+ const ServerConf* const psc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_openauth);
if(psc == NULL) {
cfailure << "[Tuscany] Due to one or more errors mod_tuscany_openauth loading failed. Causing apache to stop loading." << endl;
exit(APEXIT_CHILDFATAL);
}
- ServerConf& sc = *psc;
+ const ServerConf& sc = *psc;
// Merge the updated configuration into the virtual hosts
postConfigMerge(sc, s->next);
@@ -416,27 +466,27 @@ void childInit(apr_pool_t* p, server_rec* s) {
/**
* Configuration commands.
*/
-const char* confEnabled(cmd_parms *cmd, void *c, const int arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confEnabled(cmd_parms* cmd, void *c, const int arg) {
+ const gc_scoped_pool sp(cmd->pool);
DirConf& dc = httpd::dirConf<DirConf>(c);
dc.enabled = (bool)arg;
return NULL;
}
-const char* confLogin(cmd_parms *cmd, void *c, const char* arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confLogin(cmd_parms *cmd, void *c, const char* arg) {
+ const gc_scoped_pool sp(cmd->pool);
DirConf& dc = httpd::dirConf<DirConf>(c);
dc.login = arg;
return NULL;
}
-const char* confAuthnProvider(cmd_parms *cmd, void *c, const char* arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confAuthnProvider(cmd_parms *cmd, void *c, const char* arg) {
+ const gc_scoped_pool sp(cmd->pool);
DirConf& dc = httpd::dirConf<DirConf>(c);
// Lookup and cache the Authn provider
const authn_provider* provider = (authn_provider*)ap_lookup_provider(AUTHN_PROVIDER_GROUP, arg, AUTHN_PROVIDER_VERSION);
- if (provider == NULL)
+ if(provider == NULL)
return apr_psprintf(cmd->pool, "Unknown Authn provider: %s", arg);
- if (!provider->check_password)
+ if(!provider->check_password)
return apr_psprintf(cmd->pool, "The '%s' Authn provider doesn't support password authentication", arg);
dc.apcs = append<AuthnProviderConf>(dc.apcs, mklist<AuthnProviderConf>(AuthnProviderConf(arg, provider)));
return NULL;
@@ -458,6 +508,7 @@ void registerHooks(unused apr_pool_t *p) {
ap_hook_check_authn(checkAuthn, NULL, NULL, APR_HOOK_MIDDLE, AP_AUTH_INTERNAL_PER_CONF);
ap_hook_session_load(sessionCookieLoad, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_session_save(sessionCookieSave, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_handler(logoutHandler, NULL, NULL, APR_HOOK_MIDDLE);
}
}
diff --git a/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp b/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
index b66cd29959..0a9ebc1a80 100644
--- a/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
+++ b/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
@@ -53,17 +53,17 @@ namespace modssltunnel {
*/
class ServerConf {
public:
- ServerConf(apr_pool_t* p, server_rec* s) : p(p), server(s) {
+ ServerConf(apr_pool_t* const p, server_rec* const s) : p(p), server(s) {
}
const gc_pool p;
- server_rec* server;
- string pass;
- string host;
- string path;
- string ca;
- string cert;
- string key;
+ server_rec* const server;
+ gc_mutable_ref<string> pass;
+ gc_mutable_ref<string> host;
+ gc_mutable_ref<string> path;
+ gc_mutable_ref<string> ca;
+ gc_mutable_ref<string> cert;
+ gc_mutable_ref<string> key;
};
extern "C" {
@@ -74,7 +74,7 @@ extern module AP_DECLARE_DATA core_module;
* Process the module configuration.
*/
int M_SSLTUNNEL;
-int postConfigMerge(ServerConf& mainsc, apr_pool_t* p, server_rec* s) {
+int postConfigMerge(const ServerConf& mainsc, apr_pool_t* const p, server_rec* const s) {
if (s == NULL)
return OK;
ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_ssltunnel);
@@ -102,10 +102,10 @@ int postConfigMerge(ServerConf& mainsc, apr_pool_t* p, server_rec* s) {
return postConfigMerge(mainsc, p, s->next);
}
-int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp, server_rec* s) {
- gc_scoped_pool pool(p);
+int postConfig(apr_pool_t* const p, unused apr_pool_t* const plog, unused apr_pool_t* const ptemp, server_rec* const s) {
+ const gc_scoped_pool sp(p);
- ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_ssltunnel);
+ const ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_ssltunnel);
debug(httpd::serverName(s), "modssltunnel::postConfig::serverName");
// Register the SSLTUNNEL method
@@ -118,7 +118,7 @@ int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp,
/**
* Close a connection.
*/
-const int close(conn_rec* conn, apr_socket_t* csock) {
+const int close(conn_rec* const conn, apr_socket_t* const csock) {
debug("modssltunnel::close");
apr_socket_close(csock);
conn->aborted = 1;
@@ -128,7 +128,7 @@ const int close(conn_rec* conn, apr_socket_t* csock) {
/**
* Abort a connection.
*/
-const int abort(conn_rec* conn, apr_socket_t* csock, const string& reason) {
+const int abort(conn_rec* const conn, apr_socket_t* const csock, const string& reason) {
debug("modssltunnel::abort");
apr_socket_close(csock);
conn->aborted = 1;
@@ -138,21 +138,21 @@ const int abort(conn_rec* conn, apr_socket_t* csock, const string& reason) {
/**
* Tunnel traffic from a client connection to a target URL.
*/
-int tunnel(conn_rec* conn, const string& ca, const string& cert, const string& key, const string& url, const string& preamble, const gc_pool& p, unused ap_filter_t* ifilter, ap_filter_t* ofilter) {
+int tunnel(conn_rec* const conn, const string& ca, const string& cert, const string& key, const string& url, const string& preamble, const gc_pool& p, unused ap_filter_t* const ifilter, ap_filter_t* const ofilter) {
// Create input/output bucket brigades
- apr_bucket_brigade* ib = apr_brigade_create(pool(p), conn->bucket_alloc);
- apr_bucket_brigade* ob = apr_brigade_create(pool(p), conn->bucket_alloc);
+ apr_bucket_brigade* const ib = apr_brigade_create(pool(p), conn->bucket_alloc);
+ apr_bucket_brigade* const ob = apr_brigade_create(pool(p), conn->bucket_alloc);
// Get client connection socket
- apr_socket_t* csock = (apr_socket_t*)ap_get_module_config(conn->conn_config, &core_module);
+ apr_socket_t* const csock = (apr_socket_t*)ap_get_module_config(conn->conn_config, &core_module);
// Open connection to target
- http::CURLSession cs(ca, cert, key, "", 0);
+ const http::CURLSession cs(ca, cert, key, emptyString, 0);
const failable<bool> crc = http::connect(url, cs);
if (!hasContent(crc))
return abort(conn, csock, reason(crc));
- apr_socket_t* tsock = http::sock(cs);
+ apr_socket_t* const tsock = http::sock(cs);
// Send preamble
if (length(preamble) != 0) {
@@ -164,7 +164,7 @@ int tunnel(conn_rec* conn, const string& ca, const string& cert, const string& k
// Create a pollset for the client and target sockets
apr_pollset_t* pollset;
- apr_status_t cprc = apr_pollset_create(&pollset, 2, pool(p), 0);
+ const apr_status_t cprc = apr_pollset_create(&pollset, 2, pool(p), 0);
if (cprc != APR_SUCCESS)
return abort(conn, csock, http::apreason(cprc));
const apr_pollfd_t* cpollfd = http::pollfd(csock, APR_POLLIN, p);
@@ -241,7 +241,7 @@ int tunnel(conn_rec* conn, const string& ca, const string& cert, const string& k
// Poll the client and target sockets
debug("modssltunnel::tunnel::poll");
- apr_status_t pollrc = apr_pollset_poll(pollset, -1, &pollcount, &pollfds);
+ const apr_status_t pollrc = apr_pollset_poll(pollset, -1, &pollcount, &pollfds);
if (pollrc != APR_SUCCESS)
return abort(conn, csock, "Couldn't poll sockets");
debug(pollcount, "modssltunnel::tunnel::pollfds");
@@ -254,7 +254,7 @@ int tunnel(conn_rec* conn, const string& ca, const string& cert, const string& k
/**
* Return the first connection filter in a list of filters.
*/
-ap_filter_t* connectionFilter(ap_filter_t* f) {
+ap_filter_t* const connectionFilter(ap_filter_t* const f) {
if (f == NULL)
return f;
if (f->frec->ftype < AP_FTYPE_CONNECTION)
@@ -265,14 +265,14 @@ ap_filter_t* connectionFilter(ap_filter_t* f) {
/**
* Process a client connection and relay it to a tunnel.
*/
-int processConnection(conn_rec *conn) {
+int processConnection(conn_rec* conn) {
// Only allow configured virtual hosts
if (!conn->base_server->is_virtual)
return DECLINED;
if (ap_get_module_config(conn->base_server->module_config, &mod_tuscany_ssltunnel) == NULL)
return DECLINED;
- gc_scoped_pool pool(conn->pool);
+ const gc_scoped_pool sp(conn->pool);
// Get the server configuration
const ServerConf& sc = httpd::serverConf<ServerConf>(conn->base_server, &mod_tuscany_ssltunnel);
@@ -297,41 +297,41 @@ int handler(request_rec* r) {
if (strcmp(r->server->server_scheme, "https"))
return DECLINED;
- gc_scoped_pool pool(r->pool);
+ const gc_scoped_pool sp(r->pool);
// Build the target URL
debug(r->uri, "modssltunnel::handler::uri");
const list<value> path(pathValues(r->uri));
- const string url = string(cadr(path)) + ":" + caddr(path);
+ const string url = string(cadr(path)) + ":" + (string)caddr(path);
debug(url, "modssltunnel::handler::target");
// Run the tunnel
- return tunnel(r->connection, "", "", "", url, "", gc_pool(r->pool), connectionFilter(r->proto_input_filters), connectionFilter(r->proto_output_filters));
+ return tunnel(r->connection, emptyString, emptyString, emptyString, url, emptyString, gc_pool(r->pool), connectionFilter(r->proto_input_filters), connectionFilter(r->proto_output_filters));
}
/**
* Configuration commands.
*/
-const char* confTunnelPass(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confTunnelPass(cmd_parms *cmd, unused void *c, const char *arg) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_ssltunnel);
sc.pass = arg;
return NULL;
}
-const char* confCAFile(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confCAFile(cmd_parms *cmd, unused void *c, const char *arg) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_ssltunnel);
sc.ca = arg;
return NULL;
}
-const char* confCertFile(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confCertFile(cmd_parms *cmd, unused void *c, const char *arg) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_ssltunnel);
sc.cert = arg;
return NULL;
}
-const char* confCertKeyFile(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confCertKeyFile(cmd_parms *cmd, unused void *c, const char *arg) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_ssltunnel);
sc.key = arg;
return NULL;
diff --git a/sca-cpp/trunk/modules/http/openauth.hpp b/sca-cpp/trunk/modules/http/openauth.hpp
index 3ffa88d362..dcf405d487 100644
--- a/sca-cpp/trunk/modules/http/openauth.hpp
+++ b/sca-cpp/trunk/modules/http/openauth.hpp
@@ -42,11 +42,12 @@ namespace openauth {
/**
* Return the session id from a request.
*/
-const char* cookieName(const char* cs) {
+const char* const cookieName(const char* const cs) {
if (*cs != ' ')
return cs;
return cookieName(cs + 1);
}
+
const maybe<string> sessionID(const list<string>& c, const string& key) {
if (isNil(c))
return maybe<string>();
@@ -62,7 +63,7 @@ const maybe<string> sessionID(const list<string>& c, const string& key) {
return sessionID(cdr(c), key);
}
-const maybe<string> sessionID(const request_rec* r, const string& key) {
+const maybe<string> sessionID(const request_rec* const r, const string& key) {
const string c = httpd::cookie(r);
debug(c, "openauth::sessionid::cookies");
if (length(c) == 0)
@@ -74,10 +75,15 @@ const maybe<string> sessionID(const request_rec* r, const string& key) {
* Convert a session id to a cookie string.
*/
const string cookie(const string& key, const string& sid, const string& domain) {
+ if (length(sid) == 0) {
+ const string c = key + string("=") + "; max-age=0; domain=." + httpd::realm(domain) + "; path=/; secure; httponly";
+ debug(c, "openauth::cookie");
+ return c;
+ }
const time_t t = time(NULL) + 86400;
char exp[32];
strftime(exp, 32, "%a, %d-%b-%Y %H:%M:%S GMT", gmtime(&t));
- const string c = key + string("=") + sid + "; expires=" + string(exp) + "; domain=." + httpd::realm(domain) + "; path=/";
+ const string c = key + string("=") + sid + "; expires=" + string(exp) + "; domain=." + httpd::realm(domain) + "; path=/; secure; httponly";
debug(c, "openauth::cookie");
return c;
}
@@ -85,7 +91,7 @@ const string cookie(const string& key, const string& sid, const string& domain)
/**
* Redirect to the configured login page.
*/
-const failable<int> login(const string& page, const value& ref, const value& attempt, request_rec* r) {
+const failable<int> login(const string& page, const value& ref, const value& attempt, request_rec* const r) {
const list<list<value> > rarg = ref == string("/")? list<list<value> >() : mklist<list<value> >(mklist<value>("openauth_referrer", httpd::escape(httpd::url(isNil(ref)? r->uri : ref, r))));
const list<list<value> > aarg = isNil(attempt)? list<list<value> >() : mklist<list<value> >(mklist<value>("openauth_attempt", attempt));
const list<list<value> > largs = append<list<value> >(rarg, aarg);
@@ -94,6 +100,31 @@ const failable<int> login(const string& page, const value& ref, const value& att
return httpd::externalRedirect(loc, r);
}
+/**
+ * Report a request auth status.
+ */
+const int reportStatus(const failable<int>& authrc, const string& page, const value& attempt, request_rec* const r) {
+ debug(authrc, "openauth::reportStatus::authrc");
+
+ // Redirect to the login page if not authorized
+ if (!hasContent(authrc) && rcode(authrc) == HTTP_UNAUTHORIZED) {
+
+ // Clear any auth cookies
+ if(hasContent(sessionID(r, "TuscanyOpenAuth")))
+ apr_table_set(r->err_headers_out, "Set-Cookie", c_str(cookie("TuscanyOpenAuth", emptyString, httpd::hostName(r))));
+ if(hasContent(sessionID(r, "TuscanyOpenIDAuth")))
+ apr_table_set(r->err_headers_out, "Set-Cookie", c_str(cookie("TuscanyOpenIDAuth", emptyString, httpd::hostName(r))));
+ if(hasContent(sessionID(r, "TuscanyOAuth1")))
+ apr_table_set(r->err_headers_out, "Set-Cookie", c_str(cookie("TuscanyOAuth1", emptyString, httpd::hostName(r))));
+ if(hasContent(sessionID(r, "TuscanyOAuth2")))
+ apr_table_set(r->err_headers_out, "Set-Cookie", c_str(cookie("TuscanyOAuth2", emptyString, httpd::hostName(r))));
+
+ return httpd::reportStatus(login(page, string("/"), attempt, r));
+ }
+
+ return httpd::reportStatus(authrc);
+}
+
}
}
diff --git a/sca-cpp/trunk/modules/java/Makefile.am b/sca-cpp/trunk/modules/java/Makefile.am
index 8b80276d15..a25576537c 100644
--- a/sca-cpp/trunk/modules/java/Makefile.am
+++ b/sca-cpp/trunk/modules/java/Makefile.am
@@ -36,7 +36,7 @@ EXTRA_DIST = domain-test.composite
mod_LTLIBRARIES = libmod_tuscany_java.la
libmod_tuscany_java_la_SOURCES = mod-java.cpp
-libmod_tuscany_java_la_LDFLAGS = -lxml2 -lcurl -lmozjs ${JAVA_LDFLAGS}
+libmod_tuscany_java_la_LDFLAGS = -lxml2 -lcurl -ljansson ${JAVA_LDFLAGS}
noinst_DATA = libmod_tuscany_java${libsuffix}
libmod_tuscany_java${libsuffix}:
ln -s .libs/libmod_tuscany_java${libsuffix}
@@ -55,12 +55,13 @@ jardir = ${prefix}/modules/java
jarfile = libmod-tuscany-java-${PACKAGE_VERSION}.jar
jar_DATA = ${jarfile}
${jarfile}: ${dist_mod_JAVA}
+ ${JAVAC} ${dist_mod_JAVA}
${JAR} cf $@ org/apache/tuscany/*.class
CLEANFILES = *.stamp ${jarfile} org/apache/tuscany/*.class test/*.class
client_test_SOURCES = client-test.cpp
-client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+client_test_LDFLAGS = -lxml2 -lcurl -ljansson
dist_noinst_SCRIPTS = server-test wiring-test
noinst_PROGRAMS = jni-test java-test client-test
diff --git a/sca-cpp/trunk/modules/java/driver.hpp b/sca-cpp/trunk/modules/java/driver.hpp
index ddfc057940..4ffc84f4db 100644
--- a/sca-cpp/trunk/modules/java/driver.hpp
+++ b/sca-cpp/trunk/modules/java/driver.hpp
@@ -37,7 +37,7 @@ namespace java {
const value evalDriverLoop(const JavaRuntime& jr, const JavaClass jc, istream& in, ostream& out) {
scheme::promptForInput(scheme::evalInputPrompt, out);
- value input = scheme::readValue(in);
+ const value input = content(scheme::readValue(in));
if (isNil(input))
return input;
const failable<value> output = evalClass(jr, input, jc);
@@ -46,7 +46,7 @@ const value evalDriverLoop(const JavaRuntime& jr, const JavaClass jc, istream& i
return evalDriverLoop(jr, jc, in, out);
}
-const bool evalDriverRun(const char* name, istream& in, ostream& out) {
+const bool evalDriverRun(const char* const name, istream& in, ostream& out) {
scheme::setupDisplay(out);
JavaRuntime javaRuntime;
const failable<JavaClass> jc = readClass(javaRuntime, ".", name);
diff --git a/sca-cpp/trunk/modules/java/eval.hpp b/sca-cpp/trunk/modules/java/eval.hpp
index 31fb09f741..2c76b764fa 100644
--- a/sca-cpp/trunk/modules/java/eval.hpp
+++ b/sca-cpp/trunk/modules/java/eval.hpp
@@ -50,12 +50,12 @@ jobject JNICALL nativeUUID(JNIEnv *env);
class JavaRuntime {
public:
- JavaRuntime() {
+ JavaRuntime() : h(*(new (gc_new<handles>()) handles())) {
debug("java::javaruntime");
// Get existing JVM
jsize nvms = 0;
- JNI_GetCreatedJavaVMs(&jvm, 1, &nvms);
+ JNI_GetCreatedJavaVMs(&h.jvm, 1, &nvms);
if (nvms == 0) {
// Create a new JVM
@@ -67,7 +67,7 @@ public:
args.nOptions = 0;
// Configure classpath
- const char* envcp = getenv("CLASSPATH");
+ const char* const envcp = getenv("CLASSPATH");
const string cp = string("-Djava.class.path=") + (envcp == NULL? "." : envcp);
options[args.nOptions].optionString = const_cast<char*>(c_str(cp));
options[args.nOptions++].extraInfo = NULL;
@@ -78,12 +78,12 @@ public:
#endif
// Configure Java debugging
- const char* jpdaopts = getenv("JPDA_OPTS");
+ const char* const jpdaopts = getenv("JPDA_OPTS");
if (jpdaopts != NULL) {
options[args.nOptions].optionString = const_cast<char*>(jpdaopts);
options[args.nOptions++].extraInfo = NULL;
} else {
- const char* jpdaaddr = getenv("JPDA_ADDRESS");
+ const char* const jpdaaddr = getenv("JPDA_ADDRESS");
if (jpdaaddr != NULL) {
const string jpda = string("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=") + jpdaaddr;
options[args.nOptions].optionString = const_cast<char*>(c_str(jpda));
@@ -93,114 +93,131 @@ public:
// Create the JVM
#ifdef JAVA_HARMONY_VM
- JNI_CreateJavaVM(&jvm, &env, &args);
+ JNI_CreateJavaVM(&h.jvm, &h.env, &args);
#else
- JNI_CreateJavaVM(&jvm, (void**)&env, &args);
+ JNI_CreateJavaVM(&h.jvm, (void**)&h.env, &args);
#endif
} else {
// Just point to existing JVM
- jvm->GetEnv((void**)&env, JNI_VERSION);
+ h.jvm->GetEnv((void**)&h.env, JNI_VERSION);
}
// Lookup System classes and methods
- classClass = env->FindClass("java/lang/Class");
- methodClass = env->FindClass("java/lang/reflect/Method");
- objectClass = env->FindClass("java/lang/Object");
- doubleClass = env->FindClass("java/lang/Double");
- booleanClass = env->FindClass("java/lang/Boolean");
- stringClass = env->FindClass("java/lang/String");
- objectArrayClass = env->FindClass("[Ljava/lang/Object;");
- iterableClass = env->FindClass("java/lang/Iterable");
- classForName = env->GetStaticMethodID(classClass, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
- doubleValueOf = env->GetStaticMethodID(doubleClass, "valueOf", "(D)Ljava/lang/Double;");
- doubleValue = env->GetMethodID(doubleClass, "doubleValue", "()D");
- booleanValueOf = env->GetStaticMethodID(booleanClass, "valueOf", "(Z)Ljava/lang/Boolean;");
- booleanValue = env->GetMethodID(booleanClass, "booleanValue", "()Z");
- declaredMethods = env->GetMethodID(classClass, "getDeclaredMethods", "()[Ljava/lang/reflect/Method;");
- methodName = env->GetMethodID(methodClass, "getName", "()Ljava/lang/String;");
- parameterTypes = env->GetMethodID(methodClass, "getParameterTypes", "()[Ljava/lang/Class;");
+ h.classClass = h.env->FindClass("java/lang/Class");
+ h.methodClass = h.env->FindClass("java/lang/reflect/Method");
+ h.objectClass = h.env->FindClass("java/lang/Object");
+ h.doubleClass = h.env->FindClass("java/lang/Double");
+ h.booleanClass = h.env->FindClass("java/lang/Boolean");
+ h.stringClass = h.env->FindClass("java/lang/String");
+ h.objectArrayClass = h.env->FindClass("[Ljava/lang/Object;");
+ h.iterableClass = h.env->FindClass("java/lang/Iterable");
+ h.classForName = h.env->GetStaticMethodID(h.classClass, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
+ h.doubleValueOf = h.env->GetStaticMethodID(h.doubleClass, "valueOf", "(D)Ljava/lang/Double;");
+ h.doubleValue = h.env->GetMethodID(h.doubleClass, "doubleValue", "()D");
+ h.booleanValueOf = h.env->GetStaticMethodID(h.booleanClass, "valueOf", "(Z)Ljava/lang/Boolean;");
+ h.booleanValue = h.env->GetMethodID(h.booleanClass, "booleanValue", "()Z");
+ h.declaredMethods = h.env->GetMethodID(h.classClass, "getDeclaredMethods", "()[Ljava/lang/reflect/Method;");
+ h.methodName = h.env->GetMethodID(h.methodClass, "getName", "()Ljava/lang/String;");
+ h.parameterTypes = h.env->GetMethodID(h.methodClass, "getParameterTypes", "()[Ljava/lang/Class;");
// Lookup Tuscany classes and methods
- loaderClass = env->FindClass("org/apache/tuscany/ClassLoader");
- loaderValueOf = env->GetStaticMethodID(loaderClass, "valueOf", "(Ljava/lang/String;)Ljava/lang/ClassLoader;");
- loaderForName = env->GetStaticMethodID(loaderClass, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
- invokerClass = env->FindClass("org/apache/tuscany/InvocationHandler");
- invokerValueOf = env->GetStaticMethodID(invokerClass, "valueOf", "(Ljava/lang/Class;J)Ljava/lang/Object;");
- invokerStackTrace = env->GetStaticMethodID(invokerClass, "stackTrace", "(Ljava/lang/Throwable;)Ljava/lang/String;");
- invokerLambda = env->GetFieldID(invokerClass, "lambda", "J");
- iterableUtilClass = env->FindClass("org/apache/tuscany/IterableUtil");
- iterableValueOf = env->GetStaticMethodID(iterableUtilClass, "list", "([Ljava/lang/Object;)Ljava/lang/Iterable;");
- iterableIsNil = env->GetStaticMethodID(iterableUtilClass, "isNil", "(Ljava/lang/Object;)Z");
- iterableCar = env->GetStaticMethodID(iterableUtilClass, "car", "(Ljava/lang/Object;)Ljava/lang/Object;");
- iterableCdr = env->GetStaticMethodID(iterableUtilClass, "cdr", "(Ljava/lang/Object;)Ljava/lang/Iterable;");
- uuidClass = env->FindClass("org/apache/tuscany/UUIDUtil");
+ h.loaderClass = h.env->FindClass("org/apache/tuscany/ClassLoader");
+ h.loaderValueOf = h.env->GetStaticMethodID(h.loaderClass, "valueOf", "(Ljava/lang/String;)Ljava/lang/ClassLoader;");
+ h.loaderForName = h.env->GetStaticMethodID(h.loaderClass, "forName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;");
+ h.invokerClass = h.env->FindClass("org/apache/tuscany/InvocationHandler");
+ h.invokerValueOf = h.env->GetStaticMethodID(h.invokerClass, "valueOf", "(Ljava/lang/Class;J)Ljava/lang/Object;");
+ h.invokerStackTrace = h.env->GetStaticMethodID(h.invokerClass, "stackTrace", "(Ljava/lang/Throwable;)Ljava/lang/String;");
+ h.invokerLambda = h.env->GetFieldID(h.invokerClass, "lambda", "J");
+ h.iterableUtilClass = h.env->FindClass("org/apache/tuscany/IterableUtil");
+ h.iterableValueOf = h.env->GetStaticMethodID(h.iterableUtilClass, "list", "([Ljava/lang/Object;)Ljava/lang/Iterable;");
+ h.iterableIsNil = h.env->GetStaticMethodID(h.iterableUtilClass, "isNil", "(Ljava/lang/Object;)Z");
+ h.iterableCar = h.env->GetStaticMethodID(h.iterableUtilClass, "car", "(Ljava/lang/Object;)Ljava/lang/Object;");
+ h.iterableCdr = h.env->GetStaticMethodID(h.iterableUtilClass, "cdr", "(Ljava/lang/Object;)Ljava/lang/Iterable;");
+ h.uuidClass = h.env->FindClass("org/apache/tuscany/UUIDUtil");
// Register our native invocation handler function
JNINativeMethod invokenm;
invokenm.name = const_cast<char*>("invoke");
invokenm.signature = const_cast<char*>("(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;");
invokenm.fnPtr = (void*)nativeInvoke;
- env->RegisterNatives(invokerClass, &invokenm, 1);
+ h.env->RegisterNatives(h.invokerClass, &invokenm, 1);
// Register our native UUID function
JNINativeMethod uuidnm;
uuidnm.name = const_cast<char*>("uuid");
uuidnm.signature = const_cast<char*>("()Ljava/lang/String;");
uuidnm.fnPtr = (void*)nativeUUID;
- env->RegisterNatives(uuidClass, &uuidnm, 1);
+ h.env->RegisterNatives(h.uuidClass, &uuidnm, 1);
}
+ JavaRuntime(const JavaRuntime& c) : h(c.h) {
+ }
+
+ JavaRuntime& operator=(const JavaRuntime&) = delete;
+
~JavaRuntime() {
}
- JavaVM* jvm;
- JNIEnv* env;
-
- jclass classClass;
- jclass methodClass;
- jclass objectClass;
- jclass doubleClass;
- jclass booleanClass;
- jclass stringClass;
- jclass objectArrayClass;
- jclass iterableClass;
- jmethodID doubleValueOf;
- jmethodID doubleValue;
- jmethodID booleanValueOf;
- jmethodID booleanValue;
- jmethodID declaredMethods;
- jmethodID methodName;
- jmethodID parameterTypes;
- jmethodID classForName;
- jclass loaderClass;
- jmethodID loaderValueOf;
- jmethodID loaderForName;
- jclass invokerClass;
- jmethodID invokerValueOf;
- jmethodID invokerStackTrace;
- jfieldID invokerLambda;
- jclass iterableUtilClass;
- jmethodID iterableValueOf;
- jmethodID iterableCar;
- jmethodID iterableCdr;
- jmethodID iterableIsNil;
- jclass uuidClass;
+public:
+ class handles {
+ public:
+ handles() {
+ }
+
+ public:
+ friend class JavaRuntime;
+
+ JavaVM* jvm;
+ JNIEnv* env;
+
+ jclass classClass;
+ jclass methodClass;
+ jclass objectClass;
+ jclass doubleClass;
+ jclass booleanClass;
+ jclass stringClass;
+ jclass objectArrayClass;
+ jclass iterableClass;
+ jmethodID doubleValueOf;
+ jmethodID doubleValue;
+ jmethodID booleanValueOf;
+ jmethodID booleanValue;
+ jmethodID declaredMethods;
+ jmethodID methodName;
+ jmethodID parameterTypes;
+ jmethodID classForName;
+ jclass loaderClass;
+ jmethodID loaderValueOf;
+ jmethodID loaderForName;
+ jclass invokerClass;
+ jmethodID invokerValueOf;
+ jmethodID invokerStackTrace;
+ jfieldID invokerLambda;
+ jclass iterableUtilClass;
+ jmethodID iterableValueOf;
+ jmethodID iterableCar;
+ jmethodID iterableCdr;
+ jmethodID iterableIsNil;
+ jclass uuidClass;
+ };
+
+ handles& h;
};
/**
* Return the last exception that occurred in a JVM.
*/
-string lastException(const JavaRuntime& jr) {
- if (!jr.env->ExceptionCheck())
+const string lastException(const JavaRuntime& jr) {
+ if (!jr.h.env->ExceptionCheck())
return "No Exception";
- const jthrowable ex = jr.env->ExceptionOccurred();
- const jstring trace = (jstring)jr.env->CallStaticObjectMethod(jr.invokerClass, jr.invokerStackTrace, ex);
- const char* c = jr.env->GetStringUTFChars(trace, NULL);
+ const jthrowable ex = jr.h.env->ExceptionOccurred();
+ const jstring trace = (jstring)jr.h.env->CallStaticObjectMethod(jr.h.invokerClass, jr.h.invokerStackTrace, ex);
+ const char* const c = jr.h.env->GetStringUTFChars(trace, NULL);
const string msg(c);
- jr.env->ReleaseStringUTFChars(trace, c);
- jr.env->ExceptionClear();
+ jr.h.env->ReleaseStringUTFChars(trace, c);
+ jr.h.env->ExceptionClear();
return msg;
}
@@ -216,7 +233,7 @@ const list<value> jiterableToValues(const JavaRuntime& jr, const jobject o);
/**
* Convert a Java class name to a JNI class name.
*/
-const bool jniClassNameHelper(char* to, const char* from) {
+const bool jniClassNameHelper(char* const to, const char* const from) {
if (*from == '\0') {
*to = '\0';
return true;
@@ -236,7 +253,7 @@ const string jniClassName(const string& from) {
*/
class javaLambda {
public:
- javaLambda(const JavaRuntime& jr, const value& iface, const lambda<value(const list<value>&)>& func) : jr(jr), iface(iface), func(func) {
+ javaLambda(const JavaRuntime& jr, const value& iface, const lvvlambda& func) : jr(jr), iface(iface), func(func) {
}
const value operator()(const list<value>& expr) const {
@@ -255,9 +272,10 @@ public:
return func(expr);
}
- const JavaRuntime& jr;
+public:
+ const JavaRuntime jr;
const value iface;
- const lambda<value(const list<value>&)> func;
+ const lvvlambda func;
};
/**
@@ -267,12 +285,12 @@ public:
jobject JNICALL nativeInvoke(JNIEnv* env, jobject self, unused jobject proxy, jobject method, jobjectArray args) {
// Retrieve the lambda function from the invocation handler
- jclass clazz = env->GetObjectClass(self);
- jfieldID f = env->GetFieldID(clazz, "lambda", "J");
+ const jclass clazz = env->GetObjectClass(self);
+ const jfieldID f = env->GetFieldID(clazz, "lambda", "J");
const javaLambda& jl = *(javaLambda*)(long)env->GetLongField(self, f);
// Retrieve the function name
- const jstring s = (jstring)env->CallObjectMethod(method, jl.jr.methodName);
+ const jstring s = (jstring)env->CallObjectMethod(method, jl.jr.h.methodName);
const char* c = env->GetStringUTFChars(s, NULL);
const value func(c);
env->ReleaseStringUTFChars(s, c);
@@ -287,7 +305,7 @@ jobject JNICALL nativeInvoke(JNIEnv* env, jobject self, unused jobject proxy, jo
debug(result, "java::nativeInvoke::result");
// Convert result to a jobject
- return valueToJobject(jl.jr, value(), result);
+ return valueToJobject(jl.jr, nilValue, result);
}
/**
@@ -302,10 +320,10 @@ jobject JNICALL nativeUUID(JNIEnv* env) {
/**
* Convert a lambda function to Java proxy.
*/
-const jobject mkJavaLambda(const JavaRuntime& jr, unused const value& iface, const lambda<value(const list<value>&)>& l) {
+const jobject mkJavaLambda(const JavaRuntime& jr, unused const value& iface, const lvvlambda& l) {
const gc_ptr<javaLambda> jl = new (gc_new<javaLambda>()) javaLambda(jr, iface, l);
jclass jc = (jclass)(long)(double)iface;
- const jobject obj = jr.env->CallStaticObjectMethod(jr.invokerClass, jr.invokerValueOf, jc, (long)(javaLambda*)jl);
+ const jobject obj = jr.h.env->CallStaticObjectMethod(jr.h.invokerClass, jr.h.invokerValueOf, jc, (long)(javaLambda*)jl);
return obj;
}
@@ -315,20 +333,20 @@ const jobject mkJavaLambda(const JavaRuntime& jr, unused const value& iface, con
const jobjectArray valuesToJarrayHelper(const JavaRuntime& jr, jobjectArray a, const list<value>& v, const int i) {
if (isNil(v))
return a;
- jr.env->SetObjectArrayElement(a, i, valueToJobject(jr, value(), car(v)));
+ jr.h.env->SetObjectArrayElement(a, i, valueToJobject(jr, nilValue, car(v)));
return valuesToJarrayHelper(jr, a, cdr(v), i + 1);
}
const jobjectArray valuesToJarray(const JavaRuntime& jr, const list<value>& v) {
- jobjectArray a = jr.env->NewObjectArray((jsize)length(v), jr.objectClass, NULL);
+ jobjectArray a = jr.h.env->NewObjectArray((jsize)length(v), jr.h.objectClass, NULL);
return valuesToJarrayHelper(jr, a, v, 0);
}
/**
* Convert a Java jobjectArray to a Java iterable.
*/
-const jobject jarrayToJiterable(const JavaRuntime& jr, jobjectArray a) {
- return jr.env->CallStaticObjectMethod(jr.iterableClass, jr.iterableValueOf, a);
+const jobject jarrayToJiterable(const JavaRuntime& jr, const jobjectArray a) {
+ return jr.h.env->CallStaticObjectMethod(jr.h.iterableClass, jr.h.iterableValueOf, a);
}
/**
@@ -341,13 +359,13 @@ const jobject valueToJobject(const JavaRuntime& jr, const value& jtype, const va
case value::Lambda:
return mkJavaLambda(jr, jtype, v);
case value::Symbol:
- return jr.env->NewStringUTF(c_str(string("'") + v));
+ return jr.h.env->NewStringUTF(c_str(string("'") + (string)v));
case value::String:
- return jr.env->NewStringUTF(c_str(v));
+ return jr.h.env->NewStringUTF(c_str(v));
case value::Number:
- return jr.env->CallStaticObjectMethod(jr.doubleClass, jr.doubleValueOf, (double)v);
+ return jr.h.env->CallStaticObjectMethod(jr.h.doubleClass, jr.h.doubleValueOf, (double)v);
case value::Bool:
- return jr.env->CallStaticObjectMethod(jr.booleanClass, jr.booleanValueOf, (bool)v);
+ return jr.h.env->CallStaticObjectMethod(jr.h.booleanClass, jr.h.booleanValueOf, (bool)v);
default:
return NULL;
}
@@ -356,7 +374,7 @@ const jobject valueToJobject(const JavaRuntime& jr, const value& jtype, const va
/**
* Convert a list of values to an array of jvalues.
*/
-const jvalue* valuesToJvaluesHelper(const JavaRuntime& jr, jvalue* a, const list<value>& types, const list<value>& v) {
+const jvalue* valuesToJvaluesHelper(const JavaRuntime& jr, jvalue* const a, const list<value>& types, const list<value>& v) {
if (isNil(v))
return a;
a->l = valueToJobject(jr, car(types), car(v));
@@ -365,7 +383,7 @@ const jvalue* valuesToJvaluesHelper(const JavaRuntime& jr, jvalue* a, const list
const jvalue* valuesToJvalues(const JavaRuntime& jr, const list<value>& types, const list<value>& v) {
const size_t n = length(v);
- jvalue* a = new (gc_anew<jvalue>(n)) jvalue[n];
+ jvalue* const a = new (gc_anew<jvalue>(n)) jvalue[n];
valuesToJvaluesHelper(jr, a, types, v);
return a;
}
@@ -373,79 +391,67 @@ const jvalue* valuesToJvalues(const JavaRuntime& jr, const list<value>& types, c
/**
* Convert a Java jobjectArray to a list of values.
*/
-const list<value> jarrayToValuesHelper(const JavaRuntime& jr, jobjectArray a, const int i, const int size) {
+const list<value> jarrayToValuesHelper(const JavaRuntime& jr, const jobjectArray a, const int i, const int size) {
if (i == size)
- return list<value>();
- return cons(jobjectToValue(jr, jr.env->GetObjectArrayElement(a, i)), jarrayToValuesHelper(jr, a, i + 1, size));
+ return nilListValue;
+ return cons(jobjectToValue(jr, jr.h.env->GetObjectArrayElement(a, i)), jarrayToValuesHelper(jr, a, i + 1, size));
}
-const list<value> jarrayToValues(const JavaRuntime& jr, jobjectArray o) {
+const list<value> jarrayToValues(const JavaRuntime& jr, const jobjectArray o) {
if (o == NULL)
- return list<value>();
- return jarrayToValuesHelper(jr, o, 0, jr.env->GetArrayLength(o));
+ return nilListValue;
+ return jarrayToValuesHelper(jr, o, 0, jr.h.env->GetArrayLength(o));
}
/**
* Convert a Java Iterable to a list of values.
*/
-const list<value> jiterableToValuesHelper(const JavaRuntime& jr, jobject o) {
- if ((bool)jr.env->CallStaticBooleanMethod(jr.iterableUtilClass, jr.iterableIsNil, o))
- return list<value>();
- jobject car = jr.env->CallStaticObjectMethod(jr.iterableUtilClass, jr.iterableCar, o);
- jobject cdr = jr.env->CallStaticObjectMethod(jr.iterableUtilClass, jr.iterableCdr, o);
+const list<value> jiterableToValuesHelper(const JavaRuntime& jr, const jobject o) {
+ if ((bool)jr.h.env->CallStaticBooleanMethod(jr.h.iterableUtilClass, jr.h.iterableIsNil, o))
+ return nilListValue;
+ const jobject car = jr.h.env->CallStaticObjectMethod(jr.h.iterableUtilClass, jr.h.iterableCar, o);
+ const jobject cdr = jr.h.env->CallStaticObjectMethod(jr.h.iterableUtilClass, jr.h.iterableCdr, o);
return cons(jobjectToValue(jr, car), jiterableToValuesHelper(jr, cdr));
}
-const list<value> jiterableToValues(const JavaRuntime& jr, jobject o) {
+const list<value> jiterableToValues(const JavaRuntime& jr, const jobject o) {
if (o == NULL)
- return list<value>();
+ return nilListValue;
return jiterableToValuesHelper(jr, o);
}
/**
- * Lambda function used to represent a Java callable object.
- */
-struct javaCallable {
- const JavaRuntime& jr;
- const jobject obj;
-
- javaCallable(const JavaRuntime& jr, const jobject obj) : jr(jr), obj(obj) {
- }
-
- const value operator()(const list<value>& args) const {
- jobjectArray jargs = valuesToJarray(jr, args);
- jobject result = jargs; //CallObject(func, jargs);
- return jobjectToValue(jr, result);
- }
-};
-
-/**
* Convert a Java jobject to a value.
*/
const value jobjectToValue(const JavaRuntime& jr, const jobject o) {
if (o == NULL)
- return value();
- const jclass clazz = jr.env->GetObjectClass(o);
- if ((jr.env->IsSameObject(clazz, jr.stringClass))) {
- const char* s = jr.env->GetStringUTFChars((jstring)o, NULL);
+ return nilValue;
+ const jclass clazz = jr.h.env->GetObjectClass(o);
+ if ((jr.h.env->IsSameObject(clazz, jr.h.stringClass))) {
+ const char* const s = jr.h.env->GetStringUTFChars((jstring)o, NULL);
if (*s == '\'') {
const value v(s + 1);
- jr.env->ReleaseStringUTFChars((jstring)o, s);
+ jr.h.env->ReleaseStringUTFChars((jstring)o, s);
return v;
}
const value v = string(s);
- jr.env->ReleaseStringUTFChars((jstring)o, s);
+ jr.h.env->ReleaseStringUTFChars((jstring)o, s);
return v;
}
- if (jr.env->IsSameObject(clazz, jr.booleanClass))
- return value((bool)jr.env->CallBooleanMethod(o, jr.booleanValue));
- if (jr.env->IsSameObject(clazz, jr.doubleClass))
- return value((double)jr.env->CallDoubleMethod(o, jr.doubleValue));
- if (jr.env->IsAssignableFrom(clazz, jr.iterableClass))
+ if (jr.h.env->IsSameObject(clazz, jr.h.booleanClass))
+ return value((bool)jr.h.env->CallBooleanMethod(o, jr.h.booleanValue));
+ if (jr.h.env->IsSameObject(clazz, jr.h.doubleClass))
+ return value((double)jr.h.env->CallDoubleMethod(o, jr.h.doubleValue));
+ if (jr.h.env->IsAssignableFrom(clazz, jr.h.iterableClass))
return jiterableToValues(jr, o);
- if (jr.env->IsAssignableFrom(clazz, jr.objectArrayClass))
+ if (jr.h.env->IsAssignableFrom(clazz, jr.h.objectArrayClass))
return jarrayToValues(jr, (jobjectArray)o);
- return lambda<value(const list<value>&)>(javaCallable(jr, o));
+ const lvvlambda javaCallable = [jr](const list<value>& params) -> const value {
+ jobjectArray jargs = valuesToJarray(jr, params);
+ jobject result = jargs; //CallObject(func, jargs);
+ return jobjectToValue(jr, result);
+ };
+ return value(javaCallable);
}
/**
@@ -457,33 +463,33 @@ const value parameterTypeToValue(const jobject t) {
const list<value> parameterTypesToValues(const JavaRuntime& jr, const jobjectArray t, const int i) {
if (i == 0)
- return list<value>();
- return cons<value>(parameterTypeToValue(jr.env->GetObjectArrayElement(t, i - 1)), parameterTypesToValues(jr, t, i - 1));
+ return nilListValue;
+ return cons<value>(parameterTypeToValue(jr.h.env->GetObjectArrayElement(t, i - 1)), parameterTypesToValues(jr, t, i - 1));
}
const value methodToValue(const JavaRuntime& jr, const jobject m) {
- const jobject s = jr.env->CallObjectMethod(m, jr.methodName);
- const char* c = jr.env->GetStringUTFChars((jstring)s, NULL);
+ const jobject s = jr.h.env->CallObjectMethod(m, jr.h.methodName);
+ const char* const c = jr.h.env->GetStringUTFChars((jstring)s, NULL);
const string& name = string(c);
- jr.env->ReleaseStringUTFChars((jstring)s, c);
+ jr.h.env->ReleaseStringUTFChars((jstring)s, c);
- const jmethodID mid = jr.env->FromReflectedMethod(m);
+ const jmethodID mid = jr.h.env->FromReflectedMethod(m);
- const jobjectArray t = (jobjectArray)jr.env->CallObjectMethod(m, jr.parameterTypes);
- const list<value> types = reverse(parameterTypesToValues(jr, t, jr.env->GetArrayLength(t)));
+ const jobjectArray t = (jobjectArray)jr.h.env->CallObjectMethod(m, jr.h.parameterTypes);
+ const list<value> types = reverse(parameterTypesToValues(jr, t, jr.h.env->GetArrayLength(t)));
return cons<value>(c_str(name), cons<value>((double)(long)mid, types));
}
const list<value> methodsToValues(const JavaRuntime& jr, const jobjectArray m, const int i) {
if (i == 0)
- return list<value>();
- return cons<value>(methodToValue(jr, jr.env->GetObjectArrayElement(m, i - 1)), methodsToValues(jr, m, i - 1));
+ return nilListValue;
+ return cons<value>(methodToValue(jr, jr.h.env->GetObjectArrayElement(m, i - 1)), methodsToValues(jr, m, i - 1));
}
const list<value> methodsToValues(const JavaRuntime& jr, const jclass clazz) {
- const jobjectArray m = (jobjectArray)jr.env->CallObjectMethod(clazz, jr.declaredMethods);
- return methodsToValues(jr, m, jr.env->GetArrayLength(m));
+ const jobjectArray m = (jobjectArray)jr.h.env->CallObjectMethod(clazz, jr.h.declaredMethods);
+ return methodsToValues(jr, m, jr.h.env->GetArrayLength(m));
}
/**
@@ -508,20 +514,20 @@ public:
const failable<JavaClass> readClass(const JavaRuntime& jr, const string& path, const string& name) {
// Create a class loader from the given path
- const jobject jpath = jr.env->NewStringUTF(c_str(path));
- jobject loader = jr.env->CallStaticObjectMethod(jr.loaderClass, jr.loaderValueOf, jpath);
+ const jobject jpath = jr.h.env->NewStringUTF(c_str(path));
+ const jobject loader = jr.h.env->CallStaticObjectMethod(jr.h.loaderClass, jr.h.loaderValueOf, jpath);
// Load the class
- const jobject jname = jr.env->NewStringUTF(c_str(name));
- const jclass clazz = (jclass)jr.env->CallStaticObjectMethod(jr.loaderClass, jr.loaderForName, jname, JNI_TRUE, loader);
+ const jobject jname = jr.h.env->NewStringUTF(c_str(name));
+ const jclass clazz = (jclass)jr.h.env->CallStaticObjectMethod(jr.h.loaderClass, jr.h.loaderForName, jname, JNI_TRUE, loader);
if (clazz == NULL)
return mkfailure<JavaClass>(string("Couldn't load class: ") + name + " : " + lastException(jr));
// Create an instance
- const jmethodID constr = jr.env->GetMethodID(clazz, "<init>", "()V");
+ const jmethodID constr = jr.h.env->GetMethodID(clazz, "<init>", "()V");
if (constr == NULL)
return mkfailure<JavaClass>(string("Couldn't find constructor: ") + name + " : " + lastException(jr));
- const jobject obj = jr.env->NewObject(clazz, constr);
+ const jobject obj = jr.h.env->NewObject(clazz, constr);
if (obj == NULL)
return mkfailure<JavaClass>(string("Couldn't construct object: ") + name + " : " + lastException(jr));
@@ -541,19 +547,19 @@ const failable<value> evalClass(const JavaRuntime& jr, const value& expr, const
// The start, stop, and restart functions are optional
const value fn = car<value>(expr);
if (fn == "start" || fn == "stop")
- return value(lambda<value(const list<value>&)>());
+ return value(lvvlambda());
- return mkfailure<value>(string("Couldn't find function: ") + car<value>(expr) + " : " + lastException(jr));
+ return mkfailure<value>(string("Couldn't find function: ") + (string)car<value>(expr) + " : " + lastException(jr));
}
const jmethodID fid = (jmethodID)(long)(double)cadr(func);
// Convert args to Java jvalues
- const jvalue* args = valuesToJvalues(jr, cddr(func), cdr<value>(expr));
+ const jvalue* const args = valuesToJvalues(jr, cddr(func), cdr<value>(expr));
// Call the Java function
- const jobject result = jr.env->CallObjectMethodA(jc.obj, fid, const_cast<jvalue*>(args));
+ const jobject result = jr.h.env->CallObjectMethodA(jc.obj, fid, const_cast<jvalue*>(args));
if (result == NULL)
- return mkfailure<value>(string("Function call failed: ") + car<value>(expr) + " : " + lastException(jr));
+ return mkfailure<value>(string("Function call failed: ") + (string)car<value>(expr) + " : " + lastException(jr));
// Convert Java result to a value
const value v = jobjectToValue(jr, result);
diff --git a/sca-cpp/trunk/modules/java/java-shell.cpp b/sca-cpp/trunk/modules/java/java-shell.cpp
index 51df513990..d76fa8b45b 100644
--- a/sca-cpp/trunk/modules/java/java-shell.cpp
+++ b/sca-cpp/trunk/modules/java/java-shell.cpp
@@ -29,8 +29,8 @@
#include "string.hpp"
#include "driver.hpp"
-int main(const int argc, char** argv) {
- tuscany::gc_scoped_pool pool;
+int main(const int argc, const char** const argv) {
+ const tuscany::gc_scoped_pool pool;
if (argc != 2) {
tuscany::cerr << "Usage: java-shell <class name>" << tuscany::endl;
return 1;
diff --git a/sca-cpp/trunk/modules/java/java-test.cpp b/sca-cpp/trunk/modules/java/java-test.cpp
index f811a4f58d..7ae170d03f 100644
--- a/sca-cpp/trunk/modules/java/java-test.cpp
+++ b/sca-cpp/trunk/modules/java/java-test.cpp
@@ -32,8 +32,8 @@ namespace tuscany {
namespace java {
bool testEvalExpr() {
- gc_scoped_pool pool;
- JavaRuntime javaRuntime;
+ const gc_scoped_pool pool;
+ const JavaRuntime javaRuntime;
{
const failable<JavaClass> obj = readClass(javaRuntime, ".", "test.CalcImpl");
assert(hasContent(obj));
@@ -48,7 +48,7 @@ bool testEvalExpr() {
const value exp = mklist<value>("even", 2);
const failable<value> r = evalClass(javaRuntime, exp, content(obj));
assert(hasContent(r));
- assert(content(r) == value(true));
+ assert(content(r) == trueValue);
}
{
const failable<JavaClass> obj = readClass(javaRuntime, ".", "test.AdderImpl");
@@ -77,12 +77,12 @@ const value add(const list<value>& args) {
}
bool testEvalLambda() {
- gc_scoped_pool pool;
- JavaRuntime javaRuntime;
+ const gc_scoped_pool pool;
+ const JavaRuntime javaRuntime;
{
const failable<JavaClass> obj = readClass(javaRuntime, ".", "test.CalcImpl");
assert(hasContent(obj));
- const value tcel = mklist<value>("add", 3, 4, lambda<value(const list<value>&)>(add));
+ const value tcel = mklist<value>("add", 3, 4, lvvlambda(add));
const failable<value> r = evalClass(javaRuntime, tcel, content(obj));
assert(hasContent(r));
assert(content(r) == value(7));
@@ -90,7 +90,7 @@ bool testEvalLambda() {
{
const failable<JavaClass> obj = readClass(javaRuntime, ".", "test.CalcImpl");
assert(hasContent(obj));
- const value tcel = mklist<value>("addEval", 3, 4, lambda<value(const list<value>&)>(add));
+ const value tcel = mklist<value>("addEval", 3, 4, lvvlambda(add));
const failable<value> r = evalClass(javaRuntime, tcel, content(obj));
assert(hasContent(r));
assert(content(r) == value(7));
@@ -99,26 +99,26 @@ bool testEvalLambda() {
}
bool testClassLoader() {
- gc_scoped_pool pool;
- JavaRuntime javaRuntime;
+ const gc_scoped_pool pool;
+ const JavaRuntime javaRuntime;
const failable<JavaClass> obj = readClass(javaRuntime, ".", "org.apache.tuscany.ClassLoader$Test");
assert(hasContent(obj));
const value exp = mklist<value>("testClassLoader");
const failable<value> r = evalClass(javaRuntime, exp, content(obj));
assert(hasContent(r));
- assert(content(r) == value(true));
+ assert(content(r) == trueValue);
return true;
}
bool testIterableUtil() {
- gc_scoped_pool pool;
- JavaRuntime javaRuntime;
+ const gc_scoped_pool pool;
+ const JavaRuntime javaRuntime;
const failable<JavaClass> obj = readClass(javaRuntime, ".", "org.apache.tuscany.IterableUtil$Test");
assert(hasContent(obj));
const value exp = mklist<value>("testList");
const failable<value> r = evalClass(javaRuntime, exp, content(obj));
assert(hasContent(r));
- assert(content(r) == value(true));
+ assert(content(r) == trueValue);
return true;
}
diff --git a/sca-cpp/trunk/modules/java/jni-test.cpp b/sca-cpp/trunk/modules/java/jni-test.cpp
index 727af13dc6..f69460f235 100644
--- a/sca-cpp/trunk/modules/java/jni-test.cpp
+++ b/sca-cpp/trunk/modules/java/jni-test.cpp
@@ -40,7 +40,7 @@ namespace java {
#endif
bool testJNI() {
- gc_scoped_pool pool;
+ const gc_scoped_pool pool;
JavaVM* jvm;
JNIEnv* env;
@@ -50,7 +50,7 @@ bool testJNI() {
JavaVMOption options[3];
args.options = options;
args.nOptions = 0;
- const char* envcp = getenv("CLASSPATH");
+ const char* const envcp = getenv("CLASSPATH");
const string cp = string("-Djava.class.path=") + (envcp == NULL? "." : envcp);
options[args.nOptions].optionString = const_cast<char*>(c_str(cp));
options[args.nOptions++].extraInfo = NULL;
@@ -60,9 +60,9 @@ bool testJNI() {
JNI_CreateJavaVM(&jvm, (void**)&env, &args);
#endif
- jclass classClass = env->FindClass("java/lang/Class");
+ const jclass classClass = env->FindClass("java/lang/Class");
assert(classClass != NULL);
- jclass loaderClass = env->FindClass("org/apache/tuscany/ClassLoader");
+ const jclass loaderClass = env->FindClass("org/apache/tuscany/ClassLoader");
assert(loaderClass != NULL);
return true;
}
diff --git a/sca-cpp/trunk/modules/java/mod-java.cpp b/sca-cpp/trunk/modules/java/mod-java.cpp
index d96861cc6d..61711db9f4 100644
--- a/sca-cpp/trunk/modules/java/mod-java.cpp
+++ b/sca-cpp/trunk/modules/java/mod-java.cpp
@@ -40,32 +40,25 @@ namespace modeval {
/**
* Apply a lifecycle start or restart event.
*/
-struct javaLifecycle {
- javaLifecycle(java::JavaRuntime& jr) : jr(jr) {
- }
- const value operator()(const list<value>& params) const {
- const value func = car(params);
- if (func == "javaRuntime")
- return (gc_ptr<value>)(value*)(void*)&jr;
- return lambda<value(const list<value>&)>();
- }
- java::JavaRuntime& jr;
-};
-
const value applyLifecycle(unused const list<value>& params) {
// Create a Java runtime
- java::JavaRuntime& jr = *(new (gc_new<java::JavaRuntime>()) java::JavaRuntime());
+ const java::JavaRuntime& jr = *(new (gc_new<java::JavaRuntime>()) java::JavaRuntime());
// Return the function to invoke on subsequent events
- return failable<value>(lambda<value(const list<value>&)>(javaLifecycle(jr)));
+ return failable<value>(lvvlambda([&jr](const list<value>& params) -> const value {
+ const value func = car(params);
+ if (func == "javaRuntime")
+ return (gc_ptr<value>)(value*)(void*)&jr;
+ return lvvlambda();
+ }));
}
/**
* Evaluate a Java component implementation and convert it to an applicable
* lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, const lambda<value(const list<value>&)>& lifecycle) {
+const failable<lvvlambda > evalImplementation(const string& path, const value& impl, const list<value>& px, const lvvlambda& lifecycle) {
const string itype(elementName(impl));
if (contains(itype, ".java")) {
const void* p = (gc_ptr<value>)lifecycle(mklist<value>("javaRuntime"));
@@ -74,8 +67,8 @@ const failable<lambda<value(const list<value>&)> > evalImplementation(const stri
if (contains(itype, ".cpp"))
return modcpp::evalImplementation(path, impl, px);
if (contains(itype, ".widget"))
- return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype, -1, false);
- return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype);
+ return mkfailure<lvvlambda >(string("Unsupported implementation type: ") + itype, -1, false);
+ return mkfailure<lvvlambda >(string("Unsupported implementation type: ") + itype);
}
}
diff --git a/sca-cpp/trunk/modules/java/mod-java.hpp b/sca-cpp/trunk/modules/java/mod-java.hpp
index b68f17aa3f..4dd2fe33a2 100644
--- a/sca-cpp/trunk/modules/java/mod-java.hpp
+++ b/sca-cpp/trunk/modules/java/mod-java.hpp
@@ -40,34 +40,26 @@ namespace server {
namespace modjava {
/**
- * Apply a Java component implementation function.
- */
-struct applyImplementation {
- java::JavaClass impl;
- const list<value> px;
- java::JavaRuntime& jr;
- applyImplementation(const java::JavaClass& impl, const list<value>& px, java::JavaRuntime& jr) : impl(impl), px(px), jr(jr) {
- }
- const value operator()(const list<value>& params) const {
- const value expr = append<value>(params, px);
- debug(expr, "modeval::java::applyImplementation::input");
- const failable<value> res = java::evalClass(jr, expr, impl);
- const value val = !hasContent(res)? mklist<value>(value(), reason(res), rcode(res)) : mklist<value>(content(res));
- debug(val, "modeval::java::applyImplementation::result");
- return val;
- }
-};
-
-/**
* Evaluate a Java component implementation and convert it to an applicable
* lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, java::JavaRuntime& jr) {
+const failable<lvvlambda > evalImplementation(const string& path, const value& impl, const list<value>& px, const java::JavaRuntime& jr) {
const string cn(attributeValue("class", impl));
- const failable<java::JavaClass> jc = java::readClass(jr, path, cn);
- if (!hasContent(jc))
- return mkfailure<lambda<value(const list<value>&)> >(jc);
- return lambda<value(const list<value>&)>(applyImplementation(content(jc), px, jr));
+ const failable<java::JavaClass> fjc = java::readClass(jr, path, cn);
+ if (!hasContent(fjc))
+ return mkfailure<lvvlambda >(fjc);
+
+ // Return Java component implementation lambda function
+ const java::JavaClass jc = content(fjc);
+ const lvvlambda applyImplementation = [jc, px, jr](const list<value>& params) -> const value {
+ const value expr = append<value>(params, px);
+ debug(expr, "modeval::java::applyImplementation::expr");
+ const failable<value> res = java::evalClass(jr, expr, jc);
+ const value val = !hasContent(res)? mklist<value>(nilValue, reason(res), rcode(res)) : mklist<value>(content(res));
+ debug(val, "modeval::java::applyImplementation::result");
+ return val;
+ };
+ return applyImplementation;
}
}
diff --git a/sca-cpp/trunk/modules/oauth/Makefile.am b/sca-cpp/trunk/modules/oauth/Makefile.am
index 9e8eb5a0dd..d72a584f49 100644
--- a/sca-cpp/trunk/modules/oauth/Makefile.am
+++ b/sca-cpp/trunk/modules/oauth/Makefile.am
@@ -26,12 +26,12 @@ mod_LTLIBRARIES = libmod_tuscany_oauth1.la libmod_tuscany_oauth2.la
noinst_DATA = libmod_tuscany_oauth1${libsuffix} libmod_tuscany_oauth2${libsuffix}
libmod_tuscany_oauth1_la_SOURCES = mod-oauth1.cpp
-libmod_tuscany_oauth1_la_LDFLAGS = -L${LIBOAUTH_LIB} -R${LIBOAUTH_LIB} -loauth -lxml2 -lcurl -lmozjs
+libmod_tuscany_oauth1_la_LDFLAGS = -L${LIBOAUTH_LIB} -R${LIBOAUTH_LIB} -loauth -lxml2 -lcurl -ljansson
libmod_tuscany_oauth1${libsuffix}:
ln -s .libs/libmod_tuscany_oauth1${libsuffix}
libmod_tuscany_oauth2_la_SOURCES = mod-oauth2.cpp
-libmod_tuscany_oauth2_la_LDFLAGS = -lxml2 -lcurl -lmozjs
+libmod_tuscany_oauth2_la_LDFLAGS = -lxml2 -lcurl -ljansson
libmod_tuscany_oauth2${libsuffix}:
ln -s .libs/libmod_tuscany_oauth2${libsuffix}
diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
index d2c7cf7ddd..c9d8607144 100644
--- a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
+++ b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp
@@ -56,18 +56,18 @@ namespace oauth1 {
*/
class ServerConf {
public:
- ServerConf(apr_pool_t* p, server_rec* s) : p(p), server(s) {
+ ServerConf(apr_pool_t* const p, server_rec* const s) : p(p), server(s) {
}
const gc_pool p;
- server_rec* server;
- string ca;
- string cert;
- string key;
- list<list<value> > appkeys;
- list<string> mcaddrs;
- memcache::MemCached mc;
- perthread_ptr<http::CURLSession> cs;
+ server_rec* const server;
+ gc_mutable_ref<string> ca;
+ gc_mutable_ref<string> cert;
+ gc_mutable_ref<string> key;
+ gc_mutable_ref<list<list<value> > > appkeys;
+ gc_mutable_ref<list<string> > mcaddrs;
+ gc_mutable_ref<memcache::MemCached> mc;
+ gc_mutable_ref<perthread_ptr<http::CURLSession> > cs;
};
/**
@@ -80,7 +80,7 @@ public:
AuthnProviderConf(const string name, const authn_provider* provider) : name(name), provider(provider) {
}
- string name;
+ const string name;
const authn_provider* provider;
};
@@ -89,21 +89,21 @@ public:
*/
class DirConf {
public:
- DirConf(apr_pool_t* p, char* d) : p(p), dir(d), enabled(false), login("") {
+ DirConf(apr_pool_t* const p, const char* const d) : p(p), dir(d), enabled(false), login(emptyString) {
}
const gc_pool p;
- const char* dir;
+ const char* const dir;
bool enabled;
- string login;
- list<list<value> > scopeattrs;
- list<AuthnProviderConf> apcs;
+ gc_mutable_ref<string> login;
+ gc_mutable_ref<list<list<value> > > scopeattrs;
+ gc_mutable_ref<list<AuthnProviderConf> > apcs;
};
/**
* Run the authnz hooks to authenticate a request.
*/
-const failable<int> checkAuthnzProviders(const string& user, request_rec* r, const list<AuthnProviderConf>& apcs) {
+const failable<int> checkAuthnzProviders(const string& user, request_rec* const r, const list<AuthnProviderConf>& apcs) {
if (isNil(apcs))
return mkfailure<int>("Authentication failure for: " + user, HTTP_UNAUTHORIZED);
const AuthnProviderConf apc = car<AuthnProviderConf>(apcs);
@@ -118,7 +118,7 @@ const failable<int> checkAuthnzProviders(const string& user, request_rec* r, con
return OK;
}
-const failable<int> checkAuthnz(const string& user, request_rec* r, const list<AuthnProviderConf>& apcs) {
+const failable<int> checkAuthnz(const string& user, request_rec* const r, const list<AuthnProviderConf>& apcs) {
if (substr(user, 0, 1) == "/")
return mkfailure<int>(string("Encountered FakeBasicAuth spoof: ") + user, HTTP_UNAUTHORIZED);
@@ -139,7 +139,7 @@ const failable<value> userInfo(const value& sid, const memcache::MemCached& mc)
/**
* Handle an authenticated request.
*/
-const failable<int> authenticated(const list<list<value> >& userinfo, const bool check, request_rec* r, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs) {
+const failable<int> authenticated(const list<list<value> >& userinfo, const bool check, request_rec* const r, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs) {
debug(userinfo, "modoauth2::authenticated::userinfo");
if (isNil(scopeattrs)) {
@@ -147,7 +147,7 @@ const failable<int> authenticated(const list<list<value> >& userinfo, const bool
// Store user id in an environment variable
const list<value> id = assoc<value>("id", userinfo);
if (isNil(id) || isNil(cdr(id)))
- return mkfailure<int>("Couldn't retrieve user id");
+ return mkfailure<int>("Couldn't retrieve user id", HTTP_UNAUTHORIZED);
apr_table_set(r->subprocess_env, "OAUTH2_ID", apr_pstrdup(r->pool, c_str(cadr(id))));
// If the request user field has not been mapped to another attribute, map the
@@ -157,7 +157,7 @@ const failable<int> authenticated(const list<list<value> >& userinfo, const bool
// Run the authnz hooks to check the authenticated user
if (check)
- return checkAuthnz(r->user == NULL? "" : r->user, r, apcs);
+ return checkAuthnz(r->user == NULL? emptyString : r->user, r, apcs);
return OK;
}
@@ -210,7 +210,7 @@ const string header(const string& qs, const string& redir, const string& verif)
*/
const list<string> sign(const string& verb, const string& uri, const list<value> appkey, const string& tok, const string& sec) {
char* qs = NULL;
- char* suri = oauth_sign_url2(c_str(uri), &qs, OA_HMAC, c_str(verb), c_str(car(appkey)), c_str(cadr(appkey)), length(tok) != 0? c_str(tok) : NULL, length(sec) != 0? c_str(sec) : NULL);
+ char* const suri = oauth_sign_url2(c_str(uri), &qs, OA_HMAC, c_str(verb), c_str(car(appkey)), c_str(cadr(appkey)), length(tok) != 0? c_str(tok) : NULL, length(sec) != 0? c_str(sec) : NULL);
const list<string> res = mklist<string>(suri, qs);
free(suri);
free(qs);
@@ -220,7 +220,7 @@ const list<string> sign(const string& verb, const string& uri, const list<value>
/**
* Handle an authorize request.
*/
-const failable<int> authorize(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys, const memcache::MemCached& mc) {
+const failable<int> authorize(const list<list<value> >& args, request_rec* const r, const list<list<value> >& appkeys, const memcache::MemCached& mc) {
// Extract authorize, access_token, client ID and info URIs
const list<value> ref = assoc<value>("openauth_referrer", args);
if (isNil(ref) || isNil(cdr(ref)))
@@ -249,19 +249,19 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co
// Lookup client app configuration
const list<value> app = assoc<value>(cadr(cid), appkeys);
if (isNil(app) || isNil(cdr(app)))
- return mkfailure<int>(string("client id not found: ") + cadr(cid));
+ return mkfailure<int>(string("client id not found: ") + (string)cadr(cid));
list<value> appkey = cadr(app);
// Build and sign the request token URI
const string requri = httpd::unescape(cadr(req)) + string("&") + http::queryString(mklist<list<value> >(mklist<value>("oauth_callback", httpd::escape(redir))));
- const list<string> srequri = sign("POST", requri, appkey, "", "");
+ const list<string> srequri = sign("POST", requri, appkey, emptyString, emptyString);
debug(srequri, "modoauth1::authorize::srequri");
// Put the args into an oauth header
- const string reqhdr = header(cadr(srequri), redir, "");
+ const string reqhdr = header(cadr(srequri), redir, emptyString);
// Send the request token request
- char* pres = oauth_http_post2(c_str(car(srequri)), "", c_str(reqhdr));
+ char* const pres = oauth_http_post2(c_str(car(srequri)), "", c_str(reqhdr));
if (pres == NULL)
return mkfailure<int>("Couldn't send request token request");
const string res(pres);
@@ -297,11 +297,10 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co
* User profile parsing needs to be made configurable.
*/
const failable<list<value> > profileUserInfo(const value& cid, const string& info) {
- string b = substr(info, 0, 1);
+ const string b = substr(info, 0, 1);
if (b == "[") {
// Twitter JSON profile
- js::JSContext cx;
- const list<value> infov(json::jsonValues(content(json::readJSON(mklist<string>(info), cx))));
+ const list<value> infov(content(json::readValue(mklist<string>(info))));
if (isNil(infov))
return mkfailure<list<value> >("Couldn't retrieve user info");
debug(infov, "modoauth1::access_token::info");
@@ -314,8 +313,7 @@ const failable<list<value> > profileUserInfo(const value& cid, const string& inf
}
if (b == "{") {
// Foursquare JSON profile
- js::JSContext cx;
- const list<value> infov(json::jsonValues(content(json::readJSON(mklist<string>(info), cx))));
+ const list<value> infov(content(json::readValue(mklist<string>(info))));
if (isNil(infov))
return mkfailure<list<value> >("Couldn't retrieve user info");
debug(infov, "modoauth1::access_token::info");
@@ -328,7 +326,7 @@ const failable<list<value> > profileUserInfo(const value& cid, const string& inf
}
if (b == "<") {
// XML profile
- const list<value> infov = elementsToValues(readXML(mklist<string>(info)));
+ const list<value> infov = elementsToValues(content(xml::readElements(mklist<string>(info))));
if (isNil(infov))
return mkfailure<list<value> >("Couldn't retrieve user info");
debug(infov, "modoauth1::access_token::info");
@@ -370,8 +368,8 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r,
// Lookup client app configuration
const list<value> app = assoc<value>(cadr(cid), appkeys);
if (isNil(app) || isNil(cdr(app)))
- return mkfailure<int>(string("client id not found: ") + cadr(cid));
- list<value> appkey = cadr(app);
+ return mkfailure<int>(string("client id not found: ") + (string)cadr(cid));
+ const list<value> appkey = cadr(app);
// Retrieve the request token from memcached
const failable<value> sv = memcache::get(mklist<value>("tuscanyOAuth1Token", cadr(tv)), mc);
@@ -384,10 +382,10 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r,
debug(stokuri, "modoauth1::access_token::stokuri");
// Put the args into an oauth header
- string tokhdr = header(cadr(stokuri), "", cadr(vv));
+ string tokhdr = header(cadr(stokuri), emptyString, cadr(vv));
// Send the access token request
- char* ptokres = oauth_http_post2(c_str(car(stokuri)), "", c_str(tokhdr));
+ char* const ptokres = oauth_http_post2(c_str(car(stokuri)), "", c_str(tokhdr));
if (ptokres == NULL)
return mkfailure<int>("Couldn't post access_token request");
const string tokres(ptokres);
@@ -410,10 +408,10 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r,
debug(sprofuri, "modoauth1::access_token::sprofuri");
// Put the args into an oauth header
- string profhdr = header(cadr(sprofuri), "", "");
+ const string profhdr = header(cadr(sprofuri), emptyString, emptyString);
// Send the user profile request
- char* pprofres = oauth_http_get2(c_str(car(sprofuri)), NULL, c_str(profhdr));
+ char* const pprofres = oauth_http_get2(c_str(car(sprofuri)), NULL, c_str(profhdr));
if (pprofres == NULL)
return mkfailure<int>("Couldn't get user info");
const string profres(pprofres);
@@ -431,7 +429,7 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r,
return authrc;
// Store user info in memcached keyed by session ID
- const value sid = string("OAuth1_") + mkrand();
+ const value sid = string("OAuth1_") + (string)mkrand();
const failable<bool> prc = memcache::put(mklist<value>("tuscanyOAuth1", sid), content(userinfo), mc);
if (!hasContent(prc))
return mkfailure<int>(prc);
@@ -446,17 +444,17 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r,
* Check user authentication.
*/
static int checkAuthn(request_rec *r) {
- gc_scoped_pool pool(r->pool);
+ const gc_scoped_pool sp(r->pool);
// Decline if we're not enabled or AuthType is not set to Open
const DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_oauth1);
if (!dc.enabled)
return DECLINED;
- const char* atype = ap_auth_type(r);
+ const char* const atype = ap_auth_type(r);
if (atype == NULL || strcasecmp(atype, "Open"))
return DECLINED;
debug_httpdRequest(r, "modoauth1::checkAuthn::input");
- debug(atype, "modopenauth::checkAuthn::auth_type");
+ debug(atype, "modoauth1::checkAuthn::auth_type");
// Get the server configuration
const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_oauth1);
@@ -471,9 +469,9 @@ static int checkAuthn(request_rec *r) {
// Extract the user info from the auth session
const failable<value> userinfo = userInfo(content(sid), sc.mc);
if (!hasContent(userinfo))
- return httpd::reportStatus(mkfailure<int>(userinfo));
+ return openauth::reportStatus(mkfailure<int>(reason(userinfo), HTTP_UNAUTHORIZED), dc.login, nilValue, r);
r->ap_auth_type = const_cast<char*>(atype);
- return httpd::reportStatus(authenticated(content(userinfo), false, r, dc.scopeattrs, dc.apcs));
+ return openauth::reportStatus(authenticated(content(userinfo), false, r, dc.scopeattrs, dc.apcs), dc.login, nilValue, r);
}
// Get the request args
@@ -482,19 +480,14 @@ static int checkAuthn(request_rec *r) {
// Handle OAuth authorize request step
if (string(r->uri) == "/oauth1/authorize/") {
r->ap_auth_type = const_cast<char*>(atype);
- return httpd::reportStatus(authorize(args, r, sc.appkeys, sc.mc));
+ return openauth::reportStatus(authorize(args, r, sc.appkeys, sc.mc), dc.login, 1, r);
}
// Handle OAuth access_token request step
if (string(r->uri) == "/oauth1/access_token/") {
r->ap_auth_type = const_cast<char*>(atype);
const failable<int> authrc = accessToken(args, r, sc.appkeys, dc.scopeattrs, dc.apcs, sc.mc);
-
- // Redirect to the login page if user is not authorized
- if (!hasContent(authrc) && rcode(authrc) == HTTP_UNAUTHORIZED)
- return httpd::reportStatus(openauth::login(dc.login, string("/"), 1, r));
-
- return httpd::reportStatus(authrc);
+ return openauth::reportStatus(authrc, dc.login, 1, r);
}
// Redirect to the login page, unless we have a session id or an authorization
@@ -509,22 +502,22 @@ static int checkAuthn(request_rec *r) {
return DECLINED;
r->ap_auth_type = const_cast<char*>(atype);
- return httpd::reportStatus(openauth::login(dc.login, value(), value(), r));
+ return httpd::reportStatus(openauth::login(dc.login, nilValue, nilValue, r));
}
/**
* Process the module configuration.
*/
-int postConfigMerge(ServerConf& mainsc, server_rec* s) {
+int postConfigMerge(const ServerConf& mainsc, server_rec* const s) {
if (s == NULL)
return OK;
ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth1);
debug(httpd::serverName(s), "modoauth1::postConfigMerge::serverName");
// Merge configuration from main server
- if (isNil(sc.appkeys))
+ if (isNil((list<list<value> >)sc.appkeys))
sc.appkeys = mainsc.appkeys;
- if (isNil(sc.mcaddrs))
+ if (isNil((list<string>)sc.mcaddrs))
sc.mcaddrs = mainsc.mcaddrs;
sc.mc = mainsc.mc;
sc.cs = mainsc.cs;
@@ -532,10 +525,10 @@ int postConfigMerge(ServerConf& mainsc, server_rec* s) {
return postConfigMerge(mainsc, s->next);
}
-int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp, server_rec* s) {
- gc_scoped_pool pool(p);
+int postConfig(apr_pool_t* const p, unused apr_pool_t* const plog, unused apr_pool_t* const ptemp, server_rec* const s) {
+ const gc_scoped_pool sp(p);
- ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth1);
+ const ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth1);
debug(httpd::serverName(s), "modoauth1::postConfig::serverName");
// Merge server configurations
@@ -543,30 +536,12 @@ int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp,
}
/**
- * Lambda function that creates a new CURL session.
- */
-class newsession {
-public:
- newsession(const string& ca, const string& cert, const string& key) : ca(ca), cert(cert), key(key) {
- }
-
- const gc_ptr<http::CURLSession> operator()() const {
- return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, key, "", 0);
- }
-
-private:
- const string ca;
- const string cert;
- const string key;
-};
-
-/**
* Child process initialization.
*/
-void childInit(apr_pool_t* p, server_rec* s) {
- gc_scoped_pool pool(p);
+void childInit(apr_pool_t* const p, server_rec* const s) {
+ const gc_scoped_pool sp(p);
- ServerConf* psc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_oauth1);
+ ServerConf* const psc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_oauth1);
if(psc == NULL) {
cfailure << "[Tuscany] Due to one or more errors mod_tuscany_oauth1 loading failed. Causing apache to stop loading." << endl;
exit(APEXIT_CHILDFATAL);
@@ -574,13 +549,21 @@ void childInit(apr_pool_t* p, server_rec* s) {
ServerConf& sc = *psc;
// Connect to Memcached
- if (isNil(sc.mcaddrs))
+ if (isNil((list<string>)sc.mcaddrs))
sc.mc = *(new (gc_new<memcache::MemCached>()) memcache::MemCached("localhost", 11211));
else
sc.mc = *(new (gc_new<memcache::MemCached>()) memcache::MemCached(sc.mcaddrs));
// Setup a CURL session
- sc.cs = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(sc.ca, sc.cert, sc.key)));
+ const string ca(sc.ca);
+ const string cert(sc.cert);
+ const string key(sc.key);
+ const gc_pool cp(gc_current_pool());
+ const lambda<const gc_ptr<http::CURLSession>()> newsession = [ca, cert, key, cp]() -> const gc_ptr<http::CURLSession> {
+ const gc_scoped_pool sp(pool(cp));
+ return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, key, emptyString, 0);
+ };
+ sc.cs = *(new (gc_new<perthread_ptr<http::CURLSession> >()) perthread_ptr<http::CURLSession>(newsession));
// Merge the updated configuration into the virtual hosts
postConfigMerge(sc, s->next);
@@ -589,56 +572,56 @@ void childInit(apr_pool_t* p, server_rec* s) {
/**
* Configuration commands.
*/
-const char* confAppKey(cmd_parms *cmd, unused void *c, const char *arg1, const char* arg2, const char* arg3) {
- gc_scoped_pool pool(cmd->pool);
+char* const confAppKey(cmd_parms* cmd, unused void *c, char *arg1, char* arg2, char* arg3) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth1);
- sc.appkeys = cons<list<value> >(mklist<value>(arg1, mklist<value>(arg2, arg3)), sc.appkeys);
+ sc.appkeys = cons<list<value> >(mklist<value>(arg1, mklist<value>(arg2, arg3)), (list<list<value> >)sc.appkeys);
return NULL;
}
-const char* confMemcached(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confMemcached(cmd_parms *cmd, unused void *c, char *arg) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth1);
- sc.mcaddrs = cons<string>(arg, sc.mcaddrs);
+ sc.mcaddrs = cons<string>(arg, (list<string>)sc.mcaddrs);
return NULL;
}
-const char* confEnabled(cmd_parms *cmd, void *c, const int arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confEnabled(cmd_parms *cmd, void *c, int arg) {
+ const gc_scoped_pool sp(cmd->pool);
DirConf& dc = httpd::dirConf<DirConf>(c);
dc.enabled = (bool)arg;
return NULL;
}
-const char* confLogin(cmd_parms *cmd, void *c, const char* arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confLogin(cmd_parms *cmd, void *c, char* arg) {
+ const gc_scoped_pool sp(cmd->pool);
DirConf& dc = httpd::dirConf<DirConf>(c);
dc.login = arg;
return NULL;
}
-const char* confCAFile(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confCAFile(cmd_parms *cmd, unused void *c, char *arg) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth1);
sc.ca = arg;
return NULL;
}
-const char* confCertFile(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confCertFile(cmd_parms *cmd, unused void *c, char *arg) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth1);
sc.cert = arg;
return NULL;
}
-const char* confCertKeyFile(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confCertKeyFile(cmd_parms *cmd, unused void *c, char *arg) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth1);
sc.key = arg;
return NULL;
}
-const char* confScopeAttr(cmd_parms *cmd, void* c, const char* arg1, const char* arg2) {
- gc_scoped_pool pool(cmd->pool);
+char* confScopeAttr(cmd_parms *cmd, void* c, char* arg1, char* arg2) {
+ const gc_scoped_pool sp(cmd->pool);
DirConf& dc = httpd::dirConf<DirConf>(c);
- dc.scopeattrs = cons<list<value> >(mklist<value>(arg1, arg2), dc.scopeattrs);
+ dc.scopeattrs = cons<list<value> >(mklist<value>(arg1, arg2), (list<list<value> >)dc.scopeattrs);
return NULL;
}
-const char* confAuthnProvider(cmd_parms *cmd, void *c, const char* arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confAuthnProvider(cmd_parms *cmd, void *c, char* arg) {
+ const gc_scoped_pool sp(cmd->pool);
DirConf& dc = httpd::dirConf<DirConf>(c);
// Lookup and cache the Authn provider
diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
index e384a0e742..bedf83325f 100644
--- a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
+++ b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp
@@ -50,18 +50,18 @@ namespace oauth2 {
*/
class ServerConf {
public:
- ServerConf(apr_pool_t* p, server_rec* s) : p(p), server(s) {
+ ServerConf(apr_pool_t* const p, server_rec* const s) : p(p), server(s) {
}
const gc_pool p;
- server_rec* server;
- string ca;
- string cert;
- string key;
- list<list<value> > appkeys;
- list<string> mcaddrs;
- memcache::MemCached mc;
- perthread_ptr<http::CURLSession> cs;
+ server_rec* const server;
+ gc_mutable_ref<string> ca;
+ gc_mutable_ref<string> cert;
+ gc_mutable_ref<string> key;
+ gc_mutable_ref<list<list<value> > > appkeys;
+ gc_mutable_ref<list<string> > mcaddrs;
+ gc_mutable_ref<memcache::MemCached> mc;
+ gc_mutable_ref<perthread_ptr<http::CURLSession> > cs;
};
/**
@@ -74,7 +74,7 @@ public:
AuthnProviderConf(const string name, const authn_provider* provider) : name(name), provider(provider) {
}
- string name;
+ const string name;
const authn_provider* provider;
};
@@ -83,21 +83,21 @@ public:
*/
class DirConf {
public:
- DirConf(apr_pool_t* p, char* d) : p(p), dir(d), enabled(false), login("") {
+ DirConf(apr_pool_t* const p, const char* const d) : p(p), dir(d), enabled(false), login(emptyString) {
}
const gc_pool p;
- const char* dir;
+ const char* const dir;
bool enabled;
- string login;
- list<list<value> > scopeattrs;
- list<AuthnProviderConf> apcs;
+ gc_mutable_ref<string> login;
+ gc_mutable_ref<list<list<value> > > scopeattrs;
+ gc_mutable_ref<list<AuthnProviderConf> > apcs;
};
/**
* Run the authnz hooks to authenticate a request.
*/
-const failable<int> checkAuthnzProviders(const string& user, request_rec* r, const list<AuthnProviderConf>& apcs) {
+const failable<int> checkAuthnzProviders(const string& user, request_rec* const r, const list<AuthnProviderConf>& apcs) {
if (isNil(apcs))
return mkfailure<int>("Authentication failure for: " + user, HTTP_UNAUTHORIZED);
const AuthnProviderConf apc = car<AuthnProviderConf>(apcs);
@@ -112,7 +112,7 @@ const failable<int> checkAuthnzProviders(const string& user, request_rec* r, con
return OK;
}
-const failable<int> checkAuthnz(const string& user, request_rec* r, const list<AuthnProviderConf>& apcs) {
+const failable<int> checkAuthnz(const string& user, request_rec* const r, const list<AuthnProviderConf>& apcs) {
if (substr(user, 0, 1) == "/")
return mkfailure<int>(string("Encountered FakeBasicAuth spoof: ") + user, HTTP_UNAUTHORIZED);
@@ -133,7 +133,7 @@ const failable<value> userInfo(const value& sid, const memcache::MemCached& mc)
/**
* Handle an authenticated request.
*/
-const failable<int> authenticated(const list<list<value> >& userinfo, const bool check, request_rec* r, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs) {
+const failable<int> authenticated(const list<list<value> >& userinfo, const bool check, request_rec* const r, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs) {
debug(userinfo, "modoauth2::authenticated::userinfo");
if (isNil(scopeattrs)) {
@@ -141,7 +141,7 @@ const failable<int> authenticated(const list<list<value> >& userinfo, const bool
// Store user id in an environment variable
const list<value> id = assoc<value>("id", userinfo);
if (isNil(id) || isNil(cdr(id)))
- return mkfailure<int>("Couldn't retrieve user id");
+ return mkfailure<int>("Couldn't retrieve user id", HTTP_UNAUTHORIZED);
apr_table_set(r->subprocess_env, "OAUTH2_ID", apr_pstrdup(r->pool, c_str(cadr(id))));
// If the request user field has not been mapped to another attribute, map the
@@ -151,7 +151,7 @@ const failable<int> authenticated(const list<list<value> >& userinfo, const bool
// Run the authnz hooks to check the authenticated user
if (check)
- return checkAuthnz(r->user == NULL? "" : r->user, r, apcs);
+ return checkAuthnz(r->user == NULL? emptyString : r->user, r, apcs);
return OK;
}
@@ -172,7 +172,7 @@ const failable<int> authenticated(const list<list<value> >& userinfo, const bool
/**
* Handle an authorize request.
*/
-const failable<int> authorize(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys) {
+const failable<int> authorize(const list<list<value> >& args, request_rec* const r, const list<list<value> >& appkeys) {
// Extract authorize, access_token, client ID and info URIs
const list<value> ref = assoc<value>("openauth_referrer", args);
if (isNil(ref) || isNil(cdr(ref)))
@@ -206,11 +206,11 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co
// Lookup client app configuration
const list<value> app = assoc<value>(cadr(cid), appkeys);
if (isNil(app) || isNil(cdr(app)))
- return mkfailure<int>(string("client id not found: ") + cadr(cid));
+ return mkfailure<int>(string("client id not found: ") + (string)cadr(cid));
list<value> appkey = cadr(app);
// Redirect to the authorize URI
- const list<value> adisplay = (isNil(display) || isNil(cdr(display)))? list<value>() : mklist<value>("display", cadr(display));
+ const list<value> adisplay = (isNil(display) || isNil(cdr(display)))? nilListValue : mklist<value>("display", cadr(display));
const list<list<value> > aargs = mklist<list<value> >(mklist<value>("response_type", "code"), mklist<value>("client_id", car(appkey)), mklist<value>("scope", cadr(scope)), adisplay, mklist<value>("redirect_uri", httpd::escape(redir)), mklist<value>("state", httpd::escape(state)));
const string uri = httpd::unescape(cadr(auth)) + string("?") + http::queryString(aargs);
debug(uri, "modoauth2::authorize::uri");
@@ -229,7 +229,7 @@ const failable<list<value> > profileUserInfo(const value& cid, const list<value>
/**
* Handle an access_token request.
*/
-const failable<int> accessToken(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys, const perthread_ptr<http::CURLSession>& cs, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs, const memcache::MemCached& mc) {
+const failable<int> accessToken(const list<list<value> >& args, request_rec* r, const list<list<value> >& appkeys, const http::CURLSession& cs, const list<list<value> >& scopeattrs, const list<AuthnProviderConf>& apcs, const memcache::MemCached& mc) {
// Extract access_token URI, client ID and authorization code parameters
const list<value> state = assoc<value>("state", args);
@@ -255,7 +255,7 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r,
// Lookup client app configuration
const list<value> app = assoc<value>(cadr(cid), appkeys);
if (isNil(app) || isNil(cdr(app)))
- return mkfailure<int>(string("client id not found: ") + cadr(cid));
+ return mkfailure<int>(string("client id not found: ") + (string)cadr(cid));
list<value> appkey = cadr(app);
// Build the redirect URI
@@ -269,7 +269,7 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r,
const string turi = httpd::unescape(cadr(tok));
debug(turi, "modoauth2::access_token::tokenuri");
const value tval = mklist<value>(string("application/x-www-form-urlencoded;charset=UTF-8"), mklist<value>(tqs));
- const failable<value> ftr = http::post(tval, turi, *(cs));
+ const failable<value> ftr = http::post(tval, turi, cs);
if (!hasContent(ftr))
return mkfailure<int>(ftr);
const value tr = content(ftr);
@@ -288,7 +288,7 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r,
const list<list<value> > iargs = mklist<list<value> >(tv);
const string iuri = httpd::unescape(cadr(info)) + string("?") + http::queryString(iargs);
debug(iuri, "modoauth2::access_token::infouri");
- const failable<value> profres = http::get(iuri, *(cs));
+ const failable<value> profres = http::get(iuri, cs);
if (!hasContent(profres))
return mkfailure<int>("Couldn't retrieve user info");
debug(content(profres), "modoauth2::access_token::info");
@@ -304,7 +304,7 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r,
return authrc;
// Store user info in memcached keyed by a session ID
- const value sid = string("OAuth2_") + mkrand();
+ const value sid = string("OAuth2_") + (string)mkrand();
const failable<bool> prc = memcache::put(mklist<value>("tuscanyOAuth2", sid), content(userinfo), mc);
if (!hasContent(prc))
return mkfailure<int>(prc);
@@ -319,7 +319,7 @@ const failable<int> accessToken(const list<list<value> >& args, request_rec* r,
* Check user authentication.
*/
static int checkAuthn(request_rec *r) {
- gc_scoped_pool pool(r->pool);
+ const gc_scoped_pool sp(r->pool);
// Decline if we're not enabled or AuthType is not set to Open
const DirConf& dc = httpd::dirConf<DirConf>(r, &mod_tuscany_oauth2);
@@ -329,7 +329,7 @@ static int checkAuthn(request_rec *r) {
if (atype == NULL || strcasecmp(atype, "Open"))
return DECLINED;
debug_httpdRequest(r, "modoauth2::checkAuthn::input");
- debug(atype, "modopenauth::checkAuthn::auth_type");
+ debug(atype, "modoauth2::checkAuthn::auth_type");
// Get the server configuration
const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_oauth2);
@@ -344,9 +344,9 @@ static int checkAuthn(request_rec *r) {
// Extract the user info from the auth session
const failable<value> userinfo = userInfo(content(sid), sc.mc);
if (!hasContent(userinfo))
- return httpd::reportStatus(mkfailure<int>(userinfo));
+ return openauth::reportStatus(mkfailure<int>(reason(userinfo), HTTP_UNAUTHORIZED), dc.login, nilValue, r);
r->ap_auth_type = const_cast<char*>(atype);
- return httpd::reportStatus(authenticated(content(userinfo), false, r, dc.scopeattrs, dc.apcs));
+ return openauth::reportStatus(authenticated(content(userinfo), false, r, dc.scopeattrs, dc.apcs), dc.login, nilValue, r);
}
// Get the request args
@@ -355,19 +355,14 @@ static int checkAuthn(request_rec *r) {
// Handle OAuth authorize request step
if (string(r->uri) == "/oauth2/authorize/") {
r->ap_auth_type = const_cast<char*>(atype);
- return httpd::reportStatus(authorize(args, r, sc.appkeys));
+ return openauth::reportStatus(authorize(args, r, sc.appkeys), dc.login, 1, r);
}
// Handle OAuth access_token request step
if (string(r->uri) == "/oauth2/access_token/") {
r->ap_auth_type = const_cast<char*>(atype);
- const failable<int> authrc = accessToken(args, r, sc.appkeys, sc.cs, dc.scopeattrs, dc.apcs, sc.mc);
-
- // Redirect to the login page if user is not authorized
- if (!hasContent(authrc) && rcode(authrc) == HTTP_UNAUTHORIZED)
- return httpd::reportStatus(openauth::login(dc.login, string("/"), 1, r));
-
- return httpd::reportStatus(authrc);
+ const failable<int> authrc = accessToken(args, r, sc.appkeys, *(*(perthread_ptr<http::CURLSession>*)sc.cs), dc.scopeattrs, dc.apcs, sc.mc);
+ return openauth::reportStatus(authrc, dc.login, 1, r);
}
// Redirect to the login page, unless we have a session id or an authorization
@@ -382,22 +377,22 @@ static int checkAuthn(request_rec *r) {
return DECLINED;
r->ap_auth_type = const_cast<char*>(atype);
- return httpd::reportStatus(openauth::login(dc.login, value(), value(), r));
+ return httpd::reportStatus(openauth::login(dc.login, nilValue, nilValue, r));
}
/**
* Process the module configuration.
*/
-int postConfigMerge(ServerConf& mainsc, server_rec* s) {
+int postConfigMerge(const ServerConf& mainsc, server_rec* const s) {
if (s == NULL)
return OK;
ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth2);
debug(httpd::serverName(s), "modoauth2::postConfigMerge::serverName");
// Merge configuration from main server
- if (isNil(sc.appkeys))
+ if (isNil((list<list<value> >)sc.appkeys))
sc.appkeys = mainsc.appkeys;
- if (isNil(sc.mcaddrs))
+ if (isNil((list<string>)sc.mcaddrs))
sc.mcaddrs = mainsc.mcaddrs;
sc.mc = mainsc.mc;
sc.cs = mainsc.cs;
@@ -405,10 +400,10 @@ int postConfigMerge(ServerConf& mainsc, server_rec* s) {
return postConfigMerge(mainsc, s->next);
}
-int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp, server_rec* s) {
- gc_scoped_pool pool(p);
+int postConfig(apr_pool_t* const p, unused apr_pool_t* const plog, unused apr_pool_t* const ptemp, server_rec* const s) {
+ const gc_scoped_pool sp(p);
- ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth2);
+ const ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_oauth2);
debug(httpd::serverName(s), "modoauth2::postConfig::serverName");
// Merge server configurations
@@ -416,30 +411,12 @@ int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp,
}
/**
- * Lambda function that creates a new CURL session.
- */
-class newsession {
-public:
- newsession(const string& ca, const string& cert, const string& key) : ca(ca), cert(cert), key(key) {
- }
-
- const gc_ptr<http::CURLSession> operator()() const {
- return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, key, "", 0);
- }
-
-private:
- const string ca;
- const string cert;
- const string key;
-};
-
-/**
* Child process initialization.
*/
-void childInit(apr_pool_t* p, server_rec* s) {
- gc_scoped_pool pool(p);
+void childInit(apr_pool_t* const p, server_rec* const s) {
+ const gc_scoped_pool sp(p);
- ServerConf* psc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_oauth2);
+ ServerConf* const psc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_oauth2);
if(psc == NULL) {
cfailure << "[Tuscany] Due to one or more errors mod_tuscany_oauth2 loading failed. Causing apache to stop loading." << endl;
exit(APEXIT_CHILDFATAL);
@@ -447,13 +424,21 @@ void childInit(apr_pool_t* p, server_rec* s) {
ServerConf& sc = *psc;
// Connect to Memcached
- if (isNil(sc.mcaddrs))
+ if (isNil((list<string>)sc.mcaddrs))
sc.mc = *(new (gc_new<memcache::MemCached>()) memcache::MemCached("localhost", 11211));
else
sc.mc = *(new (gc_new<memcache::MemCached>()) memcache::MemCached(sc.mcaddrs));
// Setup a CURL session
- sc.cs = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(sc.ca, sc.cert, sc.key)));
+ const string ca = sc.ca;
+ const string cert = sc.cert;
+ const string key = sc.key;
+ const gc_pool cp = gc_current_pool();
+ const lambda<const gc_ptr<http::CURLSession>()> newsession = [ca, cert, key, cp]() -> const gc_ptr<http::CURLSession> {
+ const gc_scoped_pool sp(pool(cp));
+ return new (gc_new<http::CURLSession>()) http::CURLSession(ca, cert, key, emptyString, 0);
+ };
+ sc.cs = *(new (gc_new<perthread_ptr<http::CURLSession> >()) perthread_ptr<http::CURLSession>(newsession));
// Merge the updated configuration into the virtual hosts
postConfigMerge(sc, s->next);
@@ -462,56 +447,56 @@ void childInit(apr_pool_t* p, server_rec* s) {
/**
* Configuration commands.
*/
-const char* confAppKey(cmd_parms *cmd, unused void *c, const char *arg1, const char* arg2, const char* arg3) {
- gc_scoped_pool pool(cmd->pool);
+char* confAppKey(cmd_parms *cmd, unused void *c, char *arg1, char* arg2, char* arg3) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth2);
- sc.appkeys = cons<list<value> >(mklist<value>(arg1, mklist<value>(arg2, arg3)), sc.appkeys);
+ sc.appkeys = cons<list<value> >(mklist<value>(arg1, mklist<value>(arg2, arg3)), (list<list<value> >)sc.appkeys);
return NULL;
}
-const char* confMemcached(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confMemcached(cmd_parms *cmd, unused void *c, char *arg) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth2);
- sc.mcaddrs = cons<string>(arg, sc.mcaddrs);
+ sc.mcaddrs = cons<string>(arg, (list<string>)sc.mcaddrs);
return NULL;
}
-const char* confEnabled(cmd_parms *cmd, void *c, const int arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confEnabled(cmd_parms *cmd, void *c, int arg) {
+ const gc_scoped_pool sp(cmd->pool);
DirConf& dc = httpd::dirConf<DirConf>(c);
dc.enabled = (bool)arg;
return NULL;
}
-const char* confLogin(cmd_parms *cmd, void *c, const char* arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confLogin(cmd_parms *cmd, void *c, char* arg) {
+ const gc_scoped_pool sp(cmd->pool);
DirConf& dc = httpd::dirConf<DirConf>(c);
dc.login = arg;
return NULL;
}
-const char* confCAFile(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confCAFile(cmd_parms *cmd, unused void *c, char *arg) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth2);
sc.ca = arg;
return NULL;
}
-const char* confCertFile(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confCertFile(cmd_parms *cmd, unused void *c, char *arg) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth2);
sc.cert = arg;
return NULL;
}
-const char* confCertKeyFile(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confCertKeyFile(cmd_parms *cmd, unused void *c, char *arg) {
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_oauth2);
sc.key = arg;
return NULL;
}
-const char* confScopeAttr(cmd_parms *cmd, void* c, const char* arg1, const char* arg2) {
- gc_scoped_pool pool(cmd->pool);
+char* confScopeAttr(cmd_parms *cmd, void* c, char* arg1, char* arg2) {
+ const gc_scoped_pool sp(cmd->pool);
DirConf& dc = httpd::dirConf<DirConf>(c);
- dc.scopeattrs = cons<list<value> >(mklist<value>(arg1, arg2), dc.scopeattrs);
+ dc.scopeattrs = cons<list<value> >(mklist<value>(arg1, arg2), (list<list<value> >)dc.scopeattrs);
return NULL;
}
-const char* confAuthnProvider(cmd_parms *cmd, void *c, const char* arg) {
- gc_scoped_pool pool(cmd->pool);
+char* confAuthnProvider(cmd_parms *cmd, void *c, char* arg) {
+ const gc_scoped_pool sp(cmd->pool);
DirConf& dc = httpd::dirConf<DirConf>(c);
// Lookup and cache the Authn provider
diff --git a/sca-cpp/trunk/modules/opencl/Makefile.am b/sca-cpp/trunk/modules/opencl/Makefile.am
index 3e76a435c8..92da55b307 100644
--- a/sca-cpp/trunk/modules/opencl/Makefile.am
+++ b/sca-cpp/trunk/modules/opencl/Makefile.am
@@ -36,7 +36,7 @@ endif
#mod_LTLIBRARIES = libmod_tuscany_opencl.la
#libmod_tuscany_opencl_la_SOURCES = mod-opencl.cpp
-#libmod_tuscany_opencl_la_LDFLAGS = -lxml2 -lcurl -lmozjs -framework OpenCL
+#libmod_tuscany_opencl_la_LDFLAGS = -lxml2 -lcurl -ljansson -framework OpenCL
#noinst_DATA = libmod_tuscany_opencl${libsuffix}
#libmod_tuscany_opencl${libsuffix}:
# ln -s .libs/libmod_tuscany_opencl${libsuffix}
@@ -48,7 +48,7 @@ opencl_shell_SOURCES = opencl-shell.cpp
opencl_shell_LDFLAGS = ${OPENCL_FLAGS}
client_test_SOURCES = client-test.cpp
-client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+client_test_LDFLAGS = -lxml2 -lcurl -ljansson
dist_noinst_SCRIPTS = server-test
noinst_PROGRAMS = opencl-test client-test
diff --git a/sca-cpp/trunk/modules/opencl/driver.hpp b/sca-cpp/trunk/modules/opencl/driver.hpp
index b4b6c2845b..c45bcf6ee4 100644
--- a/sca-cpp/trunk/modules/opencl/driver.hpp
+++ b/sca-cpp/trunk/modules/opencl/driver.hpp
@@ -37,7 +37,7 @@ namespace opencl {
const value evalDriverLoop(const OpenCLProgram& clprog, istream& in, ostream& out, const OpenCLContext& cl) {
scheme::promptForInput(scheme::evalInputPrompt, out);
- value input = scheme::readValue(in);
+ const value input = content(scheme::readValue(in));
if (isNil(input))
return input;
const failable<value> output = evalKernel(createKernel(input, clprog), input, 1, value::String, 512, cl);
diff --git a/sca-cpp/trunk/modules/opencl/eval.hpp b/sca-cpp/trunk/modules/opencl/eval.hpp
index 5606b2f57a..f842ba783d 100644
--- a/sca-cpp/trunk/modules/opencl/eval.hpp
+++ b/sca-cpp/trunk/modules/opencl/eval.hpp
@@ -61,7 +61,7 @@ cl_ulong evaltime = 0;
/**
* Reset the OpenCL profiling counters.
*/
-bool resetOpenCLCounters() {
+const bool resetOpenCLCounters() {
memtime = kernelqtime = kerneltime = preptime = evaltime = 0;
return true;
}
@@ -69,7 +69,7 @@ bool resetOpenCLCounters() {
/**
* Print the OpenCL profiling counters.
*/
-bool printOpenCLCounters(const long n) {
+const bool printOpenCLCounters(const long n) {
cout << " kernelq " << ((double)kernelqtime / 1000000.0) / (double)n << " ms kernel " << ((double)kerneltime / 1000000.0) / (double)n << " ms memory " << ((double)memtime / 1000000.0) / (double)n << " ms prep " << ((double)preptime / 1000000.0) / (double)n << " ms eval " << ((double)evaltime / 1000000.0) / (double)n << " ms";
return true;
}
@@ -77,7 +77,7 @@ bool printOpenCLCounters(const long n) {
/**
* Profile a memory event.
*/
-failable<cl_ulong> profileMemEvent(const cl_event evt) {
+const failable<cl_ulong> profileMemEvent(const cl_event evt) {
cl_ulong start = 0;
const cl_int serr = clGetEventProfilingInfo(evt, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &start, NULL);
if (serr != CL_SUCCESS)
@@ -94,7 +94,7 @@ failable<cl_ulong> profileMemEvent(const cl_event evt) {
/**
* Profile a kernel event.
*/
-failable<cl_ulong> profileKernelEvent(const cl_event evt) {
+const failable<cl_ulong> profileKernelEvent(const cl_event evt) {
cl_ulong queued = 0;
const cl_int qerr = clGetEventProfilingInfo(evt, CL_PROFILING_COMMAND_QUEUED, sizeof(cl_ulong), &queued, NULL);
if (qerr != CL_SUCCESS)
@@ -117,7 +117,7 @@ failable<cl_ulong> profileKernelEvent(const cl_event evt) {
/**
* Profile an array of memory events.
*/
-failable<cl_ulong> profileMemEvents(const cl_uint n, const cl_event* evt) {
+const failable<cl_ulong> profileMemEvents(const cl_uint n, const cl_event* const evt) {
if (n == 0)
return 0;
const failable<cl_ulong> t = profileMemEvent(*evt);
@@ -221,6 +221,21 @@ public:
}
}
+ OpenCLContext(const OpenCLContext& c) : dev(c.dev), ndevs(c.ndevs), ctx(c.ctx) {
+ for (cl_uint i = 0; i < ndevs; i++) {
+ devid[i] = c.devid[i];
+ cq[i] = c.cq[i];
+ if (cq[i] != 0) {
+ const cl_int rcqerr = clRetainCommandQueue(cq[i]);
+ if (rcqerr != CL_SUCCESS)
+ mkfailure<bool>(string("Couldn't retain OpenCL command queue: ") + clError(rcqerr));
+ }
+ }
+ const cl_int rcerr = clRetainContext(ctx);
+ if (rcerr != CL_SUCCESS)
+ mkfailure<bool>(string("Couldn't retain OpenCL context: ") + clError(rcerr));
+ }
+
~OpenCLContext() {
for (cl_uint i = 0; i < ndevs; i++) {
if (cq[i] != 0)
@@ -372,7 +387,7 @@ private:
/**
* Return a read-only memory buffer.
*/
-const failable<OpenCLBuffer> readOnlyBuffer(const size_t size, const void* p, const OpenCLContext& cl, const cl_command_queue cq) {
+const failable<OpenCLBuffer> readOnlyBuffer(const size_t size, const void* const p, const OpenCLContext& cl, const cl_command_queue cq) {
if (cl.dev == OpenCLContext::CPU) {
cl_int err;
const cl_mem buf = clCreateBuffer(cl.ctx, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, size, const_cast<void*>(p), &err);
@@ -396,7 +411,7 @@ const failable<OpenCLBuffer> readOnlyBuffer(const size_t size, const void* p, co
/**
* Fill an array of write events for a given list of buffers.
*/
-const cl_uint writeBufferEvents(const list<OpenCLBuffer>& buf, cl_event* evt) {
+const cl_uint writeBufferEvents(const list<OpenCLBuffer>& buf, cl_event* const evt) {
if (isNil(buf))
return 0;
const cl_event e = car(buf).evt;
@@ -427,7 +442,7 @@ const failable<OpenCLBuffer> writeOnlyBuffer(const size_t size, const OpenCLCont
/**
* Convert a value to a kernel arg.
*/
-const failable<OpenCLBuffer> valueToKernelArg(const cl_uint i, const size_t size, const void* p, const failable<OpenCLBuffer>& buf, const OpenCLKernel& kernel) {
+const failable<OpenCLBuffer> valueToKernelArg(const cl_uint i, const size_t size, const void* const p, const failable<OpenCLBuffer>& buf, const OpenCLKernel& kernel) {
if (!hasContent(buf))
return buf;
if (p != NULL) {
@@ -446,7 +461,7 @@ const failable<OpenCLBuffer> valueToKernelArg(const cl_uint i, const size_t size
const failable<OpenCLBuffer> valueToKernelArg(const value& v, const cl_uint i, const OpenCLKernel& kernel, const OpenCLContext& cl, const cl_command_queue cq) {
switch (type(v)) {
case value::Symbol: {
- const string s = string("'") + v;
+ const string s = string("'") + (string)v;
return valueToKernelArg(i, 0, NULL, readOnlyBuffer(length(s) + 1, c_str(s), cl, cq), kernel);
}
case value::String: {
@@ -489,28 +504,28 @@ const failable<list<OpenCLBuffer>> valuesToKernelArgs(const list<value>& v, cons
/**
* Convert a kernel result to a value.
*/
-const value kernelResultToValue(const void* p, const value::ValueType type) {
+const value kernelResultToValue(const void* const p, const value::ValueType type) {
switch(type) {
case value::Symbol: {
- const char* s = static_cast<const char*>(p);
+ const char* const s = (const char*)p;
const size_t l = strlen(s);
if (l != 0 && *s == '\'')
return value(s + 1);
return value(s);
}
case value::String: {
- const char* s = static_cast<const char*>(p);
+ const char* const s = (const char*)p;
const size_t l = strlen(s);
if (l != 0 && *s == '\'')
return value(s + 1);
return value(string(s, l));
}
case value::Number:
- return (double)(*(static_cast<const cl_float*>(p)));
+ return (double)(*(const cl_float*)p);
case value::Bool:
- return (bool)(*(static_cast<const cl_int*>(p)));
+ return (bool)(*(const cl_int*)p);
default:
- return *(static_cast<const value*>(p));
+ return *(const value*)p;
}
}
@@ -582,9 +597,9 @@ const failable<OpenCLKernel> createKernel(const value& expr, const OpenCLProgram
// The start, stop, and restart functions are optional
//if (fn == "start" || fn == "stop")
- //return value(lambda<value(const list<value>&)>());
+ //return value(lvvlambda());
- return mkfailure<OpenCLKernel>(string("Couldn't find function: ") + car<value>(expr) + " : " + clError(ckerr));
+ return mkfailure<OpenCLKernel>(string("Couldn't find function: ") + (string)car<value>(expr) + " : " + clError(ckerr));
}
return OpenCLKernel(k);
}
diff --git a/sca-cpp/trunk/modules/opencl/opencl-shell.cpp b/sca-cpp/trunk/modules/opencl/opencl-shell.cpp
index 1dfeaeea1d..a0598c9d32 100644
--- a/sca-cpp/trunk/modules/opencl/opencl-shell.cpp
+++ b/sca-cpp/trunk/modules/opencl/opencl-shell.cpp
@@ -29,8 +29,8 @@
#include "string.hpp"
#include "driver.hpp"
-int main(const int argc, char** argv) {
- tuscany::gc_scoped_pool pool;
+int main(const int argc, char** const argv) {
+ const tuscany::gc_scoped_pool pool;
if (argc != 2) {
tuscany::cerr << "Usage: opencl-shell <kernel.cl>" << tuscany::endl;
return 1;
diff --git a/sca-cpp/trunk/modules/opencl/opencl-test.cpp b/sca-cpp/trunk/modules/opencl/opencl-test.cpp
index 17bc5ccfa6..4c7f3fa86b 100644
--- a/sca-cpp/trunk/modules/opencl/opencl-test.cpp
+++ b/sca-cpp/trunk/modules/opencl/opencl-test.cpp
@@ -159,8 +159,8 @@ const string testCharsParallelGPU =
" r[i] = i < ixl? x[i] : i < ixl + iyl? y[i - ixl] : '\\0';\n"
"}\n";
-bool testTaskParallel(const OpenCLContext::DeviceType dev) {
- gc_scoped_pool pool;
+const bool testTaskParallel(const OpenCLContext::DeviceType dev) {
+ const gc_scoped_pool pool;
OpenCLContext cl(dev);
if (!devices(cl) != 0)
return true;
@@ -192,12 +192,12 @@ bool testTaskParallel(const OpenCLContext::DeviceType dev) {
const value exp = mklist<value>("int_or", true, false);
const failable<value> r = evalKernel(createKernel(exp, content(clprog)), exp, cl);
assert(hasContent(r));
- assert(content(r) == value(true));
+ assert(content(r) == trueValue);
const value exp2 = mklist<value>("int_or", false, false);
const failable<value> r2 = evalKernel(createKernel(exp2, content(clprog)), exp2, cl);
assert(hasContent(r2));
- assert(content(r2) == value(false));
+ assert(content(r2) == falseValue);
}
{
istringstream is(dev == OpenCLContext::CPU? testCharsCPU : testCharsGPU);
@@ -223,41 +223,33 @@ bool testTaskParallel(const OpenCLContext::DeviceType dev) {
return true;
}
-struct evalTaskParallelLoop {
- evalTaskParallelLoop(const OpenCLContext& cl, const OpenCLProgram& clprog) : cl(cl), clprog(clprog), exp(mklist<value>("add", 60, string("Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello "), 60, string("World World World World World World World World World World "))) {
- }
- const bool operator()() const {
- const failable<value> r = evalKernel(createKernel(exp, clprog), exp, 1, value::String, 128, cl);
- assert(hasContent(r));
- assert(content(r) == value(string("Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello World World World World World World World World World World ")));
- return true;
- }
-
- const OpenCLContext& cl;
- const OpenCLProgram& clprog;
- const value exp;
-};
-
const bool testTaskParallelPerf(const OpenCLContext::DeviceType dev, const bool copy) {
- gc_scoped_pool pool;
+ const gc_scoped_pool pool;
OpenCLContext cl(dev);
if (!devices(cl) != 0)
return true;
istringstream is(dev == OpenCLContext::CPU? testCharsCPU : copy? testCharsCopyGPU : testCharsGPU);
- failable<OpenCLProgram> clprog = readProgram("kernel.cl", is, cl);
- assert(hasContent(clprog));
+ failable<OpenCLProgram> fclprog = readProgram("kernel.cl", is, cl);
+ assert(hasContent(fclprog));
resetOpenCLCounters();
- const lambda<bool()> el = evalTaskParallelLoop(cl, content(clprog));
+ OpenCLProgram clprog = content(fclprog);
+ const value exp = mklist<value>("add", 60, string("Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello "), 60, string("World World World World World World World World World World "));
+ const blambda el = [cl, clprog, exp]() -> const bool {
+ const failable<value> r = evalKernel(createKernel(exp, clprog), exp, 1, value::String, 128, cl);
+ assert(hasContent(r));
+ assert(content(r) == value(string("Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello World World World World World World World World World World ")));
+ return true;
+ };
cout << "OpenCL task-parallel eval " << (dev == OpenCLContext::CPU? "CPU" : "GPU") << (copy? " copy" : "") << " test " << time(el, 5, 500) << " ms";
printOpenCLCounters(500);
cout << endl;
return true;
}
-bool testDataParallel(const OpenCLContext::DeviceType dev) {
- gc_scoped_pool pool;
+const bool testDataParallel(const OpenCLContext::DeviceType dev) {
+ const gc_scoped_pool pool;
OpenCLContext cl(dev);
if (!devices(cl) != 0)
return true;
@@ -276,33 +268,25 @@ bool testDataParallel(const OpenCLContext::DeviceType dev) {
return true;
}
-struct evalDataParallelLoop {
- evalDataParallelLoop(const OpenCLContext& cl, const OpenCLProgram& clprog) : cl(cl), clprog(clprog), exp(mklist<value>("add", 60, string("Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello "), 60, string("World World World World World World World World World World "))) {
- }
- const bool operator()() const {
- const failable<value> r = evalKernel(createKernel(exp, clprog), exp, 121, value::String, 128, cl);
- assert(hasContent(r));
- assert(content(r) == value(string("Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello World World World World World World World World World World ")));
- return true;
- }
-
- const OpenCLContext& cl;
- const OpenCLProgram& clprog;
- const value exp;
-};
-
const bool testDataParallelPerf(const OpenCLContext::DeviceType dev, const bool copy) {
- gc_scoped_pool pool;
+ const gc_scoped_pool pool;
OpenCLContext cl(dev);
if (!devices(cl) != 0)
return true;
istringstream is(dev == OpenCLContext::CPU? testCharsParallelCPU : copy? testCharsParallelCopyGPU : testCharsParallelGPU);
- failable<OpenCLProgram> clprog = readProgram("kernel.cl", is, cl);
- assert(hasContent(clprog));
+ failable<OpenCLProgram> fclprog = readProgram("kernel.cl", is, cl);
+ assert(hasContent(fclprog));
resetOpenCLCounters();
- const lambda<bool()> el = evalDataParallelLoop(cl, content(clprog));
+ OpenCLProgram clprog = content(fclprog);
+ const value exp = mklist<value>("add", 60, string("Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello "), 60, string("World World World World World World World World World World "));
+ const blambda el = [cl, clprog, exp]() -> const bool {
+ const failable<value> r = evalKernel(createKernel(exp, clprog), exp, 121, value::String, 128, cl);
+ assert(hasContent(r));
+ assert(content(r) == value(string("Hello Hello Hello Hello Hello Hello Hello Hello Hello Hello World World World World World World World World World World ")));
+ return true;
+ };
cout << "OpenCL data-parallel eval " << (dev == OpenCLContext::CPU? "CPU" : "GPU") << (copy? " copy" : "") << " test " << time(el, 5, 500) << " ms";
printOpenCLCounters(500);
cout << endl;
diff --git a/sca-cpp/trunk/modules/python/Makefile.am b/sca-cpp/trunk/modules/python/Makefile.am
index 80c3097b48..92548de6d0 100644
--- a/sca-cpp/trunk/modules/python/Makefile.am
+++ b/sca-cpp/trunk/modules/python/Makefile.am
@@ -35,7 +35,7 @@ EXTRA_DIST = domain-test.composite client-test.py server-test.py
mod_LTLIBRARIES = libmod_tuscany_python.la
libmod_tuscany_python_la_SOURCES = mod-python.cpp
-libmod_tuscany_python_la_LDFLAGS = -lxml2 -lcurl -lmozjs -L${PYTHON_LIB} -R${PYTHON_LIB} -lpython${PYTHON_VERSION}
+libmod_tuscany_python_la_LDFLAGS = -lxml2 -lcurl -ljansson -L${PYTHON_LIB} -R${PYTHON_LIB} -lpython${PYTHON_VERSION}
noinst_DATA = libmod_tuscany_python${libsuffix}
libmod_tuscany_python${libsuffix}:
ln -s .libs/libmod_tuscany_python${libsuffix}
@@ -47,7 +47,7 @@ python_shell_SOURCES = python-shell.cpp
python_shell_LDFLAGS = -L${PYTHON_LIB} -R${PYTHON_LIB} -lpython${PYTHON_VERSION}
client_test_SOURCES = client-test.cpp
-client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+client_test_LDFLAGS = -lxml2 -lcurl -ljansson
dist_noinst_SCRIPTS = server-test wiring-test
noinst_PROGRAMS = python-test client-test
diff --git a/sca-cpp/trunk/modules/python/driver.hpp b/sca-cpp/trunk/modules/python/driver.hpp
index a5d554172b..41daed32c3 100644
--- a/sca-cpp/trunk/modules/python/driver.hpp
+++ b/sca-cpp/trunk/modules/python/driver.hpp
@@ -35,9 +35,9 @@
namespace tuscany {
namespace python {
-const value evalDriverLoop(PyObject* script, istream& in, ostream& out, PythonRuntime& py) {
+const value evalDriverLoop(PyObject* const script, istream& in, ostream& out, PythonRuntime& py) {
scheme::promptForInput(scheme::evalInputPrompt, out);
- value input = scheme::readValue(in);
+ const value input = content(scheme::readValue(in));
if (isNil(input))
return input;
const failable<value> output = evalScript(input, script, py);
@@ -46,11 +46,11 @@ const value evalDriverLoop(PyObject* script, istream& in, ostream& out, PythonRu
return evalDriverLoop(script, in, out, py);
}
-const bool evalDriverRun(const char* path, istream& in, ostream& out) {
+const bool evalDriverRun(const char* const path, istream& in, ostream& out) {
PythonRuntime py;
scheme::setupDisplay(out);
ifstream is(path);
- failable<PyObject*> script = readScript(moduleName(path), path, is, py);
+ const failable<PyObject*> script = readScript(moduleName(path), path, is, py);
if (!hasContent(script))
return true;
evalDriverLoop(content(script), in, out, py);
diff --git a/sca-cpp/trunk/modules/python/eval.hpp b/sca-cpp/trunk/modules/python/eval.hpp
index 5c0be7d261..3f9c6c20a2 100644
--- a/sca-cpp/trunk/modules/python/eval.hpp
+++ b/sca-cpp/trunk/modules/python/eval.hpp
@@ -53,8 +53,8 @@ class PythonRuntime;
/**
* Maintain a garbage collected reference to a Python object.
*/
-const bool pyIncRef(PyObject* o);
-const bool pyDecRef(PyObject* o, PythonRuntime* py);
+const bool pyIncRef(PyObject* const o);
+const bool pyDecRef(PyObject* const o, PythonRuntime* const py);
/**
* Write to debug log from Python.
@@ -70,7 +70,7 @@ const value pyDebug(const list<value>& args) {
class PythonRuntime {
public:
- PythonRuntime() {
+ PythonRuntime() : owner(true) {
debug("python::pythonruntime");
// Save current process id
@@ -115,7 +115,7 @@ public:
PySys_SetArgv(0, const_cast<char**>(&arg0));
// Install debug log function
- PyObject* mkPyLambda(const lambda<value(const list<value>&)>& l, PythonRuntime* py);
+ PyObject* mkPyLambda(const lvvlambda& l, PythonRuntime* py);
PyObject* pyd= mkPyLambda(pyDebug, this);
PyObject* sys = PyImport_ImportModule("sys");
PyObject_SetAttrString(sys, "debug", pyd);
@@ -127,10 +127,21 @@ public:
#endif
}
+#ifdef WANT_THREADS
+ PythonRuntime(const PythonRuntime& py) : owner(false), mutex(py.mutex), pidmutex(py.pidmutex), pid(py.pid) {
+ }
+#else
+ PythonRuntime(const PythonRuntime& py) : owner(false), pid(py.pid) {
+ }
+#endif
+
+ PythonRuntime& operator=(const PythonRuntime& py) = delete;
+
~PythonRuntime() {
}
private:
+ const bool owner;
#ifdef WANT_THREADS
pthread_mutex_t mutex;
pthread_mutex_t pidmutex;
@@ -145,9 +156,9 @@ private:
/**
* Return the last python error.
*/
-const string lastErrorTrace(PyObject *trace) {
+const string lastErrorTrace(PyObject* const trace) {
if (trace == NULL)
- return "";
+ return emptyString;
PyTracebackObject* tb = (PyTracebackObject*)trace;
const int limit = 16;
int depth = 0;
@@ -167,16 +178,16 @@ const string lastErrorTrace(PyObject *trace) {
return str(os);
}
-const string lastError(PythonRuntime* py) {
+const string lastError(PythonRuntime* const py) {
if(PyErr_Occurred()) {
PyObject* type = NULL;
PyObject* val = NULL;
PyObject* trace = NULL;
PyErr_Fetch(&type, &val, &trace);
if (type != NULL && val != NULL) {
- PyObject* stype = PyObject_Repr(type);
- PyObject* sval = PyObject_Repr(val);
- string msg = string() + PyString_AsString(stype) + " : " + PyString_AsString(sval) + lastErrorTrace(trace);
+ PyObject* const stype = PyObject_Repr(type);
+ PyObject* const sval = PyObject_Repr(val);
+ const string msg = string() + PyString_AsString(stype) + " : " + PyString_AsString(sval) + lastErrorTrace(trace);
pyDecRef(stype, py);
pyDecRef(sval, py);
PyErr_Restore(type, val, trace);
@@ -187,7 +198,7 @@ const string lastError(PythonRuntime* py) {
PyErr_Clear();
return "Unknown Python error";
}
- return "";
+ return emptyString;
}
/**
@@ -195,7 +206,7 @@ const string lastError(PythonRuntime* py) {
*/
class PythonRuntimeLock {
public:
- PythonRuntimeLock(PythonRuntime* py) : py(py) {
+ PythonRuntimeLock(PythonRuntime* const py) : py(py) {
#ifdef WANT_THREADS
pthread_mutex_lock(&py->mutex);
#endif
@@ -208,7 +219,7 @@ public:
}
private:
- PythonRuntime* py;
+ PythonRuntime* const py;
};
/**
@@ -216,7 +227,7 @@ private:
*/
class PythonThreadIn {
public:
- PythonThreadIn(PythonRuntime* py) : py(py) {
+ PythonThreadIn(PythonRuntime* const py) : py(py) {
// Reinitialize Python thread support after a fork
const unsigned long pid = processId();
@@ -261,7 +272,7 @@ public:
}
private:
- PythonRuntime* py;
+ PythonRuntime* const py;
#ifdef WANT_THREADS
PyGILState_STATE gstate;
#endif
@@ -272,7 +283,7 @@ private:
*/
class PythonThreadOut {
public:
- PythonThreadOut(PythonRuntime* py) : py(py) {
+ PythonThreadOut(PythonRuntime* const py) : py(py) {
#ifdef WANT_THREADS
//debug("python::gil::save");
tstate = PyEval_SaveThread();
@@ -289,7 +300,7 @@ public:
}
private:
- PythonRuntime* py;
+ PythonRuntime* const py;
#ifdef WANT_THREADS
PyThreadState* tstate;
#endif
@@ -300,7 +311,7 @@ private:
*/
class PyGCRef {
public:
- PyGCRef(PyObject* o, PythonRuntime* py) : o(o), py(py) {
+ PyGCRef(PyObject* const o, PythonRuntime* const py) : o(o), py(py) {
}
~PyGCRef() {
@@ -311,21 +322,21 @@ public:
}
private:
- PyObject* o;
- PythonRuntime* py;
+ PyObject* const o;
+ PythonRuntime* const py;
};
/**
* Maintain a garbage collected reference to a Python object.
*/
-const bool pyIncRef(PyObject* o) {
+const bool pyIncRef(PyObject* const o) {
if (o == NULL)
return true;
Py_INCREF(o);
return true;
}
-const bool pyDecRef(unused PyObject* o, unused PythonRuntime* py) {
+const bool pyDecRef(unused PyObject* const o, unused PythonRuntime* const py) {
if (o == NULL)
return true;
//new (gc_new<PyGCRef>()) PyGCRef(o, py);
@@ -336,40 +347,40 @@ const bool pyDecRef(unused PyObject* o, unused PythonRuntime* py) {
/**
* Declare conversion functions.
*/
-PyObject* valueToPyObject(const value& v, PythonRuntime* py);
-const value pyObjectToValue(PyObject *o, PythonRuntime* py);
-PyObject* valuesToPyTuple(const list<value>& v, PythonRuntime* py);
-const list<value> pyTupleToValues(PyObject* o, PythonRuntime* py);
+PyObject* const valueToPyObject(const value& v, PythonRuntime* const py);
+const value pyObjectToValue(PyObject* const o, PythonRuntime* const py);
+PyObject* const valuesToPyTuple(const list<value>& v, PythonRuntime* const py);
+const list<value> pyTupleToValues(PyObject* const o, PythonRuntime* const py);
/**
* Callable python type used to represent a lambda expression.
*/
typedef struct {
PyObject_HEAD
- lambda<value(const list<value>&)>* func;
+ lvvlambda* func;
PythonRuntime* py;
} pyLambda;
-PyObject *mkPyLambda(const lambda<value(const list<value>&)>& l, PythonRuntime* py);
+PyObject* const mkPyLambda(const lvvlambda& l, PythonRuntime* const py);
-void pyLambda_dealloc(PyObject* self) {
+void pyLambda_dealloc(PyObject* const self) {
//debug(self, "python::pylambda_dealloc");
PyObject_Del(self);
}
-const string pyRepr(PyObject* o, PythonRuntime* py) {
- PyObject* r = PyObject_Repr(o);
+const string pyRepr(PyObject* const o, PythonRuntime* const py) {
+ PyObject* const r = PyObject_Repr(o);
const string s = PyString_AsString(r);
pyDecRef(r, py);
return s;
}
-const value pyLambda_callout(const pyLambda* pyl, const list<value>& args, PythonRuntime* py) {
+const value pyLambda_callout(const pyLambda* const pyl, const list<value>& args, PythonRuntime* const py) {
PythonThreadOut pyout(py);
return (*(pyl->func))(args);
}
-PyObject* pyLambda_call(PyObject* self, PyObject* args, unused PyObject* kwds) {
+PyObject* const pyLambda_call(PyObject* const self, PyObject* const args, unused PyObject* const kwds) {
debug("python::call");
const pyLambda* pyl = (const pyLambda*)self;
const value result = pyLambda_callout(pyl, pyTupleToValues(args, pyl->py), pyl->py);
@@ -378,22 +389,7 @@ PyObject* pyLambda_call(PyObject* self, PyObject* args, unused PyObject* kwds) {
return pyr;
}
-struct pyProxy {
- const value name;
- const lambda<value(const list<value>&)> func;
-
- pyProxy(const value& name, const lambda<value(const list<value>&)>& func) : name(name), func(func) {
- }
-
- const value operator()(const list<value>& args) const {
- debug(name, "python::proxy::name");
- const value result = func(cons<value>(name, args));
- debug(result, "python::proxy::result");
- return result;
- }
-};
-
-PyObject* pyLambda_getattr(PyObject *self, PyObject *attrname) {
+PyObject* const pyLambda_getattr(PyObject* const self, PyObject* const attrname) {
const string name = PyString_AsString(attrname);
if (substr(name, 0, 1) == "_")
return PyObject_GenericGetAttr(self, attrname);
@@ -403,9 +399,18 @@ PyObject* pyLambda_getattr(PyObject *self, PyObject *attrname) {
return self;
}
- const pyLambda* pyl = (pyLambda*)self;
+ const pyLambda* const pyl = (const pyLambda* const)self;
debug(name, "python::getattr::name");
- PyObject* pyr = mkPyLambda(pyProxy(name, *(pyl->func)), pyl->py);
+
+ const lvvlambda func = *(pyl->func);
+ const lvvlambda pyProxy = [name, func](const list<value>& args) -> const value {
+ debug(name, "python::proxy::name");
+ const value result = func(cons<value>(name, args));
+ debug(result, "python::proxy::result");
+ return result;
+ };
+
+ PyObject* const pyr = mkPyLambda(pyProxy, pyl->py);
return pyr;
}
@@ -464,10 +469,10 @@ PyObject* pyLambda_getattr(PyObject *self, PyObject *attrname) {
/**
* Create a new python object representing a lambda expression.
*/
-PyObject *mkPyLambda(const lambda<value(const list<value>&)>& l, PythonRuntime* py) {
- pyLambda* pyl = PyObject_New(pyLambda, &pyLambda_type);
+PyObject* const mkPyLambda(const lvvlambda& l, PythonRuntime* const py) {
+ pyLambda* const pyl = PyObject_New(pyLambda, &pyLambda_type);
if (pyl != NULL) {
- pyl->func = new (gc_new<lambda<value(const list<value>&)> >()) lambda<value(const list<value>&)>(l);
+ pyl->func = new (gc_new<lvvlambda >()) lvvlambda(l);
pyl->py = py;
}
//debug(pyl, "python::mkpylambda");
@@ -477,18 +482,18 @@ PyObject *mkPyLambda(const lambda<value(const list<value>&)>& l, PythonRuntime*
/**
* Convert a list of values to a python list.
*/
-PyObject* valuesToPyListHelper(PyObject* l, const list<value>& v, PythonRuntime* py) {
+PyObject* const valuesToPyListHelper(PyObject* const l, const list<value>& v, PythonRuntime* const py) {
if (isNil(v))
return l;
- PyObject* pyv = valueToPyObject(car(v), py);
+ PyObject* const pyv = valueToPyObject(car(v), py);
PyList_Append(l, pyv);
pyDecRef(pyv, py);
return valuesToPyListHelper(l, cdr(v), py);
}
-PyObject* valuesToPyTuple(const list<value>& v, PythonRuntime* py) {
- PyObject* pyl = valuesToPyListHelper(PyList_New(0), v, py);
- PyObject* pyt = PyList_AsTuple(pyl);
+PyObject* const valuesToPyTuple(const list<value>& v, PythonRuntime* const py) {
+ PyObject* const pyl = valuesToPyListHelper(PyList_New(0), v, py);
+ PyObject* const pyt = PyList_AsTuple(pyl);
pyDecRef(pyl, py);
return pyt;
}
@@ -496,14 +501,14 @@ PyObject* valuesToPyTuple(const list<value>& v, PythonRuntime* py) {
/**
* Convert a value to a python object.
*/
-PyObject* valueToPyObject(const value& v, PythonRuntime* py) {
+PyObject* const valueToPyObject(const value& v, PythonRuntime* const py) {
switch (type(v)) {
case value::List:
return valuesToPyTuple(v, py);
case value::Lambda:
return mkPyLambda(v, py);
case value::Symbol:
- return PyString_FromString(c_str(string("'") + v));
+ return PyString_FromString(c_str(string("'") + (string)v));
case value::String: {
const string s = (string)v;
return PyString_FromStringAndSize(c_str(s), length(s));
@@ -511,12 +516,12 @@ PyObject* valueToPyObject(const value& v, PythonRuntime* py) {
case value::Number:
return PyFloat_FromDouble((double)v);
case value::Bool: {
- PyObject* b = (bool)v? Py_True : Py_False;
+ PyObject* const b = (bool)v? Py_True : Py_False;
pyIncRef(b);
return b;
}
default: {
- PyObject* n = Py_None;
+ PyObject* const n = Py_None;
pyIncRef(n);
return n;
}
@@ -526,39 +531,29 @@ PyObject* valueToPyObject(const value& v, PythonRuntime* py) {
/**
* Convert a python tuple to a list of values.
*/
-const list<value> pyTupleToValuesHelper(PyObject* o, const size_t i, const size_t size, PythonRuntime* py) {
+const list<value> pyTupleToValuesHelper(PyObject* const o, const size_t i, const size_t size, PythonRuntime* const py) {
if (i == size)
- return list<value>();
+ return nilListValue;
return cons(pyObjectToValue(PyTuple_GetItem(o, i), py), pyTupleToValuesHelper(o, i + 1, size, py));
}
-const list<value> pyTupleToValues(PyObject* o, PythonRuntime* py) {
+const list<value> pyTupleToValues(PyObject* const o, PythonRuntime* const py) {
return pyTupleToValuesHelper(o, 0, PyTuple_Size(o), py);
}
/**
* Lambda function used to represent a python callable object.
*/
-struct pyCallable {
- PyObject* func;
- PythonRuntime* py;
- bool owner;
-
- pyCallable(PyObject* func, PythonRuntime* py) : func(func), py(py), owner(true) {
+class pyCallable {
+public:
+ pyCallable(PyObject* const func, PythonRuntime* const py) : func(func), py(py), owner(true) {
pyIncRef(func);
}
pyCallable(const pyCallable& c) : func(c.func), py(c.py), owner(false) {
}
- const pyCallable& operator=(const pyCallable& c) {
- if(this == &c)
- return *this;
- func = c.func;
- py = c.py;
- owner = false;
- return *this;
- }
+ pyCallable& operator=(const pyCallable& c) = delete;
~pyCallable() {
if (!owner)
@@ -569,16 +564,16 @@ struct pyCallable {
const value operator()(const list<value>& args) const {
PythonThreadIn pyin(py);
if (debug_islogging()) {
- PyObject* rfunc = PyObject_Repr(func);
+ PyObject* const rfunc = PyObject_Repr(func);
char* s = NULL;
Py_ssize_t l = 0;
PyString_AsStringAndSize(rfunc, &s, &l);
debug(string(s, l), "python::operator()::func");
pyDecRef(rfunc, py);
}
- PyObject* pyargs = valuesToPyTuple(args, py);
+ PyObject* const pyargs = valuesToPyTuple(args, py);
if (debug_islogging()) {
- PyObject* rargs = PyObject_Repr(pyargs);
+ PyObject* const rargs = PyObject_Repr(pyargs);
char* s = NULL;
Py_ssize_t l = 0;
PyString_AsStringAndSize(rargs, &s, &l);
@@ -586,21 +581,26 @@ struct pyCallable {
pyDecRef(rargs, py);
}
- PyObject* result = PyObject_CallObject(func, pyargs);
+ PyObject* const result = PyObject_CallObject(func, pyargs);
pyDecRef(pyargs, py);
const value v = pyObjectToValue(result, py);
pyDecRef(result, py);
return v;
}
+
+private:
+ PyObject* const func;
+ PythonRuntime* const py;
+ const bool owner;
};
/**
* Convert a python object to a value.
*/
-const value pyObjectToValue(PyObject *o, PythonRuntime* py) {
+const value pyObjectToValue(PyObject* const o, PythonRuntime* const py) {
if (o == NULL)
- return value();
+ return nilValue;
if (PyString_Check(o)) {
char* s = NULL;
Py_ssize_t l = 0;
@@ -622,8 +622,8 @@ const value pyObjectToValue(PyObject *o, PythonRuntime* py) {
if (PyObject_TypeCheck(o, &pyLambda_type))
return *(((pyLambda*)o)->func);
if (PyCallable_Check(o))
- return lambda<value(const list<value>&)>(pyCallable(o, py));
- return value();
+ return lvvlambda(pyCallable(o, py));
+ return nilValue;
}
/**
@@ -636,37 +636,37 @@ const string moduleName(const string& path) {
/**
* Evaluate an expression against a script provided as a python object.
*/
-const failable<value> evalScript(const value& expr, PyObject* script, PythonRuntime& py) {
+const failable<value> evalScript(const value& expr, PyObject* const script, PythonRuntime& py) {
PythonThreadIn pyin(&py);
// Get the requested function
- PyObject* func = PyObject_GetAttrString(script, c_str(car<value>(expr)));
+ PyObject* const func = PyObject_GetAttrString(script, c_str(car<value>(expr)));
if (func == NULL) {
// The start, stop, and restart functions are optional
const value fn = car<value>(expr);
if (fn == "start" || fn == "stop") {
PyErr_Clear();
- return value(lambda<value(const list<value>&)>());
+ return value(lvvlambda());
}
- return mkfailure<value>(string("Couldn't find function: ") + car<value>(expr) + " : " + lastError(&py));
+ return mkfailure<value>(string("Couldn't find function: ") + (string)car<value>(expr) + " : " + lastError(&py));
}
if (!PyCallable_Check(func)) {
pyDecRef(func, &py);
- return mkfailure<value>(string("Couldn't find callable function: ") + car<value>(expr));
+ return mkfailure<value>(string("Couldn't find callable function: ") + (string)car<value>(expr));
}
// Convert args to python objects
- PyObject* args = valuesToPyTuple(cdr<value>(expr), &py);
+ PyObject* const args = valuesToPyTuple(cdr<value>(expr), &py);
// Call the function
- PyObject* result = PyObject_CallObject(func, args);
+ PyObject* const result = PyObject_CallObject(func, args);
if (result == NULL) {
const string msg = lastError(&py);
pyDecRef(func, &py);
pyDecRef(args, &py);
- return mkfailure<value>(string("Function call failed: ") + car<value>(expr) + " : " + msg);
+ return mkfailure<value>(string("Function call failed: ") + (string)car<value>(expr) + " : " + msg);
}
pyDecRef(func, &py);
pyDecRef(args, &py);
@@ -684,8 +684,8 @@ const failable<PyObject*> readScript(const string& name, const string& path, ist
PythonThreadIn pyin(&py);
// Lookup already loaded module
- PyObject *mods = PyImport_GetModuleDict();
- PyObject *emod = PyDict_GetItemString(mods, const_cast<char*>(c_str(name)));
+ PyObject* const mods = PyImport_GetModuleDict();
+ PyObject* const emod = PyDict_GetItemString(mods, const_cast<char*>(c_str(name)));
if (emod != NULL)
return emod;
@@ -695,10 +695,10 @@ const failable<PyObject*> readScript(const string& name, const string& path, ist
const list<string> ls = streamList(is);
ostringstream os;
write(ls, os);
- PyObject* code = Py_CompileStringFlags(c_str(str(os)), c_str(path), Py_file_input, NULL);
+ PyObject* const code = Py_CompileStringFlags(c_str(str(os)), c_str(path), Py_file_input, NULL);
if (code == NULL)
return mkfailure<PyObject*>(string("Couldn't compile script: ") + path + " : " + lastError(&py));
- PyObject* mod = PyImport_ExecCodeModuleEx(const_cast<char*>(c_str(name)), code, const_cast<char*>(c_str(path)));
+ PyObject* const mod = PyImport_ExecCodeModuleEx(const_cast<char*>(c_str(name)), code, const_cast<char*>(c_str(path)));
if (mod == NULL) {
const string msg = lastError(&py);
pyDecRef(code, &py);
@@ -708,7 +708,7 @@ const failable<PyObject*> readScript(const string& name, const string& path, ist
pyDecRef(mod, &py);
// Lookup the loaded module
- PyObject *lmod = PyDict_GetItemString(mods, const_cast<char*>(c_str(name)));
+ PyObject* const lmod = PyDict_GetItemString(mods, const_cast<char*>(c_str(name)));
if (lmod != NULL)
return lmod;
@@ -718,7 +718,7 @@ const failable<PyObject*> readScript(const string& name, const string& path, ist
/**
* Release a python script.
*/
-const failable<bool> releaseScript(unused PyObject* script, PythonRuntime& py) {
+const failable<bool> releaseScript(unused PyObject* const script, PythonRuntime& py) {
PythonThreadIn pyin(&py);
// No need to decref the script here, as it's referenced only once from sys.modules
return true;
diff --git a/sca-cpp/trunk/modules/python/mod-python.cpp b/sca-cpp/trunk/modules/python/mod-python.cpp
index 956edf1059..eaaeeb8e3e 100644
--- a/sca-cpp/trunk/modules/python/mod-python.cpp
+++ b/sca-cpp/trunk/modules/python/mod-python.cpp
@@ -40,42 +40,35 @@ namespace modeval {
/**
* Apply a lifecycle start or restart event.
*/
-struct pythonLifecycle {
- python::PythonRuntime& py;
- pythonLifecycle(python::PythonRuntime& py) : py(py) {
- }
- const value operator()(const list<value>& params) const {
- const value func = car(params);
- if (func == "pythonRuntime")
- return (gc_ptr<value>)(value*)&py;
- return lambda<value(const list<value>&)>();
- }
-};
-
const value applyLifecycle(unused const list<value>& params) {
// Create a Python runtime
python::PythonRuntime& py = *(new (gc_new<python::PythonRuntime>()) python::PythonRuntime());
// Return the function to invoke on subsequent events
- return failable<value>(lambda<value(const list<value>&)>(pythonLifecycle(py)));
+ return failable<value>(lvvlambda([&py](const list<value>& params) -> const value {
+ const value func = car(params);
+ if (func == "pythonRuntime")
+ return (gc_ptr<value>)(value*)&py;
+ return lvvlambda();
+ }));
}
/**
* Evaluate a Python component implementation and convert it to an applicable
* lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, const lambda<value(const list<value>&)>& lifecycle) {
+const failable<lvvlambda > evalImplementation(const string& path, const value& impl, const list<value>& px, const lvvlambda& lifecycle) {
const string itype(elementName(impl));
if (contains(itype, ".python")) {
- const value* p = (gc_ptr<value>)lifecycle(mklist<value>("pythonRuntime"));
+ const value* const p = (gc_ptr<value>)lifecycle(mklist<value>("pythonRuntime"));
return modpython::evalImplementation(path, impl, px, *(python::PythonRuntime*)p);
}
if (contains(itype, ".cpp"))
return modcpp::evalImplementation(path, impl, px);
if (contains(itype, ".widget"))
- return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype, -1, false);
- return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype);
+ return mkfailure<lvvlambda >(string("Unsupported implementation type: ") + itype, -1, false);
+ return mkfailure<lvvlambda >(string("Unsupported implementation type: ") + itype);
}
}
diff --git a/sca-cpp/trunk/modules/python/mod-python.hpp b/sca-cpp/trunk/modules/python/mod-python.hpp
index e6effb985b..00f2e4ab4e 100644
--- a/sca-cpp/trunk/modules/python/mod-python.hpp
+++ b/sca-cpp/trunk/modules/python/mod-python.hpp
@@ -40,38 +40,30 @@ namespace server {
namespace modpython {
/**
- * Apply a Python component implementation function.
- */
-struct applyImplementation {
- PyObject* impl;
- const list<value> px;
- python::PythonRuntime& py;
- applyImplementation(PyObject* impl, const list<value>& px, python::PythonRuntime& py) : impl(impl), px(px), py(py) {
- }
- const value operator()(const list<value>& params) const {
- const value expr = append<value>(params, px);
- debug(expr, "modeval::python::applyImplementation::input");
- const failable<value> res = python::evalScript(expr, impl, py);
- const value val = !hasContent(res)? mklist<value>(value(), reason(res), rcode(res)) : mklist<value>(content(res));
- debug(val, "modeval::python::applyImplementation::result");
- return val;
- }
-};
-
-/**
* Evaluate a Python component implementation and convert it to an applicable
* lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, python::PythonRuntime& py) {
+const failable<lvvlambda > evalImplementation(const string& path, const value& impl, const list<value>& px, python::PythonRuntime& py) {
const string spath(attributeValue("script", impl));
const string fpath(path + spath);
ifstream is(fpath);
if (fail(is))
- return mkfailure<lambda<value(const list<value>&)> >(string("Could not read implementation: ") + fpath);
- const failable<PyObject*> script = python::readScript(python::moduleName(spath), fpath, is, py);
- if (!hasContent(script))
- return mkfailure<lambda<value(const list<value>&)> >(script);
- return lambda<value(const list<value>&)>(applyImplementation(content(script), px, py));
+ return mkfailure<lvvlambda >(string("Could not read implementation: ") + fpath);
+ const failable<PyObject*> fscript = python::readScript(python::moduleName(spath), fpath, is, py);
+ if (!hasContent(fscript))
+ return mkfailure<lvvlambda >(fscript);
+ PyObject* const script = content(fscript);
+
+ const lvvlambda applyImplementation = [script, px, &py](const list<value>& params) -> const value {
+ // Apply a Python component implementation function
+ const value expr = append<value>(params, px);
+ debug(expr, "modeval::python::applyImplementation::input");
+ const failable<value> res = python::evalScript(expr, script, py);
+ const value val = !hasContent(res)? mklist<value>(nilValue, reason(res), rcode(res)) : mklist<value>(content(res));
+ debug(val, "modeval::python::applyImplementation::result");
+ return val;
+ };
+ return applyImplementation;
}
}
diff --git a/sca-cpp/trunk/modules/python/python-shell.cpp b/sca-cpp/trunk/modules/python/python-shell.cpp
index 89b47b8d44..7575ffa077 100644
--- a/sca-cpp/trunk/modules/python/python-shell.cpp
+++ b/sca-cpp/trunk/modules/python/python-shell.cpp
@@ -29,8 +29,8 @@
#include "string.hpp"
#include "driver.hpp"
-int main(const int argc, char** argv) {
- tuscany::gc_scoped_pool pool;
+int main(const int argc, const char** const argv) {
+ const tuscany::gc_scoped_pool pool;
if (argc != 2) {
tuscany::cerr << "Usage: python-shell <script.py>" << tuscany::endl;
return 1;
diff --git a/sca-cpp/trunk/modules/python/python-test.cpp b/sca-cpp/trunk/modules/python/python-test.cpp
index 29a66cc2e7..44a72f8f88 100644
--- a/sca-cpp/trunk/modules/python/python-test.cpp
+++ b/sca-cpp/trunk/modules/python/python-test.cpp
@@ -37,12 +37,12 @@ const string testPythonAdd =
"def add(x, y):\n"
" return x + y\n";
-bool testEvalExpr() {
- gc_scoped_pool pool;
+const bool testEvalExpr() {
+ const gc_scoped_pool pool;
PythonRuntime py;
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script1", "script1.py", is, py);
+ const failable<PyObject*> script = readScript("script1", "script1.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("add", 2, 3);
@@ -58,12 +58,12 @@ const string testPythonMap =
"def addmap(x, y):\n"
" return tuple(map(lambda i: i + y, x))\n";
-bool testEvalList() {
- gc_scoped_pool pool;
+const bool testEvalList() {
+ const gc_scoped_pool pool;
PythonRuntime py;
istringstream is(testPythonMap);
- failable<PyObject*> script = readScript("script2", "script2.py", is, py);
+ const failable<PyObject*> script = readScript("script2", "script2.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("addmap", mklist<value>(1, 2, 3), 1);
@@ -94,8 +94,8 @@ const string testCallLambda(
"def testCallLambda(l, x, y):\n"
" return l(x, y)\n");
-bool testEvalLambda() {
- gc_scoped_pool pool;
+const bool testEvalLambda() {
+ const gc_scoped_pool pool;
PythonRuntime py;
const value trl = mklist<value>("testReturnLambda");
@@ -104,7 +104,7 @@ bool testEvalLambda() {
assert(hasContent(trlv));
assert(isLambda(content(trlv)));
- const lambda<value(const list<value>&)> trll(content(trlv));
+ const lvvlambda trll(content(trlv));
assert(trll(mklist<value>(2, 3)) == value(6));
istringstream tclis(testCallLambda);
@@ -114,20 +114,20 @@ bool testEvalLambda() {
assert(content(tclv) == value(6));
istringstream tcelis(testCallLambda);
- const value tcel = mklist<value>("testCallLambda", lambda<value(const list<value>&)>(mult), 3, 4);
+ const value tcel = mklist<value>("testCallLambda", lvvlambda(mult), 3, 4);
const failable<value> tcelv = evalScript(tcel, tcelis, py);
assert(hasContent(tcelv));
assert(content(tcelv) == value(12));
return true;
}
-struct testEvalReadAdd {
- PythonRuntime& py;
- testEvalReadAdd(PythonRuntime& py) : py(py) {
- }
- const bool operator()() const {
+const bool testEvalPerf() {
+ const gc_scoped_pool pool;
+ PythonRuntime py;
+
+ const blambda erl = [&py]() -> const bool {
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script3", "script3.py", is, py);
+ const failable<PyObject*> script = readScript("script3", "script3.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("add", 2, 3);
@@ -137,51 +137,36 @@ struct testEvalReadAdd {
releaseScript(content(script), py);
return true;
- }
-};
-
-struct testEvalAdd {
- PyObject* script;
- PythonRuntime& py;
- testEvalAdd(PyObject* script, PythonRuntime& py) : script(script), py(py) {
- }
- const bool operator()() const {
+ };
+ cout << "Python read + eval test " << time(erl, 5, 10000) << " ms" << endl;
+
+ istringstream is(testPythonAdd);
+ const failable<PyObject*> fscript = readScript("script4", "script4.py", is, py);
+ assert(hasContent(fscript));
+
+ PyObject* const script = content(fscript);
+ const blambda el = [script, &py]() -> const bool {
const value exp = mklist<value>("add", 2, 3);
const failable<value> r = evalScript(exp, script, py);
assert(hasContent(r));
assert(content(r) == value(5));
return true;
- }
-};
-
-bool testEvalPerf() {
- gc_scoped_pool pool;
- PythonRuntime py;
-
- const lambda<bool()> erl = lambda<bool()>(testEvalReadAdd(py));
- cout << "Python read + eval test " << time(erl, 5, 10000) << " ms" << endl;
-
- istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script4", "script4.py", is, py);
- assert(hasContent(script));
-
- const lambda<bool()> el = lambda<bool()>(testEvalAdd(content(script), py));
+ };
cout << "Python eval test " << time(el, 5, 10000) << " ms" << endl;
- releaseScript(content(script), py);
+ releaseScript(script, py);
return true;
}
#ifdef WANT_THREADS
-struct testReadEvalAddLoop {
- PythonRuntime& py;
- testReadEvalAddLoop(PythonRuntime& py) : py(py) {
- }
- const bool operator()() const {
+const list<future<bool> > submitReadEvals(worker& w, const int max, const int i, PythonRuntime& py) {
+ if (i == max)
+ return list<future<bool> >();
+ const blambda func = [&py]() -> const bool {
for (int i = 0; i < 100; i++) {
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script6", "script6.py", is, py);
+ const failable<PyObject*> script = readScript("script6", "script6.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("add", 2, 3);
@@ -192,15 +177,14 @@ struct testReadEvalAddLoop {
releaseScript(content(script), py);
}
return true;
- }
-};
-
-struct testEvalAddLoop {
- PyObject* script;
- PythonRuntime& py;
- testEvalAddLoop(PyObject* script, PythonRuntime& py) : script(script), py(py) {
- }
- const bool operator()() const {
+ };
+ return cons(submit(w, func), submitReadEvals(w, max, i + 1, py));
+}
+
+const list<future<bool> > submitEvals(worker& w, const int max, const int i, PyObject* const script, PythonRuntime& py) {
+ if (i == max)
+ return list<future<bool> >();
+ const blambda func = [script, &py]() -> const bool {
for (int i = 0; i < 100; i++) {
const value exp = mklist<value>("add", 2, 3);
const failable<value> r = evalScript(exp, script, py);
@@ -208,75 +192,44 @@ struct testEvalAddLoop {
assert(content(r) == value(5));
}
return true;
- }
-};
-
-const list<future<bool> > submitReadEvals(worker& w, const int max, const int i, PythonRuntime& py) {
- if (i == max)
- return list<future<bool> >();
- const lambda<bool()> func = lambda<bool()>(testReadEvalAddLoop(py));
- return cons(submit(w, func), submitReadEvals(w, max, i + 1, py));
-}
-
-const list<future<bool> > submitEvals(worker& w, const int max, const int i, PyObject* script, PythonRuntime& py) {
- if (i == max)
- return list<future<bool> >();
- const lambda<bool()> func = lambda<bool()>(testEvalAddLoop(script, py));
+ };
return cons(submit(w, func), submitEvals(w, max, i + 1, script, py));
}
-bool checkEvalResults(const list<future<bool> > r) {
+const bool checkEvalResults(const list<future<bool> > r) {
if (isNil(r))
return true;
assert(car(r) == true);
return checkEvalResults(cdr(r));
}
-struct testReadEvalThreads {
- worker& w;
- const int max;
- PythonRuntime& py;
- testReadEvalThreads(worker& w, const int max, PythonRuntime& py) : w(w), max(max), py(py) {
- }
- const bool operator()() const {
- const list<future<bool> > r(submitReadEvals(w, max, 0, py));
- checkEvalResults(r);
- return true;
- }
-};
-
-struct testEvalThreads {
- worker& w;
- const int max;
- PyObject* script;
- PythonRuntime& py;
- testEvalThreads(worker& w, const int max, PyObject* script, PythonRuntime& py) : w(w), max(max), script(script), py(py) {
- }
- const bool operator()() const {
- const list<future<bool> > r(submitEvals(w, max, 0, script, py));
- checkEvalResults(r);
- return true;
- }
-};
-
-bool testThreads() {
- gc_scoped_pool pool;
+const bool testThreads() {
+ const gc_scoped_pool pool;
PythonRuntime py;
const int max = 100;
worker w(max);
- const lambda<bool()> elr = lambda<bool()>(testReadEvalThreads(w, max, py));
+ const blambda elr = [&w, max, &py]() -> const bool {
+ const list<future<bool> > r(submitReadEvals(w, max, 0, py));
+ checkEvalResults(r);
+ return true;
+ };
cout << "Python eval + read thread test " << time(elr, 1, 1) / 10000.0 << " ms" << endl;
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script7", "script7.py", is, py);
- assert(hasContent(script));
+ const failable<PyObject*> fscript = readScript("script7", "script7.py", is, py);
+ assert(hasContent(fscript));
- const lambda<bool()> el = lambda<bool()>(testEvalThreads(w, max, content(script), py));
+ PyObject* const script = content(fscript);
+ const blambda el = [&w, max, script, &py]() -> const bool {
+ const list<future<bool> > r(submitEvals(w, max, 0, script, py));
+ checkEvalResults(r);
+ return true;
+ };
cout << "Python eval thread test " << time(el, 1, 1) / 10000.0 << " ms" << endl;
- releaseScript(content(script), py);
+ releaseScript(script, py);
return true;
}
@@ -286,7 +239,7 @@ bool testThreads() {
}
int main() {
- tuscany::gc_scoped_pool p;
+ const tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::python::testEvalExpr();
diff --git a/sca-cpp/trunk/modules/server/Makefile.am b/sca-cpp/trunk/modules/server/Makefile.am
index e2fd67d9b8..c5c19a5ba7 100644
--- a/sca-cpp/trunk/modules/server/Makefile.am
+++ b/sca-cpp/trunk/modules/server/Makefile.am
@@ -29,7 +29,7 @@ mod_LTLIBRARIES = libmod_tuscany_eval.la
noinst_DATA = libmod_tuscany_eval${libsuffix}
libmod_tuscany_eval_la_SOURCES = mod-eval.cpp
-libmod_tuscany_eval_la_LDFLAGS = -lxml2 -lcurl -lmozjs
+libmod_tuscany_eval_la_LDFLAGS = -lxml2 -lcurl -ljansson
libmod_tuscany_eval${libsuffix}:
ln -s .libs/libmod_tuscany_eval${libsuffix}
@@ -42,7 +42,7 @@ libimpl-test${libsuffix}:
ln -s .libs/libimpl-test${libsuffix}
client_test_SOURCES = client-test.cpp
-client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+client_test_LDFLAGS = -lxml2 -lcurl -ljansson
dist_noinst_SCRIPTS = httpd-test server-test wiring-test
noinst_PROGRAMS = client-test
diff --git a/sca-cpp/trunk/modules/server/client-test.hpp b/sca-cpp/trunk/modules/server/client-test.hpp
index 1c7b26da39..dc9ca299ad 100644
--- a/sca-cpp/trunk/modules/server/client-test.hpp
+++ b/sca-cpp/trunk/modules/server/client-test.hpp
@@ -36,7 +36,8 @@
namespace tuscany {
namespace server {
-string testURI = "http://localhost:8090/scheme";
+gc_mutable_ref<string> testURI = string("http://localhost:8090/scheme");
+
bool testBlobs = true;
ostream* curlWriter(const string& s, ostream* os) {
@@ -45,8 +46,8 @@ ostream* curlWriter(const string& s, ostream* os) {
}
const bool testGet() {
- gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "", 0);
+ const gc_scoped_pool pool;
+ const http::CURLSession ch("", "", "", "", 0);
{
ostringstream os;
const failable<list<ostream*> > r = http::get<ostream*>(curlWriter, &os, "http://localhost:8090/index.html", ch);
@@ -62,160 +63,127 @@ const bool testGet() {
return true;
}
-struct getLoop {
- http::CURLSession& ch;
- getLoop(http::CURLSession& ch) : ch(ch) {
- }
- const bool operator()() const {
+const bool testGetPerf() {
+ const gc_scoped_pool pool;
+ const http::CURLSession ch("", "", "", "", 0);
+ const blambda gl = [ch]() -> const bool {
const failable<value> r = http::getcontent("http://localhost:8090/index.html", ch);
assert(hasContent(r));
assert(contains(car(reverse(list<value>(content(r)))), "It works"));
return true;
- }
-};
-
-const bool testGetPerf() {
- gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "", 0);
- const lambda<bool()> gl = getLoop(ch);
+ };
cout << "Static GET test " << time(gl, 5, 200) << " ms" << endl;
return true;
}
const bool testEval() {
- gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "", 0);
+ const gc_scoped_pool pool;
+ const http::CURLSession ch("", "", "", "", 0);
const failable<value> r = http::evalExpr(mklist<value>(string("echo"), string("Hello")), testURI, ch);
assert(hasContent(r));
assert(content(r) == string("Hello"));
return true;
}
-struct evalLoop {
- const string uri;
- http::CURLSession& ch;
- evalLoop(const string& uri, http::CURLSession& ch) : uri(uri), ch(ch) {
- }
- const bool operator()() const {
- const failable<value> r = http::evalExpr(mklist<value>(string("echo"), string("Hello")), uri, ch);
- assert(hasContent(r));
- assert(content(r) == string("Hello"));
- return true;
- }
-};
-
const value blob(string(2048, 'A'));
const list<value> blobs = mklist(blob, blob);
-struct blobEvalLoop {
- const string uri;
- http::CURLSession& ch;
- blobEvalLoop(const string& uri, http::CURLSession& ch) : uri(uri), ch(ch) {
- }
- const bool operator()() const {
- const failable<value> r = content(http::evalExpr(mklist<value>(string("echo"), blobs), uri, ch));
+const bool testEvalPerf() {
+ const gc_scoped_pool pool;
+ const http::CURLSession ch("", "", "", "", 0);
+ const blambda el = [ch]() -> const bool {
+ const failable<value> r = http::evalExpr(mklist<value>(string("echo"), string("Hello")), testURI, ch);
assert(hasContent(r));
- assert(content(r) == blobs);
+ assert(content(r) == string("Hello"));
return true;
- }
-};
-
-const bool testEvalPerf() {
- gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "", 0);
- const lambda<bool()> el = evalLoop(testURI, ch);
+ };
cout << "JSON-RPC eval echo test " << time(el, 5, 200) << " ms" << endl;
if (testBlobs) {
- const lambda<bool()> bel = blobEvalLoop(testURI, ch);
+ const blambda bel = [ch]() -> const bool {
+ const failable<value> r = content(http::evalExpr(mklist<value>(string("echo"), blobs), testURI, ch));
+ assert(hasContent(r));
+ assert(content(r) == blobs);
+ return true;
+ };
cout << "JSON-RPC eval blob test " << time(bel, 5, 200) << " ms" << endl;
}
return true;
}
-bool testPost() {
- gc_scoped_pool pool;
- const list<value> i = list<value>() + "content" + (list<value>() + "item"
- + (list<value>() + "name" + string("Apple"))
- + (list<value>() + "price" + string("$2.99")));
- const list<value> a = list<value>() + (list<value>() + "entry"
- + (list<value>() + "title" + string("item"))
- + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+const bool testPost() {
+ const gc_scoped_pool pool;
+ const list<value> i = nilListValue + "content" + (nilListValue + "item"
+ + (nilListValue + "name" + string("Apple"))
+ + (nilListValue + "price" + string("$2.99")));
+ const list<value> a = nilListValue + (nilListValue + "entry"
+ + (nilListValue + "title" + string("item"))
+ + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- http::CURLSession ch("", "", "", "", 0);
+ const http::CURLSession ch("", "", "", "", 0);
const failable<value> id = http::post(a, testURI, ch);
assert(hasContent(id));
return true;
}
-struct postLoop {
- const string uri;
- const value val;
- http::CURLSession& ch;
- postLoop(const string& uri, const value& val, http::CURLSession& ch) : uri(uri), val(val), ch(ch) {
- }
- const bool operator()() const {
- const failable<value> id = http::post(val, uri, ch);
- assert(hasContent(id));
- return true;
- }
-};
-
-struct postBlobLoop {
- const string uri;
- const value val;
- http::CURLSession& ch;
- postBlobLoop(const string& uri, const value& val, http::CURLSession& ch) : uri(uri), val(val), ch(ch) {
- }
- const bool operator()() const {
- gc_scoped_pool pool;
- const failable<value> id = http::post(val, uri, ch);
- assert(hasContent(id));
- return true;
- }
-};
-
const bool testPostPerf() {
- gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "", 0);
+ const gc_scoped_pool pool;
+ const http::CURLSession ch("", "", "", "", 0);
{
- const list<value> i = list<value>() + "content" + (list<value>() + "item"
- + (list<value>() + "name" + string("Apple"))
- + (list<value>() + "price" + string("$2.99")));
- const list<value> val = list<value>() + (list<value>() + "entry"
- + (list<value>() + "title" + string("item"))
- + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ const list<value> i = nilListValue + "content" + (nilListValue + "item"
+ + (nilListValue + "name" + string("Apple"))
+ + (nilListValue + "price" + string("$2.99")));
+ const list<value> val = nilListValue + (nilListValue + "entry"
+ + (nilListValue + "title" + string("item"))
+ + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- const lambda<bool()> pl = postLoop(testURI, val, ch);
+ const blambda pl = [val, ch]() -> const bool {
+ const failable<value> id = http::post(val, testURI, ch);
+ assert(hasContent(id));
+ return true;
+ };
cout << "ATOMPub POST small test " << time(pl, 5, 200) << " ms" << endl;
}
if (testBlobs) {
- const list<value> i = list<value>() + "content" + (list<value>() + "item"
- + (list<value>() + "name" + string("Apple"))
- + (list<value>() + "blob1" + blob)
- + (list<value>() + "blob2" + blob)
- + (list<value>() + "price" + string("$2.99")));
- const list<value> val = list<value>() + (list<value>() + "entry"
- + (list<value>() + "title" + string("item"))
- + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ const list<value> i = nilListValue + "content" + (nilListValue + "item"
+ + (nilListValue + "name" + string("Apple"))
+ + (nilListValue + "blob1" + blob)
+ + (nilListValue + "blob2" + blob)
+ + (nilListValue + "price" + string("$2.99")));
+ const list<value> val = nilListValue + (nilListValue + "entry"
+ + (nilListValue + "title" + string("item"))
+ + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- const lambda<bool()> pl = postBlobLoop(testURI, val, ch);
+ const blambda pl = [val, ch]() -> const bool {
+ const gc_scoped_pool pool;
+ const failable<value> id = http::post(val, testURI, ch);
+ assert(hasContent(id));
+ return true;
+ };
cout << "ATOMPub POST blob test " << time(pl, 5, 200) << " ms" << endl;
}
return true;
}
+const blambda mkpostLoop(const string& uri, const value& val, const http::CURLSession& ch) {
+ return [uri, val, ch]() -> const bool {
+ const failable<value> id = http::post(val, uri, ch);
+ assert(hasContent(id));
+ return true;
+ };
+}
+
#ifdef WANT_THREADS
const bool postThread(const string& uri, const int count, const value& val) {
- gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "", 0);
- const lambda<bool()> pl = postLoop(uri, val, ch);
+ const gc_scoped_pool pool;
+ const http::CURLSession ch("", "", "", "", 0);
+ const blambda pl = mkpostLoop(uri, val, ch);
time(pl, 0, count);
return true;
}
-const list<future<bool> > startPost(worker& w, const int threads, const lambda<bool()>& l) {
+const list<future<bool> > startPost(worker& w, const int threads, const blambda& l) {
if (threads == 0)
return list<future<bool> >();
return cons(submit(w, l), startPost(w, threads - 1, l));
@@ -228,36 +196,27 @@ const bool checkPost(const list<future<bool> >& r) {
return checkPost(cdr(r));
}
-struct postThreadLoop {
- const lambda<bool()> l;
- worker& w;
- const int threads;
- postThreadLoop(const lambda<bool()>& l, worker& w, const int threads) : l(l), w(w), threads(threads) {
- }
- const bool operator()() const {
- list<future<bool> > r = startPost(w, threads, l);
- checkPost(r);
- return true;
- }
-};
-
const bool testPostThreadPerf() {
- gc_scoped_pool pool;
+ const gc_scoped_pool pool;
const int count = 50;
const int threads = 10;
worker w(threads);
- const list<value> i = list<value>() + "content" + (list<value>() + "item"
- + (list<value>() + "name" + string("Apple"))
- + (list<value>() + "price" + string("$2.99")));
- const value val = list<value>() + (list<value>() + "entry"
- + (list<value>() + "title" + string("item"))
- + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ const list<value> i = nilListValue + "content" + (nilListValue + "item"
+ + (nilListValue + "name" + string("Apple"))
+ + (nilListValue + "price" + string("$2.99")));
+ const value val = nilListValue + (nilListValue + "entry"
+ + (nilListValue + "title" + string("item"))
+ + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- const lambda<bool()> pl= curry(lambda<bool(const string, const int, const value)>(postThread), testURI, count, val);
- const lambda<bool()> ptl = postThreadLoop(pl, w, threads);
- double t = time(ptl, 0, 1) / (threads * count);
+ const blambda pl= curry(lambda<const bool(const string, const int, const value)>(postThread), (const string)testURI, count, val);
+ const blambda ptl = [pl, &w, threads]() -> const bool {
+ list<future<bool> > r = startPost(w, threads, pl);
+ checkPost(r);
+ return true;
+ };
+ const double t = time(ptl, 0, 1) / (threads * count);
cout << "ATOMPub POST thread test " << t << " ms" << endl;
return true;
@@ -266,17 +225,17 @@ const bool testPostThreadPerf() {
#else
const bool postProc(const string& uri, const int count, const value& val) {
- gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "", 0);
- const lambda<bool()> pl = postLoop(uri, val, ch);
+ const gc_scoped_pool pool;
+ const http::CURLSession ch("", "", "", "", 0);
+ const blambda pl = mkpostLoop(uri, val, ch);
time(pl, 0, count);
return true;
}
-const list<pid_t> startPost(const int procs, const lambda<bool()>& l) {
+const list<pid_t> startPost(const int procs, const blambda& l) {
if (procs == 0)
return list<pid_t>();
- pid_t pid = fork();
+ const pid_t pid = fork();
if (pid == 0) {
assert(l() == true);
exit(0);
@@ -293,34 +252,26 @@ const bool checkPost(const list<pid_t>& r) {
return checkPost(cdr(r));
}
-struct postForkLoop {
- const lambda<bool()> l;
- const int procs;
- postForkLoop(const lambda<bool()>& l, const int procs) : l(l), procs(procs) {
- }
- const bool operator()() const {
- list<pid_t> r = startPost(procs, l);
- checkPost(r);
- return true;
- }
-};
-
const bool testPostForkPerf() {
- gc_scoped_pool pool;
+ const gc_scoped_pool pool;
const int count = 50;
const int procs = 10;
- const list<value> i = list<value>() + "content" + (list<value>() + "item"
- + (list<value>() + "name" + string("Apple"))
- + (list<value>() + "price" + string("$2.99")));
- const value val = list<value>() + (list<value>() + "entry"
- + (list<value>() + "title" + string("item"))
- + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ const list<value> i = nilListValue + "content" + (nilListValue + "item"
+ + (nilListValue + "name" + string("Apple"))
+ + (nilListValue + "price" + string("$2.99")));
+ const value val = nilListValue + (nilListValue + "entry"
+ + (nilListValue + "title" + string("item"))
+ + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- const lambda<bool()> pl= curry(lambda<bool(const string, const int, const value)>(postProc), testURI, count, val);
- const lambda<bool()> ptl = postForkLoop(pl, procs);
- double t = time(ptl, 0, 1) / (procs * count);
+ const blambda pl= curry(lambda<const bool(const string, const int, const value)>(postProc), testURI, count, val);
+ const blambda ptl = [pl, procs]() -> const bool {
+ list<pid_t> r = startPost(procs, l);
+ checkPost(r);
+ return true;
+ };
+ const double t = time(ptl, 0, 1) / (procs * count);
cout << "ATOMPub POST fork test " << t << " ms" << endl;
return true;
@@ -329,25 +280,25 @@ const bool testPostForkPerf() {
#endif
const bool testPut() {
- gc_scoped_pool pool;
- const list<value> i = list<value>() + "content" + (list<value>() + "item"
- + (list<value>() + "name" + string("Apple"))
- + (list<value>() + "price" + string("$2.99")));
- const list<value> a = list<value>() + (list<value>() + "entry"
- + (list<value>() + "title" + string("item"))
- + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ const gc_scoped_pool pool;
+ const list<value> i = nilListValue + "content" + (nilListValue + "item"
+ + (nilListValue + "name" + string("Apple"))
+ + (nilListValue + "price" + string("$2.99")));
+ const list<value> a = nilListValue + (nilListValue + "entry"
+ + (nilListValue + "title" + string("item"))
+ + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- http::CURLSession ch("", "", "", "", 0);
- value rc = content(http::put(a, testURI + "/111", ch));
- assert(rc == value(true));
+ const http::CURLSession ch("", "", "", "", 0);
+ const value rc = content(http::put(a, testURI + "/111", ch));
+ assert(rc == trueValue);
return true;
}
const bool testDel() {
- gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "", 0);
- value rc = content(http::del(testURI + "/111", ch));
- assert(rc == value(true));
+ const gc_scoped_pool pool;
+ const http::CURLSession ch("", "", "", "", 0);
+ const value rc = content(http::del(testURI + "/111", ch));
+ assert(rc == trueValue);
return true;
}
diff --git a/sca-cpp/trunk/modules/server/htdocs/test/entry.xml b/sca-cpp/trunk/modules/server/htdocs/test/entry.xml
index 46053c3138..6528c793e3 100644
--- a/sca-cpp/trunk/modules/server/htdocs/test/entry.xml
+++ b/sca-cpp/trunk/modules/server/htdocs/test/entry.xml
@@ -1,14 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
-<entry xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Item</title>
- <id>111</id>
- <content type="application/xml">
- <item>
- <name>Apple</name>
- <currencyCode>USD</currencyCode>
- <currencySymbol>$</currencySymbol>
- <price>2.99</price>
- </item>
- </content>
- <link href="111"/>
-</entry>
+<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>111</id><content type="application/xml"><item><name>Apple</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>2.99</price></item></content><link href="111"/></entry>
diff --git a/sca-cpp/trunk/modules/server/htdocs/test/feed.xml b/sca-cpp/trunk/modules/server/htdocs/test/feed.xml
index 337320e4c5..bcb304f9c2 100644
--- a/sca-cpp/trunk/modules/server/htdocs/test/feed.xml
+++ b/sca-cpp/trunk/modules/server/htdocs/test/feed.xml
@@ -1,44 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Sample Feed</title>
- <id>123456789</id>
- <entry xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Item</title>
- <id>111</id>
- <content type="application/xml">
- <item>
- <name>Apple</name>
- <currencyCode>USD</currencyCode>
- <currencySymbol>$</currencySymbol>
- <price>2.99</price>
- </item>
- </content>
- <link href="111"/>
- </entry>
- <entry xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Item</title>
- <id>222</id>
- <content type="application/xml">
- <item>
- <name>Orange</name>
- <currencyCode>USD</currencyCode>
- <currencySymbol>$</currencySymbol>
- <price>3.55</price>
- </item>
- </content>
- <link href="222"/>
- </entry>
- <entry xmlns="http://www.w3.org/2005/Atom">
- <title type="text">Item</title>
- <id>333</id>
- <content type="application/xml">
- <item>
- <name>Pear</name>
- <currencyCode>USD</currencyCode>
- <currencySymbol>$</currencySymbol>
- <price>1.55</price>
- </item>
- </content>
- <link href="333"/>
- </entry>
-</feed>
+<feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Sample Feed</title><id>123456789</id><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>111</id><content type="application/xml"><item><name>Apple</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>2.99</price></item></content><link href="111"/></entry><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>222</id><content type="application/xml"><item><name>Orange</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>3.55</price></item></content><link href="222"/></entry><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>333</id><content type="application/xml"><item><name>Pear</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>1.55</price></item></content><link href="333"/></entry></feed>
diff --git a/sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt b/sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt
index 2cff8b7339..09809a10df 100644
--- a/sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt
+++ b/sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt
@@ -1,14 +1 @@
-{
- "id": "1",
- "result": {
- "host": "localhost",
- "path": [
- "c",
- "property-test"
- ],
- "query": {
- "id": "1",
- "method": "print"
- }
- }
-} \ No newline at end of file
+{"id":"1","result":{"host":"localhost","path":["c","property-test"],"query":{"id":"1","method":"print"}}} \ No newline at end of file
diff --git a/sca-cpp/trunk/modules/server/htdocs/test/json-result.txt b/sca-cpp/trunk/modules/server/htdocs/test/json-result.txt
index 72b27b67db..121bf74902 100644
--- a/sca-cpp/trunk/modules/server/htdocs/test/json-result.txt
+++ b/sca-cpp/trunk/modules/server/htdocs/test/json-result.txt
@@ -1,4 +1 @@
-{
- "id": 1,
- "result": "Hello"
-} \ No newline at end of file
+{"id":1,"result":"Hello"} \ No newline at end of file
diff --git a/sca-cpp/trunk/modules/server/impl-test.cpp b/sca-cpp/trunk/modules/server/impl-test.cpp
index 1bd0843745..a9bd9ad585 100644
--- a/sca-cpp/trunk/modules/server/impl-test.cpp
+++ b/sca-cpp/trunk/modules/server/impl-test.cpp
@@ -42,11 +42,11 @@ const failable<value> post(unused const list<value>& params) {
}
const failable<value> put(unused const list<value>& params) {
- return value(true);
+ return trueValue;
}
const failable<value> del(unused const list<value>& params) {
- return value(true);
+ return trueValue;
}
const failable<value> echo(const list<value>& params) {
diff --git a/sca-cpp/trunk/modules/server/mod-cpp.hpp b/sca-cpp/trunk/modules/server/mod-cpp.hpp
index 8cae35e493..1321466383 100644
--- a/sca-cpp/trunk/modules/server/mod-cpp.hpp
+++ b/sca-cpp/trunk/modules/server/mod-cpp.hpp
@@ -54,47 +54,38 @@ const list<value> failableResult(const value& func, const list<value>& v) {
const value reason = cadr(v);
if (length(reason) == 0) {
if (func == "start" || func == "stop")
- return mklist<value>(lambda<value(const list<value>&)>());
- return mklist<value>(value(), string("Function not supported: ") + func);
+ return mklist<value>(lvvlambda());
+ return mklist<value>(nilValue, string("Function not supported: ") + (string)func);
}
return v;
}
-struct applyImplementation {
- const lib ilib;
- const lambda<value(const list<value>&)> impl;
- const list<value> px;
-
- applyImplementation(const lib& ilib, const lambda<value(const list<value>&)>& impl, const list<value>& px) : ilib(ilib), impl(impl), px(px) {
- }
-
- const value operator()(const list<value>& params) const {
- debug(params, "modeval::cpp::applyImplementation::input");
-
- // Apply the component implementation function
- const value val = failableResult(car(params), impl(append(params, px)));
-
- debug(val, "modeval::cpp::applyImplementation::result");
- return val;
- }
-};
-
/**
* Evaluate a C++ component implementation and convert it to
* an applicable lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) {
+const failable<lvvlambda > evalImplementation(const string& path, const value& impl, const list<value>& px) {
// Configure the implementation's lambda function
const value ipath(attributeValue("path", impl));
const value iname(attributeValue("library", impl));
- const string fpath(isNil(ipath)? path + iname : path + ipath + "/" + iname);
+ const string fpath(isNil(ipath)? path + (string)iname : path + (string)ipath + "/" + (string)iname);
const lib ilib(*(new (gc_new<lib>()) lib(fpath + dynlibExt)));
- const failable<lambda<value(const list<value>&)> > evalf(dynlambda<value(const list<value>&)>("apply", ilib));
- if (!hasContent(evalf))
- return evalf;
- const lambda<value(const list<value>&)> l(applyImplementation(ilib, content(evalf), px));
- return l;
+ const failable<lvvlambda > fappl(dynlambda<const value(const list<value>&)>("apply", ilib));
+ if (!hasContent(fappl))
+ return fappl;
+ const lvvlambda appl = content(fappl);
+
+ const lvvlambda applyImplementation = [ilib, appl, px](const list<value>& params) -> const value {
+ debug(params, "modeval::cpp::applyImplementation::params");
+
+ // Apply the component implementation function
+ const value val = failableResult(car(params), appl(append(params, px)));
+
+ debug(val, "modeval::cpp::applyImplementation::result");
+ return val;
+ };
+ return applyImplementation;
}
}
diff --git a/sca-cpp/trunk/modules/server/mod-eval.cpp b/sca-cpp/trunk/modules/server/mod-eval.cpp
index 3fd69c1fea..9b28f3df67 100644
--- a/sca-cpp/trunk/modules/server/mod-eval.cpp
+++ b/sca-cpp/trunk/modules/server/mod-eval.cpp
@@ -42,22 +42,22 @@ namespace modeval {
*/
const value applyLifecycle(unused const list<value>& params) {
// Return a nil function as we don't need to handle any subsequent events
- return failable<value>(lambda<value(const list<value>&)>());
+ return failable<value>(lvvlambda());
}
/**
* Evaluate a Scheme or C++ component implementation and convert it to an
* applicable lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, unused const lambda<value(const list<value>&)>& lifecycle) {
+const failable<lvvlambda > evalImplementation(const string& path, const value& impl, const list<value>& px, unused const lvvlambda& lifecycle) {
const string itype(elementName(impl));
if (contains(itype, ".scheme"))
return modscheme::evalImplementation(path, impl, px);
if (contains(itype, ".cpp"))
return modcpp::evalImplementation(path, impl, px);
if (contains(itype, ".widget"))
- return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype, -1, false);
- return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype);
+ return mkfailure<lvvlambda >(string("Unsupported implementation type: ") + itype, -1, false);
+ return mkfailure<lvvlambda >(string("Unsupported implementation type: ") + itype);
}
}
diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp
index ee99baa039..aa13584534 100644
--- a/sca-cpp/trunk/modules/server/mod-eval.hpp
+++ b/sca-cpp/trunk/modules/server/mod-eval.hpp
@@ -63,9 +63,9 @@ public:
SSLConf() {
}
- string ca;
- string cert;
- string key;
+ gc_mutable_ref<string> ca;
+ gc_mutable_ref<string> cert;
+ gc_mutable_ref<string> key;
};
/**
@@ -76,13 +76,13 @@ public:
VhostConf() {
}
- string domain;
- string contribPath;
- string composName;
- string contributorName;
- value contributor;
- string authenticatorName;
- value authenticator;
+ gc_mutable_ref<string> domain;
+ gc_mutable_ref<string> contribPath;
+ gc_mutable_ref<string> composName;
+ gc_mutable_ref<string> contributorName;
+ gc_mutable_ref<value> contributor;
+ gc_mutable_ref<string> authenticatorName;
+ gc_mutable_ref<value> authenticator;
};
/**
@@ -93,8 +93,8 @@ public:
ContribConf() {
}
- string contribPath;
- string composName;
+ gc_mutable_ref<string> contribPath;
+ gc_mutable_ref<string> composName;
};
/**
@@ -108,9 +108,9 @@ public:
Composite(const list<value>& refs, const list<value>& svcs, const list<value>& impls) : refs(refs), svcs(svcs), impls(impls) {
}
- list<value> refs;
- list<value> svcs;
- list<value> impls;
+ gc_mutable_ref<list<value> > refs;
+ gc_mutable_ref<list<value> > svcs;
+ gc_mutable_ref<list<value> > impls;
};
/**
@@ -121,12 +121,12 @@ public:
ServerConf() {
}
- ServerConf(apr_pool_t* p, const server_rec* s) : p(p), server(s), timeout(0) {
+ ServerConf(apr_pool_t* const p, const server_rec* s) : p(p), server(s), timeout(0) {
}
const gc_pool p;
const server_rec* server;
- lambda<value(const list<value>&)> lifecycle;
+ gc_mutable_ref<value> lifecycle;
ContribConf contribc;
SSLConf sslc;
int timeout;
@@ -139,16 +139,16 @@ public:
*/
class RequestConf {
public:
- RequestConf(apr_pool_t* p, const request_rec* r) : p(p), request(r), vhost(false), valias(false) {
+ RequestConf(apr_pool_t* const p, const request_rec* r) : p(p), request(r), vhost(false), valias(false) {
}
const gc_pool p;
const request_rec* request;
bool vhost;
bool valias;
- list<value> rpath;
- list<value> vpath;
- list<value> impls;
+ gc_mutable_ref<list<value> > rpath;
+ gc_mutable_ref<list<value> > vpath;
+ gc_mutable_ref<list<value> > impls;
};
/**
@@ -170,14 +170,14 @@ const failable<value> failableResult(const list<value>& v) {
* Store current HTTP request for access from property and proxy lambda functions.
*/
#ifdef WANT_THREADS
-perthread_ptr<request_rec> currentRequest;
+const perthread_ptr<request_rec> currentRequest;
#else
request_rec* currentRequest = NULL;
#endif
class ScopedRequest {
public:
- ScopedRequest(request_rec* r) {
+ ScopedRequest(request_rec* const r) {
currentRequest = r;
}
@@ -189,9 +189,9 @@ public:
/**
* Make an HTTP proxy lambda to an absolute URI
*/
-const value mkhttpProxy(const string& uri, const int timeout, const gc_pool& p) {
+const value mkhttpProxy(const string& uri, const int timeout) {
debug(uri, "modeval::mkhttpProxy::uri");
- return lambda<value(const list<value>&)>(http::proxy(uri, "", "", "", "", timeout, p));
+ return lvvlambda(http::proxy(uri, emptyString, emptyString, emptyString, emptyString, timeout));
}
/**
@@ -199,24 +199,24 @@ const value mkhttpProxy(const string& uri, const int timeout, const gc_pool& p)
*/
class implProxy {
public:
- implProxy(const value& name, const list<value>& impls, const SSLConf& sslc, const int timeout) : name(name), impls(impls), sslc(sslc), timeout(timeout) {
+ implProxy(const value& name, const gc_mutable_ref<list<value> >& impls, const SSLConf& sslc, const int timeout) : name(name), impls(impls), sslc(sslc), timeout(timeout) {
}
const value callImpl(const value& cname, const list<value>& aparams) const {
- //debug(impls, "modeval::implProxy::callImpl::impls");
+ debug(impls, "modeval::implProxy::callImpl::impls");
// Lookup the component implementation
- const list<value> impl(assoctree<value>(cname, impls));
+ const list<value> impl(assoctree<value>(cname, (list<value>)impls));
if (isNil(impl))
- return mkfailure<value>(string("Couldn't find component implementation: ") + cname);
+ return mkfailure<value>(string("Couldn't find component implementation: ") + (string)cname);
// Call its lambda function
- const lambda<value(const list<value>&)> l(cadr<value>(impl));
+ const lvvlambda l(cadr<value>(impl));
const value func = c_str(car(aparams));
const failable<value> val = failableResult(l(cons(func, cdr(aparams))));
debug(val, "modeval::implProxy::result");
if (!hasContent(val))
- return value();
+ return nilValue;
return content(val);
}
@@ -233,7 +233,7 @@ public:
// Use an HTTP proxy if the target is an absolute :// target
if (http::isAbsolute(uri)) {
- gc_pool p(currentRequest->pool);
+ const gc_pool p(currentRequest->pool);
// Interpret a uri in the form app://appname, convert it using the scheme,
// top level domain and port number from the current request
@@ -241,7 +241,7 @@ public:
ostringstream appuri;
appuri << httpd::scheme(currentRequest) << "://" << substr(uri, 6) << "." << http::topDomain(httpd::hostName(currentRequest)) << ":" << httpd::port(currentRequest) << "/";
debug(str(appuri), "modeval::implProxy::httpproxy::appuri");
- const lambda<value(const list<value>&)> px = lambda<value(const list<value>&)>(http::proxy(str(appuri), sslc.ca, sslc.cert, sslc.key, httpd::cookie(currentRequest), timeout, p));
+ const lvvlambda px = lvvlambda(http::proxy(str(appuri), sslc.ca, sslc.cert, sslc.key, httpd::cookie(currentRequest), timeout));
return px(aparams);
}
@@ -249,13 +249,13 @@ public:
// only if the target is in the same top level domain
if (http::topDomain(http::hostName(uri, p)) == http::topDomain(httpd::hostName(currentRequest))) {
debug(uri, "modeval::implProxy::httpproxy::samedomain");
- const lambda<value(const list<value>&)> px = lambda<value(const list<value>&)>(http::proxy(uri, sslc.ca, sslc.cert, sslc.key, httpd::cookie(currentRequest), timeout, p));
+ const lvvlambda px = lvvlambda(http::proxy(uri, sslc.ca, sslc.cert, sslc.key, httpd::cookie(currentRequest), timeout));
return px(aparams);
}
// No SSL certificate or cookie on a cross domain call
debug(uri, "modeval::implProxy::httpproxy::crossdomain");
- const lambda<value(const list<value>&)> px = lambda<value(const list<value>&)>(http::proxy(uri, "", "", "", "", timeout, p));
+ const lvvlambda px = lvvlambda(http::proxy(uri, emptyString, emptyString, emptyString, emptyString, timeout));
return px(aparams);
}
@@ -269,54 +269,41 @@ public:
private:
const value name;
- const list<value>& impls;
+ const gc_mutable_ref<list<value> >& impls;
const SSLConf& sslc;
const int timeout;
};
-const value mkimplProxy(const value& name, const list<value>& impls, const SSLConf& sslc, const int timeout) {
+const value mkimplProxy(const value& name, const gc_mutable_ref<list<value> >& impls, const SSLConf& sslc, const int timeout) {
debug(name, "modeval::implProxy::impl");
- return lambda<value(const list<value>&)>(implProxy(name, impls, sslc, timeout));
+ return lvvlambda(implProxy(name, impls, sslc, timeout));
}
/**
* Return a proxy lambda for an unwired reference.
*/
-class unwiredProxy {
-public:
- unwiredProxy(const value& name) : name(name) {
- }
-
- const value operator()(const list<value>& params) const {
+const value mkunwiredProxy(const string& name) {
+ debug(name, "modeval::mkunwiredProxy::name");
+ const lvvlambda unwiredProxy = [name](const list<value>& params) -> const value {
debug(name, "modeval::unwiredProxy::name");
- debug(params, "modeval::unwiredProxy::input");
+ debug(params, "modeval::unwiredProxy::params");
// Get function returns a default empty value
if (car(params) == "get") {
- debug(value(), "modeval::unwiredProxy::result");
- return value();
+ debug(nilValue, "modeval::unwiredProxy::result");
+ return nilValue;
}
// All other functions return a failure
return mkfailure<value>(string("Reference is not wired: ") + name);
- }
-
-private:
- const value name;
-};
-
-/**
- * Make a proxy lambda for an unwired reference.
- */
-const value mkunwiredProxy(const string& ref) {
- debug(ref, "modeval::mkunwiredProxy::ref");
- return lambda<value(const list<value>&)>(unwiredProxy(ref));
+ };
+ return unwiredProxy;
}
/**
* Convert a list of component references to a list of proxy lambdas.
*/
-const value mkrefProxy(const value& ref, const list<value>& impls, const SSLConf& sslc, const int timeout, const gc_pool& p) {
+const value mkrefProxy(const value& ref, const gc_mutable_ref<list<value> >& impls, const SSLConf& sslc, const int timeout) {
const value target = scdl::target(ref);
const bool wbyimpl = scdl::wiredByImpl(ref);
debug(ref, "modeval::mkrefProxy::ref");
@@ -325,18 +312,18 @@ const value mkrefProxy(const value& ref, const list<value>& impls, const SSLConf
// Use an HTTP proxy or an internal proxy to the component implementation
if (wbyimpl)
- return mkimplProxy(value(), impls, sslc, timeout);
+ return mkimplProxy(nilValue, impls, sslc, timeout);
if (isNil(target))
return mkunwiredProxy(scdl::name(ref));
if (http::isAbsolute(target))
- return mkhttpProxy(target, timeout, p);
+ return mkhttpProxy(target, timeout);
return mkimplProxy(car(pathValues(target)), impls, sslc, timeout);
}
-const list<value> refProxies(const list<value>& refs, const list<value>& impls, const SSLConf& sslc, const int timeout, const gc_pool& p) {
+const list<value> refProxies(const list<value>& refs, const gc_mutable_ref<list<value> >& impls, const SSLConf& sslc, const int timeout) {
if (isNil(refs))
return refs;
- return cons(mkrefProxy(car(refs), impls, sslc, timeout, p), refProxies(cdr(refs), impls, sslc, timeout, p));
+ return cons(mkrefProxy(car(refs), impls, sslc, timeout), refProxies(cdr(refs), impls, sslc, timeout));
}
/**
@@ -344,75 +331,56 @@ const list<value> refProxies(const list<value>& refs, const list<value>& impls,
* the property value. The host, user and email properties are configured with the values
* from the HTTP request, if any.
*/
-struct propProxy {
- const value v;
- propProxy(const value& v) : v(v) {
- }
- const value operator()(unused const list<value>& params) const {
+const lvvlambda mkvaluePropProxy(const value& v) {
+ return [v](unused const list<value>& params) -> const value {
return v;
- }
-};
+ };
+}
-struct hostPropProxy {
- const value v;
- hostPropProxy(const value& v) : v(v) {
- }
- const value operator()(unused const list<value>& params) const {
+const lvvlambda mkhostPropProxy(const value& v) {
+ return [v](unused const list<value>& params) -> const value {
if (currentRequest == NULL)
return http::hostName();
const value h = httpd::hostName(currentRequest, v);
debug(h, "modeval::hostPropProxy::value");
return h;
- }
-};
+ };
+}
-struct appPropProxy {
- const value v;
- appPropProxy(const value& v) : v(v) {
- }
- const value operator()(unused const list<value>& params) const {
+const lvvlambda mkappPropProxy(const value& v) {
+ return [v](unused const list<value>& params) -> const value {
if (currentRequest == NULL)
return v;
const RequestConf& reqc = httpd::requestConf<RequestConf>(currentRequest, &mod_tuscany_eval);
- const value a = isNil(reqc.vpath)? v : car(reqc.vpath);
+ const value a = isNil((const list<value>)reqc.vpath)? v : car((const list<value>)reqc.vpath);
debug(a, "modeval::appPropProxy::value");
return a;
- }
-};
+ };
+}
-struct pathPropProxy {
- const value v;
- pathPropProxy(const value& v) : v(v) {
- }
- const value operator()(unused const list<value>& params) const {
+const lvvlambda mkpathPropProxy(const value& v) {
+ return [v](unused const list<value>& params) -> const value {
if (currentRequest == NULL)
return v;
const RequestConf& reqc = httpd::requestConf<RequestConf>(currentRequest, &mod_tuscany_eval);
- const value p = reqc.rpath;
+ const value p = (const list<value>)reqc.rpath;
debug(p, "modeval::pathPropProxy::value");
return p;
- }
-};
+ };
+}
-struct queryPropProxy {
- const value v;
- queryPropProxy(const value& v) : v(v) {
- }
- const value operator()(unused const list<value>& params) const {
+const lvvlambda mkqueryPropProxy(const value& v) {
+ return [v](unused const list<value>& params) -> const value {
if (currentRequest == NULL)
return v;
const value q = httpd::unescapeArgs(httpd::queryArgs(currentRequest));
debug(q, "modeval::queryPropProxy::value");
return q;
- }
-};
+ };
+}
-struct envPropProxy {
- const string name;
- const value v;
- envPropProxy(const string& name, const value& v) : name(name), v(v) {
- }
- const value operator()(unused const list<value>& params) const {
+const lvvlambda mkenvPropProxy(const string& name, const value& v) {
+ return [name, v](unused const list<value>& params) -> const value {
if (currentRequest == NULL)
return v;
const char* env = apr_table_get(currentRequest->subprocess_env, c_str(name));
@@ -422,14 +390,11 @@ struct envPropProxy {
const value e = string(env);
debug(e, "modeval::envPropProxy::value");
return e;
- }
-};
+ };
+}
-struct realmPropProxy {
- const value v;
- realmPropProxy(const value& v) : v(v) {
- }
- const value operator()(unused const list<value>& params) const {
+const lvvlambda mkrealmPropProxy(const value& v) {
+ return [v](unused const list<value>& params) -> const value {
if (currentRequest == NULL)
return v;
const char* env = apr_table_get(currentRequest->subprocess_env, "REALM");
@@ -441,28 +406,22 @@ struct realmPropProxy {
const value r = realm;
debug(r, "modeval::realmPropProxy::value");
return r;
- }
-};
+ };
+}
-struct timeoutPropProxy {
- const value v;
- timeoutPropProxy(const value& v) : v(atoi(c_str((string)v))) {
- }
- const value operator()(unused const list<value>& params) const {
+const lvvlambda mktimeoutPropProxy(const value& v) {
+ return [v](unused const list<value>& params) -> const value {
if (currentRequest == NULL)
return v;
const ServerConf& sc = httpd::serverConf<ServerConf>(currentRequest, &mod_tuscany_eval);
const value r = sc.timeout;
debug(r, "modeval::timeoutPropProxy::value");
return r;
- }
-};
+ };
+}
-struct userPropProxy {
- const value v;
- userPropProxy(const value& v) : v(v) {
- }
- const value operator()(unused const list<value>& params) const {
+const lvvlambda mkuserPropProxy(const value& v) {
+ return [v](unused const list<value>& params) -> const value {
if (currentRequest == NULL)
return v;
if (currentRequest->user == NULL)
@@ -470,37 +429,37 @@ struct userPropProxy {
const value u = string(currentRequest->user);
debug(u, "modeval::userPropProxy::value");
return u;
- }
-};
+ };
+}
const value mkpropProxy(const value& prop) {
const value n = scdl::name(prop);
- const value v = elementHasValue(prop)? elementValue(prop):value(string(""));
+ const value v = elementHasValue(prop)? elementValue(prop) : emptyStringValue;
if (n == "app")
- return lambda<value(const list<value>&)>(appPropProxy(v));
+ return mkappPropProxy(v);
if (n == "host")
- return lambda<value(const list<value>&)>(hostPropProxy(v));
+ return mkhostPropProxy(v);
if (n == "path")
- return lambda<value(const list<value>&)>(pathPropProxy(v));
+ return mkpathPropProxy(v);
if (n == "query")
- return lambda<value(const list<value>&)>(queryPropProxy(v));
+ return mkqueryPropProxy(v);
if (n == "user")
- return lambda<value(const list<value>&)>(userPropProxy(v));
+ return mkuserPropProxy(v);
if (n == "realm")
- return lambda<value(const list<value>&)>(realmPropProxy(v));
+ return mkrealmPropProxy(v);
if (n == "timeout")
- return lambda<value(const list<value>&)>(timeoutPropProxy(v));
+ return mktimeoutPropProxy(v);
if (n == "email")
- return lambda<value(const list<value>&)>(envPropProxy("EMAIL", v));
+ return mkenvPropProxy("EMAIL", v);
if (n == "nickname")
- return lambda<value(const list<value>&)>(envPropProxy("NICKNAME", v));
+ return mkenvPropProxy("NICKNAME", v);
if (n == "fullname")
- return lambda<value(const list<value>&)>(envPropProxy("FULLNAME", v));
+ return mkenvPropProxy("FULLNAME", v);
if (n == "firstname")
- return lambda<value(const list<value>&)>(envPropProxy("FIRSTNAME", v));
+ return mkenvPropProxy("FIRSTNAME", v);
if (n == "lastname")
- return lambda<value(const list<value>&)>(envPropProxy("LASTNAME", v));
- return lambda<value(const list<value>&)>(propProxy(v));
+ return mkenvPropProxy("LASTNAME", v);
+ return mkvaluePropProxy(v);
}
const list<value> propProxies(const list<value>& props) {
@@ -512,51 +471,45 @@ const list<value> propProxies(const list<value>& props) {
/**
* Evaluate a component and convert it to an applicable lambda function.
*/
-struct implementationFailure {
- const value reason;
- implementationFailure(const value& r) : reason(r) {
- }
-
- // Default implementation representing an implementation that
- // couldn't be evaluated. Report the evaluation error on all
- // subsequent calls expect start/stop.
- const value operator()(unused const list<value>& params) const {
- const value func = car(params);
- if (func == "start" || func == "stop")
- return mklist<value>(lambda<value(const list<value>&)>());
- return mklist<value>(value(), reason);
- }
-};
-
-const value evalComponent(const string& contribPath, const value& comp, const list<value>& impls, const lambda<value(const list<value>&)> lifecycle, const SSLConf& sslc, const int timeout, const gc_pool& p) {
- extern const failable<lambda<value(const list<value>&)> > evalImplementation(const string& cpath, const value& impl, const list<value>& px, const lambda<value(const list<value>&)>& lifecycle);
+const value evalComponent(const string& contribPath, const value& comp, const gc_mutable_ref<list<value> >& impls, const lvvlambda& lifecycle, const SSLConf& sslc, const int timeout) {
+ extern const failable<lvvlambda > evalImplementation(const string& cpath, const value& impl, const list<value>& px, const lvvlambda& lifecycle);
const value impl = scdl::implementation(comp);
debug(comp, "modeval::evalComponent::comp");
debug(impl, "modeval::evalComponent::impl");
// Convert component references to configured proxy lambdas
- const list<value> rpx(refProxies(scdl::references(comp), impls, sslc, timeout, p));
+ const list<value> rpx(refProxies(scdl::references(comp), impls, sslc, timeout));
// Convert component properties to configured proxy lambdas
const list<value> ppx(propProxies(scdl::properties(comp)));
// Evaluate the component implementation and convert it to an applicable lambda function
- const failable<lambda<value(const list<value>&)> > cimpl(evalImplementation(contribPath, impl, append(rpx, ppx), lifecycle));
- if (!hasContent(cimpl))
- return lambda<value(const list<value>&)>(implementationFailure(reason(cimpl)));
+ const failable<lvvlambda > cimpl(evalImplementation(contribPath, impl, append(rpx, ppx), lifecycle));
+ if (!hasContent(cimpl)) {
+ // Return a lambda function which will report a component evaluation failure
+ // on all subsequent calls expect start/stop
+ const value r = reason(cimpl);
+ const lvvlambda implementationFailure = [r](const list<value>& params) -> const value {
+ const value func = car(params);
+ if (func == "start" || func == "stop")
+ return mklist<value>(lvvlambda());
+ return mklist<value>(nilValue, r);
+ };
+ return implementationFailure;
+ }
return content(cimpl);
}
/**
* Return a list of component-name + configured-implementation pairs.
*/
-const list<value> componentToImplementationAssoc(const list<value>& c, const string& contribPath, const list<value>& impls, const lambda<value(const list<value>&)> lifecycle, const SSLConf& sslc, const int timeout, const gc_pool& p) {
+const list<value> componentToImplementationAssoc(const list<value>& c, const string& contribPath, const gc_mutable_ref<list<value> >& impls, const lvvlambda& lifecycle, const SSLConf& sslc, const int timeout) {
if (isNil(c))
return c;
return cons<value>(mklist<value>(scdl::name(car(c)),
- evalComponent(contribPath, car(c), impls, lifecycle, sslc, timeout, p)),
- componentToImplementationAssoc(cdr(c), contribPath, impls, lifecycle, sslc, timeout, p));
+ evalComponent(contribPath, car(c), impls, lifecycle, sslc, timeout)),
+ componentToImplementationAssoc(cdr(c), contribPath, impls, lifecycle, sslc, timeout));
}
/**
@@ -566,24 +519,28 @@ const failable<list<value> > readComponents(const string& path) {
ifstream is(path);
if (fail(is))
return mkfailure<list<value> >(string("Could not read composite: ") + path);
- return scdl::components(readXML(streamList(is)));
+ return scdl::components(content(xml::readElements(streamList(is))));
}
/**
* Get the components returned by a contributor.
*/
-const failable<list<value> > getComponents(const lambda<value(const list<value>&)>& contributor, const string& name) {
+const failable<list<value> > getComponents(const lvvlambda& contributor, const string& name) {
const failable<value> val = failableResult(contributor(cons<value>("get", mklist<value>(mklist<value>(name)))));
if (!hasContent(val))
return mkfailure<list<value> >(val);
- const list<value> c = assoc<value>(value("composite"), assoc<value>(value("content"), (list<list<value> >)cdr<value>(car<value>(content(val)))));
- debug(c, "modeval::getComponents::comp");
- if (isNil(c))
+ debug(content(val), "modeval::getComponents::val");
+ const list<value> valc = assoc<value>(value("content"), cdr<value>(car<value>(content(val))));
+ if (isNil(valc))
+ return mkfailure<list<value> >(string("Could not get composite: ") + name);
+ const list<value> comp = assoc<value>(value("composite"), cdr<value>(valc));
+ debug(comp, "modeval::getComponents::comp");
+ if (isNil(comp))
return mkfailure<list<value> >(string("Could not get composite: ") + name);
- const failable<list<string> > x = writeXML(car<value>(valuesToElements(mklist<value>(mklist<value>(c)))));
+ const failable<list<string> > x = xml::writeElements(car<value>(valuesToElements(mklist<value>(mklist<value>(comp)))));
if (!hasContent(x))
return mkfailure<list<value> >(x);
- return scdl::components(readXML(content(x)));
+ return scdl::components(content(xml::readElements(content(x))));
}
/**
@@ -592,17 +549,17 @@ const failable<list<value> > getComponents(const lambda<value(const list<value>&
*/
const failable<list<value> > applyLifecycleExpr(const list<value>& impls, const list<value>& expr) {
if (isNil(impls))
- return list<value>();
+ return nilListValue;
// Evaluate lifecycle expression against a component implementation lambda
- const lambda<value(const list<value>&)> l = cadr<value>(car(impls));
+ const lvvlambda l = cadr<value>(car(impls));
const failable<value> r = failableResult(l(expr));
if (!hasContent(r))
return mkfailure<list<value> >(r);
- const lambda<value(const list<value>&)> rl = content(r);
+ const lvvlambda rl = content(r);
// Use the returned lambda function, if any, from now on
- const lambda<value(const list<value>&)> al = isNil(rl)? l : rl;
+ const lvvlambda al = isNil(rl)? l : rl;
// Continue with the rest of the list
const failable<list<value> > nr = applyLifecycleExpr(cdr(impls), expr);
@@ -661,7 +618,7 @@ const list<value> uriToComponentAssoc(const list<value>& c) {
/**
* Configure the components declared in the deployed composite.
*/
-const failable<Composite> confComponents(const string& contribPath, const string& composName, const value& contributor, const string& vhost, const list<value>& impls, const lambda<value(const list<value>&)> lifecycle, const SSLConf& sslc, const int timeout, const gc_pool& p) {
+const failable<Composite> confComponents(const string& contribPath, const string& composName, const value& contributor, const string& vhost, const gc_mutable_ref<list<value> >& impls, const lvvlambda lifecycle, const SSLConf& sslc, const int timeout) {
debug(contribPath, "modeval::confComponents::contribPath");
debug(composName, "modeval::confComponents::composName");
debug(contributor, "modeval::confComponents::contributor");
@@ -685,7 +642,7 @@ const failable<Composite> confComponents(const string& contribPath, const string
const list<value> cimpls = mkbtree(sort(componentToImplementationAssoc(comps,
isNil(contributor)? length(vhost) != 0? contribPath + vhost + "/" : contribPath : contribPath,
- impls, lifecycle, sslc, timeout, p)));
+ impls, lifecycle, sslc, timeout)));
debug(flatten(cimpls), "modeval::confComponents::impls");
return Composite(refs, svcs, cimpls);
@@ -715,13 +672,31 @@ const failable<bool> stopComponents(const list<value>& simpls) {
}
/**
+ * Returns the media type accepted by a client.
+ */
+const value acceptMediaType(request_rec* const r) {
+ const char* const xa = apr_table_get(r->headers_in, "X-Accept");
+ const char* const a = xa != NULL? xa : apr_table_get(r->headers_in, "Accept");
+ if (a == NULL)
+ return nilValue;
+ const string s(a);
+ if (contains(s, "text/x-scheme"))
+ return string("scheme");
+ if (contains(s, "application/json"))
+ return string("json");
+ if (contains(s, "text/xml"))
+ return string("xml");
+ return nilValue;
+}
+
+/**
* Handle an HTTP GET.
*/
-const failable<int> get(const list<value>& rpath, request_rec* r, const lambda<value(const list<value>&)>& impl) {
+const failable<int> get(const list<value>& rpath, request_rec* const r, const lvvlambda& impl) {
debug(r->uri, "modeval::get::uri");
// Inspect the query string
- const list<list<value> > args = httpd::queryArgs(r);
+ const list<list<value> > args = httpd::unescapeArgs(httpd::queryArgs(r));
const list<value> ia = assoc(value("id"), args);
const list<value> ma = assoc(value("method"), args);
@@ -738,12 +713,11 @@ const failable<int> get(const list<value>& rpath, request_rec* r, const lambda<v
return mkfailure<int>(val);
// Return JSON result
- js::JSContext cx;
- return httpd::writeResult(json::jsonResult(id, content(val), cx), "application/json-rpc; charset=utf-8", r);
+ return httpd::writeResult(json::jsonResult(id, content(val)), "application/json-rpc; charset=utf-8", r);
}
// Evaluate the GET expression
- const list<value> params(cddr(rpath));
+ const list<value> params(append<value>(cddr(rpath), mkvalues(args)));
const failable<value> val = failableResult(impl(cons<value>("get", mklist<value>(params))));
if (!hasContent(val))
return mkfailure<int>(val);
@@ -754,58 +728,42 @@ const failable<int> get(const list<value>& rpath, request_rec* r, const lambda<v
if (!isList(c) && isNil(c))
return HTTP_NOT_FOUND;
- // Check if the client requested a specific format
+ // Write in the format requested by the client, if any
const list<value> fmt = assoc<value>("format", args);
-
- // Write as a scheme value if requested by the client
- if (!isNil(fmt) && cadr(fmt) == "scheme")
- return httpd::writeResult(mklist<string>(scheme::writeValue(c)), "text/plain; charset=utf-8", r);
+ const value mtype = !isNil(fmt)? cadr(fmt) : acceptMediaType(r);
+ if (!isNil(mtype)) {
+ if (mtype == "scheme")
+ return httpd::writeResult(scheme::writeValue(c), "text/x-scheme; charset=utf-8", r);
+ if (mtype == "json")
+ return httpd::writeResult(json::writeValue(c), "application/json; charset=utf-8", r);
+ if (mtype == "xml")
+ return httpd::writeResult(xml::writeElements(valuesToElements(c)), "text/xml; charset=utf-8", r);
+ }
// Write a simple value as a JSON value
if (!isList(c)) {
- js::JSContext cx;
- if (isSymbol(c)) {
- const list<value> lc = mklist<value>(mklist<value>("name", value(string(c))));
- debug(lc, "modeval::get::symbol");
- return httpd::writeResult(json::writeJSON(valuesToElements(lc), cx), "application/json; charset=utf-8", r);
- }
-
- const list<value> lc = mklist<value>(mklist<value>("value", c));
- debug(lc, "modeval::get::value");
- return httpd::writeResult(json::writeJSON(valuesToElements(lc), cx), "application/json; charset=utf-8", r);
+ debug(c, "modeval::get::value");
+ return httpd::writeResult(json::writeValue(c), "application/json; charset=utf-8", r);
}
- // Write an empty list as a JSON empty value
+ // Write an empty list as a JSON value
if (isNil((list<value>)c)) {
- js::JSContext cx;
- debug(list<value>(), "modeval::get::empty");
- return httpd::writeResult(json::writeJSON(list<value>(), cx), "application/json; charset=utf-8", r);
+ debug(nilListValue, "modeval::get::empty");
+ return httpd::writeResult(json::writeValue(c), "application/json; charset=utf-8", r);
}
// Write content-type / content-list pair
if (isString(car<value>(c)) && !isNil(cdr<value>(c)) && isList(cadr<value>(c)))
return httpd::writeResult(convertValues<string>(cadr<value>(c)), car<value>(c), r);
- // Write an assoc value as a JSON result
+ // Write an assoc value as a JSON value
if (isSymbol(car<value>(c)) && !isNil(cdr<value>(c))) {
- js::JSContext cx;
- const list<value> lc = mklist<value>(c);
- debug(lc, "modeval::get::assoc");
- debug(valuesToElements(lc), "modeval::get::assoc::element");
- return httpd::writeResult(json::writeJSON(valuesToElements(lc), cx), "application/json; charset=utf-8", r);
- }
-
- // Write value as JSON if requested by the client
- if (!isNil(fmt) && cadr(fmt) == "json") {
- js::JSContext cx;
- return httpd::writeResult(json::writeJSON(valuesToElements(c), cx), "application/json; charset=utf-8", r);
+ debug(c, "modeval::get::assoc");
+ return httpd::writeResult(json::writeValue(c), "application/json; charset=utf-8", r);
}
- // Convert list of values to element values
- const list<value> e = valuesToElements(c);
- debug(e, "modeval::get::elements");
-
// Write an ATOM feed or entry
+ const list<value> e = valuesToElements(c);
if (isList(car<value>(e)) && !isNil(car<value>(e))) {
const list<value> el = car<value>(e);
if (isSymbol(car<value>(el)) && car<value>(el) == element && !isNil(cdr<value>(el)) && isSymbol(cadr<value>(el)) && elementHasChildren(el) && !elementHasValue(el)) {
@@ -817,14 +775,13 @@ const failable<int> get(const list<value>& rpath, request_rec* r, const lambda<v
}
// Write any other compound value as a JSON value
- js::JSContext cx;
- return httpd::writeResult(json::writeJSON(e, cx), "application/json; charset=utf-8", r);
+ return httpd::writeResult(json::writeValue(c), "application/json; charset=utf-8", r);
}
/**
* Handle an HTTP POST.
*/
-const failable<int> post(const list<value>& rpath, request_rec* r, const lambda<value(const list<value>&)>& impl) {
+const failable<int> post(const list<value>& rpath, request_rec* const r, const lvvlambda& impl) {
debug(r->uri, "modeval::post::uri");
// Evaluate a JSON-RPC request and return a JSON result
@@ -837,9 +794,8 @@ const failable<int> post(const list<value>& rpath, request_rec* r, const lambda<
return rc;
const list<string> ls = httpd::read(r);
debug(ls, "modeval::post::input");
- js::JSContext cx;
- const list<value> json = elementsToValues(content(json::readJSON(ls, cx)));
- const list<list<value> > args = httpd::postArgs(json);
+ const value jsreq = content(json::readValue(ls));
+ const list<list<value> > args = httpd::postArgs(jsreq);
// Extract the request id, method and params
const value id = cadr(assoc(value("id"), args));
@@ -852,7 +808,7 @@ const failable<int> post(const list<value>& rpath, request_rec* r, const lambda<
return mkfailure<int>(val);
// Return JSON result
- return httpd::writeResult(json::jsonResult(id, content(val), cx), "application/json-rpc; charset=utf-8", r);
+ return httpd::writeResult(json::jsonResult(id, content(val)), "application/json-rpc; charset=utf-8", r);
}
// Evaluate an ATOM POST request and return the location of the corresponding created resource
@@ -871,14 +827,21 @@ const failable<int> post(const list<value>& rpath, request_rec* r, const lambda<
if (!hasContent(val))
return mkfailure<int>(val);
- // Return the created resource location
- debug(content(val), "modeval::post::location");
- apr_table_setn(r->headers_out, "Location", apr_pstrdup(r->pool, c_str(httpd::url(r->uri, content(val), r))));
+ // Report HTTP status code
+ const value rval = content(val);
+ if (isNil(rval) || rval == falseValue)
+ return HTTP_NOT_FOUND;
+ if (isNumber(rval))
+ return (int)rval;
+
+ // Return the successfully created resource location
+ debug(rval, "modeval::post::location");
+ apr_table_setn(r->headers_out, "Location", apr_pstrdup(r->pool, c_str(httpd::url(r->uri, rval, r))));
r->status = HTTP_CREATED;
return OK;
}
- // Unknown content type, wrap the HTTP request struct in a value and pass it to
+ // Unknown content type, wrap the HTTP request structure in a value and pass it to
// the component implementation function
const failable<value> val = failableResult(impl(cons<value>("handle", mklist<value>(httpd::requestValue(r)))));
if (!hasContent(val))
@@ -889,7 +852,7 @@ const failable<int> post(const list<value>& rpath, request_rec* r, const lambda<
/**
* Handle an HTTP PUT.
*/
-const failable<int> put(const list<value>& rpath, request_rec* r, const lambda<value(const list<value>&)>& impl) {
+const failable<int> put(const list<value>& rpath, request_rec* const r, const lvvlambda& impl) {
debug(r->uri, "modeval::put::uri");
// Read the ATOM entry
@@ -904,35 +867,45 @@ const failable<int> put(const list<value>& rpath, request_rec* r, const lambda<v
const failable<value> val = failableResult(impl(cons<value>("put", mklist<value>(cddr(rpath), aval))));
if (!hasContent(val))
return mkfailure<int>(val);
- if (val == value(false))
+
+ // Report HTTP status
+ const value rval = content(val);
+ if (isNil(rval) || rval == falseValue)
return HTTP_NOT_FOUND;
+ if (isNumber(rval))
+ return (int)rval;
return OK;
}
/**
* Handle an HTTP DELETE.
*/
-const failable<int> del(const list<value>& rpath, request_rec* r, const lambda<value(const list<value>&)>& impl) {
+const failable<int> del(const list<value>& rpath, request_rec* const r, const lvvlambda& impl) {
debug(r->uri, "modeval::delete::uri");
// Evaluate an ATOM delete request
const failable<value> val = failableResult(impl(cons<value>("delete", mklist<value>(cddr(rpath)))));
if (!hasContent(val))
return mkfailure<int>(val);
- if (val == value(false))
+
+ // Report HTTP status
+ const value rval = content(val);
+ if (isNil(rval) || rval == falseValue)
return HTTP_NOT_FOUND;
+ if (isNumber(rval))
+ return (int)rval;
return OK;
}
/**
* Proceed to handle a service component request.
*/
-int proceedToHandler(request_rec* r, const int rc) {
+int proceedToHandler(request_rec* const r, const int rc) {
r->handler = "mod_tuscany_eval";
return rc;
}
-int proceedToHandler(request_rec* r, const int rc, const bool valias, const list<value>& rpath, const list<value>& vpath, const list<value>& impls) {
+int proceedToHandler(request_rec* const r, const int rc, const bool valias, const list<value>& rpath, const list<value>& vpath, const list<value>& impls) {
r->handler = "mod_tuscany_eval";
r->filename = apr_pstrdup(r->pool, c_str(string("/redirect:") + r->uri));
@@ -948,7 +921,7 @@ int proceedToHandler(request_rec* r, const int rc, const bool valias, const list
/**
* Route a component request to the specified component.
*/
-int translateComponent(request_rec *r, const list<value>& rpath, const list<value>& vpath, const list<value>& impls) {
+int translateComponent(request_rec* const r, const list<value>& rpath, const list<value>& vpath, const list<value>& impls) {
debug(rpath, "modeval::translateComponent::rpath");
debug(flatten(impls), "modeval::translateComponent::impls");
@@ -967,7 +940,7 @@ int translateComponent(request_rec *r, const list<value>& rpath, const list<valu
* Route a /references/component-name/reference-name request,
* to the target of the component reference.
*/
-int translateReference(request_rec *r, const list<value>& rpath, const list<value>& vpath, const list<value>& refs, const list<value>& impls) {
+int translateReference(request_rec* const r, const list<value>& rpath, const list<value>& vpath, const list<value>& refs, const list<value>& impls) {
debug(rpath, "modeval::translateReference::rpath");
debug(flatten(refs), "modeval::translateReference::refs");
@@ -991,7 +964,7 @@ int translateReference(request_rec *r, const list<value>& rpath, const list<valu
// Route to an absolute target URI using mod_proxy or an HTTP client redirect
const list<value> pathInfo = cdddr(rpath);
if (http::isAbsolute(target)) {
- string turi = target + path(pathInfo) + (r->args != NULL? string("?") + string(r->args) : string(""));
+ const string turi = target + (string)path(pathInfo) + (r->args != NULL? string("?") + string(r->args) : emptyString);
const string proxy(string("proxy:") + turi);
debug(proxy, "modeval::translateReference::proxy");
r->filename = apr_pstrdup(r->pool, c_str(proxy));
@@ -1035,7 +1008,7 @@ const list<value> assocPath(const value& k, const list<value>& tree) {
/**
* Route a service request to the component providing the requested service.
*/
-int translateService(request_rec *r, const list<value>& rpath, const list<value>& vpath, const list<value>& svcs, const list<value>& impls) {
+int translateService(request_rec* const r, const list<value>& rpath, const list<value>& vpath, const list<value>& svcs, const list<value>& impls) {
debug(rpath, "modeval::translateService::rpath");
debug(flatten(svcs), "modeval::translateService::svcs");
@@ -1057,10 +1030,10 @@ int translateService(request_rec *r, const list<value>& rpath, const list<value>
/**
* Translate a request to the target app and component.
*/
-const int translateRequest(request_rec* r, const list<value>& rpath, const list<value>& vpath, const list<value>& refs, const list<value>& svcs, const list<value>& impls) {
+const int translateRequest(request_rec* const r, const list<value>& rpath, const list<value>& vpath, const list<value>& refs, const list<value>& svcs, const list<value>& impls) {
debug(vpath, "modeval::translateRequest::vpath");
debug(rpath, "modeval::translateRequest::rpath");
- const string prefix = isNil(rpath)? "" : car(rpath);
+ const string prefix = isNil(rpath)? emptyStringValue : car(rpath);
// Translate a component request
if ((prefix == string("components") || prefix == string("c")) && translateComponent(r, rpath, vpath, impls) == OK)
@@ -1079,7 +1052,7 @@ const int translateRequest(request_rec* r, const list<value>& rpath, const list<
const failable<request_rec*> fnr = httpd::internalSubRequest(r->uri, r);
if (!hasContent(fnr))
return rcode(fnr);
- request_rec* nr = content(fnr);
+ request_rec* const nr = content(fnr);
nr->uri = r->filename;
const int tr = ap_core_translate(nr);
if (tr != OK)
@@ -1095,7 +1068,7 @@ const int translateRequest(request_rec* r, const list<value>& rpath, const list<
// Make sure a document root request ends with a '/' using
// an external redirect
if (isNil(rpath) && r->uri[strlen(r->uri) - 1] != '/') {
- const string target = string(r->uri) + string("/") + (r->args != NULL? string("?") + string(r->args) : string(""));
+ const string target = string(r->uri) + string("/") + (r->args != NULL? string("?") + string(r->args) : emptyString);
debug(target, "modeval::translateRequest::location");
return proceedToHandler(r, httpd::externalRedirect(target, r));
}
@@ -1117,8 +1090,7 @@ int translate(request_rec *r) {
if(r->method_number != M_GET && r->method_number != M_POST && r->method_number != M_PUT && r->method_number != M_DELETE)
return DECLINED;
- gc_scoped_pool pool(r->pool);
-
+ const gc_scoped_pool sp(r->pool);
debug_httpdRequest(r, "modeval::translate::input");
// Get the server configuration
@@ -1128,7 +1100,7 @@ int translate(request_rec *r) {
const list<value> rpath = pathValues(r->uri);
// Let default handler handle a resource request
- const string prefix = isNil(rpath)? "" : car(rpath);
+ const string prefix = isNil(rpath)? emptyStringValue : car(rpath);
if (prefix == string("vhosts") || prefix == string("v"))
return DECLINED;
@@ -1139,7 +1111,7 @@ int translate(request_rec *r) {
// in that virtual host
if (length(sc.vhostc.domain) != 0 && (length(sc.vhostc.contribPath) != 0 || !isNil(sc.vhostc.contributor)) && httpd::isVhostRequest(sc.server, sc.vhostc.domain, r)) {
const string vname = http::subDomain(httpd::hostName(r));
- const failable<Composite> fvcompos = confComponents(sc.vhostc.contribPath, sc.vhostc.composName, sc.vhostc.contributor, vname, reqc.impls, sc.lifecycle, sc.sslc, sc.timeout, sc.p);
+ const failable<Composite> fvcompos = confComponents(sc.vhostc.contribPath, sc.vhostc.composName, sc.vhostc.contributor, vname, reqc.impls, (value)sc.lifecycle, sc.sslc, sc.timeout);
if (!hasContent(fvcompos))
return DECLINED;
const Composite vcompos = content(fvcompos);
@@ -1153,14 +1125,14 @@ int translate(request_rec *r) {
}
// Translate a request targeting the main host
- const int rc = translateRequest(r, rpath, list<value>(), sc.compos.refs, sc.compos.svcs, sc.compos.impls);
+ const int rc = translateRequest(r, rpath, nilListValue, sc.compos.refs, sc.compos.svcs, sc.compos.impls);
if (rc != HTTP_NOT_FOUND)
return rc;
// Attempt to map the first segment of the request path to a virtual host
if (length(prefix) != 0 && (length(sc.vhostc.contribPath) != 0 || !isNil(sc.vhostc.contributor))) {
const string vname = prefix;
- const failable<Composite> fvcompos = confComponents(sc.vhostc.contribPath, sc.vhostc.composName, sc.vhostc.contributor, vname, reqc.impls, sc.lifecycle, sc.sslc, sc.timeout, sc.p);
+ const failable<Composite> fvcompos = confComponents(sc.vhostc.contribPath, sc.vhostc.composName, sc.vhostc.contributor, vname, reqc.impls, (value)sc.lifecycle, sc.sslc, sc.timeout);
if (!hasContent(fvcompos))
return DECLINED;
const Composite vcompos = content(fvcompos);
@@ -1175,16 +1147,16 @@ int translate(request_rec *r) {
/**
* Handle a component request.
*/
-const int handleRequest(const list<value>& rpath, request_rec *r, const list<value>& impls) {
+const int handleRequest(const list<value>& rpath, request_rec* const r, const list<value>& impls) {
debug(rpath, "modeval::handleRequest::path");
// Get the component implementation lambda
const list<value> impl(assoctree<value>(cadr(rpath), impls));
if (isNil(impl)) {
- mkfailure<int>(string("Couldn't find component implementation: ") + cadr(rpath));
+ mkfailure<int>(string("Couldn't find component implementation: ") + (string)cadr(rpath));
return HTTP_NOT_FOUND;
}
- const lambda<value(const list<value>&)> l(cadr<value>(impl));
+ const lvvlambda l(cadr<value>(impl));
// Handle HTTP method
if (r->header_only)
@@ -1203,7 +1175,7 @@ const int handleRequest(const list<value>& rpath, request_rec *r, const list<val
/**
* HTTP request handler.
*/
-int handler(request_rec *r) {
+int handler(request_rec* r) {
if (r->handler != NULL && r->handler[0] != '\0')
return DECLINED;
@@ -1217,7 +1189,7 @@ int handler(request_rec *r) {
return DECLINED;
// Create a scope for the current request
- gc_scoped_pool pool(r->pool);
+ const gc_scoped_pool sp(r->pool);
ScopedRequest sr(r);
debug_httpdRequest(r, "modeval::handler::input");
@@ -1227,18 +1199,18 @@ int handler(request_rec *r) {
// Handle an internal redirect as directed by the translate hook
if (reqc.valias) {
- const string redir = path(cons<value>(string("v"), reqc.vhost? reqc.vpath : list<value>())) + string(r->uri) + (r->args != NULL? string("?") + string(r->args) : string(""));
+ const string redir = path(cons<value>(string("v"), reqc.vhost? (const list<value>)reqc.vpath : nilListValue)) + string(r->uri) + (r->args != NULL? string("?") + string(r->args) : emptyString);
debug(redir, "modeval::handler::internalredirect");
return httpd::internalRedirect(redir, r);
}
- if (isNil(reqc.rpath))
+ if (isNil((const list<value>)reqc.rpath))
return HTTP_NOT_FOUND;
// Get the server configuration
const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_eval);
// Handle a request targeting a component in a virtual host
- if (!isNil(reqc.vpath)) {
+ if (!isNil((const list<value>)reqc.vpath)) {
// Start the components in the virtual host
const failable<list<value> > fsimpls = startComponents(reqc.impls);
@@ -1247,7 +1219,7 @@ int handler(request_rec *r) {
const list<value> simpls = content(fsimpls);
// Merge the components in the virtual host with the components in the main host
- reqc.impls = mkbtree(sort(append(flatten(sc.compos.impls), flatten(simpls))));
+ reqc.impls = mkbtree(sort(append(flatten((const list<value>)sc.compos.impls), flatten(simpls))));
// Handle the request against the running components
const int rc = handleRequest(reqc.rpath, r, reqc.impls);
@@ -1265,7 +1237,7 @@ int handler(request_rec *r) {
* Call an authenticator component to check a user's password.
*/
authn_status checkPassword(request_rec* r, const char* u, const char* p) {
- gc_scoped_pool pool(r->pool);
+ const gc_scoped_pool sp(r->pool);
// Prevent FakeBasicAuth spoofing
const string user = u;
@@ -1285,16 +1257,16 @@ authn_status checkPassword(request_rec* r, const char* u, const char* p) {
// Retrieve the user's password hash
const list<value> uid = pathValues(user);
- const failable<value> val = failableResult(sc.vhostc.authenticator(cons<value>("get", mklist<value>(uid))));
+ const failable<value> val = failableResult(((value)sc.vhostc.authenticator)(cons<value>("get", mklist<value>(uid))));
if (!hasContent(val)) {
- mkfailure<int>(string("SCA authentication check user failed, user not found: ") + user);
+ mkfailure<int>(string("SCA authentication check user failed, user not found: ") + user, rcode(val), user != "admin");
return AUTH_USER_NOT_FOUND;
}
const value hval = content(val);
- const list<value> hcontent = isList(hval) && !isNil(hval) && isList(car<value>(hval)) && !isNil(car<value>(hval))? assoc<value>(value("content"), cdr<value>(car<value>(hval))) : list<value>();
- const list<value> hassoc = isNil(hcontent)? list<value>() : assoc<value>(value("hash"), cdr<value>(hcontent));
+ const list<value> hcontent = isList(hval) && !isNil(hval) && isList(car<value>(hval)) && !isNil(car<value>(hval))? assoc<value>(value("content"), cdr<value>(car<value>(hval))) : nilListValue;
+ const list<value> hassoc = isNil(hcontent)? nilListValue : assoc<value>(value("hash"), cdr<value>(hcontent));
if (isNil(hassoc)) {
- mkfailure<int>(string("SCA authentication check user failed, hash not found: ") + user);
+ mkfailure<int>(string("SCA authentication check user failed, hash not found: ") + user, -1, user != "admin");
return AUTH_USER_NOT_FOUND;
}
const string hash = cadr<value>(hassoc);
@@ -1320,7 +1292,7 @@ authn_status checkPassword(request_rec* r, const char* u, const char* p) {
* Cleanup callback, called when the server is stopped or restarted.
*/
apr_status_t serverCleanup(void* v) {
- gc_pool pool;
+ const gc_pool pool;
ServerConf& sc = *(ServerConf*)v;
debug("modeval::serverCleanup");
@@ -1328,10 +1300,14 @@ apr_status_t serverCleanup(void* v) {
stopComponents(sc.compos.impls);
// Call the module lifecycle function
- if (isNil(sc.lifecycle))
+ if (isNil((value)sc.lifecycle))
return APR_SUCCESS;
- debug("modeval::serverCleanup::stop");
- sc.lifecycle(mklist<value>("stop"));
+ const lvvlambda ll = (value)sc.lifecycle;
+ if (isNil(ll))
+ return APR_SUCCESS;
+
+ debug((value)sc.lifecycle, "modeval::serverCleanup::stop");
+ ll(mklist<value>("stop"));
return APR_SUCCESS;
}
@@ -1340,7 +1316,7 @@ apr_status_t serverCleanup(void* v) {
* Called after all the configuration commands have been run.
* Process the server configuration and configure the deployed components.
*/
-const int postConfigMerge(const ServerConf& mainsc, server_rec* s) {
+const int postConfigMerge(const ServerConf& mainsc, server_rec* const s) {
if (s == NULL)
return OK;
ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_eval);
@@ -1348,9 +1324,9 @@ const int postConfigMerge(const ServerConf& mainsc, server_rec* s) {
sc.lifecycle = mainsc.lifecycle;
sc.contribc = mainsc.contribc;
sc.vhostc = mainsc.vhostc;
- if (sc.sslc.ca == "") sc.sslc.ca = mainsc.sslc.ca;
- if (sc.sslc.cert == "") sc.sslc.cert = mainsc.sslc.cert;
- if (sc.sslc.key == "") sc.sslc.key = mainsc.sslc.key;
+ if (sc.sslc.ca == emptyString) sc.sslc.ca = mainsc.sslc.ca;
+ if (sc.sslc.cert == emptyString) sc.sslc.cert = mainsc.sslc.cert;
+ if (sc.sslc.key == emptyString) sc.sslc.key = mainsc.sslc.key;
sc.timeout = mainsc.timeout;
sc.compos = mainsc.compos;
return postConfigMerge(mainsc, s->next);
@@ -1359,7 +1335,7 @@ const int postConfigMerge(const ServerConf& mainsc, server_rec* s) {
int postConfig(apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, server_rec *s) {
extern const value applyLifecycle(const list<value>&);
- gc_scoped_pool pool(p);
+ const gc_scoped_pool sp(p);
// Get the server configuration and determine the server name
ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_eval);
@@ -1388,7 +1364,7 @@ int postConfig(apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp,
const failable<value> r = failableResult(applyLifecycle(mklist<value>("start")));
if (!hasContent(r))
return -1;
- debug("modeval::postConfig::setlifecycle");
+ debug(content(r), "modeval::postConfig::setlifecycle");
sc.lifecycle = content(r);
}
if (count > 1) {
@@ -1396,12 +1372,12 @@ int postConfig(apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp,
const failable<value> r = failableResult(applyLifecycle(mklist<value>("restart")));
if (!hasContent(r))
return -1;
- debug("modeval::postConfig::setlifecycle");
+ debug(content(r), "modeval::postConfig::setlifecycle");
sc.lifecycle = content(r);
}
// Configure the deployed components
- const failable<Composite> compos = confComponents(sc.contribc.contribPath, sc.contribc.composName, value(), "", sc.compos.impls, sc.lifecycle, sc.sslc, sc.timeout, sc.p);
+ const failable<Composite> compos = confComponents(sc.contribc.contribPath, sc.contribc.composName, nilValue, emptyString, sc.compos.impls, (value)sc.lifecycle, sc.sslc, sc.timeout);
if (!hasContent(compos)) {
cfailure << "[Tuscany] Due to one or more errors mod_tuscany_eval loading failed. Causing apache to stop loading." << endl;
return -1;
@@ -1427,9 +1403,9 @@ void failureExitChild() {
* Child process initialization.
*/
void childInit(apr_pool_t* p, server_rec* s) {
- gc_scoped_pool pool(p);
+ const gc_scoped_pool sp(p);
- ServerConf* psc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_eval);
+ ServerConf* const psc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_eval);
if(psc == NULL)
failureExitChild();
ServerConf& sc = *psc;
@@ -1442,7 +1418,7 @@ void childInit(apr_pool_t* p, server_rec* s) {
// Get the vhost contributor component implementation lambda
if (length(sc.vhostc.contributorName) != 0) {
- const list<value> impl(assoctree<value>(sc.vhostc.contributorName, sc.compos.impls));
+ const list<value> impl(assoctree<value>((string)sc.vhostc.contributorName, (const list<value>)sc.compos.impls));
if (isNil(impl)) {
mkfailure<int>(string("Couldn't find contributor component implementation: ") + sc.vhostc.contributorName);
failureExitChild();
@@ -1452,7 +1428,7 @@ void childInit(apr_pool_t* p, server_rec* s) {
// Get the vhost authenticator component implementation lambda
if (length(sc.vhostc.authenticatorName) != 0) {
- const list<value> impl(assoctree<value>(sc.vhostc.authenticatorName, sc.compos.impls));
+ const list<value> impl(assoctree<value>((string)sc.vhostc.authenticatorName, (const list<value>)sc.compos.impls));
if (isNil(impl)) {
mkfailure<int>(string("Couldn't find authenticator component implementation: ") + sc.vhostc.authenticatorName);
failureExitChild();
@@ -1471,73 +1447,73 @@ void childInit(apr_pool_t* p, server_rec* s) {
* Configuration commands.
*/
const char* confContribution(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.contribc.contribPath = arg;
return NULL;
}
const char* confComposite(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.contribc.composName = arg;
return NULL;
}
const char* confVirtualDomain(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.vhostc.domain = arg;
return NULL;
}
const char* confVirtualContribution(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.vhostc.contribPath = arg;
return NULL;
}
const char* confVirtualContributor(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.vhostc.contributorName = arg;
return NULL;
}
const char* confVirtualComposite(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.vhostc.composName = arg;
return NULL;
}
const char* confAuthenticator(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.vhostc.authenticatorName = arg;
return NULL;
}
const char* confCAFile(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.sslc.ca = arg;
return NULL;
}
const char* confCertFile(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.sslc.cert = arg;
return NULL;
}
const char* confCertKeyFile(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.sslc.key = arg;
return NULL;
}
const char* confTimeout(cmd_parms *cmd, unused void *c, const char *arg) {
- gc_scoped_pool pool(cmd->pool);
+ const gc_scoped_pool sp(cmd->pool);
ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval);
sc.timeout = atoi(arg);
return NULL;
}
const char* confEnv(unused cmd_parms *cmd, unused void *c, const char *name, const char *value) {
- gc_scoped_pool pool(cmd->pool);
+ const gc_scoped_pool sp(cmd->pool);
setenv(name, value != NULL? value : "", 1);
return NULL;
}
diff --git a/sca-cpp/trunk/modules/server/mod-scheme.hpp b/sca-cpp/trunk/modules/server/mod-scheme.hpp
index 43d7bf4041..36d91dc904 100644
--- a/sca-cpp/trunk/modules/server/mod-scheme.hpp
+++ b/sca-cpp/trunk/modules/server/mod-scheme.hpp
@@ -49,39 +49,30 @@ const list<value> primitiveProcedures(const list<value>& l) {
}
/**
- * Apply a Scheme component implementation function.
- */
-struct applyImplementation {
- const value impl;
- const list<value> px;
-
- applyImplementation(const value& impl, const list<value>& px) : impl(impl), px(scheme::quotedParameters(primitiveProcedures(px))) {
- }
-
- const value operator()(const list<value>& params) const {
- const value expr = cons<value>(car(params), append(scheme::quotedParameters(cdr(params)), px));
- debug(expr, "modeval::scheme::applyImplementation::input");
- scheme::Env env = scheme::setupEnvironment();
- const value res = scheme::evalScript(expr, impl, env);
- const value val = isNil(res)? mklist<value>(value(), string("Could not evaluate expression")) : mklist<value>(res);
- debug(val, "modeval::scheme::applyImplementation::result");
- return val;
- }
-};
-
-/**
* Evaluate a Scheme component implementation and convert it to an
* applicable lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) {
- const string fpath(path + attributeValue("script", impl));
+const failable<lvvlambda > evalImplementation(const string& path, const value& impl, const list<value>& px) {
+ const string fpath(path + (string)attributeValue("script", impl));
ifstream is(fpath);
if (fail(is))
- return mkfailure<lambda<value(const list<value>&)> >(string("Could not read implementation: ") + fpath);
+ return mkfailure<lvvlambda >(string("Could not read implementation: ") + fpath);
const value script = scheme::readScript(is);
if (isNil(script))
- return mkfailure<lambda<value(const list<value>&)> >(string("Could not read implementation: ") + fpath);
- return lambda<value(const list<value>&)>(applyImplementation(script, px));
+ return mkfailure<lvvlambda >(string("Could not read implementation: ") + fpath);
+ const list<value> pxproc = scheme::quotedParameters(primitiveProcedures(px));
+
+ const lvvlambda applyImplementation = [script, pxproc](const list<value>& params) -> const value {
+ // Apply a Scheme component implementation function
+ const value expr = cons<value>(car(params), append(scheme::quotedParameters(cdr(params)), pxproc));
+ debug(expr, "modeval::scheme::applyImplementation::input");
+ scheme::Env env = scheme::setupEnvironment();
+ const value res = scheme::evalScript(expr, script, env);
+ const value val = isNil(res)? mklist<value>(nilValue, string("Could not evaluate expression")) : mklist<value>(res);
+ debug(val, "modeval::scheme::applyImplementation::result");
+ return val;
+ };
+ return applyImplementation;
}
}
diff --git a/sca-cpp/trunk/modules/server/server-conf b/sca-cpp/trunk/modules/server/server-conf
index bfa5ac8473..2674cd9ac5 100755
--- a/sca-cpp/trunk/modules/server/server-conf
+++ b/sca-cpp/trunk/modules/server/server-conf
@@ -22,6 +22,18 @@ here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $h
mkdir -p $1
root=`echo "import os; print os.path.realpath('$1')" | python`
+# Configure thread stack size on MacOS X
+uname=`uname -s`
+if [ "$uname" = "Darwin" ]; then
+ cat >>$root/conf/mpm.conf <<EOF
+# Generated by: httpd-conf $*
+# Set thread stack size
+ThreadStackSize 2097152
+
+EOF
+
+fi
+
# Serve Javascript scripts and CSS
$here/../js/js-conf $1
diff --git a/sca-cpp/trunk/modules/wsgi/Makefile.am b/sca-cpp/trunk/modules/wsgi/Makefile.am
index 43cffb2254..70356603d9 100644
--- a/sca-cpp/trunk/modules/wsgi/Makefile.am
+++ b/sca-cpp/trunk/modules/wsgi/Makefile.am
@@ -43,7 +43,7 @@ gae.prefix: $(top_builddir)/config.status
EXTRA_DIST = domain-test.composite *.py htdocs/test/*.xml htdocs/test/*.txt htdocs/*.html
client_test_SOURCES = client-test.cpp
-client_test_LDFLAGS = -lxml2 -lcurl -lmozjs
+client_test_LDFLAGS = -lxml2 -lcurl -ljansson
noinst_PROGRAMS = client-test
diff --git a/sca-cpp/trunk/modules/wsgi/client-test.cpp b/sca-cpp/trunk/modules/wsgi/client-test.cpp
index da4fff973b..f0bc490896 100644
--- a/sca-cpp/trunk/modules/wsgi/client-test.cpp
+++ b/sca-cpp/trunk/modules/wsgi/client-test.cpp
@@ -27,7 +27,7 @@
#include "string.hpp"
#include "../server/client-test.hpp"
-int main(const int argc, const char** argv) {
+int main(const int argc, const char** const argv) {
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::server::testURI = argc < 2? "http://localhost:8090/wsgi" : argv[1];
tuscany::server::testBlobs = false;