From 2faafb710633884260b070e1d4ed4ef46326612a Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Mon, 23 May 2011 06:50:15 +0000 Subject: Support cookies over outgoing HTTP calls and a shorter component URL addressing scheme. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1126336 13f79535-47bb-0310-9956-ffa450edef68 --- sca-cpp/trunk/components/cache/client-test.cpp | 6 +- sca-cpp/trunk/components/chat/client-test.cpp | 2 +- sca-cpp/trunk/components/filedb/client-test.cpp | 4 +- sca-cpp/trunk/components/http/client-test.cpp | 4 +- sca-cpp/trunk/components/http/httpdelete.cpp | 2 +- sca-cpp/trunk/components/http/httpget.cpp | 2 +- sca-cpp/trunk/components/log/client-test.cpp | 6 +- sca-cpp/trunk/components/nosqldb/client-test.cpp | 4 +- sca-cpp/trunk/components/queue/client-test.cpp | 2 +- sca-cpp/trunk/components/sqldb/client-test.cpp | 4 +- .../trunk/components/webservice/client-test.cpp | 2 +- sca-cpp/trunk/modules/http/curl-connect.cpp | 2 +- sca-cpp/trunk/modules/http/curl-get.cpp | 2 +- sca-cpp/trunk/modules/http/curl-test.cpp | 6 +- sca-cpp/trunk/modules/http/http.hpp | 45 ++++++- sca-cpp/trunk/modules/http/httpd.hpp | 17 +-- sca-cpp/trunk/modules/http/mod-ssltunnel.cpp | 2 +- sca-cpp/trunk/modules/http/openauth.hpp | 4 +- sca-cpp/trunk/modules/oauth/mod-oauth1.cpp | 2 +- sca-cpp/trunk/modules/oauth/mod-oauth2.cpp | 2 +- sca-cpp/trunk/modules/server/client-test.hpp | 20 ++-- sca-cpp/trunk/modules/server/mod-eval.hpp | 133 +++++++++++++++------ sca-cpp/trunk/modules/server/mod-wiring.cpp | 7 +- 23 files changed, 190 insertions(+), 90 deletions(-) (limited to 'sca-cpp/trunk') diff --git a/sca-cpp/trunk/components/cache/client-test.cpp b/sca-cpp/trunk/components/cache/client-test.cpp index bef5aa454a..c44060b7a4 100644 --- a/sca-cpp/trunk/components/cache/client-test.cpp +++ b/sca-cpp/trunk/components/cache/client-test.cpp @@ -41,7 +41,7 @@ const string datacacheuri("http://localhost:8090/datacache"); const string memocacheuri("http://localhost:8090/memocache"); bool testCache(const string& uri) { - http::CURLSession cs("", "", ""); + http::CURLSession cs("", "", "", ""); const list i = list() + "content" + (list() + "item" + (list() + "name" + string("Apple")) @@ -101,7 +101,7 @@ bool testDatacache() { } bool testMemocache() { - http::CURLSession cs("", "", ""); + http::CURLSession cs("", "", "", ""); const failable res = http::evalExpr(mklist(string("add"), 33, 22), memocacheuri, cs); assert(hasContent(res)); @@ -137,7 +137,7 @@ bool testGetPerf() { + (list() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - http::CURLSession cs("", "", ""); + http::CURLSession cs("", "", "", ""); const failable 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 cd1021c147..9595194fe9 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("", "", "", ""); const failable id = http::post(entry, "http://localhost:8090/print-sender/sca2@localhost", ch); assert(hasContent(id)); return true; diff --git a/sca-cpp/trunk/components/filedb/client-test.cpp b/sca-cpp/trunk/components/filedb/client-test.cpp index 97141eba97..19f76c22fe 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("", "", "", ""); const list i = list() + "content" + (list() + "item" + (list() + "name" + string("Apple")) @@ -113,7 +113,7 @@ bool testGetPerf() { + (list() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - http::CURLSession cs("", "", ""); + http::CURLSession cs("", "", "", ""); const failable 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 eb8162b834..a83bf55252 100644 --- a/sca-cpp/trunk/components/http/client-test.cpp +++ b/sca-cpp/trunk/components/http/client-test.cpp @@ -39,7 +39,7 @@ namespace http { const string uri("http://localhost:8090/httpget"); bool testGet() { - http::CURLSession cs("", "", ""); + http::CURLSession cs("", "", "", ""); const failable val = http::get(uri, cs); assert(hasContent(val)); @@ -61,7 +61,7 @@ struct getLoop { }; bool testGetPerf() { - http::CURLSession cs("", "", ""); + http::CURLSession cs("", "", "", ""); const lambda gl = getLoop(cs); cout << "HTTP get test " << time(gl, 5, 200) << " ms" << endl; diff --git a/sca-cpp/trunk/components/http/httpdelete.cpp b/sca-cpp/trunk/components/http/httpdelete.cpp index 0bebfb9de2..5386ba588f 100644 --- a/sca-cpp/trunk/components/http/httpdelete.cpp +++ b/sca-cpp/trunk/components/http/httpdelete.cpp @@ -69,7 +69,7 @@ private: */ const failable start(const list& params) { // Create a CURL session - http::CURLSession& ch = *(new (gc_new()) http::CURLSession("", "", "")); + http::CURLSession& ch = *(new (gc_new()) http::CURLSession("", "", "", "")); // Return the component implementation lambda function return value(lambda&)>(applyhttp(car(params), ch))); diff --git a/sca-cpp/trunk/components/http/httpget.cpp b/sca-cpp/trunk/components/http/httpget.cpp index e64761714c..ac7a99775b 100644 --- a/sca-cpp/trunk/components/http/httpget.cpp +++ b/sca-cpp/trunk/components/http/httpget.cpp @@ -69,7 +69,7 @@ private: */ const failable start(const list& params) { // Create a CURL session - http::CURLSession& ch = *(new (gc_new()) http::CURLSession("", "", "")); + http::CURLSession& ch = *(new (gc_new()) http::CURLSession("", "", "", "")); // Return the component implementation lambda function return value(lambda&)>(applyhttp(car(params), ch))); diff --git a/sca-cpp/trunk/components/log/client-test.cpp b/sca-cpp/trunk/components/log/client-test.cpp index 09651f4f43..c67d3a4b27 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("", "", "", ""); const list i = list() + "content" + (list() + "item" + (list() + "name" + string("Apple")) @@ -77,7 +77,7 @@ bool testLogPerf() { + (list() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - http::CURLSession cs("", "", ""); + http::CURLSession cs("", "", "", ""); const failable id = http::post(a, uri, cs); assert(hasContent(id)); @@ -88,7 +88,7 @@ bool testLogPerf() { } bool testLogger() { - http::CURLSession cs("", "", ""); + http::CURLSession cs("", "", "", ""); const failable res = http::evalExpr(mklist(string("sum"), 33, 22), string("http://localhost:8090/client"), cs); assert(hasContent(res)); diff --git a/sca-cpp/trunk/components/nosqldb/client-test.cpp b/sca-cpp/trunk/components/nosqldb/client-test.cpp index b64f838f46..970f817d5a 100644 --- a/sca-cpp/trunk/components/nosqldb/client-test.cpp +++ b/sca-cpp/trunk/components/nosqldb/client-test.cpp @@ -39,7 +39,7 @@ namespace nosqldb { const string uri("http://localhost:8090/nosqldb"); bool testNoSqlDb() { - http::CURLSession cs("", "", ""); + http::CURLSession cs("", "", "", ""); const list i = list() + "content" + (list() + "item" + (list() + "name" + string("Apple")) @@ -113,7 +113,7 @@ bool testGetPerf() { + (list() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - http::CURLSession cs("", "", ""); + http::CURLSession cs("", "", "", ""); const failable id = http::post(a, uri, cs); assert(hasContent(id)); const string p = path(content(id)); diff --git a/sca-cpp/trunk/components/queue/client-test.cpp b/sca-cpp/trunk/components/queue/client-test.cpp index d44fd0f37a..a88d9576cb 100644 --- a/sca-cpp/trunk/components/queue/client-test.cpp +++ b/sca-cpp/trunk/components/queue/client-test.cpp @@ -80,7 +80,7 @@ bool testListen() { bool testPost() { gc_scoped_pool pool; - http::CURLSession ch("", "", ""); + http::CURLSession ch("", "", "", ""); const failable id = http::post(entry, "http://localhost:8090/print-sender", ch); assert(hasContent(id)); return true; diff --git a/sca-cpp/trunk/components/sqldb/client-test.cpp b/sca-cpp/trunk/components/sqldb/client-test.cpp index 9e2cbdc248..d5f07de969 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("", "", "", ""); const list i = list() + "content" + (list() + "item" + (list() + "name" + string("Apple")) @@ -113,7 +113,7 @@ bool testGetPerf() { + (list() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - http::CURLSession cs("", "", ""); + http::CURLSession cs("", "", "", ""); const failable id = http::post(a, uri, cs); assert(hasContent(id)); const string p = path(content(id)); diff --git a/sca-cpp/trunk/components/webservice/client-test.cpp b/sca-cpp/trunk/components/webservice/client-test.cpp index 658c87e2fc..16dd659b22 100644 --- a/sca-cpp/trunk/components/webservice/client-test.cpp +++ b/sca-cpp/trunk/components/webservice/client-test.cpp @@ -60,7 +60,7 @@ bool testModAxis2() { } bool testEval() { - http::CURLSession cs("", "", ""); + http::CURLSession cs("", "", "", ""); const value func = "http://ws.apache.org/axis2/c/samples/echoString"; const list arg = mklist( diff --git a/sca-cpp/trunk/modules/http/curl-connect.cpp b/sca-cpp/trunk/modules/http/curl-connect.cpp index 432ccc2000..0bb193623f 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, ""); const failable 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 762423bebb..cd575ccc66 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, ""); const failable 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 a7b8fd90b6..2a1803b873 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("", "", "", ""); { ostringstream os; const failable > r = get(curlWriter, &os, testURI, ch); @@ -69,7 +69,7 @@ struct getLoop { }; const bool testGetPerf() { - CURLSession ch("", "", ""); + CURLSession ch("", "", "", ""); lambda gl = getLoop(ch); cout << "Static GET test " << time(gl, 5, 200) << " ms" << endl; return true; @@ -80,7 +80,7 @@ const bool testGetPerf() { int main() { 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 1a207669c0..d4159add29 100644 --- a/sca-cpp/trunk/modules/http/http.hpp +++ b/sca-cpp/trunk/modules/http/http.hpp @@ -35,6 +35,7 @@ #include #include #include +#include #include "string.hpp" #include "gc.hpp" @@ -65,13 +66,13 @@ public: */ class CURLSession { public: - CURLSession() : h(NULL), p(NULL), sock(NULL), wpollset(NULL), wpollfd(NULL), rpollset(NULL), rpollfd(NULL), owner(false), ca(""), cert(""), key("") { + CURLSession() : h(NULL), p(NULL), sock(NULL), wpollset(NULL), wpollfd(NULL), rpollset(NULL), rpollfd(NULL), owner(false), ca(""), cert(""), key(""), cookie("") { } - CURLSession(const string& ca, const string& cert, const string& key) : 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) { + 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 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) { + 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() { @@ -104,6 +105,7 @@ public: string ca; string cert; string key; + string cookie; }; /** @@ -184,6 +186,34 @@ const string escapeArg(const string& arg) { return e; } +/** + * Parse a URI and return its host name. + */ +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 ""; + if (u.hostname == NULL) + return ""; + return u.hostname; +} + +/** + * Return the first subdomain name in a host name. + */ +const string subDomain(const string& host) { + return substr(host, 0, find(host, '.')); +} + +/** + * Return the top domain name in a host name. + */ +const string topDomain(const string& host) { + const size_t d = find(host, '.'); + return d == length(host) ? host : substr(host, d + 1); +} + /** * Setup a CURL session */ @@ -217,6 +247,10 @@ const failable setup(const string& url, const CURLSession& cs) { curl_easy_setopt(ch, CURLOPT_SSLKEY, c_str(cs.key)); curl_easy_setopt(ch, CURLOPT_SSLKEYTYPE, "PEM"); } + if (cs.cookie != "") { + debug(cs.cookie, "http::setup::cookie"); + curl_easy_setopt(ch, CURLOPT_COOKIE, c_str(cs.cookie)); + } // Set target URL curl_easy_setopt(ch, CURLOPT_URL, c_str(escapeURI(url))); @@ -567,7 +601,7 @@ const failable del(const string& url, const CURLSession& cs) { /** * Returns the current host name. */ -const string hostname() { +const string hostName() { char h[256]; if (gethostname(h, 256) == -1) return "localhost"; @@ -722,7 +756,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 gc_pool& p) : p(p), uri(uri), ca(ca), cert(cert), key(key), cs(*(new (gc_new(p)) CURLSession(ca, cert, key))) { + 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(p)) CURLSession(ca, cert, key, cookie))) { } const value operator()(const list& args) const { @@ -757,6 +791,7 @@ struct proxy { const string ca; const string cert; const string key; + const string cookie; const CURLSession& cs; }; diff --git a/sca-cpp/trunk/modules/http/httpd.hpp b/sca-cpp/trunk/modules/http/httpd.hpp index 86a89d8823..534fd78503 100644 --- a/sca-cpp/trunk/modules/http/httpd.hpp +++ b/sca-cpp/trunk/modules/http/httpd.hpp @@ -144,13 +144,6 @@ const string hostName(request_rec* r, const string& def = "localhost") { return hn != NULL? hn : (r->server->server_hostname != NULL? r->server->server_hostname : def); } -/** - * Return the first subdomain name in a host name. - */ -const string subdomain(const string& host) { - return substr(host, 0, find(host, '.')); -} - /** * Return true if a request is targeting a virtual host. */ @@ -189,6 +182,16 @@ const string contentType(const request_rec* r) { return ct; } +/** + * Return the cookie header of a request. + */ +const string cookie(const request_rec* r) { + const char* c = apr_table_get(r->headers_in, "Cookie"); + if (c == NULL) + return ""; + return c; +} + /** * Return the remaining part of a uri after the given path (aka the path info.) */ diff --git a/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp b/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp index edbc8f3b99..0fd347c469 100644 --- a/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp +++ b/sca-cpp/trunk/modules/http/mod-ssltunnel.cpp @@ -141,7 +141,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, ""); const failable crc = http::connect(url, cs); if (!hasContent(crc)) return abort(conn, csock, reason(crc)); diff --git a/sca-cpp/trunk/modules/http/openauth.hpp b/sca-cpp/trunk/modules/http/openauth.hpp index 9b49cfa4c2..d7377324d9 100644 --- a/sca-cpp/trunk/modules/http/openauth.hpp +++ b/sca-cpp/trunk/modules/http/openauth.hpp @@ -63,9 +63,9 @@ const maybe sessionID(const list c) { } const maybe sessionID(const request_rec* r) { - const char* c = apr_table_get(r->headers_in, "Cookie"); + const string c = httpd::cookie(r); debug(c, "openauth::sessionid::cookies"); - if (c == NULL) + if (length(c) == 0) return maybe(); return sessionID(tokenize(";", c)); } diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp index 2b43ecc953..e990f6dba2 100644 --- a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp +++ b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp @@ -493,7 +493,7 @@ void childInit(apr_pool_t* p, server_rec* s) { sc.mc = *(new (gc_new()) memcache::MemCached(sc.mcaddrs)); // Setup a CURL session - sc.cs = *(new (gc_new()) http::CURLSession(sc.ca, sc.cert, sc.key)); + sc.cs = *(new (gc_new()) http::CURLSession(sc.ca, sc.cert, sc.key, "")); // Merge the updated configuration into the virtual hosts postConfigMerge(sc, s->next); diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp index 639d927891..61f242a80e 100644 --- a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp +++ b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp @@ -345,7 +345,7 @@ void childInit(apr_pool_t* p, server_rec* s) { sc.mc = *(new (gc_new()) memcache::MemCached(sc.mcaddrs)); // Setup a CURL session - sc.cs = *(new (gc_new()) http::CURLSession(sc.ca, sc.cert, sc.key)); + sc.cs = *(new (gc_new()) http::CURLSession(sc.ca, sc.cert, sc.key, "")); // Merge the updated configuration into the virtual hosts postConfigMerge(sc, s->next); diff --git a/sca-cpp/trunk/modules/server/client-test.hpp b/sca-cpp/trunk/modules/server/client-test.hpp index dffdb8977d..73bf5fd83a 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("", "", "", ""); { ostringstream os; const failable > r = http::get(curlWriter, &os, "http://localhost:8090/index.html", ch); @@ -76,7 +76,7 @@ struct getLoop { const bool testGetPerf() { gc_scoped_pool pool; - http::CURLSession ch("", "", ""); + http::CURLSession ch("", "", "", ""); const lambda 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("", "", "", ""); const value val = content(http::evalExpr(mklist(string("echo"), string("Hello")), testURI, ch)); assert(val == string("Hello")); return true; @@ -119,7 +119,7 @@ struct blobEvalLoop { const bool testEvalPerf() { gc_scoped_pool pool; - http::CURLSession ch("", "", ""); + http::CURLSession ch("", "", "", ""); const lambda el = evalLoop(testURI, ch); cout << "JSON-RPC eval echo test " << time(el, 5, 200) << " ms" << endl; @@ -139,7 +139,7 @@ bool testPost() { + (list() + "title" + string("item")) + (list() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - http::CURLSession ch("", "", ""); + http::CURLSession ch("", "", "", ""); const failable id = http::post(a, testURI, ch); assert(hasContent(id)); return true; @@ -174,7 +174,7 @@ struct postBlobLoop { const bool testPostPerf() { gc_scoped_pool pool; - http::CURLSession ch("", "", ""); + http::CURLSession ch("", "", "", ""); { const list i = list() + "content" + (list() + "item" + (list() + "name" + string("Apple")) @@ -206,7 +206,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("", "", "", ""); const lambda pl = postLoop(uri, val, ch); time(pl, 0, count); return true; @@ -263,7 +263,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("", "", "", ""); const lambda pl = postLoop(uri, val, ch); time(pl, 0, count); return true; @@ -333,7 +333,7 @@ const bool testPut() { + (list() + "title" + string("item")) + (list() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - http::CURLSession ch("", "", ""); + http::CURLSession ch("", "", "", ""); value rc = content(http::put(a, testURI + "/111", ch)); assert(rc == value(true)); return true; @@ -341,7 +341,7 @@ const bool testPut() { const bool testDel() { gc_scoped_pool pool; - http::CURLSession ch("", "", ""); + http::CURLSession ch("", "", "", ""); value rc = content(http::del(testURI + "/111", ch)); assert(rc == value(true)); return true; diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp index 362726622b..30d45baac4 100644 --- a/sca-cpp/trunk/modules/server/mod-eval.hpp +++ b/sca-cpp/trunk/modules/server/mod-eval.hpp @@ -96,6 +96,25 @@ const failable failableResult(const list& v) { return mkfailure(string(cadr(v))); } +/** + * Store current HTTP request for access from property and proxy lambda functions. + */ +#ifdef WANT_THREADS +__thread +#endif +request_rec* currentRequest = NULL; + +class ScopedRequest { +public: + ScopedRequest(request_rec* r) { + currentRequest = r; + } + + ~ScopedRequest() { + currentRequest = NULL; + } +}; + /** * Handle an HTTP GET. */ @@ -311,7 +330,7 @@ const failable del(request_rec* r, const lambda&)>& 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; - if (strncmp(r->uri, "/components/", 12) != 0) + if (strncmp(r->uri, "/components/", 12) != 0 && strncmp(r->uri, "/c/", 3) != 0) return DECLINED; r->handler = "mod_tuscany_eval"; return OK; @@ -323,7 +342,7 @@ int translate(request_rec *r) { const value mkhttpProxy(const ServerConf& sc, const string& ref, const string& base) { const string uri = base + ref; debug(uri, "modeval::mkhttpProxy::uri"); - return lambda&)>(http::proxy(uri, sc.ca, sc.cert, sc.key, sc.p)); + return lambda&)>(http::proxy(uri, sc.ca, sc.cert, sc.key, "", sc.p)); } /** @@ -331,7 +350,7 @@ const value mkhttpProxy(const ServerConf& sc, const string& ref, const string& b */ const value mkhttpProxy(const ServerConf& sc, const string& uri) { debug(uri, "modeval::mkhttpProxy::uri"); - return lambda&)>(http::proxy(uri, "", "", "", sc.p)); + return lambda&)>(http::proxy(uri, "", "", "", "", sc.p)); } /** @@ -342,17 +361,7 @@ public: implProxy(const ServerConf& sc, const value& name) : sc(sc), name(name) { } - const value operator()(const list& params) const { - debug(name, "modeval::implProxy::name"); - debug(params, "modeval::implProxy::input"); - - // If no component name was configured, use the first param as component name - const value cname = isNil(name)? cadr(params) : name; - const list aparams = isNil(name)? cons(car(params), cddr(params)) : params; - if (isNil(name)) { - debug(cname, "modeval::implProxy::wiredByImpl::name"); - debug(aparams, "modeval::implProxy::wiredByImpl::input"); - } + const value callImpl(const value& cname, const list& aparams) const { // Lookup the component implementation const list impl(assoctree(cname, sc.implTree)); @@ -369,6 +378,43 @@ public: return content(val); } + const value operator()(const list& params) const { + debug(name, "modeval::implProxy::name"); + debug(params, "modeval::implProxy::input"); + + // If the reference was 'wiredByImpl' use the first param as target + if (isNil(name)) { + const value uri = cadr(params); + const list aparams = cons(car(params), cddr(params)); + debug(uri, "modeval::implProxy::wiredByImpl::uri"); + debug(aparams, "modeval::implProxy::wiredByImpl::input"); + + // Use an HTTP proxy if the target is an absolute http:// target + if (httpd::isAbsolute(uri)) { + gc_pool p(currentRequest->pool); + + // Pass our certificate and the cookie from the current request + // if the target is in the same domain + if (http::topDomain(http::hostName(uri, p)) == http::topDomain(httpd::hostName(currentRequest))) { + debug(uri, "modeval::implProxy::httpproxy::samedomain"); + const lambda&)> px = lambda&)>(http::proxy(uri, sc.ca, sc.cert, sc.key, httpd::cookie(currentRequest), p)); + return px(aparams); + } + + // No certificate or cookie on a cross domain call + debug(uri, "modeval::implProxy::httpproxy::crossdomain"); + const lambda&)> px = lambda&)>(http::proxy(uri, "", "", "", "", p)); + return px(aparams); + } + + // Call the component implementation + return callImpl(uri, aparams); + } + + // Call the component implementation + return callImpl(name, params); + } + private: const ServerConf& sc; const value name; @@ -379,10 +425,44 @@ const value mkimplProxy(const ServerConf& sc, const value& name) { return lambda&)>(implProxy(sc, name)); } +/** + * Return a proxy lambda for an unwired reference. + */ +class unwiredProxy { +public: + unwiredProxy(const value& name) : name(name) { + } + + const value operator()(const list& params) const { + debug(name, "modeval::unwiredProxy::name"); + debug(params, "modeval::unwiredProxy::input"); + + // Get function returns a default empty value + if (car(params) == "get") { + debug(value(), "modeval::unwiredProxy::result"); + return value(); + } + + // All other functions return a failure + return mkfailure(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&)>(unwiredProxy(ref)); +} + /** * Convert a list of component references to a list of proxy lambdas. */ -const value mkrefProxy(const ServerConf& sc, const value& ref, const string& base) { +const value mkrefProxy(const ServerConf& sc, const value& ref, unused const string& base) { const value target = scdl::target(ref); const bool wbyimpl = scdl::wiredByImpl(ref); debug(ref, "modeval::mkrefProxy::ref"); @@ -393,7 +473,7 @@ const value mkrefProxy(const ServerConf& sc, const value& ref, const string& bas if (wbyimpl) return mkimplProxy(sc, value()); if (isNil(target)) - return mkhttpProxy(sc, scdl::name(ref), base); + return mkunwiredProxy(scdl::name(ref)); if (httpd::isAbsolute(target)) return mkhttpProxy(sc, target); return mkimplProxy(sc, car(pathValues(target))); @@ -405,25 +485,6 @@ const list refProxies(const ServerConf& sc, const list& refs, cons return cons(mkrefProxy(sc, car(refs), base), refProxies(sc, cdr(refs), base)); } -/** - * Store current HTTP request for access from property lambda functions. - */ -#ifdef WANT_THREADS -__thread -#endif -request_rec* currentRequest = NULL; - -class ScopedRequest { -public: - ScopedRequest(request_rec* r) { - currentRequest = r; - } - - ~ScopedRequest() { - currentRequest = NULL; - } -}; - /** * Convert a list of component properties to a list of lambda functions that just return * the property value. The host, user and email properties are configured with the values @@ -682,7 +743,7 @@ const failable virtualHostConfig(ServerConf& vsc, const ServerConf& sc, re // Resolve the configured virtual contribution under // the virtual host's SCA contribution root - vsc.contributionPath = vsc.virtualHostContributionPath + httpd::subdomain(httpd::hostName(r)) + "/"; + vsc.contributionPath = vsc.virtualHostContributionPath + http::subDomain(httpd::hostName(r)) + "/"; vsc.compositeName = vsc.virtualHostCompositeName; // Chdir to the virtual host's contribution diff --git a/sca-cpp/trunk/modules/server/mod-wiring.cpp b/sca-cpp/trunk/modules/server/mod-wiring.cpp index 8bc4504155..b1a8047525 100644 --- a/sca-cpp/trunk/modules/server/mod-wiring.cpp +++ b/sca-cpp/trunk/modules/server/mod-wiring.cpp @@ -33,6 +33,7 @@ #include "value.hpp" #include "monad.hpp" #include "../scdl/scdl.hpp" +#include "../http/http.hpp" #include "../http/httpd.hpp" extern "C" { @@ -292,7 +293,7 @@ const failable virtualHostConfig(ServerConf& sc, request_rec* r) { // Resolve the configured virtual contribution under // the virtual host's SCA contribution root - sc.contributionPath = sc.virtualHostContributionPath + httpd::subdomain(httpd::hostName(r)) + "/"; + sc.contributionPath = sc.virtualHostContributionPath + http::subDomain(httpd::hostName(r)) + "/"; sc.compositeName = sc.virtualHostCompositeName; // Configure the wiring for the deployed components @@ -309,7 +310,7 @@ int translate(request_rec *r) { return DECLINED; // No translation needed for a component or tunnel request - if (!strncmp(r->uri, "/components/", 12)) + if (!strncmp(r->uri, "/components/", 12) || !strncmp(r->uri, "/c/", 3)) return DECLINED; // Create a scoped memory pool @@ -328,7 +329,7 @@ int translate(request_rec *r) { } // Translate a component reference request - if (!strncmp(r->uri, "/references/", 12)) + if (!strncmp(r->uri, "/references/", 12) || !strncmp(r->uri, "/r/", 3)) return translateReference(usevh? vhc.sc: sc, r); // Translate a service request -- cgit v1.2.3