List keys with special characters are RFC 3986 encoded

This commit is contained in:
Olof hagsand 2017-01-16 22:55:28 +01:00
parent 2db346abc8
commit c9f1ece53e
3 changed files with 59 additions and 12 deletions

View file

@ -29,6 +29,7 @@
# #
# ***** END LICENSE BLOCK ***** # ***** END LICENSE BLOCK *****
- List keys with special characters are RFC 3986 encoded.
- Added cli multiple callback and expand support. Use options - Added cli multiple callback and expand support. Use options
CLICON_CLIGEN_CALLBACK_SINGLE_ARG and CLICON_CLIGEN_EXPAND_SINGLE_ARG CLICON_CLIGEN_CALLBACK_SINGLE_ARG and CLICON_CLIGEN_EXPAND_SINGLE_ARG
to control these. to control these.

View file

@ -51,6 +51,7 @@
#include <dirent.h> #include <dirent.h>
#include <assert.h> #include <assert.h>
#include <syslog.h> #include <syslog.h>
#include <curl/curl.h>
/* cligen */ /* cligen */
#include <cligen/cligen.h> #include <cligen/cligen.h>
@ -95,14 +96,16 @@
* +-----------------+ +-----------------+ * +-----------------+ +-----------------+
* | yang-stmt | yang2xmlkeyfmt | xmlkeyfmt | * | yang-stmt | yang2xmlkeyfmt | xmlkeyfmt |
* | list aa,leaf k | ----------------->| /aa/%s | * | list aa,leaf k | ----------------->| /aa/%s |
* | | | XXX: /aa=%s |
* +-----------------+ +-----------------+ * +-----------------+ +-----------------+
* | * |
* | xmlkeyfmt2key * | xmlkeyfmt2key
* | k=17 * | k=17
* v * v
* +-------------------+ +-----------------+ * +-------------------+ +-----------------+
* | xml-tree/cxobj | xmlkey2xml | xmlkey | * | xml-tree/cxobj | xmlkey2xml | xmlkey RFC3986|
* | <aa><k>17</k></aa>| <------------- | /aa/17 | * | <aa><k>17</k></aa>| <------------- | /aa/17 |
* | | | XXX: /aa=17 |
* +-------------------+ +-----------------+ * +-------------------+ +-----------------+
* *
* Alternative for xmlkeyfmt would be xpath: eg * Alternative for xmlkeyfmt would be xpath: eg
@ -235,6 +238,8 @@ xmlkeyfmt2key(char *xkfmt,
int i; int i;
int j; int j;
char *str; char *str;
char *strenc=NULL;
/* Sanity check */ /* Sanity check */
#if 1 #if 1
@ -266,7 +271,12 @@ xmlkeyfmt2key(char *xkfmt,
clicon_err(OE_UNIX, errno, "strdup"); clicon_err(OE_UNIX, errno, "strdup");
goto done; goto done;
} }
cprintf(cb, "%s", str); if ((strenc = curl_easy_escape(NULL, str, 0)) == NULL){
clicon_err(OE_UNIX, errno, "curl_easy_escape");
goto done;
}
cprintf(cb, "%s", strenc);
curl_free(strenc);
free(str); free(str);
} }
else else
@ -493,6 +503,7 @@ append_listkeys(cbuf *ckey,
cg_var *cvi; cg_var *cvi;
cvec *cvk = NULL; /* vector of index keys */ cvec *cvk = NULL; /* vector of index keys */
char *keyname; char *keyname;
char *bodyenc;
if ((ykey = yang_find((yang_node*)ys, Y_KEY, NULL)) == NULL){ if ((ykey = yang_find((yang_node*)ys, Y_KEY, NULL)) == NULL){
clicon_err(OE_XML, errno, "%s: List statement \"%s\" has no key", clicon_err(OE_XML, errno, "%s: List statement \"%s\" has no key",
@ -511,7 +522,12 @@ append_listkeys(cbuf *ckey,
xml_name(xt), keyname); xml_name(xt), keyname);
goto done; goto done;
} }
cprintf(ckey, "/%s", xml_body(xkey)); if ((bodyenc = curl_easy_escape(NULL, xml_body(xkey), 0)) == NULL){
clicon_err(OE_UNIX, errno, "curl_easy_escape");
goto done;
}
cprintf(ckey, "/%s", bodyenc);
free(bodyenc); bodyenc = NULL;
} }
retval = 0; retval = 0;
done: done:
@ -617,6 +633,7 @@ get(char *dbname,
cvec *cvk = NULL; /* vector of index keys */ cvec *cvk = NULL; /* vector of index keys */
char *keyname; char *keyname;
char *arg; char *arg;
char *argdec;
cbuf *cb; cbuf *cb;
// clicon_debug(1, "%s xkey:%s val:%s", __FUNCTION__, xk, val); // clicon_debug(1, "%s xkey:%s val:%s", __FUNCTION__, xk, val);
@ -700,7 +717,13 @@ get(char *dbname,
goto done; goto done;
} }
arg = vec[i]; arg = vec[i];
cprintf(cb, "[%s=%s]", cv_string_get(cvi), arg); if ((argdec = curl_easy_unescape(NULL, arg, 0, NULL)) == NULL){
clicon_err(OE_UNIX, errno, "curl_easy_escape");
goto done;
}
cprintf(cb, "[%s=%s]", cv_string_get(cvi), argdec);
free(argdec);
argdec=NULL;
} }
if ((xc = xpath_first(x, cbuf_get(cb))) == NULL){ if ((xc = xpath_first(x, cbuf_get(cb))) == NULL){
if ((xc = xml_new_spec(name, x, y)) == NULL) if ((xc = xml_new_spec(name, x, y)) == NULL)
@ -712,11 +735,16 @@ get(char *dbname,
keyname = cv_string_get(cvi); keyname = cv_string_get(cvi);
i++; i++;
arg = vec[i]; arg = vec[i];
if ((argdec = curl_easy_unescape(NULL, arg, 0, NULL)) == NULL){
clicon_err(OE_UNIX, errno, "curl_easy_escape");
goto done;
}
if (create_keyvalues(xc, if (create_keyvalues(xc,
ykey, ykey,
arg, argdec,
keyname) < 0) keyname) < 0)
goto done; goto done;
free(argdec); argdec = NULL;
} /* while */ } /* while */
} }
if (cb){ if (cb){
@ -1570,7 +1598,7 @@ xmldb_put_xkey_local(clicon_handle h,
char *name; char *name;
cg_var *cvi; cg_var *cvi;
cvec *cvk = NULL; /* vector of index keys */ cvec *cvk = NULL; /* vector of index keys */
char *val2; char *val2 = NULL;
cbuf *ckey=NULL; /* partial keys */ cbuf *ckey=NULL; /* partial keys */
cbuf *csubkey=NULL; /* partial keys */ cbuf *csubkey=NULL; /* partial keys */
cbuf *crx=NULL; /* partial keys */ cbuf *crx=NULL; /* partial keys */

View file

@ -312,12 +312,12 @@ xpath_parse(char *xpath,
{ {
int retval = -1; int retval = -1;
int nvec = 0; int nvec = 0;
char *p;
char *s; char *s;
char *s0; char *s0;
int i; int i;
struct xpath_element *xplist = NULL; struct xpath_element *xplist = NULL;
struct xpath_element **xpnext = &xplist; struct xpath_element **xpnext = &xplist;
int esc = 0;
if ((s0 = strdup(xpath)) == NULL){ if ((s0 = strdup(xpath)) == NULL){
clicon_err(OE_XML, errno, "%s: strdup", __FUNCTION__); clicon_err(OE_XML, errno, "%s: strdup", __FUNCTION__);
@ -326,10 +326,28 @@ xpath_parse(char *xpath,
s = s0; s = s0;
if (strlen(s)) if (strlen(s))
nvec = 1; nvec = 1;
while ((p = index(s, '/')) != NULL){ /* Chop up LocatoinPath in Steps delimited by '/' (unless [] predicate)
nvec++; * Eg, "/a/b[/c]/d" -> "a" "b[/c]" "d"
*p = '\0'; */
s = p+1; esc = 0;
while (*s != '\0'){
switch (*s){
case '/':
if (esc)
break;
nvec++;
*s = '\0';
break;
case '[':
esc++;
break;
case ']':
esc--;
break;
default:
break;
}
s++;
} }
s = s0; s = s0;
for (i=0; i<nvec; i++){ for (i=0; i<nvec; i++){
@ -421,7 +439,7 @@ recursive_find(cxobj *xn,
* The predicate expression is a subset of the standard, namely: * The predicate expression is a subset of the standard, namely:
* - @<attr>=<value> * - @<attr>=<value>
* - <number> * - <number>
* - <name>=<value> * - <name>=<value> # RelationalExpr '=' RelationalExpr
* @see https://www.w3.org/TR/xpath/#predicates * @see https://www.w3.org/TR/xpath/#predicates
*/ */
static int static int