summaryrefslogtreecommitdiffstats
path: root/sca-cpp
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2012-07-16 06:47:59 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2012-07-16 06:47:59 +0000
commit419f903ff44a22debba43976baae1e86c1e5d871 (patch)
tree8e715931d2f85c036a27f7de47c6e665ae7d8e80 /sca-cpp
parent11522a4b90a4056319cdbc204fffc63780cbfa51 (diff)
Add a timeout property to the CURL HTTP clients.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1361916 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-cpp')
-rw-r--r--sca-cpp/trunk/components/cache/client-test.cpp12
-rw-r--r--sca-cpp/trunk/components/chat/client-test.cpp2
-rw-r--r--sca-cpp/trunk/components/constdb/client-test.cpp8
-rw-r--r--sca-cpp/trunk/components/filedb/client-test.cpp8
-rw-r--r--sca-cpp/trunk/components/http/client-test.cpp14
-rw-r--r--sca-cpp/trunk/components/http/http.composite5
-rw-r--r--sca-cpp/trunk/components/http/httpdelete.componentType1
-rw-r--r--sca-cpp/trunk/components/http/httpdelete.cpp20
-rw-r--r--sca-cpp/trunk/components/http/httpget.componentType1
-rw-r--r--sca-cpp/trunk/components/http/httpget.cpp20
-rw-r--r--sca-cpp/trunk/components/http/httppatch.componentType1
-rw-r--r--sca-cpp/trunk/components/http/httppatch.cpp20
-rw-r--r--sca-cpp/trunk/components/http/httppost.componentType1
-rw-r--r--sca-cpp/trunk/components/http/httppost.cpp20
-rw-r--r--sca-cpp/trunk/components/http/httpput.componentType1
-rw-r--r--sca-cpp/trunk/components/http/httpput.cpp20
-rw-r--r--sca-cpp/trunk/components/log/client-test.cpp10
-rw-r--r--sca-cpp/trunk/components/smtp/client-test.cpp2
-rw-r--r--sca-cpp/trunk/components/smtp/smtppost.cpp34
-rw-r--r--sca-cpp/trunk/components/sqldb/client-test.cpp8
-rw-r--r--sca-cpp/trunk/hosting/server/client-test.hpp436
-rw-r--r--sca-cpp/trunk/hosting/server/data/apps/testhttp/app.composite7
-rw-r--r--sca-cpp/trunk/hosting/server/data/apps/testlogic/app.composite1
-rw-r--r--sca-cpp/trunk/hosting/server/data/apps/testsearch/app.composite1
-rw-r--r--sca-cpp/trunk/hosting/server/data/apps/twsms/app.composite1
-rw-r--r--sca-cpp/trunk/hosting/server/data/palettes/http/palette.composite5
-rw-r--r--sca-cpp/trunk/modules/http/curl-connect.cpp2
-rw-r--r--sca-cpp/trunk/modules/http/curl-get.cpp2
-rw-r--r--sca-cpp/trunk/modules/http/curl-test.cpp7
-rw-r--r--sca-cpp/trunk/modules/http/http.hpp126
-rw-r--r--sca-cpp/trunk/modules/http/mod-ssltunnel.cpp8
-rw-r--r--sca-cpp/trunk/modules/server/client-test.hpp30
32 files changed, 700 insertions, 134 deletions
diff --git a/sca-cpp/trunk/components/cache/client-test.cpp b/sca-cpp/trunk/components/cache/client-test.cpp
index b652ad3a88..63d1691f8b 100644
--- a/sca-cpp/trunk/components/cache/client-test.cpp
+++ b/sca-cpp/trunk/components/cache/client-test.cpp
@@ -43,7 +43,7 @@ const string partition1uri("http://localhost:8090/partitioner/a");
const string partition2uri("http://localhost:8090/partitioner/b");
bool testCache(const string& uri) {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const list<value> i = list<value>() + "content" + (list<value>() + "item"
+ (list<value>() + "name" + string("Apple"))
@@ -103,7 +103,7 @@ bool testDatacache() {
}
bool testMemocache() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> res = http::evalExpr(mklist<value>(string("add"), 33, 22), memocacheuri, cs);
assert(hasContent(res));
@@ -117,7 +117,7 @@ bool testMemocache() {
}
bool testPartitioner() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> res1 = http::get(partition1uri, cs);
assert(hasContent(res1));
@@ -133,8 +133,8 @@ bool testPartitioner() {
struct getLoop {
const string path;
const value entry;
- http::CURLSession cs;
- getLoop(const string& path, const value& entry, http::CURLSession cs) : path(path), entry(entry), cs(cs) {
+ http::CURLSession& cs;
+ getLoop(const string& path, const value& entry, http::CURLSession& cs) : path(path), entry(entry), cs(cs) {
}
const bool operator()() const {
const failable<value> val = http::get(memcacheuri + path, cs);
@@ -153,7 +153,7 @@ bool testGetPerf() {
+ (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> id = http::post(a, memcacheuri, cs);
assert(hasContent(id));
const string p = path(content(id));
diff --git a/sca-cpp/trunk/components/chat/client-test.cpp b/sca-cpp/trunk/components/chat/client-test.cpp
index 9595194fe9..220382fa89 100644
--- a/sca-cpp/trunk/components/chat/client-test.cpp
+++ b/sca-cpp/trunk/components/chat/client-test.cpp
@@ -86,7 +86,7 @@ bool testListen() {
bool testPost() {
gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "");
+ http::CURLSession ch("", "", "", "", 0);
const failable<value> id = http::post(entry, "http://localhost:8090/print-sender/sca2@localhost", ch);
assert(hasContent(id));
return true;
diff --git a/sca-cpp/trunk/components/constdb/client-test.cpp b/sca-cpp/trunk/components/constdb/client-test.cpp
index 766e1d2583..ea45762cd6 100644
--- a/sca-cpp/trunk/components/constdb/client-test.cpp
+++ b/sca-cpp/trunk/components/constdb/client-test.cpp
@@ -39,7 +39,7 @@ namespace constdb {
const string uri("http://localhost:8090/constdb");
bool testConstDb() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const list<value> i = list<value>() + "content" + (list<value>() + "item"
+ (list<value>() + "name" + string("Apple"))
@@ -93,8 +93,8 @@ bool testConstDb() {
struct getLoop {
const string path;
const value entry;
- http::CURLSession cs;
- getLoop(const string& path, const value& entry, http::CURLSession cs) : path(path), entry(entry), cs(cs) {
+ http::CURLSession& cs;
+ getLoop(const string& path, const value& entry, http::CURLSession& cs) : path(path), entry(entry), cs(cs) {
}
const bool operator()() const {
const failable<value> val = http::get(uri + path, cs);
@@ -113,7 +113,7 @@ bool testGetPerf() {
+ (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> id = http::post(a, uri, cs);
assert(hasContent(id));
const string p = path(content(id));
diff --git a/sca-cpp/trunk/components/filedb/client-test.cpp b/sca-cpp/trunk/components/filedb/client-test.cpp
index 19f76c22fe..e0f98d8c3b 100644
--- a/sca-cpp/trunk/components/filedb/client-test.cpp
+++ b/sca-cpp/trunk/components/filedb/client-test.cpp
@@ -39,7 +39,7 @@ namespace filedb {
const string uri("http://localhost:8090/filedb");
bool testFileDB() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const list<value> i = list<value>() + "content" + (list<value>() + "item"
+ (list<value>() + "name" + string("Apple"))
@@ -93,8 +93,8 @@ bool testFileDB() {
struct getLoop {
const string path;
const value entry;
- http::CURLSession cs;
- getLoop(const string& path, const value& entry, http::CURLSession cs) : path(path), entry(entry), cs(cs) {
+ http::CURLSession& cs;
+ getLoop(const string& path, const value& entry, http::CURLSession& cs) : path(path), entry(entry), cs(cs) {
}
const bool operator()() const {
const failable<value> val = http::get(uri + path, cs);
@@ -113,7 +113,7 @@ bool testGetPerf() {
+ (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> id = http::post(a, uri, cs);
assert(hasContent(id));
const string p = path(content(id));
diff --git a/sca-cpp/trunk/components/http/client-test.cpp b/sca-cpp/trunk/components/http/client-test.cpp
index c040ed39df..bb1918f1f8 100644
--- a/sca-cpp/trunk/components/http/client-test.cpp
+++ b/sca-cpp/trunk/components/http/client-test.cpp
@@ -42,7 +42,7 @@ const string putURI("http://localhost:8090/httpput");
const string deleteURI("http://localhost:8090/httpdelete");
bool testGet() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> val = http::get(getURI, cs);
assert(hasContent(val));
@@ -50,8 +50,8 @@ bool testGet() {
}
struct getLoop {
- http::CURLSession cs;
- getLoop(http::CURLSession cs) : cs(cs) {
+ http::CURLSession& cs;
+ getLoop(http::CURLSession& cs) : cs(cs) {
}
const bool operator()() const {
const failable<value> val = http::get(getURI, cs);
@@ -61,7 +61,7 @@ struct getLoop {
};
bool testGetPerf() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const lambda<bool()> gl = getLoop(cs);
cout << "HTTP get test " << time(gl, 5, 200) << " ms" << endl;
@@ -70,7 +70,7 @@ bool testGetPerf() {
}
bool testPost() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> val = http::get(postURI, cs);
assert(hasContent(val));
@@ -78,7 +78,7 @@ bool testPost() {
}
bool testPut() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> val = http::get(putURI, cs);
assert(hasContent(val));
@@ -86,7 +86,7 @@ bool testPut() {
}
bool testDelete() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> val = http::get(deleteURI, cs);
assert(hasContent(val));
diff --git a/sca-cpp/trunk/components/http/http.composite b/sca-cpp/trunk/components/http/http.composite
index ea0adedf51..32c0da62c0 100644
--- a/sca-cpp/trunk/components/http/http.composite
+++ b/sca-cpp/trunk/components/http/http.composite
@@ -23,6 +23,7 @@
<component name="httpget">
<implementation.cpp path="." library="libhttpget"/>
+ <property name="timeout">0</property>
<service name="httpget">
<binding.http uri="httpget"/>
</service>
@@ -31,6 +32,7 @@
<component name="httppost">
<implementation.cpp path="." library="libhttppost"/>
+ <property name="timeout">0</property>
<service name="httppost">
<binding.http uri="httppost"/>
</service>
@@ -40,6 +42,7 @@
<component name="httpput">
<implementation.cpp path="." library="libhttpput"/>
+ <property name="timeout">0</property>
<service name="httpput">
<binding.http uri="httpput"/>
</service>
@@ -49,6 +52,7 @@
<component name="httppatch">
<implementation.cpp path="." library="libhttppatch"/>
+ <property name="timeout">0</property>
<service name="httppatch">
<binding.http uri="httppatch"/>
</service>
@@ -58,6 +62,7 @@
<component name="httpdelete">
<implementation.cpp path="." library="libhttpdelete"/>
+ <property name="timeout">0</property>
<service name="httpdelete">
<binding.http uri="httpdelete"/>
</service>
diff --git a/sca-cpp/trunk/components/http/httpdelete.componentType b/sca-cpp/trunk/components/http/httpdelete.componentType
index 34e2a60632..c2d728a538 100644
--- a/sca-cpp/trunk/components/http/httpdelete.componentType
+++ b/sca-cpp/trunk/components/http/httpdelete.componentType
@@ -22,6 +22,7 @@
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
targetNamespace="http://tuscany.apache.org/xmlns/sca/components">
+ <property name="timeout"/>
<service name="httpdelete"/>
<reference name="url"/>
diff --git a/sca-cpp/trunk/components/http/httpdelete.cpp b/sca-cpp/trunk/components/http/httpdelete.cpp
index d78a4d60df..c725461ec2 100644
--- a/sca-cpp/trunk/components/http/httpdelete.cpp
+++ b/sca-cpp/trunk/components/http/httpdelete.cpp
@@ -37,7 +37,7 @@ namespace httpdelete {
/**
* Evaluate an HTTP delete.
*/
-const failable<value> get(const lambda<value(const list<value>&)> url, http::CURLSession& ch) {
+const failable<value> get(const lambda<value(const list<value>&)>& url, http::CURLSession& ch) {
debug("httpdelete::get");
const value u = url(mklist<value>("get", list<value>()));
debug(u, "httpdelete::get::url");
@@ -49,7 +49,7 @@ const failable<value> get(const lambda<value(const list<value>&)> url, http::CUR
*/
class applyhttp {
public:
- applyhttp(const lambda<value(const list<value>&)> url, const perthread_ptr<http::CURLSession>& ch) : url(url), ch(ch) {
+ applyhttp(const lambda<value(const list<value>&)>& url, const perthread_ptr<http::CURLSession>& ch) : url(url), ch(ch) {
}
const value operator()(const list<value>& params) const {
@@ -68,16 +68,24 @@ private:
/**
* Create a new CURL session.
*/
-const gc_ptr<http::CURLSession> newsession() {
- return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "");
-}
+class newsession {
+public:
+ newsession(const lambda<value(const list<value>&)>& timeout) : timeout(timeout) {
+ }
+ const gc_ptr<http::CURLSession> operator()() const {
+ const int t = atoi(c_str((string)timeout(list<value>())));
+ return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "", t);
+ }
+private:
+ const lambda<value(const list<value>&)> timeout;
+};
/**
* Start the component.
*/
const failable<value> start(const list<value>& params) {
// Create a CURL session
- const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession));
+ const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(cadr(params))));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applyhttp(car(params), ch)));
diff --git a/sca-cpp/trunk/components/http/httpget.componentType b/sca-cpp/trunk/components/http/httpget.componentType
index a45474b88d..c6c24fbed8 100644
--- a/sca-cpp/trunk/components/http/httpget.componentType
+++ b/sca-cpp/trunk/components/http/httpget.componentType
@@ -22,6 +22,7 @@
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
targetNamespace="http://tuscany.apache.org/xmlns/sca/components">
+ <property name="timeout"/>
<service name="httpget"/>
<reference name="url"/>
diff --git a/sca-cpp/trunk/components/http/httpget.cpp b/sca-cpp/trunk/components/http/httpget.cpp
index 8515d6f41e..884dc1a6ff 100644
--- a/sca-cpp/trunk/components/http/httpget.cpp
+++ b/sca-cpp/trunk/components/http/httpget.cpp
@@ -38,7 +38,7 @@ namespace httpget {
/**
* Evaluate an HTTP get.
*/
-const failable<value> get(const lambda<value(const list<value>&)> url, http::CURLSession& ch) {
+const failable<value> get(const lambda<value(const list<value>&)>& url, http::CURLSession& ch) {
debug("httpget::get");
const value u = url(mklist<value>("get", list<value>()));
debug(u, "httpget::get::url");
@@ -50,7 +50,7 @@ const failable<value> get(const lambda<value(const list<value>&)> url, http::CUR
*/
class applyhttp {
public:
- applyhttp(const lambda<value(const list<value>&)> url, const perthread_ptr<http::CURLSession>& ch) : url(url), ch(ch) {
+ applyhttp(const lambda<value(const list<value>&)>& url, const perthread_ptr<http::CURLSession>& ch) : url(url), ch(ch) {
}
const value operator()(const list<value>& params) const {
@@ -70,16 +70,24 @@ private:
/**
* Create a new CURL session.
*/
-const gc_ptr<http::CURLSession> newsession() {
- return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "");
-}
+class newsession {
+public:
+ newsession(const lambda<value(const list<value>&)>& timeout) : timeout(timeout) {
+ }
+ const gc_ptr<http::CURLSession> operator()() const {
+ const int t = atoi(c_str((string)timeout(list<value>())));
+ return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "", t);
+ }
+private:
+ const lambda<value(const list<value>&)> timeout;
+};
/**
* Start the component.
*/
const failable<value> start(const list<value>& params) {
// Create a CURL session
- const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession));
+ const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(cadr(params))));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applyhttp(car(params), ch)));
diff --git a/sca-cpp/trunk/components/http/httppatch.componentType b/sca-cpp/trunk/components/http/httppatch.componentType
index 0ab5ecf45b..eb3a96078b 100644
--- a/sca-cpp/trunk/components/http/httppatch.componentType
+++ b/sca-cpp/trunk/components/http/httppatch.componentType
@@ -22,6 +22,7 @@
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
targetNamespace="http://tuscany.apache.org/xmlns/sca/components">
+ <property name="timeout"/>
<service name="httppatch"/>
<reference name="url"/>
<reference name="content"/>
diff --git a/sca-cpp/trunk/components/http/httppatch.cpp b/sca-cpp/trunk/components/http/httppatch.cpp
index 3e6f7af2c0..051b1e09ac 100644
--- a/sca-cpp/trunk/components/http/httppatch.cpp
+++ b/sca-cpp/trunk/components/http/httppatch.cpp
@@ -38,7 +38,7 @@ namespace httppatch {
/**
* Evaluate an HTTP patch.
*/
-const failable<value> get(const lambda<value(const list<value>&)> url, const lambda<value(const list<value>&)> val, http::CURLSession& ch) {
+const failable<value> get(const lambda<value(const list<value>&)>& url, const lambda<value(const list<value>&)>& val, http::CURLSession& ch) {
debug("httppatch::get");
const value u = url(mklist<value>("get", list<value>()));
const value v = val(mklist<value>("get", list<value>()));
@@ -52,7 +52,7 @@ const failable<value> get(const lambda<value(const list<value>&)> url, const lam
*/
class applyhttp {
public:
- applyhttp(const lambda<value(const list<value>&)> url, const lambda<value(const list<value>&)> val, const perthread_ptr<http::CURLSession>& ch) : url(url), val(val), ch(ch) {
+ applyhttp(const lambda<value(const list<value>&)>& url, const lambda<value(const list<value>&)>& val, const perthread_ptr<http::CURLSession>& ch) : url(url), val(val), ch(ch) {
}
const value operator()(const list<value>& params) const {
@@ -72,16 +72,24 @@ private:
/**
* Create a new CURL session.
*/
-const gc_ptr<http::CURLSession> newsession() {
- return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "");
-}
+class newsession {
+public:
+ newsession(const lambda<value(const list<value>&)>& timeout) : timeout(timeout) {
+ }
+ const gc_ptr<http::CURLSession> operator()() const {
+ const int t = atoi(c_str((string)timeout(list<value>())));
+ return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "", t);
+ }
+private:
+ const lambda<value(const list<value>&)> timeout;
+};
/**
* Start the component.
*/
const failable<value> start(const list<value>& params) {
// Create a CURL session
- const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession));
+ const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(caddr(params))));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applyhttp(car(params), cadr(params), ch)));
diff --git a/sca-cpp/trunk/components/http/httppost.componentType b/sca-cpp/trunk/components/http/httppost.componentType
index 2cb7310332..42b0096446 100644
--- a/sca-cpp/trunk/components/http/httppost.componentType
+++ b/sca-cpp/trunk/components/http/httppost.componentType
@@ -22,6 +22,7 @@
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
targetNamespace="http://tuscany.apache.org/xmlns/sca/components">
+ <property name="timeout"/>
<service name="httppost"/>
<reference name="url"/>
<reference name="content"/>
diff --git a/sca-cpp/trunk/components/http/httppost.cpp b/sca-cpp/trunk/components/http/httppost.cpp
index 8d0f526bdc..84fd984e19 100644
--- a/sca-cpp/trunk/components/http/httppost.cpp
+++ b/sca-cpp/trunk/components/http/httppost.cpp
@@ -38,7 +38,7 @@ namespace httppost {
/**
* Evaluate an HTTP post.
*/
-const failable<value> get(const lambda<value(const list<value>&)> url, const lambda<value(const list<value>&)> val, http::CURLSession& ch) {
+const failable<value> get(const lambda<value(const list<value>&)>& url, const lambda<value(const list<value>&)>& val, http::CURLSession& ch) {
debug("httppost::get");
const value u = url(mklist<value>("get", list<value>()));
const value v = val(mklist<value>("get", list<value>()));
@@ -52,7 +52,7 @@ const failable<value> get(const lambda<value(const list<value>&)> url, const lam
*/
class applyhttp {
public:
- applyhttp(const lambda<value(const list<value>&)> url, const lambda<value(const list<value>&)> val, const perthread_ptr<http::CURLSession>& ch) : url(url), val(val), ch(ch) {
+ applyhttp(const lambda<value(const list<value>&)>& url, const lambda<value(const list<value>&)>& val, const perthread_ptr<http::CURLSession>& ch) : url(url), val(val), ch(ch) {
}
const value operator()(const list<value>& params) const {
@@ -72,16 +72,24 @@ private:
/**
* Create a new CURL session.
*/
-const gc_ptr<http::CURLSession> newsession() {
- return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "");
-}
+class newsession {
+public:
+ newsession(const lambda<value(const list<value>&)>& timeout) : timeout(timeout) {
+ }
+ const gc_ptr<http::CURLSession> operator()() const {
+ const int t = atoi(c_str((string)timeout(list<value>())));
+ return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "", t);
+ }
+private:
+ const lambda<const value(const list<value>&)> timeout;
+};
/**
* Start the component.
*/
const failable<value> start(const list<value>& params) {
// Create a CURL session
- const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession));
+ const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(caddr(params))));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applyhttp(car(params), cadr(params), ch)));
diff --git a/sca-cpp/trunk/components/http/httpput.componentType b/sca-cpp/trunk/components/http/httpput.componentType
index 654bb5e82f..791a7faa8a 100644
--- a/sca-cpp/trunk/components/http/httpput.componentType
+++ b/sca-cpp/trunk/components/http/httpput.componentType
@@ -22,6 +22,7 @@
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
targetNamespace="http://tuscany.apache.org/xmlns/sca/components">
+ <property name="timeout"/>
<service name="httpput"/>
<reference name="url"/>
<reference name="content"/>
diff --git a/sca-cpp/trunk/components/http/httpput.cpp b/sca-cpp/trunk/components/http/httpput.cpp
index c157ee32cc..2ae5da396e 100644
--- a/sca-cpp/trunk/components/http/httpput.cpp
+++ b/sca-cpp/trunk/components/http/httpput.cpp
@@ -38,7 +38,7 @@ namespace httpput {
/**
* Evaluate an HTTP put.
*/
-const failable<value> get(const lambda<value(const list<value>&)> url, const lambda<value(const list<value>&)> val, http::CURLSession& ch) {
+const failable<value> get(const lambda<value(const list<value>&)>& url, const lambda<value(const list<value>&)>& val, http::CURLSession& ch) {
debug("httpput::get");
const value u = url(mklist<value>("get", list<value>()));
const value v = val(mklist<value>("get", list<value>()));
@@ -52,7 +52,7 @@ const failable<value> get(const lambda<value(const list<value>&)> url, const lam
*/
class applyhttp {
public:
- applyhttp(const lambda<value(const list<value>&)> url, const lambda<value(const list<value>&)> val, const perthread_ptr<http::CURLSession>& ch) : url(url), val(val), ch(ch) {
+ applyhttp(const lambda<value(const list<value>&)>& url, const lambda<value(const list<value>&)>& val, const perthread_ptr<http::CURLSession>& ch) : url(url), val(val), ch(ch) {
}
const value operator()(const list<value>& params) const {
@@ -72,16 +72,24 @@ private:
/**
* Create a new CURL session.
*/
-const gc_ptr<http::CURLSession> newsession() {
- return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "");
-}
+class newsession {
+public:
+ newsession(const lambda<value(const list<value>&)>& timeout) : timeout(timeout) {
+ }
+ const gc_ptr<http::CURLSession> operator()() const {
+ const int t = atoi(c_str((string)timeout(list<value>())));
+ return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "", t);
+ }
+private:
+ const lambda<value(const list<value>&)> timeout;
+};
/**
* Start the component.
*/
const failable<value> start(const list<value>& params) {
// Create a CURL session
- const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession));
+ const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(caddr(params))));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applyhttp(car(params), cadr(params), ch)));
diff --git a/sca-cpp/trunk/components/log/client-test.cpp b/sca-cpp/trunk/components/log/client-test.cpp
index c67d3a4b27..d8cac5ee81 100644
--- a/sca-cpp/trunk/components/log/client-test.cpp
+++ b/sca-cpp/trunk/components/log/client-test.cpp
@@ -39,7 +39,7 @@ namespace log {
const string uri("http://localhost:8090/log");
bool testLog() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const list<value> i = list<value>() + "content" + (list<value>() + "item"
+ (list<value>() + "name" + string("Apple"))
@@ -58,8 +58,8 @@ bool testLog() {
struct logLoop {
const value a;
const string uri;
- http::CURLSession cs;
- logLoop(const value& a, const string& uri, http::CURLSession cs) : a(a), uri(uri), cs(cs) {
+ http::CURLSession& cs;
+ logLoop(const value& a, const string& uri, http::CURLSession& cs) : a(a), uri(uri), cs(cs) {
}
const bool operator()() const {
const failable<value> id = http::post(a, uri, cs);
@@ -77,7 +77,7 @@ bool testLogPerf() {
+ (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> id = http::post(a, uri, cs);
assert(hasContent(id));
@@ -88,7 +88,7 @@ bool testLogPerf() {
}
bool testLogger() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> res = http::evalExpr(mklist<value>(string("sum"), 33, 22), string("http://localhost:8090/client"), cs);
assert(hasContent(res));
diff --git a/sca-cpp/trunk/components/smtp/client-test.cpp b/sca-cpp/trunk/components/smtp/client-test.cpp
index 216861d35e..10274a6248 100644
--- a/sca-cpp/trunk/components/smtp/client-test.cpp
+++ b/sca-cpp/trunk/components/smtp/client-test.cpp
@@ -39,7 +39,7 @@ namespace smtp {
const string postURI("http://localhost:8090/smtppost");
bool testPost() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> val = http::get(postURI, cs);
assert(hasContent(val));
diff --git a/sca-cpp/trunk/components/smtp/smtppost.cpp b/sca-cpp/trunk/components/smtp/smtppost.cpp
index db2ac9ef18..1030ccc223 100644
--- a/sca-cpp/trunk/components/smtp/smtppost.cpp
+++ b/sca-cpp/trunk/components/smtp/smtppost.cpp
@@ -38,7 +38,7 @@ namespace smtppost {
/**
* Post/send an email message using SMTP.
*/
-const failable<value> post(const string& url, const string& user, const string& pass, const string& from, const string& to, const string& subject, const value& val, const http::CURLSession& cs) {
+const failable<value> post(const string& url, const string& user, const string& pass, const string& from, const string& to, const string& subject, const value& val, http::CURLSession& cs) {
// Convert value to a content request
const failable<list<list<string> > > freq = http::contentRequest(val, url);
if (!hasContent(freq))
@@ -48,8 +48,10 @@ const failable<value> post(const string& url, const string& user, const string&
// Setup the CURL session
const failable<CURL*> fch = http::setup(url, cs);
- if (!hasContent(fch))
+ if (!hasContent(fch)) {
+ http::cleanup(cs);
return mkfailure<value>(fch);
+ }
CURL* ch = content(fch);
curl_easy_setopt(ch, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL);
@@ -80,18 +82,22 @@ const failable<value> post(const string& url, const string& user, const string&
curl_slist_free_all(rcpt);
// Return the CURL return code or true
- if (rc)
+ if (rc) {
+ http::cleanup(cs);
return mkfailure<value>(string(curl_easy_strerror(rc)));
+ }
+
+ http::cleanup(cs);
return value(true);
}
/**
* Evaluate an SMTP post/send.
*/
-const failable<value> get(const lambda<value(const list<value>&)> url,
- const lambda<value(const list<value>&)> user, const lambda<value(const list<value>&)> pass,
- const lambda<value(const list<value>&)> from, const lambda<value(const list<value>&)> to,
- const lambda<value(const list<value>&)> subject, const lambda<value(const list<value>&)> val,
+const failable<value> get(const lambda<value(const list<value>&)>& url,
+ const lambda<value(const list<value>&)>& user, const lambda<value(const list<value>&)>& pass,
+ const lambda<value(const list<value>&)>& from, const lambda<value(const list<value>&)>& to,
+ const lambda<value(const list<value>&)>& subject, const lambda<value(const list<value>&)>& val,
http::CURLSession& ch) {
debug("smtppost::get");
const value u = url(mklist<value>("get", list<value>()));
@@ -116,11 +122,11 @@ const failable<value> get(const lambda<value(const list<value>&)> url,
*/
class applysmtp {
public:
- applysmtp(const lambda<value(const list<value>&)> url,
- const lambda<value(const list<value>&)> user, const lambda<value(const list<value>&)> pass,
- const lambda<value(const list<value>&)> from, const lambda<value(const list<value>&)> to,
- const lambda<value(const list<value>&)> subject, const lambda<value(const list<value>&)> val,
- const perthread_ptr<http::CURLSession>& ch) :
+ applysmtp(const lambda<value(const list<value>&)>& url,
+ const lambda<value(const list<value>&)>& user, const lambda<value(const list<value>&)>& pass,
+ const lambda<value(const list<value>&)>& from, const lambda<value(const list<value>&)>& to,
+ const lambda<value(const list<value>&)>& subject, const lambda<value(const list<value>&)>& val,
+ perthread_ptr<http::CURLSession>& ch) :
url(url), user(user), pass(pass), from(from), to(to), subject(subject), val(val), ch(ch) {
}
@@ -147,7 +153,7 @@ private:
* Create a new CURL session.
*/
const gc_ptr<http::CURLSession> newsession() {
- return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "");
+ return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "", 0);
}
/**
@@ -155,7 +161,7 @@ const gc_ptr<http::CURLSession> newsession() {
*/
const failable<value> start(const list<value>& params) {
// Create a CURL session
- const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession));
+ perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession));
// Return the component implementation lambda function
return value(lambda<value(const list<value>&)>(applysmtp(car(params), cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params), caddddddr(params), ch)));
diff --git a/sca-cpp/trunk/components/sqldb/client-test.cpp b/sca-cpp/trunk/components/sqldb/client-test.cpp
index d5f07de969..0cbcb57363 100644
--- a/sca-cpp/trunk/components/sqldb/client-test.cpp
+++ b/sca-cpp/trunk/components/sqldb/client-test.cpp
@@ -39,7 +39,7 @@ namespace sqldb {
const string uri("http://localhost:8090/sqldb");
bool testSqlDb() {
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const list<value> i = list<value>() + "content" + (list<value>() + "item"
+ (list<value>() + "name" + string("Apple"))
@@ -93,8 +93,8 @@ bool testSqlDb() {
struct getLoop {
const string path;
const value entry;
- http::CURLSession cs;
- getLoop(const string& path, const value& entry, http::CURLSession cs) : path(path), entry(entry), cs(cs) {
+ http::CURLSession& cs;
+ getLoop(const string& path, const value& entry, http::CURLSession& cs) : path(path), entry(entry), cs(cs) {
}
const bool operator()() const {
const failable<value> val = http::get(uri + path, cs);
@@ -113,7 +113,7 @@ bool testGetPerf() {
+ (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- http::CURLSession cs("", "", "", "");
+ http::CURLSession cs("", "", "", "", 0);
const failable<value> id = http::post(a, uri, cs);
assert(hasContent(id));
const string p = path(content(id));
diff --git a/sca-cpp/trunk/hosting/server/client-test.hpp b/sca-cpp/trunk/hosting/server/client-test.hpp
new file mode 100644
index 0000000000..7d85fc99a6
--- /dev/null
+++ b/sca-cpp/trunk/hosting/server/client-test.hpp
@@ -0,0 +1,436 @@
+/*
+ * 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.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Test HTTP client functions.
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "parallel.hpp"
+#include "perf.hpp"
+#include "../../modules/http/http.hpp"
+
+namespace tuscany {
+namespace server {
+
+string testURI = "http://localhost:8090";
+bool testBlobs = true;
+
+ostream* curlWriter(const string& s, ostream* os) {
+ (*os) << s;
+ return os;
+}
+
+const bool testGetDoc() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ {
+ ostringstream os;
+ const failable<list<ostream*> > r = http::get<ostream*>(curlWriter, &os, testURI + "/", ch);
+ assert(hasContent(r));
+ assert(contains(str(os), "HTTP/1.1 200") || contains(str(os), "HTTP/1.0 200"));
+ assert(contains(str(os), "<base href=\"/\"/>"));
+ }
+ {
+ const failable<value> r = http::getcontent(testURI + "/", ch);
+ assert(hasContent(r));
+ assert(contains(car(list<value>(content(r))), "<base href=\"/\"/>"));
+ }
+ return true;
+}
+
+struct getDocLoop {
+ http::CURLSession& ch;
+ getDocLoop(http::CURLSession& ch) : ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> r = http::getcontent(testURI + "/", ch);
+ assert(hasContent(r));
+ assert(contains(car(list<value>(content(r))), "<base href=\"/\"/>"));
+ return true;
+ }
+};
+
+const bool testGetDocPerf() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ const lambda<bool()> gl = getDocLoop(ch);
+ cout << "GET doc test " << time(gl, 10, 50) << " ms" << endl;
+ return true;
+}
+
+struct getCompositeLoop {
+ http::CURLSession& ch;
+ getCompositeLoop(http::CURLSession& ch) : ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> r = http::getcontent(testURI + "/r/Editor/composites/test", ch);
+ assert(hasContent(r));
+ return true;
+ }
+};
+
+const bool testGetCompositePerf() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ const lambda<bool()> gl = getCompositeLoop(ch);
+ cout << "GET composite test " << time(gl, 10, 50) << " ms" << endl;
+ return true;
+}
+
+struct getPageLoop {
+ http::CURLSession& ch;
+ getPageLoop(http::CURLSession& ch) : ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> r = http::getcontent(testURI + "/r/Editor/pages/test", ch);
+ assert(hasContent(r));
+ return true;
+ }
+};
+
+const bool testGetPagePerf() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ const lambda<bool()> gl = getPageLoop(ch);
+ cout << "GET page test " << time(gl, 10, 50) << " ms" << endl;
+ return true;
+}
+
+struct getAppLoop {
+ http::CURLSession& ch;
+ getAppLoop(http::CURLSession& ch) : ch(ch) {
+ }
+ const bool operator()() const {
+ const failable<value> r = http::getcontent(testURI + "/r/Editor/apps/test", ch);
+ assert(hasContent(r));
+ return true;
+ }
+};
+
+const bool testGetAppPerf() {
+ gc_scoped_pool pool;
+ http::CURLSession ch("", "", "", "", 0);
+ const lambda<bool()> gl = getAppLoop(ch);
+ cout << "GET app test " << time(gl, 10, 50) << " ms" << endl;
+ return true;
+}
+
+const bool testEval() {
+ gc_scoped_pool pool;
+ 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));
+ assert(hasContent(r));
+ assert(content(r) == blobs);
+ 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);
+ 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"))
+ + i);
+ 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 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"))
+ + i);
+ const lambda<bool()> pl = postLoop(testURI, val, ch);
+ 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"))
+ + i);
+ const lambda<bool()> pl = postBlobLoop(testURI, val, ch);
+ cout << "ATOMPub POST blob test " << time(pl, 5, 200) << " ms" << endl;
+ }
+ 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);
+ time(pl, 0, count);
+ return true;
+}
+
+const list<future<bool> > startPost(worker& w, const int threads, const lambda<bool()>& l) {
+ if (threads == 0)
+ return list<future<bool> >();
+ return cons(submit(w, l), startPost(w, threads - 1, l));
+}
+
+const bool checkPost(const list<future<bool> >& r) {
+ if (isNil(r))
+ return true;
+ assert(car(r) == true);
+ 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 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"))
+ + 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);
+ cout << "ATOMPub POST thread test " << t << " ms" << endl;
+
+ return true;
+}
+
+#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);
+ time(pl, 0, count);
+ return true;
+}
+
+const list<pid_t> startPost(const int procs, const lambda<bool()>& l) {
+ if (procs == 0)
+ return list<pid_t>();
+ pid_t pid = fork();
+ if (pid == 0) {
+ assert(l() == true);
+ exit(0);
+ }
+ return cons(pid, startPost(procs - 1, l));
+}
+
+const bool checkPost(const list<pid_t>& r) {
+ if (isNil(r))
+ return true;
+ int status;
+ waitpid(car(r), &status, 0);
+ assert(status == 0);
+ 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 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"))
+ + 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);
+ cout << "ATOMPub POST fork test " << t << " ms" << endl;
+
+ return true;
+}
+
+#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"))
+ + i);
+ http::CURLSession ch("", "", "", "", 0);
+ value rc = content(http::put(a, testURI + "/111", ch));
+ assert(rc == value(true));
+ 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));
+ return true;
+}
+
+const bool testServer() {
+ tuscany::server::testGetDoc();
+#ifdef FOO
+ tuscany::server::testPost();
+ tuscany::server::testPut();
+ tuscany::server::testDel();
+ tuscany::server::testEval();
+#endif
+ tuscany::server::testGetDocPerf();
+ tuscany::server::testGetCompositePerf();
+ tuscany::server::testGetPagePerf();
+ tuscany::server::testGetAppPerf();
+#ifdef FOO
+ tuscany::server::testPostPerf();
+#ifdef WANT_THREADS
+ tuscany::server::testPostThreadPerf();
+#else
+ tuscany::server::testPostForkPerf();
+#endif
+ tuscany::server::testEvalPerf();
+#endif
+ return true;
+}
+
+}
+}
diff --git a/sca-cpp/trunk/hosting/server/data/apps/testhttp/app.composite b/sca-cpp/trunk/hosting/server/data/apps/testhttp/app.composite
index a252a2ca64..aa78b576d0 100644
--- a/sca-cpp/trunk/hosting/server/data/apps/testhttp/app.composite
+++ b/sca-cpp/trunk/hosting/server/data/apps/testhttp/app.composite
@@ -51,36 +51,43 @@
<component x="20" y="10" name="get" title="get" color="green1">
<implementation.cpp path="lib/http" library="libhttpget"/>
<service name="get"/>
+ <property name="timeout" visible="false"/>
<reference target="text" name="url"/>
</component>
<component x="20" y="60" name="get2" title="get" color="green1">
<implementation.cpp path="lib/http" library="libhttpget"/>
<service name="get"/>
+ <property name="timeout" visible="false"/>
<reference target="text2" name="url"/>
</component>
<component x="20" y="100" name="get3" title="get" color="green1">
<implementation.cpp path="lib/http" library="libhttpget"/>
<service name="get"/>
+ <property name="timeout" visible="false"/>
<reference target="text3" name="url"/>
</component>
<component x="310" y="10" name="get4" title="get" color="green1">
<implementation.cpp path="lib/http" library="libhttpget"/>
<service name="get"/>
+ <property name="timeout" visible="false"/>
<reference target="text4" name="url"/>
</component>
<component x="200" y="10" name="get5" title="get" color="green1">
<implementation.cpp path="lib/http" library="libhttpget"/>
<service name="get"/>
+ <property name="timeout" visible="false"/>
<reference target="text5" name="url"/>
</component>
<component x="20" y="140" name="get6" title="get" color="green1">
<implementation.cpp path="lib/http" library="libhttpget"/>
<service name="get"/>
+ <property name="timeout" visible="false"/>
<reference target="text6" name="url"/>
</component>
<component name="get7" title="get" color="green1">
<implementation.cpp path="lib/http" library="libhttpget"/>
<service name="get"/>
+ <property name="timeout" visible="false"/>
<reference target="text7" name="url"/>
</component>
<component name="item2" title="{propval}:" color="orange1">
diff --git a/sca-cpp/trunk/hosting/server/data/apps/testlogic/app.composite b/sca-cpp/trunk/hosting/server/data/apps/testlogic/app.composite
index db63d75b82..d838773839 100644
--- a/sca-cpp/trunk/hosting/server/data/apps/testlogic/app.composite
+++ b/sca-cpp/trunk/hosting/server/data/apps/testlogic/app.composite
@@ -64,6 +64,7 @@
<component name="get" title="get" color="green1">
<implementation.cpp path="lib/http" library="libhttpget"/>
<service name="get"/>
+ <property name="timeout" visible="false"/>
<reference target="text5" name="url"/>
</component>
<component name="greater" title="gt" color="cyan1">
diff --git a/sca-cpp/trunk/hosting/server/data/apps/testsearch/app.composite b/sca-cpp/trunk/hosting/server/data/apps/testsearch/app.composite
index d1411b5bea..6c2ba82131 100644
--- a/sca-cpp/trunk/hosting/server/data/apps/testsearch/app.composite
+++ b/sca-cpp/trunk/hosting/server/data/apps/testsearch/app.composite
@@ -51,6 +51,7 @@
<component x="20" y="250" name="get" title="get" color="green1">
<implementation.cpp path="lib/http" library="libhttpget"/>
<service name="get"/>
+ <property name="timeout" visible="false"/>
<reference target="text3" name="url"/>
</component>
<component x="490" y="10" name="ggeopos1" title="geo position" color="pink1">
diff --git a/sca-cpp/trunk/hosting/server/data/apps/twsms/app.composite b/sca-cpp/trunk/hosting/server/data/apps/twsms/app.composite
index 7c30c38e93..e8b2e27584 100644
--- a/sca-cpp/trunk/hosting/server/data/apps/twsms/app.composite
+++ b/sca-cpp/trunk/hosting/server/data/apps/twsms/app.composite
@@ -102,6 +102,7 @@
<component x="80" y="10" name="post1" title="post" color="green1">
<implementation.cpp path="lib/http" library="libhttppost"/>
<service name="post"/>
+ <property name="timeout" visible="false"/>
<reference target="format4" name="url"/>
<reference target="list21" name="content"/>
</component>
diff --git a/sca-cpp/trunk/hosting/server/data/palettes/http/palette.composite b/sca-cpp/trunk/hosting/server/data/palettes/http/palette.composite
index 13f92e8954..f4d0c2bdf5 100644
--- a/sca-cpp/trunk/hosting/server/data/palettes/http/palette.composite
+++ b/sca-cpp/trunk/hosting/server/data/palettes/http/palette.composite
@@ -40,6 +40,7 @@
<component x="80" y="220" name="delete" title="delete" color="green1">
<implementation.cpp path="lib/http" library="libhttpdelete"/>
<service name="delete"/>
+ <property name="timeout" visible="false"/>
<reference name="url"/>
</component>
<component x="140" y="110" name="email" title="email" color="green1">
@@ -50,6 +51,7 @@
<component x="80" y="170" name="get" title="get" color="green1">
<implementation.cpp path="lib/http" library="libhttpget"/>
<service name="get"/>
+ <property name="timeout" visible="false"/>
<reference name="url"/>
</component>
<component x="130" y="10" name="host" title="host" color="green1">
@@ -77,6 +79,7 @@
<component x="260" y="170" name="patch" title="patch" color="green1">
<implementation.cpp path="lib/http" library="libhttppatch"/>
<service name="patch"/>
+ <property name="timeout" visible="false"/>
<reference name="url"/>
<reference name="content"/>
</component>
@@ -88,12 +91,14 @@
<component x="200" y="170" name="post" title="post" color="green1">
<implementation.cpp path="lib/http" library="libhttppost"/>
<service name="post"/>
+ <property name="timeout" visible="false"/>
<reference name="url"/>
<reference name="content"/>
</component>
<component x="140" y="170" name="put" title="put" color="green1">
<implementation.cpp path="lib/http" library="libhttpput"/>
<service name="put"/>
+ <property name="timeout" visible="false"/>
<reference name="url"/>
<reference name="content"/>
</component>
diff --git a/sca-cpp/trunk/modules/http/curl-connect.cpp b/sca-cpp/trunk/modules/http/curl-connect.cpp
index 0bb193623f..9f5ee17368 100644
--- a/sca-cpp/trunk/modules/http/curl-connect.cpp
+++ b/sca-cpp/trunk/modules/http/curl-connect.cpp
@@ -36,7 +36,7 @@ namespace http {
const bool testConnect(const string& url, const string& ca = "", const string& cert = "", const string& key = "") {
gc_scoped_pool p;
- CURLSession cs(ca, cert, key, "");
+ CURLSession cs(ca, cert, key, "", 0);
const failable<bool> crc = connect(url, cs);
assert(hasContent(crc));
diff --git a/sca-cpp/trunk/modules/http/curl-get.cpp b/sca-cpp/trunk/modules/http/curl-get.cpp
index cd575ccc66..a16daeeae3 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, "");
+ CURLSession ch(ca, cert, key, "", 0);
const failable<value> val = get(url, ch);
assert(hasContent(val));
cout << content(val) << endl;
diff --git a/sca-cpp/trunk/modules/http/curl-test.cpp b/sca-cpp/trunk/modules/http/curl-test.cpp
index 2a1803b873..f0806ea577 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("", "", "", "");
+ CURLSession ch("", "", "", "", 0);
{
ostringstream os;
const failable<list<ostream*> > r = get<ostream*>(curlWriter, &os, testURI, ch);
@@ -69,7 +69,7 @@ struct getLoop {
};
const bool testGetPerf() {
- CURLSession ch("", "", "", "");
+ CURLSession ch("", "", "", "", 0);
lambda<bool()> gl = getLoop(ch);
cout << "Static GET test " << time(gl, 5, 200) << " ms" << endl;
return true;
@@ -79,8 +79,9 @@ const bool testGetPerf() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
- tuscany::http::testURI = tuscany::string("http://") + tuscany::http::hostName() + ":8090";
+ //tuscany::http::testURI = tuscany::string("http://") + tuscany::http::hostName() + ":8090";
tuscany::http::testGet();
tuscany::http::testGetPerf();
diff --git a/sca-cpp/trunk/modules/http/http.hpp b/sca-cpp/trunk/modules/http/http.hpp
index e8c88f8a83..408b9fdee5 100644
--- a/sca-cpp/trunk/modules/http/http.hpp
+++ b/sca-cpp/trunk/modules/http/http.hpp
@@ -71,13 +71,32 @@ public:
*/
class CURLSession {
public:
- CURLSession() : h(NULL), p(NULL), sock(NULL), wpollset(NULL), wpollfd(NULL), rpollset(NULL), rpollfd(NULL), owner(false), ca(""), cert(""), key(""), cookie("") {
+ CURLSession() : h(NULL), p(), sock(NULL), wpollset(NULL), wpollfd(NULL), rpollset(NULL), rpollfd(NULL), owner(false), ca(""), cert(""), key(""), cookie(""), timeout(0) {
}
- CURLSession(const string& ca, const string& cert, const string& key, const string& cookie) : h(curl_easy_init()), p(gc_pool(mkpool())), sock(NULL), wpollset(NULL), wpollfd(NULL), rpollset(NULL), rpollfd(NULL), owner(true), ca(ca), cert(cert), key(key), cookie(cookie) {
+ 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 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) {
+ 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) {
+ }
+
+ 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() {
@@ -86,12 +105,11 @@ public:
if (h == NULL)
return;
curl_easy_cleanup(h);
- destroy(p);
}
private:
CURL* h;
- gc_pool p;
+ gc_child_pool p;
apr_socket_t* sock;
apr_pollset_t* wpollset;
apr_pollfd_t* wpollfd;
@@ -101,16 +119,18 @@ private:
friend CURL* handle(const CURLSession& cs);
friend apr_socket_t* sock(const CURLSession& cs);
- friend const failable<CURL*> setup(const string& url, 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, const CURLSession& cs);
- friend const failable<size_t> recv(char* c, const size_t l, const 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);
public:
string ca;
string cert;
string key;
string cookie;
+ int timeout;
};
/**
@@ -242,11 +262,13 @@ const string topDomain(const string& host) {
/**
* Setup a CURL session
*/
-const failable<CURL*> setup(const string& url, const CURLSession& cs) {
+const failable<CURL*> setup(const string& url, CURLSession& cs) {
// Init CURL session
- CURL* ch = handle(cs);
- curl_easy_reset(ch);
+ if (cs.h != NULL)
+ cleanup(cs);
+ cs.h = curl_easy_init();
+ CURL* ch = cs.h;
curl_easy_setopt(ch, CURLOPT_USERAGENT, "libcurl/1.0");
#ifdef WANT_MAINTAINER_CURL_VERBOSE
curl_easy_setopt(ch, CURLOPT_VERBOSE, true);
@@ -256,6 +278,8 @@ const failable<CURL*> setup(const string& url, const CURLSession& cs) {
curl_easy_setopt(ch, CURLOPT_TCP_NODELAY, true);
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_TIMEOUT, cs.timeout);
// Setup SSL options
if (cs.ca != "") {
@@ -310,6 +334,17 @@ const failable<CURL*> setup(const string& url, const CURLSession& cs) {
}
/**
+ * Cleanup a CURL session
+ */
+const failable<bool> cleanup(CURLSession& cs) {
+ if (cs.h == NULL)
+ return true;
+ curl_easy_cleanup(cs.h);
+ cs.h = NULL;
+ return true;
+}
+
+/**
* Context passed to the read callback function.
*/
class CURLReadContext {
@@ -364,14 +399,16 @@ curl_slist* headers(curl_slist* cl, const list<string>& h) {
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, const CURLSession& cs) {
+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) {
debug(url, "http::apply::url");
debug(verb, "http::apply::verb");
// Setup the CURL session
const failable<CURL*> fch = setup(url, cs);
- if (!hasContent(fch))
+ if (!hasContent(fch)) {
+ cleanup(cs);
return mkfailure<list<R>>(fch);
+ }
CURL* ch = content(fch);
// Set the request headers
@@ -417,22 +454,27 @@ template<typename R> const failable<list<R> > apply(const list<list<string> >& h
curl_slist_free_all(hl);
// Return the HTTP return code or content
- if (rc)
+ if (rc) {
+ cleanup(cs);
return mkfailure<list<R> >(string(curl_easy_strerror(rc)));
+ }
long httprc;
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));
}
+
+ cleanup(cs);
return mklist<R>(hcx.accum, wcx.accum);
}
/**
* Evaluate an expression remotely, at the given URL.
*/
-const failable<value> evalExpr(const value& expr, const string& url, const CURLSession& cs) {
+const failable<value> evalExpr(const value& expr, const string& url, CURLSession& cs) {
debug(url, "http::evalExpr::url");
debug(expr, "http::evalExpr::input");
@@ -498,7 +540,7 @@ const string contentType(const list<string>& h) {
/**
* 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, const CURLSession& cs) {
+template<typename R> const failable<list<R> > get(const lambda<R(const string&, const R)>& reduce, const R& initial, const string& url, 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);
@@ -507,7 +549,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, const CURLSession& cs) {
+const failable<value> getcontent(const string& url, CURLSession& cs) {
debug(url, "http::get::url");
// Get the contents of the resource at the given URL
@@ -591,7 +633,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, const CURLSession& cs) {
+const failable<value> get(const string& url, CURLSession& cs) {
debug(url, "http::get::url");
// Get the contents of the resource at the given URL
@@ -689,7 +731,7 @@ const failable<list<list<string> > > contentRequest(const value& c, unused const
/**
* HTTP POST.
*/
-const failable<value> post(const value& val, const string& url, const CURLSession& cs) {
+const failable<value> post(const value& val, const string& url, CURLSession& cs) {
debug(url, "http::post::url");
// Convert value to a content request
@@ -718,7 +760,7 @@ const failable<value> post(const value& val, const string& url, const CURLSessio
/**
* HTTP PUT.
*/
-const failable<value> put(const value& val, const string& url, const CURLSession& cs) {
+const failable<value> put(const value& val, const string& url, CURLSession& cs) {
debug(url, "http::put::url");
// Convert value to a content request
@@ -739,7 +781,7 @@ const failable<value> put(const value& val, const string& url, const CURLSession
/**
* HTTP PATCH.
*/
-const failable<value> patch(const value& val, const string& url, const CURLSession& cs) {
+const failable<value> patch(const value& val, const string& url, CURLSession& cs) {
debug(url, "http::put::patch");
// Convert value to a content request
@@ -760,7 +802,7 @@ const failable<value> patch(const value& val, const string& url, const CURLSessi
/**
* HTTP DELETE.
*/
-const failable<value, string> del(const string& url, const CURLSession& cs) {
+const failable<value, string> del(const string& url, CURLSession& cs) {
debug(url, "http::delete::url");
const list<list<string> > req = mklist(list<string>(), list<string>());
@@ -804,32 +846,42 @@ const failable<bool> connect(const string& url, CURLSession& cs) {
// Setup the CURL session
const failable<CURL*> fch = setup(url, cs);
- if (!hasContent(fch))
+ if (!hasContent(fch)) {
+ cleanup(cs);
return mkfailure<bool>(fch);
+ }
CURL* ch = content(fch);
// Connect
curl_easy_setopt(ch, CURLOPT_CONNECT_ONLY, true);
const CURLcode rc = curl_easy_perform(ch);
- if (rc)
+ if (rc) {
+ cleanup(cs);
return mkfailure<bool>(string(curl_easy_strerror(rc)));
+ }
// Convert the connected socket to an apr_socket_t
int sd;
const CURLcode grc = curl_easy_getinfo(ch, CURLINFO_LASTSOCKET, &sd);
- if (grc)
+ if (grc) {
+ cleanup(cs);
return mkfailure<bool>(string(curl_easy_strerror(grc)));
+ }
cs.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);
- if (rpcrc != APR_SUCCESS)
+ 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);
- if (wpcrc != APR_SUCCESS)
+ 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);
@@ -839,15 +891,17 @@ 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, const CURLSession& cs) {
+const failable<bool> send(const char* c, const size_t l, CURLSession& cs) {
// Send the data
size_t wl = 0;
const CURLcode rc = curl_easy_send(cs.h, c, (size_t)l, &wl);
if (rc == CURLE_OK && wl == (size_t)l)
return true;
- if (rc != CURLE_AGAIN)
+ if (rc != CURLE_AGAIN) {
+ cleanup(cs);
return mkfailure<bool>(curlreason(rc));
+ }
// If the socket was not ready, wait for it to become ready
const apr_pollfd_t* pollfds;
@@ -863,7 +917,7 @@ const failable<bool> send(const char* c, const size_t l, const CURLSession& cs)
/**
* Receive an array of chars.
*/
-const failable<size_t> recv(char* c, const size_t l, const CURLSession& cs) {
+const failable<size_t> recv(char* c, const size_t l, CURLSession& cs) {
// Receive data
size_t rl;
@@ -872,15 +926,19 @@ const failable<size_t> recv(char* c, const size_t l, const CURLSession& cs) {
return (size_t)rl;
if (rc == 1)
return 0;
- if (rc != CURLE_AGAIN)
+ if (rc != CURLE_AGAIN) {
+ cleanup(cs);
return mkfailure<size_t>(curlreason(rc));
+ }
// 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);
- if (pollrc != APR_SUCCESS)
+ if (pollrc != APR_SUCCESS) {
+ cleanup(cs);
return mkfailure<size_t>(apreason(pollrc));
+ }
// Receive again
return recv(c, l, cs);
@@ -933,7 +991,7 @@ 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 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))) {
+ 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))) {
}
const value operator()(const list<value>& args) const {
@@ -975,7 +1033,7 @@ struct proxy {
const string cert;
const string key;
const string cookie;
- const CURLSession& cs;
+ CURLSession& cs;
};
}
diff --git a/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp b/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
index a23687d6b4..b66cd29959 100644
--- a/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
+++ b/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp
@@ -104,6 +104,7 @@ int postConfigMerge(ServerConf& mainsc, apr_pool_t* p, server_rec* s) {
int postConfig(apr_pool_t* p, unused apr_pool_t* plog, unused apr_pool_t* ptemp, server_rec* s) {
gc_scoped_pool pool(p);
+
ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_ssltunnel);
debug(httpd::serverName(s), "modssltunnel::postConfig::serverName");
@@ -147,7 +148,7 @@ int tunnel(conn_rec* conn, const string& ca, const string& cert, const string& k
apr_socket_t* csock = (apr_socket_t*)ap_get_module_config(conn->conn_config, &core_module);
// Open connection to target
- http::CURLSession cs(ca, cert, key, "");
+ http::CURLSession cs(ca, cert, key, "", 0);
const failable<bool> crc = http::connect(url, cs);
if (!hasContent(crc))
return abort(conn, csock, reason(crc));
@@ -271,9 +272,9 @@ int processConnection(conn_rec *conn) {
if (ap_get_module_config(conn->base_server->module_config, &mod_tuscany_ssltunnel) == NULL)
return DECLINED;
- // Create a scoped memory pool
- gc_scoped_pool pool;
+ gc_scoped_pool pool(conn->pool);
+ // Get the server configuration
const ServerConf& sc = httpd::serverConf<ServerConf>(conn->base_server, &mod_tuscany_ssltunnel);
if (length(sc.pass) == 0)
return DECLINED;
@@ -296,7 +297,6 @@ int handler(request_rec* r) {
if (strcmp(r->server->server_scheme, "https"))
return DECLINED;
- // Create a scoped memory pool
gc_scoped_pool pool(r->pool);
// Build the target URL
diff --git a/sca-cpp/trunk/modules/server/client-test.hpp b/sca-cpp/trunk/modules/server/client-test.hpp
index 2207127e67..1c7b26da39 100644
--- a/sca-cpp/trunk/modules/server/client-test.hpp
+++ b/sca-cpp/trunk/modules/server/client-test.hpp
@@ -46,7 +46,7 @@ ostream* curlWriter(const string& s, ostream* os) {
const bool testGet() {
gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "");
+ http::CURLSession ch("", "", "", "", 0);
{
ostringstream os;
const failable<list<ostream*> > r = http::get<ostream*>(curlWriter, &os, "http://localhost:8090/index.html", ch);
@@ -63,7 +63,7 @@ const bool testGet() {
}
struct getLoop {
- http::CURLSession ch;
+ http::CURLSession& ch;
getLoop(http::CURLSession& ch) : ch(ch) {
}
const bool operator()() const {
@@ -76,7 +76,7 @@ struct getLoop {
const bool testGetPerf() {
gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "");
+ http::CURLSession ch("", "", "", "", 0);
const lambda<bool()> gl = getLoop(ch);
cout << "Static GET test " << time(gl, 5, 200) << " ms" << endl;
return true;
@@ -84,7 +84,7 @@ const bool testGetPerf() {
const bool testEval() {
gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "");
+ 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"));
@@ -93,7 +93,7 @@ const bool testEval() {
struct evalLoop {
const string uri;
- http::CURLSession ch;
+ http::CURLSession& ch;
evalLoop(const string& uri, http::CURLSession& ch) : uri(uri), ch(ch) {
}
const bool operator()() const {
@@ -109,7 +109,7 @@ const list<value> blobs = mklist(blob, blob);
struct blobEvalLoop {
const string uri;
- http::CURLSession ch;
+ http::CURLSession& ch;
blobEvalLoop(const string& uri, http::CURLSession& ch) : uri(uri), ch(ch) {
}
const bool operator()() const {
@@ -122,7 +122,7 @@ struct blobEvalLoop {
const bool testEvalPerf() {
gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "");
+ http::CURLSession ch("", "", "", "", 0);
const lambda<bool()> el = evalLoop(testURI, ch);
cout << "JSON-RPC eval echo test " << time(el, 5, 200) << " ms" << endl;
@@ -142,7 +142,7 @@ bool testPost() {
+ (list<value>() + "title" + string("item"))
+ (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- http::CURLSession ch("", "", "", "");
+ http::CURLSession ch("", "", "", "", 0);
const failable<value> id = http::post(a, testURI, ch);
assert(hasContent(id));
return true;
@@ -151,7 +151,7 @@ bool testPost() {
struct postLoop {
const string uri;
const value val;
- http::CURLSession ch;
+ http::CURLSession& ch;
postLoop(const string& uri, const value& val, http::CURLSession& ch) : uri(uri), val(val), ch(ch) {
}
const bool operator()() const {
@@ -164,7 +164,7 @@ struct postLoop {
struct postBlobLoop {
const string uri;
const value val;
- http::CURLSession ch;
+ http::CURLSession& ch;
postBlobLoop(const string& uri, const value& val, http::CURLSession& ch) : uri(uri), val(val), ch(ch) {
}
const bool operator()() const {
@@ -177,7 +177,7 @@ struct postBlobLoop {
const bool testPostPerf() {
gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "");
+ http::CURLSession ch("", "", "", "", 0);
{
const list<value> i = list<value>() + "content" + (list<value>() + "item"
+ (list<value>() + "name" + string("Apple"))
@@ -209,7 +209,7 @@ const bool testPostPerf() {
const bool postThread(const string& uri, const int count, const value& val) {
gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "");
+ http::CURLSession ch("", "", "", "", 0);
const lambda<bool()> pl = postLoop(uri, val, ch);
time(pl, 0, count);
return true;
@@ -267,7 +267,7 @@ const bool testPostThreadPerf() {
const bool postProc(const string& uri, const int count, const value& val) {
gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "");
+ http::CURLSession ch("", "", "", "", 0);
const lambda<bool()> pl = postLoop(uri, val, ch);
time(pl, 0, count);
return true;
@@ -337,7 +337,7 @@ const bool testPut() {
+ (list<value>() + "title" + string("item"))
+ (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"))
+ i);
- http::CURLSession ch("", "", "", "");
+ http::CURLSession ch("", "", "", "", 0);
value rc = content(http::put(a, testURI + "/111", ch));
assert(rc == value(true));
return true;
@@ -345,7 +345,7 @@ const bool testPut() {
const bool testDel() {
gc_scoped_pool pool;
- http::CURLSession ch("", "", "", "");
+ http::CURLSession ch("", "", "", "", 0);
value rc = content(http::del(testURI + "/111", ch));
assert(rc == value(true));
return true;