Fixed: A long TLS+HTTP/2 request such as by a browser causing block of other requests.

Test: Disabled privileges test if clixon_restconf started with -r
This commit is contained in:
Olof hagsand 2022-05-02 10:31:53 +02:00
parent 463aa15544
commit 90474d1523
3 changed files with 38 additions and 24 deletions

View file

@ -112,6 +112,7 @@ Users may have to change how they access the system
### Corrected Bugs ### Corrected Bugs
* Fixed: A long TLS+HTTP/2 request such as by a browser causing block of other requests.
* Fixed: [Error message seen twice in some cases](https://github.com/clicon/clixon/issues/325) * Fixed: [Error message seen twice in some cases](https://github.com/clicon/clixon/issues/325)
* Fixed: [if choice is declared with multiple elements or leaf-list with in a case scope , addition or updation is not happening as expected](https://github.com/clicon/clixon/issues/327) * Fixed: [if choice is declared with multiple elements or leaf-list with in a case scope , addition or updation is not happening as expected](https://github.com/clicon/clixon/issues/327)
* This includes several choice/case adjustments to follow RFC 7950 Sec 7.9 better * This includes several choice/case adjustments to follow RFC 7950 Sec 7.9 better

View file

@ -465,7 +465,7 @@ native_send_badrequest(clicon_handle h,
* @retval -1 Error * @retval -1 Error
*/ */
static int static int
native_clear_input(clicon_handle h, http1_native_clear_input(clicon_handle h,
restconf_stream_data *sd) restconf_stream_data *sd)
{ {
int retval = -1; int retval = -1;
@ -524,6 +524,7 @@ read_ssl(restconf_conn *rc,
} }
retval = 0; retval = 0;
done: done:
clicon_debug(1, "%s %d", __FUNCTION__, retval);
return retval; return retval;
} }
@ -577,7 +578,8 @@ read_regular(restconf_conn *rc,
} }
#ifdef HAVE_HTTP1 #ifdef HAVE_HTTP1
/*! RESTCONF HTTP/1 processing after chunk of bytes read
/*! Restconf HTTP/1 processing after chunk of bytes read
* *
* @param[in] rc Restconf connection handle * @param[in] rc Restconf connection handle
* @param[in] buf Input buffer * @param[in] buf Input buffer
@ -588,7 +590,7 @@ read_regular(restconf_conn *rc,
* @retval 1 OK * @retval 1 OK
*/ */
static int static int
restconf_http1(restconf_conn *rc, restconf_http1_process(restconf_conn *rc,
char *buf, char *buf,
size_t n, size_t n,
int *readmore) int *readmore)
@ -641,7 +643,7 @@ restconf_http1(restconf_conn *rc,
else if ((ret = clixon_event_poll(rc->rc_s)) < 0) else if ((ret = clixon_event_poll(rc->rc_s)) < 0)
goto done; goto done;
if (ret > 0){ if (ret > 0){
if (native_clear_input(h, sd) < 0) if (http1_native_clear_input(h, sd) < 0)
goto done; goto done;
(*readmore)++; (*readmore)++;
goto ok; goto ok;
@ -790,15 +792,18 @@ restconf_http2_upgrade(restconf_conn *rc)
} }
#endif /* HAVE_LIBHTTP1 */ #endif /* HAVE_LIBHTTP1 */
/*! /*! Restconf HTTP/2 processing after chunk of bytes read
* @param[in] rc Restconf connection
* @param[in] buf Input buffer * @param[in] buf Input buffer
* @param[in] n Size of input buffer * @param[in] n Size of input buffer
* @param[in] n Length of data in input buffer
* @param[out] readmore If set, read data again, do not continue processing
* @retval -1 Error * @retval -1 Error
* @retval 0 Socket closed, quit * @retval 0 Socket closed, quit
* @retval 1 OK * @retval 1 OK
*/ */
static int static int
restconf_http2(restconf_conn *rc, restconf_http2_process(restconf_conn *rc,
char *buf, char *buf,
size_t n, size_t n,
int *readmore) int *readmore)
@ -823,7 +828,13 @@ restconf_http2(restconf_conn *rc,
retval = 0; retval = 0;
goto done; goto done;
} }
/* There may be more data frames */ /* Check if read more data frames */
ret = 0;
if (rc->rc_ssl)
ret = SSL_pending(rc->rc_ssl);
else if ((ret = clixon_event_poll(rc->rc_s)) < 0)
goto done;
if (ret > 0)
(*readmore)++; (*readmore)++;
} }
retval = 1; retval = 1;
@ -891,7 +902,7 @@ restconf_connection(int s,
#ifdef HAVE_HTTP1 #ifdef HAVE_HTTP1
case HTTP_10: case HTTP_10:
case HTTP_11: case HTTP_11:
if ((ret = restconf_http1(rc, buf, n, &readmore)) < 0) if ((ret = restconf_http1_process(rc, buf, n, &readmore)) < 0)
goto done; goto done;
if (ret == 0) if (ret == 0)
goto ok; goto ok;
@ -905,12 +916,10 @@ restconf_connection(int s,
#endif /* HAVE_HTTP1 */ #endif /* HAVE_HTTP1 */
#ifdef HAVE_LIBNGHTTP2 #ifdef HAVE_LIBNGHTTP2
case HTTP_2: case HTTP_2:
if ((ret = restconf_http2(rc, buf, n, &readmore)) < 0) if ((ret = restconf_http2_process(rc, buf, n, &readmore)) < 0)
goto done; goto done;
if (ret == 0) if (ret == 0)
goto ok; goto ok;
if (readmore)
continue;
break; break;
#endif /* HAVE_LIBNGHTTP2 */ #endif /* HAVE_LIBNGHTTP2 */
default: default:

View file

@ -228,11 +228,15 @@ EOF
new "WWW get http soft link" new "WWW get http soft link"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $proto://localhost/data/inside.html)" 0 "HTTP/$HVER 403" "Content-Type: text/html" "<title>403 Forbidden</title>" --not-- "<title>Dont access this</title>" expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $proto://localhost/data/inside.html)" 0 "HTTP/$HVER 403" "Content-Type: text/html" "<title>403 Forbidden</title>" --not-- "<title>Dont access this</title>"
# Two cases where the privileges test is not run:
if [ ! -f /.dockerenv ] ; then # XXX Privs dont not work on docker/alpine? # 1) Docker in alpine for some reason
# 2) Restconf run explicitly as root (eg coverage)
if [ ! -f /.dockerenv ] ; then
if [[ "$clixon_restconf" != *"-r"* ]]; then
new "WWW get http not read access" new "WWW get http not read access"
expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $proto://localhost/data/noread.html)" 0 "HTTP/$HVER 403" "Content-Type: text/html" "<title>403 Forbidden</title>" expectpart "$(curl $CURLOPTS -X GET -H 'Accept: text/html' $proto://localhost/data/noread.html)" 0 "HTTP/$HVER 403" "Content-Type: text/html" "<title>403 Forbidden</title>"
fi fi
fi
# Try .. Cannot get .. in path to work in curl (it seems to remove it) # Try .. Cannot get .. in path to work in curl (it seems to remove it)
if [ "$proto" = http -a -n "$netcat" ]; then if [ "$proto" = http -a -n "$netcat" ]; then