http: http_buffer improvements 50/42650/3
authorMatus Fabian <[email protected]>
Thu, 3 Apr 2025 09:59:06 +0000 (05:59 -0400)
committerFlorin Coras <[email protected]>
Mon, 7 Apr 2025 19:39:37 +0000 (19:39 +0000)
needed for http/2 to make data frame header

http_buffer_get_segs return number bytes in returned segments
http_buffer_is_drain changed to http_buffer_bytes_left
ptr buffer can track u64 data length

Type: improvement

Change-Id: I586bec69c851cb38d7be7af9e254cd240bbd7e62
Signed-off-by: Matus Fabian <[email protected]>
src/plugins/http/http1.c
src/plugins/http/http_buffer.c
src/plugins/http/http_buffer.h

index 09d69f5..e71a458 100644 (file)
@@ -1504,12 +1504,12 @@ static http_sm_result_t
 http1_req_state_app_io_more_data (http_conn_t *hc, http_req_t *req,
                                  transport_send_params_t *sp)
 {
-  u32 max_write, n_segs, n_written = 0;
+  u32 max_write, n_read, n_segs, n_written = 0;
   http_buffer_t *hb = &req->tx_buf;
   svm_fifo_seg_t *seg;
   u8 finished = 0;
 
-  ASSERT (!http_buffer_is_drained (hb));
+  ASSERT (http_buffer_bytes_left (hb) > 0);
   max_write = http_io_ts_max_write (hc, sp);
   if (max_write == 0)
     {
@@ -1517,8 +1517,8 @@ http1_req_state_app_io_more_data (http_conn_t *hc, http_req_t *req,
       goto check_fifo;
     }
 
-  seg = http_buffer_get_segs (hb, max_write, &n_segs);
-  if (!seg)
+  n_read = http_buffer_get_segs (hb, max_write, &seg, &n_segs);
+  if (n_read == 0)
     {
       HTTP_DBG (1, "no data to deq");
       goto check_fifo;
@@ -1527,7 +1527,7 @@ http1_req_state_app_io_more_data (http_conn_t *hc, http_req_t *req,
   n_written = http_io_ts_write_segs (hc, seg, n_segs, sp);
 
   http_buffer_drain (hb, n_written);
-  finished = http_buffer_is_drained (hb);
+  finished = http_buffer_bytes_left (hb) == 0;
 
   if (finished)
     {
index 909aa53..fd90fbf 100644 (file)
@@ -57,8 +57,9 @@ buf_fifo_free (http_buffer_t *hb)
   vec_free (bf->segs);
 }
 
-static svm_fifo_seg_t *
-buf_fifo_get_segs (http_buffer_t *hb, u32 max_len, u32 *n_segs)
+static u32
+buf_fifo_get_segs (http_buffer_t *hb, u32 max_len, svm_fifo_seg_t **fs,
+                  u32 *n_segs)
 {
   http_buffer_fifo_t *bf = (http_buffer_fifo_t *) &hb->data;
 
@@ -77,7 +78,8 @@ buf_fifo_get_segs (http_buffer_t *hb, u32 max_len, u32 *n_segs)
 
   HTTP_DBG (1, "available to send %u n_segs %u", len, *n_segs);
 
-  return bf->segs;
+  *fs = bf->segs;
+  return len;
 }
 
 static u32
@@ -92,13 +94,13 @@ buf_fifo_drain (http_buffer_t *hb, u32 len)
   return len;
 }
 
-static u8
-buf_fifo_is_drained (http_buffer_t *hb)
+static u64
+buf_fifo_bytes_left (http_buffer_t *hb)
 {
   http_buffer_fifo_t *bf = (http_buffer_fifo_t *) &hb->data;
 
   ASSERT (bf->offset <= bf->len);
-  return (bf->offset == bf->len);
+  return (bf->len - bf->offset);
 }
 
 const static http_buffer_vft_t buf_fifo_vft = {
@@ -106,7 +108,7 @@ const static http_buffer_vft_t buf_fifo_vft = {
   .free = buf_fifo_free,
   .get_segs = buf_fifo_get_segs,
   .drain = buf_fifo_drain,
-  .is_drained = buf_fifo_is_drained,
+  .bytes_left = buf_fifo_bytes_left,
 };
 
 HTTP_BUFFER_REGISTER_VFT (HTTP_BUFFER_FIFO, buf_fifo_vft);
@@ -115,6 +117,7 @@ typedef struct http_buffer_ptr_
 {
   svm_fifo_seg_t *segs;
   svm_fifo_t *f;
+  u64 len;
 } http_buffer_ptr_t;
 
 STATIC_ASSERT (sizeof (http_buffer_ptr_t) <= HTTP_BUFFER_DATA_SZ, "buf data");
@@ -135,12 +138,11 @@ buf_ptr_init (http_buffer_t *hb, void *data, u64 len)
 
   bf->f = f;
   bf->segs = 0;
-  vec_validate (bf->segs, 1);
+  vec_validate (bf->segs, 0);
 
   bf->segs[0].data = uword_to_pointer (ptr, u8 *);
-  bf->segs[0].len = len;
 
-  bf->segs[1] = bf->segs[0];
+  bf->len = len;
 }
 
 static void
@@ -152,15 +154,17 @@ buf_ptr_free (http_buffer_t *hb)
   vec_free (bf->segs);
 }
 
-static svm_fifo_seg_t *
-buf_ptr_get_segs (http_buffer_t *hb, u32 max_len, u32 *n_segs)
+static u32
+buf_ptr_get_segs (http_buffer_t *hb, u32 max_len, svm_fifo_seg_t **fs,
+                 u32 *n_segs)
 {
   http_buffer_ptr_t *bf = (http_buffer_ptr_t *) &hb->data;
 
   *n_segs = 1;
-  bf->segs[1].len = clib_min (bf->segs[0].len, max_len);
+  bf->segs[0].len = clib_min (bf->len, (u64) max_len);
 
-  return &bf->segs[1];
+  *fs = bf->segs;
+  return bf->segs[0].len;
 }
 
 static u32
@@ -168,14 +172,14 @@ buf_ptr_drain (http_buffer_t *hb, u32 len)
 {
   http_buffer_ptr_t *bf = (http_buffer_ptr_t *) &hb->data;
 
-  ASSERT (bf->segs[0].len >= len);
+  ASSERT (bf->len >= len);
 
-  bf->segs[1].data += len;
-  bf->segs[0].len -= len;
+  bf->segs[0].data += len;
+  bf->len -= len;
 
-  HTTP_DBG (1, "drained %u left %u", len, bf->segs[0].len);
+  HTTP_DBG (1, "drained %u left %u", len, bf->len);
 
-  if (!bf->segs[0].len)
+  if (!bf->len)
     {
       svm_fifo_dequeue_drop (bf->f, sizeof (uword));
       return sizeof (uword);
@@ -184,12 +188,12 @@ buf_ptr_drain (http_buffer_t *hb, u32 len)
   return 0;
 }
 
-static u8
-buf_ptr_is_drained (http_buffer_t *hb)
+static u64
+buf_ptr_bytes_left (http_buffer_t *hb)
 {
   http_buffer_ptr_t *bf = (http_buffer_ptr_t *) &hb->data;
 
-  return (bf->segs[0].len == 0);
+  return bf->len;
 }
 
 const static http_buffer_vft_t buf_ptr_vft = {
@@ -197,7 +201,7 @@ const static http_buffer_vft_t buf_ptr_vft = {
   .free = buf_ptr_free,
   .get_segs = buf_ptr_get_segs,
   .drain = buf_ptr_drain,
-  .is_drained = buf_ptr_is_drained,
+  .bytes_left = buf_ptr_bytes_left,
 };
 
 HTTP_BUFFER_REGISTER_VFT (HTTP_BUFFER_PTR, buf_ptr_vft);
index 1140be4..01b37d4 100644 (file)
@@ -38,9 +38,10 @@ struct http_buffer_vft_
 {
   void (*init) (http_buffer_t *, void *data, u64 len);
   void (*free) (http_buffer_t *);
-  svm_fifo_seg_t *(*get_segs) (http_buffer_t *, u32 max_len, u32 *n_segs);
+  u32 (*get_segs) (http_buffer_t *, u32 max_len, svm_fifo_seg_t **fs,
+                  u32 *n_segs);
   u32 (*drain) (http_buffer_t *, u32 len);
-  u8 (*is_drained) (http_buffer_t *);
+  u64 (*bytes_left) (http_buffer_t *);
 };
 
 void http_buffer_init (http_buffer_t *hb, http_buffer_type_t type,
@@ -53,10 +54,11 @@ http_buffer_free (http_buffer_t *hb)
     hb->vft->free (hb);
 }
 
-static inline svm_fifo_seg_t *
-http_buffer_get_segs (http_buffer_t *hb, u32 max_len, u32 *n_segs)
+static inline u32
+http_buffer_get_segs (http_buffer_t *hb, u32 max_len, svm_fifo_seg_t **fs,
+                     u32 *n_segs)
 {
-  return hb->vft->get_segs (hb, max_len, n_segs);
+  return hb->vft->get_segs (hb, max_len, fs, n_segs);
 }
 
 static inline u32
@@ -65,10 +67,10 @@ http_buffer_drain (http_buffer_t *hb, u32 len)
   return hb->vft->drain (hb, len);
 }
 
-static inline u8
-http_buffer_is_drained (http_buffer_t *hb)
+static inline u64
+http_buffer_bytes_left (http_buffer_t *hb)
 {
-  return hb->vft->is_drained (hb);
+  return hb->vft->bytes_left (hb);
 }
 
 #endif /* SRC_PLUGINS_HTTP_HTTP_BUFFER_H_ */