http: http_state_wait_app_reply improvement 80/41480/2
authorMatus Fabian <[email protected]>
Mon, 26 Aug 2024 16:26:58 +0000 (18:26 +0200)
committerFlorin Coras <[email protected]>
Wed, 28 Aug 2024 06:08:04 +0000 (06:08 +0000)
set http status according to whether app also sent the body

Type: improvement
Change-Id: Ia41603cc21b410ca6929ec3d3e7c4c6808305769
Signed-off-by: Matus Fabian <[email protected]>
extras/hs-test/http_test.go
src/plugins/hs_apps/test_builtins.c
src/plugins/http/http.c

index 5a33964..733ca46 100644 (file)
@@ -85,24 +85,39 @@ func HttpPersistentConnectionTest(s *NoTopoSuite) {
                        return http.ErrUseLastResponse
                }}
 
-       req, err := http.NewRequest("GET", "http://"+serverAddress+":80/test1", nil)
+       body := []byte("{\"sandwich\": {\"spam\": 2, \"eggs\": 1}}")
+       req, err := http.NewRequest("POST", "http://"+serverAddress+":80/test3", bytes.NewBuffer(body))
        s.AssertNil(err, fmt.Sprint(err))
        resp, err := client.Do(req)
        s.AssertNil(err, fmt.Sprint(err))
        s.Log(DumpHttpResp(resp, true))
        s.AssertHttpStatus(resp, 200)
        s.AssertEqual(false, resp.Close)
-       s.AssertHttpBody(resp, "hello")
+       s.AssertHttpContentLength(resp, int64(0))
        o1 := vpp.Vppctl("show session verbose proto http state ready")
        s.Log(o1)
        s.AssertContains(o1, "ESTABLISHED")
 
-       req, err = http.NewRequest("GET", "http://"+serverAddress+":80/test2", nil)
+       req, err = http.NewRequest("GET", "http://"+serverAddress+":80/test1", nil)
+       s.AssertNil(err, fmt.Sprint(err))
        clientTrace := &httptrace.ClientTrace{
                GotConn: func(info httptrace.GotConnInfo) {
                        s.AssertEqual(true, info.Reused, "connection not reused")
                },
        }
+       req = req.WithContext(httptrace.WithClientTrace(req.Context(), clientTrace))
+       resp, err = client.Do(req)
+       s.AssertNil(err, fmt.Sprint(err))
+       s.Log(DumpHttpResp(resp, true))
+       s.AssertHttpStatus(resp, 200)
+       s.AssertEqual(false, resp.Close)
+       s.AssertHttpBody(resp, "hello")
+       o2 := vpp.Vppctl("show session verbose proto http state ready")
+       s.Log(o2)
+       s.AssertContains(o2, "ESTABLISHED")
+       s.AssertEqual(o1, o2)
+
+       req, err = http.NewRequest("GET", "http://"+serverAddress+":80/test2", nil)
        s.AssertNil(err, fmt.Sprint(err))
        req = req.WithContext(httptrace.WithClientTrace(req.Context(), clientTrace))
        resp, err = client.Do(req)
@@ -111,7 +126,7 @@ func HttpPersistentConnectionTest(s *NoTopoSuite) {
        s.AssertHttpStatus(resp, 200)
        s.AssertEqual(false, resp.Close)
        s.AssertHttpBody(resp, "some data")
-       o2 := vpp.Vppctl("show session verbose proto http state ready")
+       o2 = vpp.Vppctl("show session verbose proto http state ready")
        s.Log(o2)
        s.AssertContains(o2, "ESTABLISHED")
        s.AssertEqual(o1, o2)
index cd6b00d..631c1f1 100644 (file)
@@ -125,6 +125,13 @@ handle_get_test_delayed (hss_url_handler_args_t *args)
   return HSS_URL_HANDLER_ASYNC;
 }
 
+static hss_url_handler_rc_t
+handle_post_test3 (hss_url_handler_args_t *args)
+{
+  send_data_to_hss (args->sh, 0);
+  return HSS_URL_HANDLER_ASYNC;
+}
+
 static void
 test_builtins_init (vlib_main_t *vm)
 {
@@ -144,6 +151,7 @@ test_builtins_init (vlib_main_t *vm)
   (*fp) (handle_get_test1, "test1", HTTP_REQ_GET);
   (*fp) (handle_get_test2, "test2", HTTP_REQ_GET);
   (*fp) (handle_get_test_delayed, "test_delayed", HTTP_REQ_GET);
+  (*fp) (handle_post_test3, "test3", HTTP_REQ_POST);
 
   tbm->send_data =
     vlib_get_plugin_symbol ("http_static_plugin.so", "hss_session_send_data");
index b143893..b993daa 100644 (file)
@@ -1093,6 +1093,7 @@ http_state_wait_app_reply (http_conn_t *hc, transport_send_params_t *sp)
   http_status_code_t sc;
   http_msg_t msg;
   int rv;
+  http_sm_result_t sm_result = HTTP_SM_ERROR;
 
   as = session_get_from_handle (hc->h_pa_session_handle);
 
@@ -1159,9 +1160,6 @@ http_state_wait_app_reply (http_conn_t *hc, transport_send_params_t *sp)
     }
   HTTP_DBG (0, "%v", header);
 
-  http_buffer_init (&hc->tx_buf, msg_to_buf_type[msg.data.type], as->tx_fifo,
-                   msg.data.body_len);
-
   offset = http_send_data (hc, header, vec_len (header), 0);
   if (offset != vec_len (header))
     {
@@ -1172,12 +1170,24 @@ http_state_wait_app_reply (http_conn_t *hc, transport_send_params_t *sp)
     }
   vec_free (header);
 
-  /* Start sending the actual data */
-  http_state_change (hc, HTTP_STATE_APP_IO_MORE_DATA);
+  if (msg.data.body_len)
+    {
+      /* Start sending the actual data */
+      http_buffer_init (&hc->tx_buf, msg_to_buf_type[msg.data.type],
+                       as->tx_fifo, msg.data.body_len);
+      http_state_change (hc, HTTP_STATE_APP_IO_MORE_DATA);
+      sm_result = HTTP_SM_CONTINUE;
+    }
+  else
+    {
+      /* No response body, we are done */
+      http_state_change (hc, HTTP_STATE_WAIT_CLIENT_METHOD);
+      sm_result = HTTP_SM_STOP;
+    }
 
   ASSERT (sp->max_burst_size >= offset);
   sp->max_burst_size -= offset;
-  return HTTP_SM_CONTINUE;
+  return sm_result;
 
 error:
   http_send_error (hc, sc);