http: fix sending error responses to rejected requests by server apps 59/42159/3
authorSemir Sionek <[email protected]>
Thu, 16 Jan 2025 14:03:41 +0000 (09:03 -0500)
committerFlorin Coras <[email protected]>
Thu, 16 Jan 2025 21:45:21 +0000 (21:45 +0000)
Plugins such as http_static sometimes reject requests without reading
all of the body. http_static in that case sends an error response and
closes the connection. But the error response cannot go out due to the
connection state being HTTP_REQ_STATE_TRANSPORT_IO_MORE_DATA.
With this change, we make http_app_tx_callback give a response like
that special treatment, allowing it to go out.

Type: fix
Change-Id: I72ae74b869183f5d5921837f6ac9c52f0efc7598
Signed-off-by: Semir Sionek <[email protected]>
src/plugins/http/http.c

index 5a0c654..c33c85a 100644 (file)
@@ -2467,13 +2467,24 @@ http_app_tx_callback (void *session, transport_send_params_t *sp)
 
   if (!http_req_state_is_tx_valid (hc))
     {
-      clib_warning ("hc [%u]%x invalid tx state: http req state "
-                   "'%U', session state '%U'",
-                   as->thread_index, as->connection_index,
-                   format_http_req_state, hc->req.state,
-                   format_http_conn_state, hc);
-      svm_fifo_dequeue_drop_all (as->tx_fifo);
-      return 0;
+      /* Sometimes the server apps can send the response earlier
+       * than expected (e.g when rejecting a bad request)*/
+      if (hc->req.state == HTTP_REQ_STATE_TRANSPORT_IO_MORE_DATA &&
+         hc->is_server)
+       {
+         svm_fifo_dequeue_drop_all (as->rx_fifo);
+         hc->req.state = HTTP_REQ_STATE_WAIT_APP_REPLY;
+       }
+      else
+       {
+         clib_warning ("hc [%u]%x invalid tx state: http req state "
+                       "'%U', session state '%U'",
+                       as->thread_index, as->connection_index,
+                       format_http_req_state, hc->req.state,
+                       format_http_conn_state, hc);
+         svm_fifo_dequeue_drop_all (as->tx_fifo);
+         return 0;
+       }
     }
 
   HTTP_DBG (1, "run state machine");