/** Common part of request parser, usually after JSON representation is made available in req->params * @param req the request * @param leave leave the req->params */ static bool common(struct req *req, bool leave) { ut *ut; /* guarantee that req->params is ok */ if (!ut_ok(req->params)) { req->reply = req->params; req->params = NULL; return false; } else if (ut_type(req->params) != T_HASH) { return errcode(JSON_RPC_INVALID_REQUEST); } /* JSON-RPC argument check */ if ((ut = uth_get(req->params, "service"))) /* used by Qooxdoo */ req->service = ut_char(ut); if ((ut = uth_get(req->params, "method"))) req->method = ut_char(ut); if ((ut = uth_get(req->params, "id"))) req->id = ut_char(ut); /* XXX: dont check jsonrpc=2.0 */ if (!leave) { if ((ut = uth_get(req->params, "params"))) req->params = ut; else req->params = uth_set_thash(req->params, "params", NULL); /* create empty hash */ if (ut_is_tlist(req->params) && thash_get(req->http.headers, "X-Qooxdoo-Response-Type")) { tlist *tl = ut_tlist(req->params); req->params = tlist_shift(tl); } } return true; }
/* this probably needs a wise rewrite */ static char *fill_query(struct req *req, char *orig_query, tlist *data) { int i, qs; enum fq_state { NORMAL, INQ } state = NORMAL; xstr *query; MYSQL *conn; ut *arg, *el, *el2; tlist *list, *list2; bool atleastone, atleastone2; #define iskeyw(a) (sizeof(a) == i - qs && strncmp((a), orig_query + qs + 1, sizeof(a) - 1) == 0) /* XXX: uses list and el */ #define appendlist(utlist) do { \ atleastone = false; \ xstr_append(query, "("); \ list = ut_tlist(utlist); \ TLIST_ITER_LOOP(list, el) { \ if (atleastone) \ xstr_append_char(query, ','); \ xstr_append(query, \ pb("\"%s\"", escape(conn, ut_xstr(el)))); \ atleastone = true; \ } \ xstr_append(query, ")"); \ } while(0); conn = uthp_ptr(req->prv, "sqler", "conn"); query = xstr_create("", req); tlist_reset(data); for (i = 0; orig_query[i]; i++) { switch (state) { case NORMAL: if (orig_query[i] == '?') { qs = i; state = INQ; } else { xstr_append_char(query, orig_query[i]); } break; case INQ: if (orig_query[i] == '?') { if (iskeyw("login")) { xstr_append(query, pb("\"%s\"", uthp_char(req->prv, "sqler", "login"))); } else if (iskeyw("role")) { xstr_append(query, pb("\"%s\"", uthp_char(req->prv, "sqler", "role"))); } else { /* probably needs an arg */ arg = tlist_iter(data); if (arg) { if (iskeyw("int")) { xstr_append(query, pb("%d", ut_int(arg))); } else if (iskeyw("str")) { xstr_append(query, pb("\"%s\"", escape(conn, ut_xstr(arg)))); } else if (iskeyw("dbl")) { xstr_append(query, pb("%g", ut_double(arg))); } else if (iskeyw("login")) { xstr_append(query, pb("\"%s\"", uthp_char(req->prv, "sqler", "login"))); } else if (iskeyw("role")) { xstr_append(query, pb("\"%s\"", uthp_char(req->prv, "sqler", "role"))); } else if (iskeyw("array")) { appendlist(arg); } else if (iskeyw("arrays")) { atleastone2 = false; list2 = ut_tlist(arg); TLIST_ITER_LOOP(list2, el2) { if (atleastone2) xstr_append_char(query, ','); appendlist(el2); atleastone2 = true; } } /* XXX: arg eaten by unrecognizible substitution */ } } state = NORMAL; } else if (orig_query[i] < 'a' || orig_query[i] > 'z') { rollback: while (qs <= i) xstr_append_char(query, orig_query[qs++]); state = NORMAL; } break; }