Skip to content

Commit

Permalink
Fixed: [Multiple http requests in native restconf yields same reply #212
Browse files Browse the repository at this point in the history
](#212)
  • Loading branch information
olofhagsand committed Apr 24, 2021
1 parent d48b8a8 commit 6981daf
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 2 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ Expected: June 2021
* hide-database : specifies that a command is not visible in database. This can be useful for setting passwords and not exposing them to users.
* hide-database-auto-completion : specifies that a command is not visible in database and in auto completion. This can be useful for a password that was put in device by super user, not be changed.

### Corrected Bugs

* Fixed: [Multiple http requests in native restconf yields same reply #212](https://github.com/clicon/clixon/issues/212)

## 5.1.0
15 April 2021

Expand Down
23 changes: 21 additions & 2 deletions apps/restconf/restconf_main_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -946,12 +946,25 @@ restconf_connection(int s,
struct evbuffer *ev;

if ((ev = bufferevent_get_output(conn->bev)) != NULL){
buf = (char*)evbuffer_pullup(ev, -1);
buflen = evbuffer_get_length(ev);
clicon_debug(1, "%s buf:%s", __FUNCTION__, buf);
if (buflen){
#ifdef RESTCONF_LIBEVENT_POS_PATCH
size_t pos;

pos = (size_t)conn->arg;
#endif
buf = (char*)evbuffer_pullup(ev, -1);
clicon_debug(1, "%s buf:%s", __FUNCTION__, buf);
#ifdef RESTCONF_LIBEVENT_POS_PATCH
if (buf_write(buf+pos, buflen, conn->sock, conn->ssl) < 0)
goto done;
pos += buflen;
conn->arg = (void*)pos;
#else
/* Does not work w multiple requests */
if (buf_write(buf, buflen, conn->sock, conn->ssl) < 0)
goto done;
#endif
}
else{
/* Return 0 from evhtp parser can be that it needs more data.
Expand Down Expand Up @@ -1231,6 +1244,12 @@ restconf_accept_client(int fd,
/*
* Register callbacks for actual data socket
*/
#ifdef LIBEVENT_POS_PATCH
/* patch to keep track os position in output buffer
* cannot use drain/copyout since the start position is "freezed" in bufferevent_socket_new
*/
conn->arg = (void*)0;
#endif
if (clixon_event_reg_fd(s, restconf_connection, (void*)conn, "restconf client socket") < 0)
goto done;
ok:
Expand Down
11 changes: 11 additions & 0 deletions include/clixon_custom.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,14 @@
/* Name of default netns for clixon-restconf.yang socket/namespace field
*/
#define RESTCONF_NETNS_DEFAULT "default"

/* Patch to keep track os position in output buffer for native restconf using libevent
* It addresses that multiple requests in a single TCP HTTP session will only reply first
* reply again
* Cannot use drain/copyout since the start position is "freezed" in bufferevent_socket_new
* Strange thing is that evbuffer_drain / evbuffer_copyout cannot be used due to freeze set
* One could have thought freeze was in place for writing only?
* Note may not wrap-around correctly at size-t boundary
*/
#define RESTCONF_LIBEVENT_POS_PATCH
7 changes: 7 additions & 0 deletions test/test_restconf2.sh → test/test_restconf_op.sh
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,13 @@ expectpart "$(curl $CURLOPTS -X PUT -H "Content-Type: application/yang-data+json
new "restconf GET datastore eth"
expectpart "$(curl $CURLOPTS -X GET $RCPROTO://localhost/restconf/data/example:cont1/interface=local0)" 0 "HTTP/1.1 200 OK" '{"example:interface":\[{"name":"local0","type":"eth0"}\]}'

new "restconf DELETE whole datastore"
expectpart "$(curl $CURLOPTS -X DELETE $RCPROTO://localhost/restconf/data)" 0 "HTTP/1.1 204 No Content"

#--------------- Multiple request in single TCP tests

expectpart "$(curl $CURLOPTS -H "Accept: application/yang-data+xml" -X GET $RCPROTO://localhost/restconf/data?content=config --next $CURLOPTS -H "Content-Type: application/yang-data+json" -X POST $RCPROTO://localhost/restconf/data -d '{"example:cont1":{"interface":{"name":"local0","type":"regular"}}}')" 0 "HTTP/1.1 200 OK" '<data/>' 'HTTP/1.1 201 Created'

#--------------- json type tests
new "restconf POST type x3 POST"
expectpart "$(curl $CURLOPTS -X POST -H "Content-Type: application/yang-data+json" -d '{"example:types":{"tint":42,"tdec64":42.123,"tbool":false,"tstr":"str"}}' $RCPROTO://localhost/restconf/data)" 0 "HTTP/1.1 201 Created" "Location: $RCPROTO://localhost/restconf/data/example:types"
Expand Down

0 comments on commit 6981daf

Please sign in to comment.