diff options
22 files changed, 500 insertions, 221 deletions
diff --git a/sca-cpp/trunk/components/webservice/axiom-test.cpp b/sca-cpp/trunk/components/webservice/axiom-test.cpp index a3ab8e7e8f..75ce2452fd 100644 --- a/sca-cpp/trunk/components/webservice/axiom-test.cpp +++ b/sca-cpp/trunk/components/webservice/axiom-test.cpp @@ -45,6 +45,10 @@ const string customerElement = "<account><id>4567</id><balance>3000</balance></account>" "</customer>"; +const string echo("<ns1:echoString xmlns:ns1=\"http://ws.apache.org/axis2/services/echo\">\n" + " <text>Hello World!</text>\n" + "</ns1:echoString>"); + bool testAxiom() { const Axis2Context ax; { @@ -63,7 +67,7 @@ bool testAxiom() { assert(hasContent(n)); const failable<const string> x = axiomNodeToString(content(n), ax); assert(hasContent(x)); - assert(content(x) == "<ns1:echoString xmlns:ns1=\"http://ws.apache.org/axis2/services/echo\"><text>Hello World!</text></ns1:echoString>"); + assert(content(x) == echo); const failable<const list<value> > l = axiomNodeToValues(content(n), ax); assert(hasContent(l)); assert(l == arg); diff --git a/sca-cpp/trunk/kernel/value.hpp b/sca-cpp/trunk/kernel/value.hpp index 211873ef0c..07be7f5c82 100644 --- a/sca-cpp/trunk/kernel/value.hpp +++ b/sca-cpp/trunk/kernel/value.hpp @@ -240,7 +240,7 @@ public: return true; switch(type) { case value::Undefined: - return true; + return v.type == value::Undefined; case value::List: return v.type == value::List && lst()() == v.lst()(); case value::Lambda: diff --git a/sca-cpp/trunk/kernel/xml.hpp b/sca-cpp/trunk/kernel/xml.hpp index 3459592c97..97c9effcc2 100644 --- a/sca-cpp/trunk/kernel/xml.hpp +++ b/sca-cpp/trunk/kernel/xml.hpp @@ -347,6 +347,7 @@ template<typename R> const failable<R> writeXML(const lambda<R(const string&, co xmlTextWriterPtr xml = xmlNewTextWriter(out); if (xml == NULL) return mkfailure<R>("xmlNewTextWriter failed"); + xmlTextWriterSetIndent(xml, 1); const failable<bool> w = write(l, xml, xmlTag); xmlFreeTextWriter(xml); diff --git a/sca-cpp/trunk/modules/atom/atom-test.cpp b/sca-cpp/trunk/modules/atom/atom-test.cpp index 762331d528..5503c0f9b4 100644 --- a/sca-cpp/trunk/modules/atom/atom-test.cpp +++ b/sca-cpp/trunk/modules/atom/atom-test.cpp @@ -36,52 +36,56 @@ ostream* writer(const string& s, ostream* os) { return os; } -string itemEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\">" - "<title type=\"text\">item</title>" - "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>" - "<content type=\"application/xml\">" - "<item>" - "<name>Apple</name><price>$2.99</price>" - "</item>" - "</content>" - "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>" +const string itemEntry( + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<entry xmlns=\"http://www.w3.org/2005/Atom\">\n" + " <title type=\"text\">item</title>\n" + " <id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>\n" + " <content type=\"application/xml\">\n" + " <item>\n" + " <name>Apple</name>\n" + " <price>$2.99</price>\n" + " </item>\n" + " </content>\n" + " <link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>\n" "</entry>\n"); -string itemTextEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\">" - "<title type=\"text\">item</title>" - "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>" - "<content type=\"text\">Apple</content>" - "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>" +const string itemTextEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<entry xmlns=\"http://www.w3.org/2005/Atom\">\n" + " <title type=\"text\">item</title>\n" + " <id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>\n" + " <content type=\"text\">Apple</content>\n" + " <link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>\n" "</entry>\n"); -string itemNoContentEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\">" - "<title type=\"text\">item</title>" - "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>" - "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>" +const string itemNoContentEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<entry xmlns=\"http://www.w3.org/2005/Atom\">\n" + " <title type=\"text\">item</title>\n" + " <id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>\n" + " <link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>\n" "</entry>\n"); -string incompleteEntry("<entry xmlns=\"http://www.w3.org/2005/Atom\">" - "<title>item</title><content type=\"text/xml\">" - "<Item xmlns=\"http://services/\">" - "<name xmlns=\"\">Orange</name>" - "<price xmlns=\"\">3.55</price>" - "</Item>" - "</content>" - "</entry>"); - -string completedEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<entry xmlns=\"http://www.w3.org/2005/Atom\">" - "<title type=\"text\">item</title>" - "<id></id>" - "<content type=\"application/xml\">" - "<Item xmlns=\"http://services/\">" - "<name xmlns=\"\">Orange</name>" - "<price xmlns=\"\">3.55</price>" - "</Item>" - "</content><link href=\"\"/>" +const string incompleteEntry("<entry xmlns=\"http://www.w3.org/2005/Atom\">\n" + " <title>item</title>\n" + " <content type=\"text/xml\">\n" + " <Item xmlns=\"http://services/\">\n" + " <name xmlns=\"\">Orange</name>\n" + " <price xmlns=\"\">3.55</price>\n" + " </Item>\n" + " </content>\n" + "</entry>\n"); + +const string completedEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<entry xmlns=\"http://www.w3.org/2005/Atom\">\n" + " <title type=\"text\">item</title>\n" + " <id></id>\n" + " <content type=\"application/xml\">\n" + " <Item xmlns=\"http://services/\">\n" + " <name xmlns=\"\">Orange</name>\n" + " <price xmlns=\"\">3.55</price>\n" + " </Item>\n" + " </content>\n" + " <link href=\"\"/>\n" "</entry>\n"); bool testEntry() { @@ -133,36 +137,38 @@ bool testEntry() { return true; } -string emptyFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<feed xmlns=\"http://www.w3.org/2005/Atom\">" - "<title type=\"text\">Feed</title>" - "<id>1234</id>" +const string emptyFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n" + " <title type=\"text\">Feed</title>\n" + " <id>1234</id>\n" "</feed>\n"); -string itemFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<feed xmlns=\"http://www.w3.org/2005/Atom\">" - "<title type=\"text\">Feed</title>" - "<id>1234</id>" - "<entry xmlns=\"http://www.w3.org/2005/Atom\">" - "<title type=\"text\">item</title>" - "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>" - "<content type=\"application/xml\">" - "<item>" - "<name>Apple</name><price>$2.99</price>" - "</item>" - "</content>" - "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>" - "</entry>" - "<entry xmlns=\"http://www.w3.org/2005/Atom\">" - "<title type=\"text\">item</title>" - "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c</id>" - "<content type=\"application/xml\">" - "<item>" - "<name>Orange</name><price>$3.55</price>" - "</item>" - "</content>" - "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c\"/>" - "</entry>" +const string itemFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n" + " <title type=\"text\">Feed</title>\n" + " <id>1234</id>\n" + " <entry xmlns=\"http://www.w3.org/2005/Atom\">\n" + " <title type=\"text\">item</title>\n" + " <id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>\n" + " <content type=\"application/xml\">\n" + " <item>\n" + " <name>Apple</name>\n" + " <price>$2.99</price>\n" + " </item>\n" + " </content>\n" + " <link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>\n" + " </entry>\n" + " <entry xmlns=\"http://www.w3.org/2005/Atom\">\n" + " <title type=\"text\">item</title>\n" + " <id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c</id>\n" + " <content type=\"application/xml\">\n" + " <item>\n" + " <name>Orange</name>\n" + " <price>$3.55</price>\n" + " </item>\n" + " </content>\n" + " <link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c\"/>\n" + " </entry>\n" "</feed>\n"); bool testFeed() { diff --git a/sca-cpp/trunk/modules/http/http.hpp b/sca-cpp/trunk/modules/http/http.hpp index 26a2e0cf0c..e2327be40a 100644 --- a/sca-cpp/trunk/modules/http/http.hpp +++ b/sca-cpp/trunk/modules/http/http.hpp @@ -620,6 +620,39 @@ const failable<size_t> recv(char* c, const size_t l, const CURLSession& cs) { return recv(c, l, cs); } + +/** + * Filter path segment in a list of arguments. + */ +const bool filterPath(const value& arg) { + return isString(arg); +} + +/** + * Filter query string arguments in a list of arguments. + */ +const bool filterQuery(const value& arg) { + return isList(arg); +} + +/** + * Converts a list of key value pairs to a query string. + */ +ostringstream& queryString(const list<list<value> > args, ostringstream& os) { + if (isNil(args)) + return os; + debug(car(args), "http::queryString::arg"); + os << car(car(args)) << "=" << c_str(cadr(car(args))); + if (!isNil(cdr(args))) + os << "&"; + return queryString(cdr(args), os); +} + +const string queryString(const list<list<value> > args) { + ostringstream os; + return str(queryString(args, os)); +} + /** * HTTP client proxy function. */ @@ -630,7 +663,13 @@ struct proxy { const value operator()(const list<value>& args) const { const value fun = car(args); if (fun == "get") { - const failable<value> val = get(uri + path(cadr(args)), cs); + const list<value> lp = filter<value>(filterPath, cadr(args)); + debug(lp, "http::queryString::arg"); + const list<value> lq = filter<value>(filterQuery, cadr(args)); + debug(lq, "http::get::query"); + const value p = path(lp); + const value q = queryString(lq); + const failable<value> val = get(uri + p + (q != ""? string("?") + q : string("")), cs); return content(val); } if (fun == "post") { diff --git a/sca-cpp/trunk/modules/http/httpd.hpp b/sca-cpp/trunk/modules/http/httpd.hpp index b6756c51e3..768537aa03 100644 --- a/sca-cpp/trunk/modules/http/httpd.hpp +++ b/sca-cpp/trunk/modules/http/httpd.hpp @@ -283,24 +283,6 @@ const list<list<value> > queryArgs(const request_rec* r) { } /** - * Converts a list of key value pairs to a query string. - */ -ostringstream& queryString(const list<list<value> > args, ostringstream& os) { - if (isNil(args)) - return os; - debug(car(args), "httpd::queryString::arg"); - os << car(car(args)) << "=" << c_str(cadr(car(args))); - if (!isNil(cdr(args))) - os << "&"; - return queryString(cdr(args), os); -} - -const string queryString(const list<list<value> > args) { - ostringstream os; - return str(queryString(args, os)); -} - -/** * Converts the args received in a POST to a list of key value pairs. */ const list<list<value> > postArgs(const list<value>& a) { diff --git a/sca-cpp/trunk/modules/http/openauth.hpp b/sca-cpp/trunk/modules/http/openauth.hpp index ff69a9732f..9023848305 100644 --- a/sca-cpp/trunk/modules/http/openauth.hpp +++ b/sca-cpp/trunk/modules/http/openauth.hpp @@ -87,7 +87,7 @@ const string cookie(const string& sid) { */ const failable<int> login(const string& page, request_rec* r) { const list<list<value> > largs = mklist<list<value> >(mklist<value>("openauth_referrer", httpd::escape(httpd::url(r->uri, r)))); - const string loc = httpd::url(page, r) + string("?") + httpd::queryString(largs); + const string loc = httpd::url(page, r) + string("?") + http::queryString(largs); debug(loc, "openauth::login::uri"); return httpd::externalRedirect(loc, r); } diff --git a/sca-cpp/trunk/modules/js/htdocs/xmlutil.js b/sca-cpp/trunk/modules/js/htdocs/xmlutil.js index b3fb34435a..3965596599 100644 --- a/sca-cpp/trunk/modules/js/htdocs/xmlutil.js +++ b/sca-cpp/trunk/modules/js/htdocs/xmlutil.js @@ -61,7 +61,10 @@ function childElements(e) { * Return the child text nodes of an element. */ function childText(e) { - return filter(function(n) { return n.nodeType == 3; }, nodeList(e.childNodes)); + function trim(s) { + return s.replace(/^\s*/, '').replace(/\s*$/, ''); + } + return filter(function(n) { return n.nodeType == 3 && trim(n.nodeValue) != ''; }, nodeList(e.childNodes)); } /** diff --git a/sca-cpp/trunk/modules/json/json-test.cpp b/sca-cpp/trunk/modules/json/json-test.cpp index 6666b3f479..eed41c4e59 100644 --- a/sca-cpp/trunk/modules/json/json-test.cpp +++ b/sca-cpp/trunk/modules/json/json-test.cpp @@ -36,6 +36,35 @@ ostream* jsonWriter(const string& s, ostream* os) { return os; } +const string jscustomer("{\n" + " \"customer\":{\n" + " \"@name\":\"jdoe\",\n" + " \"address\":{\n" + " \"@city\":\"san francisco\",\n" + " \"@state\":\"ca\"\n" + " },\n" + " \"account\":{\n" + " \"id\":\"1234\",\n" + " \"@balance\":1000\n" + " }\n" + " }\n" + "}"); + +const string jsphones("{\n" + " \"phones\":[\"408-1234\",\n" + " \"650-1234\"\n" + " ],\n" + " \"lastName\":\"test\\u0009tab\",\n" + " \"@firstName\":\"test1\"\n" + "}"); + +const string jsecho("{\n" + " \"ns1:echoString\":{\n" + " \"@xmlns:ns1\":\"http://ws.apache.org/axis2/services/echo\",\n" + " \"text\":\"Hello World!\"\n" + " }\n" + "}"); + bool testJSON() { const js::JSContext cx; @@ -47,7 +76,7 @@ bool testJSON() { ostringstream os; writeJSON<ostream*>(jsonWriter, &os, c, cx); - assert(str(os) == "{\"customer\":{\"@name\":\"jdoe\",\"address\":{\"@city\":\"san francisco\",\"@state\":\"ca\"},\"account\":{\"id\":\"1234\",\"@balance\":1000}}}"); + assert(str(os) == jscustomer); } { const list<value> phones = mklist<value> (string("408-1234"), string("650-1234")); @@ -55,7 +84,7 @@ bool testJSON() { ostringstream os; writeJSON<ostream*>(jsonWriter, &os, l, cx); - assert(str(os) == "{\"phones\":[\"408-1234\",\"650-1234\"],\"lastName\":\"test\\u0009tab\",\"@firstName\":\"test1\"}"); + assert(str(os) == jsphones); istringstream is(str(os)); const list<string> il = streamList(is); @@ -70,7 +99,7 @@ bool testJSON() { const list<value> l = mklist<value>(list<value>() + "ns1:echoString" + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + (list<value>() + "text" + string("Hello World!"))); ostringstream wos; write(content(writeJSON(valuesToElements(l), cx)), wos); - assert(str(wos) == "{\"ns1:echoString\":{\"@xmlns:ns1\":\"http://ws.apache.org/axis2/services/echo\",\"text\":\"Hello World!\"}}"); + assert(str(wos) == jsecho); istringstream is(str(wos)); const list<string> il = streamList(is); @@ -80,6 +109,86 @@ bool testJSON() { return true; } +const string jsitem("{\n" + " \"id\":3,\n" + " \"result\":[{\n" + " \"price\":\"$2.99\",\n" + " \"name\":\"Apple\"\n" + " },\n" + " {\n" + " \"price\":\"$3.55\",\n" + " \"name\":\"Orange\"\n" + " },\n" + " {\n" + " \"price\":\"$1.55\",\n" + " \"name\":\"Pear\"\n" + " }\n" + " ]\n" + "}"); + +const string jsresult("{\n" + " \"id\":1,\n" + " \"result\":[\"Service.get\",\n" + " \"Service.getTotal\"\n" + " ]\n" + "}"); + +const string jsfeed("{\n" + " \"id\":1,\n" + " \"result\":[\"Sample Feed\",\n" + " \"123456789\",\n" + " [\"Item\",\n" + " \"111\",\n" + " {\n" + " \"name\":\"Apple\",\n" + " \"currencyCode\":\"USD\",\n" + " \"currencySymbol\":\"$\",\n" + " \"price\":2.99\n" + " }\n" + " ],\n" + " [\"Item\",\n" + " \"222\",\n" + " {\n" + " \"name\":\"Orange\",\n" + " \"currencyCode\":\"USD\",\n" + " \"currencySymbol\":\"$\",\n" + " \"price\":3.55\n" + " }\n" + " ],\n" + " [\"Item\",\n" + " \"333\",\n" + " {\n" + " \"name\":\"Pear\",\n" + " \"currencyCode\":\"USD\",\n" + " \"currencySymbol\":\"$\",\n" + " \"price\":1.55\n" + " }\n" + " ]\n" + " ]\n" + "}"); + +const string jsechoreq("{\n" + " \"id\":1,\n" + " \"method\":\"echo\",\n" + " \"params\":[{\n" + " \"ns1:echoString\":{\n" + " \"@xmlns:ns1\":\"http://ws.apache.org/axis2/services/echo\",\n" + " \"text\":\"Hello World!\"\n" + " }\n" + " }\n" + " ]\n" + "}"); + +const string jsechores("{\n" + " \"id\":1,\n" + " \"result\":{\n" + " \"ns1:echoString\":{\n" + " \"@xmlns:ns1\":\"http://ws.apache.org/axis2/c/samples\",\n" + " \"text\":\"Hello World!\"\n" + " }\n" + " }\n" + "}"); + bool testJSONRPC() { js::JSContext cx; { @@ -91,18 +200,16 @@ bool testJSONRPC() { assert(assoc<value>("params", v) == mklist<value>("params", list<value>())); } { - const string i("{\"id\":3,\"result\":[{\"price\":\"$2.99\",\"name\":\"Apple\"},{\"price\":\"$3.55\",\"name\":\"Orange\"},{\"price\":\"$1.55\",\"name\":\"Pear\"}]}"); - const list<value> e = content(readJSON(mklist(i), cx)); - const string i2("{\"id\":3,\"result\":{\"0\":{\"price\":\"$2.99\",\"name\":\"Apple\"},\"1\":{\"price\":\"$3.55\",\"name\":\"Orange\"},\"2\":{\"price\":\"$1.55\",\"name\":\"Pear\"}}}"); - const list<value> e2 = content(readJSON(mklist(i), cx)); + const string i2 = "{\"id\":3,\"result\":{\"0\":{\"price\":\"$2.99\",\"name\":\"Apple\"},\"1\":{\"price\":\"$3.55\",\"name\":\"Orange\"},\"2\":{\"price\":\"$1.55\",\"name\":\"Pear\"}}}"; + const list<value> e = content(readJSON(mklist(jsitem), cx)); + const list<value> e2 = content(readJSON(mklist(i2), cx)); assert(e == e2); } { - const string i("{\"id\":3,\"result\":[{\"price\":\"$2.99\",\"name\":\"Apple\"},{\"price\":\"$3.55\",\"name\":\"Orange\"},{\"price\":\"$1.55\",\"name\":\"Pear\"}]}"); - const list<value> e = content(readJSON(mklist(i), cx)); + const list<value> e = content(readJSON(mklist(jsitem), cx)); ostringstream os; write(content(writeJSON(e, cx)), os); - assert(str(os) == i); + assert(str(os) == jsitem); const list<value> v = elementsToValues(e); const list<value> r = valuesToElements(v); assert(r == e); @@ -112,23 +219,22 @@ bool testJSONRPC() { const list<value> e = valuesToElements(r); ostringstream os; write(content(writeJSON(e, cx)), os); - assert(str(os) == "{\"id\":1,\"result\":[\"Service.get\",\"Service.getTotal\"]}"); + assert(str(os) == jsresult); } { - const string f("{\"id\":1,\"result\":[\"Sample Feed\",\"123456789\",[\"Item\",\"111\",{\"name\":\"Apple\",\"currencyCode\":\"USD\",\"currencySymbol\":\"$\",\"price\":2.99}],[\"Item\",\"222\",{\"name\":\"Orange\",\"currencyCode\":\"USD\",\"currencySymbol\":\"$\",\"price\":3.55}],[\"Item\",\"333\",{\"name\":\"Pear\",\"currencyCode\":\"USD\",\"currencySymbol\":\"$\",\"price\":1.55}]]}"); - const list<value> r = content(readJSON(mklist(f), cx)); + const list<value> r = content(readJSON(mklist(jsfeed), cx)); const list<value> v = elementsToValues(r); const list<value> e = valuesToElements(v); ostringstream os; write(content(writeJSON(e, cx)), os); - assert(str(os) == f); + assert(str(os) == jsfeed); } { const list<value> arg = mklist<value>(list<value>() + "ns1:echoString" + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + (list<value>() + "text" + string("Hello World!"))); const failable<list<string> > r = jsonRequest(1, "echo", mklist<value>(arg), cx); ostringstream os; write(content(r), os); - assert(str(os) == "{\"id\":1,\"method\":\"echo\",\"params\":[{\"ns1:echoString\":{\"@xmlns:ns1\":\"http://ws.apache.org/axis2/services/echo\",\"text\":\"Hello World!\"}}]}"); + assert(str(os) == jsechoreq); istringstream is(str(os)); const list<string> il = streamList(is); @@ -140,7 +246,7 @@ bool testJSONRPC() { const failable<list<string> > r = jsonResult(1, res, cx); ostringstream os; write(content(r), os); - assert(str(os) == "{\"id\":1,\"result\":{\"ns1:echoString\":{\"@xmlns:ns1\":\"http://ws.apache.org/axis2/c/samples\",\"text\":\"Hello World!\"}}}"); + assert(str(os) == jsechores); istringstream is(str(os)); const list<string> il = streamList(is); diff --git a/sca-cpp/trunk/modules/json/json.hpp b/sca-cpp/trunk/modules/json/json.hpp index df82fddbb5..f35c04208e 100644 --- a/sca-cpp/trunk/modules/json/json.hpp +++ b/sca-cpp/trunk/modules/json/json.hpp @@ -110,7 +110,7 @@ template<typename R> const failable<R> writeJSON(const lambda<R(const string&, c val = OBJECT_TO_JSVAL(valuesToJSProperties(JS_NewObject(cx, NULL, NULL, NULL), l, cx)); WriteContext<R> wcx(reduce, initial, cx); - if (!JS_Stringify(cx, &val, NULL, JSVAL_NULL, writeCallback<R>, &wcx)) + if (!JS_Stringify(cx, &val, NULL, INT_TO_JSVAL(1), writeCallback<R>, &wcx)) return mkfailure<R>("JS_Stringify failed"); return wcx.accum; } diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp index 84de8f2d05..acf39601b3 100644 --- a/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp +++ b/sca-cpp/trunk/modules/oauth/mod-oauth1.cpp @@ -193,7 +193,7 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co // Build the redirect URI const list<list<value> > redirargs = mklist<list<value> >(mklist<value>("mod_oauth1_step", "access_token"), tok, cid, info); - const string redir = httpd::url(r->uri, r) + string("?") + httpd::queryString(redirargs); + const string redir = httpd::url(r->uri, r) + string("?") + http::queryString(redirargs); debug(redir, "modoauth1::authorize::redir"); // Lookup client app configuration @@ -203,7 +203,7 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co list<value> appkey = cadr(app); // Build and sign the request token URI - const string requri = httpd::unescape(cadr(req)) + string("&") + httpd::queryString(mklist<list<value> >(mklist<value>("oauth_callback", httpd::escape(redir)))); + const string requri = httpd::unescape(cadr(req)) + string("&") + http::queryString(mklist<list<value> >(mklist<value>("oauth_callback", httpd::escape(redir)))); const list<string> srequri = sign("POST", requri, appkey, "", ""); debug(srequri, "modoauth1::authorize::srequri"); @@ -236,7 +236,7 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co return mkfailure<int>(reason(prc)); // Redirect to the authorize URI - const string authuri = httpd::unescape(cadr(auth)) + string("?") + httpd::queryString(mklist<list<value> >(tv)); + const string authuri = httpd::unescape(cadr(auth)) + string("?") + http::queryString(mklist<list<value> >(tv)); debug(authuri, "modoauth1::authorize::authuri"); return httpd::externalRedirect(authuri, r); } @@ -325,7 +325,7 @@ const failable<int> access_token(const list<list<value> >& args, request_rec* r, return mkfailure<int>(reason(sv)); // Build and sign access token request URI - const string tokuri = httpd::unescape(cadr(tok)) + string("?") + httpd::queryString(mklist<list<value> >(vv)); + const string tokuri = httpd::unescape(cadr(tok)) + string("?") + http::queryString(mklist<list<value> >(vv)); const list<string> stokuri = sign("POST", tokuri, appkey, cadr(tv), content(sv)); debug(stokuri, "modoauth1::access_token::stokuri"); diff --git a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp index 51bd240177..a662333c9e 100644 --- a/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp +++ b/sca-cpp/trunk/modules/oauth/mod-oauth2.cpp @@ -141,7 +141,7 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co // Build the redirect URI const list<list<value> > rargs = mklist<list<value> >(mklist<value>("mod_oauth2_step", "access_token"), tok, cid, info); - const string redir = httpd::url(r->uri, r) + string("?") + httpd::queryString(rargs); + const string redir = httpd::url(r->uri, r) + string("?") + http::queryString(rargs); debug(redir, "modoauth2::authorize::redir"); // Lookup client app configuration @@ -152,7 +152,7 @@ const failable<int> authorize(const list<list<value> >& args, request_rec* r, co // Redirect to the authorize URI const list<list<value> > aargs = mklist<list<value> >(mklist<value>("client_id", car(appkey)), mklist<value>("scope", "email"), mklist<value>("redirect_uri", httpd::escape(redir))); - const string uri = httpd::unescape(cadr(auth)) + string("?") + httpd::queryString(aargs); + const string uri = httpd::unescape(cadr(auth)) + string("?") + http::queryString(aargs); debug(uri, "modoauth2::authorize::uri"); return httpd::externalRedirect(uri, r); } @@ -192,12 +192,12 @@ const failable<int> access_token(const list<list<value> >& args, request_rec* r, // Build the redirect URI const list<list<value> > rargs = mklist<list<value> >(mklist<value>("mod_oauth2_step", "access_token"), tok, cid, info); - const string redir = httpd::url(r->uri, r) + string("?") + httpd::queryString(rargs); + const string redir = httpd::url(r->uri, r) + string("?") + http::queryString(rargs); debug(redir, "modoauth2::access_token::redir"); // Request access token const list<list<value> > targs = mklist<list<value> >(mklist<value>("client_id", car(appkey)), mklist<value>("redirect_uri", httpd::escape(redir)), mklist<value>("client_secret", cadr(appkey)), code); - const string turi = httpd::unescape(cadr(tok)) + string("?") + httpd::queryString(targs); + const string turi = httpd::unescape(cadr(tok)) + string("?") + http::queryString(targs); debug(turi, "modoauth2::access_token::tokenuri"); const failable<value> tr = http::get(turi, sc.cs); if (!hasContent(tr)) @@ -211,7 +211,7 @@ const failable<int> access_token(const list<list<value> >& args, request_rec* r, // Request user info // TODO Make this step configurable const list<list<value> > iargs = mklist<list<value> >(tv); - const string iuri = httpd::unescape(cadr(info)) + string("?") + httpd::queryString(iargs); + const string iuri = httpd::unescape(cadr(info)) + string("?") + http::queryString(iargs); debug(iuri, "modoauth2::access_token::infouri"); const failable<value> profres = http::get(iuri, sc.cs); if (!hasContent(profres)) diff --git a/sca-cpp/trunk/modules/rss/rss-test.cpp b/sca-cpp/trunk/modules/rss/rss-test.cpp index 0b773ba31e..c2c3eb9e8f 100644 --- a/sca-cpp/trunk/modules/rss/rss-test.cpp +++ b/sca-cpp/trunk/modules/rss/rss-test.cpp @@ -36,49 +36,51 @@ ostream* writer(const string& s, ostream* os) { return os; } -string itemEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<item>" - "<title>fruit</title>" - "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>" - "<description>" - "<item>" - "<name>Apple</name><price>$2.99</price>" - "</item>" - "</description>" +const string itemEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<item>\n" + " <title>fruit</title>\n" + " <link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>\n" + " <description>\n" + " <item>\n" + " <name>Apple</name>\n" + " <price>$2.99</price>\n" + " </item>\n" + " </description>\n" "</item>\n"); -string itemTextEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<item>" - "<title>fruit</title>" - "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>" - "<description>Apple</description>" +const string itemTextEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<item>\n" + " <title>fruit</title>\n" + " <link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>\n" + " <description>Apple</description>\n" "</item>\n"); -string itemNoDescriptionEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<item>" - "<title>fruit</title>" - "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>" +const string itemNoDescriptionEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<item>\n" + " <title>fruit</title>\n" + " <link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>\n" "</item>\n"); -string incompleteEntry("<item>" - "<title>fruit</title><description>" - "<Item xmlns=\"http://services/\">" - "<name xmlns=\"\">Orange</name>" - "<price xmlns=\"\">3.55</price>" - "</Item>" - "</description>" +const string incompleteEntry("<item>\n" + " <title>fruit</title>\n" + " <description>\n" + " <Item xmlns=\"http://services/\">\n" + " <name xmlns=\"\">Orange</name>\n" + " <price xmlns=\"\">3.55</price>\n" + " </Item>\n" + " </description>\n" "</item>"); -string completedEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<item>" - "<title>fruit</title>" - "<link></link>" - "<description>" - "<Item xmlns=\"http://services/\">" - "<name xmlns=\"\">Orange</name>" - "<price xmlns=\"\">3.55</price>" - "</Item>" - "</description>" +const string completedEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<item>\n" + " <title>fruit</title>\n" + " <link></link>\n" + " <description>\n" + " <Item xmlns=\"http://services/\">\n" + " <name xmlns=\"\">Orange</name>\n" + " <price xmlns=\"\">3.55</price>\n" + " </Item>\n" + " </description>\n" "</item>\n"); bool testEntry() { @@ -130,40 +132,42 @@ bool testEntry() { return true; } -string emptyFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<rss version=\"2.0\">" - "<channel>" - "<title>Feed</title>" - "<link>1234</link>" - "<description>Feed</description>" - "</channel>" +const string emptyFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<rss version=\"2.0\">\n" + " <channel>\n" + " <title>Feed</title>\n" + " <link>1234</link>\n" + " <description>Feed</description>\n" + " </channel>\n" "</rss>\n"); -string itemFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" - "<rss version=\"2.0\">" - "<channel>" - "<title>Feed</title>" - "<link>1234</link>" - "<description>Feed</description>" - "<item>" - "<title>fruit</title>" - "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>" - "<description>" - "<item>" - "<name>Apple</name><price>$2.99</price>" - "</item>" - "</description>" - "</item>" - "<item>" - "<title>fruit</title>" - "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c</link>" - "<description>" - "<item>" - "<name>Orange</name><price>$3.55</price>" - "</item>" - "</description>" - "</item>" - "</channel>" +const string itemFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<rss version=\"2.0\">\n" + " <channel>\n" + " <title>Feed</title>\n" + " <link>1234</link>\n" + " <description>Feed</description>\n" + " <item>\n" + " <title>fruit</title>\n" + " <link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>\n" + " <description>\n" + " <item>\n" + " <name>Apple</name>\n" + " <price>$2.99</price>\n" + " </item>\n" + " </description>\n" + " </item>\n" + " <item>\n" + " <title>fruit</title>\n" + " <link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c</link>\n" + " <description>\n" + " <item>\n" + " <name>Orange</name>\n" + " <price>$3.55</price>\n" + " </item>\n" + " </description>\n" + " </item>\n" + " </channel>\n" "</rss>\n"); bool testFeed() { diff --git a/sca-cpp/trunk/modules/scdl/scdl-test.cpp b/sca-cpp/trunk/modules/scdl/scdl-test.cpp index e8ee77eb4e..09a3dcd5dd 100644 --- a/sca-cpp/trunk/modules/scdl/scdl-test.cpp +++ b/sca-cpp/trunk/modules/scdl/scdl-test.cpp @@ -47,8 +47,8 @@ bool testComponents() { const value store = car(c); assert(name(store) == string("Store")); const value impl = implementation(store); - assert(uri(impl) == string("store.html")); assert(implementationType(impl) == "t:implementation.scheme"); + assert(attributeValue("script", impl) == string("store.scm")); const value catalog = named(string("Catalog"), c); assert(name(catalog) == string("Catalog")); diff --git a/sca-cpp/trunk/modules/server/htdocs/test/entry.xml b/sca-cpp/trunk/modules/server/htdocs/test/entry.xml index 6528c793e3..46053c3138 100644 --- a/sca-cpp/trunk/modules/server/htdocs/test/entry.xml +++ b/sca-cpp/trunk/modules/server/htdocs/test/entry.xml @@ -1,2 +1,14 @@ <?xml version="1.0" encoding="UTF-8"?> -<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>111</id><content type="application/xml"><item><name>Apple</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>2.99</price></item></content><link href="111"/></entry> +<entry xmlns="http://www.w3.org/2005/Atom"> + <title type="text">Item</title> + <id>111</id> + <content type="application/xml"> + <item> + <name>Apple</name> + <currencyCode>USD</currencyCode> + <currencySymbol>$</currencySymbol> + <price>2.99</price> + </item> + </content> + <link href="111"/> +</entry> diff --git a/sca-cpp/trunk/modules/server/htdocs/test/feed.xml b/sca-cpp/trunk/modules/server/htdocs/test/feed.xml index bcb304f9c2..337320e4c5 100644 --- a/sca-cpp/trunk/modules/server/htdocs/test/feed.xml +++ b/sca-cpp/trunk/modules/server/htdocs/test/feed.xml @@ -1,2 +1,44 @@ <?xml version="1.0" encoding="UTF-8"?> -<feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Sample Feed</title><id>123456789</id><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>111</id><content type="application/xml"><item><name>Apple</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>2.99</price></item></content><link href="111"/></entry><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>222</id><content type="application/xml"><item><name>Orange</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>3.55</price></item></content><link href="222"/></entry><entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><id>333</id><content type="application/xml"><item><name>Pear</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>1.55</price></item></content><link href="333"/></entry></feed> +<feed xmlns="http://www.w3.org/2005/Atom"> + <title type="text">Sample Feed</title> + <id>123456789</id> + <entry xmlns="http://www.w3.org/2005/Atom"> + <title type="text">Item</title> + <id>111</id> + <content type="application/xml"> + <item> + <name>Apple</name> + <currencyCode>USD</currencyCode> + <currencySymbol>$</currencySymbol> + <price>2.99</price> + </item> + </content> + <link href="111"/> + </entry> + <entry xmlns="http://www.w3.org/2005/Atom"> + <title type="text">Item</title> + <id>222</id> + <content type="application/xml"> + <item> + <name>Orange</name> + <currencyCode>USD</currencyCode> + <currencySymbol>$</currencySymbol> + <price>3.55</price> + </item> + </content> + <link href="222"/> + </entry> + <entry xmlns="http://www.w3.org/2005/Atom"> + <title type="text">Item</title> + <id>333</id> + <content type="application/xml"> + <item> + <name>Pear</name> + <currencyCode>USD</currencyCode> + <currencySymbol>$</currencySymbol> + <price>1.55</price> + </item> + </content> + <link href="333"/> + </entry> +</feed> diff --git a/sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt b/sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt index 70f0139ea0..75843bc286 100644 --- a/sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt +++ b/sca-cpp/trunk/modules/server/htdocs/test/json-properties.txt @@ -1 +1,13 @@ -{"id":"1","result":{"host":"localhost","path":["components","property-test"],"query":{"id":"1","method":"print"}}}
\ No newline at end of file +{ + "id":"1", + "result":{ + "host":"localhost", + "path":["components", + "property-test" + ], + "query":{ + "id":"1", + "method":"print" + } + } +}
\ No newline at end of file diff --git a/sca-cpp/trunk/modules/server/htdocs/test/json-result.txt b/sca-cpp/trunk/modules/server/htdocs/test/json-result.txt index 121bf74902..38aa8a2a5e 100644 --- a/sca-cpp/trunk/modules/server/htdocs/test/json-result.txt +++ b/sca-cpp/trunk/modules/server/htdocs/test/json-result.txt @@ -1 +1,4 @@ -{"id":1,"result":"Hello"}
\ No newline at end of file +{ + "id":1, + "result":"Hello" +}
\ No newline at end of file diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp index 64ab6df4bb..8047015cbc 100644 --- a/sca-cpp/trunk/modules/server/mod-eval.hpp +++ b/sca-cpp/trunk/modules/server/mod-eval.hpp @@ -125,24 +125,43 @@ 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 failable<value> val = failableResult(impl(cons<value>("get", mklist<value>(cddr(path))))); + const list<value> params(append<value>(cddr(path), mkvalues(args))); + const failable<value> val = failableResult(impl(cons<value>("get", mklist<value>(params)))); if (!hasContent(val)) return mkfailure<int>(reason(val)); const value c = content(val); + // Write a simple value as a JSON value + if (!isList(c)) { + js::JSContext cx; + return httpd::writeResult(json::writeJSON(valuesToElements(mklist<value>(mklist<value>("value", c))), cx), "application/json", r); + } + + // Write an empty list as a JSON empty value + if (isNil(c)) { + js::JSContext cx; + return httpd::writeResult(json::writeJSON(list<value>(), cx), "application/json", r); + } + + // Write an assoc value as a JSON result + if (isSymbol(car<value>(c)) && !isNil(cdr<value>(c))) { + js::JSContext cx; + return httpd::writeResult(json::writeJSON(valuesToElements(mklist<value>(c)), cx), "application/json", r); + } + // Write content-type / content-list pair - if (isString(car<value>(c)) && isList(cadr<value>(c))) + if (isString(car<value>(c)) && !isNil(cdr<value>(c)) && isList(cadr<value>(c))) return httpd::writeResult(convertValues<string>(cadr<value>(c)), car<value>(c), r); - // Write ATOM feed or entry - if (isString(car<value>(c)) && isString(cadr<value>(c))) { + // Write an ATOM feed or entry + if (isString(car<value>(c)) && !isNil(cdr<value>(c)) && isString(cadr<value>(c))) { if (isNil(cddr(path))) return httpd::writeResult(atom::writeATOMFeed(atom::feedValuesToElements(c)), "application/atom+xml", r); else return httpd::writeResult(atom::writeATOMEntry(atom::entryValuesToElements(c)), "application/atom+xml", r); } - // Write JSON value + // Write any other compound value as a JSON value js::JSContext cx; return httpd::writeResult(json::writeJSON(valuesToElements(c), cx), "application/json", r); } @@ -419,27 +438,29 @@ struct userPropProxy { }; const value mkpropProxy(const value& prop) { - if (scdl::name(prop) == "host") - return lambda<value(const list<value>&)>(hostPropProxy(elementValue(prop))); - if (scdl::name(prop) == "path") - return lambda<value(const list<value>&)>(pathPropProxy(elementValue(prop))); - if (scdl::name(prop) == "query") - return lambda<value(const list<value>&)>(queryPropProxy(elementValue(prop))); - if (scdl::name(prop) == "user") - return lambda<value(const list<value>&)>(userPropProxy(elementValue(prop))); - if (scdl::name(prop) == "realm") - return lambda<value(const list<value>&)>(envPropProxy("REALM", elementValue(prop))); - if (scdl::name(prop) == "email") - return lambda<value(const list<value>&)>(envPropProxy("EMAIL", elementValue(prop))); - if (scdl::name(prop) == "nickname") - return lambda<value(const list<value>&)>(envPropProxy("NICKNAME", elementValue(prop))); - if (scdl::name(prop) == "fullname") - return lambda<value(const list<value>&)>(envPropProxy("FULLNAME", elementValue(prop))); - if (scdl::name(prop) == "firstname") - return lambda<value(const list<value>&)>(envPropProxy("FIRSTNAME", elementValue(prop))); - if (scdl::name(prop) == "lastname") - return lambda<value(const list<value>&)>(envPropProxy("LASTNAME", elementValue(prop))); - return lambda<value(const list<value>&)>(propProxy(elementValue(prop))); + const value n = scdl::name(prop); + const value v = elementHasValue(prop)? elementValue(prop):value(string("")); + if (n == "host") + return lambda<value(const list<value>&)>(hostPropProxy(v)); + if (n == "path") + return lambda<value(const list<value>&)>(pathPropProxy(v)); + if (n == "query") + return lambda<value(const list<value>&)>(queryPropProxy(v)); + if (n == "user") + return lambda<value(const list<value>&)>(userPropProxy(v)); + if (n == "realm") + return lambda<value(const list<value>&)>(envPropProxy("REALM", v)); + if (n == "email") + return lambda<value(const list<value>&)>(envPropProxy("EMAIL", v)); + if (n == "nickname") + return lambda<value(const list<value>&)>(envPropProxy("NICKNAME", v)); + if (n == "fullname") + return lambda<value(const list<value>&)>(envPropProxy("FULLNAME", v)); + if (n == "firstname") + return lambda<value(const list<value>&)>(envPropProxy("FIRSTNAME", v)); + if (n == "lastname") + return lambda<value(const list<value>&)>(envPropProxy("LASTNAME", v)); + return lambda<value(const list<value>&)>(propProxy(v)); } const list<value> propProxies(const list<value>& props) { @@ -675,8 +696,10 @@ int handler(request_rec *r) { // Get the component implementation lambda const list<value> path(pathValues(r->uri)); const list<value> impl(assoctree<value>(cadr(path), usevh? vhc.vsc.implTree : sc.implTree)); - if (isNil(impl)) - return httpd::reportStatus(mkfailure<int>(string("Couldn't find component implementation: ") + cadr(path))); + if (isNil(impl)) { + mkfailure<int>(string("Couldn't find component implementation: ") + cadr(path)); + return HTTP_NOT_FOUND; + } // Handle HTTP method const lambda<value(const list<value>&)> l(cadr<value>(impl)); diff --git a/sca-cpp/trunk/modules/server/mod-wiring.cpp b/sca-cpp/trunk/modules/server/mod-wiring.cpp index b63cd3fb37..ac9e621177 100644 --- a/sca-cpp/trunk/modules/server/mod-wiring.cpp +++ b/sca-cpp/trunk/modules/server/mod-wiring.cpp @@ -107,7 +107,7 @@ int translateReference(const ServerConf& sc, request_rec *r) { if (useModProxy) { // Build proxy URI // current request's protocol scheme, reference target uri and request path info - string turi = httpd::scheme(r) + substr(target, find(target, "://")) + path(pathInfo); + string turi = httpd::scheme(r) + substr(target, find(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"); r->proxyreq = PROXYREQ_REVERSE; @@ -124,7 +124,7 @@ 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)); + 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"); r->handler = "mod_tuscany_wiring"; diff --git a/sca-cpp/trunk/samples/store-cpp/htdocs/test/items-result.txt b/sca-cpp/trunk/samples/store-cpp/htdocs/test/items-result.txt index 56f87d2778..676ded6242 100644 --- a/sca-cpp/trunk/samples/store-cpp/htdocs/test/items-result.txt +++ b/sca-cpp/trunk/samples/store-cpp/htdocs/test/items-result.txt @@ -1 +1,22 @@ -{"id":1,"result":[{"name":"Apple","currencyCode":"USD","currencySymbol":"$","price":2.99},{"name":"Orange","currencyCode":"USD","currencySymbol":"$","price":3.55},{"name":"Pear","currencyCode":"USD","currencySymbol":"$","price":1.55}]}
\ No newline at end of file +{ + "id":1, + "result":[{ + "name":"Apple", + "currencyCode":"USD", + "currencySymbol":"$", + "price":2.99 + }, + { + "name":"Orange", + "currencyCode":"USD", + "currencySymbol":"$", + "price":3.55 + }, + { + "name":"Pear", + "currencyCode":"USD", + "currencySymbol":"$", + "price":1.55 + } + ] +}
\ No newline at end of file diff --git a/sca-cpp/trunk/samples/store-python/htdocs/test/items-result.txt b/sca-cpp/trunk/samples/store-python/htdocs/test/items-result.txt index 788b7cdf89..5e498c948a 100644 --- a/sca-cpp/trunk/samples/store-python/htdocs/test/items-result.txt +++ b/sca-cpp/trunk/samples/store-python/htdocs/test/items-result.txt @@ -1 +1,22 @@ -{"id":1,"result":[{"name":"Mango","currencyCode":"USD","currencySymbol":"$","price":2.99},{"name":"Passion","currencyCode":"USD","currencySymbol":"$","price":3.55},{"name":"Kiwi","currencyCode":"USD","currencySymbol":"$","price":1.55}]}
\ No newline at end of file +{ + "id":1, + "result":[{ + "name":"Mango", + "currencyCode":"USD", + "currencySymbol":"$", + "price":2.99 + }, + { + "name":"Passion", + "currencyCode":"USD", + "currencySymbol":"$", + "price":3.55 + }, + { + "name":"Kiwi", + "currencyCode":"USD", + "currencySymbol":"$", + "price":1.55 + } + ] +}
\ No newline at end of file |