diff options
Diffstat (limited to 'sca-cpp/trunk/modules/server')
-rw-r--r-- | sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/server/mod-eval.hpp | 245 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/server/mod-wiring.cpp | 186 | ||||
-rwxr-xr-x | sca-cpp/trunk/modules/server/server-conf | 22 |
4 files changed, 228 insertions, 227 deletions
diff --git a/sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt b/sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt index 4395abf1dc..2cff8b7339 100644 --- a/sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt +++ b/sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt @@ -3,7 +3,7 @@ "result": { "host": "localhost", "path": [ - "components", + "c", "property-test" ], "query": { diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp index 00f59b9dda..b94636074a 100644 --- a/sca-cpp/trunk/modules/server/mod-eval.hpp +++ b/sca-cpp/trunk/modules/server/mod-eval.hpp @@ -26,6 +26,8 @@ * HTTPD module used to eval component implementations. */ +#include <sys/stat.h> + #include "string.hpp" #include "stream.hpp" #include "function.hpp" @@ -54,13 +56,15 @@ namespace modeval { */ class ServerConf { public: - ServerConf(apr_pool_t* p, server_rec* s) : p(p), server(s), wiringServerName(""), contributionPath(""), compositeName(""), virtualHostContributionPath(""), virtualHostCompositeName(""), ca(""), cert(""), key("") { + ServerConf(apr_pool_t* p, server_rec* s) : p(p), server(s), contributionPath(""), compositeName(""), virtualHostContributionPath(""), virtualHostCompositeName(""), ca(""), cert(""), key("") { + } + + ServerConf(apr_pool_t* p, const ServerConf& ssc, const string& name) : p(p), server(ssc.server), lifecycle(ssc.lifecycle), contributionPath(ssc.virtualHostContributionPath + name + "/"), compositeName(ssc.virtualHostCompositeName), virtualHostContributionPath(""), virtualHostCompositeName(""), ca(ssc.ca), cert(ssc.cert), key(ssc.key) { } const gc_pool p; server_rec* server; lambda<value(const list<value>&)> lifecycle; - string wiringServerName; string contributionPath; string compositeName; string virtualHostContributionPath; @@ -119,7 +123,7 @@ public: /** * Handle an HTTP GET. */ -const failable<int> get(request_rec* r, const lambda<value(const list<value>&)>& impl) { +const failable<int> get(const list<value>& rpath, request_rec* r, const lambda<value(const list<value>&)>& impl) { debug(r->uri, "modeval::get::uri"); // Inspect the query string @@ -145,8 +149,7 @@ const failable<int> get(request_rec* r, const lambda<value(const list<value>&)>& } // Evaluate the GET expression - const list<value> path(pathValues(r->uri)); - const list<value> params(append<value>(cddr(path), mkvalues(args))); + const list<value> params(append<value>(cddr(rpath), mkvalues(args))); const failable<value> val = failableResult(impl(cons<value>("get", mklist<value>(params)))); if (!hasContent(val)) return mkfailure<int>(reason(val)); @@ -222,7 +225,7 @@ const failable<int> get(request_rec* r, const lambda<value(const list<value>&)>& /** * Handle an HTTP POST. */ -const failable<int> post(request_rec* r, const lambda<value(const list<value>&)>& impl) { +const failable<int> post(const list<value>& rpath, request_rec* r, const lambda<value(const list<value>&)>& impl) { debug(r->uri, "modeval::post::url"); // Evaluate a JSON-RPC request and return a JSON result @@ -257,7 +260,6 @@ const failable<int> post(request_rec* r, const lambda<value(const list<value>&)> if (contains(ct, "application/atom+xml")) { // Read the ATOM entry - const list<value> path(pathValues(r->uri)); const int rc = httpd::setupReadPolicy(r); if(rc != OK) return rc; @@ -266,7 +268,7 @@ const failable<int> post(request_rec* r, const lambda<value(const list<value>&)> const value entry = elementsToValues(content(atom::readATOMEntry(ls))); // Evaluate the POST expression - const failable<value> val = failableResult(impl(cons<value>("post", mklist<value>(cddr(path), entry)))); + const failable<value> val = failableResult(impl(cons<value>("post", mklist<value>(cddr(rpath), entry)))); if (!hasContent(val)) return mkfailure<int>(reason(val)); @@ -288,11 +290,10 @@ const failable<int> post(request_rec* r, const lambda<value(const list<value>&)> /** * Handle an HTTP PUT. */ -const failable<int> put(request_rec* r, const lambda<value(const list<value>&)>& impl) { +const failable<int> put(const list<value>& rpath, request_rec* r, const lambda<value(const list<value>&)>& impl) { debug(r->uri, "modeval::put::url"); // Read the ATOM entry - const list<value> path(pathValues(r->uri)); const int rc = httpd::setupReadPolicy(r); if(rc != OK) return rc; @@ -301,7 +302,7 @@ const failable<int> put(request_rec* r, const lambda<value(const list<value>&)>& const value entry = elementsToValues(content(atom::readATOMEntry(ls))); // Evaluate the PUT expression and update the corresponding resource - const failable<value> val = failableResult(impl(cons<value>("put", mklist<value>(cddr(path), entry)))); + const failable<value> val = failableResult(impl(cons<value>("put", mklist<value>(cddr(rpath), entry)))); if (!hasContent(val)) return mkfailure<int>(reason(val)); if (val == value(false)) @@ -312,12 +313,11 @@ const failable<int> put(request_rec* r, const lambda<value(const list<value>&)>& /** * Handle an HTTP DELETE. */ -const failable<int> del(request_rec* r, const lambda<value(const list<value>&)>& impl) { +const failable<int> del(const list<value>& rpath, request_rec* r, const lambda<value(const list<value>&)>& impl) { debug(r->uri, "modeval::delete::url"); // Evaluate an ATOM delete request - const list<value> path(pathValues(r->uri)); - const failable<value> val = failableResult(impl(cons<value>("delete", mklist<value>(cddr(path))))); + const failable<value> val = failableResult(impl(cons<value>("delete", mklist<value>(cddr(rpath))))); if (!hasContent(val)) return mkfailure<int>(reason(val)); if (val == value(false)) @@ -328,13 +328,52 @@ const failable<int> del(request_rec* r, const lambda<value(const list<value>&)>& /** * Translate a component request. */ +const int translateRequest(const ServerConf& sc, const list<value>& rpath, request_rec *r) { + debug(rpath, "modeval::translateRequest::path"); + if (isNil(rpath)) + return DECLINED; + + // Translate a component request + const value c = car(rpath); + if (c == string("components") || c == string("c")) { + r->handler = "mod_tuscany_eval"; + return OK; + } + + // Translate a request targeting a virtual host or virtual app + if (hasVirtualCompositeConf(sc) && !isNil(cdr(rpath))) { + const string cp = sc.virtualHostContributionPath + string(c) + "/" + sc.virtualHostCompositeName; + struct stat st; + const int s = stat(c_str(cp), &st); + if (s != -1) { + const value d = cadr(rpath); + if (d == string("components") || d == string("c")) { + r->handler = "mod_tuscany_eval"; + return OK; + } + } + } + + return DECLINED; +} + +/** + * Translate a component request. + */ 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 && strncmp(r->uri, "/c/", 3) != 0) - return DECLINED; - r->handler = "mod_tuscany_eval"; - return OK; + + // Create a scoped memory pool + gc_scoped_pool pool(r->pool); + + httpdDebugRequest(r, "modeval::translate::input"); + + // Get the server configuration + const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_eval); + + // Translate the request + return translateRequest(sc, pathValues(r->uri), r); } /** @@ -473,7 +512,7 @@ const value mkunwiredProxy(const string& ref) { /** * Convert a list of component references to a list of proxy lambdas. */ -const value mkrefProxy(const ServerConf& sc, const value& ref, unused const string& base) { +const value mkrefProxy(const ServerConf& sc, const value& ref) { const value target = scdl::target(ref); const bool wbyimpl = scdl::wiredByImpl(ref); debug(ref, "modeval::mkrefProxy::ref"); @@ -490,10 +529,10 @@ const value mkrefProxy(const ServerConf& sc, const value& ref, unused const stri return mkimplProxy(sc, car(pathValues(target))); } -const list<value> refProxies(const ServerConf& sc, const list<value>& refs, const string& base) { +const list<value> refProxies(const ServerConf& sc, const list<value>& refs) { if (isNil(refs)) return refs; - return cons(mkrefProxy(sc, car(refs), base), refProxies(sc, cdr(refs), base)); + return cons(mkrefProxy(sc, car(refs)), refProxies(sc, cdr(refs))); } /** @@ -525,7 +564,8 @@ struct pathPropProxy { pathPropProxy(unused const value& v) { } const value operator()(unused const list<value>& params) const { - const value v = pathValues(currentRequest->uri); + const char* u = apr_table_get(currentRequest->headers_in, "X-Request-URI"); + const value v = u != NULL? pathValues(string(u)) : list<value>(); debug(v, "modeval::pathPropProxy::value"); return v; } @@ -624,9 +664,7 @@ const value evalComponent(ServerConf& sc, const value& comp) { debug(impl, "modeval::evalComponent::impl"); // Convert component references to configured proxy lambdas - ostringstream base; - base << sc.wiringServerName << "/references/" << string(scdl::name(comp)) << "/"; - const list<value> rpx(refProxies(sc, scdl::references(comp), str(base))); + const list<value> rpx(refProxies(sc, scdl::references(comp))); // Convert component properties to configured proxy lambdas const list<value> ppx(propProxies(scdl::properties(comp))); @@ -719,116 +757,93 @@ const failable<bool> startComponents(ServerConf& sc) { } /** - * Virtual host scoped server configuration. - */ -class VirtualHostConf { -public: - VirtualHostConf(const gc_pool& p, const ServerConf& sc) : sc(sc), vsc(pool(p), sc.server) { - vsc.lifecycle = sc.lifecycle; - vsc.virtualHostContributionPath = sc.virtualHostContributionPath; - vsc.virtualHostCompositeName = sc.virtualHostCompositeName; - vsc.ca = sc.ca; - vsc.cert = sc.cert; - vsc.key = sc.key; - } - - ~VirtualHostConf() { - extern const failable<bool> virtualHostCleanup(const ServerConf& vsc, const ServerConf& sc); - virtualHostCleanup(vsc, sc); - } - - const ServerConf& sc; - ServerConf vsc; -}; - -/** * Configure and start the components deployed in a virtual host. */ -const failable<bool> virtualHostConfig(ServerConf& vsc, const ServerConf& sc, request_rec* r) { - - // Determine the server name and wiring server name - debug(httpd::serverName(vsc.server), "modeval::virtualHostConfig::serverName"); +const failable<bool> virtualHostConfig(ServerConf& sc, const ServerConf& ssc, request_rec* r) { + debug(httpd::serverName(ssc.server), "modeval::virtualHostConfig::serverName"); debug(httpd::serverName(r), "modeval::virtualHostConfig::virtualHostName"); - vsc.wiringServerName = httpd::serverName(r); - debug(vsc.wiringServerName, "modeval::virtualHostConfig::wiringServerName"); - debug(vsc.virtualHostContributionPath, "modwiring::virtualHostConfig::virtualHostContributionPath"); - - // Resolve the configured virtual contribution under - // the virtual host's SCA contribution root - vsc.contributionPath = vsc.virtualHostContributionPath + http::subDomain(httpd::hostName(r)) + "/"; - vsc.compositeName = vsc.virtualHostCompositeName; + debug(ssc.virtualHostContributionPath, "modwiring::virtualHostConfig::virtualHostContributionPath"); + debug(sc.contributionPath, "modeval::virtualHostConfig::contributionPath"); // Chdir to the virtual host's contribution if (chdir(c_str(sc.contributionPath)) != 0) return mkfailure<bool>(string("Couldn't chdir to the deployed contribution: ") + sc.contributionPath); // Configure the deployed components - const failable<bool> cr = confComponents(vsc); + const failable<bool> cr = confComponents(sc); if (!hasContent(cr)) return cr; // Start the configured components - const failable<bool> sr = startComponents(vsc); + const failable<bool> sr = startComponents(sc); if (!hasContent(sr)) return sr; // Store the implementation lambda functions (from both the virtual host and the // main server) in a tree for fast retrieval - vsc.implTree = mkbtree(sort(append(vsc.implementations, sc.implementations))); + sc.implTree = mkbtree(sort(append(sc.implementations, ssc.implementations))); return true; } /** * Cleanup a virtual host. */ -const failable<bool> virtualHostCleanup(const ServerConf& vsc, const ServerConf& sc) { - if (!hasCompositeConf(vsc)) +const failable<bool> virtualHostCleanup(const ServerConf& sc, const ServerConf& ssc) { + if (!hasCompositeConf(sc)) return true; debug("modeval::virtualHostCleanup"); // Stop the component implementations - applyLifecycleExpr(vsc.implementations, mklist<value>("stop")); + applyLifecycleExpr(sc.implementations, mklist<value>("stop")); // Chdir back to the main server's contribution - if (chdir(c_str(sc.contributionPath)) != 0) - return mkfailure<bool>(string("Couldn't chdir to the deployed contribution: ") + sc.contributionPath); + if (chdir(c_str(ssc.contributionPath)) != 0) + return mkfailure<bool>(string("Couldn't chdir to the deployed contribution: ") + ssc.contributionPath); return true; } /** - * HTTP request handler. + * Handle a component request. */ -int handler(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(strcmp(r->handler, "mod_tuscany_eval")) - return DECLINED; - - // Create a scoped memory pool - gc_scoped_pool pool(r->pool); - - ScopedRequest sr(r); - httpdDebugRequest(r, "modeval::handler::input"); +const int handleRequest(const ServerConf& sc, const list<value>& rpath, request_rec *r) { + debug(rpath, "modeval::handleRequest::path"); + if (isNil(cdr(rpath))) + return HTTP_NOT_FOUND; - // Get the server configuration - const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_eval); + // Handle a request targeting a virtual host or virtual app + if (hasVirtualCompositeConf(sc)) { + if (httpd::isVirtualHostRequest(sc.server, r)) { + ServerConf vsc(r->pool, sc, http::subDomain(httpd::hostName(r))); + if (!hasContent(virtualHostConfig(vsc, sc, r))) + return HTTP_INTERNAL_SERVER_ERROR; + const int rc = handleRequest(vsc, rpath, r); + virtualHostCleanup(vsc, sc); + return rc; + } - // Process dynamic virtual host configuration, if any - VirtualHostConf vhc(gc_pool(r->pool), sc); - const bool usevh = hasVirtualCompositeConf(vhc.vsc) && httpd::isVirtualHostRequest(sc.server, r); - if (usevh) { - const failable<bool> cr = virtualHostConfig(vhc.vsc, sc, r); - if (!hasContent(cr)) - return httpd::reportStatus(mkfailure<int>(reason(cr))); + const value c = car(rpath); + if (c != string("components") && c != string("c")) { + const string cp = sc.virtualHostContributionPath + string(c) + "/" + sc.virtualHostCompositeName; + struct stat st; + const int s = stat(c_str(cp), &st); + if (s != -1) { + ServerConf vsc(r->pool, sc, string(c)); + if (!hasContent(virtualHostConfig(vsc, sc, r))) + return HTTP_INTERNAL_SERVER_ERROR; + const int rc = handleRequest(vsc, cdr(rpath), r); + virtualHostCleanup(vsc, sc); + return rc; + } + } } + // Store the request uri path in a header + apr_table_setn(r->headers_in, "X-Request-URI", apr_pstrdup(r->pool, c_str(path(rpath)))); + // Get the component implementation lambda - const list<value> path(pathValues(r->uri)); - if (isNil(cdr(path))) - return HTTP_NOT_FOUND; - const list<value> impl(assoctree<value>(cadr(path), usevh? vhc.vsc.implTree : sc.implTree)); + const list<value> impl(assoctree<value>(cadr(rpath), sc.implTree)); if (isNil(impl)) { - mkfailure<int>(string("Couldn't find component implementation: ") + cadr(path)); + mkfailure<int>(string("Couldn't find component implementation: ") + cadr(rpath)); return HTTP_NOT_FOUND; } @@ -837,17 +852,39 @@ int handler(request_rec *r) { if (r->header_only) return OK; if(r->method_number == M_GET) - return httpd::reportStatus(get(r, l)); + return httpd::reportStatus(get(rpath, r, l)); if(r->method_number == M_POST) - return httpd::reportStatus(post(r, l)); + return httpd::reportStatus(post(rpath, r, l)); if(r->method_number == M_PUT) - return httpd::reportStatus(put(r, l)); + return httpd::reportStatus(put(rpath, r, l)); if(r->method_number == M_DELETE) - return httpd::reportStatus(del(r, l)); + return httpd::reportStatus(del(rpath, r, l)); return HTTP_NOT_IMPLEMENTED; } /** + * HTTP request handler. + */ +int handler(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(strcmp(r->handler, "mod_tuscany_eval")) + return DECLINED; + + // Create a scoped memory pool + gc_scoped_pool pool(r->pool); + + ScopedRequest sr(r); + httpdDebugRequest(r, "modeval::handler::input"); + + // Get the server configuration + const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_eval); + + // Handle the request + return handleRequest(sc, pathValues(r->uri), r); +} + +/** * Cleanup callback, called when the server is stopped or restarted. */ apr_status_t serverCleanup(void* v) { @@ -876,9 +913,6 @@ const int postConfigMerge(const ServerConf& mainsc, server_rec* s) { return OK; ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_eval); debug(httpd::serverName(s), "modeval::postConfigMerge::serverName"); - if (sc.wiringServerName == "") - sc.wiringServerName = mainsc.wiringServerName != ""? mainsc.wiringServerName : httpd::serverName(s); - debug(sc.wiringServerName, "modeval::postConfigMerge::wiringServerName"); sc.lifecycle = mainsc.lifecycle; sc.contributionPath = mainsc.contributionPath; sc.compositeName = mainsc.compositeName; @@ -900,8 +934,6 @@ int postConfig(apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, // Get the server configuration and determine the wiring server name ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_eval); debug(httpd::serverName(s), "modeval::postConfig::serverName"); - if (sc.wiringServerName == "") sc.wiringServerName = httpd::serverName(s); - debug(sc.wiringServerName, "modeval::postConfig::wiringServerName"); // Count the calls to post config const string k("tuscany::modeval::postConfig"); @@ -982,12 +1014,6 @@ void childInit(apr_pool_t* p, server_rec* s) { /** * Configuration commands. */ -const char* confWiringServerName(cmd_parms *cmd, unused void *c, const char *arg) { - gc_scoped_pool pool(cmd->pool); - ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval); - sc.wiringServerName = arg; - return NULL; -} const char* confContribution(cmd_parms *cmd, unused void *c, const char *arg) { gc_scoped_pool pool(cmd->pool); ServerConf& sc = httpd::serverConf<ServerConf>(cmd, &mod_tuscany_eval); @@ -1040,7 +1066,6 @@ const char* confEnv(unused cmd_parms *cmd, unused void *c, const char *name, con * HTTP server module declaration. */ const command_rec commands[] = { - AP_INIT_TAKE1("SCAWiringServerName", (const char*(*)())confWiringServerName, NULL, RSRC_CONF, "SCA wiring server name"), AP_INIT_TAKE1("SCAContribution", (const char*(*)())confContribution, NULL, RSRC_CONF, "SCA contribution location"), AP_INIT_TAKE1("SCAComposite", (const char*(*)())confComposite, NULL, RSRC_CONF, "SCA composite location"), AP_INIT_TAKE1("SCAVirtualContribution", (const char*(*)())confVirtualContribution, NULL, RSRC_CONF, "SCA virtual host contribution location"), diff --git a/sca-cpp/trunk/modules/server/mod-wiring.cpp b/sca-cpp/trunk/modules/server/mod-wiring.cpp index cb2f44c729..39e43c0420 100644 --- a/sca-cpp/trunk/modules/server/mod-wiring.cpp +++ b/sca-cpp/trunk/modules/server/mod-wiring.cpp @@ -57,6 +57,9 @@ public: ServerConf(apr_pool_t* p, server_rec* s) : p(p), server(s), contributionPath(""), compositeName(""), virtualHostContributionPath(""), virtualHostCompositeName("") { } + ServerConf(apr_pool_t* p, const ServerConf& ssc, const string& name) : p(p), server(ssc.server), contributionPath(ssc.virtualHostContributionPath + name + "/"), compositeName(ssc.virtualHostCompositeName), virtualHostContributionPath(""), virtualHostCompositeName("") { + } + const gc_pool p; server_rec* server; string contributionPath; @@ -85,12 +88,13 @@ const bool hasVirtualCompositeConf(const ServerConf& sc) { * Route a /references/component-name/reference-name request, * to the target of the component reference. */ -int translateReference(const ServerConf& sc, request_rec *r) { +int translateReference(const ServerConf& sc, request_rec *r, const list<value>& rpath, const list<value>& apath) { httpdDebugRequest(r, "modwiring::translateReference::input"); debug(r->uri, "modwiring::translateReference::uri"); + debug(apath, "modwiring::translateReference::apath"); + debug(rpath, "modwiring::translateReference::rpath"); // Find the requested component - const list<value> rpath(pathValues(r->uri)); if (isNil(cdr(rpath))) return HTTP_NOT_FOUND; const list<value> comp(assoctree(cadr(rpath), sc.references)); @@ -110,8 +114,9 @@ int translateReference(const ServerConf& sc, request_rec *r) { if (useModProxy) { // Build proxy URI string turi = target + path(pathInfo) + (r->args != NULL? string("?") + r->args : string("")); - r->filename = apr_pstrdup(r->pool, c_str(string("proxy:") + turi)); - debug(r->filename, "modwiring::translateReference::filename"); + const string proxy(string("proxy:") + turi); + debug(proxy, "modwiring::translateReference::proxy"); + r->filename = apr_pstrdup(r->pool, c_str(proxy)); r->proxyreq = PROXYREQ_REVERSE; r->handler = "proxy-server"; apr_table_setn(r->notes, "proxy-nocanon", "1"); @@ -126,9 +131,10 @@ int translateReference(const ServerConf& sc, request_rec *r) { // Route to a relative target URI using a local internal redirect // /components/, target component name and request path info const value tname = substr(target, 0, find(target, '/')); - const string tpath = path(cons(tname, pathInfo)) + (r->args != NULL? string("?") + r->args : string("")); - r->filename = apr_pstrdup(r->pool, c_str(string("/redirect:/components") + tpath)); - debug(r->filename, "modwiring::translateReference::filename"); + const string tp = path(append(apath, cons<value>(string("c"), cons(tname, pathInfo)))) + (r->args != NULL? string("?") + r->args : string("")); + const string redir(string("/redirect:") + tp); + debug(redir, "modwiring::translateReference::redirect"); + r->filename = apr_pstrdup(r->pool, c_str(redir)); r->handler = "mod_tuscany_wiring"; return OK; } @@ -159,26 +165,24 @@ const list<value> assocPath(const value& k, const list<value>& tree) { /** * Route a service request to the component providing the requested service. */ -int translateService(const ServerConf& sc, request_rec *r) { +int translateService(const ServerConf& sc, request_rec *r, const list<value>& rpath, const list<value>& apath) { httpdDebugRequest(r, "modwiring::translateService::input"); debug(r->uri, "modwiring::translateService::uri"); // Find the requested component debug(sc.services, "modwiring::translateService::services"); - const list<value> p(pathValues(r->uri)); - const list<value> svc(assocPath(p, sc.services)); + const list<value> svc(assocPath(rpath, sc.services)); if (isNil(svc)) return DECLINED; debug(svc, "modwiring::translateService::service"); // Build a component-name + path-info URI - const list<value> target(cons<value>(cadr(svc), httpd::pathInfo(p, car(svc)))); + const list<value> target(append(apath, cons<value>(string("c"), cons<value>(cadr(svc), httpd::pathInfo(rpath, car(svc)))))); debug(target, "modwiring::translateService::target"); // Dispatch to the target component using a local internal redirect - const string tp(path(target)); - debug(tp, "modwiring::translateService::path"); - const string redir(string("/redirect:/components") + tp); + const string tp(path(target) + (r->args != NULL? string("?") + r->args : string(""))); + const string redir(string("/redirect:") + tp); debug(redir, "modwiring::translateService::redirect"); r->filename = apr_pstrdup(r->pool, c_str(redir)); r->handler = "mod_tuscany_wiring"; @@ -186,38 +190,6 @@ int translateService(const ServerConf& sc, request_rec *r) { } /** - * Route an /apps/app-name/... request to the target app domain. - */ -int translateDomain(request_rec *r) { - httpdDebugRequest(r, "modwiring::translateDomain::input"); - debug(r->uri, "modwiring::translateDomain::uri"); - - // Extract the requested app name - const list<value> apath(pathValues(r->uri)); - if (isNil(cdr(apath))) - return HTTP_NOT_FOUND; - - // Compute the target uri in the target app domain - ostringstream turi; - turi << httpd::scheme(r) << "://" << string(cadr(apath)) << "." << httpd::hostName(r) << ":" << httpd::port(r) << string(path(cddr(apath))) << (r->args != NULL? string("?") + r->args : string("")); - debug(str(turi), "modwiring::translateDomain::appuri"); - - // Route to an absolute target URI using mod_proxy or an HTTP client redirect - if (useModProxy) { - r->filename = apr_pstrdup(r->pool, c_str(string("proxy:") + str(turi))); - debug(r->filename, "modwiring::translateDomain::filename"); - r->proxyreq = PROXYREQ_REVERSE; - r->handler = "proxy-server"; - apr_table_setn(r->notes, "proxy-nocanon", "1"); - return OK; - } - - debug(str(turi), "modwiring::translateDomain::location"); - r->handler = "mod_tuscany_wiring"; - return httpd::externalRedirect(str(turi), r); -} - -/** * Read the components declared in a composite. */ const failable<list<value> > readComponents(const string& path) { @@ -299,37 +271,83 @@ const bool confComponents(ServerConf& sc) { } /** - * Virtual host scoped server configuration. + * Configure and start the components deployed in a virtual host. */ -class VirtualHostConf { -public: - VirtualHostConf(const gc_pool& p, const ServerConf& ssc) : sc(pool(p), ssc.server) { - sc.virtualHostContributionPath = ssc.virtualHostContributionPath; - sc.virtualHostCompositeName = ssc.virtualHostCompositeName; - } +const failable<ServerConf> virtualHostConfig(ServerConf& sc, const ServerConf& ssc, request_rec* r) { + debug(httpd::serverName(ssc.server), "modwiring::virtualHostConfig::serverName"); + debug(httpd::serverName(r), "modwiring::virtualHostConfig::virtualHostName"); + debug(ssc.virtualHostContributionPath, "modwiring::virtualHostConfig::virtualHostContributionPath"); + debug(sc.contributionPath, "modwiring::virtualHostConfig::contributionPath"); - ~VirtualHostConf() { - } + // Configure the wiring for the deployed components + confComponents(sc); - ServerConf sc; -}; + return sc; +} /** - * Configure and start the components deployed in a virtual host. + * Translate an HTTP service or reference request and route it + * to the target component. */ -const failable<bool> virtualHostConfig(ServerConf& sc, request_rec* r) { - debug(httpd::serverName(sc.server), "modwiring::virtualHostConfig::serverName"); - debug(httpd::serverName(r), "modwiring::virtualHostConfig::virtualHostName"); - debug(sc.virtualHostContributionPath, "modwiring::virtualHostConfig::virtualHostContributionPath"); +const int translateRequest(const ServerConf& sc, request_rec *r, const list<value>& rpath, const list<value>& apath) { + debug(apath, "modwiring::translateRequest::apath"); + debug(rpath, "modwiring::translateRequest::rpath"); + if (isNil(apath) && isNil(rpath)) + return DECLINED; - // Resolve the configured virtual contribution under - // the virtual host's SCA contribution root - sc.contributionPath = sc.virtualHostContributionPath + http::subDomain(httpd::hostName(r)) + "/"; - sc.compositeName = sc.virtualHostCompositeName; + if (!isNil(rpath)) { + + // No translation needed for a component or resource request + const value c = car(rpath); + if (c == string("components") || c == string("c") || c == string("vhosts") || c == string("v")) + return DECLINED; + + // If the request is targeting a virtual host, use the corresponding + // virtual host configuration + const bool vcc = hasVirtualCompositeConf(sc); + if (vcc && httpd::isVirtualHostRequest(sc.server, r)) { + ServerConf vsc(r->pool, sc, http::subDomain(httpd::hostName(r))); + if (!hasContent(virtualHostConfig(vsc, sc, r))) + return HTTP_INTERNAL_SERVER_ERROR; + return translateRequest(vsc, r, rpath, list<value>()); + } - // Configure the wiring for the deployed components - confComponents(sc); - return true; + // Translate a component reference request + if (c == string("references") || c == string("r")) + return translateReference(sc, r, rpath, apath); + + // Attempt to translate the request to a service request + if (translateService(sc, r, rpath, apath) == OK) + return OK; + + // If the request is targeting a virtual app, use the corresponding + // virtual host configuration + if (vcc) { + const string cp = sc.virtualHostContributionPath + string(c) + "/" + sc.virtualHostCompositeName; + struct stat st; + const int s = stat(c_str(cp), &st); + if (s == -1) + return DECLINED; + ServerConf vsc(r->pool, sc, string(c)); + if (!hasContent(virtualHostConfig(vsc, sc, r))) + return HTTP_INTERNAL_SERVER_ERROR; + return translateRequest(vsc, r, cdr(rpath), mklist<value>(car(rpath))); + } + } + + // If we're in a virtual app and the request is targeting a regular + // resource, redirect it to /v/<uri>. This will allow mapping to the + // actual resources using HTTPD aliases. + if (!isNil(apath)) { + const string tp = string("/v") + string(r->uri) + (r->args != NULL? string("?") + r->args : string("")); + const string redir = string("/redirect:") + tp; + debug(redir, "modwiring::translateRequest::redirect"); + r->filename = apr_pstrdup(r->pool, c_str(redir)); + r->handler = "mod_tuscany_wiring"; + return OK; + } + + return DECLINED; } /** @@ -340,35 +358,15 @@ 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; - // No translation needed for a component or tunnel request - if (!strncmp(r->uri, "/components/", 12) || !strncmp(r->uri, "/c/", 3)) - return DECLINED; - // Create a scoped memory pool gc_scoped_pool pool(r->pool); - - // Translate an app domain request - if (!strncmp(r->uri, "/apps/", 6) || !strncmp(r->uri, "/a/", 3)) - return translateDomain(r); + httpdDebugRequest(r, "modwiring::translate::input"); // Get the server configuration const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_wiring); - // Process dynamic virtual host configuration - VirtualHostConf vhc(gc_pool(r->pool), sc); - const bool usevh = hasVirtualCompositeConf(vhc.sc) && httpd::isVirtualHostRequest(sc.server, r); - if (usevh) { - const failable<bool> cr = virtualHostConfig(vhc.sc, r); - if (!hasContent(cr)) - return -1; - } - - // Translate a component reference request - if (!strncmp(r->uri, "/references/", 12) || !strncmp(r->uri, "/r/", 3)) - return translateReference(usevh? vhc.sc: sc, r); - - // Translate a service request - return translateService(usevh? vhc.sc : sc, r); + // Translate the request + return translateRequest(sc, r, pathValues(r->uri), list<value>()); } /** @@ -389,12 +387,12 @@ int handler(request_rec *r) { // Create a scoped memory pool gc_scoped_pool pool(r->pool); - // Do an internal redirect httpdDebugRequest(r, "modwiring::handler::input"); - debug(r->uri, "modwiring::handler::uri"); debug(r->filename, "modwiring::handler::filename"); debug(r->path_info, "modwiring::handler::path info"); + + // Do an internal redirect if (r->args == NULL) return httpd::internalRedirect(httpd::redirectURI(string(r->filename + 10), string(r->path_info)), r); return httpd::internalRedirect(httpd::redirectURI(string(r->filename + 10), string(r->path_info), string(r->args)), r); diff --git a/sca-cpp/trunk/modules/server/server-conf b/sca-cpp/trunk/modules/server/server-conf index a8e57cf289..5b3024abbc 100755 --- a/sca-cpp/trunk/modules/server/server-conf +++ b/sca-cpp/trunk/modules/server/server-conf @@ -31,25 +31,6 @@ else libsuffix=".so" fi -conf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-conf"` -host=`echo $conf | awk '{ print $6 }'` -port=`echo $conf | awk '{ print $7 }' | awk -F "/" '{ print $1 }'` -pport=`echo $conf | awk '{ print $7 }' | awk -F "/" '{ print $2 }'` -if [ "$pport" = "" ]; then - pport=$port -fi -servername="http://$host:$pport" - -sslconf=`cat $root/conf/httpd.conf | grep "# Generated by: httpd-ssl-conf"` -if [ "$sslconf" != "" ]; then - sslport=`echo $sslconf | awk '{ print $6 }' | awk -F "/" '{ print $1 }'` - sslpport=`echo $sslconf | awk '{ print $6 }' | awk -F "/" '{ print $2 }'` - if [ "$sslpport" = "" ]; then - sslpport=$sslport - fi - servername="https://$host:$sslpport" -fi - cat >>$root/conf/modules.conf <<EOF # Generated by: server-conf $* # Support for SCA component wiring @@ -59,9 +40,6 @@ EOF cat >>$root/conf/httpd.conf <<EOF # Generated by: server-conf $* -# Route all wiring through the configured server name -SCAWiringServerName $servername - # Serve JavaScript client scripts Alias /component.js $jsprefix/htdocs/component.js Alias /util.js $jsprefix/htdocs/util.js |