in modules/server/mod-eval.hpp [695:779]
const failable<int> get(const list<value>& rpath, request_rec* const r, const lvvlambda& impl) {
debug(r->uri, "modeval::get::uri");
// Inspect the query string
const list<value> args = httpd::unescapeArgs(httpd::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 (!isNull(ia) && !isNull(ma)) {
// Extract the request id, method and params
const value id = cadr(ia);
const value func = c_str(json::funcName(string(cadr(ma))));
// Apply the requested function
const failable<value> val = failableResult(impl(cons(func, json::queryParams(args))));
if (!hasContent(val))
return mkfailure<int>(val);
// Return JSON result
return httpd::writeResult(json::jsonResult(id, content(val)), "application/json-rpc; charset=utf-8", r);
}
// Evaluate the GET expression
const list<value> params(append<value>(cddr(rpath), mkvalues(args)));
const failable<value> val = failableResult(impl(cons<value>("get", mklist<value>(params))));
if (!hasContent(val))
return mkfailure<int>(val);
const value c = content(val);
debug(c, "modeval::get::content");
// Return a nil value as a not found status
if (!isList(c) && isNull(c))
return HTTP_NOT_FOUND;
// Write in the format requested by the client, if any
const list<value> fmt = assoc<value>("format", args);
const value mtype = !isNull(fmt)? cadr(fmt) : acceptMediaType(r);
if (!isNull(mtype)) {
if (mtype == "scheme")
return httpd::writeResult(scheme::writeValue(c), "text/x-scheme; charset=utf-8", r);
if (mtype == "json")
return httpd::writeResult(json::writeValue(c), "application/json; charset=utf-8", r);
if (mtype == "xml")
return httpd::writeResult(xml::writeElements(valuesToElements(c)), "text/xml; charset=utf-8", r);
}
// Write a simple value as a JSON value
if (!isList(c)) {
debug(c, "modeval::get::value");
return httpd::writeResult(json::writeValue(c), "application/json; charset=utf-8", r);
}
// Write an empty list as a JSON value
if (isNull((list<value>)c)) {
debug(nilListValue, "modeval::get::empty");
return httpd::writeResult(json::writeValue(c), "application/json; charset=utf-8", r);
}
// Write content-type / content-list pair
if (isString(car<value>(c)) && !isNull(cdr<value>(c)) && isList(cadr<value>(c)))
return httpd::writeResult(convertValues<string>(cadr<value>(c)), car<value>(c), r);
// Write an assoc value as a JSON value
if (isSymbol(car<value>(c)) && !isNull(cdr<value>(c))) {
debug(c, "modeval::get::assoc");
return httpd::writeResult(json::writeValue(c), "application/json; charset=utf-8", r);
}
// Write an ATOM feed or entry
const list<value> e = valuesToElements(c);
if (isList(car<value>(e)) && !isNull(car<value>(e))) {
const list<value> el = car<value>(e);
if (isSymbol(car<value>(el)) && car<value>(el) == element && !isNull(cdr<value>(el)) && isSymbol(cadr<value>(el)) && elementHasChildren(el) && !elementHasValue(el)) {
if (cadr<value>(el) == atom::feed)
return httpd::writeResult(atom::writeATOMFeed(e), "application/atom+xml; charset=utf-8", r);
if (cadr<value>(el) == atom::entry)
return httpd::writeResult(atom::writeATOMEntry(e), "application/atom+xml; charset=utf-8", r);
}
}
// Write any other compound value as a JSON value
return httpd::writeResult(json::writeValue(c), "application/json; charset=utf-8", r);
}