diff options
author | Matus Fabian <matfabia@cisco.com> | 2024-06-27 13:20:10 +0200 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2024-07-23 20:37:16 +0000 |
commit | d086a3650eea95056e738e2cc5dc18ce6edc278b (patch) | |
tree | 4dcb6d843b01143ab76428c268b6e382c6694545 /src/plugins/http | |
parent | 8ca6ce6fe1e65c8b57b9c0910dfd1243db0e49b9 (diff) |
http: state machine fix
When client sends second request without waiting for response of the
first request http_ts_rx_callback should drop request (pipelining is
not supported) instead of invoking return to state machine which can
lead to erroneous state, e.g. reading random data from server app
fifo.
Added simple http static server url handler for testing to simulate
long running request processing, for now hardcoded delay 5 seconds.
Type: fix
Change-Id: Ied9f7e2e4ee64c982f045c0f7f99a2dc5d7a2108
Signed-off-by: Matus Fabian <matfabia@cisco.com>
Diffstat (limited to 'src/plugins/http')
-rw-r--r-- | src/plugins/http/http.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/src/plugins/http/http.c b/src/plugins/http/http.c index db101539ac4..416ba8fe817 100644 --- a/src/plugins/http/http.c +++ b/src/plugins/http/http.c @@ -82,11 +82,19 @@ http_state_is_tx_valid (http_conn_t *hc) { http_state_t state = hc->http_state; return (state == HTTP_STATE_APP_IO_MORE_DATA || - state == HTTP_STATE_CLIENT_IO_MORE_DATA || state == HTTP_STATE_WAIT_APP_REPLY || state == HTTP_STATE_WAIT_APP_METHOD); } +static inline int +http_state_is_rx_valid (http_conn_t *hc) +{ + http_state_t state = hc->http_state; + return (state == HTTP_STATE_WAIT_SERVER_REPLY || + state == HTTP_STATE_CLIENT_IO_MORE_DATA || + state == HTTP_STATE_WAIT_CLIENT_METHOD); +} + static inline http_worker_t * http_worker_get (u32 thread_index) { @@ -1060,7 +1068,6 @@ http_state_wait_app_reply (http_conn_t *hc, transport_send_params_t *sp) return HTTP_SM_CONTINUE; error: - clib_warning ("unexpected msg type from app %u", msg.type); http_send_error (hc, sc); http_state_change (hc, HTTP_STATE_WAIT_CLIENT_METHOD); session_transport_closing_notify (&hc->connection); @@ -1294,12 +1301,16 @@ http_ts_rx_callback (session_t *ts) return -1; } - if (hc->state == HTTP_CONN_STATE_CLOSED) + if (!http_state_is_rx_valid (hc)) { + if (hc->state != HTTP_CONN_STATE_CLOSED) + clib_warning ("app data req state '%U' session state %u", + format_http_state, hc->http_state, hc->state); svm_fifo_dequeue_drop_all (ts->tx_fifo); return 0; } + HTTP_DBG (1, "run state machine"); http_req_run_state_machine (hc, 0); if (hc->state == HTTP_CONN_STATE_TRANSPORT_CLOSED) @@ -1605,6 +1616,7 @@ http_app_tx_callback (void *session, transport_send_params_t *sp) max_burst_sz = sp->max_burst_size * TRANSPORT_PACER_MIN_MSS; sp->max_burst_size = max_burst_sz; + HTTP_DBG (1, "run state machine"); http_req_run_state_machine (hc, sp); if (hc->state == HTTP_CONN_STATE_APP_CLOSED) |