diff options
Diffstat (limited to 'sca-cpp/trunk/modules/http')
-rw-r--r-- | sca-cpp/trunk/modules/http/curl-test.cpp | 161 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/http/curl.hpp | 39 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/http/htdocs/entry.xml | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/http/htdocs/feed.xml | 2 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/http/htdocs/json-request.txt | 1 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/http/htdocs/json-result.txt | 1 | ||||
-rwxr-xr-x | sca-cpp/trunk/modules/http/http-test | 12 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/http/httpd-client.scm | 25 | ||||
-rwxr-xr-x | sca-cpp/trunk/modules/http/httpd-conf | 2 | ||||
-rwxr-xr-x | sca-cpp/trunk/modules/http/httpd-test | 41 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/http/httpd-test.composite | 42 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/http/httpd-test.scm | 29 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/http/httpd.hpp | 146 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/http/mod-eval.cpp | 532 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/http/mod-wiring.cpp | 276 | ||||
-rwxr-xr-x | sca-cpp/trunk/modules/http/wiring-test | 92 |
16 files changed, 173 insertions, 1230 deletions
diff --git a/sca-cpp/trunk/modules/http/curl-test.cpp b/sca-cpp/trunk/modules/http/curl-test.cpp index 863aa98828..0a6fbcd8a6 100644 --- a/sca-cpp/trunk/modules/http/curl-test.cpp +++ b/sca-cpp/trunk/modules/http/curl-test.cpp @@ -53,16 +53,15 @@ const bool testGet() { CURLHandle ch; { std::ostringstream os; - const failable<list<std::ostringstream*>, std::string> r = get<std::ostringstream*>(curlWriter, &os, "http://localhost:8091", ch); - assert(hasValue(r)); + const failable<list<std::ostringstream*>, std::string> r = get<std::ostringstream*>(curlWriter, &os, "http://localhost:8090", ch); + assert(hasContent(r)); assert(contains(os.str(), "HTTP/1.1 200 OK")); assert(contains(os.str(), "It works")); } { - const failable<value, std::string> r = get("http://localhost:8091", ch); - assert(hasValue(r)); - const value val = r; - assert(contains(val, "It works")); + const failable<value, std::string> r = get("http://localhost:8090", ch); + assert(hasContent(r)); + assert(contains(content(r), "It works")); } return true; } @@ -70,10 +69,9 @@ const bool testGet() { const bool testGetLoop(const int count, CURLHandle& ch) { if (count == 0) return true; - const failable<value, std::string> r = get("http://localhost:8091", ch); - assert(hasValue(r)); - const value val = r; - assert(contains(val, "It works")); + const failable<value, std::string> r = get("http://localhost:8090", ch); + assert(hasContent(r)); + assert(contains(content(r), "It works")); return testGetLoop(count - 1, ch); } @@ -95,142 +93,6 @@ const bool testGetPerf() { return true; } -const bool testEval() { - CURLHandle ch; - const value val = evalExpr(mklist<value>(std::string("echo"), std::string("Hello")), "http://localhost:8091/test", ch); - assert(val == std::string("Hello")); - return true; -} - -const bool testEvalLoop(const int count, CURLHandle& ch) { - if (count == 0) - return true; - const value val = evalExpr(mklist<value>(std::string("echo"), std::string("Hello")), "http://localhost:8091/test", ch); - assert(val == std::string("Hello")); - return testEvalLoop(count - 1, ch); -} - -const value blob(std::string(3000, 'A')); -const list<value> blobs = mklist(blob, blob, blob, blob, blob); - -const bool testBlobEvalLoop(const int count, CURLHandle& ch) { - if (count == 0) - return true; - const value val = evalExpr(mklist<value>(std::string("echo"), blobs), "http://localhost:8091/test", ch); - assert(val == blobs); - return testBlobEvalLoop(count - 1, ch); -} - -const bool testEvalPerf() { - const int count = 50; - CURLHandle ch; - struct timeval start; - struct timeval end; - { - testEvalLoop(5, ch); - - gettimeofday(&start, NULL); - - testEvalLoop(count, ch); - - gettimeofday(&end, NULL); - std::cout << "JSON-RPC eval echo test " << duration(start, end, count) << " ms" << std::endl; - } - { - testBlobEvalLoop(5, ch); - - gettimeofday(&start, NULL); - - testBlobEvalLoop(count, ch); - - gettimeofday(&end, NULL); - std::cout << "JSON-RPC eval blob test " << duration(start, end, count) << " ms" << std::endl; - } - return true; -} - -const bool testFeed() { - return true; -} - -bool testPost() { - const list<value> i = list<value>() - << (list<value>() << "name" << std::string("Apple")) - << (list<value>() << "price" << std::string("$2.99")); - const list<value> a = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); - CURLHandle ch; - value rc = post(a, "http://localhost:8091/test", ch); - assert(rc == value(true)); - return true; -} - -const bool testPostLoop(const int count, const value& val, CURLHandle& ch) { - if (count == 0) - return true; - const value rc = post(val, "http://localhost:8091/test", ch); - assert(rc == value(true)); - return testPostLoop(count - 1, val, ch); -} - -const bool testPostPerf() { - const int count = 50; - CURLHandle ch; - struct timeval start; - struct timeval end; - { - const list<value> i = list<value>() - << (list<value>() << "name" << std::string("Apple")) - << (list<value>() << "price" << std::string("$2.99")); - const list<value> val = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); - testPostLoop(5, val, ch); - - gettimeofday(&start, NULL); - - testPostLoop(count, val, ch); - - gettimeofday(&end, NULL); - std::cout << "ATOMPub POST small test " << duration(start, end, count) << " ms" << std::endl; - } - { - const list<value> i = list<value>() - << (list<value>() << "name" << std::string("Apple")) - << (list<value>() << "blob1" << blob) - << (list<value>() << "blob2" << blob) - << (list<value>() << "blob3" << blob) - << (list<value>() << "blob4" << blob) - << (list<value>() << "blob5" << blob) - << (list<value>() << "price" << std::string("$2.99")); - const list<value> val = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); - testPostLoop(5, val, ch); - - gettimeofday(&start, NULL); - - testPostLoop(count, val, ch); - - gettimeofday(&end, NULL); - std::cout << "ATOMPub POST blob test " << duration(start, end, count) << " ms" << std::endl; - } - return true; -} - -const bool testPut() { - const list<value> i = list<value>() - << (list<value>() << "name" << std::string("Apple")) - << (list<value>() << "price" << std::string("$2.99")); - const list<value> a = mklist<value>(std::string("item"), std::string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i); - CURLHandle ch; - value rc = put(a, "http://localhost:8091/test/111", ch); - assert(rc == value(true)); - return true; -} - -const bool testDel() { - CURLHandle ch; - value rc = del("http://localhost:8091/test/123456789", ch); - assert(rc == value(true)); - return true; -} - } } @@ -239,13 +101,6 @@ int main() { tuscany::http::testGet(); tuscany::http::testGetPerf(); - tuscany::http::testPost(); - tuscany::http::testPostPerf(); - tuscany::http::testEval(); - tuscany::http::testEvalPerf(); - tuscany::http::testFeed(); - tuscany::http::testPut(); - tuscany::http::testDel(); std::cout << "OK" << std::endl; diff --git a/sca-cpp/trunk/modules/http/curl.hpp b/sca-cpp/trunk/modules/http/curl.hpp index 5ee3a090b0..6c3a3a47dc 100644 --- a/sca-cpp/trunk/modules/http/curl.hpp +++ b/sca-cpp/trunk/modules/http/curl.hpp @@ -209,29 +209,29 @@ const failable<value, std::string> evalExpr(const value& expr, const std::string // Convert expression to a JSON-RPC request json::JSONContext cx; const failable<list<std::string>, std::string> jsreq = jsonRequest(1, car<value>(expr), cdr<value>(expr), cx); - if (!hasValue(jsreq)) + if (!hasContent(jsreq)) return mkfailure<value, std::string>(reason(jsreq)); if (logContent) { std::cout<< "content: " << std::endl; - write(jsreq, std::cout); + write(content(jsreq), std::cout); std::cout<< std::endl; std::cout.flush(); } // POST it to the URL const list<std::string> h = mklist<std::string>("Content-Type: application/json-rpc"); - const failable<list<list<std::string> >, std::string> res = apply<list<std::string> >(mklist<list<std::string> >(h, jsreq), rcons<std::string>, list<std::string>(), url, "POST", ch); - if (!hasValue(res)) + const failable<list<list<std::string> >, std::string> res = apply<list<std::string> >(mklist<list<std::string> >(h, content(jsreq)), rcons<std::string>, list<std::string>(), url, "POST", ch); + if (!hasContent(res)) return mkfailure<value, std::string>(reason(res)); // Return result if (logContent) { std::cout << "content:" << std::endl; - write(cadr<list<std::string> >(res), std::cout); + write(cadr<list<std::string> >(content(res)), std::cout); std::cout << std::endl; } - const list<value> val = elementsToValues(json::readJSON(cadr<list<std::string> >(res), cx)); + const list<value> val = elementsToValues(content(json::readJSON(cadr<list<std::string> >(content(res)), cx))); return cadr<value>(cadr<value>(val)); } @@ -250,9 +250,8 @@ const failable<value, std::string> get(const std::string& url, const CURLHandle& // Get the contents of the resource at the given URL const failable<list<list<std::string> >, std::string> res = get<list<std::string> >(rcons<std::string>, list<std::string>(), url, ch); - if (!hasValue(res)) + if (!hasContent(res)) return mkfailure<value, std::string>(reason(res)); - const list<list<std::string> > ls = res; const std::string ct; if (ct.find("application/atom+xml") != std::string::npos) { @@ -261,7 +260,7 @@ const failable<value, std::string> get(const std::string& url, const CURLHandle& // Return the content as a string value std::ostringstream os; - write(reverse(cadr(ls)), os); + write(reverse(cadr(content(res))), os); return value(os.str()); } @@ -272,19 +271,19 @@ const failable<value, std::string> post(const value& val, const std::string& url // Convert value to an ATOM entry const failable<list<std::string>, std::string> entry = atom::writeATOMEntry(atom::entryValuesToElements(val)); - if (!hasValue(entry)) + if (!hasContent(entry)) return mkfailure<value, std::string>(reason(entry)); if (logContent) { std::cout << "content:" << std::endl; - write(list<std::string>(entry), std::cout); + write(list<std::string>(content(entry)), std::cout); std::cout << std::endl; } // POST it to the URL const list<std::string> h = mklist<std::string>("Content-Type: application/atom+xml"); - const list<list<std::string> > req = mklist<list<std::string> >(h, entry); + const list<list<std::string> > req = mklist<list<std::string> >(h, content(entry)); const failable<list<list<std::string> >, std::string> res = apply<list<std::string> >(req, rcons<std::string>, list<std::string>(), url, "POST", ch); - if (!hasValue(res)) + if (!hasContent(res)) return mkfailure<value, std::string>(reason(res)); return value(true); } @@ -296,19 +295,19 @@ const failable<value, std::string> put(const value& val, const std::string& url, // Convert value to an ATOM entry const failable<list<std::string>, std::string> entry = atom::writeATOMEntry(atom::entryValuesToElements(val)); - if (!hasValue(entry)) + if (!hasContent(entry)) return mkfailure<value, std::string>(reason(entry)); if (logContent) { std::cout << "content:" << std::endl; - write(list<std::string>(entry), std::cout); + write(list<std::string>(content(entry)), std::cout); std::cout << std::endl; } // PUT it to the URL const list<std::string> h = mklist<std::string>("Content-Type: application/atom+xml"); - const list<list<std::string> > req = mklist<list<std::string> >(h, entry); + const list<list<std::string> > req = mklist<list<std::string> >(h, content(entry)); const failable<list<list<std::string> >, std::string> res = apply<list<std::string> >(req, rcons<std::string>, list<std::string>(), url, "PUT", ch); - if (!hasValue(res)) + if (!hasContent(res)) return mkfailure<value, std::string>(reason(res)); return value(true); } @@ -319,7 +318,7 @@ const failable<value, std::string> put(const value& val, const std::string& url, const failable<value, std::string> del(const std::string& url, const CURLHandle& ch) { const list<list<std::string> > req = mklist(list<std::string>(), list<std::string>()); const failable<list<list<std::string> >, std::string> res = apply<list<std::string> >(req, rcons<std::string>, list<std::string>(), url, "DELETE", ch); - if (!hasValue(res)) + if (!hasContent(res)) return mkfailure<value, std::string>(reason(res)); return value(true); } @@ -333,9 +332,9 @@ struct proxy { const value operator()(const list<value>& args) const { failable<value, std::string> val = evalExpr(args, url, ch); - if (!hasValue(val)) + if (!hasContent(val)) return value(); - return val; + return content(val); } const std::string url; diff --git a/sca-cpp/trunk/modules/http/htdocs/entry.xml b/sca-cpp/trunk/modules/http/htdocs/entry.xml deleted file mode 100644 index 86b8a10547..0000000000 --- a/sca-cpp/trunk/modules/http/htdocs/entry.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>111</id><content type="application/xml"><item><javaClass>services.Item</javaClass><name>Apple</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>2.99</price></item></content><link href="111"/></entry> diff --git a/sca-cpp/trunk/modules/http/htdocs/feed.xml b/sca-cpp/trunk/modules/http/htdocs/feed.xml deleted file mode 100644 index 5e37de6580..0000000000 --- a/sca-cpp/trunk/modules/http/htdocs/feed.xml +++ /dev/null @@ -1,2 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Sample Feed</title><id>123456789</id><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>111</id><content type="application/xml"><item><javaClass>services.Item</javaClass><name>Apple</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>2.99</price></item></content><link href="111"/></entry><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>222</id><content type="application/xml"><item><javaClass>services.Item</javaClass><name>Orange</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>3.55</price></item></content><link href="222"/></entry><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>333</id><content type="application/xml"><item><javaClass>services.Item</javaClass><name>Pear</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>1.55</price></item></content><link href="333"/></entry></feed> diff --git a/sca-cpp/trunk/modules/http/htdocs/json-request.txt b/sca-cpp/trunk/modules/http/htdocs/json-request.txt deleted file mode 100644 index b4bd07fc46..0000000000 --- a/sca-cpp/trunk/modules/http/htdocs/json-request.txt +++ /dev/null @@ -1 +0,0 @@ -{"id":1,"method":"echo","params":["Hello"]} diff --git a/sca-cpp/trunk/modules/http/htdocs/json-result.txt b/sca-cpp/trunk/modules/http/htdocs/json-result.txt deleted file mode 100644 index 121bf74902..0000000000 --- a/sca-cpp/trunk/modules/http/htdocs/json-result.txt +++ /dev/null @@ -1 +0,0 @@ -{"id":1,"result":"Hello"}
\ No newline at end of file diff --git a/sca-cpp/trunk/modules/http/http-test b/sca-cpp/trunk/modules/http/http-test index d70db8d469..1ab0da64b9 100755 --- a/sca-cpp/trunk/modules/http/http-test +++ b/sca-cpp/trunk/modules/http/http-test @@ -18,17 +18,7 @@ # under the License. # Setup -./httpd-conf tmp 8091 htdocs -cat >>tmp/conf/httpd.conf <<EOF - -<Location /test> -SetHandler mod_tuscany_eval -SCAContribution `pwd`/ -SCAComposite httpd-test.composite -SCAComponent httpd-test -</Location> -EOF - +./httpd-conf tmp 8090 htdocs apachectl -k start -d `pwd`/tmp sleep 1 diff --git a/sca-cpp/trunk/modules/http/httpd-client.scm b/sca-cpp/trunk/modules/http/httpd-client.scm deleted file mode 100644 index 12275693f4..0000000000 --- a/sca-cpp/trunk/modules/http/httpd-client.scm +++ /dev/null @@ -1,25 +0,0 @@ -; JSON-RPC test case - -(define (echo x ref) (ref "echo" x)) - -; ATOMPub test case - -(define (getall ref) - (ref "getall") -) - -(define (get id ref) - (ref "get" id) -) - -(define (post entry ref) - (ref "post" entry) -) - -(define (put id entry ref) - (ref "put" id entry) -) - -(define (delete id ref) - (ref "delete" id) -) diff --git a/sca-cpp/trunk/modules/http/httpd-conf b/sca-cpp/trunk/modules/http/httpd-conf index 10a5b47ac2..b00ee06ed3 100755 --- a/sca-cpp/trunk/modules/http/httpd-conf +++ b/sca-cpp/trunk/modules/http/httpd-conf @@ -31,7 +31,5 @@ ServerName 127.0.0.1 Listen $port DocumentRoot $htdocs TypesConfig $here/conf/mime.types -LoadModule mod_tuscany_eval $here/.libs/libmod_tuscany_eval.so -LoadModule mod_tuscany_wiring $here/.libs/libmod_tuscany_wiring.so EOF diff --git a/sca-cpp/trunk/modules/http/httpd-test b/sca-cpp/trunk/modules/http/httpd-test index 1d9b3cb34d..57c35c5cc9 100755 --- a/sca-cpp/trunk/modules/http/httpd-test +++ b/sca-cpp/trunk/modules/http/httpd-test @@ -21,16 +21,6 @@ echo "Testing..." # Setup ./httpd-conf tmp 8090 htdocs -cat >>tmp/conf/httpd.conf <<EOF - -<Location /test> -SetHandler mod_tuscany_eval -SCAContribution `pwd`/ -SCAComposite httpd-test.composite -SCAComponent httpd-test -</Location> -EOF - apachectl -k start -d `pwd`/tmp sleep 1 @@ -39,37 +29,6 @@ curl http://localhost:8090/index.html 2>/dev/null >tmp/index.html diff tmp/index.html htdocs/index.html rc=$? -# Test ATOMPub -if [ "$rc" = "0" ]; then - curl http://localhost:8090/test/ >tmp/feed.xml 2>/dev/null - diff tmp/feed.xml htdocs/feed.xml - rc=$? -fi -if [ "$rc" = "0" ]; then - curl http://localhost:8090/test/111 >tmp/entry.xml 2>/dev/null - diff tmp/entry.xml htdocs/entry.xml - rc=$? -fi -if [ "$rc" = "0" ]; then - curl http://localhost:8090/test/ -X POST -H "Content-type: application/atom+xml" --data @htdocs/entry.xml 2>/dev/null - rc=$? -fi -if [ "$rc" = "0" ]; then - curl http://localhost:8090/test/111 -X PUT -H "Content-type: application/atom+xml" --data @htdocs/entry.xml 2>/dev/null - rc=$? -fi -if [ "$rc" = "0" ]; then - curl http://localhost:8090/test/111 -X DELETE 2>/dev/null - rc=$? -fi - -# Test JSON-RPC -if [ "$rc" = "0" ]; then - curl http://localhost:8090/test/ -X POST -H "Content-type: application/json-rpc" --data @htdocs/json-request.txt >tmp/json-result.txt 2>/dev/null - diff tmp/json-result.txt htdocs/json-result.txt - rc=$? -fi - # Cleanup apachectl -k stop -d `pwd`/tmp sleep 2 diff --git a/sca-cpp/trunk/modules/http/httpd-test.composite b/sca-cpp/trunk/modules/http/httpd-test.composite deleted file mode 100644 index 875d26ae1b..0000000000 --- a/sca-cpp/trunk/modules/http/httpd-test.composite +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * 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. ---> -<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200903" - xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1" - targetNamespace="http://test" - name="httpd-test"> - - <component name="httpd-test"> - <t:implementation.scheme uri="httpd-test.scm"/> - <service name="test"> - <t:binding.http uri="test"/> - </service> - </component> - - <component name="httpd-client"> - <t:implementation.scheme uri="httpd-client.scm"/> - <service name="client"> - <t:binding.http uri="client"/> - </service> - <reference name="ref" target="test"> - <t:binding.http/> - </reference> - </component> - -</composite> diff --git a/sca-cpp/trunk/modules/http/httpd-test.scm b/sca-cpp/trunk/modules/http/httpd-test.scm deleted file mode 100644 index 0566eaf36f..0000000000 --- a/sca-cpp/trunk/modules/http/httpd-test.scm +++ /dev/null @@ -1,29 +0,0 @@ -; JSON-RPC test case - -(define (echo x) x) - -; ATOMPub test case - -(define (getall) - '("Sample Feed" "123456789" - ("Item" "111" ((javaClass "services.Item") (name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99))) - ("Item" "222" ((javaClass "services.Item") (name "Orange") (currencyCode "USD") (currencySymbol "$") (price 3.55))) - ("Item" "333" ((javaClass "services.Item") (name "Pear") (currencyCode "USD") (currencySymbol "$") (price 1.55)))) -) - -(define (get id) - (define entry '((javaClass "services.Item") (name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99))) - (cons "Item" (list id entry)) -) - -(define (post entry) - "123456789" -) - -(define (put id entry) - true -) - -(define (delete id) - true -) diff --git a/sca-cpp/trunk/modules/http/httpd.hpp b/sca-cpp/trunk/modules/http/httpd.hpp index 1271afc03c..a9ced05208 100644 --- a/sca-cpp/trunk/modules/http/httpd.hpp +++ b/sca-cpp/trunk/modules/http/httpd.hpp @@ -23,7 +23,7 @@ #define tuscany_httpd_hpp /** - * HTTPD module utility functions. + * HTTPD module implementation functions. */ #include <string> @@ -62,6 +62,32 @@ bool logRequests = false; bool logContent = false; /** + * Returns a server-scoped module configuration. + */ +template<typename C> void* makeServerConf(apr_pool_t *p, server_rec *s) { + C* c = new (apr_palloc(p, sizeof(C))) C(s); + apr_pool_cleanup_register(p, c, gc_pool_cleanupCallback<C>, apr_pool_cleanup_null) ; + return c; +} + +template<typename C> const C& serverConf(const request_rec* r, const module* mod) { + return *(C*)ap_get_module_config(r->server->module_config, mod); +} + +/** + * Returns a directory-scoped module configuration. + */ +template<typename C> void *makeDirConf(apr_pool_t *p, char *dirspec) { + C* c = new (apr_palloc(p, sizeof(C))) C(dirspec); + apr_pool_cleanup_register(p, c, gc_pool_cleanupCallback<C>, apr_pool_cleanup_null) ; + return c; +} + +template<typename C> C& dirConf(const request_rec* r, const module* mod) { + return *(C*)ap_get_module_config(r->per_dir_config, mod); +} + +/** * Convert a path string to a list of values. */ const list<std::string> pathTokens(const char* p) { @@ -111,6 +137,8 @@ int logHeader(void* r, const char* key, const char* value) { } const bool logRequest(request_rec* r, const std::string& msg) { + if (!logRequests) + return true; std::cout << msg << std::endl; std::cout << "protocol: " << optional(r->protocol) << std::endl; std::cout << "method: " << optional(r->method) << std::endl; @@ -128,6 +156,32 @@ const bool logRequest(request_rec* r, const std::string& msg) { return true; } +const bool logValue(const value& v, const std::string& msg) { + if (!logContent) + return true; + std::cout<< msg << ": " << v << std::endl; + std::cout.flush(); + return true; +} + +const bool logValue(const failable<value, std::string>& v, const std::string& msg) { + if (!logContent) + return true; + std::cout<< msg << ": " << v << std::endl; + std::cout.flush(); + return true; +} + +const bool logStrings(const list<std::string>& ls, const std::string& msg) { + if (!logContent) + return true; + std::cout<< msg << ": " << std::endl; + write(ls, std::cout); + std::cout<< std::endl; + std::cout.flush(); + return true; +} + /** * Returns a list of key value pairs from the args in a query string. */ @@ -144,6 +198,19 @@ const list<list<value> > queryArgs(const request_rec* r) { } /** + * Returns a list of param values other than the id and method args from a list + * of key value pairs. + */ +const list<value> queryParams(const list<list<value> >& a) { + if (isNil(a)) + return list<value>(); + const list<value> p = car(a); + if (car(p) == value("id") || car(p) == value("method")) + return queryParams(cdr(a)); + return cons(cadr(p), queryParams(cdr(a))); +} + +/** * Converts the args received in a POST to a list of key value pairs. */ const list<list<value> > postArgs(const list<value>& a) { @@ -153,6 +220,83 @@ const list<list<value> > postArgs(const list<value>& a) { return cons(l, postArgs(cdr(a))); } +/** + * Setup the HTTP read policy. + */ +const int setupReadPolicy(request_rec* r) { + const int rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK); + if(rc != OK) + return rc; + ap_should_client_block(r); + if(r->read_chunked == true && r->remaining == 0) + r->chunked = true; + //apr_table_setn(r->headers_out, "Connection", "close"); + return OK; +} + +/** + * Read the content of a POST or PUT. + */ +const list<std::string> read(request_rec* r) { + char b[2048]; + const int n = ap_get_client_block(r, b, 2048); + if (n <= 0) + return list<std::string>(); + return cons(std::string(b, n), read(r)); +} + +/** + * Convert a URI value to an absolute URL. + */ +const char* url(const value& v, request_rec* r) { + std::string u = r->uri; + u.append("/"); + u.append(v); + return ap_construct_url(r->pool, u.c_str(), r); +} + +/** + * Convert an ATOM entry to a value. + */ +const value feedEntry(const list<value>& e) { + const list<value> v = elementsToValues(mklist<value>(caddr(e))); + return cons(car(e), mklist<value>(cadr(e), cdr<value>(car(v)))); +} + +/** + * Write an HTTP result. + */ +const failable<int, std::string> writeResult(const failable<list<std::string>, std::string>& ls, const std::string& ct, request_rec* r) { + if (!hasContent(ls)) + return mkfailure<int, std::string>(reason(ls)); + std::ostringstream os; + write(content(ls), os); + if (logContent) { + std::cout<< "content: " << std::endl << os.str() << std::endl; + std::cout.flush(); + } + + const std::string etag(ap_md5(r->pool, (const unsigned char*)std::string(os.str()).c_str())); + const char* match = apr_table_get(r->headers_in, "If-None-Match"); + apr_table_setn(r->headers_out, "ETag", apr_pstrdup(r->pool, etag.c_str())); + if (match != NULL && etag == match) { + r->status = HTTP_NOT_MODIFIED; + return OK; + } + ap_set_content_type(r, ct.c_str()); + ap_rputs(std::string(os.str()).c_str(), r); + return OK; +} + +/** + * Report request execution status. + */ +const int reportStatus(const failable<int, std::string>& rc) { + if (!hasContent(rc)) + return HTTP_INTERNAL_SERVER_ERROR; + return content(rc); +} + } } diff --git a/sca-cpp/trunk/modules/http/mod-eval.cpp b/sca-cpp/trunk/modules/http/mod-eval.cpp deleted file mode 100644 index 6fef2be2cb..0000000000 --- a/sca-cpp/trunk/modules/http/mod-eval.cpp +++ /dev/null @@ -1,532 +0,0 @@ -/* - * 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$ */ - -/** - * HTTPD module used to eval component implementations. - */ - -#include <sys/stat.h> - -#include <string> -#include <iostream> -#include <sstream> -#include <fstream> - -#include "list.hpp" -#include "slist.hpp" -#include "value.hpp" -#include "element.hpp" -#include "monad.hpp" -#include "../atom/atom.hpp" -#include "../json/json.hpp" -#include "../eval/driver.hpp" -#include "../scdl/scdl.hpp" -#include "../cache/cache.hpp" -#include "curl.hpp" -#include "httpd.hpp" - -extern "C" { -extern module AP_MODULE_DECLARE_DATA mod_tuscany_eval; -} - -namespace tuscany { -namespace httpd { -namespace modeval { - -/** - * Server configuration. - */ -class ServerConf { -public: - ServerConf() : home("") { - } - std::string home; -}; - -const ServerConf& serverConf(const request_rec* r) { - return *(ServerConf*)ap_get_module_config(r->server->module_config, &mod_tuscany_eval); -} - -/** - * Port number used for wiring requests. Set it to zero to use the current - * server port number, set it to a port number to direct wiring requests - * to that port, for debugging or tracing for example. - */ -int debugWiringPort = 0; - -/** - * Directory configuration. - */ -class DirConf { -public: - DirConf() : contributionPath(""), compositeName(""), componentName(""), implementationPath("") { - } - std::string contributionPath; - std::string compositeName; - std::string componentName; - std::string implementationPath; - cache::cached<failable<value, std::string> > component; - cache::cached<failable<value, std::string> > implementation; -}; - -DirConf& dirConf(const request_rec* r) { - return *(DirConf*)ap_get_module_config(r->per_dir_config, &mod_tuscany_eval); -} - -/** - * Evaluate an expression against a component implementation. - */ -const failable<value, std::string> evalExpr(const value& expr, const value& impl) { - gc_pool pool; - eval::Env globalEnv = eval::setupEnvironment(pool); - if (logContent) { - std::cout<< "expr: " << expr << std::endl; - std::cout.flush(); - } - const value val = eval::evalScript(expr, impl, globalEnv, pool); - if (logContent) { - std::cout<< "val: " << val << std::endl; - std::cout.flush(); - } - - if (isNil(val)) - return mkfailure<value, std::string>("Could not evaluate expression"); - return val; -} - -/** - * Returns a list of param values other than the id and method args from a list - * of key value pairs. - */ -const list<value> queryParams(const list<list<value> >& a) { - if (isNil(a)) - return list<value>(); - const list<value> p = car(a); - if (car(p) == value("id") || car(p) == value("method")) - return queryParams(cdr(a)); - return cons(cadr(p), queryParams(cdr(a))); -} - -/** - * Write an HTTP result. - */ -const failable<int, std::string> writeResult(const failable<list<std::string>, std::string>& ls, const std::string& ct, request_rec* r) { - if (!hasValue(ls)) - return mkfailure<int, std::string>(reason(ls)); - std::ostringstream os; - write(ls, os); - if (logContent) { - std::cout<< "content: " << std::endl << os.str() << std::endl; - std::cout.flush(); - } - - const std::string etag(ap_md5(r->pool, (const unsigned char*)std::string(os.str()).c_str())); - const char* match = apr_table_get(r->headers_in, "If-None-Match"); - apr_table_setn(r->headers_out, "ETag", apr_pstrdup(r->pool, etag.c_str())); - if (match != NULL && etag == match) { - r->status = HTTP_NOT_MODIFIED; - return OK; - } - ap_set_content_type(r, ct.c_str()); - ap_rputs(std::string(os.str()).c_str(), r); - return OK; -} - -/** - * Handle an HTTP GET. - */ -const failable<int, std::string> get(request_rec* r, const value& impl, const list<value>& px) { - - // Inspect the query string - const list<list<value> > args = queryArgs(r); - const list<value> ia = assoc(value("id"), args); - const list<value> ma = assoc(value("method"), args); - - // Evaluate a JSON-RPC request and return a JSON result - if (!isNil(ia) && !isNil(ma)) { - - // Extract the request id, method and params - const value id = cadr(ia); - const value func = std::string(cadr(ma)).c_str(); - const list<value> params = queryParams(args); - - // Evaluate the request expression - const failable<value, std::string> val = evalExpr(cons<value>(func, eval::quotedParameters(append(params, px))), impl); - if (!hasValue(val)) - return mkfailure<int, std::string>(reason(val)); - - // Return JSON result - json::JSONContext cx; - return writeResult(json::jsonResult(id, val, cx), "application/json-rpc", r); - } - - // Evaluate an ATOM GET request and return an ATOM feed - const list<value> id(path(r->path_info)); - if (isNil(id)) { - const failable<value, std::string> val = evalExpr(cons<value>("getall", eval::quotedParameters(px)), impl); - if (!hasValue(val)) - return mkfailure<int, std::string>(reason(val)); - const value feed = val; - return writeResult(atom::writeATOMFeed(atom::feedValuesToElements(feed)), "application/atom+xml;type=feed", r); - } - - // Evaluate an ATOM GET and return an ATOM entry - const failable<value, std::string> val = evalExpr(cons<value>("get", eval::quotedParameters(cons<value>(car(id), px))), impl); - if (!hasValue(val)) - return mkfailure<int, std::string>(reason(val)); - const value entry = val; - return writeResult(atom::writeATOMEntry(atom::entryValuesToElements(entry)), "application/atom+xml;type=entry", r); - -} - -/** - * Read the content of a POST. - */ -const list<std::string> read(request_rec* r) { - char b[2048]; - const int n = ap_get_client_block(r, b, 2048); - if (n <= 0) - return list<std::string>(); - return cons(std::string(b, n), read(r)); -} - -/** - * Convert a URI value to an absolute URL. - */ -const char* url(const value& v, request_rec* r) { - std::string u = r->uri; - u.append("/"); - u.append(v); - return ap_construct_url(r->pool, u.c_str(), r); -} - -/** - * Convert an ATOM entry to a value. - */ -const value feedEntry(const list<value>& e) { - const list<value> v = elementsToValues(mklist<value>(caddr(e))); - return cons(car(e), mklist<value>(cadr(e), cdr<value>(car(v)))); -} - -/** - * Handle an HTTP POST. - */ -const failable<int, std::string> post(request_rec* r, const value& impl, const list<value>& px) { - const list<std::string> ls = read(r); - if (logContent) { - std::cout<< "content: " << std::endl; - write(ls, std::cout); - std::cout<< std::endl; - std::cout.flush(); - } - - // Evaluate a JSON-RPC request and return a JSON result - const std::string ct = contentType(r); - if (ct.find("application/json-rpc") != std::string::npos || ct.find("text/plain") != std::string::npos) { - json::JSONContext cx; - const list<value> json = elementsToValues(json::readJSON(ls, cx)); - const list<list<value> > args = postArgs(json); - - // Extract the request id, method and params - const value id = cadr(assoc(value("id"), args)); - const value func = std::string(cadr(assoc(value("method"), args))).c_str(); - const list<value> params = (list<value>)cadr(assoc(value("params"), args)); - - // Evaluate the request expression - const failable<value, std::string> val = evalExpr(cons<value>(func, eval::quotedParameters(append(params, px))), impl); - if (!hasValue(val)) - return mkfailure<int, std::string>(reason(val)); - - // Return JSON result - return writeResult(json::jsonResult(id, val, cx), "application/json-rpc", r); - } - - // Evaluate an ATOM POST request and return the created resource location - if (ct.find("application/atom+xml") != std::string::npos) { - - // Evaluate the request expression - const value entry = feedEntry(atom::readEntry(ls)); - const failable<value, std::string> val = evalExpr(cons<value>("post", eval::quotedParameters(cons<value>(entry, px))), impl); - if (!hasValue(val)) - return mkfailure<int, std::string>(reason(val)); - - // Return the created resource location - apr_table_setn(r->headers_out, "Location", apr_pstrdup(r->pool, url(val, r))); - r->status = HTTP_CREATED; - return OK; - } - - return HTTP_NOT_IMPLEMENTED; -} - -/** - * Handle an HTTP PUT. - */ -const failable<int, std::string> put(request_rec* r, const value& impl, const list<value>& px) { - const list<std::string> ls = read(r); - if (logContent) { - std::cout<< "content: " << std::endl; - write(ls, std::cout); - std::cout<< std::endl; - std::cout.flush(); - } - - // Evaluate an ATOM PUT request - const list<value> id(path(r->path_info)); - const value entry = feedEntry(atom::readEntry(ls)); - const failable<value, std::string> val = evalExpr(cons<value>("put", eval::quotedParameters(append(mklist<value>(entry, car(id)), px))), impl); - if (!hasValue(val)) - return mkfailure<int, std::string>(reason(val)); - if (val == value(false)) - return HTTP_NOT_FOUND; - return OK; -} - -/** - * Handle an HTTP DELETE. - */ -const failable<int, std::string> del(request_rec* r, const value& impl, const list<value>& px) { - - // Evaluate an ATOM delete request - const list<value> id(path(r->path_info)); - const failable<value, std::string> val = evalExpr(cons<value>("delete", eval::quotedParameters(cons<value>(car(id), px))), impl); - if (!hasValue(val)) - return mkfailure<int, std::string>(reason(val)); - if (val == value(false)) - return HTTP_NOT_FOUND; - return OK; -} - -/** - * Report request execution status. - */ -const int reportStatus(const failable<int, std::string>& rc) { - if (!hasValue(rc)) - return HTTP_INTERNAL_SERVER_ERROR; - return rc; -} - -/** - * Read the SCDL configuration of a component. - */ -const failable<value, std::string> readComponent(const std::string& path, const std::string& name) { - - // Read composite - std::ifstream is(path); - if (is.fail() || is.bad()) - return mkfailure<value, std::string>("Could not read composite: " + path); - - // Return the component - const list<value> c = scdl::components(readXML(streamList(is))); - const value comp = scdl::named(name, c); - if (isNil(comp)) - return mkfailure<value, std::string>("Could not find component: " + name); - return comp; -} - -const cache::cached<failable<value, std::string> > component(DirConf* conf) { - const std::string path(conf->contributionPath + conf->compositeName); - const lambda<failable<value, std::string>(std::string, std::string)> rc(readComponent); - const lambda<unsigned long(std::string)> ft(cache::latestFileTime); - return cache::cached<failable<value, std::string> >(curry(rc, path, conf->componentName), curry(ft, path)); -} - -/** - * Read a component implementation. - */ -const failable<value, std::string> readImplementation(const std::string path) { - std::ifstream is(path.c_str(), std::ios_base::in); - if (is.fail() || is.bad()) - return mkfailure<value, std::string>("Could not read implementation: " + path); - const value impl = eval::readScript(is); - if (isNil(impl)) - return mkfailure<value, std::string>("Could not read implementation: " + path); - return impl; -} - -const cache::cached<failable<value, std::string> > implementation(const std::string& path) { - const lambda<failable<value, std::string>(std::string)> ri(readImplementation); - const lambda<unsigned long(std::string)> ft(cache::latestFileTime); - return cache::cached<failable<value, std::string> >(curry(ri, path), curry(ft, path)); -} - -/** - * Convert a list of component references to a list of HTTP proxy lambdas. - */ -const value mkproxy(const value& ref, const std::string& base, const http::CURLHandle& ch) { - return eval::primitiveProcedure(http::proxy(base + std::string(scdl::name(ref)), ch)); -} - -const list<value> proxies(const list<value>& refs, const std::string& base, const http::CURLHandle& ch) { - if (isNil(refs)) - return refs; - return cons(mkproxy(car(refs), base, ch), proxies(cdr(refs), base, ch)); -} - -/** - * HTTP request handler. - */ -int handler(request_rec *r) { - if(strcmp(r->handler, "mod_tuscany_eval")) - return DECLINED; - - // Log the request - if(logRequests) - logRequest(r, "mod_tuscany_eval::handler"); - - // Set up the read policy - const int rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK); - if(rc != OK) - return rc; - ap_should_client_block(r); - if(r->read_chunked == true && r->remaining == 0) - r->chunked = true; - //apr_table_setn(r->headers_out, "Connection", "close"); - - // Retrieve the latest component configuration - DirConf& conf = dirConf(r); - conf.component = cache::latest(conf.component); - const failable<value, std::string> comp(conf.component); - if (!hasValue(comp)) - return HTTP_NOT_FOUND; - - // Retrieve the latest implementation - const std::string path = conf.contributionPath + std::string(scdl::uri(scdl::implementation(comp))); - if (path != conf.implementationPath) { - conf.implementationPath = path; - conf.implementation = cache::latest(implementation(path)); - } - else - conf.implementation = cache::latest(conf.implementation); - const failable<value, std::string> impl(conf.implementation); - if (!hasValue(impl)) - return HTTP_NOT_FOUND; - - // Convert component references to configured proxy lambdas - std::ostringstream base; - base << "http://localhost:" << (debugWiringPort == 0? ap_get_server_port(r) : debugWiringPort) << "/references/" << std::string(scdl::name(comp)) << "/"; - http::CURLHandle ch; - const list<value> px(proxies(scdl::references(comp), base.str(), ch)); - - // Handle HTTP method - if (r->header_only) - return OK; - if(r->method_number == M_GET) - return reportStatus(get(r, impl, px)); - if(r->method_number == M_POST) - return reportStatus(post(r, impl, px)); - if(r->method_number == M_PUT) - return reportStatus(put(r, impl, px)); - if(r->method_number == M_DELETE) - return reportStatus(del(r, impl, px)); - return HTTP_NOT_IMPLEMENTED; -} - -/** - * Configuration commands. - */ -const char *confHome(cmd_parms *cmd, void *dummy, const char *arg) { - ServerConf *c = (ServerConf*)ap_get_module_config(cmd->server->module_config, &mod_tuscany_eval); - c->home = arg; - return NULL; -} -const char *confContribution(cmd_parms *cmd, void *c, const char *arg) { - DirConf* conf = (DirConf*)c; - conf->contributionPath = arg; - conf->component = component(conf); - return NULL; -} -const char *confComposite(cmd_parms *cmd, void *c, const char *arg) { - DirConf* conf = (DirConf*)c; - conf->compositeName = arg; - conf->component = component(conf); - return NULL; -} -const char *confComponent(cmd_parms *cmd, void *c, const char *arg) { - DirConf* conf = (DirConf*)c; - conf->componentName = arg; - conf->component = component(conf); - return NULL; -} - -void *makeDirConf(apr_pool_t *p, char *dirspec) { - DirConf* c = new (apr_palloc(p, sizeof(DirConf))) DirConf(); - apr_pool_cleanup_register(p, c, gc_pool_cleanupCallback<DirConf>, apr_pool_cleanup_null) ; - return c; -} -void* makeServerConf(apr_pool_t *p, server_rec *s) { - ServerConf* c = new (apr_palloc(p, sizeof(ServerConf))) ServerConf(); - apr_pool_cleanup_register(p, c, gc_pool_cleanupCallback<ServerConf>, apr_pool_cleanup_null) ; - return c; -} - -/** - * HTTP server module declaration. - */ -const command_rec commands[] = { - AP_INIT_TAKE1("TuscanyHome", (const char*(*)())confHome, NULL, RSRC_CONF, "Tuscany home directory"), - AP_INIT_TAKE1("SCAContribution", (const char*(*)())confContribution, NULL, ACCESS_CONF, "SCA contribution location"), - AP_INIT_TAKE1("SCAComposite", (const char*(*)())confComposite, NULL, ACCESS_CONF, "SCA composite location"), - AP_INIT_TAKE1("SCAComponent", (const char*(*)())confComponent, NULL, ACCESS_CONF, "SCA component name"), - {NULL} -}; - -int postConfig(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { - return OK; -} - -void childInit(apr_pool_t* p, server_rec* svr_rec) { - ServerConf *c = (ServerConf*)ap_get_module_config(svr_rec->module_config, &mod_tuscany_eval); - if(c == NULL) { - std::cerr << "[Tuscany] Due to one or more errors mod_tuscany_eval loading failed. Causing apache to stop loading." << std::endl; - exit(APEXIT_CHILDFATAL); - } -} - -void registerHooks(apr_pool_t *p) { - ap_hook_post_config(postConfig, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_child_init(childInit, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_handler(handler, NULL, NULL, APR_HOOK_MIDDLE); -} - -} -} -} - -extern "C" { - -module AP_MODULE_DECLARE_DATA mod_tuscany_eval = { - STANDARD20_MODULE_STUFF, - // dir config - tuscany::httpd::modeval::makeDirConf, - // dir merger, default is to override - NULL, - // server config - tuscany::httpd::modeval::makeServerConf, - // merge server config - NULL, - // command table - tuscany::httpd::modeval::commands, - // register hooks - tuscany::httpd::modeval::registerHooks -}; - -} diff --git a/sca-cpp/trunk/modules/http/mod-wiring.cpp b/sca-cpp/trunk/modules/http/mod-wiring.cpp deleted file mode 100644 index 965d5a87fb..0000000000 --- a/sca-cpp/trunk/modules/http/mod-wiring.cpp +++ /dev/null @@ -1,276 +0,0 @@ -/* - * 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$ */ - -/** - * HTTPD module used to wire components. - */ - -#include <sys/stat.h> - -#include <string> -#include <iostream> -#include <sstream> -#include <fstream> - -#include "list.hpp" -#include "slist.hpp" -#include "value.hpp" -#include "monad.hpp" -#include "../scdl/scdl.hpp" -#include "../cache/cache.hpp" -#include "httpd.hpp" - -extern "C" { -extern module AP_MODULE_DECLARE_DATA mod_tuscany_wiring; -} - -namespace tuscany { -namespace httpd { -namespace modwiring { - -/** - * Server configuration. - */ -class ServerConf { -public: - std::string home; - ServerConf() : home("") { - } -}; - -const ServerConf& serverConf(const request_rec* r) { - return *(ServerConf*)ap_get_module_config(r->server->module_config, &mod_tuscany_wiring); -} - -/** - * Set to true to wire using mod_proxy, false to wire using HTTP client redirects. - */ -const bool useModProxy = true; - -/** - * Directory configuration. - */ -class DirConf { -public: - DirConf() : contributionPath(""), compositeName("") { - } - std::string contributionPath; - std::string compositeName; - cache::cached<failable<list<value>, std::string> > components; -}; - -DirConf& dirConf(const request_rec* r) { - return *(DirConf*)ap_get_module_config(r->per_dir_config, &mod_tuscany_wiring); -} - -/** - * Read the SCDL configuration of the deployed components. - */ -const failable<list<value>, std::string> readComponents(const std::string& path) { - std::ifstream is(path); - if (is.fail() || is.bad()) - return mkfailure<list<value>, std::string>("Could not read composite: " + path); - return scdl::components(readXML(streamList(is))); -} - -const cache::cached<failable<list<value>, std::string> > components(DirConf* conf) { - const std::string path(conf->contributionPath + conf->compositeName); - const lambda<failable<list<value>, std::string>(std::string)> rc(readComponents); - const lambda<unsigned long(std::string)> ft(cache::latestFileTime); - return cache::cached<failable<list<value>, std::string> >(curry(rc, path), curry(ft, path)); -} - -/** - * Returns true if a URI is absolute. - */ -const bool isAbsolute(const std::string& uri) { - return uri.find("://") != std::string::npos; -} - -/** - * Translate an HTTP request URI. Wire a URI in the form /references/component-name/reference-name - * to the target of the reference. - */ -int translate(request_rec *r) { - if (strncmp(r->uri, "/references/", 12) != 0) - return DECLINED; - const list<value> rpath(path(r->uri)); - - // Log the request - if(logRequests) - logRequest(r, "mod_tuscany_wiring::translate"); - - // Find the requested component, reference and its target configuration - DirConf& conf = dirConf(r); - conf.components = cache::latest(conf.components); - const failable<list<value>, std::string> comps(conf.components); - if (!hasValue(comps)) - return HTTP_INTERNAL_SERVER_ERROR; - const value comp(scdl::named(cadr(rpath), list<value>(comps))); - if (isNil(comp)) - return HTTP_NOT_FOUND; - const value ref(scdl::named(caddr(rpath), scdl::references(comp))); - if (isNil(ref)) - return HTTP_NOT_FOUND; - const std::string target(scdl::target(ref)); - - // Absolute target URI - if (isAbsolute(target)) { - - // Wire using mod_proxy - if (useModProxy) { - r->filename = apr_pstrdup(r->pool, std::string("proxy:" + target).c_str()); - r->proxyreq = PROXYREQ_REVERSE; - r->handler = "proxy-server"; - return OK; - } - - // Wire using an HTTP client redirect - r->status = HTTP_MOVED_TEMPORARILY; - apr_table_setn(r->headers_out, "Location", apr_pstrdup(r->pool, target.c_str())); - r->handler = "mod_tuscany_wiring"; - return OK; - - } - - // Local internal redirect - r->filename = apr_pstrdup(r->pool, std::string("/redirect:/" + target).c_str()); - r->handler = "mod_tuscany_wiring"; - return OK; -} - -/** - * Construct a redirect URI. - */ -const std::string redirect(const std::string& file, const std::string& pi) { - return file + pi; -} - -const std::string redirect(const std::string& file, const std::string& pi, const std::string& args) { - return file + pi + "?" + args; -} - -/** - * HTTP request internal redirect handler. - */ -int handler(request_rec *r) { - if(strcmp(r->handler, "mod_tuscany_wiring")) - return DECLINED; - - // Log the request - if(logRequests) - logRequest(r, "mod_tuscany_wiring::handler"); - - // Do an internal redirect - if (r->filename == NULL || strncmp(r->filename, "/redirect:", 10) != 0) - return DECLINED; - if (r->args == NULL) { - ap_internal_redirect(apr_pstrdup(r->pool, redirect(r->filename + 10, r->path_info).c_str()), r); - return OK; - } - ap_internal_redirect(apr_pstrdup(r->pool, redirect(r->filename + 10, r->path_info, r->args).c_str()), r); - return OK; -} - -/** - * Configuration commands. - */ -const char *confHome(cmd_parms *cmd, void *dummy, const char *arg) { - ServerConf *c = (ServerConf*)ap_get_module_config(cmd->server->module_config, &mod_tuscany_wiring); - c->home = arg; - return NULL; -} -const char *confContribution(cmd_parms *cmd, void *c, const char *arg) { - DirConf* conf = (DirConf*)c; - conf->contributionPath = arg; - conf->components = components(conf); - return NULL; -} -const char *confComposite(cmd_parms *cmd, void *c, const char *arg) { - DirConf* conf = (DirConf*)c; - conf->compositeName = arg; - conf->components = components(conf); - return NULL; -} - -void *makeDirConf(apr_pool_t *p, char *dirspec) { - DirConf* c = new (apr_palloc(p, sizeof(DirConf))) DirConf(); - apr_pool_cleanup_register(p, c, gc_pool_cleanupCallback<DirConf>, apr_pool_cleanup_null) ; - return c; -} -void* makeServerConf(apr_pool_t *p, server_rec *s) { - ServerConf* c = new (apr_palloc(p, sizeof(ServerConf))) ServerConf(); - apr_pool_cleanup_register(p, c, gc_pool_cleanupCallback<ServerConf>, apr_pool_cleanup_null) ; - return c; -} - -/** - * HTTP server module declaration. - */ -const command_rec commands[] = { - AP_INIT_TAKE1("TuscanyHome", (const char*(*)())confHome, NULL, RSRC_CONF, "Tuscany home directory"), - AP_INIT_TAKE1("SCAContribution", (const char*(*)())confContribution, NULL, ACCESS_CONF, "SCA contribution location"), - AP_INIT_TAKE1("SCAComposite", (const char*(*)())confComposite, NULL, ACCESS_CONF, "SCA composite location"), - {NULL} -}; - -int postConfig(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) { - return OK; -} - -void childInit(apr_pool_t* p, server_rec* svr_rec) { - ServerConf *conf = (ServerConf*)ap_get_module_config(svr_rec->module_config, &mod_tuscany_wiring); - if(conf == NULL) { - std::cerr << "[Tuscany] Due to one or more errors mod_tuscany_wiring loading failed. Causing apache to stop loading." << std::endl; - exit(APEXIT_CHILDFATAL); - } -} - -void registerHooks(apr_pool_t *p) { - ap_hook_post_config(postConfig, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_child_init(childInit, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_handler(handler, NULL, NULL, APR_HOOK_MIDDLE); - ap_hook_translate_name(translate, NULL, NULL, APR_HOOK_FIRST); -} - -} -} -} - -extern "C" { - -module AP_MODULE_DECLARE_DATA mod_tuscany_wiring = { - STANDARD20_MODULE_STUFF, - // dir config - tuscany::httpd::modwiring::makeDirConf, - // dir merger, default is to override - NULL, - // server config - tuscany::httpd::modwiring::makeServerConf, - // merge server config - NULL, - // command table - tuscany::httpd::modwiring::commands, - // register hooks - tuscany::httpd::modwiring::registerHooks -}; - -} diff --git a/sca-cpp/trunk/modules/http/wiring-test b/sca-cpp/trunk/modules/http/wiring-test deleted file mode 100755 index 0c3f36b513..0000000000 --- a/sca-cpp/trunk/modules/http/wiring-test +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/sh - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -echo "Testing..." - -# Setup -./httpd-conf tmp 8092 htdocs -cat >>tmp/conf/httpd.conf <<EOF - -<Location /test> -SetHandler mod_tuscany_eval -SCAContribution `pwd`/ -SCAComposite httpd-test.composite -SCAComponent httpd-test -</Location> - -<Location /client> -SetHandler mod_tuscany_eval -SCAContribution /home/delfinoj/SCAZone/Source/tuscany-cpp/sca/modules/http/ -SCAComposite httpd-test.composite -SCAComponent httpd-client -</Location> - -<Location /references> -SetHandler mod_tuscany_wiring -SCAContribution `pwd`/ -SCAComposite httpd-test.composite -</Location> -EOF - -apachectl -k start -d `pwd`/tmp -sleep 1 - -# Test HTTP GET -curl http://localhost:8092/index.html 2>/dev/null >tmp/index.html -diff tmp/index.html htdocs/index.html -rc=$? - -# Test ATOMPub -if [ "$rc" = "0" ]; then - curl http://localhost:8092/client/ >tmp/feed.xml 2>/dev/null - diff tmp/feed.xml htdocs/feed.xml - rc=$? -fi -if [ "$rc" = "0" ]; then - curl http://localhost:8092/client/111 >tmp/entry.xml 2>/dev/null - diff tmp/entry.xml htdocs/entry.xml - rc=$? -fi -if [ "$rc" = "0" ]; then - curl http://localhost:8092/client/ -X POST -H "Content-type: application/atom+xml" --data @htdocs/entry.xml 2>/dev/null - rc=$? -fi -if [ "$rc" = "0" ]; then - curl http://localhost:8092/client/111 -X PUT -H "Content-type: application/atom+xml" --data @htdocs/entry.xml 2>/dev/null - rc=$? -fi -if [ "$rc" = "0" ]; then - curl http://localhost:8092/client/111 -X DELETE 2>/dev/null - rc=$? -fi - -# Test JSON-RPC -if [ "$rc" = "0" ]; then - curl http://localhost:8092/client/ -X POST -H "Content-type: application/json-rpc" --data @htdocs/json-request.txt >tmp/json-result.txt 2>/dev/null - diff tmp/json-result.txt htdocs/json-result.txt - rc=$? -fi - -# Cleanup -apachectl -k stop -d `pwd`/tmp -sleep 2 -if [ "$rc" = "0" ]; then - echo "OK" -fi -return $rc |