Correctly pass query strings through component wiring redirects and improve format of XML and JSON response documents.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1074924 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
0ee21c5d96
commit
7c018c6fb6
22 changed files with 500 additions and 221 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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>");
|
||||
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");
|
||||
|
||||
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 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() {
|
||||
|
|
|
|||
|
|
@ -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") {
|
||||
|
|
|
|||
|
|
@ -282,24 +282,6 @@ const list<list<value> > queryArgs(const request_rec* r) {
|
|||
return queryArgs(r->args);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -1 +1,13 @@
|
|||
{"id":"1","result":{"host":"localhost","path":["components","property-test"],"query":{"id":"1","method":"print"}}}
|
||||
{
|
||||
"id":"1",
|
||||
"result":{
|
||||
"host":"localhost",
|
||||
"path":["components",
|
||||
"property-test"
|
||||
],
|
||||
"query":{
|
||||
"id":"1",
|
||||
"method":"print"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1,4 @@
|
|||
{"id":1,"result":"Hello"}
|
||||
{
|
||||
"id":1,
|
||||
"result":"Hello"
|
||||
}
|
||||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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}]}
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -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}]}
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue