hsa: http cli client improvement 36/43436/3
authorMatus Fabian <[email protected]>
Fri, 11 Jul 2025 13:13:34 +0000 (09:13 -0400)
committerFlorin Coras <[email protected]>
Tue, 15 Jul 2025 18:05:18 +0000 (18:05 +0000)
notify http transport when body data is read and transport requested
notification (e.g. used by h2 flow control)

switch to new format of host and target path parsing

Type: improvement

Change-Id: Ie209f1e6fa244f44baa51b4e9a7c66b51b7e5a50
Signed-off-by: Matus Fabian <[email protected]>
extras/hs-test/http1_test.go
extras/hs-test/http2_test.go
src/plugins/hs_apps/http_cli.c
src/plugins/hs_apps/http_client_cli.c

index b806826..045109c 100644 (file)
@@ -261,7 +261,7 @@ func HttpCliTest(s *VethsSuite) {
        s.Containers.ServerVpp.VppInstance.Vppctl(cliServerCmd)
 
        o := s.Containers.ClientVpp.VppInstance.Vppctl("http cli client" +
-               " uri http://" + serverAddress + " query /show/vlib/graph")
+               " uri http://" + serverAddress + "/show/vlib/graph")
 
        s.Log(o)
        s.AssertContains(o, "<html>", "<html> not found in the result!")
@@ -286,19 +286,19 @@ func HttpCliTest(s *VethsSuite) {
 }
 
 func HttpCliTlsTest(s *VethsSuite) {
-       uri := "tls://" + s.Interfaces.Server.Ip4AddressString() + "/" + s.Ports.Port1
+       uri := "https://" + s.Interfaces.Server.Ip4AddressString() + ":" + s.Ports.Port1
 
        s.Containers.ServerVpp.VppInstance.Vppctl("http cli server http1-only uri " + uri)
 
        o := s.Containers.ClientVpp.VppInstance.Vppctl("http cli client" +
-               " uri " + uri + " query /show/version")
+               " uri " + uri + "/show/version")
        s.Log(o)
        s.AssertContains(o, "<html>", "<html> not found in the result!")
        s.AssertContains(o, "</html>", "</html> not found in the result!")
 
        /* second request to test postponed ho-cleanup */
        o = s.Containers.ClientVpp.VppInstance.Vppctl("http cli client" +
-               " uri " + uri + " query /show/version")
+               " uri " + uri + "/show/version")
        s.Log(o)
        s.AssertContains(o, "<html>", "<html> not found in the result!")
        s.AssertContains(o, "</html>", "</html> not found in the result!")
@@ -308,7 +308,7 @@ func HttpCliConnectErrorTest(s *VethsSuite) {
        uri := "http://" + s.Interfaces.Server.Ip4AddressString() + "/80"
 
        o := s.Containers.ClientVpp.VppInstance.Vppctl("http cli client" +
-               " uri " + uri + " query /show/vlib/graph")
+               " uri " + uri + "/show/vlib/graph")
 
        s.Log(o)
        s.AssertContains(o, "failed to connect")
