From a122efceff348fdc397268833a4a865c24b15a4f Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 10 Jun 2021 13:05:03 +0200 Subject: [PATCH] * Fixed: [restconf patch method adds redundant namespaces #235](https://github.com/clicon/clixon/issues/235) --- .travis.yml | 3 ++- CHANGELOG.md | 21 ++++++---------- lib/clixon/clixon_xml_map.h | 2 +- lib/src/clixon_datastore_write.c | 3 +-- lib/src/clixon_xml_map.c | 43 ++++++++++++++++++-------------- lib/src/clixon_xml_nsctx.c | 5 +++- test/test_cli.sh | 6 ++--- 7 files changed, 43 insertions(+), 40 deletions(-) diff --git a/.travis.yml b/.travis.yml index 11e46db3..1e73a976 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,5 +8,6 @@ branches: script: ./configure --with-restconf=fcgi && make && sudo make install && make test before_script: - sudo apt-get install -y libfcgi-dev - - echo "$DOCKERPASSWD" | docker login -u "$DOCKERUSER" --password-stdin + + - if [[ -n "${DOCKERUSER}" ]]; then echo "$DOCKERPASSWD" | docker login -u "$DOCKERUSER" --password-stdin; fi - ./test/travis/before_script.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index b007ea0e..94345350 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,12 +34,11 @@ Expected: June 2021 ### New features -* HTTP/2 support using nghttp2 - * --with-restconf=fcgi not affected, only for --with-restconf=native - * Added autoconf config for --with-restconf=native: - * `--disable-evhtp` disabling http/1 - * `--enable-nghttp2` enabling http/2 - * Remaining work: http (non ALPN) h1->h2 upgrade +* Restconf native HTTP/2 support using nghttp2 + * Enable using: `--with-restconf=native --enable-nghttp2` + * FCGI/nginx not affected only for `--with-restconf=native` + * HTTP/1 co-exists, unless `--disable-evhtp` which results in http/2 only + * TLS ALPN upgrade works but http (non SSL) http/1->http/2 upgrade is not yet implemented * YANG when statement in conjunction with grouping/uses/augment * Several cases were not implemented fully according to RFC 7950: * Do not extend default values if when statements evaluate to false @@ -76,15 +75,8 @@ Users may have to change how they access the system * Previous meaning (wrong): Return all `a` elements. * New meaning (correct): Return the `a` instance with empty key string: "". -### C/CLI-API changes on existing features - -Developers may need to change their code - -* - ### Minor features -* Restconf: ensure HEAD method works everywhere GET does. * Added new startup-mode: `running-startup`: First try running db, if it is empty try startup db. * See [Can startup mode to be extended to support running-startup mode? #234](https://github.com/clicon/clixon/issues/234) * Restconf: added inline configuration using `-R ` command line as an alternative to making advanced restconf configuration @@ -97,8 +89,11 @@ Developers may need to change their code ### Corrected Bugs +* Fixed: [restconf patch method adds redundant namespaces #235](https://github.com/clicon/clixon/issues/235) +* Fixed: Restconf HEAD did not work everywhere GET did, such as well-known and exact root. * Fixed: [JSON parsing error for a specific input. #236](https://github.com/clicon/clixon/issues/236) * JSON empty list parse problems, eg `a:[]` + * May also have fixed: [Json parser not work properly with empry array \[\] #228](https://github.com/clicon/clixon/issues/228) * Fixed: [restconf patch method unable to chage value to empty string #229](https://github.com/clicon/clixon/issues/229) * Fixed: [when condition error under augment in restconf #227](https://github.com/clicon/clixon/issues/227) * Fixed: [Using YANG union with decimal64 and string leads to regexp match fail #226](https://github.com/clicon/clixon/issues/226) diff --git a/lib/clixon/clixon_xml_map.h b/lib/clixon/clixon_xml_map.h index 352689c9..8f4a288f 100644 --- a/lib/clixon/clixon_xml_map.h +++ b/lib/clixon/clixon_xml_map.h @@ -72,7 +72,7 @@ int xml_sanity(cxobj *x, void *arg); int xml_non_config_data(cxobj *xt, cxobj **xerr); int xml2xpath(cxobj *x, char **xpath); int assign_namespace_element(cxobj *x0, cxobj *x1, cxobj *x1p); -int assign_namespace_body(cxobj *x0, char *x0bstr, cxobj *x1); +int assign_namespace_body(cxobj *x0, cxobj *x1); int xml_merge(cxobj *x0, cxobj *x1, yang_stmt *yspec, char **reason); int yang_enum_int_value(cxobj *node, int32_t *val); int xml_copy_marked(cxobj *x0, cxobj *x1); diff --git a/lib/src/clixon_datastore_write.c b/lib/src/clixon_datastore_write.c index 02a8f5c5..4c78d41b 100644 --- a/lib/src/clixon_datastore_write.c +++ b/lib/src/clixon_datastore_write.c @@ -487,7 +487,6 @@ text_modify(clicon_handle h, if (strcmp(restype, "enumeration") == 0 || strcmp(restype, "bits") == 0) x1bstr = clixon_trim2(x1bstr, " \t\n"); - /* If origin body has namespace definitions, copy them. The reason is that * some bodies rely on namespace prefixes, such as NACM path, but there is * no way we can know this here. @@ -496,7 +495,7 @@ text_modify(clicon_handle h, * is for element symbols) * Oh well. */ - if (assign_namespace_body(x1, x1bstr, x0) < 0) + if (assign_namespace_body(x1, x0) < 0) goto done; } if ((x0b = xml_body_get(x0)) != NULL){ diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index af400177..0b933992 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -933,7 +933,6 @@ add_namespace(cxobj *x, if (xml_value_set(xa, namespace) < 0) goto done; xml_sort(xp); /* Ensure attr is first / XXX xml_insert? */ - retval = 0; done: return retval; @@ -1798,47 +1797,53 @@ assign_namespace_element(cxobj *x0, /* source */ return retval; } -/* If origin body has namespace definitions, copy them. The reason is that +/*! Copy namespace declarations from source to target + * + * If origin body has namespace definitions, copy them. The reason is that * some bodies rely on namespace prefixes, such as NACM path, but there is * no way we can now this here. * However, this may lead to namespace collisions if these prefixes are not * canonical, and may collide with the assign_namespace_element() above (but that - * is for element sysmbols) + * is for element symbols) + * + * @param[in] x0 Source XML + * @param[in] x1 Destination XML */ int assign_namespace_body(cxobj *x0, /* source */ - char *x0bstr, cxobj *x1) /* target */ { int retval = -1; char *namespace = NULL; + char *namespace1; char *name; - char *prefix; - char *prefix0 = NULL;; - char *pexisting = NULL;; + char *prefix0; + char *prefix1 = NULL; cxobj *xa; xa = NULL; while ((xa = xml_child_each(x0, xa, CX_ATTR)) != NULL) { - prefix = xml_prefix(xa); + prefix0 = xml_prefix(xa); name = xml_name(xa); namespace = xml_value(xa); - if ((strcmp(name, "xmlns")==0 && prefix==NULL) || - (prefix != NULL && strcmp(prefix, "xmlns")==0)){ - if (prefix == NULL) - prefix0 = NULL; + if ((strcmp(name, "xmlns")==0 && prefix0==NULL) || + (prefix0 != NULL && strcmp(prefix0, "xmlns")==0)){ + if (prefix0 == NULL) + prefix1 = NULL; else - prefix0 = name; + prefix1 = name; + /* prefix1 contains actual prefix or NULL, prefix0 can be xmlns */ if (strcmp(namespace, NETCONF_BASE_NAMESPACE) ==0 || strcmp(namespace, YANG_XML_NAMESPACE) ==0) continue; /* Detect if prefix:namespace is declared already? */ - if (xml2prefix(x1, namespace, &pexisting) == 1){ - /* Yes, and it has prefix pexist */ - if (clicon_strcmp(pexisting, prefix0) ==0) - continue; - } - if (add_namespace(x1, x1, prefix0, namespace) < 0) + if (xml2ns(x1, prefix1, &namespace1) == 1) + continue; + /* Does prefix already point at right namespace? */ + if (namespace1 && strcmp(namespace, namespace1)==0) + continue; + /* No, add entry */ + if (add_namespace(x1, x1, prefix1, namespace) < 0) goto done; } } diff --git a/lib/src/clixon_xml_nsctx.c b/lib/src/clixon_xml_nsctx.c index e68201c2..c8d0c84b 100644 --- a/lib/src/clixon_xml_nsctx.c +++ b/lib/src/clixon_xml_nsctx.c @@ -189,7 +189,7 @@ xml_nsctx_get_prefix(cvec *cvv, /*! Set or replace namespace in namespace context * @param[in] cvv Namespace context * @param[in] prefix Namespace prefix, or NULL for default - * @param[in] ns Cached namespace to set (assume non-null?) + * @param[in] ns Cached namespace to set (assume non-null?) * @retval 0 OK * @retval -1 Error */ @@ -604,6 +604,8 @@ xmlns_set(cxobj *x, * @retval -1 Error * @retval 0 No namespace found * @retval 1 Namespace found, prefix returned in prefixp + * @note a namespace can have two or more prefixes, this just returns the first + * @see xml2prefixexists to check a specific pair */ int xml2prefix(cxobj *xn, @@ -660,3 +662,4 @@ xml2prefix(cxobj *xn, goto done; } + diff --git a/test/test_cli.sh b/test/test_cli.sh index 903480c1..9933db6b 100755 --- a/test/test_cli.sh +++ b/test/test_cli.sh @@ -43,11 +43,11 @@ if [ $BE -ne 0 ]; then fi new "start backend -s init -f $cfg" start_backend -s init -f $cfg - - new "waiting" - wait_backend fi +new "wait backend" +wait_backend + new "cli configure top" expectpart "$($clixon_cli -1 -f $cfg set interfaces)" 0 "^$"