@@ -332,7 +332,7 @@ func HttpClientTest(s *Http1Suite) {
        defer server.Close()
        uri := "http://" + serverAddress
        vpp := s.Containers.Vpp.VppInstance
-       o := vpp.Vppctl("http cli client uri " + uri + " query /test")
+       o := vpp.Vppctl("http cli client uri " + uri + "/test")
 
        s.Log(o)
        s.AssertContains(o, "<html>", "<html> not found in the result!")
@@ -450,7 +450,7 @@ func HttpClientErrRespTest(s *Http1Suite) {
        defer server.Close()
        uri := "http://" + serverAddress
        vpp := s.Containers.Vpp.VppInstance
-       o := vpp.Vppctl("http cli client uri " + uri + " query /test")
+       o := vpp.Vppctl("http cli client uri " + uri + "/test")
 
        s.Log(o)
        s.AssertContains(o, "404: Not Found", "error not found in the result!")
@@ -934,12 +934,12 @@ func HttpClientGetMemLeakTest(s *VethsSuite) {
        /* no goVPP less noise */
        clientVpp.Disconnect()
 
-       serverVpp.Vppctl("http cli server uri " + s.Interfaces.Server.Ip4AddressString() + "/" + s.Ports.Port1)
+       uri := "http://" + s.Interfaces.Server.Ip4AddressString() + ":" + s.Ports.Port1
 
-       uri := "http://" + s.Interfaces.Server.Ip4AddressString() + "/" + s.Ports.Port1
+       serverVpp.Vppctl("http cli server uri " + uri)
 
        /* warmup request (FIB) */
-       clientVpp.Vppctl("http cli client uri " + uri + " query /show/version")
+       clientVpp.Vppctl("http cli client uri " + uri + "/show/version")
 
        /* let's give it some time to clean up sessions, so local port can be reused and we have less noise */
        time.Sleep(time.Second * 12)
@@ -948,7 +948,7 @@ func HttpClientGetMemLeakTest(s *VethsSuite) {
        traces1, err := clientVpp.GetMemoryTrace()
        s.AssertNil(err, fmt.Sprint(err))
 
-       clientVpp.Vppctl("http cli client uri " + uri + " query /show/vlib/graph")
+       clientVpp.Vppctl("http cli client uri " + uri + "/show/vlib/graph")
 
        /* let's give it some time to clean up sessions */
        time.Sleep(time.Second * 12)
index 1b75c52..011e4b9 100644 (file)
@@ -17,7 +17,7 @@ func init() {
 func Http2TcpGetTest(s *Http2Suite) {
        vpp := s.Containers.Vpp.VppInstance
        serverAddress := s.VppAddr() + ":" + s.Ports.Port1
-       vpp.Vppctl("http cli server listener add uri tcp://" + serverAddress)
+       vpp.Vppctl("http cli server listener add uri http://" + serverAddress)
        s.Log(vpp.Vppctl("show session verbose 2"))
        args := fmt.Sprintf("--max-time 10 --noproxy '*' --http2-prior-knowledge http://%s/show/version", serverAddress)
        writeOut, log := s.RunCurlContainer(s.Containers.Curl, args)
@@ -46,7 +46,7 @@ func Http2TcpGetTest(s *Http2Suite) {
        s.AssertEqual(true, httpStreamCleanupDone, "HTTP/2 stream not cleaned up")
 
        /* test server app stop listen */
-       vpp.Vppctl("http cli server listener del uri tcp://" + serverAddress)
+       vpp.Vppctl("http cli server listener del uri http://" + serverAddress)
        o := vpp.Vppctl("show session verbose proto http")
        s.AssertNotContains(o, "LISTEN")
 }
index 6fddd5e..fdc549f 100644 (file)
@@ -630,20 +630,12 @@ hcs_attach ()
   return 0;
 }
 
-static int
-hcs_transport_needs_crypto (transport_proto_t proto)
-{
-  return proto == TRANSPORT_PROTO_TLS || proto == TRANSPORT_PROTO_DTLS ||
-        proto == TRANSPORT_PROTO_QUIC;
-}
-
 static int
 hcs_listen ()
 {
   session_endpoint_cfg_t sep = SESSION_ENDPOINT_CFG_NULL;
   hcs_main_t *hcm = &hcs_main;
   vnet_listen_args_t _a, *a = &_a;
-  u8 need_crypto;
   int rv;
   char *uri;
 
@@ -656,12 +648,10 @@ hcs_listen ()
   if (parse_uri (uri, &sep))
     return -1;
 
-  need_crypto = hcs_transport_needs_crypto (sep.transport_proto);
-
   sep.transport_proto = TRANSPORT_PROTO_HTTP;
   clib_memcpy (&a->sep_ext, &sep, sizeof (sep));
 
-  if (need_crypto)
+  if (sep.flags & SESSION_ENDPT_CFG_F_SECURE)
     {
       transport_endpt_ext_cfg_t *ext_cfg = session_endpoint_add_ext_cfg (
        &a->sep_ext, TRANSPORT_ENDPT_EXT_CFG_CRYPTO,
@@ -681,7 +671,7 @@ hcs_listen ()
       hash_set_mem (hcm->index_by_uri, map->uri, map - hcm->uri_map_pool);
     }
 
-  if (need_crypto)
+  if (sep.flags & SESSION_ENDPT_CFG_F_SECURE)
     session_endpoint_free_ext_cfgs (&a->sep_ext);
 
   return rv;
@@ -824,7 +814,7 @@ hcs_create_command_fn (vlib_main_t *vm, unformat_input_t *input,
 start_server:
 
   if (hcm->uri == 0)
-    hcm->uri = format (0, "tcp://0.0.0.0/80");
+    hcm->uri = format (0, "http://0.0.0.0");
 
   if (hcm->app_index != (u32) ~0)
     {
index f8984be..f6247ea 100644 (file)
@@ -270,6 +270,8 @@ hcc_ts_rx_callback (session_t *ts)
     }
 
   u32 max_deq = svm_fifo_max_dequeue (ts->rx_fifo);
+  if (!max_deq)
+    goto done;
 
   u32 n_deq = clib_min (hs->to_recv, max_deq);
   u64 curr = vec_len (hcm->http_response);
@@ -283,6 +285,12 @@ hcc_ts_rx_callback (session_t *ts)
   if (rv != n_deq)
     return -1;
 
+  if (svm_fifo_needs_deq_ntf (ts->rx_fifo, n_deq))
+    {
+      svm_fifo_clear_deq_ntf (ts->rx_fifo);
+      session_program_transport_io_evt (ts->handle, SESSION_IO_EVT_RX);
+    }
+
   vec_set_len (hcm->http_response, curr + n_deq);
   ASSERT (hs->to_recv >= rv);
   hs->to_recv -= rv;
@@ -579,8 +587,6 @@ hcc_command_fn (vlib_main_t *vm, unformat_input_t *input,
        ;
       else if (unformat (line_input, "secret %lu", &hcm->appns_secret))
        ;
-      else if (unformat (line_input, "query %s", &hcm->http_query))
-       ;
       else
        {
          err = clib_error_return (0, "unknown input `%U'",
@@ -598,13 +604,19 @@ hcc_command_fn (vlib_main_t *vm, unformat_input_t *input,
       goto done;
     }
 
+  if ((rv = parse_target ((char **) &hcm->uri, (char **) &hcm->http_query)))
+    {
+      err = clib_error_return (0, "target parse error: %U",
+                              format_session_error, rv);
+      goto done;
+    }
+
   if ((rv = parse_uri ((char *) hcm->uri, &hcm->connect_sep)))
     {
       err = clib_error_return (0, "Uri parse error: %d", rv);
       goto done;
     }
-  hcm->need_crypto = hcm->connect_sep.transport_proto == TRANSPORT_PROTO_TLS;
-  hcm->connect_sep.transport_proto = TRANSPORT_PROTO_HTTP;
+  hcm->need_crypto = hcm->connect_sep.flags & SESSION_ENDPT_CFG_F_SECURE;
 
   session_enable_disable_args_t args = { .is_en = 1,
                                         .rt_engine_type =
@@ -631,8 +643,9 @@ done:
 
 VLIB_CLI_COMMAND (hcc_command, static) = {
   .path = "http cli client",
-  .short_help = "[appns <app-ns> secret <appns-secret>] uri http://<ip-addr> "
-               "query <query-string> [no-output]",
+  .short_help =
+    "[appns <app-ns> secret <appns-secret>] uri http[s]://<ip-addr>/<target> "
+    "[no-output]",
   .function = hcc_command_fn,
   .is_mp_safe = 1,
 };